Incident ManagerとAutomationを使って運用自動化を試してみた -その1

記事タイトルとURLをコピーする

こんにちは!SRE2課 入倉です。
みなさん、運用の自動化してますか? 初投稿である今回はSystems Managerの機能であるIncident ManagerとAutomationを使って運用自動化を色々と試してみました!

はじめに

今回は以下の構成にてEC2でhttpdプロセスのアラートが発生したら、Incident Managerによる電話通知・インシデント起票、Automationでhttpプロセスを自動復旧・正常に復旧したらインシデントを自動クローズまで行います。

f:id:swx-irikura:20220207154210p:plain

Incident Managerとは

 CloudWatchアラームやEventBridgeのイベントをトリガーとしてインシデント起票し、その後の自動復旧の実行やメール、電話による通知が可能なサービスです。

docs.aws.amazon.com

Automationとは

 自動復旧の際のアクションとして何をするかを定義した、オートメーションドキュメント(Runbook)を実行することで様々なタスクを自動化できます。

docs.aws.amazon.com

前提

  • EC2のhttpdプロセスをCloudWatchにて監視できていること

(オプション)

  • ChatbotでのSlack連携ができていること(以下記事参考)

blog.serverworks.co.jp

 

Automationの設定

それでは早速、Automationの設定から行っていきます。

Runbookの作成

AWSで事前に定義されたランブックは数多くありますが、
今回はカスタムランブックの作成から行い、独自の内容をAutomationで実行します。

AWSアカウントにログインを行い、
「Systems Manager」 > 「ドキュメント」 > 「Create document」 > 「Automation」をクリック

f:id:swx-irikura:20220207120733p:plain

「名前」を入力 > 「エディタ」 > 「編集」をクリック

f:id:swx-irikura:20220207153128p:plain

以下のyamlを「ドキュメントエディタ」内に貼り付けます。

※以下の箇所の"xxxxxxxxxxxx"はご自身のAWSアカウント番号に書き換える必要があります。
   ActionPrefix: 'arn:aws:ssm-incidents::xxxxxxxxxxxx:response-plan/EC2Incident'

description: ''
schemaVersion: '0.3'
assumeRole: '{{ AutomationAssumeRole }}'
parameters:
  AutomationAssumeRole:
    type: String
    description: (Optional) The ARN of the role that allows Automation to perform the actions on your behalf.
mainSteps:
  - name: GetInstanceId
    action: 'aws:executeAwsApi'
    inputs:
      Service: cloudwatch
      Api: describeAlarms
      StateValue: ALARM
      ActionPrefix: 'arn:aws:ssm-incidents::xxxxxxxxxxxx:response-plan/EC2Incident'
    outputs:
      - Selector: '$.MetricAlarms[0].Dimensions[1].Value'
        Name: InstanceId
      - Selector: '$.MetricAlarms[0].AlarmName'
        Name: AlarmName
  - name: ListIncidentRecords
    action: 'aws:executeAwsApi'
    inputs:
      Service: ssm-incidents
      Api: ListIncidentRecords
      filters:
        - condition:
            equals:
              stringValues:
                - OPEN
          key: status
    outputs:
      - Name: IncidentRecordsTitle
        Selector: '$.incidentRecordSummaries[0].title'
        Type: String
      - Selector: '$.incidentRecordSummaries[0].arn'
        Name: IncidentRecordsArn
        Type: String
    nextStep: BranchIncidentTitle
  - name: BranchIncidentTitle
    action: 'aws:branch'
    inputs:
      Choices:
        - NextStep: HttpdRestartCommand
          Variable: '{{ListIncidentRecords.IncidentRecordsTitle}}'
          StringEquals: 'EC2Incident [{{GetInstanceId.AlarmName}}]'
    isEnd: true
  - name: HttpdRestartCommand
    action: 'aws:runCommand'
    inputs:
      DocumentName: AWS-RunShellScript
      InstanceIds:
        - '{{GetInstanceId.InstanceId}}'
      Parameters:
        commands: systemctl restart httpd
    nextStep: HttpdProccessCount
    onFailure: 'step:RebootInstance'
  - name: HttpdProccessCount
    action: 'aws:runCommand'
    inputs:
      DocumentName: AWS-RunShellScript
      InstanceIds:
        - '{{GetInstanceId.InstanceId}}'
      Parameters:
        commands: ps aux | grep httpd | grep -v grep | wc -l
    nextStep: BranchHttpdProccessCount
  - name: BranchHttpdProccessCount
    action: 'aws:branch'
    inputs:
      Choices:
        - NextStep: IncidentResolved
          Not:
            Variable: '{{HttpdProccessCount.Output}}'
            StringEquals: '0'
        - NextStep: RebootInstance
          Variable: '{{HttpdProccessCount.Output}}'
          StringEquals: '0'
  - name: IncidentResolved
    action: 'aws:executeAwsApi'
    inputs:
      Service: ssm-incidents
      Api: UpdateIncidentRecord
      arn: '{{ListIncidentRecords.IncidentRecordsArn}}'
      status: RESOLVED
    isEnd: true
  - name: RebootInstance
    action: 'aws:executeAwsApi'
    inputs:
      Service: ec2
      Api: RebootInstances
      InstanceIds:
        - '{{GetInstanceId.InstanceId}}'

