Skip to content

Configuration reference (cicd.config.ts)

Everything the Autopilot (1.x) wrapper needs is declared in one file, cicd.config.ts, next to your cdk.json, using defineCICD({ ... }). This page documents every field it accepts. The source of truth is src/config/types.ts and src/config/define.ts.

import { defineCICD, Repository } from '@cdklabs/cdk-cicd-wrapper';

export default defineCICD({
  application: 'my-app',
  repository: Repository.codestarConnection(
    'my-org/my-app',
    'arn:aws:codestar-connections:eu-west-1:111111111111:connection/01234567-89ab-cdef-0123-456789abcdef',
  ),
  stages: ['dev', { name: 'prod', env: { account: '111111111111', region: 'eu-west-1' } }],
});

Fields at a glance

Field Type Default Purpose
application string — Application name; drives asset naming and the default-synthesizer qualifier.
qualifier string derived from application (≤10 chars) Target-stack CDK bootstrap qualifier.
pipelineStackName string ${application}-pipeline CloudFormation stack name for the self-mutating pipeline stack (CDK_PIPELINES/GITHUB_ACTIONS). See Pipeline stack name.
repository Repository — (required) The pipeline's source. See Repository.
stages Array<string \| StageInput> — (required) Deployment stages, in order. See Stages.
engine EngineType CODEPIPELINE Which engine renders the pipeline. See Engine.
githubActions GitHubActionsConfig — GitHub Actions engine config; read only when engine is GITHUB_ACTIONS.
synthesizer { type: SynthesizerType, appId?: string } DEFAULT Stack synthesizer. appId defaults to application for APP_STAGING.
ci CiConfigInput engine defaults Build steps and which stages CI synthesizes. See CI.
deployModel DeployModel ASSEMBLY_PROMOTION How the deployed assembly is produced. See Deploy model.
codeArtifact CodeArtifactConfig — Private CodeArtifact npm repo the builds authenticate against.
npmRegistry NpmRegistryConfig — Generic private npm registry (bearer token).
proxy ProxyConfigInput — HTTP(S) proxy every build project routes through.
warmAccountsFromSsm boolean false Export ACCOUNT_<STAGE> env vars in a self-mutating engine's synth step by scanning SSM. See Warming accounts from SSM.
vpc VpcConfig no VPC VPC the pipeline's CodeBuild projects run in. See VPC.
complianceLogBucketName string — Compliance/access-log destination bucket name; all logged buckets must share its account and Region.
createComplianceLogBucket boolean true Create/manage the compliance bucket; set false to reference a pre-existing owner-managed Blueprint bucket.
pipelineRoleNames PipelineRoleNames CDK-generated names Force IAM role names on the CDK_PIPELINES engine's roles. See Pipeline role names.
codePipelineRoleNames CodePipelineRoleNames CDK-generated names Force IAM role names on the flat CODEPIPELINE engine's roles. See Pipeline role names.
deployRoleExternalId string — Pipeline-level default ExternalId for the forced deploy-role assumption. See Cross-account externalId.
codeBuildEnvSettings codebuild.BuildEnvironment — CodeBuild overrides (privileged mode, compute, env vars).
asyncDeploy boolean false Let a Lambda own the CloudFormation wait instead of build compute.
express boolean false Deploy with CloudFormation express mode. See Express mode.
deployerImage BuildImage — Container mode: build & push a deployer image instead of deploying.
plugins PluginRef[] the default-on hardening set Security plugins (hardening Aspects) applied tree-wide. See Security plugins.

APP_STAGING is valid for direct/local application deployment (cdk deploy, including local cdk-cicd deploy --from-image) and Repo 1 container-image builds, which deploy no application stacks. Every wrapper-generated deployment pipeline rejects it: flat CODEPIPELINE, Repo 2, CDK_PIPELINES, and GITHUB_ACTIONS. The pinned alpha honors bootstrapQualifier, so a custom qualifier works on the direct/local path. It also maps deployment.deployRole and deployment.cfnExecutionRole to DeploymentIdentities.specifyRoles, so those custom identities govern application-stack deployments. The separate staging support stack uses BootstraplessSynthesizer and deploys with caller/base credentials; the application-stack identities do not govern those support resources.

