やりたいこと
- EC2インスタンスが数多く存在しているが、指定したタグ(Env=dev)を持つインスタンスのみフィルタしてAMIを作成したい。
- ワンライナーでやることは、AWS CLIのコマンドを生成するところまで。実際の作成は出力結果をコピー&ペーストして実行する。
- AMI名は、インスタンス名(Nameタグの値)と、日付8桁の文字列としたい。(例:api_20181011)
- 出力結果は、インスタンス名(Nameタグ)でソートしたい。
作成したワンライナー
$ aws ec2 describe-instances --filters "Name=tag:Env,Values=dev" \
| jq -r '.Reservations[].Instances[] | [.InstanceId, (.Tags[] | select (.Key == "Name").Value)] | @csv' \
| sed 's/\"//g' | sort -t , -k 2 \
| awk -F, '{image_name=$2 "_" strftime ("%Y%m%d"); print "aws ec2 create-image --no-reboot --instance-id", $1, "--name", image_name};'
実行するとこんな感じで結果が出力されます。
aws ec2 create-image --no-reboot --instance-id i-xxxxxxxxxxxxxxxxx --name api11_20181011
aws ec2 create-image --no-reboot --instance-id i-xxxxxxxxxxxxxxxxx --name api12_20181011
aws ec2 create-image --no-reboot --instance-id i-xxxxxxxxxxxxxxxxx --name web11_20181011
aws ec2 create-image --no-reboot --instance-id i-xxxxxxxxxxxxxxxxx --name web12_20181011
補足
ec2-describe-instancesの出力結果をフィルタする
まず、AWS API発行時点で、対象のインスタンスのみを抽出するよう、フィルタ条件を指定します。
$ aws ec2 describe-instances --filters "Name=tag:Env,Values=dev"
jqの結果をCSVとして出力する
下記を実行すると、インスタンスIDとNameタグの値をCSVとして出力します。
$ aws ec2 describe-instances --filters "Name=tag:Env,Values=dev" \
| jq -r '.Reservations[].Instances[] | [.InstanceId, (.Tags[] | select (.Key == "Name").Value)] | @csv'
sortコマンドで指定の列を元に並べる・区切り文字として空白以外の文字を使う
sortコマンドは「-k」オプション(若しくは「--key=KEYDEF」オプション)を指定することで、ソート対象の列を指定することが出来ます。
また列の区切り文字は、デフォルトでは空白文字(white space/tab)ですが、
「-t」オプション(若しくは「--field-separator=SEP」オプション)で、任意の文字を指定することが可能です。
$ aws ec2 describe-instances --filters "Name=tag:Env,Values=dev" \
| jq -r '.Reservations[].Instances[] | [.InstanceId, (.Tags[] | select (.Key == "Name").Value)] | @csv' \
| sed 's/\"//g' | sort -t , -k 2 \
awkの中で時刻を取得する
シェルのコマンド置換を利用して、dateコマンドの出力結果を用いることもできますが、今回はawkスクリプトが少し長くなったので、strftimeを使いました。
フォーマット文字列は、dateコマンド等と恐らく一緒です、多分。(※未確認)
$ awk 'BEGIN {print strftime ("%Y%m%d")}'