Skip to content
This repository was archived by the owner on Nov 4, 2022. It is now read-only.

Commit bfdccf2

Browse files
committed
Finished creating pipeline with CDK
1 parent 9ba756a commit bfdccf2

File tree

13 files changed

+310
-86
lines changed

13 files changed

+310
-86
lines changed

workshop/content/buildpipe/buildspec/_index.en.md

Lines changed: 0 additions & 64 deletions
This file was deleted.
Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
+++
2-
title = "Verify pipeline running"
2+
title = "Verify pipeline"
33
date = 2019-11-05T14:20:52-08:00
44
weight = 35
55
+++
66

7-
Once you push the buildspec.yaml file into the code repository, the pipeline should trigger automatically. This time, the build step should succeed along with the deployment steps.
7+
Once your pipeline has finished every stage successfully, it should look like the following screenshot:
88

9-
![VerifyPipelineRunning](/images/screenshot-pipeline-verify-3.png)
9+
![VerifyPipelineRunning](/images/chapter4/screenshot-pipeline-verify-3.png)
1010

11-
{{% notice tip %}}
12-
This pipeline performs deployments using CloudFormation ChangeSets. If you are not familiar with them, you can learn about them here: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-changesets.html.
13-
{{% /notice %}}
14-
15-
#### Congratulations! You have created a CI/CD pipeline.
11+
#### Congratulations! You have created a CI/CD pipeline for a Serverless application!
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
+++
2+
title = "Build Stage"
3+
date = 2019-11-01T15:26:09-07:00
4+
weight = 20
5+
+++
6+
7+
The build stage is where your Serverless application gets built and packaged. We are going to use AWS CodeBuild as the Build provider for our pipeline. It is worth mentioning that CodePipeline also supports other providers like Jenkins, TeamCity or CloudBees.
8+
9+
AWS CodeBuild is a great option because you only pay for the time where your build is running, which makes it very cost effective compared to running a dedicated build server 24 hours a day when you really only build during office hours. It is also container-based which means that you can bring your own Docker container image where your build runs, or [use a managed image](https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-available.html) provided by CodeBuild.
10+
11+
Let's go ahead and add a Build stage to our pipeline:
12+
13+
```js
14+
// lib/pipeline-stack.ts
15+
16+
import * as cdk from '@aws-cdk/core';
17+
import s3 = require('@aws-cdk/aws-s3');
18+
import codecommit = require('@aws-cdk/aws-codecommit');
19+
import codepipeline = require('@aws-cdk/aws-codepipeline');
20+
import codepipeline_actions = require('@aws-cdk/aws-codepipeline-actions');
21+
import codebuild = require('@aws-cdk/aws-codebuild');
22+
23+
export class PipelineStack extends cdk.Stack {
24+
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
25+
super(scope, id, props);
26+
27+
// The code that defines your stack goes here
28+
const artifactsBucket = new s3.Bucket(this, "ArtifactsBucket");
29+
30+
// Import existing CodeCommit sam-app repository
31+
const codeRepo = codecommit.Repository.fromRepositoryName(
32+
this,
33+
'AppRepository', // Logical name within CloudFormation
34+
'sam-app' // Repository name
35+
);
36+
37+
// Pipeline creation starts
38+
const pipeline = new codepipeline.Pipeline(this, 'Pipeline', {
39+
artifactBucket: artifactsBucket
40+
});
41+
42+
// Declare source code as an artifact
43+
const sourceOutput = new codepipeline.Artifact();
44+
45+
// Add source stage to pipeline
46+
pipeline.addStage({
47+
stageName: 'Source',
48+
actions: [
49+
new codepipeline_actions.CodeCommitSourceAction({
50+
actionName: 'CodeCommit_Source',
51+
repository: codeRepo,
52+
output: sourceOutput,
53+
}),
54+
],
55+
});
56+
57+
// Declare build output as artifacts
58+
const buildOutput = new codepipeline.Artifact();
59+
60+
// Declare a new CodeBuild project
61+
const buildProject = new codebuild.PipelineProject(this, 'Build', {
62+
environment: { buildImage: codebuild.LinuxBuildImage.AMAZON_LINUX_2_2 },
63+
environmentVariables: {
64+
'PACKAGE_BUCKET': {
65+
value: artifactsBucket.bucketName
66+
}
67+
}
68+
});
69+
70+
// Add the build stage to our pipeline
71+
pipeline.addStage({
72+
stageName: 'Build',
73+
actions: [
74+
new codepipeline_actions.CodeBuildAction({
75+
actionName: 'Build',
76+
project: buildProject,
77+
input: sourceOutput,
78+
outputs: [buildOutput],
79+
}),
80+
],
81+
});
82+
83+
}
84+
}
85+
```
86+
87+
### Deploy the pipeline
88+
89+
From your terminal, run the following commands to deploy the pipeline:
90+
91+
```
92+
npm run build
93+
cdk deploy
94+
```
95+
96+
### Verify pipeline creation
97+
98+
Navigate to the [AWS CodePipeline Console](https://console.aws.amazon.com/codesuite/codepipeline/home) and click on your newly created pipeline!
99+
100+
![VerifyPipeline](/images/chapter4/screenshot-pipeline-verify-1.png)
101+
102+
Oh no! the Build step failed. **Don't worry, this is expected** because we haven't specified what commands to run on the build yet so AWS CodeBuild doesn't know how to build our Serverless application.
103+
104+
![VerifyPipeline](/images/chapter4/screenshot-pipeline-verify-2.png)
105+
106+
Let's fix that.
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
+++
2+
title = "Buildspec file"
3+
date = 2019-10-04T12:54:48-07:00
4+
weight = 30
5+
+++
6+
7+
A buildspec file is a series of commands in YAML format that CodeBuild executes to build your application. This file is placed in the root folder of a SAM application and CodeBuild will automatically find it and run it during build time.
8+
9+
In your Cloud9 editor, create a new file named `buildspec.yml` in the root (top level) of the _sam-app_ directory by right clicking on the `sam-app` folder and selecting New file.
10+
11+
{{% notice tip %}}
12+
The extension of the file can be either `yml` or `yaml`, CodeBuild will find it either way.
13+
{{% /notice%}}
14+
15+
![CreateNewFileCloud9](/images/screenshot-cloud9-new-file.png)
16+
17+
Then, paste the following content into the file:
18+
19+
```
20+
# ~/environment/sam-app/buildspec.yml
21+
22+
version: 0.2
23+
phases:
24+
install:
25+
runtime-versions:
26+
nodejs: 12
27+
commands:
28+
# Install packages or any pre-reqs in this phase.
29+
# Upgrading SAM CLI to latest version
30+
- pip3 install --upgrade aws-sam-cli
31+
- sam --version
32+
# Installing project dependencies
33+
- cd hello-world
34+
- npm install
35+
36+
pre_build:
37+
commands:
38+
# Run tests, lint scripts or any other pre-build checks.
39+
- npm run test
40+
41+
build:
42+
commands:
43+
# Use Build phase to build your artifacts (compile, etc.)
44+
- cd ..
45+
- sam build
46+
47+
post_build:
48+
commands:
49+
# Use Post-Build for notifications, git tags, upload artifacts to S3
50+
- sam package --s3-bucket $PACKAGE_BUCKET --output-template-file packaged.yaml
51+
52+
artifacts:
53+
discard-paths: yes
54+
files:
55+
# List of local artifacts that will be passed down the pipeline
56+
- packaged.yaml
57+
```
58+
59+
**Save the file**. It should look like the following screenshot.
60+
61+
![CreateBuildspec](/images/chapter4/screenshot-buildspec.png)
62+
63+
Take a moment to understand the structure of the file and feel free to read the Buildsec Reference here: https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html.
64+
65+
### Push code changes
66+
Commit your changes and push them to the repository.
67+
68+
```
69+
git add .
70+
git commit -m "Added buildspec.yml"
71+
git push
72+
```
73+
74+
### Verify build succeeds
75+
76+
Navigate to your CodePipeline again, and wait for it to trigger automatically. This time the build will succeed:
77+
78+
![BuildSucceeds](/images/chapter4/screenshot-build-succeeds.png)
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
+++
2+
title = "Deploy stage"
3+
date = 2019-10-04T12:54:48-07:00
4+
weight = 40
5+
+++
6+
7+
The deploy stage is where your SAM application and all its resources are created an in an AWS account. The most common way to do this is by using CloudFormation ChangeSets to deploy. This means that this stage will have 2 actions: the _CreateChangeSet_ and the _ExecuteChangeSet_.
8+
9+
Add the Deploy stage to your pipeline:
10+
11+
```js
12+
// lib/pipeline-stack.ts
13+
14+
import * as cdk from '@aws-cdk/core';
15+
import s3 = require('@aws-cdk/aws-s3');
16+
import codecommit = require('@aws-cdk/aws-codecommit');
17+
import codepipeline = require('@aws-cdk/aws-codepipeline');
18+
import codepipeline_actions = require('@aws-cdk/aws-codepipeline-actions');
19+
import codebuild = require('@aws-cdk/aws-codebuild');
20+
21+
export class PipelineStack extends cdk.Stack {
22+
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
23+
super(scope, id, props);
24+
25+
// The code that defines your stack goes here
26+
const artifactsBucket = new s3.Bucket(this, "ArtifactsBucket");
27+
28+
// Import existing CodeCommit sam-app repository
29+
const codeRepo = codecommit.Repository.fromRepositoryName(
30+
this,
31+
'AppRepository', // Logical name within CloudFormation
32+
'sam-app' // Repository name
33+
);
34+
35+
// Pipeline creation starts
36+
const pipeline = new codepipeline.Pipeline(this, 'Pipeline', {
37+
artifactBucket: artifactsBucket
38+
});
39+
40+
// Declare source code as an artifact
41+
const sourceOutput = new codepipeline.Artifact();
42+
43+
// Add source stage to pipeline
44+
pipeline.addStage({
45+
stageName: 'Source',
46+
actions: [
47+
new codepipeline_actions.CodeCommitSourceAction({
48+
actionName: 'CodeCommit_Source',
49+
repository: codeRepo,
50+
output: sourceOutput,
51+
}),
52+
],
53+
});
54+
55+
// Declare build output as artifacts
56+
const buildOutput = new codepipeline.Artifact();
57+
58+
// Declare a new CodeBuild project
59+
const buildProject = new codebuild.PipelineProject(this, 'Build', {
60+
environment: { buildImage: codebuild.LinuxBuildImage.AMAZON_LINUX_2_2 },
61+
environmentVariables: {
62+
'PACKAGE_BUCKET': {
63+
value: artifactsBucket.bucketName
64+
}
65+
}
66+
});
67+
68+
// Add the build stage to our pipeline
69+
pipeline.addStage({
70+
stageName: 'Build',
71+
actions: [
72+
new codepipeline_actions.CodeBuildAction({
73+
actionName: 'Build',
74+
project: buildProject,
75+
input: sourceOutput,
76+
outputs: [buildOutput],
77+
}),
78+
],
79+
});
80+
81+
// Deploy stage
82+
pipeline.addStage({
83+
stageName: 'Dev',
84+
actions: [
85+
new codepipeline_actions.CloudFormationCreateReplaceChangeSetAction({
86+
actionName: 'CreateChangeSet',
87+
templatePath: buildOutput.atPath("packaged.yaml"),
88+
stackName: 'sam-app',
89+
adminPermissions: true,
90+
changeSetName: 'sam-app-dev-changeset',
91+
runOrder: 1
92+
}),
93+
new codepipeline_actions.CloudFormationExecuteChangeSetAction({
94+
actionName: 'Deploy',
95+
stackName: 'sam-app',
96+
changeSetName: 'sam-app-dev-changeset',
97+
runOrder: 2
98+
}),
99+
],
100+
});
101+
102+
}
103+
}
104+
```
105+
106+
### Deploy the pipeline
107+
108+
On your terminal, run the following commands from within the _pipeline_ directory:
109+
110+
```
111+
npm run build
112+
cdk deploy
113+
```
114+
115+
The CDK CLI might ask you to confirm the changes before deploying, this is because we are giving Admin permissions to the IAM role that deploys our application. This is generally not a bad practice since this role can only be assumed by CloudFormation and not by a human, however, if your organization has a stricter security posture you may want to consider providing a fine grain policy for the deployment role.
116+
117+
### Trigger a release
118+
119+
Navigate to your pipeline and you will see the Deploy stage has been added, however, it is currently grayed out because it hasn't been triggered. Let's just trigger a new run of the pipeline manually by clicking the Release Change buttton.
120+
121+
![ReleaseChange](/images/chapter4/screenshot-release-change.png)

0 commit comments

Comments
 (0)