AWS Systems Manager パラメータストア
で階層構造で登録したパラメータをEC2で利用する方法のメモです
前提
- EC2インスタンスのtagにName=MyApp, Env=Devが設定されている
- roleにパラメータストアの権限が付与されている
- roleにEC2のreadonly権限が付与されている
- aws cli設定済み
- jqがインストール済み
パラメータストアに登録
aws ssm put-parameter --name "/MyApp/Dev/S3_BUCKET_NAME" --value "MyAppBucket" --type String
aws ssm put-parameter --name "/MyApp/Dev/AWS_ACCESS_KEY_ID" --value "dummy_s3_access_key" --type String
aws ssm put-parameter --name "/MyApp/Dev/AWS_SECRET_ACCESS_KEY" --value "dummy_s3_secret_key" --type "SecureString"
確認
aws ssm get-parameters-by-path --path "/MyApp/Dev" --with-decryption
EC2上でパラメータストアの情報を利用
#!/bin/sh
# ssm parameter-store settings
INSTANCE_ID=$(curl 169.254.169.254/latest/meta-data/instance-id)
ZONE=$(curl 169.254.169.254/latest/meta-data/placement/availability-zone)
REGION=$(echo ${ZONE/%?/})
APP_NAME=$(aws --region ${REGION} ec2 describe-instances --instance-ids ${INSTANCE_ID} --query "Reservations[0].Instances[0].Tags[?Key=='Name'].Value" --output text)
APP_ENV=$(aws --region ${REGION} ec2 describe-instances --instance-ids ${INSTANCE_ID} --query "Reservations[0].Instances[0].Tags[?Key=='Env'].Value" --output text)
FILENAME="/var/www/${APP_NAME}/.env"
# put .env file
SSM_PARAMS=$(aws --region ${REGION} ssm get-parameters-by-path --path "/${APP_NAME}/${APP_ENV}" --with-decryption)
for params in $(echo $SSM_PARAMS | jq -r '.Parameters[] | .Name + "=" + .Value'); do
echo ${params##*/}
done > ${FILENAME}
echo "APP_ENV=${APP_ENV}" >> ${FILENAME}
- EC2のinstanceIdとregionを取得
- describe-instancesでタグ情報からNameとEnvを取得
- パラメータストアからget-parameters-by-pathで階層化されたパラメータをまとめて取得
- Key=Valueの形に整形して出力
です。
S3_BUCKET_NAME=MyAppBucket
AWS_ACCESS_KEY_ID=dummy_s3_access_key
AWS_SECRET_ACCESS_KEY=dummy_s3_secret_key
APP_ENV=Dev
このような内容で.envが作られます
最後に
LambdaやECSでの記事はあったのですが、EC2で汎用的に利用する例が見つからなかったので試してみました
このスクリプトをCodeDeployのBeforeInstallに登録して、デプロイすると.envファイルが最新の状態になるようにしています。
ユーザーデータに登録してEC2の初期化に利用したり、export命令に変えて環境変数を設定したりもできると思います
EC2のtagとパラメータストアの名称を合わせることで環境にあったパラメータを設定できるのは楽ですね