application and qualifier

application names the app and drives asset naming. qualifier is derived from application when omitted — lowercased, non-alphanumerics stripped, truncated to 10 characters (falling back to cdkcicd if that leaves nothing). An explicit qualifier is trimmed and must match [A-Za-z0-9_-]{1,10}; blank, invalid, or overlong values are rejected. APP_STAGING additionally uses its separate appId for application-specific staging resources and threads the configured qualifier into its bootstrap-role contract on direct/local deployments and into the configuration baked by a Repo 1 image build.

The engine-owned pipeline stack itself always uses the standard hub-account bootstrap qualifier. A target application's custom qualifier does not require a second custom bootstrap for the pipeline stack.

Pipeline stack name

The CDK_PIPELINES and GITHUB_ACTIONS engines assemble their own self-mutating pipeline stack, named ${application}-pipeline by default. pipelineStackName overrides the CloudFormation stack name of that stack:

export default defineCICD({
  application: 'automation',
  pipelineStackName: 'automation', // deploy the pipeline stack as `automation`, not `automation-pipeline`
  repository: Repository.codecommit('automation'),
  engine: EngineType.CDK_PIPELINES,
  stages: [/* … */],
});

Set it to preserve a pre-1.x (Blueprint) pipeline stack name when migrating an already-deployed pipeline. A deployed pipeline is self-mutating: its SelfMutate step runs cdk deploy <stackName>, and a self-mutating pipeline cannot rename its own root stack in place — so if the synthesized stack name changes from the deployed one, SelfMutate fails with No stacks match the name(s) <oldName>. Pinning the name back to the deployed value lets the existing pipeline update in place, avoiding a disruptive rename cutover (pipeline outage plus, where the pipeline pins cross-account role names, a manual role-name resequencing).

The override changes only the CloudFormation stackName. The construct id stays ${application}-pipeline, so the pipeline's child resource logical IDs (roles, CodeBuild projects, artifact buckets) — which derive from the construct node path — are unchanged from the default. It does not restore pre-1.x child logical IDs; it is scoped to the pipeline stack name only. Omitting the field keeps the ${application}-pipeline default, so existing consumers are unaffected.

Repository

The source repository, constructed through a Repository factory. The tracked branch defaults to main.

Repository.codestarConnection('my-org/my-app', connArn); // GitHub or another provider via an existing connection ARN
Repository.codecommit('my-repo'); // AWS CodeCommit
Repository.s3('my-bucket/my-key'); // a versioned S3 object
Repository.github('my-org/my-app'); // GitHub Actions engine only
// each factory takes an optional trailing `branch` argument
Repository.codestarConnection('my-org/my-app', connArn, 'develop');
// CodeCommit is CREATED by default; pass { existing: true } to import an existing repo instead:
Repository.codecommit('my-repo', 'main', { existing: true });

The default CODEPIPELINE and CDK_PIPELINES engines require Repository.codestarConnection(...) for GitHub sources. When engine is GITHUB_ACTIONS, repository must instead be Repository.github(...) because the workflow runs where GitHub already checked the source out.

Stages

Each entry is either a bare name ('dev') or a full object. A stage's environment can target one region (region) or many (regions), and regionOrder controls rollout order.

stages: [
  'dev', // account/region resolved from ambient credentials at deploy time
  { name: 'int', env: { account: '222222222222', region: 'eu-west-1' } },
  {
    name: 'prod',
    env: { account: '333333333333', regions: ['eu-west-1', 'us-east-1'], regionOrder: RegionOrder.PARALLEL },
    manualApproval: true,
    deployment: { deployRole: 'arn:aws:iam::333333333333:role/Deployer' },
  },
],
  • manualApproval — defaults to auto-approve for dev and res (inner-loop stages) and gated for every other stage. Set it explicitly to override.
  • regionOrder — RegionOrder.SEQUENTIAL (default) rolls regions out one after another; RegionOrder.PARALLEL deploys them at once.
  • deployment — force the deployment role CDK assumes and/or the distinct cfnExecutionRole CloudFormation assumes for the stage, and optionally an externalId presented when assuming deployRole. See Cross-account externalId.

