@cfxlabsinc/b2b-services
    Preparing search index...

    Module @cfxlabsinc/ecr

    @cfxlabsinc/ecr

    Pulumi-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 enabled
    • A lifecycle policy that expires untagged images after 1 day and keeps the last 10 tagged images

    The 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