Amazon ECSを試したメモ

雰囲気をつかむこと・動かすことを優先に考えてポチポチ。

方針

  • Nginx + PHP-FPM
  • GitHubリポジトリのmasterに変更があったら自動デプロイ
    • pull-req mergeでデプロイ
    • pull-req revertでロールバック
  • デプロイ時にシングルタスク(e.g. database migrate)を実行
  • ログはCloudWatch
  • なんとなく本番っぽいフロー

GitHubリポジトリのmasterを更新して、CodePipelineから自動デプロイされたら成功 :)

ソースコード

github.com

やったことメモ

リポジトリ作成

Elastic Container Service > Amazon ECR > リポジトリ
ポチポチするだけで、特に悩むことはない。
イメージの追加は、あとでCode Pipelineで行う。

ロググループ作成

CloudWatch > ログ > アクション
あとでコンテナで使用する。
ロググループ名はecstestにした。

ECSタスク定義作成

Elastic Container Service > Amazon ECS > タスク定義

ラベル
タスク定義名 ecstest
タスクロール なし
ネットワークモード default
タスクメモリ(MiB) 256
タスクCPU(単位) 256

コンテナの追加

PHPの設定。表に立たないのでポートマッピングはしない。 ヘルスチェックはいったんなし。
ログはawslogsを使用する。ロググループ名は前述で作成したものを指定する。

ラベル
コンテナ名 ecstest-php
イメージ XXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/ecstest-php:latest
メモリ制限(MB) ハード制限, 128
ログ設定 awslogs, awslogs-group:ecstest, awslogs-region:ap-northeast-1, awslogs-stream-prefix:php

Nginxの設定。ポートマッピングをする。
ecstest-phpをリンクする。aliasはNginxの設定に合わせてphpfpm。
ログはawslogsを使用する。prefixだけPHPの設定と違うものにする。

ラベル
コンテナ名 ecstest-nginx
イメージ XXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/ecstest-nginx:latest
メモリ制限(MB) ハード制限, 128
ポートマッピング ホストポート:なし, コンテナポート:80, tcp
リンク ecstest-php:phpfpm
ログ設定 awslogs, awslogs-group:ecstest, awslogs-region:ap-northeast-1, awslogs-stream-prefix:nginx

ロードバランサー作成

EC2 > ロードバランサー
ECSサービスで使用する。

Application Load Balancerを選択。

ラベル
名前 ecstest
スキーム インターネット向け
IPアドレスタイプ ipv4
リスナー プロトコル:HTTP, ポート:80

VPC, アベイラビリティゾーン, セキュリティグループはよしなに。

ラベル
ターゲットグループ 新しいターゲットグループ
名前 ecstest
以下略 デフォルト値

ターゲットの登録では何も選択しない。

ECSクラスター作成

Elastic Container Service > Amazon ECS > クラスター

EC2 Linux + ネットワーキングを選択。

ラベル
クラスター名 ecstest
プロビジョニングモデル オンデマンドインスタンス
EC2 インスタンスタイプ t2.micro
インスタンス数 1
EBSストレージ(GiB) 22
キーペア なし
コンテナインスタンスIAMロール ecsInstanceRole(default)

VPC, サブネット, セキュリティグループはよしなに。

サービス作成

ecstestクラスター > サービス
リポジトリにイメージを追加していないので、タスクは立ち上がらないけど、いったん気にしない。

ステップ1: サービスの設定

最大率200は指定タスク数の200%まで許容する。
うっかりインスタンスのメモリ上限を超えるとデプロイに失敗したりする。

ラベル
タスク定義 ecstest:1
クラスター ecstest
サービス名 ecstest
タスク数 1
最小ヘルス率 50
最大率 200
配置テンプレート AZ バランススプレッド

ステップ2: ネットワーク構成

ラベル
ELBタイプ Application Load Balancer
サービス用IAMロールの選択 AWSServiceRoleForECS
ELB名 ecstest

コンテナの選択からecstest-nginx:0:80を追加。

ラベル
リスナーポート 80:HTTP
ターゲットグループ名 ecstest

ステップ3: Auto Scaling

デフォルトのまま。

CodePipeline作成

AWS CodePipeline

ステップ1: 名前

ラベル
パイプライン名 ecstest

ステップ2: ソース

ラベル
ソースプロバイダ GitHub
リポジトリ utahta/php-ecs-sample
ブランチ master

ステップ3: ビルド

CodeBuildプロジェクトを作成して保存する。

ラベル
ビルドプロバイダ AWS CodeBuild
プロジェクトの設定 新しいビルドプロジェクトを作成
プロジェクト名 ecstest
環境の設定
環境イメージ AWS CodeBuildマネージド型イメージの使用
OS Ubuntu
ランタイム Docker
バージョン aws/codebuild/docker:17.09.0
ビルド仕様 ソースコードのルートディレクトリのbuildspec.ymlを使用
キャッシュ_
タイプ なし
CodeBuildサービスロール アカウントで新しいロールを作成します
ロール名 code-build-ecstest-service-role

VPC, サブネット, セキュリティグループはよしなに。

アドバンストの環境変数を設定。buildspec.ymlで使用する。

Key Value
AWS_ACCOUNT_ID XXXXXXXXX
AWS_DEFAULT_REGION ap-northeast-1

ステップ4: デプロイ

ラベル
デプロイプロバイダ Amazon ECS
クラスター名 ecstest
サービス名 ecstest

ステップ5: サービスロール

ラベル
ロール名 AWS-CodePipeline-Service

IAM編集

IAM > ロール > code-build-ecstest-service-role

AmazonEC2ContainerRegistryFullAccessをアタッチ。
イメージの追加に必要。

AmazonEC2ContainerServiceFullAccessをアタッチ。
ECSのタスク実行に必要。本当はタスク実行のみ許可するポリシーを作成してアタッチした方が良いけど省略。

ECSタスク定義作成(シングルタスク)

Elastic Container Service > Amazon ECS > タスク定義

デプロイするときに合わせて実行するタスク(仮)の作成。
ここではdatabase migrateを想定したタスクを作る。
メモリ・CPUは適当。

ラベル
タスク定義名 ecstest-migrate
タスクロール なし
ネットワークモード default
タスクメモリ(MiB) 256
タスクCPU(単位) 256

コンテナの追加

コマンドの設定。ヘルスチェックはなし。ログはawslogsを使用する。
コマンドにmigrateコマンド(仮)を指定する。

ラベル
コンテナ名 ecstest-migrate
イメージ XXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/ecstest-php:latest
メモリ制限(MB) ハード制限, 128
コマンド php,worker.php
ログ設定 awslogs, awslogs-group:ecstest, awslogs-region:ap-northeast-1, awslogs-stream-prefix:migrate

おわり

ECSよりもNginxの設定でハマった。

参考

Amazon ECS
AWS CodePipeline
Twelve-Factor App