🌳

[AWS/CodeDeploy]デプロイエラー対策覚書き(主にAppSpec)

2022/04/25に公開

概要

CodeDeployでデプロイ時に出たエラーとその対策の覚書き。
主にAppSpecの書き方でハマったお話

前提条件

ソースファイル群をS3にzipファイルとして配置、それを使用し、CodeDeployでEC2へデプロイする

ディレクトリ構成は以下の通りとし、

  • 全てのディレクトリ/ファイルの所有者、グループをfuga
  • www/tmpの権限を644
  • www/tmp/requestの権限を777
  • www/tmp/responseの権限を644
    に設定したいものとする
ディレクトリ構成
hoge
  |-- hoge1.php
  |-- hoge2.php
  |-- hoge3.php
  |-- www
       |-- hoge.php
       |-- tmp
            | -- request
	    | -- response

※現場での内容をサンプル的な名称に変更しています。

補足事項

エラーを、発生した順に解決していく形式となっています
最終版のみ必要な場合は、「完成形」セクションをご参照ください

ケースと対策

ケース1

CodeDeploy上ではエラーは出ないが、意図した権限になっていないケース
この時のAppSpecの内容は以下の通り

appspec.yml
version: 0.0
os: linux
files:
  - source: /
    destination: /hoge
permissions:
  - object: /hoge
    pattern: "**"
    owner: fuga
    group: fuga
permissions:
  - object: /hoge/www/tmp
   pattern: "**"
    owner: fuga
    group: fuga
    mode: 644
    type:
      - directory
permissions:
  - object: /hoge/www/tmp/request
    owner: fuga
    group: fuga
    mode: 777
    type:
      - directory
permissions:
  - object: /hoge/www/tmp/response
    owner: fuga
    group: fuga
    mode: 644
    type:
      - directory

原因と対策

permissionsをobject毎に宣言している のが原因
2番目以降の「permissions:」を行ごと削除する

ケース2

デプロイするとコンソール上で以下のエラーが出るケース

エラー内容
The overall deployment failed because too many individual instances failed deployment, too few healthy instances are available for deployment, or some instances in your deployment group are experiencing problems.

この時のAppSpecの内容は以下の通り

appspec.yml
version: 0.0
os: linux
files:
  - source: /
    destination: /hoge
permissions:
  - object: /hoge
    pattern: "**"
    owner: fuga
    group: fuga
  - object: /hoge/www/tmp
   pattern: "**"
    owner: fuga
    group: fuga
    mode: 644
    type:
      - directory
  - object: /hoge/www/tmp/request
    owner: fuga
    group: fuga
    mode: 777
    type:
      - directory
  - object: /hoge/www/tmp/response
    owner: fuga
    group: fuga
    mode: 644
    type:
      - directory

原因と対策

ひとつのオブジェクトに対し、複数回権限を設定しようとしているのが原因
(hoge配下の全てのオブジェクトに一度権限設定した後、配下のwww/tmp, www/tmp/request,www/tmp/responseに権限設定しようとしている)

特定のオブジェクトだけ権限を変えたい場合は、exceptを使って重複しないようにする

ケース3

デプロイするとコンソール上および /var/log/aws/codedeploy-agent/codedeploy-agent.logで以下のエラーが出るケース
※後者はエラーの発生したEC2インスタンス内で確認できます

エラー内容(コンソール)
The overall deployment failed because too many individual instances failed deployment, too few healthy instances are available for deployment, or some instances in your deployment group are experiencing problems.
エラー内容(codedeploy-agent.log)
The deployment failed because the permissions setting for (/hoge/www/tmp/request) is specified more than once in the application specification file.

この時のAppSpecの内容は以下の通り

appspec.yml
version: 0.0
os: linux
files:
  - source: /
    destination: /hoge
permissions:
  - object: /hoge
    pattern: "**"
    except: [hoge/www/tmp]
    owner: fuga
    group: fuga
  - object: /hoge/www/tmp
   pattern: "**"
   except: [hoge/www/tmp/request,hoge/www/tmp/response]
    owner: fuga
    group: fuga
    mode: 644
    type:
      - directory
  - object: /hoge/www/tmp/request
    owner: fuga
    group: fuga
    mode: 777
    type:
      - directory
  - object: /hoge/www/tmp/response
    owner: fuga
    group: fuga
    mode: 644
    type:
      - directory

原因と対策

なんと!CodeDeploy自体のバグが原因・・
exceptのネストはNGなんだとか。。
(ここでは、hoge/www/tmpをexceptした後、さらにその配下のhoge/www/tmp/request,hoge/www/tmp/responseをexceptしようとしている)

詳細は以下の通り
https://github.com/aws/aws-codedeploy-agent/issues/151

やむなく、アプリケーション開始時にスクリプトで対応することに

完成形

AppSpecの完成形がこちら
かなりシンプルな見た目になりました

appspec.yml
version: 0.0
os: linux
files:
  - source: /
    destination: /hoge
permissions:
  - object: /hoge
    pattern: "**"
    owner: fuga
    group: fuga
hooks:
  ApplicationStart:
    - location: scripts/changePermission.sh

scripts/changePermission.shの中身は以下の通り
※hogeディレクトリ直下にて、scriptsディレクトリを切り、changePermission.shを追加しています

scripts/changePermission.sh
#!bin/bash

# change permissions
chmod 644 /hoge/www/tmp
chmod 777 /hoge/www/tmp/request
chmod 644 /hoge/www/tmp/response

hoge/www/tmpのみexceptして、別途権限をAppSpecに記述、/hoge/www/tmp/requestのみシェルスクリプト内で権限変更、という手もありましたが、配下に余分なファイル(.gitkeep)があるとエラーになるっぽいので、この書き方になりました

初歩的なことかもですが、

  • 改行コード(Linux環境ならLF)
  • コマンドミス
    にも要注意!

その他

他、ソースファイルをGit管理していてそのままデプロイするとエラーになります。
.gitをディレクトリごと削除してからzip化 → デプロイしましょう。
(.gitignoreやREADME.mdなど稼働環境上で使用しないものもできる限り)

終わりに

エラーが連発して心が折れそうになりましたが解決できてほっと一安心。
にしても、最後のエラーがまさかのCodeDeploy側のバグだったとは・・

その他の要因によるエラーに関しては、以下の記事を参考にするとよさそう
https://techblog.forgevision.com/entry/2020/07/16/210647

参考

パーミッション系

Discussion