はじめに
改めて terraform を勉強したいと思ってドキュメントを見ていたら、扱えるリソースとして ECS もサポートしているようなのでひとまず試してみる。
尚、利用する terraform のバージョンは以下の通り。
% terraform -version
Terraform v0.6.1
改めて ECS とは
黒帯目指して
www.slideshare.net
上記の資料がとても詳しいのでウンチクは割愛。
terraform で ECS
terraform のバージョン
今回利用する terraform のバージョンは以下の通り。
% terraform -version
Terraform v0.6.1
terraform で扱える ECS のリソース
terraform で扱える ECS のリソースは以下の通り。
詳細については上記のドキュメントを参照して頂くとして、それぞれのサンプルを以下に掲載。
aws_ecs_cluster
ECS のクラスタは以下のように定義。
resource "aws_ecs_cluster" "kappa-cluster" { name = "kappa-cluster" }
aws_ecs_task_definition
Task definition は以下の通りに定義。
resource "aws_ecs_task_definition" "docker_registry" { family = "docker_registry" container_definitions = "${file("task-definitions/registry.json")}" }
registry.json
は以下の通り。
[ { "environment": [], "name": "registry", "image": "registry:2", "cpu": 10, "portMappings": [ { "containerPort": 5000, "hostPort": 5000 } ], "memory": 10, "command": [ ], "essential": true } ]
Docker registry コンテナを起動する定義。
aws_ecs_service
サービスは以下のように定義。
resource "aws_ecs_service" "kappa-registry" { name = "kappa-registry" cluster = "${aws_ecs_cluster.kappa-cluster.id}" task_definition = "${aws_ecs_task_definition.docker_registry.arn}" desired_count = 1 }
ECS の中で Service についてなかなか理解が出来ていなかったが、先ほどの資料の 43 ページ目で一発理解出来た気がする。ざっくり、ECS で docker run
するなら、Run Task
か Service
を定義すると覚えておけばイイと勝手に解釈。
さらに
コンテナインスタンスが必要になったりするので、github にサンプルをアップ。
事前にアクセスキー、シークレットアクセスキー、SSH キー、VPC のサブネット、セキュリティグループ(1 つ)と以下のような IAM ロール(以下のサンプルでは your_iam_role_name
という名前で定義する)を用意しておく。
{ "Version": "2012-10-17", "Statement": [ { "Action": "ecs:*", "Effect": "Allow", "Resource": "*" } ] }
ということでサンプルを動かしてみる
事前に用意した情報
パラメータ | 値 | 備考 |
---|---|---|
アクセスキー | AK123456789123456789 | |
シークレットアクセスキー | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | |
SSH キー | your_ssh_key_name | コンテナインスタンスにログインする為に必要 |
VPC サブネット | subnet-12345678 | 任意の VPC から一つのサブネットを選択 |
セキュリティグループ | sg-12345678 | 任意の VPC で定義されているセキュリティグループを選択 |
IAM ロール | your_iam_role_name |
サンプルを少し修正
% git diff oreno_tf_ecs_ecs.tf [~/git/myrepo/oreno_docker-compose] diff --git a/oreno_tf_ecs_ecs.tf b/oreno_tf_ecs_ecs.tf index fedebd8..61c92cc 100644 --- a/oreno_tf_ecs_ecs.tf +++ b/oreno_tf_ecs_ecs.tf @@ -21,7 +21,7 @@ resource "aws_ecs_service" "kappa-sample1" { name = "kappa-sample1" cluster = "${aws_ecs_cluster.kappa-cluster.id}" task_definition = "${aws_ecs_task_definition.sample_app1.arn}" - desired_count = 0 + desired_count = 1 } resource "aws_ecs_service" "kappa-sample2" { @@ -35,5 +35,5 @@ resource "aws_ecs_service" "kappa-registry" { name = "kappa-registry" cluster = "${aws_ecs_cluster.kappa-cluster.id}" task_definition = "${aws_ecs_task_definition.docker_registry.arn}" - desired_count = 0 + desired_count = 1 }
desired_count
を 0
から 1
に増やすことで Task definition で定義されている Task の数を定義する。
% git diff oreno_tf_ecs_ec2.tf diff --git a/oreno_tf_ecs_ec2.tf b/oreno_tf_ecs_ec2.tf index 071e6b0..5e66e0a 100644 --- a/oreno_tf_ecs_ec2.tf +++ b/oreno_tf_ecs_ec2.tf @@ -2,7 +2,7 @@ # Launch Container Instance # resource "aws_instance" "oreno_tf_ecs" { - count = 0 + count = 1 instance_type = "${var.instance_type}" ami = "${lookup(var.aws_amis, var.region)}" subnet_id = "${var.subnet}"
コンテナインスタンスを 1
台起動するので count = 0
を count = 1
に修正。
以下のように plan を実行
terraform plan \ -var 'access_key=AK123456789123456789' \ -var 'secret_key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \ -var 'ssh_key_name=your_ssh_key_name' \ -var 'subnet=subnet-12345678' \ -var 'securiy_group=sg-12345678' \ -var 'iam_profile_name=your_iam_role_name'
以下のように出力される。
+ aws_ecs_cluster.kappa-cluster name: "" => "kappa-cluster" + aws_ecs_service.kappa-registry cluster: "" => "${aws_ecs_cluster.kappa-cluster.id}" desired_count: "" => "1" name: "" => "kappa-registry" task_definition: "" => "${aws_ecs_task_definition.docker_registry.arn}" + aws_ecs_service.kappa-sample1 cluster: "" => "${aws_ecs_cluster.kappa-cluster.id}" desired_count: "" => "1" name: "" => "kappa-sample1" task_definition: "" => "${aws_ecs_task_definition.sample_app1.arn}" + aws_ecs_service.kappa-sample2 cluster: "" => "${aws_ecs_cluster.kappa-cluster.id}" desired_count: "" => "0" name: "" => "kappa-sample2" task_definition: "" => "${aws_ecs_task_definition.sample_app2.arn}" + aws_ecs_task_definition.docker_registry arn: "" => "<computed>" container_definitions: "" => "bd45398f7dc732c1ba3a004a8b9c9f1c118a8eb9" family: "" => "docker_registry" revision: "" => "<computed>" + aws_ecs_task_definition.sample_app1 arn: "" => "<computed>" container_definitions: "" => "6d19f9f53f6179d307ff2563cec96da7ef466117" family: "" => "sample_app1" revision: "" => "<computed>" + aws_ecs_task_definition.sample_app2 arn: "" => "<computed>" container_definitions: "" => "56d66c407c63da3519cbcd03a73ab551bb78b9cd" family: "" => "sample_app2" revision: "" => "<computed>" + aws_instance.oreno_tf_ecs ami: "" => "ami-50b01450" associate_public_ip_address: "" => "1" availability_zone: "" => "<computed>" ebs_block_device.#: "" => "<computed>" ephemeral_block_device.#: "" => "<computed>" iam_instance_profile: "" => "ecs_iam_role" instance_type: "" => "t2.micro" key_name: "" => "your_ssh_key_name" placement_group: "" => "<computed>" private_dns: "" => "<computed>" private_ip: "" => "<computed>" public_dns: "" => "<computed>" public_ip: "" => "<computed>" root_block_device.#: "" => "<computed>" security_groups.#: "" => "<computed>" source_dest_check: "" => "1" subnet_id: "" => "subnet-12345678" tags.#: "" => "1" tags.Name: "" => "ecs-container-instance01" tenancy: "" => "<computed>" user_data: "" => "592ff0d81b045135aec95ba9b2adfdbfcf93ad62" vpc_security_group_ids.#: "" => "1" vpc_security_group_ids.3722172370: "" => "sg-12345678" Plan: 8 to add, 0 to change, 0 to destroy.
そして apply
terraform apply \ -var 'access_key=AK123456789123456789' \ -var 'secret_key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \ -var 'ssh_key_name=your_ssh_key_name' \ -var 'subnet=subnet-12345678' \ -var 'securiy_group=sg-12345678' \ -var 'iam_profile_name=your_iam_role_name'
ヅラヅラとメッセージが流れて...
Apply complete! Resources: 8 added, 0 changed, 0 destroyed.
terraform show
でも確認しておこう。
確認
コンテナインスタンスにログインして確認。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1db091f91203 centos:centos6 "/bin/sh -c 'hostnam 20 seconds ago Up 20 seconds 0.0.0.0:32769->4567/tcp ecs-sample_app1-6-centos-c0eabebd9b8d90898301 818edd2adf1e redis:latest "/entrypoint.sh redi 34 seconds ago Up 33 seconds 0.0.0.0:32768->6379/tcp ecs-sample_app1-6-redis-fce9a3e7d4fbd9ea8b01 ae12b982594b registry:2 "registry cmd/regist 47 seconds ago Up 47 seconds 0.0.0.0:5000->5000/tcp ecs-docker_registry-2-registry-eebb8da6f3c2a8d33f00 e8c5b33fd767 amazon/amazon-ecs-agent:latest "/agent" 2 minutes ago Up 2 minutes 127.0.0.1:51678->51678/tcp ecs-agent
ひと通り Task definition で定義した内容でコンテナが起動してるが、AWS CLI でも定義を確認しておく。
# クラスタ一覧確認 % aws ecs list-clusters { "clusterArns": [ "arn:aws:ecs:ap-northeast-1:123456789123:cluster/kappa-cluster" ] } # サービス一覧確認 % aws ecs list-services --cluster kappa-cluster { "serviceArns": [ "arn:aws:ecs:ap-northeast-1:123456789123:service/kappa-sample2", "arn:aws:ecs:ap-northeast-1:123456789123:service/kappa-sample1", "arn:aws:ecs:ap-northeast-1:123456789123:service/kappa-registry" ] } # コンテナインスタンス一覧 % aws ecs list-container-instances --cluster kappa-cluster { "containerInstanceArns": [ "arn:aws:ecs:ap-northeast-1:123456789123:container-instance/7b242f77-58e9-4c75-98d2-b5b878077dd8" ] } # タスク定義一覧 % aws ecs list-task-definitions [~/git/myrepo/oreno_docker-compose] { "taskDefinitionArns": [ "arn:aws:ecs:ap-northeast-1:123456789123:task-definition/docker_registry:1", "arn:aws:ecs:ap-northeast-1:123456789123:task-definition/docker_registry:2", "arn:aws:ecs:ap-northeast-1:123456789123:task-definition/sample_app1:5", "arn:aws:ecs:ap-northeast-1:123456789123:task-definition/sample_app1:6", "arn:aws:ecs:ap-northeast-1:123456789123:task-definition/sample_app2:6", "arn:aws:ecs:ap-northeast-1:123456789123:task-definition/sample_app2:7" ] } # タスク一覧 % aws ecs list-tasks --cluster kappa-cluster { "taskArns": [ "arn:aws:ecs:ap-northeast-1:123456789123:task/331e0a1d-a9ac-4651-b92b-35288dd9a657", "arn:aws:ecs:ap-northeast-1:123456789123:task/ce8c54e2-9a52-446d-9718-9c81c3dfdcc1" ] }
ということで...
気付いた点
- Task definition の内容を update して apply してもコンテナが入れ替わらないっぽい
こちらの資料に記載されているように Task definition の内容を update(JSON の内容を修正)して terraform apply
すると自動で古いコンテナから新しいコンテナに入れ替わってくれるのかなーと期待していたが、そのような動作にはならなかった。terraform 以外での挙動は試せていないので切り分けは不完全、引き続き要調査。(自分の認識不足も否めない)
- Run Task に該当するリソースが無いのはナゼなんだろう
漠然とした疑問。
AWS CLI + JSON で弄るのと比較して...
Task definition は JSON で定義するのは変わらないので、どっちがイイとかは言えないが、terraform を利用することで得られるメリット(state ファイルによる状態管理等)を享受出来る点では terraform を利用する意味はあると感じた。