ECRのイメージをデプロイします。
次の2つが参考になりました。
https://dev.classmethod.jp/articles/codepipeline-ecs-codedeploy/
https://aws.amazon.com/jp/blogs/news/build-a-continuous-delivery-pipeline-for-your-container-images-with-amazon-ecr-as-source/
前提
VPCが作成されていること
ECRにイメージがアップされていること
リポジトリ
イメージ
「イメージのURIのコピー」をクリックすると「イメージ名:タグ」をコピーできます。
例)xxxxxxxxxxxxxx.ecr.ap-northeast-1.amazonaws.com/php-sample:latest
デプロイ先
今回は、AmazonECS(ブルー/グリーン)でデプロイします。
本来はVPCでPrivateサブネット2つとロードバランサの構成になると思います。Privateサブネットにデプロイしたときにインストール作業で、インターネットに接続するため、Natゲートウェイが必要になります。Natゲートウェイは料金がかかるため、この記事では、Publicサブネット2つにデプロイすることにします。
デプロイ時のインストールが何をしているかは。。まだ、わかりません。
ロードバランサ用のセキュリティグループを作成
- セキュリティグループ名
- わかりやすい名称をつけます
- VPC
- 作成済みのVPCを選択
「セキュリティグループを作成」をクリック
「インバウンドルールの編集」をクリック
「ルールを追加」をクリック
項目 | 設定 |
---|---|
タイプ | HTTP |
ソース | 任意の場所 0.0.0.0/0 ::/0 |
を設定して「ルールを保存」をクリック
ロードバランサの作成
EC2 > 「ロードバランサの作成」 > 「HTTP HTTPS」を選んで「作成」
手順1
- 名前
- ロードバランサの名前
- リスナーの追加
- 今回は8080ポートを追加した
- アベイラビリティーゾーン
- サブネット二つを登録
手順2
「次の手順:~」をクリック
手順3
先に作成したセキュリティグループとdefaultの両方をチェック!
手順4
- 名前
- 後で削除するので適当な名前でOKです。
手順5
「次の手順:~」をクリック
手順6
「作成」をクリック
リスナーの削除
リスナーは、Fargateのサービス作成時に同時に作成するのでここで削除しておく
「リスナー」タブの「リスナー」を選択して「削除」をクリック
ターゲットグループの削除
ターゲットも、Fargateのサービス作成時に同時に作成するのでここで削除しておく
先ほど作成したターゲットグループを選択し、「Action」->「Delete」を選択する
Fargate
この記事での作成順序。サービスを作成実行した後にデプロイされてコンテナが実行されます。
- CodeDeployが利用するロールの作成
- クラスタ
- タスク定義
- サービス
CodeDeployが利用するロールの作成
再利用できるロールがある場合はそちらをご利用ください。
- サービス -> IAM -> ロール -> ロールの作成
- 「AWSサービス」から「CodeDeploy」を選択
- 「ユースケースの選択」から「CodeDeploy - ECS」を選択
- 「次のステップ:~」をクリック
- 「AWSCodeDeployRoleForECS」があることを確認
- 「次のステップ:~」をクリック
- 「次のステップ:~」をクリック
- ロール名を設定
- 「ロールの作成」
クラスタ
- サービス -> Elastic Container Service
- 「クラスターの作成」
- 「ネットワーキングのみ」を選択 -> 「次のステップ」をクリック
- 「クラスター名」を設定 -> 「作成」をクリック
VPCは先に作成したものを使用する
タスク定義
- サービス -> Elastic Container Service
- メニューから「タスク定義」をクリック
- 「新しいタスク定義の作成」をクリック
- 「FARGATE」を選択 -> 「次のステップ」
項目 | 設定値 |
---|---|
タスク定義名 | わかりやすい名前 |
タスクロール | なし |
項目 | 設定値 |
---|---|
タスクメモリ | 0.5GB |
タスクCPU | 0.25vCPU |
「コンテナの追加」をクリック
項目 | 設定値 |
---|---|
コンテナ名 | 名前をつけましょ |
イメージ | ECRのリポジトリ名とタグ名 |
メモリ制限 | ソフト制限 128 |
ポートマッピング | 80 |
項目 | 設定値 |
---|---|
GPUユニット数 | 256 (1024CPU units = 1Coreらしい。。1/4Core予約だと256) |
「追加」をクリック
「作成」をクリック
サービス
- タスク定義の詳細を表示
- 「アクション」-> 「サービスの作成」を選択
項目 | 設定値 |
---|---|
起動タイプ | FARGATE |
リビジョン | 自動設定。テストで同名のタスク定義を作っていたので、3になっています。最初なら1です。 |
プラットフォームバージョン | LATEST |
クラスター | 先に作成したクラスターを選択 |
サービス名 | 名付けてください |
タスクの数 | 今回は1 |
項目 | 設定値 |
---|---|
デプロイメントタイプ | Blue/Greenデプロイメント |
codeDeployのサービスロール | 先に作成したサービスロール |
「次のステップ」をクリック
項目 | 設定値 |
---|---|
クラスターVPC | 準備しておいたVPC |
サブネット | サブネットを2つ選択 |
セキュリティグループ | 「編集」で「default」を選択 |
パブリックIPの自動割り当て | 今回はPublicのサブネットなので Enabledとした。PrivateならDisabled |
項目 | 設定値 |
---|---|
ロードバランサーの種類 | Application Load Balancer |
ロードバランサー名 | 先に作成したロードバランサーを選択 |
「ロードバランサーに追加」をクリック
項目 | 設定値 |
---|---|
プロダクションポート | 80 |
テストリスナーポート | 8080 |
「次のステップ」をクリック
「Auto Scaling (オプション)」はそのままで「次のステップ」をクリック
「サービスの作成」をクリック
サービスが作成され、タスクが一つ起動していることを確認
FARGATEのサービス作成で作ったターゲットグループのどちらかを確認
EC2 -> ターゲットグループの「Targets」タブのStatusがhealthyであること
ロードバランサーのDNS名のURLにアクセスして、アプリケーションが表示されることを確認
CodePipeline
ECRのリポジトリに新しいイメージがプッシュされたらデプロイするように設定します。
CodePipelineの設定ファイル
CodePipelineでデプロイするためには次のファイルを準備します。
- appspec.yml
- taskdef.json
今回はCodeCommitに保存します。S3でもイケるはず!
appspec.yml
version: 0.0
Resources:
- TargetService:
Type: AWS::ECS::Service
Properties:
TaskDefinition: "<TASK_DEFINITION>" ## <TASK_DEFINITION>という文字列を置き換えることなくそのまま使用してください。
LoadBalancerInfo:
ContainerName: "php-container" ##コンテナ名、適切な名前に置き換えてください
ContainerPort: "80" ##適切なポート番号に置き換えてください
taskdef.json
{
"executionRoleArn": "arn:aws:iam::xxxxxxxxx:role/ecsTaskExecutionRole",
"containerDefinitions": [
{
"name": "php-container",
"image": "<IMAGE1_NAME>",
"portMappings": [
{
"containerPort": 80,
"hostPort": 80,
"protocol": "tcp"
}
],
"essential": true
}
],
"requiresCompatibilities": ["FARGATE"],
"networkMode": "awsvpc",
"cpu": "256",
"memory": "512",
"family": "php-task"
}
項目名 | 設定値 |
---|---|
executionRoleArn | タスクを実行するロール "arn:aws:iam::xxxxxx:role/ecsTaskExecutionRole" |
ContainerDefinitions.name | コンテナ名php-container |
ContainerDefinitions.image | IMAGE1_NAME は、パイプライン作成時に設定しCodePipeline実行時に置き換えられます。 |
CodePipeline
- サービス -> CodePipeline を選択
- 「Pipelineを作成する」をクリック
パイプライン名を設定して「次に」をクリック
項目 | 設定値 |
---|---|
ソースプロバイダー | Amazon ECR |
リポジトリ名 | amazon ECR のリポジトリ |
画像タグ | latest (画像と翻訳されているが Docker Image のImageだと思う) |
「次に」をクリック
「ビルドステージを追加する」でビルドは追加しないのでそのまま「ビルドステージをスキップ」をクリック。確認ダイアログで「スキップ」をクリック
項目 | 設定値 |
---|---|
デプロイプロバイダー | Amazon ECS(ブルー/グリーン)を選択 |
AWS CodeDeployアプリケーション | ECSのクラスターで作成したサービス実行時に作成されている。類似名称を探そう! |
AWS CodeDeploy デプロイグループ | これもサービス実行時に作成されている。類似名称を探す |
AWS ECS タスク定義 | SourceArtifact (後で修正します) |
AWS ECS AppSpecファイル | SourceArtifact (後で修正します) |
タスク定義のプレースホルダー文字 | IMAGE1_NAME (taskdef.jsonファイルの image項目に設定した文字列) |
「次に」をクリック
「レビュー」画面で確認し、「パイプラインを作成する」をクリック。
パイプラインが作成され、実行されます。
ここでは、Deployは、設定が足りないので失敗します。
SourceにCodeCommitを追加
パイプラインのSourceに、appspec.ymlとtaskdef.jsonがあるCodeCommitを追加します。
- パイプラインの詳細画面で「編集する」をクリック
- 「編集する:Source」の「ステージを編集する」をクリック
- 「アクションの追加」をクリック
項目 | 設定値 |
---|---|
アクション名 | 名前を付けます |
アクションプロバイダー | AWS CodeCommit |
リポジトリ名 | 作成済みのリポジトリを選択 |
ブランチ名 | ここでは、masterを選択 |
出力アーティファクト | パイプラインの後続のDeployで参照するアーティファクトの名称。ここではCodeFiles |
「完了」をクリック
「編集する:Source」の「完了」をクリック
SourceにAmazonECRとAWS CodeCommitの二つが追加されています。
Deployの編集
- 「編集する:Deploy」の「ステージを編集する」をクリック
- Deployの編集ボタンをクリック。(画像の赤矢印)
項目 | 設定値 |
---|---|
入力アーティファクト | 「追加」し、Sourceプロバイダで追加したアーティファクトを選択 |
Amazon ECS タスク定義 | Sourceプロバイダで追加したアーティファクトを選択 |
Amazon CodeDeploy AppSpecファイル | Sourceプロバイダで追加したアーティファクトを選択 |
入力アーティファクト | Amazon ECRの出力アーティファクトを選択 |
タスク定義のプレースホルダー文字 | IMAGE1_NAME (taskdef.jsonファイルの image項目に設定した文字列) |
「完了」をクリック
「編集する:Deploy」の「完了」をクリック
「保存する」をクリック->「保存する」をクリック
「変更をリリースする」をクリック
デプロイされます。失敗する場合はエラー表示やログなどを参照。