cdk: start the CloudWatch agent on every instance, not just ollama - #2677
Merged
Merged
Conversation
The agent is already INSTALLED on every instance (launchTemplates.ts, inside the shared `usrdata()`), but the config download and `systemctl start` live only in the ollama user-data block. So only the GPU box publishes `mem_used_percent` — every other tier reports CPU, network and EBS but no memory. That matters because memory, not CPU, is the binding resource on these instances. A 30-day production baseline shows the math worker at 0.5% mean CPU and both delphi tiers at 0.6-1.3%, so CPU says only "idle"; without memory there is no evidence on which to right-size them. This moves the agent's config-and-start block from `ollamaUsrData` into the shared `usrdata()`. Effect: every instance publishes `mem_used_percent` and `disk used_percent`. The `nvidia_gpu` section of the config collects nothing where there is no GPU, so the ollama box is unaffected. Safety notes, both deliberate: * All five launch templates already use the same `instanceRole`, and `cwAgentConfigAsset.grantRead(instanceRole)` is already granted — so the S3 fetch is authorised everywhere. Verified, not assumed. * `usrdata()` runs under `set -e`. The added commands are therefore guarded with `|| true` and `|| echo`: a metrics agent must never be able to abort an instance boot. This is the one place this deliberately differs from the ollama block it is derived from, which is unguarded. Not included on purpose: no change to the agent config JSON, no new metrics, no change to collection interval. This turns on what is already configured. Verified before submitting: * `npx tsc --noEmit` exits 0, before and after. `usrdata` is declared above `cwAgentConfigAsset` but only CALLED below it, and TypeScript does not object. * `npx cdk synth` succeeds with no AWS credentials. * In the synthesized CloudFormation, all five launch templates contain `systemctl start amazon-cloudwatch-agent` exactly once, each guarded. Ollama gets it once, not twice — the move is not a duplication. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
tevko
approved these changes
Jul 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Moves the CloudWatch agent's config download +
systemctl startfrom the ollama user-data block into the sharedusrdata(), so every instance starts it — not just the GPU box.The agent is already installed everywhere; only ollama ever started it. Result today: no
mem_used_percenton the math, delphi or web tiers. Memory is what we need to right-size them — CPU sits at 0.5–1.3% and tells us nothing.Added commands are guarded with
|| true(the function runs underset -e), so a failing agent can never abort an instance boot.Rollout
Deploying this on its own gives you zero memory data. User-data only applies to instances at launch, and none of the ASGs has a rolling-update policy, so nothing gets replaced on deploy. Instances pick it up only when they're replaced — and this fleet is idle, so that won't happen on its own.
Two steps. Do both: step 1 gets data now, step 2 keeps it working after instances cycle.
Both scripts find the ASGs themselves and skip ollama (it already publishes memory, and its boot does the most work — nothing to gain, most to break). Nothing to fill in.
Step 1 — turn it on now, on the instances already running
Doesn't need this PR merged. Nothing is replaced. Data arrives in ~1 minute. Safe to re-run.
Any command that failed:
aws ssm list-command-invocations --details \ --query 'CommandInvocations[?Status!=`Success`].[InstanceId,Status,StatusDetails]' --output tableStep 2 — after this PR is deployed, refresh the ASGs
This is what makes it stick. Step 1's fix is lost the moment an instance is replaced.
MaxHealthyPercentage: 200launches the replacement before terminating the old one, so capacity never dips. Every ASG has room (desired/max): math1/5, delphi-small2/7, delphi-large1/3, web2/10.Watch it:
Check it worked
aws cloudwatch list-metrics --namespace CWAgent --metric-name mem_used_percent \ --query 'Metrics[].Dimensions[?Name==`AutoScalingGroupName`].Value' --output textYou should see every ASG listed, not just ollama. Metrics land at 60s intervals.
🤖 Generated with Claude Code