in lib/pipeline-stack.ts [24:191]
constructor(app: App, id: string, props: PipelineStackProps) {
super(app, id, props);
const repository = codecommit.Repository.fromRepositoryName(this, 'CodeCommitRepo', `repo-${this.account}`);
const prodDeploymentRole = iam.Role.fromRoleArn(this, 'ProdDeploymentRole', `arn:aws:iam::${props.prodAccountId}:role/CloudFormationDeploymentRole`, {
mutable: false
});
const prodCrossAccountRole = iam.Role.fromRoleArn(this, 'ProdCrossAccountRole', `arn:aws:iam::${props.prodAccountId}:role/CodePipelineCrossAccountRole`, {
mutable: false
});
const prodAccountRootPrincipal = new iam.AccountPrincipal(props.prodAccountId);
const key = new kms.Key(this, 'ArtifactKey', {
alias: 'key/artifact-key',
});
key.grantDecrypt(prodAccountRootPrincipal);
key.grantDecrypt(prodCrossAccountRole);
const artifactBucket = new s3.Bucket(this, 'ArtifactBucket', {
bucketName: `artifact-bucket-${this.account}`,
removalPolicy: RemovalPolicy.DESTROY,
encryption: s3.BucketEncryption.KMS,
encryptionKey: key
});
artifactBucket.grantPut(prodAccountRootPrincipal);
artifactBucket.grantRead(prodAccountRootPrincipal);
const cdkBuild = new codebuild.PipelineProject(this, 'CdkBuild', {
buildSpec: codebuild.BuildSpec.fromObject({
version: '0.2',
phases: {
install: {
commands: [
'npm install'
],
},
build: {
commands: [
'npm run build',
'npm run cdk synth -- -o dist'
],
},
},
artifacts: {
'base-directory': 'dist',
files: [
'*ApplicationStack.template.json',
],
},
}),
environment: {
buildImage: codebuild.LinuxBuildImage.UBUNTU_14_04_NODEJS_10_14_1,
},
encryptionKey: key
});
const lambdaBuild = new codebuild.PipelineProject(this, 'LambdaBuild', {
buildSpec: codebuild.BuildSpec.fromObject({
version: '0.2',
phases: {
install: {
commands: [
'cd app',
'npm install',
],
},
build: {
commands: 'npm run build',
},
},
artifacts: {
'base-directory': 'app',
files: [
'index.js',
'node_modules/**/*',
],
},
}),
environment: {
buildImage: codebuild.LinuxBuildImage.UBUNTU_14_04_NODEJS_10_14_1,
},
encryptionKey: key
});
const sourceOutput = new codepipeline.Artifact();
const cdkBuildOutput = new codepipeline.Artifact('CdkBuildOutput');
const lambdaBuildOutput = new codepipeline.Artifact('LambdaBuildOutput');
const pipeline = new codepipeline.Pipeline(this, 'Pipeline', {
pipelineName: 'CrossAccountPipeline',
artifactBucket: artifactBucket,
stages: [
{
stageName: 'Source',
actions: [
new codepipeline_actions.CodeCommitSourceAction({
actionName: 'CodeCommit_Source',
repository: repository,
output: sourceOutput,
}),
],
},
{
stageName: 'Build',
actions: [
new codepipeline_actions.CodeBuildAction({
actionName: 'Application_Build',
project: lambdaBuild,
input: sourceOutput,
outputs: [lambdaBuildOutput],
}),
new codepipeline_actions.CodeBuildAction({
actionName: 'CDK_Synth',
project: cdkBuild,
input: sourceOutput,
outputs: [cdkBuildOutput],
}),
],
},
{
stageName: 'Deploy_Dev',
actions: [
new codepipeline_actions.CloudFormationCreateUpdateStackAction({
actionName: 'Deploy',
templatePath: cdkBuildOutput.atPath('DevApplicationStack.template.json'),
stackName: 'DevApplicationDeploymentStack',
adminPermissions: true,
parameterOverrides: {
...props.devApplicationStack.lambdaCode.assign(lambdaBuildOutput.s3Location),
},
extraInputs: [lambdaBuildOutput],
})
],
},
{
stageName: 'Deploy_Prod',
actions: [
new codepipeline_actions.CloudFormationCreateUpdateStackAction({
actionName: 'Deploy',
templatePath: cdkBuildOutput.atPath('ProdApplicationStack.template.json'),
stackName: 'ProdApplicationDeploymentStack',
adminPermissions: true,
parameterOverrides: {
...props.prodApplicationStack.lambdaCode.assign(lambdaBuildOutput.s3Location),
},
deploymentRole: prodDeploymentRole,
capabilities: [cloudformation.CloudFormationCapabilities.ANONYMOUS_IAM],
extraInputs: [lambdaBuildOutput],
role: prodCrossAccountRole,
}),
],
},
],
});
pipeline.addToRolePolicy(new iam.PolicyStatement({
actions: ['sts:AssumeRole'],
resources: [`arn:aws:iam::${props.prodAccountId}:role/*`]
}));
new CfnOutput(this, 'ArtifactBucketEncryptionKeyArn', {
value: key.keyArn,
exportName: 'ArtifactBucketEncryptionKey'
});
}