AWS Amplify with Terraform
Recently I needed to set up the infrastructure to deploy a small React progressive web application (PWA) to the cloud. This application was essentially a static site with no backend. I would also need to set up the infrastructure for this project using Terraform. Amplify is an AWS service offering that allows you to easily deploy full-stack applications or static sites really easily. It allows you to either connect to a repository or to do manual deploys where you can either point it at an S3 bucket or upload a zip file containing your site. Another neat feature is it performs an automatic ui check for your deployed application against a few common devices so you can check that it is rendering correctly on different screen sizes. There are many other great features such as monitoring and automatic branch creation that you can read about here. For the purposes of this article we will assume that we already have a React application that we want to deploy. The content or code of the application is not important as we will be focusing on setting up the infrastructure not developing the application. We will be making use of AWS Amplify’s managed deployments where we connect a CodeCommit repository to Amplify so that when we push changes to our repository, our application will automatically deploy the changes. We will also be using Terraform to set up our AWS infrastructure. Generally it is a good idea to set up your infrastructure with code as it enables you to guarantee that each time you deploy your environment, it will turn out exactly the same as the previous time. Infrastructure as code also allows you to keep your architecture in source control and allows for easier review. I will also be assuming you have managed to set up Terraform and are able to deploy resources to your AWS account as I will be focusing on the specific terraform code required for this project.
Setting up a CodeCommit Repository
The first thing we need to do is set up a CodeCommit Repository. To do this we need to define the following resource. Once you have added this resource, you can go ahead and apply these changes so that the repository gets created in your AWS Account and add your code to it. Now we are ready to get to the interesting part.
Creating a Service Role
The next thing we need to do is very important. We need to set up an IAM role to be used as a service role by the Amplify project which will enable it to connect to CodeCommit to pull the code. From the AWS documentation it is not clear that you need a service role for a static site. It seems to allude to the fact that you only need one if you have backend services that your app needs to talk to. However, if you create the project manually on the Amplify Console, and try to connect it to CodeCommit, you will need to specify a service role. To set up the IAM role, add the following code. The second part creates an IAM Role that references the above policy document and provides read-only access for the specified service to CodeCommit. Generally it is best practice to always supply the least privilege necessary to achieve your goals.
Creating the Amplify Project
Now we can set up our Amplify project resource. To do that we need to specify a few things:
- Project name — the name of the project that will be displayed on the Amplify Console.
- Repository — Reference to the CodeCommit repository created above.
- IAM service role — As mentioned above, to allow Amplify to talk to CodeCommit.
- Enable branch auto build — We need this so that when changes are pushed to our repository, the project will redeploy.
Buildspec — this is an inline file (can be an external file) that specifies how to build your application. Note in the buildspec I am running
npm run buildas this is for a React application. I am also running my ui tests as part of this build. See the code below:
Creating a development branch
The last piece of the puzzle is we need to link up our Amplify app with a specific branch in our CodeCommit repository. Generally a team would want to have a
develop branch to work and test on and then keep
master as the production branch. Amplify is awesome in this way as it allows us to map different instances of our app environment to specific branches. So changes pushed to the
develop branch for example, would not affect production on the
So to add the branches add the following:
And that’s it! If you apply these changes, you will have set up a fully automated AWS Amplify application deployment with all your infrastructure neatly specified in Terraform.
In an upcoming article, I will be covering setting up a Jenkins pipeline to synchronise a Bitbucket repository to CodeCommit with a webhook that will trigger the job on Push to the repository.
Thanks for reading! :)