For CodeBuild-backed deployment actions, the project role assumes deployRole. That assumed deployment role passes cfnExecutionRole to CloudFormation, so the deployment role needs iam:PassRole for the execution role. The CodeBuild project role does not need direct iam:PassRole on it.

See Continuous Deployment for the deeper stage model.

Engine

engine selects how the pipeline is rendered:

  • EngineType.CODEPIPELINE (default) — a lightweight flat pipeline on raw aws-cdk-lib/aws-codepipeline. Deploy stages re-invoke the app per stage, so bin/ stays a plain single-stage app. This is also the only engine that supports container mode.
  • EngineType.CDK_PIPELINES — the Blueprint-compatible self-mutating pipeline on aws-cdk-lib/pipelines (Source → Synth → Assets → one wave per stage). Choose it when you want a pipeline shaped like a Blueprint (0.x) one.
  • EngineType.GITHUB_ACTIONS — renders a GitHub Actions workflow instead of an AWS-hosted pipeline. Requires repository to be Repository.github(...) and reads the githubActions config.

GitHub Actions

When engine is EngineType.GITHUB_ACTIONS, githubActions configures the generated workflow and the OIDC role it assumes. Every field is optional.

githubActions: {
  roleName: 'my-app-github-role', // OIDC role the workflow assumes (literal; embedded in the workflow YAML)
  subjectClaims: ['repo:my-org/my-app:ref:refs/heads/main'], // allowed OIDC subject claims
  openIdConnectProviderArn: 'arn:aws:iam::111111111111:oidc-provider/token.actions.githubusercontent.com',
  thumbprints: ['<sha1>'], // GitHub cert thumbprints (defaults to the built-in set)
  workflowPath: '.github/workflows/deploy.yml',
  workflowName: 'deploy',
  workflowTriggers: { push: { branches: ['main'] } }, // cdk-pipelines-github WorkflowTriggers
  publishAssetsAuthRegion: 'eu-west-1', // defaults to the pipeline stack Region
  buildContainerCredentials: {
    usernameSecretName: 'REGISTRY_USERNAME',
    passwordSecretName: 'REGISTRY_TOKEN',
  },
  // Required when any stage has manualApproval: true, after required reviewers are configured
  // on the generated GitHub Environments.
  environmentProtectionConfigured: true,
},
  • roleName — the OIDC role the workflow assumes. Must be literal (the workflow YAML embeds its ARN as plain text). Defaults to <application>-github-role.
  • subjectClaims — OIDC subject claims allowed to assume the role. Defaults to every ref/environment of repository's owner/repo.
  • openIdConnectProviderArn — an existing OIDC provider ARN; omit to have one created.
  • thumbprints — GitHub certificate thumbprints; defaults to the built-in, currently-valid set.
  • workflowPath / workflowName — file path and name of the generated workflow (default .github/workflows/deploy.yml, deploy).
  • workflowTriggers — the workflow's triggers (default: push to the tracked branch plus manual dispatch).
  • publishAssetsAuthRegion — the region the OIDC role is assumed in when publishing assets (not the region assets publish to). Defaults to the pipeline stack Region.
  • buildContainerCredentials — GitHub Actions secret names used to authenticate an external ci.image job container. The workflow renders ${{ secrets.NAME }} expressions; literal credentials are never accepted. This does not support private ECR, whose authorization-token exchange cannot run before GitHub pulls the job container.
  • environmentProtectionConfigured — explicit acknowledgement that required-reviewer rules have been configured on every generated GitHub Environment used by a stage with manualApproval: true. Workflow YAML can reference an environment but cannot create its protection rule, so the engine fails closed when an approval-gated stage exists and this flag is not true.

CI

ci controls the build steps and which stages CI synthesizes for validation.

