Simple Steps to Include CDK Diffs in GitHub PRs
![Cover Image for Simple Steps to Include CDK Diffs in GitHub PRs](https://cdn.hashnode.com/res/hashnode/image/upload/v1686032625812/72664174-525d-44e6-bcc1-94ccd855561f.png?w=1600&h=840&fit=crop&crop=entropy&auto=compress,format&format=webp)
Hey, everyone! If you've been using AWS, chances are you've come across CDK and building cloud apps with it. As seamless as it is to deploy apps using CDK, it is equally important to monitor changes in infrastructure code and prevent issues.
This guide is here to make your life a bit easier by showing you how to include the CDK diff directly in your GitHub PR.
Let's start by understanding the CDK first.
A Brief Overview of CDK (Cloud Development Kit)
The Cloud Development Kit (CDK) enables developers to define, build, and deploy cloud infrastructure as code using supported programming languages. A CDK app consists of one or more Stacks where each stack defines AWS resources it uses, such as Lambda function, EC2 instance or SNS. This CDK app is usually written in TypeScript, JavaScript, Python, Java, C# or Go.
A stack is simply a collection of AWS resources in the form of constructs managed as a single unit. You instantiate constructs within a stack to declare them to AWS and connect them using well-defined interfaces.
Here's an example of using a construct in AWS CDK to create an Amazon S3 bucket with public read access:
import { Stack, StackProps, Construct } from '@aws-cdk/core';
import { Bucket } from '@aws-cdk/aws-s3';
export class MyS3BucketStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const bucket = new Bucket(this, 'MyS3Bucket', {
publicReadAccess: true,
});
}
}
Since a construct is a reusable piece of code that encapsulates AWS resource creation and configuration logic, we can say that these constructs are the building blocks of a CDK app. Please pay close attention to this point, as it will be crucial in understanding why it is important to assess the CDK differences effectively.
Importance of CDK Diffs in GitHub PRs (Pull Requests)
As we just learned, a CDK app enables seamless building and deployment of cloud infrastructure as code. Since we define the resources used in an app as constructs, they can be employed to analyze the differences in resource allocation when changes occur.
These changes can be harmful if overlooked, leading to poor resource allocation, inconsistencies, and fatal crashes.
At times, it may not be apparent that changes could result in the deletion and recreation of a resource. For instance, in the case of a database, this could have disastrous consequences. That's why monitoring whenever there is a change in infrastructure code is essential.
The integration of CDK diffs in GitHub Pull Requests (PRs) makes it much easier for developers to review and analyze changes in the infrastructure code. This helps streamline the development process and ensure efficient cloud infrastructure management.
A CDK diff highlights any modifications, additions, or deletions made to the codebase in a concise format. Since this information is available directly within the pull request, it can be leveraged to understand the proposed changes better, assess their impact, and make informed decisions. This, in turn, helps to minimize the risk of errors and maintain the stability and security of the cloud infrastructure, ultimately leading to a more reliable and robust system.
I hope I've managed to convince you why having the CDK diff available in each pull request is crucial.
Now, let's proceed to learn how to incorporate them.
Creating GitHub Workflow to Include CDK Diff as a PR Comment
Since we need to add a comment with the CDK difference, we will use GitHub workflow to run a job whenever there is a new pull request. Create a yaml
file inside .github/workflows
and follow the steps below:
Feel free to click here if you want to skip the explanation.
Step 1: Add a name for the job and make sure it runs on pull requests only
// .github/workflows/cdk-diff-share.yaml
name: Run CDK difference
on:
pull_request:
branches: ['main']
Step 2: Define a Job and Set the Environment, Permissions and Machine it Runs On
jobs:
build:
name: Run CDK diff
environment: prod
runs-on: ubuntu-latest
permissions:
id-token: write
contents: write
pull-requests: write
Make sure you have contents
and pull-requests
access so that the job can post the comment.
Step 3: Define Steps to Checkout the Repo and Install Dependencies
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 7.27.1
- name: Setup Node and Cache
uses: actions/setup-node@v3
with:
node-version: 16
cache: pnpm
- name: Install dependencies
run: pnpm install --prefer-offline
We are also setting up the cache to speed up the consecutive runs.
Step 4: Configure AWS credentials
We need to be authenticated to access the AWS console; let's set up the AWS credentials using an IAM role.
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1-node16
with:
role-to-assume: ${{ secrets.AWS_DEPLOY_ROLE }}
aws-region: <region-of-your-choice>
Note: Always use GitHub secrets to store any credentials.
Step 5: Run CDK sync
Run the CDK synth
command to generate a CloudFormation stack. We are using aws-cdk
to run CDK commands.
- name: CDK synth
run: pnpm cdk synth
env:
SKIP_SANDBOX: true
Step 6: Run CDK diff
Run the CDK diff
command to compare the current stack with the deployed stack. Since we need this log in the next step to post a comment, we will also save this in a log file, say output.log
.
Once we generate the log file, we can parse it and make it available as GITHUB_OUTPUT
.
- name: Run AWS CDK diff
run: pnpm cdk diff --app "./cdk.out/assembly-ProdStage" 2>&1 2>&1 | tee output.log
env:
SKIP_SANDBOX: true
- name: Echo output log
id: output_log
run: |
echo "data<<EOF" >> $GITHUB_OUTPUT
echo "$(cat output.log)" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
Here, 2>&1 2>&1 | tee output.log
redirects both stdout and stderr to output.log
file and also prints them on the console
Step 7: Post the comment
We are using mshick/add-pr-comment@v2
to post a log on the GitHub pull request. We will add a markdown wrapper around the log to make it appear visually appealing.
- name: Post diff in comment
uses: mshick/add-pr-comment@v2
with:
message-id: cdk-diff
message: |
#### CDK Diff for ProdStage
<details>
<summary>Show diff</summary>
` ` `bash
${{ steps.output_log.outputs.data }}
` ` `
</details>
That's we are done. Here's how the log should appear:
Here's the complete script:
name: Run CDK difference
on:
pull_request:
branches: ['main']
jobs:
build:
name: Run CDK diff
environment: prod
runs-on: ubuntu-latest
permissions:
id-token: write
contents: write
pull-requests: write
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 7.27.1
- name: Setup Node and Cache
uses: actions/setup-node@v3
with:
node-version: 16
cache: pnpm
- name: Install dependencies
run: pnpm install --prefer-offline
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1-node16
with:
role-to-assume: ${{ secrets.AWS_DEPLOY_ROLE }}
aws-region: <your-region-here>
- name: CDK synth
run: pnpm cdk synth
env:
SKIP_SANDBOX: true
- name: Run AWS CDK diff
run: pnpm cdk diff --app "./cdk.out/assembly-ProdStage" 2>&1 2>&1 | tee output.log
env:
SKIP_SANDBOX: true
- name: Save output
id: output_log
run: |
echo "data<<EOF" >> $GITHUB_OUTPUT
echo "$(cat output.log)" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Post diff in comment
uses: mshick/add-pr-comment@v2
with:
message-id: cdk-diff
message: |
#### CDK Diff for ProdStage
<details>
<summary>Show diff</summary>
` ` `bash
${{ steps.output_log.outputs.data }}
` ` `
</details>
Please remove the space between backticks `.
Conclusion
CDK diff in GitHub PRs helps us review and analyze changes in infrastructure code, minimizing the risk of errors and maintaining stability and security. CDK diffs highlight modifications, additions, or deletions in the codebase, enabling a better understanding of proposed changes and informed decision-making.
We learned how to utilize cdk diff
it to see changes in the intended deployment and post them as a comment on our GitHub PRs.
Do let us know if this article was helpful in the comments.