@cfxlabsinc/ecrPulumi-managed ECR repositories for CFX container apps.
Per-app repositories — one ECR repository per container app (utila-cosigner, admin-dashboard, temporal-worker, internal-dashboard) per env, with:
scanOnPush enabledThe single source of truth for which repos exist is
pulumi/repos.ts. Adding a new container app means appending
a name there and running pulumi up against each env stack (or letting the
ecr-pulumi-cd-{dev,prod} job in deploy-env.yml do it on merge to main).
No base-image cache. Base images resolve through the RunsOn runner's
transparent Docker Hub mirror in the fleet account, so Dockerfiles carry bare
FROM lines and this stack owns nothing for them. The BASE_IMAGE_PREFIX
build arg still exists but CI never sets it — see
rules/ci.md for the mirror, and do not reintroduce a
per-repo image prefix.
Repos live in the same workload account that builds and consumes them
(206248878611 for dev, 372806568664 for prod). No cross-account pull policy
is needed — ECS tasks and Lambda functions read images from the same account
they run in.
Until this package existed, ECR repos were created and re-asserted on every CI
build by the .github/actions/create-ecr-repo composite action via raw
aws ecr {create-repository,set-repository-policy,put-lifecycle-policy} calls.
That left repo policy + lifecycle drift impossible to detect, and made changes
land asynchronously (only on the next CI run that happened to invoke the
action). Owning it in Pulumi makes the policy diff-able and reviewable.
Two stacks — one per env:
| Stack | Account | Backend |
|---|---|---|
dev |
206248878611 |
s3://cfx-pulumi-iac-backend-dev?region=us-west-2 |
prod |
372806568664 |
s3://cfx-pulumi-iac-backend-prod?region=us-west-2 |
Each stack provisions its repos in its own workload account via the
cfx-role-devops OIDC role already trusted by the container CI/CD workflows.
No manual bootstrap. cd-pulumi.yml invokes pulumi up --upsert, so the first
CD run per env creates the stack from Pulumi.<stack>.yaml. The Repository
resources have the import: option set, so the first apply adopted the repos
that .github/actions/create-ecr-repo/ had created imperatively rather than
re-creating them.
Wired into deploy-env.yml as ecr-pulumi-cd-{dev,prod} jobs, gated by
nx affected on packages/ecr/**.
This package is now the only thing that creates ECR repos. The imperative
create-ecr-repo safety net in container-build-push is gone, so adding a
container app means appending to containerAppNames in pulumi/repos.ts and
letting the CD job apply — a build for a repo that does not exist will fail at
push instead of silently creating one.
Before this rework, a single cicd stack lived in account 764105176280 and
emitted a cross-account pull policy granting 206248878611 and 372806568664
read access. The CICD account is being decommissioned — repos and their
consumers now share an account per env, so the cross-account dance is gone.
If the old cicd stack was ever applied, the cfx-<app> repos in
764105176280 are orphaned by this change. Decide whether to delete them or
leave them as the source for one final migration push, then clean up the
stack:
cd packages/ecr/pulumi
pulumi login s3://cfx-pulumi-iac-backend-cicd?region=us-west-2 # if it ever existed
pulumi stack rm cicd