上記の内容をフローチャートの図にすると以下の流れとなります。

f:id:swx-irikura:20220207160703p:plain

yamlの内容を入力したら「オートメーションを作成」をクリックします。

Incident Managerの設定

連絡先の登録

「Incident Manager」 > 「連絡先」 > 「連絡先を作成」をクリック

f:id:swx-irikura:20220207161625p:plain

複数の連絡先が登録可能で、登録可能なタイプは以下となります。

  • Eメール
  • SMS
  • 音声

今回は音声(電話)のみ登録します。

各項目を入力し、「作成」をクリック

f:id:swx-irikura:20220207173846p:plain

次の画面に遷移するとすぐに、登録した電話番号に電話がかかってきます。
英語で6桁のアクティベーションコードがお伝えされるので、心してヒアリングして下さい。

「アクティベーションコード」を入力 > 「終了」をクリック f:id:swx-irikura:20220207174258p:plain

エスカレーションプランの作成

エスカレーションプランの設定では、連絡先に通知した際に電話を出れなかった(「承認」作業を実施しなかった)場合、また次の連絡先に通知を回すという設定が可能です。 電話で承認する場合は、電話が来たら「1」を押すことで承認となります。

今回は先ほど作成した連絡先1つのみの設定とします。

「Incident Manager」 > 「エスカレーションプラン」 > 「エスカレーションプランを作成」をクリック

f:id:swx-irikura:20220226161918p:plain

各項目を入力し、「エスカレーションプランを作成」をクリック

f:id:swx-irikura:20220207175830p:plain

対応プランの作成

対応プランの設定では、これまで作成したエスカレーションプランやランブック、Slack通知先のチャンネルなどを紐づける設定のテンプレートとなります。

「Incident Manager」 > 「対応プラン」 > 「対応プランを作成」をクリック

f:id:swx-irikura:20220226162353p:plain

各項目を入力し、「対応プランを作成」をクリック

f:id:swx-irikura:20220222075307p:plain

f:id:swx-irikura:20220222075324p:plain

f:id:swx-irikura:20220222075336p:plain

CloudWatchアラームと対応プランの紐づけ

前提条件のhttpdのCloudWatchアラームを選択して、編集画面のアクションの設定で先ほど作成した対応プランを選択して「アラームの更新」をクリックします。

f:id:swx-irikura:20220222080900p:plain

動作確認

それではhttpdプロセスを落としてみます。

f:id:swx-irikura:20220222083715p:plain

電話通知がすぐにきて、Slackを見ると以下の処理がされたという通知がきたのを確認できます。

  1. インシデントを開始
  2. ランブックが実行完了
  3. opsitemにインシデントを関連付け
  4. インシデントが解決済み

f:id:swx-irikura:20220222084709p:plain

インシデントマネージャーを見ると、「オープン状態のインシデント」は何もなく、「解決済みのインシデント」に既になっていることが確認できます。

f:id:swx-irikura:20220222084738p:plain

インシデントのタイトルをクリックしてみると、メトリクスの現在の状態やタイムライン、ランブックが成功したか、連絡先への通知をしたかなど詳細を見ることができます。

f:id:swx-irikura:20220222091102p:plain

httpdのプロセスも無事「active」になっていました。

f:id:swx-irikura:20220222091624p:plain

まとめ

 運用の強い味方Incident Manager、Automationについてご紹介しました。
Incident Managerのセットアップは非常に簡単ですし、今回はランブックをカスタムで作成しましたが、既存のドキュメントが豊富にあったりなど簡単に自動化しやすいようになっていますので是非触って試してみてください。
本記事が運用自動化を目指す人の一助となれば幸いです。それではまたお会いしましょう!

入倉 翔吾(執筆記事の一覧)

クラウドインテグレーション部 SRE2課