ci: {
  steps: { lint: 'npx cdk-cicd validate', test: 'npx jest' }, // empty => the engine's default check set
  synthStages: 'all', // 'all' (every stage), an explicit list, or omit for the engine default
  image: 'registry.example.com/platform/ci:stable',
  codeBuildImageCredentials: {
    secretArn: 'arn:aws:secretsmanager:eu-west-1:111111111111:secret:registry-AbCdEf',
    // encryptionKeyArn: 'arn:aws:kms:eu-west-1:111111111111:key/...',
  },
  // partialBuildSpec: codebuild.BuildSpec.fromObject({ ... }), // merged into the CI build project only
},
  • steps — named shell commands. Empty (the default) applies the engine's built-in check set (npx cdk-cicd check). Setting steps replaces that default, so include a check step if you still want those checks.
  • synthStages — 'all' synthesizes every stage; an explicit list names stages; omitting it uses the engine default (every stage under ASSEMBLY_PROMOTION, one env under DEPLOY_TIME_SYNTH).
  • image — an optional image override for the CI build. On CodeBuild-backed engines, aws/codebuild/... IDs use CodeBuild-managed pull credentials. A private ECR build image must be in the pipeline account and the same Region as the CodeBuild project; the generated role receives the repository pull grant. Repo 2's separately documented, explicitly acknowledged cross-account image path does not relax the same-Region requirement for a CodeBuild environment image. On GITHUB_ACTIONS, this must instead be a pullable OCI job-container reference; managed CodeBuild IDs and private ECR images are rejected.
  • codeBuildImageCredentials — CodeBuild engines only: the complete ARN of a Secrets Manager secret containing username and password fields for an authenticated external registry, plus encryptionKeyArn when that secret uses a customer-managed KMS key. CDK renders the CodeBuild registry credential and grants the project role secret/decrypt access. It is rejected for aws/codebuild/... and private ECR images, which use their own credential models. Public external images remain anonymous when this field is omitted. GitHub Actions uses githubActions.buildContainerCredentials instead.
  • partialBuildSpec — a CodeBuild spec fragment deep-merged into the CI build project's generated buildspec (the CI project only — not self-update or per-stage deploy projects).

Deploy model

deployModel controls how the deployed cloud assembly is produced:

  • DeployModel.ASSEMBLY_PROMOTION (default) — CI synthesizes every stage once and promotes cdk.out as the pipeline artifact; each deploy stage consumes that assembly (one synth per pipeline run).
  • DeployModel.DEPLOY_TIME_SYNTH — each stage synthesizes at deploy time from code + pinned deps against that stage's injected config. Pick it when a stage's template must be produced with that stage's own credentials (for example a synth-time lookup only the target account can resolve).

Private dependencies

Three independent, optional blocks let the pipeline's builds install private packages:

  • codeArtifact — a private CodeArtifact npm repository. Every build runs aws codeartifact login before npm ci. Fields: domain and repository (required); account and region default to the pipeline's own; npmScope binds an npm scope (e.g. cdklabs for @cdklabs/*).
  • npmRegistry — any npm-compatible registry authenticated with a bearer token; the build writes a temporary npm config outside the promoted artifact tree with a token read from Secrets Manager. Fields: url (the registry URL) and basicAuthSecretArn (the Secrets Manager secret) are required; scope binds an npm scope, omit to override the default registry. Set encryptionKeyArn when the secret uses a customer-managed KMS key.
  • proxy — route every build through an HTTP(S) proxy. proxySecretArn (required) is the Secrets Manager secret holding the proxy credentials; the build exports HTTP(S)_PROXY and curls proxyTestUrl to prove the tunnel before installs. noProxy defaults to []; proxyTestUrl defaults to https://aws.amazon.com. Set encryptionKeyArn when the secret uses a customer-managed KMS key.

Warming accounts from SSM

warmAccountsFromSsm (default false) exports per-stage account env vars on a self-mutating engine's synth step (CDK_PIPELINES and GITHUB_ACTIONS — the engines that re-run cdk synth under the pipeline). When on, before cdk synth the build scans SSM Parameter Store under the pipeline's qualifier (/<qualifier>/) and exports an ACCOUNT_<STAGE> environment variable for every parameter whose name contains Account — /<qualifier>/AccountDev becomes ACCOUNT_DEV, /<qualifier>/AccountProd becomes ACCOUNT_PROD, and so on. It is dynamic: whatever Account* parameters your bootstrap wrote become env vars, with no hardcoded stage list. A cdk.config.ts that reads process.env.ACCOUNT_<STAGE> then resolves its target accounts at synth time from those values.

