はじめに
SSM Command Document の実行完了を待つために,前の記事ではカスタムリソースを作っていました。
CfnWaitConditionを使えば,以下の手順で同じことができます:
- CfnWaitConditionHandle を作る
- CfnWaitConditionを作る
- SSMのCommand Document で cfn-signal する
この記事は上記のやりかたのポイントをメモしたものです。
CfnWaitConditionHandle
このリソースは,CfnWaitCondition が待機し,cfn-signal で待機完了を通知するものです。
作り方は簡単で,Stack で new するだけです。
CfnAssociation で待機完了を通知できるように, CfnAssociation の前に作成しておきます。
const document = new CfnDocument(this, "Document", {
...
});
const handle = new CfnWaitConditionHandle(this, "Handle", {
});
const association = new CfnAssociation(this, "Association", {
name: document.ref,
...
});
CfnWaitCondition
このリソースは,CloudFormationスタックを待たせるためのものです。
new すると CREATE_IN_PROGRESS 状態になり,待機中のCfnWaitConditionHandle が cfn-signal で待機完了になると CREATE_COMPLETE 状態になります。
タイムアウトを指定することもできますが,この時はCfnWaitCondition の作成タイミングが速くなりすぎないように注意が必要です。
私の用途の場合だと,CfnAssociation が作成された(= SSM AgentがCommand Document を実行しはじめる)後に作成しないと,CfnAssociation が作成される前に CfnWaitCondition のカウントが始まり,失敗の原因になります。
それで,以下のようなコードになります:
const document = new CfnDocument(this, "Document", {
...
});
const handle = new CfnWaitConditionHandle(this, "Handle", {
});
const association = new CfnAssociation(this, "Association", {
name: document.ref,
...
});
const waitCondition = new CfnWaitCondition(this, "WaitCondition", {
handle: workerWaitHandle.ref,
timeout: "900", // 秒単位で指定
...
});
waitCondition.addDependency(association); // タイムアウトのカウントを開始するリソースを指定
cfn-signal
SSM Command Document の最後に cfn-signal を呼び出すことで,CfnWaitCondition を CREATE_COMPLETE 状態にします。
cloudinitで使う場合とは異なり,CfnWaitConditionHandle の ref と成功・失敗だけを渡せば最低限動きます。
- CfnDocument で cfn-signal を呼び出すようにする
- CfnAssociation で CfnWaitConditionHandle の ref を渡す
const document = new CfnDocument(this, "Document", {
documentType: "Command",
updateMethod: "NewVersion",
content: {
"schemaVersion": "2.2",
"description": "Sample Template",
"parameters": {
"cfnWaitHandle": {
"type": "String"
}
},
"mainSteps": [
{
"action": "aws:runPowerShellScript",
"name": "signalCfnWaitHandle",
"inputs": {
"runCommand": [
// 以下が実行されると,CfnWaitCondition が CREATE_COMPLETE になりスタック作成が継続する
// -e 1など0以外を渡せば CfnWaitCondition は CREATE_FAILED になる
"cfn-signal -e 0 \"{{ cfnWaitHandle }}\""
]
}
}
]
}
});
const handle = new CfnWaitConditionHandle(this, "Handle", {
});
const association = new CfnAssociation(this, "Association", {
name: document.ref,
parameters: {
cfnWaitHandle: [handle.ref] // CfnWaitConditionHandle を渡す
},
});
const waitCondition = new CfnWaitCondition(this, "WaitCondition", {
handle: workerWaitHandle.ref,
timeout: "900", // 秒単位で指定
...
});
waitCondition.addDependency(association); // タイムアウトのカウントを開始するリソースを指定
おわりに
これで,Command Documentが実行された状態でスタック作成が終わるようにできます。
シンプルになってよかった...