13
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【AWS】 Fargate CLI + Terraform で Docker コンテナを動かす簡単なチュートリアル

Last updated at Posted at 2020-04-25

AWS の ECS Fargate を使って本番環境を構築していますが、 Terraform だけだと環境構築が若干複雑になるのが悩みでした。
そこで、 Fargate CLI と Terraform を組み合わせると、非常にシンプルでいい感じになりました。

[追記]
最近は、 Fargate CLI をやめて素の AWS CLI でやっています。
完全自動構築を目指す場合、その方が確実だな思いました。詳しくは下記。

AWS Fargate サービスを Terraform で構築、 コマンドラインからデプロイ
[/追記]

デモ: https://github.com/acro5piano/terraform-fargate-example

概要

  • Terraform を使って、 AWS ECS に必要な基本的な環境を構築する
  • Fargate CLI で Fargate のサービスやタスク定義などを構築する
  • デプロイは Fargate のおかげでダウンタイム無し

モチベーション

AWS の ECS Fargate を使って本番環境を構築する場合、いくつかの選択肢があります。

  1. 管理画面からぽちぽち
  • AWS CLI
  • ECS CLI
  • Terraform
  • Fargate CLI

それぞれ、

  1. は属人的になるのでやりたくない。
  2. は設定が大変なのと、元に戻せないため、管理画面ぽちぽちするのとあまり変わらない。
  3. はセキュリティグループや ALB の設定などは結局管理画面からやらないといけない。
  4. は全てコード化でき、再適用や複製などもできるが、構築スクリプトがちょっと長くなる。そしてデプロイは単体ではできない。(できるけど Terraform 完全管理だと、運用上やりづらい)
  5. はセキュリティグループの設定などは結局管理画面からやらないといけない。

そこで、 4. と 5. を組み合わせて、いいとこ取りしようという話です。

完成品はこちらをご覧ください。

やり方

簡単な Web App を作る前提で進めます。

Dockerfile

ポート 3000 を Listen できれば、何でも良いです。

Dockerfile
FROM python:3.7.7-alpine3.11

CMD python -m http.server 3000

Terraform

Terraform は、下記を作成する役割を持っています。

  • ECS クラスター (Fargate のサービスを動かすもの)
  • Security Group (ファイアーウォール) 下記2つ
    • ALB
    • ECS ( ALB との通信のみを許可する)

aws-credentials.ini の置き場所やリージョンはプロジェクトによると思うので、適宜置き換えて下さい。

main.tf
# この辺の設定は環境によります
provider "aws" {
  region                  = "ap-northeast-1"
  shared_credentials_file = "./aws-credentials.ini"
  profile                 = "default"
}

resource "aws_ecs_cluster" "webapp" {
  name = "webapp"
}

resource "aws_security_group" "webapp" {
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    from_port       = 3000
    to_port         = 3000
    protocol        = "tcp"
    security_groups = [aws_security_group.webapp_lb.id]
  }
}

resource "aws_security_group" "webapp_lb" {
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

output "webapp_ecs_security_group" {
  value = aws_security_group.webapp.id
}

output "webapp_lb_security_group" {
  value = aws_security_group.webapp_lb.id
}

Fargate CLI で使う値は、 Terraform の output 機能で、簡単に取得できるようにしています。

Fargate CLI

次に、 Fargate CLI でサービスを作成します。

Fargate CLI のインストールは、下記からバイナリをダウンロードしてください。

やや長いのでスクリプトにしました。

aws-credentials.ini の置き場所やリージョンはプロジェクトによると思うので、適宜置き換えて下さい。

create.sh
#!/bin/bash

export AWS_SHARED_CREDENTIALS_FILE=$PWD/aws-credentials.ini
export AWS_PROFILE=default
export AWS_REGION=us-east-1

# 先に ALB を作成する
fargate lb create webapp \
    --cluster webapp \
    --port HTTP:80 \
    --security-group-id `terraform output webapp_lb_security_group`

# 次に Fargate のサービスを作成する
fargate service create webapp \
    --cluster webapp \
    --lb webapp \
    --num 1 \
    --port HTTP:3000 \
    --cpu 256 \
    --memory 512 \
    --security-group-id `terraform output webapp_ecs_security_group`

fargate service create コマンドには、 --image で ECR を明示的に指定することもできますが、何も指定しないことで

  • 現在のディレクトリにある Dockerfile をビルド
  • ビルドした Dockerfile を ECR にプッシュ
  • その ECR をイメージに指定してサービスを作成

という挙動をしてくれます。

確認する

サービスができたことを確認します。

$ fargate lb list --cluster webapp

NAME    TYPE            STATUS  DNS NAME                                        PORTS
webapp  Application     Active  webapp-xxxxxxxxxx.us-east-1.elb.amazonaws.com   HTTP:80

出力の webapp-xxxxxxxxxx.us-east-1.elb.amazonaws.com を開くと、サービスができていると思います。

作成されたもの一覧

By Terraform:

  • ECR Repository
  • ECS Cluser
  • EC2 Security Group

By Fargate CLI:

  • ECS Task Definition
  • ECS Service
  • ECS Task
  • ECS Task Execution Role
  • ALB
  • ALB Target Group
  • CloudWatch Log Group

更新する

$ fargate service deploy webapp --cluster webapp

消す

残念ながら Fargate CLI 自体には冪等性はありませんが、消すことはできます。

$ fargate service scale webapp 0 --cluster webapp
$ fargate service destroy webapp --cluster webapp
$ fargate lb destroy webapp
$ terraform destroy

Note: ECS Execution Role will not be deleted.

まとめ

簡潔になりましたが、これを基にデプロイのスクリプトなども容易に作れると思います。

下記のデモのリポジトリでは、 Makefile や fargate コマンドのラッパーを使って、より簡潔にしています。良かったらご覧ください。

13
17
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?