🥰
http4s で書いたサーバーを aws apprunner にデプロイする(with terraform)
サーバーのコードは以下の記事で書いたものと同じ想定.
インフラの設定
aws apprunner を terraform で作成します. まず必要なリソースを作成します.
aws apprunner を利用するために、デプロイ用の iam role, 実行用の iam role と ECR を用意します.
main.tf
resource "aws_iam_role" "runtime" {
name = "example-runtime"
path = "/"
assume_role_policy = file("path/to/runtime.json")
}
resource "aws_iam_role" "deploy" {
name = "example-deploy"
path = "/"
assume_role_policy = file("path/to/deploy.json")
}
resource "aws_iam_role_policy_attachment" "deploy" {
role = aws_iam_role.deploy.name
// aws が提供する, apprunner ビルド時に ecr にアクセスするためのロール
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSAppRunnerServicePolicyForECRAccess"
}
resource "aws_ecr_repository" "example" {
name = "example"
image_tag_mutability = "MUTABLE"
image_scanning_configuration {
scan_on_push = true
}
}
runtime.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": [
"tasks.apprunner.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
deploy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": [
"build.apprunner.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
terraform apply
ビルド定義
ビルド定義をゴニョゴニョします. apprunner で latest タグに更新があったら新しい revision をデプロイしたいので dockerUpdateLatest := true
を設定します.
build.sbt
val V = new {
val scala3 = "3.3.0"
val http4s = "1.0.0-M36"
val CE = "3.5.0"
}
lazy val server = project.in(file("server"))
.enablePlugins(JavaAppPackaging)
.enablePlugins(DockerPlugin)
.settings(
run / fork := true,
scalaVersion := V.scala3,
libraryDependencies ++= Seq(
"org.http4s" %% "http4s-core" % V.http4s,
"org.http4s" %% "http4s-dsl" % V.http4s,
"org.http4s" %% "http4s-ember-server" % V.http4s,
"org.typelevel" %% "cats-effect" % V.CE
)
)
.settings(
Docker /packageName := "example",
dockerRepository := "<aws account id>.dkr.ecr.<region>.amazonaws.com",
dockerBaseImage := "openjdk:17-jdk-slim-bullseye",
dockerExposedPorts ++= Seq(8080),
dockerUpdateLatest := true,
)
sbt docker:publish
apprunner の作成
ecr にイメージがプッシュされたのを確認したら以下の設定を terraform に追加します.
main.tf
resource "aws_apprunner_service" "this" {
service_name = "example"
// アプリケーションのランタイムで利用する role. このロールに s3 や dynamodb にアクセスする権限を付与する. ecs の task role に相当する.
instance_configuration {
instance_role_arn = aws_iam_role.runtime.arn
}
source_configuration {
authentication_configuration {
// アプリケーションのデプロイに利用する role. プライベートな ECR からイメージを取得したりシークレットを読み出す際に必要. ecs の task execution role に相当する.
access_role_arn = aws_iam_role.deploy.arn
}
image_repository {
image_configuration {
port = "8080"
}
image_identifier = "${aws_ecr_repository.example.repository_url}:latest"
image_repository_type = "ECR"
}
}
lifecycle {
ignore_changes = [
source_configuration[0].image_repository[0].image_identifier
]
}
}
terraform apply
Discussion