SSM Automationの実行方法
公式サイト:
AWS Systems Manager Automation
以下の点が公式ドキュメントやその他Blog情報からはわかりずらかったり、やってみて初めて気づいた点があるため、備忘録的に記録しておく。
- Documentの入力値、出力値
- Documentの入力パラメータでのStringMapやMapListの値の記述方法
- Documentから各Stepへ入力値を渡す方法
- Stepの出力値を次以降のStepの入力値やDocumentの出力値にする方法
- aws:branchでの分岐の記述方法
- Documentの共有とaws:executeScriptのStepを含むDocumentでのデフォルトの想定ロール
- Automationでのboto3の注意事項
Documentの入力値、出力値
- Documentの入力パラメータでのStringMapやMapListの値の記述方法
Documentの入力パラメータでタイプを指定できるが、特にStringMapやMapListの場合、かつ必須をNoにした際のデフォルト値をどのように記述して指定すればよいか。
結論から言うと、ここはJsonの書式で記載する必要がある。
StringMap | MapList |
---|---|
辞書型 | 1組のキーバリュー辞書の配列 |
{ "key1":"value1", "key2":"value2", ... }
[ { "key11":"value11", "key12":"value12", ... }, { "key21":"value21", ... } ... ]
- Documentから各Stepへ入力値を渡す方法
Stepでaws:executeScriptを実行させたい場合、Documentとして入力した値を当該Stepの入力値としたい場合がある。
その場合、当該Stepで追加の入力という項目があるが、ここで
入力名 | 入力値 |
---|---|
InputPayload | 以下参照 |
parameter1name: '{{ documentinputparametername }}'
parameter2name: '{{ step1.stepoutputparametername }}'
:
とシングルクォーテーションと波括弧2つで囲って指定する。
このparameter1nameという変数名はスクリプト内で
def script_handler(events, context):
parameter1 = events['parameter1name']
:
のように、events引数の連想配列のキー名となる。
なお、Documentの入力値として指定した変数名と異なる変数名でスクリプトへ渡しても良い。(混乱を避ける意味では統一しておいたほうが無難)
- Stepの出力値を次以降のStepの入力値やDocumentの出力値にする方法
スクリプトの出力値をStepの出力値として抽出し、次以降のStepの入力値やDocumentの出力値としたい場合、スクリプト側で連想配列をreturnする。
result = {
'key1' : 'value1',
'key2' : 'value2'
}
return result
また、Stepの出力で以下のように(抽出したい要素の数だけ)出力値の変数名とパラメータを指定する。
名前 | セレクター | タイプ |
---|---|---|
Stepの出力値として定義する変数名 |
$.Payload. の後に、returnした連想配列のキー名を指定 |
returnした連想配列のキー名に対応する値の型 |
- セレクター:例えば、キー名がkey1なら
$.Payload.key1
となる- タイプ:他のStepの入力値やDocumentの出力値に利用する場合、StringかStringListを指定するのが無難
Stepでaws:executeAutomationにより他のドキュメントを関数のように呼び出すことが可能であるが、Documentの出力でStepの出力値等を指定しておくとDocument間で実行結果等の値をやり取り可能になる。
(ロールを想定のにある)出力に、特定のStepの出力値を指定したい場合は以下のように記述する。
[ "step1.step1outputparametername","step2.step2outputparametername",... ]
aws:branchでの分岐の記述方法
下記のように、入力のChoiceの部分にMapList形式で分岐先と評価する変数、評価式を指定する。
評価は上から行われ、評価式(下記ではStringEquals)がtrueになったMapのNextStepで記載したStepにジャンプする。
例えば、以下のMapListの場合
[
{
"NextStep": "Step3"
"Variable": "''{{documentinputparametername}}''"
"StringEquals": "OutputValue1"
},
{
"NextStep": "Step4"
"Variable": "''{{step1.stepoutputparametername}}''"
"StringEquals": "OutputValue2"
},
:
]
- Documentを実行する際に入力した入力値documentinputparameternameの値が評価式の値OutputValue1と等しい場合、Step3へ
- そうではない場合、Step1の出力値であるstep1.stepoutputparameternameがOutputValue2と等しい場合、Step4へ
- いずれでもない場合、本Stepの次のStepへ実行が遷移する(Default動作を定義していた場合はDefault動作に従う)
という動作となる。
このため、aws:executeScriptのStepの実行結果を元に分岐処理を行いたい場合(Documentの入力値や前Stepのaws:executeScriptの実行結果で分岐処理を行いたい場合等)、aws:executeScriptのStepの定義で追加の入力と出力をきちんと行っておく必要がある。
Documentの共有とaws:executeScriptのStepを含むDocumentでのデフォルトの想定ロール
AWS Organizationsによって複数のアカウントを管理している場合、特定のアカウントで作成したDocumentを他のアカウントへ共有したい場合、Documentの詳細でアクセス許可に共有させたいAWSアカウントIDを指定すれば良いが、以下の落とし穴がある。
- 共有する場合はDocumentのデフォルトの想定ロールを空白にしないとならない。
想定ロールはARNで指定するため、共有先のアカウントで当該Documentを実行しようとした場合、Documentに想定ロールが指定されていると共有元のアカウントのIAMロールで実行しようとしてしまって権限エラーで実行できないことになる。 - 一方、aws:executeScriptのStepを含むDocumentの場合、想定ロールが指定されていない場合はiam:PassRoleの権限エラーとなって実行できない。
- オートメーションドキュメントの実行でシンプルな実行ではなく複数のアカウントとリージョンで実行しようとしても、上記は回避できない。
一見オートメーション実行ロール名を指定し、実行させたいアカウント上に同名のIAMロールを用意すれば可能に見えるが、実際はaws:executeScriptのStepが1つでも入っており、かつ想定ロールが指定されていない場合、実行させたいアカウント上でStepの処理が実行されるタイミングでiam:PassRole権限エラーで異常終了する。
推測であるが、aws:executeScriptのStepを実行しようとした段階で内部的に想定ロールへiam:PassRoleしようとしているようで、そこでエラーとなっている模様
よって、aws:executeScriptのStepを含むDocumentは共有できず、実行させたいアカウント上に想定ロールだけ異なるDocumentをコピーで作成する必要がある。
Automationでのboto3の注意事項
boto3のリファレンス
以下のスクリプトはboto3の各サービス(例はec2であるが、各AWSサービス名に置換すること)毎のオブジェクトを作成し、そのメソッド一覧を表示するものである。
これをaws:executeScriptのStep上で実行してみるとわかるが、実は一部のAWSサービスについてはboto3の一部のメソッドが実装されていないことが分かる。
(SSM Automationの実行環境上の問題であり、EC2等の通常のOS上に作成されたboto3の環境ではきちんと実装されている)
import boto3
import inspect
def script_handler(events, context):
client = boto3.client('ec2')
for x in inspect.getmembers(client, inspect.ismethod):
print x[0]
return
2023/3時点で確認している限りでは以下がある。
AWSサービス名 | 未実装のメソッド |
---|---|
SSOAdmin | attach_customer_managed_policy_reference_to_permission_set |
attach_managed_policy_to_permission_set | |
delete_inline_policy_from_permission_set | |
delete_permissions_boundary_from_permission_set | |
detach_customer_managed_policy_reference_from_permission_set | |
detach_managed_policy_from_permission_set | |
put_permissions_boundary_to_permission_set |
オブジェクトにメソッドが未実装の場合、AttributeErrorが発生するので、AttributeErrorで異常終了した場合は諦めるか、aws:branchとaws:executeAwsApiのStepを作成したりして回避するという緊急手段を取る必要がある。
履歴
- 2023/3/24 初稿
- 2023/3/24 Documentの出力について漏れていたので追記
- 2023/3/29 boto3のsso-adminに未実装のメソッドを追加で見つけたため追記