はじめに
こんにちは。hiranoです。
AWSを利用したタスクの定期実行はとても便利なものですよね。
夜間のスケールダウンや定期メンテなど、EventBridge Scheduler や SSM Automation を使えば運用はかなり楽になります。
一方で、定期実行のタスクが失敗した時にこんな状況になった経験はありませんか。
・失敗通知のメールは来たけど、その後何から手を付けていいかわからない
・対象のインスタンスや失敗したステップの特定に時間がかかる
・対応の証跡がSlackや色々なドキュメントに散らばっていて、あとを追いづらい
このように対応フローが整っていないと、復旧が遅れるだけでなく、再発時にも同じ調査を繰り返すことになります。
そこで本記事では SSM OpsCenter を使い、失敗イベントをきっかけに OpsItemを自動起票して、対応フローを標準化する方法をご紹介します。
OpsCenterとは
インシデント対応の受付から対応完了までを一元化するツールです。
うまく活用することで対応の標準化のみでなく、状況の見える化やナレッジ化等も可能な為、より効率的にインシデント対応が可能になります。
詳細は公式のドキュメントをご参照ください。
AWS Systems Manager OpsCenter - AWS Systems Manager
本記事の流れ
今回はEventBridge Scheduler と SSM Automation を組み合わせた定期実行タスクを例に、
OpsCenterを利用したインシデント管理方法の理解を深めます。
例として以下の内容で動作するインスタンスタイプ変更タスクを使用します。
・スケジュール:毎日 22:00 に縮退、翌日 10:30 に復帰
・対象:タグ TestShrink=true が付いたEC2を1台だけ対象
・失敗条件:0台、2台以上、停止できない、タイプ変更できない、起動後ヘルス確認NG
※タスク実行用のEC2、タグ、IAMロール、ランブック、EventBridge Schedulerは事前に作成済みとします。
この構成は『SSM Automation×EventBridge Schedulerで実現する“夜間縮退・朝復帰”運用』を参考に作成しています。気になる方はご覧ください。
上記の定期実行タスクを題材に、失敗時の対応をOpsCenterのOpsItemに集約することを目的とし、OpsItemの自動起票から対応・記録、クローズまでの一連の流れを実践します。
具体的には、次の手順で進めます。
1.権限の設定
2.EventBridgeルールの作成とOpsItem自動起票
3.OpsItemの設定変更
4.OpsItemを利用したインシデント対応
それではいきましょう。
実践
1.権限の設定
EventBridgeとOpsCenterは統合されていますが、何もせずにOpsItemが自動起票されるわけではないです。
EventBridgeがOpsItemを自動起票するには、内部的に Systems Manager の API(CreateOpsItem)を呼び出す必要がある為、
下記2点のIAMロールとIAMポリシーを作成します。
・IAMロール:EventBridge用の実行ロール(信頼ポリシー)
・IAMポリシー:OpsItem作成権限のポリシー
まずは、EventBridge用の実行ロールから作成します。
①IAM → 「ロール」 → 「ロールの作成」
②信頼されたエンティティタイプ:カスタム信頼ポリシー
③JSON形式で下記のコードを入力
④ロール名「eventbridge-opsitem-role」(任意のロール名を入力)で作成
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
続いて、OpsItem作成権限のポリシーを作成します。
①IAM → 「ポリシー」 → 「ポリシーの作成」
②JSON形式で下記のコードを入力
③ポリシー名「eventbridge-to-opscenter-opsitem-policy 」(任意のポリシー名を入力)で作成
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "OpsCenterCreateOpsItem",
"Effect": "Allow",
"Action": [
"ssm:CreateOpsItem"
],
"Resource": "*"
}
]
}
ポリシーが作成できたら先ほど作成したロールにアタッチして権限の設定は完了です。

2.EventBridgeルールの作成とOpsItem自動起票
続いて、Automationの失敗イベントをEventBridgeが受信した際にOpsItemが自動起票するようにルールを作成していきます。
①Amazon EventBridge → 「ルール」 → 「ルールの作成」
②イベントパス:デフォルト
③構築タブを選択し、トリガーイベントに「EC2 Automation Execution Status-change Notification」を設定
④トリガーイベントのイベントパターンに下記のコードを入力
{
"source": ["aws.ssm"],
"detail-type": ["EC2 Automation Execution Status-change Notification"],
"detail": {
"Definition": ["<対象のドキュメント(ランブック)名>"],
"Status": ["Failed"]
}
}
⑤ターゲットに「Systems Manager (OpsCenter) 」を設定
⑥ターゲット設定の実行ロールに「eventbridge-opsitem-role」を設定
⑦設定タブを選択し、ルール名「automation-failed-to-opscenter」(任意のルール名を入力)、アクティベーションを「アクティブ」に設定し、作成
構築図はこのようになります。
ここまで出来たら、動作を確認してみましょう。
対象となるEC2のTestShrinkタグを「false」にして、Automation(TestShrink-ChangeInstanceType-0312)を失敗させます。

