EC2 Systems ManagerのInventoryを検索して対象のインスタンスにRunCommandを実行したい!

記事タイトルとURLをコピーする

それ、Rezeptならできる(ようにした)よ!

こんにちは。照井@トーキョー出張中(公開される頃には帰っている)です。

先日(3/1)は半期に一度のキックオフでサーバーワークスメンバーが(ほぼ)全員集合したのですが、普段離れて働いているとなかなか話せない人が多いので、こういう機会は貴重ですね。とても良かったです。

RunCommandの対象インスタンスの指定方法

Systems ManagerのRunCommand機能では、標準でマネジメントコンソールおよびCLI/SDKから、インスタンスIDまたはインスタンスのタグを指定して実行対象を決めることができます。

ですが、インスタンスのタグは個数に制限があり、コスト配分に使用したりと色々な用途で使われていたりすると、なかなか調整が難しかったりします。

Inventory機能

翻ってSystems ManagerではInventoryという機能もあり、これは各インスタンスのOS・ミドルウェアなどの内部情報を収集して管理するために使用します。ここから対象のインスタンスを決めることができれば素敵そうです。例えば、OpenSSLの脆弱性パッチが提供された時にOpenSSLが入っているインスタンスを検索してアップデートできたら素敵ですよね?

それ以外にも、カスタムインベントリを登録することが出来るので、タグとは独立したインスタンスの属性などを管理するメタデータストアとしても使えそうです。良さ気ですね!


ですが・・・


このInventory機能はインスタンスIDをキーとしてそのInventoryを取得することはできますが、その逆はできません。Inventoryから対象のインスタンスを検索するためのAPIが用意されていないのです(内部的にはDynamoDBにHashキーがインスタンスIDで、RangeキーがInventory名という感じで保管されているのかなと妄想)

※参考

方法は無いわけではない!

勘の良い方はここまでで気づかれているかもしれませんが、APIを駆使して全インスタンスについて各Inventory内容を検証すれば対象のインスタンスを割り出すことは可能です。ということで、先日リリースしたRezeptにInventoryから対象インスタンスを絞り込んでRunCommandを実行する機能を追加しました(RunCommand対応自体は先日こっそりリリースしていました)

使い方

ツールの基本的な使い方や説明についてはこちらを確認してください。
対応バージョンは 0.2.0 0.3.1 以降(2017.03.08: バグがあったため修正)です。以前のバージョンを使用している場合はアップグレードをお願いします。

コマンドはこんな感じです。

$ rezept run_command -d My-RunShellScript -I Custom:Example -C "Version=2.0" --wait

オプション説明

  • -d or --document が実行するSSM Documentの名前
  • -I or --inventory が検索対象のインベントリ名
  • -C or --conditions がインベントリの検索条件

実行するとこんな感じで出力されます。

その他便利機能

また、その他の便利機能として、 --dry-run を付けると実行対象のインスタンスのリストアップのみ、 --wait --wait-results (2017.03.08: オプション名を変更) を付けると実行対象のインスタンス全ての実行結果を取得できるまで待ち、それぞれの結果を出力した上で、全て成功すればexitコード0、一つでも失敗していれば1を返して終了します。(通常は受け付けた後のコマンド実行は非同期で行われ、結果は分からない)

また、通常通りタグやインスタンスIDを指定する形での実行もサポートしていますので、詳しくはREADMEをご確認ください。

最後に

AWSの標準機能を使いこなすことはもちろん重要ですが、それだけでは実現できないことを実現することこそ、我々AWSエンジニアに求められていることかと思います。今後も精進していきたいですね。

興味があれば、使ってみてフィードバックなどお待ちしております。
https://github.com/serverworks/rezept