Hello App Runner in Terraform

Michael Warkentin
4 min readMay 26, 2021

Last week AWS launched a new service called App Runner. In their words:

AWS App Runner makes it easier for you to deploy web apps and APIs to the cloud, regardless of the language they are written in, even for teams that lack prior experience deploying and managing containers or infrastructure. The service has AWS operational and security best practices built-it and automatically scale up or down at a moment’s notice, with no cold starts to worry about.

Justin Garrison wrote a sample application called Hello App Runner and published it to a public ECR repository.

Hashicorp added support for the new service on launch day to Terraform to enable easy management of your App Runner services as code. I figured mashing these two together would give me an easy way to take the service for a test run!

Set up an autoscaling configuration

First you set up an autoscaling configuration which your service will use to scale up and down:

resource "aws_apprunner_auto_scaling_configuration_version" "hello" {                            
auto_scaling_configuration_name = "hello"
# scale between 1-5 containers
min_size = 1
max_size = 5
}

Configure the service

Now for the fun part — setting up the service:

resource "aws_apprunner_service" "hello" {                            
auto_scaling_configuration_arn = aws_apprunner_auto_scaling_configuration_version.hello.arn

service_name = "hello-app-runner"

source_configuration {
image_repository {
image_configuration {
port = "8000"
}

image_identifier = "public.ecr.aws/aws-containers/hello-app-runner:latest"
image_repository_type = "ECR_PUBLIC"
}

auto_deployments_enabled = false
}
}
output "apprunner_service_hello" {
value = aws_apprunner_service.hello
}

Terraform Plan

With those resources in place, you can run a terraform plan to see what will be created:

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
~ update in-place
Terraform will perform the following actions:# aws_apprunner_auto_scaling_configuration_version.example will be created
+ resource "aws_apprunner_auto_scaling_configuration_version" "hello" {
+ arn = (known after apply)
+ auto_scaling_configuration_name = "hello"
+ auto_scaling_configuration_revision = (known after apply)
+ id = (known after apply)
+ latest = (known after apply)
+ max_concurrency = 100
+ max_size = 5
+ min_size = 1
+ status = (known after apply)
}
# aws_apprunner_service.hello will be created
+ resource "aws_apprunner_service" "hello" {
+ arn = (known after apply)
+ auto_scaling_configuration_arn = (known after apply)
+ id = (known after apply)
+ service_id = (known after apply)
+ service_name = "hello-app-runner"
+ service_url = (known after apply)
+ status = (known after apply)
+ tags = {
+ "Name" = "hello-app-runner"
}
+ tags_all = {
+ "Name" = "hello-app-runner"
}
+ health_check_configuration {
+ healthy_threshold = (known after apply)
+ interval = (known after apply)
+ path = (known after apply)
+ protocol = (known after apply)
+ timeout = (known after apply)
+ unhealthy_threshold = (known after apply)
}
+ instance_configuration {
+ cpu = (known after apply)
+ instance_role_arn = (known after apply)
+ memory = (known after apply)
}
+ source_configuration {
+ auto_deployments_enabled = false
+ image_repository {
+ image_identifier = "public.ecr.aws/aws-containers/hello-app-runner:latest"
+ image_repository_type = "ECR_PUBLIC"
+ image_configuration {
+ port = "8000"
}
}
}
}

Terraform Apply

If everything in the plan looks good, you can run terraform apply. A couple of minutes later your service should be up and running!

aws_apprunner_auto_scaling_configuration_version.example: Creating...
aws_apprunner_auto_scaling_configuration_version.example: Creation complete after 1s [id=arn:aws:apprunner:us-east-1:123456789:autoscalingconfiguration/example/1/8a88cca0b41a4844821e92c33de84703]
aws_apprunner_service.hello: Creating...
aws_apprunner_service.hello: Still creating... [10s elapsed]
...
aws_apprunner_service.hello: Still creating... [5m40s elapsed]
aws_apprunner_service.hello: Creation complete after 5m42s [id=arn:aws:apprunner:us-east-1:123456789:service/hello-app-runner/1256948d8558405daceea9cbaabb6ec1]
Apply complete! Resources: 2 added, 1 changed, 0 destroyed.Outputs:apprunner_service_hello = {
"arn" = "arn:aws:apprunner:us-east-1:123456789:service/hello-app-runner/1256948d8558405daceea9cbaabb6ec1"
"auto_scaling_configuration_arn" = "arn:aws:apprunner:us-east-1:123456789:autoscalingconfiguration/example/1/8a88cca0b41a4844821e92c33de84703"
"encryption_configuration" = []
"health_check_configuration" = [
{
"healthy_threshold" = 1
"interval" = 5
"path" = "/"
"protocol" = "TCP"
"timeout" = 2
"unhealthy_threshold" = 5
},
]
"id" = "arn:aws:apprunner:us-east-1:123456789:service/hello-app-runner/1256948d8558405daceea9cbaabb6ec1"
"instance_configuration" = [
{
"cpu" = "1024"
"instance_role_arn" = ""
"memory" = "2048"
},
]
"service_id" = "1256948d8558405daceea9cbaabb6ec1"
"service_name" = "hello-app-runner"
"service_url" = "bg2hcjuckx.us-east-1.awsapprunner.com"
"source_configuration" = [
{
"authentication_configuration" = []
"auto_deployments_enabled" = false
"code_repository" = []
"image_repository" = [
{
"image_configuration" = [
{
"port" = "8000"
"start_command" = ""
},
]
"image_identifier" = "public.ecr.aws/aws-containers/hello-app-runner:latest"
"image_repository_type" = "ECR_PUBLIC"
},
]
},
]
"status" = "RUNNING"
}

Wrap up

Once the apply wraps up, you should have a public endpoint up and running. You can grab it from the output — in this case (no guarantees that my endpoint will stick around for long):

“service_url” = “bg2hcjuckx.us-east-1.awsapprunner.com”

If you visit the URL you will see the application page:

Hello App Runner!

I was impressed with how easy it was to get this basic application up and running using Terraform. I’m looking forward to seeing how the App Runner service evolves over time — here’s the public roadmap. My wishlist items are:

--

--