Introduction

Throughout this series, we've discussed how to build backend infrastructure using the AWS CDK. In doing so, we've touched on several services and concepts. However, to make sure our application is working as intended, we'll need to deploy our environment to AWS.

Fortunately for us, we laid a solid foundation for deploying our application when we first set it up in an earlier lesson. For the most part, this chapter can stand alone from the other chapters, though we'll use the project we've built so far so that we have something to deploy. However, if simply wanting to know how to deploy a CDK application, this guide is still for you.

In a previous guide, we used a combination of thegit-branch library and the app.node.tryGetContext() method to dynamically create a stack that was dependent on the environment we were in.Due to our diligence in the beginning, in this final guide, we'll see how easy it is to not only deploy our backend to AWS with GitHub actions but what a basic setup will look like when wanting to have a separate deployment flow for our develop and main branches.

Automation made simple with GitHub Actions

GitHub Actions is a powerful tool that allows you to automate workflows. With GitHub Actions, you can create custom workflows that automatically build, test and deploy your code whenever you push changes to your repository.

A GitHub action is defined in YML and is picked up by GitHub by being placed in a .github/workflows folder.

As seen in the image above, we'll take advantage of this by specifying a workflow with two different flows. In particular, depending on whether the event is a commit to our develop branch or a merge to our main branch, we'll do the following:

  • Checkout our application from GitHub
  • Perform the steps needed to build the application
  • Deploy the application

In your project, create the following directories and file: .github/workflows/aws.yml. In that file, paste the following.

1 name: Deploy CDK Project
2 on:
3  push:
4   branches:
5      - develop
6 pull_request:
7    branches:
8      - main
9    types:
10     - closed
11
12 jobs:
13  aws_cdk:
14  if: github.event.pull_request.merged == true || github.event_name == 'push'
15    runs-on: ubuntu-latest
16   steps:
17    - name: Checkout repo
18     uses: actions/checkout@v3
19     - uses: actions/setup-node@v2
20        with:
21          node-version: '18'
22     - run: npm install
23      - name: cdk diff
24       uses: youyo/aws-cdk-github-actions@v2
25        with:
26          cdk_subcommand: 'diff'
27         actions_comment: true
28       env:
29        AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
30        AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
31          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32     - name: cdk deploy
33        uses: youyo/aws-cdk-github-actions@v2
34        with:
35          cdk_subcommand: 'deploy'
36          cdk_stack: '*'
37          cdk_args: '--require-approval never'
38          actions_comment: false
39        env:
40          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
41.           AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

Because our deployment is dependent on the branch we are on, now is a good time to make sure we are on the develop branch and not the main branch. Also take a moment to push your project to GitHub so that the project is available.

A quick explainer of the lines is as follows:

  • lines 1-10: We give the action a name of our choosing, and define the criteria needed for our action to runlines
  • 13-15: Our workflow is called aws_cdk, if the event is a PR merge, or a push, then spin up an ubuntu server to run the following steps.
  • lines 17-22: The server is configured with git but that's it. So we create a step to checkout our repo and set up node version 18 using official GitHub-managed actions. Because NodeJS comes with NPM, we run npm install
  • lines 23-31: We need to install the CDK on our server. While this can be done manually, there is a popular and well-maintained 3rd-party action that does this. With it installed, we run the cdk diff command which is similar in spirit to git diff to view changes between what is local vs what is deployed. To do that, we provide AWS credentials as environment variables and our GitHub token environment variable for pull-request support.
  • lines 32-41: We deploy our application using the same GitHub action as the previous step except for this time we call the deploy command. Because we can't accept yes/no CLI prompts in this server, we pass a flag to auto-approve.

If following along through the course, it's a good idea to run npx aws-cdk synth locally before deploying. This will compile your code to CloudFormation which serves as a good sanity check that there are no configuration errors.

GitHub action permissions are on a per-repo basis. Ensure your repo is configured correctly:

Lastly, recall our GitHub action uses environment variables to avoid us having to pass in our raw AWS credentials (which should never be done!).

The simplest way to get those is to grab them from your machine. When you set up your AWS account, those were stored in a ~/.aws directory. Grab those values and paste them into GitHub as shown in the following screenshot:

With our application configured, you can now deploy your code and view the action run from the Actions tab:

Deploy To Production

On every commit, we have our code deploying our develop environment, however, when a merge occurs on the main branch, we want to deploy our production environment.

To accomplish this, all we have to do is update our cdk.context.json file. Paste in the following:

{
    "globals": {
        "appName": "trip-logger",
        "region": "us-east-1",
        "appDescription": "A stack for a Travel pic viewer"
    },
    "environments": [
        {
            "environment": "develop",
            "branchName": "develop",
            "s3AllowedOrigins": ["*"]
        },
        {
            "environment": "production",
            "branchName": "main",
            "s3AllowedOrigins": ["*"]
        }
    ]
}

Commit your changes and wait for your develop branch to deploy. Once done, create a pull request to your main branch and merge it. You should see your production environment deploy!

Conclusion

In this chapter, we saw how to deploy a CDK application to AWS using GitHub actions. While there are entire courses and varying opinions on how to manage your workflows and architecture, this method shows off the configuration options available while keeping the deployment straightforward. 

Now that you've completed the guide - let's start building a sample recipe app!

Looking for a fully managed GraphQL service?

Explore AWS AppSync

Explore AWS AppSync

AWS AppSync is an enterprise level, fully managed serverless GraphQL service with real-time data synchronization and offline programming features. AppSync makes it easy to build data driven mobile and web applications by securely handling all the application data management tasks such as real-time and offline data access, data synchronization, and data manipulation across multiple data sources.