CI/CD with CodePipeline
Hub › AWS › Advanced › CI/CD with CodePipeline
Goal
After this page you will have a CodePipeline that pulls source from GitHub, builds the Lambda package, and deploys via CloudFormation/CDK whenever you push to the main branch.
Prerequisites
- CloudFormation outputs
- A GitHub repository containing your CDK app and Lambda code.
- A GitHub personal access token (classic) with
reposcope.
Pipeline overview
GitHub push → CodePipeline → CodeBuild → cdk deployEach push to main triggers:
- Source stage — CodePipeline pulls the latest code from GitHub (using a stored token).
- Build stage — CodeBuild runs
npm ci,npm run build, andnpx aws-cdk synth. - Deploy stage — CodePipeline deploys the synthesized CloudFormation template.
Create the build project
Create buildspec.yml in the repo root:
yaml
version: 0.2
phases:
install:
runtime-versions:
nodejs: 20
commands:
- npm ci
build:
commands:
- npm run build # tsc compilation
- npx aws-cdk synth # synthesize CloudFormation template
artifacts:
base-directory: cdk.out
files: "**/*"Create the pipeline (CLI)
bash
# PLACEHOLDER — replace with your GitHub repo, branch, and token secret name.
aws codepipeline create-pipeline \
--pipeline-name items-api-pipeline \
--pipeline-type V2 \
--role-arn arn:aws:iam::123456789012:role/service-role/codepipeline-service-role \
--artifact-store type=S3,location=my-artifact-bucket-name \
--stages '[
{
"name": "Source",
"actions": [{
"name": "GitHubSource",
"actionTypeId": { "category": "Source", "owner": "ThirdParty", "provider": "GitHub", "version": "1" },
"configuration": {
"Owner": "your-github-username",
"Repo": "items-cdk",
"Branch": "main",
"OAuthToken": "your-github-token"
},
"outputArtifacts": [{ "name": "SourceArtifact" }],
"runOrder": 1
}]
},
{
"name": "Build",
"actions": [{
"name": "CodeBuild",
"actionTypeId": { "category": "Build", "owner": "AWS", "provider": "CodeBuild", "version": "1" },
"configuration": {
"ProjectName": "items-api-build"
},
"inputArtifacts": [{ "name": "SourceArtifact" }],
"outputArtifacts": [{ "name": "BuildArtifact" }],
"runOrder": 1
}]
},
{
"name": "Deploy",
"actions": [{
"name": "DeployToCloudFormation",
"actionTypeId": { "category": "Deploy", "owner": "AWS", "provider": "CloudFormation", "version": "1" },
"configuration": {
"ActionMode": "CREATE_UPDATE",
"StackName": "ItemsCdkStack",
"TemplatePath": "BuildArtifact::Assembly-Manifest.json",
"Capabilities": "CAPABILITY_IAM"
},
"inputArtifacts": [{ "name": "BuildArtifact" }],
"runOrder": 1
}]
}
]'Pipeline as CDK
The better approach is to define the pipeline in CDK so it is version-controlled. Add a PipelineStack to your CDK app:
typescript
import { Stack, StackProps, SecretValue } from "aws-cdk-lib";
import { Construct } from "constructs";
import { Pipeline, Artifact } from "aws-cdk-lib/aws-codepipeline";
import { GitHubSourceAction, CodeBuildAction, CloudFormationCreateUpdateStackAction } from "aws-cdk-lib/aws-codepipeline-actions";
import { PipelineProject, BuildSpec } from "aws-cdk-lib/aws-codebuild";
export class PipelineStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const sourceOutput = new Artifact("SourceArtifact");
const buildOutput = new Artifact("BuildArtifact");
const project = new PipelineProject(this, "BuildProject", {
buildSpec: BuildSpec.fromSourceFilename("buildspec.yml"),
});
new Pipeline(this, "ItemsPipeline", {
pipelineName: "items-api-pipeline",
stages: [
{
stageName: "Source",
actions: [
new GitHubSourceAction({
actionName: "GitHubSource",
owner: "your-github-username",
repo: "items-cdk",
branch: "main",
oauthToken: SecretValue.secretsManager("github-token"),
output: sourceOutput,
}),
],
},
{
stageName: "Build",
actions: [
new CodeBuildAction({
actionName: "CodeBuild",
project,
input: sourceOutput,
outputs: [buildOutput],
}),
],
},
{
stageName: "Deploy",
actions: [
new CloudFormationCreateUpdateStackAction({
actionName: "DeployToCloudFormation",
stackName: "ItemsCdkStack",
templatePath: buildOutput.atPath("Assembly-Manifest.json"),
adminPermissions: true,
}),
],
},
],
});
}
}Checkpoint
Push the pipeline CDK code to GitHub and deploy the pipeline stack:
bash
# PLACEHOLDER — use your own stack name and region.
npx aws-cdk deploy PipelineStackThen trigger the pipeline by pushing a change to main:
bash
git push origin mainMonitor progress:
bash
aws codepipeline get-pipeline-state --name items-api-pipelineExpected: all three stages show status: Succeeded. The Lambda and API Gateway are now deployed by CI/CD on every push.
Next → CloudWatch logs and alarms