|
| 1 | ++++ |
| 2 | +title = "Appendix" |
| 3 | +date = 2020-07-06T17:49:47-04:00 |
| 4 | +weight = 1000 |
| 5 | +pre = "<b>7. </b>" |
| 6 | ++++ |
| 7 | + |
| 8 | +Prior versions of this workshop used the AWS CDK to create the CI/CD pipeline. CDK is a fantastic |
| 9 | +tool! If you are looking for the CDK version, below is an example CI/CD pipeline in TypeScript using |
| 10 | +CDK V2. |
| 11 | + |
| 12 | +Note that this example from `v3` of this workshop is missing a few features compared to the one setup by |
| 13 | +SAM Pipelines. It does not have a specific unit test phase and does not self-update. |
| 14 | + |
| 15 | +```typescript |
| 16 | +import { Stack, StackProps } from "aws-cdk-lib" |
| 17 | +import { Construct } from "constructs" |
| 18 | + |
| 19 | +import * as codebuild from "aws-cdk-lib/aws-codebuild" |
| 20 | +import * as codecommit from "aws-cdk-lib/aws-codecommit" |
| 21 | +import * as codepipeline from "aws-cdk-lib/aws-codepipeline" |
| 22 | +import * as codepipeline_actions from "aws-cdk-lib/aws-codepipeline-actions" |
| 23 | +import * as s3 from "aws-cdk-lib/aws-s3" |
| 24 | + |
| 25 | +export class ServerlessCicdPipelineStack extends Stack { |
| 26 | + constructor(scope: Construct, id: string, props?: StackProps) { |
| 27 | + super(scope, id, props) |
| 28 | + |
| 29 | + const artifactsBucket = new s3.Bucket(this, "ArtifactsBucket") |
| 30 | + |
| 31 | + const codeRepo = codecommit.Repository.fromRepositoryName(this, "AppRepository", "sam-app") |
| 32 | + // Pipeline creation starts |
| 33 | + const pipeline = new codepipeline.Pipeline(this, "Pipeline", { |
| 34 | + artifactBucket: artifactsBucket, |
| 35 | + }) |
| 36 | + |
| 37 | + // Declare source code as an artifact |
| 38 | + const sourceOutput = new codepipeline.Artifact() |
| 39 | + |
| 40 | + // Add source stage to pipeline |
| 41 | + pipeline.addStage({ |
| 42 | + stageName: "Source", |
| 43 | + actions: [ |
| 44 | + new codepipeline_actions.CodeCommitSourceAction({ |
| 45 | + actionName: "CodeCommit_Source", |
| 46 | + repository: codeRepo, |
| 47 | + output: sourceOutput, |
| 48 | + branch: "main", |
| 49 | + }), |
| 50 | + ], |
| 51 | + }) |
| 52 | + |
| 53 | + // Declare build output as artifacts |
| 54 | + const buildOutput = new codepipeline.Artifact() |
| 55 | + |
| 56 | + // Declare a new CodeBuild project |
| 57 | + const buildProject = new codebuild.PipelineProject(this, "Build", { |
| 58 | + environment: { buildImage: codebuild.LinuxBuildImage.AMAZON_LINUX_2_2 }, |
| 59 | + environmentVariables: { |
| 60 | + PACKAGE_BUCKET: { |
| 61 | + value: artifactsBucket.bucketName, |
| 62 | + }, |
| 63 | + }, |
| 64 | + }) |
| 65 | + |
| 66 | + // Add the build stage to our pipeline |
| 67 | + pipeline.addStage({ |
| 68 | + stageName: "Build", |
| 69 | + actions: [ |
| 70 | + new codepipeline_actions.CodeBuildAction({ |
| 71 | + actionName: "Build", |
| 72 | + project: buildProject, |
| 73 | + input: sourceOutput, |
| 74 | + outputs: [buildOutput], |
| 75 | + }), |
| 76 | + ], |
| 77 | + }) |
| 78 | + |
| 79 | + // Prod stage |
| 80 | + pipeline.addStage({ |
| 81 | + stageName: "Dev", |
| 82 | + actions: [ |
| 83 | + new codepipeline_actions.CloudFormationCreateReplaceChangeSetAction({ |
| 84 | + actionName: "CreateChangeSet", |
| 85 | + templatePath: buildOutput.atPath("packaged.yaml"), |
| 86 | + stackName: "sam-app-dev", |
| 87 | + adminPermissions: true, |
| 88 | + changeSetName: "sam-app-dev-changeset", |
| 89 | + runOrder: 1, |
| 90 | + }), |
| 91 | + new codepipeline_actions.CloudFormationExecuteChangeSetAction({ |
| 92 | + actionName: "Deploy", |
| 93 | + stackName: "sam-app-dev", |
| 94 | + changeSetName: "sam-app-dev-changeset", |
| 95 | + runOrder: 2, |
| 96 | + }), |
| 97 | + ], |
| 98 | + }) |
| 99 | + |
| 100 | + // Production stage |
| 101 | + pipeline.addStage({ |
| 102 | + stageName: "Prod", |
| 103 | + actions: [ |
| 104 | + new codepipeline_actions.CloudFormationCreateReplaceChangeSetAction({ |
| 105 | + actionName: "CreateChangeSet", |
| 106 | + templatePath: buildOutput.atPath("packaged.yaml"), |
| 107 | + stackName: "sam-app-prod", |
| 108 | + adminPermissions: true, |
| 109 | + changeSetName: "sam-app-prod-changeset", |
| 110 | + runOrder: 1, |
| 111 | + }), |
| 112 | + new codepipeline_actions.CloudFormationExecuteChangeSetAction({ |
| 113 | + actionName: "Deploy", |
| 114 | + stackName: "sam-app-prod", |
| 115 | + changeSetName: "sam-app-prod-changeset", |
| 116 | + runOrder: 2, |
| 117 | + }), |
| 118 | + ], |
| 119 | + }) |
| 120 | + } |
| 121 | +} |
| 122 | +``` |
| 123 | + |
| 124 | +The following `buildspec.yml` file shows how to build and test a Node AWS SAM application with the |
| 125 | +pipeline above. It's possible to extract the test command into it's own pipeline stage so that tests |
| 126 | +are run once rather than per-stage. |
| 127 | + |
| 128 | +```yaml |
| 129 | +# sam-app/buildspec.yml |
| 130 | +version: 0.2 |
| 131 | +phases: |
| 132 | + install: |
| 133 | + runtime-versions: |
| 134 | + nodejs: 12 |
| 135 | + commands: |
| 136 | + # Install packages or any pre-reqs in this phase. |
| 137 | + # Upgrading SAM CLI to latest version |
| 138 | + - pip3 install --upgrade aws-sam-cli |
| 139 | + - sam --version |
| 140 | + - cd hello-world |
| 141 | + - npm install |
| 142 | + |
| 143 | + pre_build: |
| 144 | + commands: |
| 145 | + - npm run test |
| 146 | + |
| 147 | + build: |
| 148 | + commands: |
| 149 | + # Use Build phase to build your artifacts (compile, etc.) |
| 150 | + - cd .. |
| 151 | + - sam build |
| 152 | + |
| 153 | + post_build: |
| 154 | + commands: |
| 155 | + # Use Post-Build for notifications, git tags, upload artifacts to S3 |
| 156 | + - sam package --s3-bucket $PACKAGE_BUCKET --output-template-file packaged.yaml |
| 157 | + |
| 158 | +artifacts: |
| 159 | + discard-paths: yes |
| 160 | + files: |
| 161 | + # List of local artifacts that will be passed down the pipeline |
| 162 | + - packaged.yaml |
| 163 | +``` |
0 commit comments