OpsCenterを確認します。
先程設定したトリガーイベント名がタイトルとなるOpsItemが起票されていることが確認できました。
関連リソースに紐づく値は実行IDとドキュメント名で一致しているので間違いないですね。
3.OpsItemの設定変更
失敗イベントに伴ってOpsItemが起票されたはいいものの、タイトルはトリガーイベント名なので重複しそうですし、説明欄が「This is from CloudWatch Events」だけなので、これではインシデント対応の標準化はできません。
ということで、OpsItem内の情報をより充実させるために、設定変更を行います。
①Amazon EventBridge → 「ルール」 → 「automation-failed-to-opscenter」 を選択 → 「編集」
②ターゲット内の「入力変換」を選択し、ターゲット入力変換を「有効化」に設定
③トランスフォームをそれぞれ下記で入力し更新
入力パス
{
"account": "$.account",
"definition": "$.detail.Definition",
"detailType": "$.detail-type",
"executionId": "$.detail.ExecutionId",
"region": "$.region",
"source": "$.source",
"status": "$.detail.Status",
"time": "$.time"
}
※失敗イベントから抜き出したい値を設定しています。"変数名"となります。
テンプレート
{
{
"source": "eventbridge-automation-failure",
"title": "[Automation Failed] <definition> (<region>)",
"description": "## Summary\n- Definition: <definition>\n- Status: <status>\n- ExecutionId: <executionId>\n- Time: <time>\n- Account: <account>\n- Region: <region>\n\n## Quick links\n- Automation execution (search by ExecutionId): <executionId>\n\n## First response checklist\n- [ ] Automation実行の詳細を開き、失敗したStep名とエラー内容を確認する\n- [ ] Tag条件 TestShrink=falseになっていないか確認する\n- [ ] Tag条件(TestShrink=true)の対象が 0台 / 2台以上 になっていないか確認する\n- [ ] 対象EC2のインスタンス状態が「実行中」になっているか確認する\n- [ ] IAM権限不足の可能性を確認する(Stop/Start/Modify/Describe/DescribeInstanceStatus)\n\n## Rollback guideline\n- [ ] 変更途中で止まっている場合は、元のInstanceTypeに戻して起動できる状態に戻す(必要なら手動)\n\n## Close criteria\n- [ ] 以降の定期実行でSuccessになった、または手動で復旧完了したことを確認してクローズ\n\n## Notes\n- 調査メモ・対応ログはこのOpsItemに追記を必須とする(Slackだけに残さない)\n",
"severity": "2",
"category": "Availability"
}
}
※タイトルや説明に入れる内容を設定しています。入力パスの変数を<変数名>のように埋め込めます。
"description"が長文で見づらいですが、OpsItemの可視性を上げる為です。ご了承ください。
それでは入力パスとテンプレート更新後、再度Automationを失敗させてOpsItemを見てみましょう。
OpsItemのタイトルは何のタスクが失敗したか一目で分かるようになり、説明欄は後続の対応内容をチェックリスト風に載せることができました。
このくらいの粒度で説明が記載されていれば、インシデント対応の標準化は少なからず期待できるのではないでしょうか。
4.OpsItemを利用したインシデント対応
以降は、起票されたOpsItemを使って対応を進めてみます。
OpsItemはステータスを「未解決」「進行中」「解決済み」の3種類で管理できます。
このインシデントを担当するので、OpsItem上部の[ステータスの変更]から進行中に変えましょう。
タイトル横のステータスに反映されてますね。
続いて、説明内のチェックリストに沿って確認を進めます。
この説明欄はOpsItemの詳細 [編集]から自由に書き換えられます。
例えば今回タスクが失敗した原因が"対象EC2のインスタンス状態が「保留中」になっていた"であることが判明した場合は、
×印を付けたり、メモ書きを残すと分かりやすいですね。

ロールバックが必要なった場合を仮定しましょう。
OpsItemは"記録する場所"であると同時に、復旧作業の入口にもできます。
コンソールを下部の方へスクロールするとランブックの選択ウィンドウがあります。
必要に応じて、同じランブックを再実行したり、ロールバック用のランブックを実行したりといった復旧アクションへスムーズに繋げることができます。

原因の調査、復旧対応が完了したらステータスを「解決済み」に変更します。
OpsCenterのOpsItemタブからタイプやステータスをフィルターし、管理することができます。
日頃からフィルターを駆使し、対応状況をチェックしておけば対応漏れを防ぐことができそうです。
簡単ではありますがOpsItemを使ったインシデント対応の流れは以上になります。
まとめ
本記事では、SSM Automation の失敗イベントをEventBridgeで検知し、OpsCenterにOpsItemを自動起票してインシデント対応内容をテンプレ化するところまでを実践しました。
さらに、起票されたOpsItemを起点に、ステータス更新、必要に応じたランブックの実行、そしてクローズまでの一連の流れを紹介しました。
OpsCenterを参照することにより、失敗イベントの通知を見た人が都度手順を探したり、Slack等で証跡を辿るという作業はなくなり、OpsItemを“作業票”として運用することで、インシデント対応の進め方を標準化できますので、ぜひ利用してみてください。
また、運用にさらに落とし込む場合は、OpsItemの重複起票の抑止や重要度の自動調整といったこともできます。
こうした「既存OpsItemを検索して追記・更新する」処理は、EventBridge単体では完結しづらいため、一般的にはLambdaなどを組み合わせて実装しますが、これらは応用的な実践となる為、またの機会に触れたいと思います。