AWS CLI、活用していますか?AWS認定 DevOps Engineer Professional こと、みっちゃんです。(2ヶ月ぶり2回目)
以前、AWS CLIの概要についてのブログ記事を投稿しました。 今日はそこでお伝えしきれなかった便利機能、スケルトンについてご紹介したいと思います。暑いので勢いよくいきますよ。ちなみにこれ、書きながら途中で3箇所ぐらいドヤ顔してるので、読みながら「あ、こいつ多分ここ書きながらドヤ顔してるな」などと勝手な事を考えながら読み進めて頂ければ幸いです。
そうですね、まずはさっそくEC2インスタンスを一台立てるとしましょう。
ここで立てるEC2の要件はこんな感じに設定してみました。
- Amazon Linux 2015.03をプレーンなまま起動
- インスタンスタイプは m4.large
- rootボリューム(/dev/xvda) は30GB SSD(gp2)
- 詳細モニタリングは使わない
- Terminate Protection は On にしておく
- パブリックIPの自動アサインを有効にする
- Security Groupは "sg-xxxxxxxx" と "sg-yyyyyyyy" を割り当てる
- "worker-ec2" という IAM Role を割り当てる
まずはこれを満たすインスタンスをCLIで起動してみます。
aws ec2 run-instances --profile mydev --count 1 --image-id ami-cbf90ecb --instance-type m4.large --block-device-mappings '[{"DeviceName":"/dev/xvda","Ebs":{"VolumeSize":30,"DeleteOnTermination":true,"VolumeType": "gp2"}}]' --monitoring Enabled=false --disable-api-termination --associate-public-ip-address --iam-instance-profile Name=worker-ec2 --subnet-id subnet-xxxxxxxx --security-group-ids "sg-xxxxxxxx" "sg-yyyyyyyy" --key-name my-key-pair
まあ、ちまちま書くの結構めんどくさいですね。CLIのままだとパラメータをちょこっと変えて流用したい場合にも不便です。コピペしてテキストエディタで書き換えて、またシェルに流し込んで、といったオペレーションになるでしょうか。できればやりたくないです。
これ、設定ファイルみたいにして置いておけたら便利ですよね。ファイルなら共有もバージョン管理も簡単だし。そう、それができるんです、AWS CLIなら。
--cli-input-jsonオプション
コマンド行の中でオプションとパラメータのペアを逐一指定する代わりに、JSON形式で書かれたパラメータファイルを指定することができます。先のEC2の例だと、まずは以下のようなJSONを用意します。
{ "ImageId": "ami-cbf90ecb", "KeyName": "my-key-pair", "SecurityGroupIds": [ "sg-xxxxxxxx", "sg-yyyyyyyy" ], "InstanceType": "m4.large", "BlockDeviceMappings": [ { "DeviceName": "/dev/xvda", "Ebs": { "VolumeSize": 30, "DeleteOnTermination": true, "VolumeType": "gp2" }, "NoDevice": "" } ], "Monitoring": { "Enabled": false }, "SubnetId": "subnet-xxxxxxxx", "DisableApiTermination": true, "NetworkInterfaces": [ { "DeviceIndex": 0, "AssociatePublicIpAddress": true } ], "IamInstanceProfile": { "Name": "worker-ec2" } }
上記ファイルを適当なパスに保存しておきます。コマンド実行時に、--cli-input-jsonオプションのパラメータとしてこのファイルを指定することで、ファイルに記載した通りに、上記のCLIコマンドと同じ設定のインスタンスを起動することができます。
aws ec2 run-instances --profile mydev --cli-input-json file://ec2_run-instance.json
ちなみに、CLIのオプションとJSONファイルの両方で、同じオプションに対し違うパラメータ値を同時に入力した場合、CLIの方で指定したものが優先されます。ですので、JSONファイルをテンプレート代わりにして、個別の設定をCLIオプションで補足する、という使い方も当然ありです。パラメータは同じでインスタンスタイプだけ変えたい、といったこともできます。
aws ec2 run-instances --profile mydev --cli-input-json file://ec2_run-instance.json --instance-type t2.small
--generate-cli-skeltonオプション
さて、先の--cli-input-jsonオプションに与えるJSON形式のパラメータファイルですが、当然AWSのAPIが期待しているドキュメント構造になっていなければ何かしらのエラーが返されます。また、パラメータもサービス毎にたくさんあるので、いちいち調べるのも面倒ですし、それを元に手書きするのはさすがに骨が折れます。いまどき手書きで味が出るのは年賀状ぐらいなもんです。
というわけで、AWS CLIのオプションとかパラメータのことは遠慮なくAWS CLIに聞きましょう。コマンドを指定してオプションに--generate-cli-skeltonを渡すと、そのコマンドに与えることのできるパラメータの一覧が、整形されたJSON形式とダミー値付きで出力されます。適当なファイルにリダイレクトして書き換えましょう。
aws ec2 run-instances --generate-cli-skeleton > ec2run-instance.json
注意点があるとすれば、--generate-cli-skeltonオプションは、そのコマンドの実行に最低限必要なパラメータを列挙するものではなく、与えることができる全てのパラメータをずらっと書き並べてくれるもの、という点ですね。
排他的な関係にあるパラメータも全部出てきてしまいます。例えば、ec2 run-instanceのスケルトンを出力すると、--iam-instance-profileオプションに与えられるパラメータとして、以下のようにARNとNameの2つが出力されます。
"IamInstanceProfile": { "Arn": "", "Name": "" },
が、これ、通常はどちらか一方を指定するもので、同時に指定するとAPIは無慈悲にエラーを返します。そのあたりは--dry-runオプション(APIリクエストの成否判定だけを行い、実際のリソース操作を行わないオプション)などを駆使してのトライアンドエラーが必要になってくるところです。
というわけで、全てを明示的に指定する必要はないので、最低限指定したいパラメータを残し、明示的な指定が不要なパラメータを削除していく、という使い方が正しいのではないかと思います。必要なものを1つずつ調べてチマチマ書いていくのもいいですが、不要なものを削除していく方が格段に楽です。あとはJSON形式のフォーマットさえ崩さなければ何とかなります。
最後に
--generate-cli-skeltonオプションと--cli-input-jsonオプションを上手に使うことで、AWS CLIはより一層便利に使えるかと思います。前述の通りパラメータファイルを小さなテンプレートに見立てた使い方もできるので、不定期的に既存環境に同じようなコンポーネントを追加するなど、いろいろ小回りも効くようになります。どんどん活用していきたいですね。