The qualifier comes from the config's qualifier when set, otherwise the build's own $CDK_QUALIFIER. The synth step is granted ssm:GetParametersByPath scoped to /<qualifier>/* in the pipeline's account and region. If the scan finds no Account* parameter it fails the build (exit 1) rather than proceeding with an empty warm — a misconfigured qualifier or an un-bootstrapped account is surfaced loudly.

All three engines honor the flag on the CodeBuild/workflow step that runs cdk synth: CDK_PIPELINES and GITHUB_ACTIONS warm their self-mutating synth step, and the flat CODEPIPELINE engine warms its Build synth project. The scan runs ahead of cdk synth in the same shell, so the exported ACCOUNT_<STAGE> vars are visible to the app.

Compliance access logging

complianceLogBucketName provisions an SSE-S3 destination bucket and configures S3 server access logging on pipeline and application buckets for all three engines. The destination never logs to itself. Its log-delivery policy is limited to logging.s3.amazonaws.com, the pipeline account, and S3 source ARNs; TLS remains mandatory. The managed bucket and generated bucket policy share the same lifecycle: both are retained by default, and both are deleted for a disposable pipeline.

To keep a compliance bucket created by Blueprint, set createComplianceLogBucket: false alongside its existing name:

complianceLogBucketName: 'my-existing-blueprint-compliance-bucket',
createComplianceLogBucket: false,

This is an external reference, not CloudFormation adoption: Autopilot creates, updates, and deletes neither the bucket nor its policy, and a name-only CDK import cannot verify the live bucket. Before deployment, the bucket owner must confirm that it exists in the same account and Region as every logged source bucket, uses SSE-S3 (not SSE-KMS), has neither Object Lock/default retention nor Requester Pays enabled, does not log to itself, blocks public access, denies non-TLS access, and allows logging.s3.amazonaws.com to s3:PutObject with aws:SourceAccount restricted to the pipeline account and aws:SourceArn restricted to that account's S3 bucket ARNs. RemovalPolicy.DESTROY is rejected for this mode because the external owner controls the lifecycle.

Merge these statements into the existing policy—do not replace unrelated owner-managed statements. Replace the bucket name, account id, and partition placeholders:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "S3ServerAccessLogsPolicy",
      "Effect": "Allow",
      "Principal": { "Service": "logging.s3.amazonaws.com" },
      "Action": "s3:PutObject",
      "Resource": "arn:<partition>:s3:::<compliance-bucket-name>/*",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "<pipeline-account-id>"
        },
        "ArnLike": {
          "aws:SourceArn": "arn:<partition>:s3:::*"
        }
      }
    },
    {
      "Sid": "DenyInsecureTransport",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:<partition>:s3:::<compliance-bucket-name>",
        "arn:<partition>:s3:::<compliance-bucket-name>/*"
      ],
      "Condition": {
        "Bool": {
          "aws:SecureTransport": "false"
        }
      }
    }
  ]
}

Configure the destination bucket's default encryption as SSE-S3 (AES256). Do not require log delivery requests to include an encryption header; S3 applies the bucket default after accepting the object.

S3 server access logging cannot cross accounts or Regions. The wrapper therefore requires a concrete pipeline environment and rejects any configured application stage outside that same account and Region instead of inventing a bucket name that may not exist. Omit complianceLogBucketName for cross-account or multi-Region pipelines, or provide logging independently in each target environment.

VPC

vpc runs the pipeline's CodeBuild projects inside a VPC. Set managedVpc to have the wrapper create one, or vpcId to look up an existing one; setting neither (the default) runs CodeBuild without a VPC.

vpc: { managedVpc: { cidrBlock: '172.31.0.0/20', maxAzs: 2 } },
// or: vpc: { vpcId: 'vpc-0123456789abcdef0' }        // literal id, or 'resolve:ssm:/path' to read from SSM

managedVpc accepts cidrBlock (172.31.0.0/20), subnetCidrMask (24), maxAzs (2), subnetType, restrictDefaultSecurityGroup (true), allowAllOutbound (true), flowLogsBucketName, and codeBuildVpcInterfaces. See Networking.

Express mode

express: true deploys with CloudFormation express mode (cdk deploy --express): CloudFormation reports each stack complete as soon as it applies the resource configuration, without waiting for resources to stabilize — materially faster for slow-to-stabilize stacks. Express runs with rollback disabled (a failed deploy is left in a failed state for inspection). AWS does not recommend express mode for production; it targets fast iterative deployments. Off by default.

Container mode

deployerImage: BuildImage.docker({ ... }) switches the pipeline to build and push a config-agnostic deployer image instead of deploying stages (CodePipeline engine only). The deploy side is authored separately with defineDeployment in a deploy.config.ts. See the Container mode guide for the full two-repository flow.

Pipeline role names

Force deterministic IAM role names on the pipeline's own roles — the parity replacement for Blueprint's PipelineRoleNameEnforcementPlugin. Use it when external cross-account trust policies, SCPs, or permission boundaries reference fixed role names. Any field you omit keeps the CDK-generated name, so existing pipelines are unaffected. The two engines expose different role sets, so each takes its own field (the GITHUB_ACTIONS engine's only role is already nameable via githubActions.roleName).

For EngineType.CDK_PIPELINES, use pipelineRoleNames:

pipelineRoleNames: {
  pipeline: 'my-app-codepipeline-role', // the CodePipeline pipeline role
  assetsFile: 'my-app-codepipeline-assets-file-role', // CDK Pipelines file-publishing role
  assetsDocker: 'my-app-codepipeline-assets-docker-role', // CDK Pipelines docker-publishing role
},

For the flat EngineType.CODEPIPELINE, use codePipelineRoleNames:

codePipelineRoleNames: {
  pipeline: 'my-app-codepipeline-role', // the CodePipeline pipeline role
  buildRolePrefix: 'my-app-build', // per-stage CodeBuild roles => `<prefix>-<projectId>`, e.g. `my-app-build-deploy-dev`
},

Cross-account externalId

When a stage forces a deployRole (see Stages), you can present an ExternalId on the role assumption — the sts:ExternalId condition a hardened cross-account trust policy requires. It threads into the synthesized cloud assembly as DefaultStackSynthesizer.deployRoleExternalId; the CDK CLI then uses it while assuming the assembly's deployment role. It is not CloudFormation's execution-role RoleARN, and it is a no-op without a deployRole.

The installed CDK_PIPELINES engine does not carry an ExternalId from the assembly, and the installed GitHub engine hardcodes a different value. Those engines therefore reject configured deploy-role ExternalIds instead of silently ignoring them. APP_STAGING accepts custom deployment and CloudFormation execution roles, but the alpha deployment-identity API does not expose an ExternalId. It therefore rejects a nonblank ExternalId paired with a deploy role.

Set a pipeline-level default with deployRoleExternalId, and override per stage with deployment.externalId (the per-stage value wins):

export default defineCICD({
  application: 'my-app',
  repository: Repository.codestarConnection(
    'my-org/my-app',
    'arn:aws:codestar-connections:eu-west-1:111111111111:connection/01234567-89ab-cdef-0123-456789abcdef',
  ),
  deployRoleExternalId: 'org-wide-external-id', // pipeline-level default
  stages: [
    {
      name: 'prod',
      env: { account: '333333333333', region: 'eu-west-1' },
      deployment: {
        deployRole: 'arn:aws:iam::333333333333:role/Deployer',
        externalId: 'prod-only-external-id', // overrides the pipeline-level default for this stage
      },
    },
  ],
});

Either value may be a literal, or a resolve:secretsmanager:<arn> reference resolved at exec time from the secret's SecretString (so the ExternalId can live in Secrets Manager rather than in cicd.config.ts). The generated roles grant secretsmanager:GetSecretValue; use the Secrets Manager AWS-managed encryption key. A customer-managed KMS key additionally needs kms:Decrypt, which this configuration does not currently accept.

Security plugins

plugins selects the security-hardening Aspects the wrapper applies tree-wide (PluginRef[], each a { name, version }). Omitting it applies the default-on set; [] opts out of all of them; a non-empty list completely overrides the defaults (list only what you want). A name that is not a built-in is a custom plugin and must be registered in bin/ via CdkCicd.addPlugin.

plugins: [{ name: 'EncryptBucketOnTransit', version: '1.0.0' }], // only this one; defaults dropped
// plugins: [],                                                   // opt out of all default hardening

See Getting started for the built-in set and the custom-plugin flow.