はじめに
terraformでecsのタスクを作成する場合、ecsのタスク定義を書く必要がありますが、docker-compose.ymlを再度ecs用に書き直す感じがどうにも気が乗りませんでした。
なので、ecs-cliを使ってdocker-compose.ymlを利用しつつ、terraformも活用する方法の例です。
イメージとしては、terraformでvpc、サブネット、セキュリティグループ、ALB、ターゲットグループ、ecsのクラスターを作成し、ecs-cliでecsのサービス、タスクを作成する感じです。また作成したタスクは既存のターゲットグループにひもづくようにします。
terraformで各リソースを作成する手順はこの本が参考になります。
以下からはterraformでのリソース作成は終わってる前提です。
ecs-cliの設定
まず、terraformで作成したecsのクラスターに対してecs-cli configureコマンドを実行します。
以降のecs-cliコマンドがここで指定したclusterに対して実行されるようになります。
また、ecsはec2とfargateのどちらかを選べますが、ここではfargateを選んでいます。
$ ecs-cli configure \
--cluster <作成したclusterを指定> \
--region ap-northeast-1 \
--default-launch-type FARGATE
タスク定義の元を作成
まずタスク定義の元となるdocker-compose.ymlです。
appが実際のアプリケーションのコードで、リバースプロキシとしてnginxのイメージがあるような構成です。
最終的にはnginxのポート80をコンテナのポートとしていきます。
事前にコンテナのイメージはecrやdocker hubに上げておき、そのパスをimageに指定します。
また、ecs-cliでdocker-compose.ymlを利用する場合、docker-composeのversionにも気をつける必要があります。
参考:https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ECS_CLI.html
version: "3" # ecs-cliがサポートしているversionは3まで。
services:
app:
image: <ecrのパス>
ports:
- 7777:7777
nginx:
image: <ecrのパス>
ports:
- 80:80
depends_on:
- app
ecsのパラメータの作成
docker-compose.ymlだけでは対応しきれない設定などはecsパラメータとして別のymlを用意し定義することができます。
参考:https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/cmd-ecs-cli-compose-ecsparams.html
ここでfargateに割り当てる割り当てるリソースの値や、サブネット、セキュリティグループの指定ができます。
事前にterraformで作成しておいたサブネットやセキュリティグループをここで指定します。
またfargateの場合、必須項目となっているcpu_limitとmem_limitは可能な組み合わせが存在し、その組み合わせの中で選ぶ必要があります。
参考: https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task-cpu-memory-error.html
version: 1
task_definition:
task_execution_role: ecs-task-execution
ecs_network_mode: awsvpc
task_size:
cpu_limit: "256"
mem_limit: "0.5GB"
run_params:
network_configuration:
awsvpc_configuration:
subnets:
# fargateを配置するサブネット。terraformで事前に作っておく。
- subnet-*****************
- subnet-*****************
security_groups:
# fargateのセキュリティグループ。
# ecs-cliで --container-port 80 としているので80のポートをインバウンドで開けているようなセキュリティグループをterraformで事前に作っておく。
- sg-*****************
assign_public_ip: ENABLED
ecs-cli compose service コマンドの作成
ecs-cliには --target-group-arn
、--container-name
、--container-port
というoptionがあり、これを指定することで既存のターゲットグループをecsのタスクと紐づけることができます。
--target-group-arn
には事前に作っておいたターゲットグループのarn、
--container-name
にはdocker-compose.ymlに記載したコンテナ名、
--container-port
にはコンテナのポートとする80、
を指定しています。
$ ecs-cli compose \
--file docker-compose.prod.yml \
--project-name <サービス名> \
--ecs-params ./ecs_params.yml \
service up \
--vpc <vpcのid> \
--target-group-arn <ecsのタスクをぶら下げるターゲットグループのarnを指定> \
--container-name nginx \
--container-port 80
このecs-cliコマンドを実行すれば、ecsのサービス、タスクが作成されます。
また作成したタスクはterraformで作成したターゲットグループにひもづきます。
これで冒頭の terraformでecsのクラスターまでを作成し、ecs-cliでecsのサービス、タスクを作成
ができました。
実際にこれを活用する場合はecs-params.ymlにコンテナのヘルスチェックを追加したり、ecs-cliコマンドをそのまま打つのではなくもっと安全にデプロイできるフローの整備もする必要があると思います。が、一旦これでリリースはできます。