mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-10-07 16:19:09 +00:00
Packer-build the custom base image and repoint AppService off the AL2023
placeholder onto it.
deploy/ami/open-swe-base.pkr.hcl — fix two bugs that blocked the first real
`packer build` (the config had only ever been `packer validate`'d at T8):
- the file provisioner failed uploading the templates dir ('scp: …: Is a
directory') — a trailing-slash contents-upload needs the dest dir to exist;
added a 'mkdir -p /tmp/open-swe-templates' shell provisioner + dropped the
dest trailing slash.
- the shell provisioner's custom execute_command omitted {{ .Vars }}, so the
environment_vars never reached provision.sh (which runs under set -u and
aborted on CLOUDWATCH_AGENT_DEB_URL). Added {{ .Vars }}.
infra:
- ami-cache.ts: BAKED_OPEN_SWE_AMI_ID = ami-0545363bb147229ff (built 2026-06-26
from open-swe-base-arm64-20260626-201929) + bakedOpenSweArm64() pinning it by
exact id via MachineImage.genericLinux (offline, deterministic). Dropped the
now-dead AL2023 cachedInContext helper + context key; kept the EBS/replacement
discipline docs.
- app-service.ts: machineImage → bakedOpenSweArm64().
- open-swe-stack.ts: output BakedAmiId (was the AL2023 PinnedAmiId guard).
- cdk.context.json → {} (AMI is a static id pin; no context lookups remain).
- README: Baked AMI + EBS-replacement-discipline section.
tsc + cdk synth(dev+prod) + jest(16) clean; template ImageId = the baked AMI.
NOTE: held — do NOT merge until the open-swe-dev secret values are populated
(put-config.sh). The infra CD is live, so merging this to dev auto-deploys
OpenSweDevStack; without secrets the box boots but fetch-config fail-fasts →
unhealthy ALB target on the shared prod ALB. Merge once secrets are set (T14).
75 lines
3.1 KiB
TypeScript
75 lines
3.1 KiB
TypeScript
import * as cdk from "aws-cdk-lib";
|
|
import { Construct } from "constructs";
|
|
import { EnvName, prefix } from "./config";
|
|
import { AppService } from "./constructs/app-service";
|
|
import { ConfigStore } from "./constructs/config-store";
|
|
import { InstanceRole } from "./constructs/instance-role";
|
|
import { BAKED_OPEN_SWE_AMI_ID } from "./constructs/ami-cache";
|
|
|
|
export interface OpenSweStackProps extends cdk.StackProps {
|
|
/** open-swe environment — drives the `open-swe-<env>-*` resource naming. */
|
|
readonly envName: EnvName;
|
|
}
|
|
|
|
/**
|
|
* Per-env open-swe stack (`open-swe-dev` / `open-swe-prod`). Resource names are
|
|
* prefixed `open-swe-<env>-*`.
|
|
*
|
|
* Composes: the per-env least-privilege instance role (T6), the Secrets/SSM
|
|
* config store (T11), and the compute + ingress wiring (T12, AppService — EC2
|
|
* box, instance SG, target group, imported-listener rules, Route53 aliases,
|
|
* 30-day log groups). The shared VPC and ALB are imported, never owned. Synth is
|
|
* offline (AMI is the cdk.context.json-pinned placeholder until T12-deploy).
|
|
*/
|
|
export class OpenSweStack extends cdk.Stack {
|
|
public readonly instanceRole: InstanceRole;
|
|
public readonly configStore: ConfigStore;
|
|
public readonly appService: AppService;
|
|
|
|
constructor(scope: Construct, id: string, props: OpenSweStackProps) {
|
|
super(scope, id, props);
|
|
|
|
const envName = props.envName;
|
|
const p = prefix(envName);
|
|
|
|
cdk.Tags.of(this).add("project", "open-swe");
|
|
cdk.Tags.of(this).add("env", envName);
|
|
cdk.Tags.of(this).add("ManagedBy", "cdk");
|
|
|
|
// Per-env least-privilege EC2 instance role (open-swe-<env>-instance-role).
|
|
this.instanceRole = new InstanceRole(this, "Instance", envName);
|
|
|
|
// Secrets Manager + SSM Parameter Store shells the boot hook reads
|
|
// (deploy/seahaven/fetch-config.sh). Secret shells are value-less and
|
|
// populated out-of-band; IaC-managed SSM params carry real derivable values.
|
|
// The instance role already grants read on open-swe-<env>/* + /open-swe-<env>/*.
|
|
this.configStore = new ConfigStore(this, "Config", { envName });
|
|
|
|
// Surface the baked open-swe base AMI id the box runs on (pinned by id in
|
|
// ami-cache.ts; refreshed by a deliberate packer rebuild → replacement).
|
|
new cdk.CfnOutput(this, "BakedAmiId", {
|
|
value: BAKED_OPEN_SWE_AMI_ID,
|
|
description: "Baked open-swe-base-arm64 AMI id consumed by the EC2 instance.",
|
|
});
|
|
|
|
// T12: compute + ingress. Imports the shared seahaven-vpc + ALB and adds the
|
|
// env's EC2 box, instance SG, target group, listener rules, DNS, log groups.
|
|
this.appService = new AppService(this, "App", {
|
|
envName,
|
|
instanceRole: this.instanceRole.role,
|
|
});
|
|
|
|
new cdk.CfnOutput(this, "InstanceRoleArn", {
|
|
value: this.instanceRole.role.roleArn,
|
|
description: `${p} EC2 instance role ARN.`,
|
|
});
|
|
new cdk.CfnOutput(this, "InstanceId", {
|
|
value: this.appService.instance.instanceId,
|
|
description: `${p} EC2 instance id.`,
|
|
});
|
|
new cdk.CfnOutput(this, "TargetGroupArn", {
|
|
value: this.appService.targetGroup.targetGroupArn,
|
|
description: `${p} ALB target group ARN (→ instance:80 nginx).`,
|
|
});
|
|
}
|
|
}
|