概要
ECSというコンテナのクラスタ環境構築のサービスをTerraformで作成してみます。
簡単のため、以下の設定はこのコードには含んでいません。
- EC2インスタンスのオートスケール用のアラーム設定なし
- ECSのコンテナのオートスケールはなし(Terraform未対応)
完成形は以下です。
環境
- Terraform v0.6.16
ポイント
- VPC, Subnet, RouteTable, SecurityGroup, NATの用意
- AutoScalingGroupの用意
- ECS用のIAMを作る
- ECSに最適化されたAMIを使用する
- user_dataでECSクラスターに登録するための設定を作る
- task definitionの定義
- ECSの作成
VPC, Subnet, RouteTable, SecurityGroup, NATの用意
今まで通りなので割愛します。
AutoScalingGroupの用意
これも前述と同じなので割愛。ただしuser-dataには後述するものを使用します。
ECS用のIAMを作る
※@riywoさんに「AWS Managed PolicyをRoleにattachしておいた方がよい」というご指摘を受けたので修正しています(修正コミット)。ご指摘ありがとうございます!
resource "aws_iam_role" "ecs_instance_role" { name = "ecs_instance_role" assume_role_policy = "${file("policies/ec2-assume-role.json")}" } resource "aws_iam_role" "ecs_service_role" { name = "ecs_service_role" assume_role_policy = "${file("policies/ecs-assume-role.json")}" } resource "aws_iam_policy_attachment" "ecs_instance_role_attach" { name = "ecs-instance-role-attach" roles = ["${aws_iam_role.ecs_instance_role.name}"] policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role" } resource "aws_iam_policy_attachment" "ecs_service_role_attach" { name = "ecs-service-role-attach" roles = ["${aws_iam_role.ecs_service_role.name}"] policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole" } resource "aws_iam_instance_profile" "ecs" { name = "ecs-instance-profile" path = "/" roles = ["${aws_iam_role.ecs_instance_role.name}"] }
assumeRoleを用意してAWS Managed Policyをattachしています。
ec2-assume-role.json
{ "Version": "2008-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Principal": { "Service": "ec2.amazonaws.com" }, "Effect": "Allow", "Sid": "" } ] }
ecs-assume-role.json
{ "Version": "2008-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Principal": { "Service": "ecs.amazonaws.com" }, "Effect": "Allow", "Sid": "" } ] }
似ているようでPrincipal
に指定しているAWSサービスは違うので注意してください。
ECSに最適化されたAMIを使用する
最新版は以下で更新されます。
Amazon ECS 対応 AMI - Amazon EC2 Container Service
今回は以下のようにvariables.tf
に書きます。
variable "access_key" {} variable "secret_key" {} variable "region" { default = "ap-northeast-1" } variable "amis" { default = { ecs = "ami-2b08f44a" nat = "ami-27d6e626" } } variable "key_name" { default = "YOUR_SSH_KEY_PAIR_NAME" }
user_dataでECSクラスターに登録するための設定を作る
ECS optimized なAMIではECS agentというデーモンが起動します。このデーモンは/etc/ecs/ecs.config
というファイルの設定を読み込むので、ここにクラスタ名を記述することで、ASGで生成されたインスタンスがECSのクラスタに自動で登録されるようになります。クラスタ名をapi-cluster
とすると、
#!/bin/bash echo ECS_CLUSTER=api-cluster >> /etc/ecs/ecs.config
と記述します。
ちなみにDockerHubのPrivateRepoを使いたい場合は以下のように設定するとimageをpullできるようになります。
#!/bin/bash cat << EOF >> /etc/ecs/ecs.config ECS_CLUSTER=api-cluster ECS_ENGINE_AUTH_TYPE=docker ECS_ENGINE_AUTH_DATA={"https://index.docker.io/v1/":{"username":"ログインユーザ名","password":"パスワード","email":"メールアドレス"}} EOF
task definitionの定義
今回はシンプルにnginxのみ起動するので以下の通りにします。
[ { "name": "nginx", "image": "nginx", "cpu": 1024, "memory": 200, "essential": true, "portMappings": [ { "containerPort": 80, "hostPort": 80 } ] } ]
使用できるパラメータは以下の通りです。
タスク定義パラメーター - Amazon EC2 Container Service
ECSの作成
クラスタ名、TaskDefinition、IAMRole、RolePolicyなどを指定します。
resource "aws_ecs_cluster" "api_cluster" { name = "api-cluster" } resource "aws_ecs_service" "api" { name = "api-service" cluster = "${aws_ecs_cluster.api_cluster.id}" task_definition = "${aws_ecs_task_definition.api.arn}" desired_count = 1 iam_role = "${aws_iam_role.ecs_service_role.arn}" depends_on = ["aws_iam_role_policy.ecs_service_role_policy"] deployment_minimum_healthy_percent = 50 deployment_maximum_percent = 100 load_balancer { elb_name = "${aws_elb.dev_elb.name}" container_name = "nginx" container_port = 80 } } resource "aws_ecs_task_definition" "api" { family = "api" container_definitions = "${file("task-definitions/api.json")}" }
各パラメータは以下の役割があります。
パラメータ | 意味 |
---|---|
family | task definition名 |
desired_count | 起動したいコンテナ数。ただしポートの競合などがあるとインスタンスが増えない限りコンテナも増えない |
deployment_minimum_healthy_percent | rolling update時に最低限保持する旧コンテナ数。desired_countに対する割合 |
deployment_maximum_percent | rolling update時に新旧コンテナが混在して最大いくつまで起動するかの数。desired_countに対する割合 |
以上のポイントを押さえれば問題なく作成することが出来ます。お疲れ様でした。