Repository navigation
Closed
Labels
complexity: mediumdependencyfeature: project terraform setuprole: DevOps EngineerEngineer who maintains and deploys softwareEngineer who maintains and deploys softwaresize: 3ptCan be done in 13-18 hoursCan be done in 13-18 hours
Milestone
Description
Dependency
Overview
We need to replace the cluster's two m5.large instances with one t3a.medium, because once every service uses bridge networking nothing needs the second host or the larger size. This is the step that saves the money, about $115/month.
Action Items
The capacity provider has managed draining disabled, so terminating an instance without draining it first kills its tasks. Drain manually every time.
- PR: in
terraform/platform/compute.tf, changeinstance_typeonaws_launch_template.ecs(line 44 when written —instance_type = "m5.large") to"t3a.medium", anddesired_capacityonaws_autoscaling_group.ecs(line 66) from 2 to 1. Keepmin_size = 1andmax_size = 2; the second slot is what makes an AMI replacement possible without an outage.desired_capacityis inignore_changes, so the edit only keeps the code honest; the actual scale-in is the manual steps below.
- Same PR: in
terraform/modules/container/main.tf, replace the twospreadstrategies inplacement_strategies(line 127) with a singlebinpackonmemory. Spread existed only because ENI slots were scarce; its comment says so and should go with it. - Run
terraform validateandterraform fmt -check -difflocally; confirm in the CI plan that the services and ASG update in place. - After the PR merges, swap the hosts one at a time:
- Set one
m5.largecontainer instance toDRAININGand wait until its tasks are running on the other. Thenaws autoscaling terminate-instance-in-auto-scaling-group --instance-id <id> --should-decrement-desired-capacity. aws autoscaling set-desired-capacity --auto-scaling-group-name ecs-incubator-prod --desired-capacity 2. The new instance launches as at3a.mediumfrom launch template version$Latest. Wait until it registers with the cluster.- Drain the remaining
m5.large, wait for every task to land on thet3a.medium, then terminate it with--should-decrement-desired-capacity.
- Set one
- After the swap, confirm: one container instance, type
t3a.medium,HttpPutResponseHopLimit: 1; all ten services 1/1 with healthy targets; and record its registered and remaining memory in a comment:Remaining memory should be about 900 MB. That figure is the cluster's real headroom and belongs in the documentation in the next child.aws ecs describe-container-instances --cluster incubator-prod \ --container-instances $(aws ecs list-container-instances --cluster incubator-prod --query 'containerInstanceArns[]' --output text) \ --query 'containerInstances[].{ec2:ec2InstanceId,tasks:runningTasksCount,registered:registeredResources[?name==`MEMORY`].integerValue,remaining:remainingResources[?name==`MEMORY`].integerValue}' - A week after the swap, check the instance's
CPUCreditBalanceis flat or rising, and that no task was stopped for running out of memory.
Resources/Instructions
terraform/platform/compute.tfandterraform/modules/container/main.tf. Line numbers were accurate when written and may drift.- The launch template's AMI (
ami-036428f37186903ce, AL2023 ECS-optimized, x86_64) runs ont3a. The user data'sawsvpcTrunkingline is harmless on an instance type that does not support trunking. - T3 unlimited mode is the default. It charges extra only if the 24-hour average stays above the 20%-per-vCPU baseline; measured demand averages about a fifth of that.
- Draining container instances.
Metadata
Metadata
Assignees
Labels
complexity: mediumdependencyfeature: project terraform setuprole: DevOps EngineerEngineer who maintains and deploys softwareEngineer who maintains and deploys softwaresize: 3ptCan be done in 13-18 hoursCan be done in 13-18 hours
Type
Projects
- StatusShow more project fieldsDone
Activity
Shrink ECS cluster to one t3a.medium (#263)
Disable ECS AZ rebalancing so binpack placement applies (#264)
ale210 commentedon Oct 10, 2026
Host swap done 2026-10-10. The cluster is one
t3a.medium,i-08d0d64405cb2af4e(us-west-2a), launched from launch template version 10 with IMDSv2 required andHttpPutResponseHopLimit: 1. Bothm5.largeinstances are drained and terminated; the ASG is min 1 / max 2 / desired 1.The tenth task,
vrms-frontend-dev, has been failing to start since before this epic. Its 256 MiB reservation would bring headroom down to about 1,023 MiB, the cluster's real figure. The largest single reservation is 512 MiB (home-unite-us-fullstack-prod), so a production deploy still has room to start its new task beside the old one.All nine running services are 1/1 with healthy
instancetargets, and every hostname answered as before. Neither drain produced a placement failure.Two things changed along the way. #263's
binpackplacement was rejected at apply because AZ rebalancing only allows AZ-spread placement; #264 turned AZ rebalancing off, and the same placement then applied with no redeploy. Also, HomeUniteUs prod keeps its data in SQLite inside the container, so both drains reset it, as every restart does.Pre- and post-swap captures are kept outside the repo. The one-week check (CPU credit balance and memory-related task stops) is due around 2026-10-17.
Fix stale ENI comment on the ECS service lifecycle (#265)