# AWS seller registration
Source: https://docs.milkstraw.ai/aws-seller-registration
How to become an AWS registered seller
This allows us to transfer your underutilized AWS Reserved Instances by listing them on the AWS Reserved Instance Marketplace.
## Registration process
To log in, go to the [AWS seller registration page](https://portal.aws.amazon.com/ec2/ri/seller_registration).
You must log in as the root user of your AWS account to proceed.
Fill in your business name and click the **Continue** button.
This is for receiving payments from your Reserved Instance sales.
Fill in the details and click the **Continue** button.
If you don't have a US bank account, please reach out to us at [support@milkstraw.ai](mailto:support@milkstraw.ai).
Look for **Update Your Tax Profile!** and click the **Continue** button next to it.
Enter all the necessary tax information as prompted.
## You're all set! 🥳
Now we can easily transfer your underutilized AWS Reserved Instances.
# Billing
Source: https://docs.milkstraw.ai/billing
You maintain your AWS billing while we charge separately based on your savings.
## Your AWS billing remains unchanged
You continue to pay AWS directly for all your cloud usage, as you normally would.
Our service operates alongside your existing AWS billing relationship.
## Performance-based billing
* Our fee is 20% of the savings you realize by using MilkStraw AI.
* These savings are determined monthly based on the performance of the MilkBoxes we send to your AWS organization.
* We fetch the savings from the Cost Explorer API to get the total savings and from it we calculate our fee.
* There are no charges for onboarding, initial system analysis, or ongoing support.
### Example calculation
Let's say your current AWS bill is **\$10,000/month**. After using MilkStraw AI:
1. **New AWS bill**: \$7,000/month
2. **Total savings**: \$3,000/month
3. **MilkStraw AI fee (20%)**: \$600/month
4. **Your net savings**: \$2,400/month
You keep 80% of all savings while we handle the optimization work.
## Billing cycle
* A monthly bill for the MilkStraw AI service fee is issued separately for each account.
* Billing occurs after your AWS bill is issued, typically in the first week of every month.
* You can review your MilkStraw AI billing history and invoices directly within the MilkStraw AI billing page in the dashboard.
We prorate your savings for the first partial month and calculate full monthly savings thereafter.
# Cancellation
Source: https://docs.milkstraw.ai/cancellation
How to cancel your MilkStraw AI service and what to expect during offboarding.
## Overview
You can cancel MilkStraw AI at any time. There are no long-term contracts, cancellation fees, or lock-in periods. Once cancellation is complete, we remove all MilkBoxes from your AWS Organization and stop billing.
## Before you cancel
Reach out first if you're canceling due to an issue we may be able to resolve.
Book a quick call so we can address any concerns or blockers.
## How to cancel
Email [support@milkstraw.ai](mailto:support@milkstraw.ai) or [schedule a call](https://cal.com/team/milkstraw-ai/chat-with-milkstraw-team) from the account owner's email address. Include your organization name and the AWS Organization ID you want to disconnect.
Our team will confirm your cancellation request and schedule the MilkBox removal. To avoid disrupting active commitment coverage, we coordinate removal at a time that minimizes impact on your AWS bill.
We remove all MilkBoxes from your AWS Organization. Each removed account goes through a factory reset before it can be reused, ensuring full data isolation.
Once offboarding is complete, you can delete the MilkStraw AI CloudFormation stack (or StackSet) from your AWS management account to revoke our cross-account IAM role.
You'll receive a final invoice for any savings realized up to the cancellation date. See [Billing](/billing) for how fees are calculated.
## What happens to your data
* MilkStraw AI only stores billing and usage metadata — never workload data.
* After cancellation, your usage history is retained only as needed to issue and support the final invoice, then deleted in line with our data retention policy.
* You can request deletion of your account data by emailing [support@milkstraw.ai](mailto:support@milkstraw.ai).
## Billing after cancellation
* No new fees are charged after MilkBoxes are removed from your organization.
* The final invoice covers savings realized up to the removal date, prorated for the partial month.
* Existing Savings Plans or Reserved Instances you owned before MilkStraw AI are unaffected — they remain in your account.
Canceling stops future fees but does not retroactively refund past savings fees, since those correspond to savings you already realized on your AWS bill.
## Reconnecting later
If you want to come back, you can re-onboard at any time by following the [Quickstart](/quickstart) guide. Your previous account can be reactivated — [contact us](/contact) so we can restore your organization's setup.
# MilkStraw CLI
Source: https://docs.milkstraw.ai/cli
Authentication, onboarding, and manage integration from the terminal.
The MilkStraw CLI (`@milkstraw/cli`) is a developer-friendly alternative to the web-based [Quickstart](/quickstart). Use it to start or maintain your MilkStraw integration without leaving your terminal.
**Prerequisites**
* An active [MilkStraw AI](https://app.milkstraw.ai) account
* The [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html#getting-started-install-instructions) installed and configured
* AWS credentials with access to your AWS Organization management account
## Configure AWS credentials
Set up credentials using one of:
```bash theme={null}
aws configure # Access key + secret
aws configure sso # SSO login (recommended)
```
Verify your credentials are working:
```bash theme={null}
aws sts get-caller-identity
```
## Quick start
Run `setup` to authenticate, setup and deploy the MilkStraw cross role through CloudFormation stacks into your AWS organization:
```bash theme={null}
npx @milkstraw/cli setup
```
## Commands
| Command | Description |
| -------------------- | ------------------------------------------ |
| `milkstraw login` | Interactive browser login |
| `milkstraw logout` | Revoke token and clear local auth |
| `milkstraw setup` | Complete onboarding and deploy stacks |
| `milkstraw status` | Check deployment status |
| `milkstraw update` | Update deployed stacks to latest templates |
| `milkstraw org list` | List accessible organizations |
## Global options
| Option | Description |
| ---------------------- | ----------------------------------------- |
| `--org ` | Specify organization ID |
| `--aws-profile ` | Override the AWS named profile |
| `--json` | Output as JSON |
| `--quiet` | Output data only |
| `--markdown` | Output as Markdown |
| `--verbose` | Enable verbose output |
| `--agent` | Agent-safe mode (no prompts, no spinners) |
## Environment variables
| Variable | Description |
| ----------------------- | ------------------------ |
| `MILKSTRAW_ORG` | Default organization ID |
| `MILKSTRAW_AWS_PROFILE` | Default AWS profile name |
## AWS credential resolution
The CLI uses the AWS SDK for JavaScript v3 credential provider chain.
Without `--aws-profile`, credentials are resolved in this order:
1. Environment variables: `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_SESSION_TOKEN`
2. SSO token cache at `~/.aws/sso/cache`
3. Shared credentials file at `~/.aws/credentials` (default profile)
4. Shared config file at `~/.aws/config`
5. ECS container or EC2 instance metadata
With `--aws-profile ` (or `MILKSTRAW_AWS_PROFILE`), the SDK skips environment variables and uses the named profile from `~/.aws/config` and `~/.aws/credentials`.
## Authentication
Tokens are stored at `~/.config/milkstraw-cli/token`. Login uses the OAuth device code flow via your browser.
Run `milkstraw logout` at any time to revoke the token and clear local auth.
# Contact & support
Source: https://docs.milkstraw.ai/contact
Get help with MilkStraw AI and connect with our team.
## Get support
Need help with MilkStraw AI? We're here to assist you.
### Schedule a call
Book a time to chat with our team about your AWS optimization needs.
Talk to us about your specific use case or get help with setup
### Join our community
Connect with other MilkStraw AI users and get quick answers to your questions.
Ask questions, share tips, and stay updated on new features
## Additional resources
Common questions and answers
Real-world optimization examples
Latest updates and insights
Access your MilkStraw AI account
## Follow us
Stay connected with MilkStraw AI on social media:
* [Twitter/X](https://x.com/milkstrawai)
* [LinkedIn](https://www.linkedin.com/company/milkstraw-ai)
* [Instagram](https://www.instagram.com/milkstraw_ai)
## Report an issue
Found a bug or have a feature request? We'd love to hear from you.
Review our [FAQ](/faq) to see if your issue is already addressed
[Schedule a call](https://cal.com/team/milkstraw-ai/chat-with-milkstraw-team) or reach out via [Slack](https://join.slack.com/t/milkstrawaicommunity/shared_invite/zt-2ekgs1m84-yM35uKOHMadyHgwf4LSe4Q)
Include your account information, what you expected to happen, and what actually happened
For urgent issues affecting your AWS billing or commitments, please schedule a call immediately.
# Dashboard overview
Source: https://docs.milkstraw.ai/dashboard-overview
See savings potential and track costs on the organization level across regions.
## Dashboard overview
Our dashboard gives you an immediate view of your current spend and where you could save tomorrow. It is divided into three sections:
* **Summary cards**
* **Month to date cost**
* **Historical cost**
### Summary cards
Show your accounts summary with estimated savings MilkStraw AI can unlock for you.
### Month to date cost
Your running AWS bill for the month with a day-by-day trend and service breakdown compared to last month.
### Historical cost
Longer-term spend analytics (3–12 months) with period comparisons and service-level insights.
# Enable full access
Source: https://docs.milkstraw.ai/enable-full-access
To enable advanced features in MilkStraw AI, you need to update your AWS IAM policy to grant us the necessary permissions to apply savings on your account.
## Step 1 - Update the IAM policy
* ### Find the MilkStraw AI access role
In the AWS Management Console, go to IAM (Identity and Access Management), then look for the role you created for us.
* ### Edit the existing policy
Find the policy in the role under "permissions" and click on Edit Policy.
* ### Replace policy permissions
In the Policy Editor, switch to the JSON tab. Copy and paste the following JSON to add the required permissions:
```json theme={null}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"application-autoscaling:Describe*",
"autoscaling:Describe*",
"ce:Describe*",
"ce:Get*",
"ce:List*",
"cloudwatch:GetMetricData",
"ec2:Describe*",
"ec2:AcceptReservedInstancesExchangeQuote",
"ec2:CancelReservedInstancesListing",
"ec2:CreateReservedInstancesListing",
"ec2:DeleteQueuedReservedInstances",
"ec2:ModifyReservedInstances",
"ec2:PurchaseHostReservation",
"ec2:PurchaseReservedInstancesOffering",
"rds:Describe*",
"rds:List*",
"rds:PurchaseReservedDbInstancesOffering",
"elasticache:List*",
"elasticache:Describe*",
"elasticache:PurchaseReservedCacheNodesOffering",
"es:Describe*",
"es:List*",
"es:PurchaseReservedInstanceOffering",
"organizations:InviteAccountToOrganization",
"organizations:List*",
"organizations:Describe*",
"pricing:DescribeServices",
"pricing:GetAttributeValues",
"pricing:GetProducts",
"savingsplans:Describe*",
"savingsplans:List*",
"servicequotas:*",
"support:*",
"budgets:*"
],
"Resource": "*"
}
]
}
```
* ### Save and apply
Click Review Policy, then Save Changes to apply the updated permissions.
### Step 2 - Verify changes
Refresh webapp.
### Additional resources
AWS IAM Policies Documentation: [https://docs.aws.amazon.com/IAM/latest/UserGuide/access\_policies.html](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html)
# Examples
Source: https://docs.milkstraw.ai/examples
Case studies from MilkStraw AI customers
Case study
Case study
Case study
Case study
# FAQ
Source: https://docs.milkstraw.ai/faq
MilkStraw AI connects using a secure least-privilege cross-account IAM role that you deploy in your AWS management account or across your organization via CloudFormation. The role includes a unique external ID for verification.
The role has least-privilege permissions to monitor usage and savings coverage across various AWS services. It cannot modify any of your resources or infrastructure.
No, you continue to pay AWS directly for your cloud usage as normal. The MilkStraw AI service fee is separate and based on the savings achieved.
MilkStraw AI adds MilkBoxes when we find savings opportunities and removes them when they're underutilized.
No, MilkStraw AI operates with a zero-access architecture to your workloads, VPCs, or data. The connection is for billing and usage monitoring only.
When a milkbox is removed, it undergoes a "factory reset" where all residual configuration and metadata are deleted before the account can be potentially reused for another customer. This ensures data isolation.
Your AWS usage and cost data are monitored hourly by MilkStraw AI.
You can check the covered services page for the full list.
For a single account, the role is deployed directly via a CloudFormation stack. For an AWS Organization, a CloudFormation StackSet wrapper is used to deploy the same role to all member accounts in the organization via StackSets.
Our fee is calculated only from the incremental savings delivered by the MilkBoxes we provide, separate from your existing commitments.
Yes! You can connect multiple AWS Organizations to a single MilkStraw account. To do so:
1. Click the **MilkStraw AI** dropdown in the top-left corner of the app.
2. Select **Switch Organization**, then click **+ Create Organization** at the bottom of the list.
3. Follow the standard organization onboarding flow as described in the Quickstart guide — the process is the same as connecting your first organization.
Once connected, you can view all linked organizations at any time from the **MilkStraw AI** dropdown again.
# Guides overview
Source: https://docs.milkstraw.ai/guides/overview
Runbooks for AWS savings upgrades recommended by MilkStraw AI.
## Savings upgrade guides
Pick the runbook that matches your platform. Every guide includes prerequisites, console walkthroughs, and rollback checkpoints.
Create a new node group with target instance types and migrate workloads safely.
Clone your environment with the new instance types, validate, and swap traffic.
Run blue/green or instance refresh deployments with updated launch templates.
Modify gp2 volumes in place or via CLI to cut storage costs.
# Upgrade EC2 instance types for Amazon EC2 Auto Scaling groups
Source: https://docs.milkstraw.ai/guides/upgrade-asg-instance-types
Step-by-step guide to upgrade EC2 instance types for Amazon EC2 Auto Scaling groups using Blue/Green or Instance Refresh deployments.
This guide walks you through upgrading EC2 instance types for **Amazon EC2 Auto Scaling groups (ASGs)** behind a load balancer.
You've got two main paths:
* **Option 1 (recommended for traffic-facing apps): Blue/Green deployment**
Create a parallel "green" environment with new instance types, validate it, then cut over via DNS.
* **Option 2: Instance Refresh deployment**
Update an existing ASG in place using Instance Refresh and a new Launch Template version.
If you're coming from the MilkStraw AI recommender, you'll plug the recommended instance type(s) into the Launch Template steps below.
***
## Before you start
Make sure:
* You can log in to the AWS Console and have IAM permissions for:
* **EC2**, **Auto Scaling**, **ELB/ALB/NLB**, **IAM**, and **Route 53** (if you manage DNS).
* You understand your app's **ingress**:
* Which load balancer you use: **ALB / NLB / Classic**.
* Which **Target Group(s)** your ASGs register into and what health checks they use.
* Where your **DNS** (e.g., `api.example.com`) points today.
***
## Option 1 · Blue/Green deployment (recommended for traffic-facing apps)
You'll create a **parallel green environment** (new Target Group, Load Balancer, ASG with new instance types), validate it, then update DNS to send traffic to green. Rollback is just switching DNS back.
### Step 1 · Create the parallel (green) environment
#### 1.1 Create a new Target Group (green)
In the **Target Groups** section (EC2 console):
* **Target type**
* Usually `instance` for Auto Scaling Groups.
* **Health checks**
* Protocol/port: match your app (e.g., HTTP:80 or HTTPS:443).
* Path: realistic health endpoint (e.g., `/health`, `/status`).
* Thresholds: set conservative values for prod (e.g., slightly more lenient than default until you're confident).
* **Deregistration delay**
* Typical values: **60–300 seconds**.
* This controls how long in-flight connections are allowed to drain after instance removal.
This is your **green Target Group**.
#### 1.2 Create a new Load Balancer (green)
In the **Load Balancers** section:
* Choose **ALB** (HTTP/HTTPS) or **NLB** (TCP/UDP/HTTPS) to match your app.
* **Subnets**
* Use the same subnets/AZs as your current (blue) environment for high availability.
* **Security group**
* For ALB: mirror rules from the blue ALB; review any source IP allowlists or security boundaries.
* **Listeners & routing**
* Recreate the listeners you have on the blue LB (ports, protocols, SSL certs).
* Forward listener traffic to the **green Target Group** you created above.
* Any path-based routing rules from blue should be mirrored.
This LB + Target Group pair forms the front door of your **green environment**.
#### 1.3 Create or update a Launch Template
You'll now create a new Launch Template version for the new instance type.
1. Go to **EC2 → Launch Templates**.
2. Find your current template used by the blue ASG.
3. Choose **Create new version**.
In the new version:
* **Instance type**
* Set this to the **new instance type**, for example:
```text theme={null}
m6a.xlarge
```
* If you're using **MilkStraw**, plug in the **MilkStraw-recommended instance type**.
* **Root volume size**
* Adjust if your application needs more disk space:
* Typical: **50–100 GiB**.
* More if you store large logs/cache/data on the instance.
* **User data**
* Adjust only if needed (e.g., different bootstrap logic, AMI, or agent configuration).
* Keep it as close as possible to the blue environment to reduce variables.
Save this as **Launch Template Version N+1**.
#### 1.4 Create a new Auto Scaling Group (green)
1. Go to **EC2 → Auto Scaling Groups**.
2. Click **Create Auto Scaling group**.
Configure:
* **Name**
* Use your naming convention, e.g.:
```text theme={null}
production-api-asg-v2
```
* **Launch template**
* Select your existing Launch Template and explicitly choose **Version N+1** (the one with the new instance type).
* **VPC & Subnets**
* Use the **same VPC and subnets** as the current (blue) ASG.
* **Attach to load balancer**
* Attach the new ASG to the **green Target Group** you created in Step 1.1.
* Make sure it's not accidentally pointing to blue's Target Group.
* **Scaling settings**
* Example for prod:
```text theme={null}
Desired capacity: 2
Minimum capacity: 1
Maximum capacity: 10
```
* Align with your expected load and existing scaling policies.
* **Health checks**
* Enable **ELB / Target Group health checks**.
* Set **Health check grace period** realistically (e.g., 60–120s) to allow app startup.
* **(Optional) Instance warm-up**
* Set a value close to your real cold-start time (e.g., app launch + cache warm).
* **(Optional) Mixed instances / Spot**
* Only use **mixed instances** or **Spot** if you understand interruption behavior and scaling policies.
Create the ASG and wait for instances to launch and register as **healthy** in the green Target Group.
#### 1.5 Validate the green environment
Use the **green ALB's DNS name** directly (e.g., `internal-xyz-green-123456.elb.amazonaws.com`) to test.
Validate:
* **Application behavior**
* Run smoke tests and key user flows.
* **Target Group health**
* All expected instances show as **healthy**.
* **Metrics**
* HTTP 5xx rate.
* Latency and throughput.
* CPU/memory (CloudWatch).
* **Network & security**
* TLS certificates and ciphers (if HTTPS).
* Redirects (HTTP → HTTPS, domain redirects).
* WAF rules (if present).
* Access logs, if configured.
Only proceed once the green environment is stable and looks production-ready.
***
### Step 2 · DNS preparations
You'll cut over by changing DNS to point to the **green ALB**.
1. In **Route 53** (or your DNS provider):
* Find the public record, for example `api.example.com`.
* Lower the **TTL** to **60–300 seconds**.
* Do this at least **15–30 minutes before** the cutover so cached entries expire quickly.
2. If you front the ALB with **CloudFront or another CDN**:
* Plan to update the **Origin** or **CNAME** there as well.
* Allow for CDN cache and DNS TTLs in your timing.
***
### Step 3 · DNS cutover to green
Once validation is complete and TTLs are lowered:
1. Update the **DNS CNAME** for your public hostname (e.g., `api.example.com`) to point to the **green ALB's DNS name**.
2. Wait a few TTLs for propagation.
3. Confirm traffic is hitting green:
* Check green Target Group request counts.
* Compare logs and metrics against blue's previous baseline.
**Rollback** is simply:
* Change the CNAME back to the **blue ALB**.
* Wait for TTL to expire.
* Confirm traffic is back on blue.
Keep the blue environment running for a **bake period** so you can easily revert if needed.
***
## Option 2 · Instance Refresh deployment (in-place ASG rollout)
If you don't want to create a second ASG and LB, you can use **Instance Refresh** to roll the existing ASG to a new instance type by updating the Launch Template version.
This is often suitable for:
* Worker fleets.
* Internal services.
* Apps where a controlled, in-place rollout is acceptable.
This has more risk than Blue/Green because you're modifying the production environment directly, but Instance Refresh with high min-healthy-percentage can still be quite safe.
### Step 1 · Prepare a new Launch Template version
Just like in Option 1:
1. Go to **EC2 → Launch Templates**.
2. Find the template used by your **existing ASG**.
3. **Create new version**:
* Set **Instance type** to the new value (e.g., `m6a.xlarge`).
* Adjust **root volume size** and **user data** if needed.
4. Save as **Version N+1**.
Update your ASG to **use Launch Template Version N+1** as its default (in the ASG settings).
### Step 2 · Start Instance Refresh
1. In **Auto Scaling Groups**, select the ASG.
2. Choose **Instance refresh** → **Start instance refresh**.
Configure:
* **Min healthy percentage**
* Example: **90–100%** for a cautious rollout.
* This means the ASG will ensure 90–100% of the desired capacity stays healthy during the refresh.
* Lower only if your app can handle reduced capacity during rotation.
* **Warm-up time**
* Use your app's realistic startup time + load balancer health check grace period.
* Example: **120 seconds** or more for heavier apps.
* **(Optional) Skip matching**
* Enable this if you want **all instances replaced**, even those that already match the new template.
* Leave it off if you only want to replace instances that don't match the new config.
Start the refresh.
### Step 3 · Monitor and validate
While Instance Refresh runs:
* Monitor:
* ASG health status.
* Load balancer Target Group health.
* Application errors and latency.
* Capacity and scaling alarms.
If issues appear:
* You can **Cancel instance refresh**.
* Any instances already replaced remain, but the ASG stops further replacements.
* If needed, revert the ASG back to the previous Launch Template version and plan a new rollout.
Once the refresh completes:
* Confirm **all instances** are running the new instance type.
* Run smoke tests and verify that error rates and performance look good.
***
## Extra resources
* **Auto Scaling Instance Refresh** — [AWS Instance Refresh documentation](https://docs.aws.amazon.com/autoscaling/ec2/userguide/asg-instance-refresh.html)
* **Launch Templates** — [AWS Launch Template documentation](https://docs.aws.amazon.com/autoscaling/ec2/userguide/launch-templates.html)
* **Blue/Green deployments on AWS** — [AWS Blue/Green deployment whitepaper](https://docs.aws.amazon.com/whitepapers/latest/blue-green-deployments/welcome.html)
* **Target Groups for ALB/NLB** — [Elastic Load Balancing Target Groups](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-target-groups.html)
# Upgrade Amazon EBS volumes from gp2 to gp3
Source: https://docs.milkstraw.ai/guides/upgrade-ebs-gp2-to-gp3
Step-by-step guide to upgrade Amazon EBS volumes from gp2 to gp3 using the AWS Console or CLI.
This guide walks you through upgrading Amazon EBS volumes from **gp2** to **gp3**. The upgrade is done in-place with no downtime required.
gp3 volumes are up to 20% cheaper than gp2 and offer better baseline performance (3,000 IOPS and 125 MB/s throughput included).
***
## Before you start
Make sure:
* You can log in to the AWS Console and have IAM permissions for **EC2**.
* You have the **AWS CLI** installed and configured (for CLI method).
* The volume is in the **available** or **in-use** state.
* You haven't modified the volume in the last 6 hours (AWS allows one modification per volume every 6 hours).
***
## Option 1 · AWS Console
1. Open the **EC2 console**.
2. Go to **Elastic Block Store** → **Volumes**.
3. Select the **gp2 volume** you want to upgrade.
4. Click **Actions** → **Modify volume**.
5. Change **Volume type** from `gp2` to `gp3`.
6. (Optional) Adjust **IOPS** and **Throughput** if needed:
* Default: **3,000 IOPS** and **125 MB/s** (included in the base price).
* Increase only if your workload requires more.
7. Click **Modify** and confirm.
The modification runs in the background. Monitor the **State** column until it shows `completed`.
***
## Option 2 · AWS CLI
### Upgrade a single volume
```bash theme={null}
aws ec2 modify-volume --volume-type gp3 --volume-id vol-0123456789abcdef0
```
### Upgrade all gp2 volumes at once
```bash theme={null}
aws ec2 describe-volumes \
--filters Name=volume-type,Values=gp2 \
--query 'Volumes[*].VolumeId' \
--output text | xargs -n 1 aws ec2 modify-volume --volume-type gp3 --volume-id
```
### Check modification status
```bash theme={null}
aws ec2 describe-volumes-modifications --volume-id vol-0123456789abcdef0
```
***
## Extra resources
* **EBS volume types** — [Amazon EBS volume types](https://docs.aws.amazon.com/ebs/latest/userguide/ebs-volume-types.html)
* **Modify an EBS volume** — [Request modifications to your EBS volumes](https://docs.aws.amazon.com/ebs/latest/userguide/requesting-ebs-volume-modifications.html)
* **gp3 pricing** — [Amazon EBS pricing](https://aws.amazon.com/ebs/pricing/)
# Upgrade EC2 instance types for Amazon EKS
Source: https://docs.milkstraw.ai/guides/upgrade-eks-instance-types
Step-by-step guide to upgrade EC2 instance types for an existing Amazon EKS cluster.
This guide walks you through upgrading EC2 instance types for an existing Amazon EKS cluster by creating a new managed node group, migrating workloads, and then tearing down the old group.
If you're coming from the MilkStraw AI recommender, you'll plug the recommended instance types into the steps below.
***
## Before you start
Make sure:
* You can log in to the AWS Console and have IAM permissions for **EKS**, **EC2**, and **IAM**.
* `kubectl` is installed and configured for the correct cluster:
```bash theme={null}
aws eks update-kubeconfig --region --name
```
* You know whether your workloads require:
* GPU nodes, and/or
* Spot capacity (only use Spot if you understand interruption behavior and have workloads that tolerate it).
* If you use **public subnets** for nodes:
* `MapPublicIpOnLaunch=true` is set.
* Subnets have the standard EKS tags:
* `kubernetes.io/cluster/ = shared`
* `kubernetes.io/role/elb = 1` (for public subnets).
***
## Step 1 · Create a new node group with the target instance type
You'll first add a new node group using the new instance type(s). This lets you migrate workloads safely before deleting the old group.
### 1.1 Open the EKS cluster and add a node group
In the AWS Console:
1. Go to **Amazon EKS** → **Clusters**.
2. Select your cluster.
3. Open the **Compute** tab.
4. Choose **Add node group**.
### 1.2 Basics
Configure:
* **Name**
Use something descriptive and versioned, for example:
```text theme={null}
production-core-ng-v2
```
A good pattern is: `env-project-function-version`.
* **Node IAM role**
Choose the role with standard EKS worker node permissions, or create one if needed.
* **(Optional) Launch template**
Use a launch template if you need:
* Custom AMI or user data
* Specific disk types / encryption settings
* Extra EC2-level configuration
* **(Optional) Labels / Taints / Tags**
* Example label:
```text theme={null}
nodepool = new
```
* Example taint (useful for GPU-only workloads or to keep pods off until you're ready):
```text theme={null}
key = no-scheduling
effect = NoSchedule
```
### 1.3 Compute configuration
Under **Compute configuration**:
* **AMI type**
* General-purpose: **Amazon Linux 2** or **AL2023**.
AL2023 is newer and has different defaults; validate compatibility for your workloads.
* GPU: **Amazon Linux 2 GPU** (or a Bottlerocket GPU variant if you already use Bottlerocket).
* **Capacity type**
* **On-Demand** for predictable capacity.
* **Spot** only if your workloads tolerate interruption and you have a proper Spot strategy.
* **Instance types**
* Example general-purpose instance:
```text theme={null}
m6a.xlarge
```
* If you're using **MilkStraw AI recommender**, set this to the **recommended instance type(s)** from your report.
* **Disk size**
* For most applications: **50–100 GiB** root volume is sufficient.
* Increase if pods make heavy use of `emptyDir` volumes or local caching.
* **Scaling**
* Set **Desired**, **Min**, and **Max**.
For example:
```text theme={null}
Desired capacity: 2
Min size: 1
Max size: 10
```
* If you run Cluster Autoscaler, ensure these values work with your expected scale range.
### 1.4 Networking
Under **Networking**:
* **Subnets**
* Select the subnets where you want worker nodes to live.
* For public subnets, confirm:
* `MapPublicIpOnLaunch=true`
* Proper EKS tags as mentioned above.
* **(Optional) SSH key pair**
* Add an SSH key only if you need direct SSH access to nodes.
### 1.5 Create and verify node readiness
Create the node group and wait for nodes to join the cluster.
Watch nodes until they are `Ready`:
```bash theme={null}
kubectl get nodes --watch
```
#### GPU clusters
If these are **GPU nodes**, install the NVIDIA device plugin after the nodes are `Ready`.
In the NVIDIA `k8s-device-plugin` GitHub repo, locate the latest **DaemonSet** manifest and apply it:
```bash theme={null}
kubectl apply -f
```
***
## Step 2 · Move workloads to the new node group
You now have both old and new node groups attached to the cluster. The goal is to:
1. Stop new pods from landing on the old nodes.
2. Let the scheduler and Cluster Autoscaler move workloads to the new group.
3. Drain and empty the old nodes.
The examples below assume you're using **Managed Node Groups**.
### 2.1 Taint the old node group (EKS-managed taint)
First, add a taint to the old node group to prevent **new pods** from scheduling on it while existing pods continue running:
```bash theme={null}
aws eks update-nodegroup-config \
--cluster-name \
--nodegroup-name \
--taints addOrUpdateTaints='[{key=no-scheduling,effect=NO_SCHEDULE}]'
```
### 2.2 Cordon the old nodes
Cordoning marks nodes as unschedulable at the Kubernetes level:
```bash theme={null}
kubectl get nodes -l eks.amazonaws.com/nodegroup= -o name \
| xargs -n1 kubectl cordon
```
New pods will no longer be placed on these nodes.
### 2.3 Drain the old nodes
Drain nodes to evict pods safely and move them to the new node group:
```bash theme={null}
kubectl drain \
--ignore-daemonsets \
--delete-emptydir-data \
--grace-period=60 \
--timeout=10m
```
Flags:
* `--ignore-daemonsets`
DaemonSet pods are not evicted by `drain`. They are terminated when the node is deleted.
* `--delete-emptydir-data`
Only use if pods don't rely on data inside `emptyDir` volumes, as that data will be lost.
Additional considerations:
* **PodDisruptionBudgets (PDBs)**
If PDBs are strict, `kubectl drain` may block until disruptions are allowed.
You might temporarily increase `maxUnavailable` for smoother migrations.
* **Unmanaged pods**
If some pods are not controlled by a Deployment, ReplicaSet, or DaemonSet, you may need `--force`. Use this carefully and only if you understand the impact.
### 2.4 Watch workloads reschedule
Monitor pods as they are rescheduled onto the new node group:
```bash theme={null}
kubectl get pods -A -o wide --watch
```
If you set a label on the **new** node group (for example `nodepool=new`), make sure workloads can land there:
* Add a matching `nodeSelector` or node affinity to workloads that must move:
```yaml theme={null}
spec:
template:
spec:
nodeSelector:
nodepool: new
```
* Or skip tainting the new group so the scheduler naturally prefers it once old nodes are cordoned and drained.
If you run **Cluster Autoscaler**, it should automatically scale the new node group to fit the evicted pods.
### 2.5 Validate migration
Confirm the migration before deleting anything:
* All pods are `Running` and scheduled on **new nodes**:
```bash theme={null}
kubectl get pods -A -o wide
```
* All nodes in the **old** node group:
* Are `SchedulingDisabled`, and
* Either have no non-DaemonSet pods left or are fully drained.
***
## Step 3 · Remove the old node group
Once you are confident workloads are stable on the new instance types, remove the old group.
In the AWS Console:
1. Go to **Amazon EKS** → **Clusters** → select your cluster.
2. Open the **Compute** tab → **Node groups**.
3. Select the **old node group**.
4. Click **Delete**.
5. Type the node group name to confirm, then **Delete**.
If you are using **Cluster Autoscaler**:
* Make sure the old node group is no longer in its configuration, **or**
* Temporarily set its Desired/Min capacity to `0` before you delete it.
***
## Rollback · Move workloads back to the old node group
If something goes wrong after migration (for example, performance or compatibility issues), you can quickly roll workloads back to the old node group.
The high-level flow:
1. Scale the old group back up.
2. Pause scheduling onto the new group.
3. Re-enable scheduling on the old group.
4. Drain the new nodes so pods move back.
You keep the new group around until you decide next steps.
### Scale the old node group
In EC2 or EKS:
* Set the old node group's or Auto Scaling Group's **Desired/Min/Max** back to healthy values.
Example (Auto Scaling Group via console or CLI):
* Desired: previous steady-state value.
* Min: match Desired.
* Max: your upper bound.
### Pause scheduling on the new group
Add a taint to the **new** node group:
```bash theme={null}
aws eks update-nodegroup-config \
--cluster-name \
--nodegroup-name \
--taints addOrUpdateTaints='[{key=no-scheduling,effect=NO_SCHEDULE}]'
```
Cordon all new nodes:
```bash theme={null}
kubectl get nodes -l eks.amazonaws.com/nodegroup= -o name \
| xargs -n1 kubectl cordon
```
### Re-enable scheduling on the old group
Remove the taint from the **old** node group:
```bash theme={null}
aws eks update-nodegroup-config \
--cluster-name \
--nodegroup-name \
--taints removeTaints='[{key=no-scheduling,effect=NO_SCHEDULE}]'
```
Uncordon old nodes so they accept new pods again:
```bash theme={null}
kubectl get nodes -l eks.amazonaws.com/nodegroup= -o name \
| xargs -n1 kubectl uncordon
```
### Drain the new nodes
Now drain the **new** nodes so pods move back to the old group:
```bash theme={null}
kubectl drain \
--ignore-daemonsets \
--delete-emptydir-data \
--grace-period=60 \
--timeout=10m
```
Watch pods move back:
```bash theme={null}
kubectl get pods -A -o wide --watch
```
Once you stabilize and understand the root cause, you can try another migration with updated instance types or configuration.
***
## Extra resources
* **Install kubectl** — [Kubernetes documentation: Install and Set Up kubectl](https://kubernetes.io/docs/tasks/tools/)
* **NVIDIA device plugin for Kubernetes** — [NVIDIA/k8s-device-plugin on GitHub](https://github.com/NVIDIA/k8s-device-plugin)
* **VPC and subnet requirements for EKS** — [Amazon EKS VPC and subnet requirements](https://docs.aws.amazon.com/eks/latest/userguide/network_reqs.html)
# Upgrade EC2 instance types for AWS Elastic Beanstalk
Source: https://docs.milkstraw.ai/guides/upgrade-elastic-beanstalk-instance-types
Step-by-step guide to upgrade EC2 instance types for existing AWS Elastic Beanstalk environments using Blue/Green or Rolling deployments.
This guide walks you through upgrading EC2 instance types for existing AWS Elastic Beanstalk (EB) environments, with two main paths:
* **Option 1 (recommended): Blue/Green deployment**
Create a parallel environment with the new instance type, validate it, then swap traffic.
* **Option 2: Rolling / Immutable deployment**
Change instance types in place using EB's deployment policies.
If you're coming from the MilkStraw AI recommender, you'll plug the recommended instance type(s) into the steps below.
***
## Before you start
Make sure:
* You can log in to the AWS Console and have IAM permissions for:
* **Elastic Beanstalk**, **EC2**, **Auto Scaling**, **Elastic Load Balancing**, **IAM**, and **Route 53** (if you manage DNS there).
* You know your current **Elastic Beanstalk platform**, for example:
* Docker, Node.js, .NET, Python, Java, etc.
* You know whether your app requires **GPU instances**.
* Your current EB environment:
* Is **healthy (green)**.
* Can have the **same application version** deployed to a new environment (you still have the artifact and configuration).
***
## Option 1 · Blue/Green deployment (recommended)
Safest path: clone your existing environment with a new instance type (green), validate it, then swap traffic from the old one (blue). This gives:
* Zero or very low downtime.
* Instant, simple rollback by swapping traffic back.
### Step 1 · Create a parallel environment (Green)
1. Open the **Elastic Beanstalk console**.
2. Go to **Applications** → choose your app → **Environments**.
3. Select your current **production environment** (this is your **blue** env).
4. Click **Actions** → **Clone environment**.
#### 1.1 Basics
In the clone wizard:
* **Environment name**
Use your own naming convention, for example:
```text theme={null}
production-core-env-v2
```
* **Domain (CNAME)**
* Let AWS auto-generate a CNAME (recommended; you'll swap later), **or**
* Choose a distinct name like `prod-core-v2.myapp.elasticbeanstalk.com`.
* **Application version**
* Select the **same version** currently running in the blue environment.
#### 1.2 Capacity & instances
In the capacity / instances settings:
* **Instance type**
* Set to the **new instance type**, for example:
```text theme={null}
m6a.xlarge
```
* If you're using **MilkStraw**, put the **MilkStraw-recommended instance type** here.
* **Scaling**
* For load-balanced environments, something like:
```text theme={null}
Desired capacity: 2
Min: 1
Max: 10
```
* For single-instance environments:
```text theme={null}
Desired capacity: 1
Min: 1
Max: 1
```
* **Root volume size**
* Increase if your app needs more disk (for logs, temp files, `emptyDir` usage from containers, etc.).
* Typical values: **50–100 GiB** for most web apps.
* **(Optional) Spot instances**
* Only enable Spot or mixed capacity if you're comfortable with interruption handling and understand how EB manages mixed instances.
* **(Optional) GPU**
* Only choose GPU instance types if:
* Your platform / AMI supports GPU, and
* You have drivers installed (via `.ebextensions`, Docker image, or a custom AMI).
#### 1.3 Network
Use the same network setup as your current (blue) environment:
* **VPC and subnets**
* Select the **same VPC**, subnets, and availability zones.
* **Security groups**
* Use the same instance and load balancer security groups as the blue environment.
* **Load balancer**
* Keep the same type (ALB/NLB/Classic) and listener ports as the current environment.
This keeps behavior consistent so you're only changing **instance type**, not overall topology.
#### 1.4 Software & environment variables
Mirror the configuration from your blue environment:
* Environment variables and secrets.
* Health check path / URL.
* Timeouts and connection draining / deregistration delay on the load balancer.
* Any platform-specific options (Node, .NET, Docker, etc.).
Then:
* **Create the environment** and wait for health to become **Green**.
While it's coming up, you can also monitor:
* Instance registration in the **target group** (if using ALB/NLB).
* Health checks on instances.
#### 1.5 Validate the new environment
Before switching traffic, validate that the green environment behaves like production:
* Open the **new environment URL** (its EB CNAME) and run **smoke tests**:
* Basic page load.
* Login / key user flows.
* Check **logs and metrics**:
* HTTP 4xx/5xx.
* Latency.
* CPU/memory (CloudWatch).
* If you depend on external services:
* Databases (RDS, Aurora, etc.)
* Queues, caches, other APIs
* Confirm connectivity and correct IAM roles.
Only move to the next step once the new environment looks healthy and stable.
***
### Step 2 · Shift traffic to the new environment
Goal: move users to the environment running the **new instance type** while keeping the old one for fast rollback.
#### 2.1 Lower DNS TTL (if using a custom domain)
If you use a custom domain like `app.example.com`:
* Typically it's a **CNAME** to the EB CNAME.
* In Route 53 (or your DNS provider), **lower the TTL** on that CNAME to something like **60–300 seconds**, ideally **15–30 minutes before** the swap.
This makes it faster for clients to pick up the new EB CNAME after the swap.
#### 2.2 Swap CNAMEs in Elastic Beanstalk
In the EB console:
1. Select the **new (green)** environment.
2. Go to **Actions** → **Swap environment URLs**.
3. Choose the **old (blue)** environment as the swap partner.
4. Confirm the swap.
EB will swap the CNAMEs so that:
* Your **custom DNS**, if pointing to EB, now resolves to the **green environment**.
* The old environment gets the "other" CNAME, but stays running, untouched.
**Rollback** is the same action in reverse: swap URLs again to send traffic back to blue.
#### 2.3 Post-swap checks
After the swap:
* Watch:
* ALB/NLB **Target Group** healthy hosts.
* HTTP 5xx rate and latency.
* Application logs and error tracking.
* If you see:
* Error spikes, high latency, or health turning yellow/red,
* Swap back **immediately** and investigate:
* Instance sizing (CPU, memory).
* Network / security group differences.
* Any configuration drift.
***
### Step 3 · Decommission or park the old environment
Don't delete the blue environment immediately. Instead:
1. Keep it around for a **bake period** (for example, 24–48 hours).
2. During that time, monitor:
* Error rates.
* Performance.
* Any unusual behavior in the new environment.
Once you're confident:
You can either:
* **Terminate the old environment**
* This removes its Auto Scaling Group, instances, and load balancer.
**or**
* **Scale to zero (for load-balanced envs)**
* Set **Desired** and **Min** to `0`.
* This stops instances but preserves configuration so you can scale it back up temporarily if needed.
Finally, clean up:
* Old application versions you no longer need.
* Unused target groups.
* Any custom launch templates, if you created them for the old environment.
***
## Option 2 · Rolling / Immutable deployment (in-place update)
This option keeps the same environment but instructs EB to roll out the new instance type in batches. It's often useful for:
* Worker environments.
* Internal services where short partial capacity reduction is acceptable.
* Teams that prefer fewer separate environments.
This has more risk than Blue/Green because you're modifying the production environment directly, but Immutable deployments can still be quite safe.
### Step 1 · Change the instance type
In the EB console:
1. Go to **Environments** → select your environment.
2. Open the **Configuration** page.
3. Under **Instances**:
* Set **Instance type** to the new instance type (for example, `m6a.xlarge`).
* If using MilkStraw, paste in the **recommended instance type**.
### Step 2 · Configure deployment policy
Still in Configuration:
1. Go to **Rolling updates and deployments** (or similar, depending on your EB console version).
2. Choose one of:
* **Immutable** (preferred where possible)
* EB creates a **temporary Auto Scaling Group** with the new instance type.
* New instances are registered with the load balancer.
* Once healthy, EB cuts over and then retires the old instances.
* If things go wrong, EB can roll back to the original ASG.
* **Rolling with additional batch**
* EB spins up a **new batch** of instances with the new type **before** terminating old ones.
* Protects capacity during the update.
3. Set a **safe batch size**, for example **25–33%**:
* This controls how much of your capacity is updated at once.
* Make sure remaining capacity can handle your normal traffic.
Apply the changes.
### Step 3 · Monitor and validate
While EB is updating:
* Watch:
* Environment health (should stay green).
* Load balancer target health.
* CPU/memory on new instances.
* 5xx errors and latency.
If health degrades badly or errors spike:
* **Abort** the deployment in the EB console.
* EB will roll back to the previous Auto Scaling Group and instance type.
Once the deployment finishes:
* Run smoke tests.
* Validate key user paths, logs, and metrics.
***
## Extra resources
* **Elastic Beanstalk deployment policies** — [AWS Elastic Beanstalk deployment options](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.deploy-existing-version.html)
* **Blue/Green deployments with Elastic Beanstalk** — [AWS Blue/Green deployment guide](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.CNAMESwap.html)
* **Configuring Auto Scaling for Elastic Beanstalk** — [Auto Scaling configuration](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.managing.as.html)
# How MilkStraw AI works
Source: https://docs.milkstraw.ai/how-milkstraw-ai-works
Learn how MilkStraw AI optimizes your AWS cloud spend.
## Intro to MilkStraw AI
MilkStraw AI is designed to make savings on AWS simple, flexible, and risk-free. We continuously monitor your cloud usage, suggest savings, and apply discounts only when you approve.
No lock-in, no downtime, and no access to your code.\
\
With MilkStraw AI you get the discounts of 3-years Savings Plans and Reserved Instances, but you’re never locked in.
## How it works
Milkstraw AI continuously monitors your AWS on-demand capacity and existing contracts.
* **Continuous Monitoring:** We track your AWS usage and contracts in real time.
* **Fluid savings:** When there’s an opportunity to cover your on-demand usage with Fluid savings, we transfer MilkBoxes into your AWS Organization for instant discounts.
* **Dynamic Adjustment:** If your needs change, we remove underutilized MilkBoxes
This dynamic adjustment removes the commitment risk from you, making sure you only benefit from the savings.
## Key benefits
* **Cost Savings**: Enjoy committed-use discounts without the long-term commitment.
* **Flexibility**: Scale resources up or down freely. Savings adjust automatically.
* **No Downtime**: Integration and transfer of MilkBoxes happen seamlessly, so your applications and services keep running without interruption.
* **Zero Access**: We operate with a least-privilege view of your billing data, never your workloads or sensitive information.
## **Next steps**
1. [Connect to AWS ↗](/quickstart) – Set up secure, least-privilege access.
2. [Review Savings Suggestions ↗](/identify-savings) – See where you can save.
3. Approve & Save – Apply discounts with a single click.
## **FAQs & Support**
Have questions? Check our [FAQ ↗](/faq) or [contact support ↗](https://cal.com/jawadshreim/chat-with-milkstraw-ai).
MilkStraw AI is built to help you spend less and build more. Let’s get started!
# How we identify savings?
Source: https://docs.milkstraw.ai/identify-savings
MilkStraw AI monitors your AWS usage to find and apply Fluid savings.
## Monitoring your usage
With a secure, least-privilege cross-account role, MilkStraw AI regularly checks your AWS usage and cost data, including running instances, services, savings coverage, and on-demand spend.
## Identifying opportunities
MilkStraw AI looks for two main scenarios:
* **Uncovered On-Demand usage:** When on-demand usage can be covered by Fluid savings, we flag it as a savings opportunity.
* **Underutilized savings:** If any MilkBoxes in your organization aren’t being fully used, we mark them for removal.
## Triggering actions
When an opportunity is found, MilkStraw AI automatically:
* Transfers MilkBoxes to your organization to unlock savings.
* Removes underutilized MilkBoxes to prevent waste.
This dynamic, ongoing process ensures your savings always match your usage, maximizing efficiency with zero guesswork.
# Overview
Source: https://docs.milkstraw.ai/overview
MilkStraw AI is a cloud cost optimization platform.
## MilkStraw AI documentation
Learn how to get MilkStraw AI set up.
Get your account set up in a few mins
Monitoring your usage to find savings opportunities
performance-based billing
All AWS services that support commitment-based savings.
## Resources
Extra questions and examples.
Get your questions answered
Check out our showcase of our favorite customers
# Required Permissions
Source: https://docs.milkstraw.ai/permissions
Breakdown of the cross-account IAM role MilkStraw AI uses and the least-privilege permissions it requires.
## Why we need permissions
To deliver savings, we analyse your AWS usage and apply commitment-based discounts on your behalf. This is done through a **cross-account IAM role** that you create in your payer account with our CloudFormation template. The role follows the **principle of least privilege**.
We only receive the access strictly necessary to:
1. Read cost and usage data.
2. Detect optimisation opportunities.
3. Manage the lifecycle of our MilkBoxes.
***
## Monitoring (Read-Only)
These permissions let MilkStraw AI monitor your spend and resources without touching your workloads.
**Cost management**
```json theme={null}
ce:Describe*
ce:Get*
ce:List*
ce:StartSavingsPlansPurchaseRecommendationGeneration
pricing:DescribeServices
pricing:GetAttributeValues
pricing:GetProducts
savingsplans:Describe*
savingsplans:List*
cloudwatch:GetMetricData
cloudwatch:GetMetricStatistics
cloudwatch:ListMetrics
```
**Compute & DataStores**
```json theme={null}
application-autoscaling:Describe*
autoscaling:Describe*
ec2:Describe*
ecs:Describe*
ecs:List*
eks:Describe*
eks:List*
elasticache:Describe*
elasticache:List*
es:Describe*
es:List*
memorydb:Describe*
rds:Describe*
rds:List*
redshift:Describe*
redshift:Get*
redshift:List*
sagemaker:Describe*
sagemaker:Get*
sagemaker:List*
```
> We have a deny policy for Redshift, to block access to cluster credentials:
>
> ```json theme={null}
> redshift:GetClusterCredentials
> redshift:GetClusterCredentialsWithIAM
> redshift:DescribeAuthenticationProfiles
> ```
**Storage & Containers**
```json theme={null}
s3:GetBucket*
s3:GetEncryptionConfiguration
s3:GetLifecycleConfiguration
s3:GetStorageLens*
s3:ListAllMyBuckets
s3:ListBucket*
s3:ListStorageLensConfigurations
ecr:BatchGetImage
ecr:Describe*
ecr:GetLifecyclePolicy
ecr:GetRegistryPolicy
ecr:GetRepositoryPolicy
ecr:List*
```
> We only read bucket and repository metadata (configuration, lifecycle policies, Storage Lens metrics). Never the objects stored inside your buckets.
**Networking & Load Balancing**
```json theme={null}
elasticloadbalancing:Describe*
network-firewall:Describe*
network-firewall:List*
```
**Logs**
```json theme={null}
logs:DescribeLogGroups
```
> We only read log group metadata (retention settings, stored bytes). Never the log events themselves.
**AWS optimisation tools**
These permissions let us read recommendations that AWS itself generates for your account.
```json theme={null}
compute-optimizer:Describe*
compute-optimizer:Get*
support:DescribeTrustedAdvisor*
support:RefreshTrustedAdvisorCheck
trustedadvisor:Describe*
trustedadvisor:Get*
trustedadvisor:List*
```
***
## Enabling AWS cost tools
These actions are required to enable AWS Compute Optimizer and S3 Storage Lens for your account, so their recommendations can feed into our analysis.
```json theme={null}
compute-optimizer:UpdateEnrollmentStatus
s3:PutStorageLensConfiguration
organizations:EnableAWSServiceAccess
iam:CreateServiceLinkedRole
```
> `iam:CreateServiceLinkedRole` and `organizations:EnableAWSServiceAccess` are locked down with IAM conditions so they can only be used for the Compute Optimizer, S3 Storage Lens, and AWS Organizations service-linked roles, nothing else.
***
## Integration management
These actions are required to integrate MilkBox accounts into your AWS Organization.
```json theme={null}
organizations:CreateOrganization
organizations:Describe*
organizations:InviteAccountToOrganization
organizations:List*
```
> We use `organizations:CreateOrganization` when the organization is not already created, this is a one-time operation for small standalone accounts, if you already have an organization, this api cant be executed against your account, then `organizations:InviteAccountToOrganization` is used to invite MilkBox accounts to your organization.
***
## Cost monitoring and visibility
These permissions are required to read resource tags for cost allocation and visibility per resource.
**Tagging**
```json theme={null}
tag:DescribeReportCreation
tag:Get*
tag:StartReportCreation
```
***
## Review the full policy
You can always inspect the exact IAM policy generated by our CloudFormation stack:
[View the JSON policy ↗](https://s3.eu-west-1.amazonaws.com/statics.milkstraw.ai/cloudformation_templates/cross_account_role.json)
Feel free to reach out if you have any questions about security or least-privilege access.
# Quickstart
Source: https://docs.milkstraw.ai/quickstart
Securely connect your AWS account to analyze usage and identify cost-saving opportunities.
**Prerequisites**
* An active [MilkStraw AI](https://app.milkstraw.ai) account
* AWS account with permissions to create IAM roles and policies on Payer account
* Access to the AWS Management Console
This connection is established securely using a least-privilege cross-account IAM role, which you deploy in your AWS environment via CloudFormation.
## Connecting a single AWS account
In the Milkstraw AI dashboard, start the connection process. Enter your company name and AWS Payer Account ID.
We’ll generate a CloudFormation [template](https://statics.milkstraw.ai/cloudformation_templates/cross_account_role.json) for you. Launch it in your AWS Console to deploy a least-privilege cross-account IAM role with a unique external ID.
In the AWS CloudFormation console, acknowledge the required capabilities, and execute the stack. This action creates a secure cross-account IAM role in your account with a unique external ID and the necessary least-privilege permissions for monitoring.
Once the stack is `CREATE_COMPLETE`, return to MilkStraw AI and click “Verify.” We’ll check access to the necessary AWS services.
## Connecting an AWS organization
If you are using AWS Organizations with multiple linked accounts, you will need to onboard your entire organization after connecting your Payer Account.
Complete the steps above for your Payer Account.
When prompted, deploy the StackSet wrapper template in AWS CloudFormation.
The pre-filled StackSet wrapper [template](https://statics.milkstraw.ai/cloudformation_templates/cross_account_role_stackset_wrapper.json) be automatically deployed to every child account in your organization
Once all stacks are `CREATE_COMPLETE`, return to MilkStraw AI and click “Verify” to confirm access for your entire organization.
Once access across all accounts is verified, your AWS Organization is successfully connected to MilkStraw AI.
**What happens next?**
* MilkStraw AI securely monitors your usage using least-privilege permissions.
* We analyze your usage patterns and identify Fluid Savings opportunities.
# Roles
Source: https://docs.milkstraw.ai/roles
Understand the roles you can assign to members of your organization and what each role is allowed to do.
MilkStraw AI uses role-based access control to determine what each member of your organization can see and do. Every member has exactly one role, which is assigned when they are invited and can be changed later by a manager.
## Available roles
Read-only access to organization data. Cannot make changes.
Can act on savings findings and manage technical resources.
Can view and manage billing, payment methods, and coupons.
Can manage organization settings, members, and integrations.
Full control of the organization, including deletion and ownership transfer. Each organization has exactly one owner.
## Permissions by role
Roles are cumulative in scope but distinct in purpose. Each role below lists what its members can do.
* View organization data
* View organization data
* Act on savings findings
* Activate savings
* View organization data
* View billing and invoices
* Update payment method
* Redeem coupons
* View organization data
* Act on savings findings
* Activate savings
* View billing and invoices
* Update payment method
* Redeem coupons
* Manage members and invitations
* Manage integrations
* Update organization settings
* All Admin permissions
* Transfer ownership
* Delete organization
## Ownership
Every organization has exactly one owner. Only the owner can transfer ownership to another member or delete the organization. Ownership is transferred through an atomic flow, an admin cannot demote the owner or leave the organization without an owner.
## Changing a member's role
Admins and owners can change roles from the members page in your organization settings. To change roles:
1. Open your organization settings.
2. Go to **Members**.
3. Select a member and choose a new role from the dropdown.
A member can always remove their own membership from an organization. Only admins and owners can remove other members.
## Related
* [Billing](/billing)
* [Required Permissions](/permissions) — the AWS IAM permissions MilkStraw AI uses in your cloud account.
# Security
Source: https://docs.milkstraw.ai/security
Learn about our security-first approach to optimizing your AWS cloud spend.
MilkStraw AI is designed with security as a core principle, ensuring your workloads and data remain isolated and untouched. Our approach is built on isolation, least privilege, and rigorous reset-before-reuse practices.
## Integration security
Our integration with your AWS environment relies on a secure cross-account IAM role that you deploy.
* **Cross-Account IAM Role**: Resides within your AWS management account.
* **Unique External ID**: The role's trust policy includes a unique external ID known only to Milkstraw\.ai, preventing confused-deputy attacks and verifying the call origin.
* **Temporary Credentials**: We utilize temporary AWS STS credentials for each API call, avoiding the use of long-lived access keys.
## Transfer security
Onboarding and offboarding MilkBoxes (accounts with savings) are managed through secure, controlled steps.
* **Invite-Only**: You initiate the transfer by creating an AWS Organizations invite for each milkbox account we provide.
* **Single-Action Acceptance**: Milkstraw AI accepts the invite from within the milkbox account; no other permissions are exchanged.
* **Revocable**: You can instantly detach a milkbox by removing the invite in AWS Organizations.
## Least-privilege policy
MilkStraw AI operates with minimal necessary permissions to perform its function.
* **Least-privilege Role**: We use a single least-privilege IAM role.
* **No Resource Modification**: This role can only monitor your usage and cost data; it cannot start, stop, or modify any of your resources.
* **Limited Scope**: The scope is limited strictly to the AWS APIs required for cost coverage analysis.
## MilkBoxes isolated by design
MilkBoxes are engineered to be entirely separate from your existing environment.
* **Zero-Access Architecture**: They operate outside your VPCs, IAM roles, and networks.
* **No Data Paths**: There are no data paths between MilkBoxes and your workloads—only billing linkage.
* **One-Way Isolation**: You also have no access to MilkBoxes, which prevents potential lateral movement risks.
## Reset-before-reuse
When a milkbox is no longer needed in your organization, it undergoes a thorough reset process.
* When your on-demand capacity or savings needs change, we remove the milkbox from your organization.
* The account is subjected to a "factory reset," deleting all residual configuration and metadata.
* An account is only eligible to join another customer's organization after this complete reset.
This process ensures that no information or configuration from your environment is ever carried over or shared with subsequent users of the milkbox account.
## Underlying safeguards
Our technical operations incorporate standard security best practices.
* **Encryption**: All control-plane communication with AWS over the cross-account role uses TLS 1.2 or higher encryption.
* **Auditability**: Every action performed by Milkstraw AI is logged in your AWS CloudTrail for full auditability.
* **Best Practices**: Our controls are designed in alignment with AWS Well-Architected principles and CIS benchmarks.
## Billing security
We use Stripe as our payment gateway and we don't store any payment details in our platform as we also delegate this to Stripe.
# Supported services
Source: https://docs.milkstraw.ai/supported-services
AWS services MilkStraw AI optimizes with commitments across compute and databases.
We optimize commitment coverage (Savings Plans and Reserved Instances) across compute and database services. If AWS adds more eligible services, we’ll include them automatically.
## Compute
Savings Plans and Reserved Instances applied across instance families and regions where eligible.
Savings Plans applied to Fargate tasks.
Savings Plans applied to Lambda invocations.
Savings Plans applied to SageMaker where available.
## Databases
Savings Plans and Reserved Instances applied to RDS engines and Aurora clusters.
Savings Plans applied to DocumentDB where available.
Savings Plans and Reserved Instances applied to ElastiCache (Redis and Memcached) where available.
Savings Plans applied to MemoryDB where available.
Savings Plans and Reserved Instances applied to OpenSearch where available.
Reserved Instances applied to Redshift clusters.
Savings Plans applied to Neptune where available.
Need a different service? Tell us and we’ll prioritize adding support.
# Troubleshooting
Source: https://docs.milkstraw.ai/troubleshooting
Common issues and solutions when using MilkStraw AI.
This guide covers common issues you might encounter and how to resolve them.
## Connection issues
### IAM role connection failed
**Cause**: The IAM role may not have the correct trust relationship or permissions.
**Solution**:
1. Verify the CloudFormation stack deployed successfully
2. Check that the trust policy includes MilkStraw AI's account ID
3. Ensure the role has the required least-privilege permissions
4. Try reconnecting in the dashboard
See [Permissions](/permissions) for required IAM policies.
**Cause**: Cost Explorer API is not enabled in your AWS account.
**Solution**:
1. Go to AWS Cost Explorer in your management account
2. Enable Cost Explorer (may take up to 24 hours to activate)
3. Wait for activation to complete
4. Reconnect your account in MilkStraw AI dashboard
**Cause**: The IAM role is missing required permissions.
**Solution**:
1. Review the CloudFormation template
2. Ensure all required policies are attached
3. Update the stack if needed
4. Verify permissions in IAM console
## MilkBox issues
### MilkBox not appearing in AWS
**Cause**: MilkBox creation can take 15-30 minutes.
**Solution**:
1. Wait 30 minutes after approval
2. Check the MilkBox account in your AWS Organization
3. Verify the account is active and not suspended
4. Contact support if still not visible after 1 hour
**Cause**: Commitment may not match your usage patterns or regions.
**Solution**:
1. Verify the commitment type matches your workload
2. Check that usage is in the same region (for EC2 Instance Savings Plans)
3. Review commitment details in AWS Billing console
4. Allow 24-48 hours for full application
## Billing issues
### Savings not showing in dashboard
**Cause**: Savings data can take 24-48 hours to appear in Cost Explorer.
**Solution**:
1. Wait 48 hours after MilkBox deployment
2. Verify commitments are active in AWS Billing console
3. Check that Cost Explorer is showing commitment utilization
4. Contact support if savings still not visible after 72 hours
**Cause**: Fee calculation may be based on different time period or savings calculation.
**Solution**:
1. Review the billing period in your invoice
2. Check the savings calculation in Cost Explorer
3. Verify the 20% fee is applied to actual savings
4. Contact support with specific invoice details
## Performance issues
### Low commitment utilization
**Cause**: Usage patterns may have changed or commitment was oversized.
**Solution**:
1. Review recent infrastructure changes
2. Check if workloads were scaled down or terminated
3. Wait for MilkStraw AI to adjust recommendations
4. Consider modifying or exchanging commitments (for Convertible RIs)
**Cause**: Not enough commitments purchased or new workloads added.
**Solution**:
1. Review pending recommendations in dashboard
2. Approve additional MilkBoxes to increase coverage
3. Ensure automatic approval is enabled for optimal coverage
4. Allow time for AI to analyze new usage patterns
## Dashboard issues
### Data not updating
**Cause**: Data sync may be delayed or connection issue.
**Solution**:
1. Refresh the page
2. Check your internet connection
3. Verify IAM role connection is still active
4. Wait 15 minutes and try again
5. Clear browser cache if issue persists
**Cause**: Browser issue or permission problem.
**Solution**:
1. Try a different browser
2. Disable browser extensions
3. Check that you have approval permissions in your MilkStraw AI account
4. Contact support if issue continues
## Getting help
If you can't resolve your issue using this guide:
Review frequently asked questions
Schedule a call or reach out via Slack
## Diagnostic checklist
Before contacting support, gather this information:
* Your MilkStraw AI account email
* AWS account ID(s) affected
* When the issue started
* Screenshots of any error messages
* Browser console errors (if dashboard issue)
* AWS CloudFormation stack events (if deployment issue)
* Steps you've already taken to resolve the issue
* Any changes made before the issue occurred
For urgent issues affecting active commitments or billing, contact support immediately via [scheduled call](https://cal.com/team/milkstraw-ai/chat-with-milkstraw-team).