概要
夏頃、AWS FargateとEKS祭りに参加してきた。
Fargateが東京リージョンにもやってきたので、そのためだ。
会社のチーム内でもAWS Fargateの機運が高まり、頑張って検証をしたので、まずはTerraformで構築する簡単なものを記録しておく。
なお、基本的には下記Terraformのドキュメントを参考にしている。
https://www.terraform.io/docs/providers/aws/r/ecr_repository.html
<a href=“https://www.terraform.io/docs/providers/aws/r/ecs_cluster.html” rel=“noopener noreferrer” target="_blank">https://www.terraform.io/docs/providers/aws/r/ecs_cluster.html
https://www.terraform.io/docs/providers/aws/r/ecs_service.html
https://www.terraform.io/docs/providers/aws/r/ecs_task_definition.html
構成
PrivateサブネットにFargateを設置する。
コンテナにグローバルIPを付与することもできるが、EIPをつけずALBにぶら下げる場合はNAT Gateway経由でインターネットに接続するようなサブネット構成にすることになると思う。でないとイメージをpullできない!(ここでまずハマった)
今回はALBにぶら下げるようにする。
ALB
先にコンテナをぶら下げるALBを作成しておく。(グローバルIPを振る場合は不要)
SSL証明書の設定(ACM)等は自分の環境にあわせて修正する。
下記ではACMで取得した証明書を指定して、443へリダイレクトするようにしている。
resource "aws_lb" "staging-inamuu" {
name = "staging-inamuu"
internal = false
load_balancer_type = "application"
security_groups = ["${aws_security_group.staging-inamuu-alb.id}"]
subnets = ["${aws_subnet.staging-public-1a.id}"]
enable_deletion_protection = true
tags {
Env = "staging"
}
}
resource "aws_lb_target_group" "staging-inamuu" {
name = "staging-inamuu-lb-tg"
port = 80
protocol = "HTTP"
vpc_id = "${aws_vpc.staging-inamuu-vpc.id}"
target_type = "ip"
deregistration_delay = "10"
}
resource "aws_alb_listener" "staging-inamuu" {
load_balancer_arn = "${aws_lb.staging-inamuu.arn}"
port = "80"
protocol = "HTTP"
default_action {
type = "redirect"
redirect {
port = "443"
protocol = "HTTPS"
status_code = "HTTP_301"
}
}
}
resource "aws_alb_listener" "staging-inamuu-https" {
load_balancer_arn = "${aws_lb.staging-inamuu.arn}"
port = "443"
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-2015-05"
certificate_arn = "${aws_acm_certificate.staging-inamuu-com.arn}"
default_action {
target_group_arn = "${aws_lb_target_group.staging-inamuu.arn}"
type = "forward"
}
}
ECR
次にECRのリポジトリを作る。
ここにアップロードしたDockerイメージがFargateで稼働する。
ECRにリポジトリを作ると、ログイン手順やpush手順等が表示されるのでそれに則って、Dockerイメージをpushする。(Fargate構築する前にpushしておくと吉)
このあたりからイメージのタグをどういった値(latest以外)にするかなどを検討しはじめた方が良さそう。
resource "aws_ecr_repository" "staging-inamuu-app" {
name = "staging-inamuu-app"
}
クラスター
次にFargateの母体となるクラスターを構築する。
## Cluster
resource "aws_ecs_cluster" "staging-inamuu" {
name = "staging-inamuu"
}
タスク定義(task definition)
実行するコンテナのスペックや、ログ設定、イメージ元を定義する。
これを元にコンテナが作成される。
注意点として、awslogsで指定したlogグループを事前にcloudwatchlogsで作成しておかないと、構築時にエラーになってしまう。地味にハマる。
$ cat task-definition/staging-inamuu-app.json
[
{
"image": "XXXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/staging-inamuu-app",
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/staging-inamuu-app",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "ecs"
}
},
"cpu": 256,
"memory": 512,
"networkMode": "awsvpc",
"name": "staging-inamuu-app",
"portMappings": [
{
"containerPort": 80,
"protocol": "tcp"
}
]
}
]
上記でタスク定義の元を指定したら、下記でタスク定義を作成する。
## Task Definition
resource "aws_ecs_task_definition" "staging-inamuu-task" {
family = "staging-inamuu"
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
task_role_arn = "arn:aws:iam::${var.aws_account_id}:role/ecsTaskExecutionRole"
execution_role_arn = "arn:aws:iam::${var.aws_account_id}:role/ecsTaskExecutionRole"
cpu = 256
memory = 512
container_definitions = "${file("files/task-definitions/staging-inamuu-app.json")}"
}
サービス
最後に、サービスを設定する。
ここではFARGATEで起動することや、セキュリティーグループなどネットワーク周りを定義する。
## Service
resource "aws_ecs_service" "staging-inamuu-service" {
cluster = "${aws_ecs_cluster.staging-inamuu.id}"
deployment_minimum_healthy_percent = 50
desired_count = "${var.aws_ecs_service_desired_count_app}"
launch_type = "FARGATE"
name = "staging-inamuu-service"
lifecycle {
ignore_changes = [
"desired_count",
]
}
load_balancer {
container_name = "staging-inamuu-app"
container_port = "80"
target_group_arn = "${aws_lb_target_group.staging-inamuu-app.arn}"
}
network_configuration {
subnets = [
"${aws_subnet.staging-inamuu-app-1a.id}",
]
security_groups = [
"${aws_security_group.staging-inamuu-app.id}",
]
}
task_definition = "${aws_ecs_task_definition.staging-inamuu-task.arn}"
}
ここまで来たら、あとはデプロイすればOK。
最初はとりあえずAWSコンソールから新しくタスク定義のリビジョンを作成すればOK.
自動的にデプロイされて、うまくいけば、ALB経由でコンテナにアクセスできるようになる。
細かい設定等についてはまた別途。
<p style='padding: 5px;'>