Deploy AWS CloudFormation stacks with GitHub Actions

At GitHub Universe 2019, we announced that we open sourced four new GitHub Actions for Amazon ECS and ECR. Fast forward to 2020 we are expanding the number of available actions by releasing AWS CloudFormation Action for GitHub Actions.

This GitHub Action enables developers and cloud engineers to maintain their infrastructure as code in a AWS CloudFormation stack on their favorite open source platform. The action uses AWS CloudFormation to continuously deploy updates to the described infrastructure.

In this article I will explain how to use AWS CloudFormation Action for GitHub Actions by creating a new repository from the AWS CloudFormation Action for GitHub Actions React Starter template. This template contains a React app, an AWS CloudFormation stack, and a GitHub Actions Workflow. The stack configures the cloned React app as a new app in the AWS Amplify Console and uses the Amazon CloudFront Global Edge Network to distribute it globally in minutes.

Deploying a new app

You will create a new repository on GitHub to play with AWS CloudFormation for GitHub Actions. To create this repository, visit the AWS CloudFormation Action for GitHub Actions React Starter template. GitHub has this template feature to use an existing repository as a template, so you and others can create a new repository with the same directory structure, branches, and files.

Click on Use this template to create a new repository from the template.

Select the "use this template" button to get started

Name the repository and add an optional description to it. The repository can be either public or private.

The AWS CloudFormation stack for your new React app is located in the stack.yml file at the root of the repository. It configures your app as a new app in the AWS Amplify Console.

The stack uses three AWS CloudFormation resources:

The stack has required and optional parameters. It requires that you provide the following:

  • Name to set the app name.
  • Repository to set the app repository.
  • Branch to set the branch within the app.
  • OauthToken to configure the repository in the Amplify Console.

The GitHub Actions for AWS CloudFormation supports many input parameters. One is the parameter-overrides input, which lets you specify a list of comma-delimited parameters for the stack that sets the parameters for the AWS CloudFormation stack.

This input parameter is used at the deploy step of the main workflow. You can find this workflow defined in the .github/workflows/deploy.yamlfile in your repository. The workflow consists of five steps:

  1. Source code repository checkout.
  2. AWS credentials configuration.
  3. Environment variables configuration.
  4. Deployment to the AWS Amplify Console with AWS CloudFormation.
  5. Printing the configured custom domain.

Before moving to the deployment step, let’s review the second step, which uses “Configure AWS Credentials” Action For GitHub Actions to configure your AWS credentials as environment variables for use in the other steps:

- name: Configure AWS credentials
      id: creds
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: ${{ github.event.inputs.region }}

These credentials are stored in GitHub secrets. Secrets let you store sensitive information in your repository. You must create an AWS account to retrieve and configure the needed secrets and to deploy the AWS CloudFormation stack. Follow the steps in the documentation if you do not have an account. Creating a new IAM user with only programmatic access for the GitHub action is recommended.

If you have generated your access key ID and secret access key for this new user or your current user, you must configure these as secrets for your repository. The settings are accessed via the Settings tab of your new repository.

The settings are accessed via the Settings tab of your new repository, on the top right side of the screen.

In the settings, select the Secrets option and use the New secret button to create two secrets. AWS_ACCESS_KEY_ID contains the access key ID and AWS_SECRET_ACCESS_KEY contains the secret access key of the user you are using to deploy the AWS CloudFormation stack in the steps.

In the settings select the Secrets option, which is above Actions at the bottom of the list on the left side of the screen, and and use the New secret button, which is located at the top right side of the screen, to create two secrets.

The AMPLIFY_TOKEN secret shown in the list of secrets is used at step four of the workflow. This step deploys the AWS CloudFormation stack with the AWS CloudFormation Action for GitHub Actions.

- name: Deploy to Amplify Console with CloudFormation
      id: amplify-stack
      uses: aws-actions/aws-cloudformation-github-deploy@v1
      with:
        name: ${{ steps.env-name.outputs.environment }}
        template: stack.yaml
        no-fail-on-empty-changeset: "1"
        parameter-overrides: >-
          Name=${{ steps.env-name.outputs.environment }},
          Repository=https://github.com/${{ github.repository }},
          OauthToken=${{ secrets.AMPLIFY_TOKEN }},
          Domain=${{ secrets.AMPLIFY_DOMAIN }}

The AMPLIFY_TOKEN stores a personal access token for GitHub. Amplify Console uses the token to configure a webhook in your repository. This webhook is called whenever you push changes to your repository. It triggers the build pipeline in the AWS Amplify Console.

To create this personal access token, go your GitHub profile and select the Developer settings.

Developer settings option below Applications option at the bottom

In the developer settings, select Personal access token and select the Generate new token button to create a new token. You can name this token Amplify Console as shown in the following screenshot. Creating the token makes identifying and revoking access easy.

In the developer settings select Personal access token and block on the Generate new token button to create a new token. You can name this token Amplify Console as shown in the screenshot.

The token needs full control of private repository permissions.

The token needs full control of private repository permissions.

Copy the token that is created and configure it as AMPLIFY_TOKEN in the repository secrets.

If you want to use a custom domain for your app, you can configure this domain as an additional AMPLIFY_DOMAIN secret in your repository. This is optional; the AWS Amplify Console makes your app available via a subdomain to the amplifyapp.com domain.

You are ready to deploy the AWS CloudFormation stack. The deployment is run by a manual trigger, because AWS Amplify itself configures a build pipeline for your project. That pipeline is run with every push to your repository. Whenever you want to update your stack, re-run the trigger.

Click on Actions in the new repository to see all configured GitHub Actions.

Click on Actions in new repository, select the failed build and click the Re-run jobs and select the Re-run all jobs option.

The sidebar shows all workflows; select the Deploy workload to run it in the next step.

Deploy Workflow

Next, click on the Run workflow drop-down. This opens a popover that lets you configure the parameters of this deployment. By default, the AWS CloudFormation stack is deployed to the us-east-1 region. You can change the setting at this step, if you want to test this in a different region. Regardless of the region you deploy this stack to, your app is served from the Amazon CloudFront Global Edge Network.

Select the run workflow option and run the workflow

When the build has finished, you can access your new app in the AWS Management Console.

When the build has succeeded, you can access your new app in the AWS Management Console.

Select your new app; you created a new repository, so the name will be different. Because the build specs are in the amplify.yml file in the root of your project, you must manually trigger a build once.

Select the Run build button to trigger the build

After the build process has finished, you can access your React application via the provided link.

Use the link shown in the console to access your app

You also can find the deployed AWS CloudFormation stack in the console.

AWS CloudFormation console shows the stack

When you change the AWS CloudFormation stack in the master branch of your repository, AWS CloudFormation Action for GitHub Actions will update your stack.

By default, a deployment with an empty AWS CloudFormation change set results in an error in the workflow. The no-fail-on-empty-changeset input parameter allows you override this behavior, which the template you used here does. The GitHub repository shows the input parameters that are supported.

Summary

AWS CloudFormation Action for GitHub Actions is a powerful tool to bring together the open source platform and the cloud, which has the breadth of services and the deepest functionality within those services. In this tutorial, you have used infrastructure as code to make an application available to a global audience.

Submit your feedback by opening issues, by pull requests, or by starring the GitHub repository. We cannot wait to see what great things you build with it.

Acknowledgements

The code for the React app was created with the Create React App tool and is under the MIT license.