Example howto run AWS AppRunner Contaimer service with Terraform
aws_apprunner_service_with_terraform/ecr.tf
Lines 1 to 36 in e4c96bc
# my_api | |
resource "aws_ecr_repository" "my_ecr_api" { | |
name = "my_ecr/my_api" | |
image_tag_mutability = "MUTABLE" | |
image_scanning_configuration { | |
scan_on_push = true | |
} | |
} | |
resource "aws_ecr_lifecycle_policy" "my_ecr_api" { | |
repository = aws_ecr_repository.my_ecr_api.name | |
policy = jsonencode({ | |
rules = [{ | |
rulePriority = 1 | |
description = "keep last 10 images" | |
action = { | |
type = "expire" | |
} | |
selection = { | |
tagStatus = "any" | |
countType = "imageCountMoreThan" | |
countNumber = 10 | |
} | |
}] | |
}) | |
} | |
output "my_ecr_api_registry_id" { | |
value = aws_ecr_repository.my_ecr_api.registry_id | |
description = "" | |
} | |
output "my_ecr_api_repository_url" { | |
value = aws_ecr_repository.my_ecr_api.repository_url | |
description = "" | |
} |
aws_apprunner_service_with_terraform/api_service.tf
Lines 1 to 75 in e4c96bc
locals { | |
api_port = 3000 | |
api_domain = "api.mydomain.team" | |
api_git_repo = "my/my_api" | |
api_development_git_branch = "dev" | |
api_ecr_image_development = "${aws_ecr_repository.my_api_ecr.repository_url}:dev" | |
} | |
resource "aws_apprunner_service" "my_api" { | |
depends_on = [ | |
aws_ecr_repository.my_api_ecr, | |
aws_iam_role.my_app_runner_roles, | |
aws_apprunner_vpc_connector.my_vpc_connector | |
] | |
service_name = "my_api" | |
source_configuration { | |
authentication_configuration { | |
access_role_arn = aws_iam_role.my_app_runner_roles.arn | |
} | |
image_repository { | |
image_identifier = local.api_ecr_image_development | |
image_repository_type = "ECR" | |
image_configuration { | |
port = 3000 | |
runtime_environment_variables = { | |
# Server Port | |
PORT = "3000" | |
# | |
NODE_ENV = "development" | |
LOG_LEVEL = "debug" | |
PORT = local.api_port | |
CONTAINER_PORT = local.api_port | |
HOST_PORT = local.api_port | |
} | |
runtime_environment_secrets = { | |
} | |
} | |
} | |
auto_deployments_enabled = true | |
} | |
health_check_configuration { | |
path = "/api/healthcheck" | |
healthy_threshold = 1 | |
interval = 5 | |
protocol = "HTTP" | |
timeout = 20 | |
unhealthy_threshold = 20 | |
} | |
instance_configuration { | |
cpu = "2048" | |
memory = "4096" | |
} | |
network_configuration { | |
egress_configuration { | |
egress_type = "VPC" | |
vpc_connector_arn = aws_apprunner_vpc_connector.my_vpc_connector.arn | |
} | |
} | |
tags = { | |
Name = "my-my_api-apprunner-service" | |
} | |
} | |
output "my_api_apprunner_my_api_service_url" { | |
value = aws_apprunner_service.my_api.service_url | |
description = "" | |
} |
aws_apprunner_service_with_terraform/fe_service.tf
Lines 1 to 91 in e4c96bc
locals { | |
my_fe_port = 3001 | |
my_fe_domain = "frontend.my-domain.org" | |
my_fe_apprunner_domain = "members.development.my-domain.org" | |
my_fe_ecr_image_development = "${aws_ecr_repository.my_fe_ecr.repository_url}:dev" | |
my_fe_git_repo = "clearview/my-members-fe" | |
my_fe_development_git_branch = "dev" | |
} | |
resource "aws_apprunner_service" "my_fe" { | |
depends_on = [ | |
aws_ecr_repository.my_fe_ecr | |
] | |
service_name = "my_fe" | |
source_configuration { | |
authentication_configuration { | |
access_role_arn = aws_iam_role.my_app_runner_roles.arn | |
} | |
image_repository { | |
image_identifier = local.my_fe_ecr_image_development | |
image_repository_type = "ECR" | |
image_configuration { | |
port = local.my_fe_port | |
start_command = "yarn dev" | |
runtime_environment_variables = { | |
HOST = "0.0.0.0" | |
HOSTNAME = "0.0.0.0" | |
NITRO_HOST = "0.0.0.0" | |
ENV = "development" | |
NODE_ENV = "development" | |
PORT = local.my_fe_port | |
NITRO_PORT = local.my_fe_port | |
CONTAINER_PORT = local.my_fe_port | |
HOST_PORT = local.my_fe_port | |
# API | |
PROXY_TARGET = "https://${local.api_domain}" | |
NUXT_API_BASE_URL = "https://${local.api_domain}" | |
# Nuxt | |
NUXT_PUBLIC_DEV = true | |
NUXT_PUBLIC_DEBUG = true | |
NUXT_PUBLIC_SITE_URL = "http://localhost:${local.my_fe_port}" | |
NUXT_PORT = local.my_fe_port | |
NUXT_HOST = "0.0.0.0" | |
# Debug | |
LOG_LEVEL = "debug" | |
} | |
} | |
} | |
auto_deployments_enabled = true | |
} | |
health_check_configuration { | |
path = "/ping" | |
healthy_threshold = 1 | |
interval = 20 | |
protocol = "HTTP" | |
timeout = 19 | |
unhealthy_threshold = 20 | |
} | |
instance_configuration { | |
cpu = "1024" | |
memory = "2048" | |
} | |
network_configuration { | |
egress_configuration { | |
egress_type = "VPC" | |
vpc_connector_arn = aws_apprunner_vpc_connector.my_vpc_connector.arn | |
} | |
ingress_configuration { | |
is_publicly_accessible = true | |
} | |
} | |
tags = { | |
Name = "my-my_fe-apprunner-service" | |
} | |
} | |
output "my_fe_apprunner_my_fe_service_url" { | |
value = aws_apprunner_service.my_fe.service_url | |
description = "" | |
} |
aws_apprunner_service_with_terraform/iam.tf
Lines 1 to 25 in c1a3057
resource "aws_iam_role" "my_app_runner_roles" { | |
name = "my_app_runner_roles" | |
assume_role_policy = jsonencode({ | |
"Version" = "2012-10-17", | |
"Statement" = [ | |
{ | |
"Effect" = "Allow", | |
"Principal" = { | |
"Service" = "build.apprunner.amazonaws.com" | |
}, | |
"Action" = "sts:AssumeRole" | |
} | |
] | |
}) | |
} | |
resource "aws_iam_role_policy_attachment" "my_app_runner_rolespolicy" { | |
role = aws_iam_role.my_app_runner_roles.id | |
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSAppRunnerServicePolicyForECRAccess" | |
} | |
resource "time_sleep" "waitrolecreate" { | |
depends_on = [aws_iam_role.my_app_runner_roles] | |
create_duration = "60s" | |
} |