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

Commit cee4619

Browse files
committed
Merged branch cdk into dev
2 parents 9939fa5 + 1b991ed commit cee4619

31 files changed

+741
-32
lines changed

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
# CI/CD for Serverless Applications Workshop
22

3-
In this workshop, you will learn how to start a new Serverless application from scratch using the AWS Serverless Application Model (AWS SAM) and how to fully automate builds and deployments by building a continous delivery pipeline using AWS CodeCommit, AWS CodeBuild and AWS CodePipeline. You will also learn how to test a Serverless application locally using the SAM CLI.
3+
In this workshop, you will learn how to start a new Serverless application from scratch using the AWS Serverless Application Model (AWS SAM) and how to fully automate builds and deployments by building a continous delivery pipeline using the AWS CDK. You will also learn how to run a Serverless application locally using the SAM CLI.
44

55
![Image](workshop/static/images/github-home.png)
66

77
## Getting Started
88

9-
[https://cicd.serverlessworkshops.io](https://cicd.serverlessworkshops.io)
9+
Workshop URL: [https://cicd.serverlessworkshops.io](https://cicd.serverlessworkshops.io)
10+
11+
Looking for the old version of the workshop that **doesn't** use the AWS CDK? [https://v1.cicd.serverlessworkshops.io](https://cicd.serverlessworkshops.io).
1012

1113
## Want to contribute?
1214

13-
Check our [contribution guidelines](CONTRIBUTING.md) before submitting a pull request. Any contribution must be done to the `dev` branch.
15+
Check our [contribution guidelines](CONTRIBUTING.md) before submitting a pull request. Please submit your contributions to the `dev` branch.
1416

1517
## License
1618

workshop/content/_index.en.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ weight = 1
55
+++
66
# CI/CD for Serverless Applications
77

8-
In this workshop, you will learn how to start a new Serverless application from scratch using the AWS Serverless Application Model (AWS SAM) and how to fully automate builds and deployments by building a continous delivery pipeline using AWS CodeCommit, AWS CodeBuild and AWS CodePipeline. You will also learn how to test a Serverless application locally using the SAM CLI.
8+
In this workshop, you will learn how to start a new Serverless application from scratch using the AWS Serverless Application Model (AWS SAM) and how to fully automate builds and deployments by building a continous delivery pipeline using the AWS CDK. You will also learn how to run a Serverless application locally using the SAM CLI.
99

10-
![Intro](/images/intro.png)
10+
![Intro](/images/github-home.png)
1111

1212
### Issues, Comments, Feedback?
1313

workshop/content/buildpipe/_index.en.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ pre = "<b>4. </b>"
88

99
# Build the pipeline
1010

11-
In this chapter you are going to automate the build, package and deploy commands by creating a continous delivery pipeline that, a high level, looks like the diagram below.
11+
In this chapter you are going to learn how to automate the build, package and deploy commands by creating a continous delivery pipeline using AWS Code Pipeline.
1212

1313
![SimplePipeline](/images/pipeline-art.png)
1414

15-
The services used in this chapter are AWS CodeCommit, AWS CodeBuild, AWS CodePipeline, AWS CloudFormation and the AWS Serverless Application Repository.
15+
The services used in this chapter are CodeCommit, CodeBuild, CodePipeline, CloudFormation and the AWS CDK.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
+++
2+
title = "Setup a CDK project"
3+
date = 2019-11-01T15:26:09-07:00
4+
weight = 21
5+
+++
6+
7+
First of all, install the CDK CLI by running the following command from your terminal.
8+
```
9+
npm install -g aws-cdk
10+
```
11+
12+
### Initialize project
13+
14+
Now, let's create a folder within our _sam-app_ directory where the pipeline code will reside.
15+
```
16+
cd ~/environment/sam-app
17+
mkdir pipeline
18+
cd pipeline
19+
```
20+
21+
Initialize a new CDK project within the _pipeline_ folder by running the following command:
22+
23+
```
24+
cdk init --language typescript
25+
```
26+
27+
Now install the CDK modules that we will be using to build a pipeline:
28+
29+
```
30+
npm install --save @aws-cdk/aws-codedeploy @aws-cdk/aws-codebuild
31+
npm install --save @aws-cdk/aws-codecommit @aws-cdk/aws-codepipeline-actions
32+
npm install --save @aws-cdk/aws-s3
33+
```
34+
35+
After a few seconds, our new CDK project should look like this:
36+
37+
![CdkInit](/images/chapter4/screenshot-cdk-init.png)
38+
39+
40+
### Project structure
41+
42+
At this point, your project should have the structure below (only the most relevant files and folders are shown). Within the CDK project, the main file you will be interacting with is the _pipeline-stack.ts_. Don't worry about the rest of the files for now.
43+
44+
```
45+
sam-app # SAM application root
46+
├── hello-world # Lambda code
47+
├── samconfig.toml # Config file for manual deployments
48+
├── template.yaml # SAM template
49+
└── pipeline # CDK project root
50+
└── lib
51+
└── pipeline-stack.ts # Pipeline definition
52+
└── bin
53+
└── pipeline.ts # Entry point for CDK project
54+
├── cdk.json
55+
├── tsconfig.json
56+
├── package.json
57+
└── jest.config.js
58+
```
59+
60+
### Modify stack name
61+
62+
Open the `bin/pipeline.ts` file, which is your entry point to the CDK project, and change the name of the stack to **sam-app-cicd**.
63+
64+
![CdkEntryPoint](/images/chapter4/screenshot-bin-pipeline-ts.png)
65+
66+
**Save the file**.
67+
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+
Let your pipline run every stage. After it finishes it will look all green 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: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
+++
2+
title = "How to build a pipeline"
3+
date = 2019-11-01T15:26:09-07:00
4+
weight = 20
5+
+++
6+
7+
The best way to automate the creation of CI/CD pipelines is by provisioning them programmatically via Infrastructure as Code. This is specially useful in a microservices environment, where you have a pipeline per microservice, which potentially means dozens of pipelines, if not more. Having an automated way to create these pipelines enables developers to create as many as necessary without building them manually from the console every time.
8+
9+
### Different ways to create pipelines
10+
We see customers using different mechanisms for creating pipelines programmatically. Nowadays developers have many choices to pick from, but the most common ones we see are the following:
11+
12+
- [AWS CloudFormation](https://docs.aws.amazon.com/codepipeline/latest/userguide/tutorials.html)
13+
- [AWS CDK](https://docs.aws.amazon.com/cdk/latest/guide/codepipeline_example.html)
14+
- [Terraform](https://www.terraform.io/docs/providers/aws/r/codepipeline.html)
15+
- [AWS Serverless App Repository](https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:646794253159:applications~aws-sam-codepipeline-cd)
16+
17+
### Introducing the AWS CDK
18+
In this workshop, we are going to use the AWS Cloud Development Kit (also known as CDK), as the pipeline vending mechanism. The AWS CDK is a software development framework for defining cloud infrastructure in code and provisioning it through AWS CloudFormation.
19+
20+
That's right! You can describe your infrastructure by writing code in TypeScript, C#, Python or Java. Your code is then synthesized into CloudFormation and using the CDK CLI you can deploy it to an AWS account.
21+
22+
### How does SAM and CDK play together?
23+
24+
Serverless developers use the SAM framework to define their applications, SAM CLI to build them and deploy them and AWS CDK to provision any infrastructure related resources, like their CI/CD Pipeline. The nice thing about these tools is that they all share a common ground: CloudFormation.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
+++
2+
title = "Pipeline as code"
3+
date = 2019-11-01T15:26:09-07:00
4+
weight = 22
5+
+++
6+
7+
Open the file `lib/pipeline-stack.ts` in your Cloud9 workspace. It is empty at the moment, but here is where you will be adding code to build your CI/CD pipeline.
8+
9+
![CdkEmptyLib](/images/chapter4/screenshot-cdk-empty.png)
10+
11+
### Build the CDK project
12+
13+
Even though we haven't wrote any code yet, let's get familiar with how to build and deploy a CDK project, as you will be doing it multiple times in this workshop and you should get comfortable with the process. Start by building the project with the following command:
14+
15+
```
16+
cd ~/environment/sam-app/pipeline
17+
npm run build
18+
```
19+
20+
### Deploy a CDK project
21+
22+
After the build has finished, go ahead and deploy the pipeline project by using the CDK CLI:
23+
24+
```
25+
cdk deploy
26+
```
27+
28+
The output should look like the following:
29+
30+
![CdkDeploy](/images/chapter4/screenshot-cdk-deploy.png)
31+
32+
A new CloudFormation stack was created in your account, but because your CDK project is empty, the only resource that was created was an AWS::CDK::Metadata. If you check your [CloudFormation Console](https://console.aws.amazon.com/cloudformation/home), you will see the new stack and the metadata resource.
33+
34+
![CdkMetadata](/images/chapter4/screenshot-cdk-metadata.png)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
+++
2+
title = "Artifacts Bucket"
3+
date = 2019-11-01T15:26:09-07:00
4+
weight = 10
5+
+++
6+
7+
Every Code Pipeline needs an artifacts bucket, also known as Artifact Store. CodePipeline will use this bucket to pass artifacts to the downstream jobs and its also where SAM will upload the artifacts during the build process.
8+
9+
Let's get started and write the code for creating this bucket:
10+
11+
**Make sure you are editing the pipeline-stack file with _.ts_ extension**
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+
}
31+
```
32+
33+
Easy right? Now build and deploy the project like you did it earlier:
34+
35+
```
36+
npm run build
37+
cdk deploy
38+
```
39+
40+
{{% notice info %}}
41+
If you get a build error, check that all the @aws-cdk dependencies in the package.json file have the same version number, if not, fix it, delete the node_modules folder and run npm install. More info: https://github.com/aws/aws-cdk/issues/542#issuecomment-449694450.
42+
{{% /notice %}}
43+
44+
The output will show that the S3 bucket got created:
45+
46+
![CdkBucket](/images/chapter4/screenshot-cdk-s3-bucket.png)
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
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 by SAM. 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+
### Why AWS Code Build?
10+
11+
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.
12+
13+
### Add the build stage
14+
15+
Let's go ahead and add a Build stage to you pipeline-stack.ts:
16+
17+
```js
18+
// Declare build output as artifacts
19+
const buildOutput = new codepipeline.Artifact();
20+
21+
// Declare a new CodeBuild project
22+
const buildProject = new codebuild.PipelineProject(this, 'Build', {
23+
environment: { buildImage: codebuild.LinuxBuildImage.AMAZON_LINUX_2_2 },
24+
environmentVariables: {
25+
'PACKAGE_BUCKET': {
26+
value: artifactsBucket.bucketName
27+
}
28+
}
29+
});
30+
31+
// Add the build stage to our pipeline
32+
pipeline.addStage({
33+
stageName: 'Build',
34+
actions: [
35+
new codepipeline_actions.CodeBuildAction({
36+
actionName: 'Build',
37+
project: buildProject,
38+
input: sourceOutput,
39+
outputs: [buildOutput],
40+
}),
41+
],
42+
});
43+
```
44+
45+
{{%expand "Click here to see how the entire file should look like" %}}
46+
47+
The highlighted code is the new addition:
48+
49+
{{< highlight js "hl_lines=44-68" >}}
50+
// lib/pipeline-stack.ts
51+
52+
import * as cdk from '@aws-cdk/core';
53+
import s3 = require('@aws-cdk/aws-s3');
54+
import codecommit = require('@aws-cdk/aws-codecommit');
55+
import codepipeline = require('@aws-cdk/aws-codepipeline');
56+
import codepipeline_actions = require('@aws-cdk/aws-codepipeline-actions');
57+
import codebuild = require('@aws-cdk/aws-codebuild');
58+
59+
export class PipelineStack extends cdk.Stack {
60+
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
61+
super(scope, id, props);
62+
63+
// The code that defines your stack goes here
64+
const artifactsBucket = new s3.Bucket(this, "ArtifactsBucket");
65+
66+
// Import existing CodeCommit sam-app repository
67+
const codeRepo = codecommit.Repository.fromRepositoryName(
68+
this,
69+
'AppRepository', // Logical name within CloudFormation
70+
'sam-app' // Repository name
71+
);
72+
73+
// Pipeline creation starts
74+
const pipeline = new codepipeline.Pipeline(this, 'Pipeline', {
75+
artifactBucket: artifactsBucket
76+
});
77+
78+
// Declare source code as an artifact
79+
const sourceOutput = new codepipeline.Artifact();
80+
81+
// Add source stage to pipeline
82+
pipeline.addStage({
83+
stageName: 'Source',
84+
actions: [
85+
new codepipeline_actions.CodeCommitSourceAction({
86+
actionName: 'CodeCommit_Source',
87+
repository: codeRepo,
88+
output: sourceOutput,
89+
}),
90+
],
91+
});
92+
93+
// Declare build output as artifacts
94+
const buildOutput = new codepipeline.Artifact();
95+
96+
// Declare a new CodeBuild project
97+
const buildProject = new codebuild.PipelineProject(this, 'Build', {
98+
environment: { buildImage: codebuild.LinuxBuildImage.AMAZON_LINUX_2_2 },
99+
environmentVariables: {
100+
'PACKAGE_BUCKET': {
101+
value: artifactsBucket.bucketName
102+
}
103+
}
104+
});
105+
106+
// Add the build stage to our pipeline
107+
pipeline.addStage({
108+
stageName: 'Build',
109+
actions: [
110+
new codepipeline_actions.CodeBuildAction({
111+
actionName: 'Build',
112+
project: buildProject,
113+
input: sourceOutput,
114+
outputs: [buildOutput],
115+
}),
116+
],
117+
});
118+
119+
}
120+
}
121+
{{< / highlight >}}
122+
{{% /expand%}}
123+
124+
### Deploy the pipeline
125+
126+
From your terminal, run the following commands to deploy the pipeline:
127+
128+
```
129+
npm run build
130+
cdk deploy
131+
```
132+
133+
### Verify pipeline creation
134+
135+
Navigate to the [AWS CodePipeline Console](https://console.aws.amazon.com/codesuite/codepipeline/home) and click on your newly created pipeline!
136+
137+
![VerifyPipeline](/images/chapter4/screenshot-pipeline-verify-1.png)
138+
139+
The Build step should have failed. **Don't worry! this is expected** because we haven't specified what commands to run during the build yet, so AWS CodeBuild doesn't know how to build our Serverless application.
140+
141+
![VerifyPipeline](/images/chapter4/screenshot-pipeline-verify-2.png)
142+
143+
Let's fix that.

0 commit comments

Comments
 (0)