fix: env-scope the EC2 launch template name (unblocks prod deploy) (#51)
Some checks are pending
Infra CD / Infra CI (pre-deploy) (push) Waiting to run
Infra CD / Deploy open-swe-dev (push) Blocked by required conditions
Infra CD / Deploy open-swe-prod (push) Blocked by required conditions
CI / Lint (push) Waiting to run
CI / Format check (push) Waiting to run
CI / Unit tests (push) Waiting to run
CI / Playwright E2E (push) Waiting to run

requireImdsv2:true makes CDK auto-create a launch template named from the
construct id ('Instance' -> 'InstanceLaunchTemplate') with no env qualifier,
so OpenSweDevStack and OpenSweProdStack both render
LaunchTemplateName: InstanceLaunchTemplate. dev created it first (the live
dev box runs on it); the prod first-deploy then failed with
InvalidLaunchTemplateName.AlreadyExistsException and the whole stack rolled
back.

Force a per-env LT name (open-swe-<env>-lt) via an aspect (the LT is created
at synth time by the requireImdsv2 handling, not in the constructor), and
rename the instance's launch-template REFERENCE in lockstep so CFN still
resolves it. synth-verified: dev=open-swe-dev-lt, prod=open-swe-prod-lt on
both the LT resource and the instance reference; version GetAtt preserved.

NOTE: deploying this renames dev's LT -> one-time dev box replacement
(stateless; boots from the baked AMI + pulls releases/latest). prod then
creates open-swe-prod-lt cleanly.
This commit is contained in:
Adam Moussa 2026-06-29 00:51:16 -04:00 • committed by GitHub
parent 3c69dd9de6
commit 86b4859589
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -8,7 +8,7 @@ import * as logs from "aws-cdk-lib/aws-logs";
import * as route53 from "aws-cdk-lib/aws-route53";
import * as iam from "aws-cdk-lib/aws-iam";
import * as ssm from "aws-cdk-lib/aws-ssm";
import { Construct } from "constructs";
import { Construct, IConstruct } from "constructs";
import { EnvName, prefix } from "../config";
import { bakedOpenSweArm64 } from "./ami-cache";
@ -230,6 +230,27 @@ export class AppService extends Construct {
],
});
// `requireImdsv2: true` makes CDK auto-create a launch template, and it names
// that LT from the construct id ("Instance" -> "InstanceLaunchTemplate") with NO
// env qualifier — so OpenSweDevStack and OpenSweProdStack both want the identical
// LT name and the second env to deploy fails with
// InvalidLaunchTemplateName.AlreadyExistsException (prod rollback, 2026-06-29).
// Force a per-env LT name. Done via an aspect because the LT is created at synth
// time by the requireImdsv2 handling, not in this constructor.
cdk.Aspects.of(this.instance).add({
visit(node: IConstruct) {
if (node instanceof ec2.CfnLaunchTemplate) {
node.launchTemplateName = `${p}-lt`;
}
// The instance references the LT BY NAME, so the reference must be renamed in
// lockstep (preserve the GetAtt version) or CFN can't find the template.
if (node instanceof ec2.CfnInstance && node.launchTemplate) {
const spec = node.launchTemplate as ec2.CfnInstance.LaunchTemplateSpecificationProperty;
node.launchTemplate = { ...spec, launchTemplateName: `${p}-lt` };
}
},
});
// SSM deploy document (open-swe-<env>-deploy): runs the baked
// /opt/open-swe/bin/deploy.sh to pull the latest release + restart. CI fires it
// (tag-scoped to project=open-swe,env=<env>) after uploading a release, so the