How to deploy docker image to AWS App Runner with Terraform?

Kadriye Taylan
KoçSistem
Published in
5 min readMar 17, 2022

--

Hi everyone, in this article I will talk about how to create AWS App Runner service with terraform and how to automate it with Azure Pipeline.

Before we start, let’s leave a few explanations below for those who do not know terraform and app runner.

What is terraform and why do we need terraform?

HashiCorp Terraform is an open-source infrastructure as code tool that lets you define both cloud and on-prem resources in human-readable configuration files that you can version, reuse, and share. You can then use a consistent workflow to provision and manage all of your infrastructure throughout its lifecycle. Users define and provide data center infrastructure using a declarative configuration language known as HashiCorp Configuration Language (HCL), or optionally JSON. Terraform can manage low-level components like compute, storage, and networking resources, as well as high-level components like DNS entries and SaaS features. You can access the details from this link.

Some open-source infrastructure as code tools that can be used outside of terraform:

  • Chef
  • Puppet
  • CFEngine
  • Ansible
  • Otter

What is App Runner?

AWS App Runner is a fully managed service that makes it easy for developers to quickly deploy containerized web applications and APIs, at scale and with no prior infrastructure experience required. Start with your source code or a container image. App Runner builds and deploys the web application automatically, load balances traffic with encryption, scales to meet your traffic needs, and makes it easy for your services to communicate with other AWS services and applications that run in a private Amazon VPC. With App Runner, rather than thinking about servers or scaling, you have more time to focus on your applications. You can access the details from this link.

Similar services that we can use in other cloud technologies:

  • Azure App Service
  • Google Cloud Run

Let’s begin!

Requirements for AWS App Runner:

  • AWS IAM keys (access key and secret key) for access AWS resources
  • AWS IAM role and policy for create App Runner service (only required for Private ECR)
  • Public or Private ECR for docker images
  • Terraform CLI

Create App Runner

There are two registries that App runner supports for docker images and both are AWS services. These are ECR and ECR Public, and App Runner configurations differ for both. I will show you how I did it in both.

I already had an image and pushed it into a private ecr. However, if you do not have an image and you want to push it to your ecr, you can take a look at this medium post. Also, the terraform files I used while creating the ecr are as follows.

App Runner with Private ECR

Region

App Runner is only supported in 5 regions. Details

  • US East (Ohio) : us-east-2
  • US East (N. Virginia) : us-east-1
  • US West (Oregon) : us-west-2
  • Asia Pacific (Tokyo) : ap-northeast-1
  • Europe (Ireland) : eu-west-1

Resources

aws_iam_role

Provides an IAM role.

The IAM role is an IAM entity that defines a set of permissions for making AWS service requests. IAM roles are not associated with a specific user or group.

aws_iam_role_policy_attachment

Attaches a Managed IAM Policy to an IAM role.

Attaches the specified managed policy to the specified IAM role. When you attach a managed policy to a role, the managed policy becomes part of the role’s permission (access) policy.

We need these two resources as we will be using images from Private ECR.

time_sleep

Manages a resource that delays creation and/or destruction, typically for further resources. This prevents cross-platform compatibility and destroy-time issues with using the local-exec provisioner.

aws_apprunner_service

Manages an App Runner Service.

I used the arguments above as a basic example, but you can find other arguments you can use for this resource from this link.

Why am I using time sleep?

Before using Sleep, I was getting an error as below while creating the app runner.

Error: error creating App Runner Service (demo_apprunner): InvalidRequestException: Error in assuming access role arn:aws:iam::<account-id>:role/<role-name>
spongebob is sad

While investigating the cause of the error, I came across a github issue.

Creating the access role and immediately creating the service afterwards results in that same error.

AWS IAM Role is an essential resource for the App runner. However, the role must be successfully created before the App runner. Since this process will take some time, you need to wait for a while before creating the app runner.

I set it to 60 sec. However, this period can be reduced.

However, it seemed a little strange to me that such an error occurs when creating resources that are dependent on each other or that the solution is provided with a delay. But it was the only solution I could find :)

If you know of a more effective solution, I would appreciate it if you let me know in the comments :)

App Runner with Public ECR

auto_deployments_enabled is an argument that you can only use in the private registry. Since the default value is true, you need to set it back to false when using public ecr.

If you want to run these terraform scripts in your local without using any CI/CD tool, you can add your aws access keys to your terraform file as follows.

provider "aws" {
region = "us-east-1"
access_key = "<your-aws-access-key>"
secret_key = "<your-aws-secret-key>"
}

You can reach access key and secret key by following this document.

Pipeline

My terraform repo structure:

I am using Azure Pipeline for CI/CD tool.

Requirements for Pipeline:

  • Terraform tasks for Azure Pipeline. You can look this link.
  • AWS Service Connection. From the Project in Azure DevOps, go to Project Settings > Service Connection > AWS for Terraform and write the connection information (You should use aws access key and secret key here).

You can see my terraform scripts in my yaml file that I run with azure pipeline below.

spongebob is happy now

I hope it was an useful article. Have a nice day everybody :) Stay healthy!

--

--

Kadriye Taylan
KoçSistem

DevOps Engineer at Vanderlande - Eindhoven, NL