Terraform — Deploy docker image on AWS AppRunner from ECR Repository
Tags: aws, terraform, docker, devops
Published: 2021-07-21 14:16:59


In this article, we are talking about How we can deploy docker image from ECR Repository on AWS AppRunner service using terraform.

![Terraform — Deploy docker image on AWS AppRunner from ECR Repository](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/twqzqmthmdpla2mc9t47.jpg)

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 automatically builds and deploys the web application and load balances traffic with encryption.

App Runner also scales up or down automatically to meet your traffic needs. With App Runner, rather than thinking about servers or scaling, you have more time to focus on your applications.

## App Runner Features
AWS has put a lot of effort into making things easy for developers, especially for small-scale projects that don’t need beefy infrastructure. It has:

* **Simple auto scaling**: instances are started and stopped as demand changes, between configurable min and max limits.
* **Load balancing**: the service includes a transparent, non-configurable load balancer.
* **SSL enabled**: you get HTTPS endpoints for all your applications with AWS-managed certificates. You don’t need to issue or renew certificates.
* **Build service**: you can push your own images or let AWS build them for you from code.
* **Persistent URLs**: the service assigns randomly-generated URLs for each environment. You can optionally map them to domains of your own.

App Runner can run in two modes.

1. In build mode, AWS pulls code from GitHub and builds the application on every change.

2. In container mode, it deploys Docker-compatible images from public or private AWS ECR registries.

In this article we will using ECR public as well as private repository with App Runner deployment which mean we are using `container mode`.

## Prerequisites

* We require AWS IAM API keys (access key and secret key) for creating and deleting permissions for all AWS resources.
* ECR Repository and docker image pushed on it.
* Terraform should be installed on the machine. If Terraform does not exist you can download and install it from here.

## version

To build AWS App Runner, you need to meet the following versions:

* Terraform v0.12 or higher
*Latest version of AWS provider (3.42.0)
    Configuring App Runner in the Terraform AWS Provider

This time I built it with the following version.

```
$ terraform version
Terraform v1.0.0
on linux_amd64
```

## Amazon Resources Created Using Terraform

A Terraform module is a set of Terraform configuration files in a single directory. Even a simple configuration consisting of a single directory with one or more .tf files is a module. When you run Terraform commands directly from such a directory, it is considered the root module

1. IAM Module

* IAM Role and policy

2. AppRunner Module

* auto scaling configuration
* aws apprunner service

## Create an IAM role to grant to App Runner

Set up an IAM role to build AWS App Runner.
The key `build.apprunner.amazonaws.com` is `tasks.apprunner.amazonaws.com` to specify and for the service to which AssumeRole is assigned .
After that, AWS has prepared a policy for App Runner, so attach it to the IAM role.

```
resource "aws_iam_role" "role" {
   name = "test-role"
   assume_role_policy = <<EOF 
{
   "Version": "2012-10-17",
   "Statement": [
     {
       "Action": "sts:AssumeRole",
       "Principal": {
         "Service": [
           "build.apprunner.amazonaws.com",
           "tasks.apprunner.amazonaws.com"
         ]
       },
       "Effect": "Allow",
       "Sid": ""
     }
   ]
 } EOF 
}
resource "aws_iam_role_policy_attachment" "test-attach" {
   role       = aws_iam_role.role.name
   policy_arn = "arn:aws:iam::aws:policy/service-role/AWSAppRunnerServicePolicyForECRAccess"
 }
```

## Create an App Runner

Finally, create an App Runner resource in Terraform.
There are some App Runner related resources, but they are the main resources for actually creating App Runner aws_apprunner_service,
source_configuration

We have 2 ways to deploy App Runner with ECR repository.

* Deploy App Runner with ECR private repository
* Deploy App Runner with ECR public repository

### Deploy App Runner with ECR private repository

```
resource "aws_apprunner_auto_scaling_configuration_version" "ngnix-apprunner-autoscaling" {
  auto_scaling_configuration_name = "demo_auto_scalling"
  max_concurrency = 100
  max_size        = 5
  min_size        = 1

  tags = {
    Name = "demo_auto_scalling"
  }
}

resource "aws_apprunner_service" "ngnix-apprunner-service-ecr" {
  service_name = "demo_apprunner"

  source_configuration {
    image_repository {
      image_configuration {
        port = "80"
      }
      image_identifier      = "XXXXX.dkr.ecr.us-east-2.amazonaws.com/nginx-web:latest"
      image_repository_type = "ECR"
    }
    authentication_configuration{
      access_role_arn = aws_iam_role.role.arn
    }
    auto_deployments_enabled = true
  }

  auto_scaling_configuration_arn = aws_apprunner_auto_scaling_configuration_version.ngnix-apprunner-autoscaling.arn

  health_check_configuration {
          healthy_threshold   = 1
          interval            = 10
          path                = "/"
          protocol            = "TCP"
          timeout             = 5
          unhealthy_threshold = 5
        }

  tags = {
    Name = "demo_apprunner"
  }
}
```

### Deploy App Runner with ECR public repository
> Note: In this approach we don't need IAM role.

```
resource "aws_apprunner_auto_scaling_configuration_version" "ngnix-apprunner-autoscaling" {
  auto_scaling_configuration_name = "demo_auto_scalling"
  max_concurrency = 100
  max_size        = 5
  min_size        = 1

  tags = {
    Name = "demo_auto_scalling"
  }
}

resource "aws_apprunner_service" "ngnix-apprunner-service-ecr-public" {
  service_name = "demo_apprunner"

  source_configuration {
    image_repository {
      image_configuration {
        port = var.port
      }
      image_identifier      = "public.ecr.aws/nginx/nginx:latest"
      image_repository_type = "ECR_PUBLIC"
    }
    auto_deployments_enabled = false
  }

  auto_scaling_configuration_arn = aws_apprunner_auto_scaling_configuration_version.ngnix-apprunner-autoscaling.arn

  health_check_configuration {
          healthy_threshold   = 1
          interval            = 10
          path                = "/"
          protocol            = "TCP"
          timeout             = 5
          unhealthy_threshold = 5
        }

  tags = {
    Name = "demo_apprunner"
  }
}
```

#### Check the URL of App Runner created by applying

I want to check the URL of the created App Runner as the execution result of the apply command, so `output` set.

```
output "app_runner_url" {
  value = aws_apprunner_service.example.service_url
}
```

After that, just run the following commands.

>terraform init
>terraform plan
>terraform apply

it will take 2 to 3 minutes to complete the execution.
When the execution is completed, the URL will be displayed as shown below, so let’s access it.
```
app_runner_url = "xxxxx.us-east-2.awsapprunner.com/"
```

Thank you for reading, if you have anything to add please send a response or add a note!