CloudFormationでEC2 System ManagerのRun Command用ドキュメントを作成する

EC2 System Managerでは、よく使うコマンドを「ドキュメント」として保存しておくことができます。 やったことはないですが、Automationによる自動化はこのドキュメントを使用する様子ですので、使い方を覚 […]

広告ここから
広告ここまで

目次

    EC2 System Managerでは、よく使うコマンドを「ドキュメント」として保存しておくことができます。

    やったことはないですが、Automationによる自動化はこのドキュメントを使用する様子ですので、使い方を覚えておくとお得そうです。

    JSONでコマンド作るのしんどい

    ただこのドキュメントが曲者で、AWS恒例のJSONでひたすら頑張るやつです。

    AWSのドキュメントにあるサンプル

    {
       "schemaVersion":"2.0",
       "description":"Run a script",
       "parameters":{
          "commands":{
             "type":"StringList",
             "description":"(Required) Specify a shell script or a command to run.",
             "minItems":1,
             "displayType":"textarea"
          }
       },
       "mainSteps":[
          {
             "action":"aws:runShellScript",
             "name":"runShellScript",
             "inputs":{
                "commands":"{{ commands }}"
             }
          },
          {
             "action":"aws:runPowerShellScript",
             "name":"runPowerShellScript",
             "inputs":{
                "commands":"{{ commands }}"
             }
          }
       ]
    }
    

    これを作ってさらにAWS CLIから投入したりするのはちょっとめんどうだなーと思っていたのですが、いい方法がありました。

    CloudFormationならYAMLでドキュメントが作れる

    CloudFormationにはAWS::SSM::Documentというリソースが用意されています。

    これを使うことで、ドキュメントをYAML形式で作成することができます。

    YAML形式でRun Command用のドキュメントを作ってみた

    早速ですが、作ってみたものです。
    https://gist.github.com/hideokamoto/86eab90fd09770a022b38e2c0e7b9362

    aws:runShellScriptを少し拡張して、入力したコマンド + pwdを実行します。

    CloudFormationでRun Command用のドキュメントを作る時のTips

    schemaVersionに注意

    CloudFormationのドキュメントには、schemaVersionは2.0を推奨とありますが、aws:runShellScriptは2017年3月6日時点でschemaVersion: 1.2のみ対応っぽいです。

    2.0のフォーマットでドキュメントを作成すると、実行時にインスタンス内のSSMエージェントが以下のエラーを出します。

    2017-03-06 21:15:54 ERROR [ValidateExecutionTimeout @ pluginutil.go.405] [instanceID=i-0a441b6f3a8dfa5dd] [MessageProcessor] [pluginID=aws:runShellScript] Unexpected 'TimeoutSeconds' value  received. Setting 'TimeoutSeconds' to default value 3600
    

    辛いことにRun Command側では「成功」と表示される(ただし出力はカラ)ので、要注意です。

    runCommandは配列で

    APIリファレンスを見た感じだとStringで渡せば良いように見えたのですが、ここは配列です。
    Stringで渡すと以下のエラーを吐いてRun CommandがFailします。

    ----------ERROR-------
    Invalid format in plugin properties map[workingDirectory:/var/www/ id:0.aws:runShellScript runCommand:pwd && ls -la timeoutSeconds:300];
    error json: cannot unmarshal string into Go value of type []string
    

    CloudFormationでドキュメントを作るメリット

    複数のサーバに対して実行したいコマンドや、定期的に実行したいコマンドについてはドキュメント化しておくと便利そうです。
    「この順番でコマンドを実行してね」というマニュアルベースの操作から、「Run Commandでこのドキュメントを実行して」or「Automationでこのドキュメント実行するようにしときました」で済むようになるはずなので、事故や実行漏れも減るでしょう。

    CloudFormationから生成するようにすれば、スタックの更新を利用することで簡単にドキュメントの更新もできますし、なによりYAML形式でドキュメントが定義できるのが非常に助かります。

    参考

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark