Continuous Integration / Continuous Delivery for CDK Applications
This API may emit warnings. Backward compatibility is not guaranteed.
This library includes a CodePipeline composite Action for deploying AWS CDK Applications.
This module is part of the AWS Cloud Development Kit project.
Replacement recommended
This library has been deprecated. We recommend you use the
@aws-cdk/pipelines module instead.
Limitations
The construct library in it's current form has the following limitations:
- It can only deploy stacks that are hosted in the same AWS account and region as the CodePipeline is.
- Stacks that make use of
Asset
s cannot be deployed successfully.
Getting Started
In order to add the PipelineDeployStackAction
to your CodePipeline, you need to have a CodePipeline artifact that
contains the result of invoking cdk synth -o <dir>
on your CDK App. You can for example achieve this using a
CodeBuild project.
The example below defines a CDK App that contains 3 stacks:
CodePipelineStack
manages the CodePipeline resources, and self-updates before deploying any other stackServiceStackA
and ServiceStackB
are service infrastructure stacks, and need to be deployed in this order
┏━━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Source ┃ ┃ Build ┃ ┃ Self-Update ┃ ┃ Deploy ┃
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃
┃ ┌────────────┐ ┃ ┃ ┌────────────┐ ┃ ┃ ┌─────────────┐ ┃ ┃ ┌─────────────┐ ┌─────────────┐ ┃
┃ │ GitHub ┣━╋━━╋━▶ CodeBuild ┣━╋━━╋━▶Deploy Stack ┣━╋━━╋━▶Deploy Stack ┣━▶Deploy Stack │ ┃
┃ │ │ ┃ ┃ │ │ ┃ ┃ │PipelineStack│ ┃ ┃ │ServiceStackA│ │ServiceStackB│ ┃
┃ └────────────┘ ┃ ┃ └────────────┘ ┃ ┃ └─────────────┘ ┃ ┃ └─────────────┘ └─────────────┘ ┃
┗━━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
index.ts
import * as codebuild from '@aws-cdk/aws-codebuild';
import * as codepipeline from '@aws-cdk/aws-codepipeline';
import * as codepipeline_actions from '@aws-cdk/aws-codepipeline-actions';
import * as cdk from '@aws-cdk/core';
import * as cicd from '@aws-cdk/app-delivery';
import * as iam from '@aws-cdk/aws-iam';
class MyServiceStackA extends cdk.Stack {}
class MyServiceStackB extends cdk.Stack {}
const app = new cdk.App();
const pipelineStack = new cdk.Stack(app, 'PipelineStack');
const pipeline = new codepipeline.Pipeline(pipelineStack, 'CodePipeline', {
restartExecutionOnUpdate: true,
});
const sourceOutput = new codepipeline.Artifact();
const source = new codepipeline_actions.GitHubSourceAction({
actionName: 'GitHub',
output: sourceOutput,
owner: 'myName',
repo: 'myRepo',
oauthToken: cdk.SecretValue.unsafePlainText('secret'),
});
pipeline.addStage({
stageName: 'source',
actions: [source],
});
const project = new codebuild.PipelineProject(pipelineStack, 'CodeBuild', {
});
const synthesizedApp = new codepipeline.Artifact();
const buildAction = new codepipeline_actions.CodeBuildAction({
actionName: 'CodeBuild',
project,
input: sourceOutput,
outputs: [synthesizedApp],
});
pipeline.addStage({
stageName: 'build',
actions: [buildAction],
});
const selfUpdateStage = pipeline.addStage({ stageName: 'SelfUpdate' });
selfUpdateStage.addAction(new cicd.PipelineDeployStackAction({
stack: pipelineStack,
input: synthesizedApp,
adminPermissions: true,
}));
const deployStage = pipeline.addStage({ stageName: 'Deploy' });
const serviceStackA = new MyServiceStackA(app, 'ServiceStackA', { });
const deployServiceAAction = new cicd.PipelineDeployStackAction({
stack: serviceStackA,
input: synthesizedApp,
adminPermissions: false,
});
deployStage.addAction(deployServiceAAction);
const myResourceArn = 'arn:partition:service:region:account-id:resource-id';
deployServiceAAction.addToDeploymentRolePolicy(new iam.PolicyStatement({
actions: ['service:SomeAction'],
resources: [myResourceArn],
}));
const serviceStackB = new MyServiceStackB(app, 'ServiceStackB', { });
deployStage.addAction(new cicd.PipelineDeployStackAction({
stack: serviceStackB,
input: synthesizedApp,
createChangeSetRunOrder: 998,
adminPermissions: true,
}));
buildspec.yml
The repository can contain a file at the root level named buildspec.yml
, or
you can in-line the buildspec. Note that buildspec.yaml
is not compatible.
For example, a TypeScript or Javascript CDK App can add the following buildspec.yml
at the root of the repository:
version: 0.2
phases:
install:
commands:
- npm install
build:
commands:
- npm run build
- npm run cdk synth -- -o dist
artifacts:
base-directory: dist
files: '**/*'
The PipelineDeployStackAction
expects it's input
to contain the result of
synthesizing a CDK App using the cdk synth -o <directory>
.