CodeDeployのInstallイベントが一向に終わらないので原因切り分けと設定を見直した箇所

わたしは一向にかまわんッッ。いえ、困ります。
2021.09.02

FargateへCI/CDをCodePipelineで設定しました。デプロイフェーズはAmazon ECS(ブルー/グリーン)プレースホルダ(taskdef.json, appspec.ymlを用意する方)を利用した設定としました。いざパイプラインを走らせてみるとCodeDeployのInstallイベントから一向に進まなくデプロイを詰みました。

現在のステータス以上のメッセージや、ログを確認できればよかったのですが、進行中以外の情報がとくに見当たりません。どこから手がかりが得られたのか、原因切り分けと対応内容の一例として紹介します。

プレースホルダ以外の方法あったっけ?というときは以下のリンクをご確認ください。

原因

  • ソースリポジトリ(CodeCommit)内のtaskdef.jsonの内容に誤りがあった。
  • taskdef.jsonfamili:で指定するタスク定義名が違うものを指定していた。

この状況でデプロイが走るとエラーともならず、メッセージもなくInstallが進行中のまま終わらない。

CodeDeployの状況確認

Installイベントが進行中になりました。

B/Gデプロイメントのステップ1が進行中です。

35分経ってもInstallイベントが終わりません。デプロイは手動で停止しました。

エラーや、メッセージもなく思いつくところから切り分けをはじめました。

原因を特定できた箇所

CodeDeploy - デプロイメント - リビジョンの場所から該当のリビジョンをクリックします。

ソースリポジトリに保存したあったappspec.ymlの内容が置き換わった値になっていることを確認できました。

元のソースリポジトリにあるappspec.ymlの内容です。"<TASK_DEFINITION>"の部分が置き換わっていることがわかります。

appspec.yml

version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "<TASK_DEFINITION>"
        LoadBalancerInfo:
          ContainerName: "webapp"
          ContainerPort: 80
        PlatformVersion: "1.4.0"

ここで気がついたのはTaskDefinition:で指定されたタスク定義の名前が意図したものではありましたでした。B/Gデプロイメントの検証用に過去のappspec.ymltaskdef.jsonを使いまわしていました。新しいクラスター、タスク定義仕様に修正を忘れていたのが原因でした。

"<TASK_DEFINITION>"の部分はtaskdef.jsonの内容が利用されています。appspec.ymlの置き換わった内容を見て、taskdef.jsonの記述ミスに気づけたかたちです。

taskdef.jsonを確認します。family:で指定したタスク定義名の指定が誤っていました。このtaskdef.jsonに限れば全体的にsample2の部分が正しくはsample3でしたのですべて修正しました。

taskdef.json

{
	"containerDefinitions": [
		{
			"name": "log_router",
			"portMappings": [],
			"image": "<IMAGE2_NAME>",
			"firelensConfiguration": {
				"type": "fluentbit",
				"options": {
					"config-file-type": "file",
					"config-file-value": "/fluent-bit/etc/extra.conf"
				}
			},
			"logConfiguration": {
				"logDriver": "awslogs",
				"secretOptions": [],
				"options": {
					"awslogs-group": "sample3-dev-cluster-firelens-logs",
					"awslogs-region": "ap-northeast-1",
					"awslogs-stream-prefix": "FireLens"
				}
			},
			"essential": true
		},
		{
			"name": "webapp",
			"portMappings": [
				{
					"hostPort": 80,
					"protocol": "tcp",
					"containerPort": 80
				}
			],
			"image": "<IMAGE1_NAME>",
			"logConfiguration": {
				"logDriver": "awsfirelens",
				"secretOptions": [],
				"options": {}
			}
		}
	],
	"requiresCompatibilities": [
		"FARGATE"
	],
	"networkMode": "awsvpc",
	"cpu": "256",
	"memory": "512",
	"compatibilities": [
		"EC2",
		"FARGATE"
	],
	"family": "sample3-dev-webapp-taskdefinition",
	"taskRoleArn": "arn:aws:iam::123456789012:role/sample3-dev-webapp-ECSTaskRole",
	"executionRoleArn": "arn:aws:iam::123456789012:role/sample3-dev-webapp-ECSTaskExecutionRole"
}

修正後

再度パイプラインを実行しました。問題のInstallイベントは2.5分で終了し、後続の処理も成功しました。

無事B/Gデプロイメントができました。

おわりに

taskdef.jsonは以前のものを使い回すより、新しくデプロイしたクラスターのタスク定義をベースに編集し直した方がミスを減らせるかもしれません。厄介なのはエラーメッセージがなく原因調査に困るところです。他にもInstallが終わらないパターンは存在しているかと思いますが、一例として参考になれば幸いです。

たとえば以下のリンクのケースも同じ問題のようです。どこで些細なミスするかわからないですね。情報を残していただけるのはありがたいです。