はじめに
AWS Systems Manager(SSM)の便利な機能にランコマンドがあります。
これはSystems Managerのマネージドインスタンス上でコマンドを実行できるサービスで、OS内に配置されたスクリプト等をAWS API経由で実行することにより運用作業を自動化・効率化できます。
このランコマンドにはタイムアウトの値を設定できますが、実は任意の値を設定出来ないケースがありますので、そのTipsをご紹介したいと思います。
実行タイムアウトについて
ランコマンドにはコマンドの実行タイムアウト(※)があり、指定した時間になってもコマンドの実行が完了しない場合には、コマンド実行が中断されます。
さて、AWSマネジメントコンソールでランコマンドを実行する場合は、コマンドの実行タイムアウトの値は、下記の画面で設定できます。
ただし、このタイムアウトの値はドキュメントにとってのデフォルトのタイムアウト値の位置づけとなっており、実際には適用されないケースがあります。
※ タイムアウトには実行タイムアウトの他に配信タイムアウトがあるのですが、本記事では実行タイムアウトのみを扱います。
コマンドの実行タイムアウト値を設定できるケース
例えば、Linux上で任意のコマンドを実行する AWS-RunShellScript
ドキュメントの定義をみてみましょう。
その中の一部で、下記のように "timeoutSeconds": "{{ executionTimeout }}"
と定義されています。
この {{ executionTimeout }}
部分でユーザーから入力されたタイムアウト値が代入され、設定されます。
"runtimeConfig": { "aws:runShellScript": { "properties": [ { "id": "0.aws:runShellScript", "runCommand": "{{ commands }}", "workingDirectory": "{{ workingDirectory }}", "timeoutSeconds": "{{ executionTimeout }}"
コマンドの実行タイムアウト値を設定できないケース
例えば、Windows UpdateをSSM経由で行う AWS-InstallWindowsUpdates
ドキュメントの定義をみてみましょう。
その中の一部で、下記のように "timeoutSeconds": "14400",
と定義されています。
14400秒すなわち4時間に固定で設定されており、この値が実際のコマンドの実行タイムアウト値として適用されます。
したがって、このSSMドキュメントを実行する場合は、実行時にタイムアウト値を設定したとしても、タイムアウト値は常に4時間ということになります。
"runtimeConfig": { "aws:runPowerShellScript": { "properties": [ { "id": "0.aws:runPowerShellScript", "timeoutSeconds": "14400",
試してみた
実際に試してみました。
環境
- Amazon Linux2
- SSMドキュメント
- AWS-RunShellScript
- スクリプト
- 1秒おきにファイルに書き込む。60秒実行する。
#!/bin/bash for i in `seq 0 60` do echo "i = $i" >> /home/ec2-user/echo.txt sleep 1 done
実行時に設定したタイムアウト値でタイムアウトすること
まずはコマンド実行時にタイムアウト値を「30秒」に設定して、上記コマンドをランコマンドで実行してみます。
そうすると、30秒経過した時点で、以下のようにエラーとなりました(画面が途中で切れていますが、 i = 29
で中断されています)。
ドキュメントを変更し、実行時に設定したタイムアウト値でタイムアウトしないこと
SSMドキュメントは自分で定義することもできるので、「AWS-RunShellScript」ドキュメントのタイムアウトの値だけ調整した独自のドキュメントを定義して実行してみます。
今度はドキュメントの中で固定した値を設定しておき、コマンド実行時に指定した値ではタイムアウトしないことを確認してみます。
独自ドキュメントの作成
あらかじめ、「AWS-RunShellScript」ドキュメントの定義JSONをコピーしておきます。
SSMの画面の「ドキュメント」から「Create Command or session」を選択します。
「ドキュメントの作成」画面で以下のように入力し、「コンテンツ」の部分に先程コピーした「AWS-RunShellScript」ドキュメントの定義をペーストします。
そして、”timeoutSeconds” の部分を120秒に設定してみましょう。
こうすることで、コマンド実行時のタイムアウト値の設定によらず、常に120秒がタイムアウト値となります。
本ドキュメントを用いて再度、コマンド実行時にタイムアウト値を30秒に設定して、実行してみます。
今度はコマンドが最後まで実行され、中断されないことが分かります。
おわりに
今回ランコマンドのタイムアウトについてTipsをご紹介しました。
知っていないと案外落とし穴になる部分なので、気をつけて設計したいところです。