以下、AWS公式ページにて、デプロイライフサイクルに対応したスクリプトと利用できる環境変数群が指定されている。
https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/reference-appspec-file-structure-hooks.html#appspec-hooks-server
ただ、公式ページのやり方だと、DEPLOYMENT_GROUP_NAME
というデプロイメントグループ名を表すための環境変数を使って、そのEC2インスタンスがproductionなのかstagingなのかを判別する方法のみ記載されており、デプロイメントグループを直書きする気持ち悪さと、無駄なif文が記述されてしまう。
「hooks」セクション用スクリプト(シェル)にてタグの値を環境変数として利用する方法を探してみたので、メモとして残しておく。
対応の概要
以下の3ステップを順番に対応する。
- aws-cliがEC2上で利用できるようにする。
- aws-cliの「フィルター」と「クエリー」の検索条件となり得る値を準備する。
- aws-cliの機能「フィルター」と「クエリー」を活用したロジックを「hooks」セクション用スクリプト(シェル)に記述
1. aws-cliがEC2上で利用できるようにする。
AWSコンソールからIAMの管理画面に移動して、グループを作成 → EC2操作をできるロールをグループにアタッチ(今回は、AmazonEC2FullAccess) → ユーザーを作成(アクセスキーをダウンロード) → 作成したグループにユーザーを追加
個人的には、Amazon Linux 2 AMI (HVM), SSD Volume Type
という無料のマシンイメージを活用しているので、EC2上にssh接続して、以下コマンドを実行してaws-cliにする。
sudo yum install -y aws-cli
aws-cliをインストールしたら、そのままEC2上で先ほど作成したユーザーのアクセスキー情報を設定する。
aws configure
※以下の文言が順次表示するので設定する
AWS Access Key ID [None]: <IAMでのCodeDeploy用ユーザー作成でメモしたアクセスキーID>
AWS Secret Access Key [None]: <IAMでのCodeDeploy用ユーザー作成でメモしたシークレットアクセスキーID>
Default region name [None]: ap-northeast-1
Default output format [None]: json
2. aws-cliの「フィルター」と「クエリー」の検索条件となり得る値を準備する。
結論としては、インスタンスメタデータから、稼働中のEC2のインスタンスIDをaws-cliの「フィルター」と「クエリー」の検索条件として活用するようにする。
試しに、EC2上でインスタンスIDを取得するために以下コマンドを実行
curl -s http://169.254.169.254/latest/meta-data/instance-id
※169.254.169.254はリンクローカルアドレスで、インスタンスからのみ有効
※現在接続しているEC2インスタンスIDが表示されればOK
参考:
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-instance-metadata.html
3. aws-cliの機能「フィルター」と「クエリー」を活用したロジックを「hooks」セクション用スクリプト(シェル)に記述
# instance メタデータから対象EC2インスタンスのインスタンスID情報をfetch
# NOTE: 詳細:https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-instance-metadata.html
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
# インスタンスIDを介してEC2インスタンスのタグ情報(NodeEnv)の値を取得
EXPORT_ENV=$(aws ec2 describe-tags \
--filters "Name=resource-type,Values=instance" "Name=resource-id,Values=$INSTANCE_ID" "Name=tag-key,Values=NodeEnv" \
--query 'Tags[]|[0].Value')
export NODE_ENV=$EXPORT_ENV
後述
aws-cliの「フィルター」と「クエリー」の検索条件となり得る値を準備するのに大変苦労した。
最初は、hostname -I
して取得したIPアドレスを使って、以下のように検索条件となり得る値を調べようと以下のような記述を試していた。
INSTANCE_ID=$(hostname -I)
# インスタンスIDを介してEC2インスタンスのタグ情報(NodeEnv)の値を取得
EXPORT_ENV=$(aws ec2 describe-instances \
--query 'Reservations[].Instances[?PrivateIpAddress==`$INSTANCE_ID`]|[0][0].Tags[]|[0].Value')
しかし、$INSTANCE_ID
という記述箇所がバッククォートに囲まれているためなのか、変数に設定したIPアドレスが意に沿う形で展開されず、この方法では実現できなかった。。。
他に最適なやり方があったら、ぜひ知りたいと思う。