Amazon EventBridgeから Microsoft Teams に表形式や箇条書き、メンション付きで通知してみた

2024.01.12

はじめに

AWS Security Hubで検知した内容をAmazon EventBridge経由でMicrosoft Teamsにメンション付きで通知する方法について解説します。

メンション付き通知に加え、Teamsで検知内容を表形式や箇条書きで表示する方法についても紹介します。

構築

イベントパターンと入力トランスフォーマーを設定する際の入力パスやテンプレートを除き、下記の記事を参考に作成します。

イベントパターンでは、Security Hubで重要度が高いコントロールのみが通知されるように設定します。

イベントパターン

{
  "detail-type": ["Security Hub Findings - Imported"],
  "source": ["aws.securityhub"],
  "detail": {
    "findings": {
      "Severity": {
        "Label": ["HIGH", "CRITICAL"]
      },
      "ProductName": ["Security Hub"],
      "RecordState": ["ACTIVE"],
      "Workflow": {
        "Status": ["NEW"]
      }
    }
  }
}

入力パスは、Teamsに通知したい内容を抽出するように設定します。

入力パス

{
  "AwsAccountId": "$.detail.findings[0].AwsAccountId",
  "FirstObservedAt": "$.detail.findings[0].FirstObservedAt",
  "LastObservedAt": "$.detail.findings[0].LastObservedAt",
  "RecommendationUrl": "$.detail.findings[0].ProductFields.RecommendationUrl",
  "Region": "$.detail.findings[0].Resources[0].Region",
  "ResourceId": "$.detail.findings[0].Resources[0].Id",
  "ResourceType": "$.detail.findings[0].Resources[0].Type",
  "SeverityLabel": "$.detail.findings[0].Severity.Label",
  "Title": "$.detail.findings[0].Title"
}

入力トランスフォーマーのテンプレートは、Teamsへの通知内容によって変わるため、後述します。

メンションのみ

まず、下記の通り、Teamsにメンションのみ通知するテンプレートを記載します。

テンプレートは下記の通りです。

テンプレート

{
  "type": "message",
  "attachments": [
    {
      "contentType": "application/vnd.microsoft.card.adaptive",
      "content": {
        "type": "AdaptiveCard",
        "body": [
          {
            "type": "TextBlock",
            "text": "\u003cat\u003e平井裕二\u003c/at\u003e",
            "weight": "bolder",
            "size": "medium"
          }
        ],
        "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
        "version": "1.5",
        "msteams": {
          "width": "full",
          "entities": [
            {
              "type": "mention",
              "text": "\u003cat\u003e平井裕二\u003c/at\u003e",
              "mentioned": {
                "id": "xxx@example.com",
                "name": "平井裕二"
              }
            }
          ]
        }
      }
    }
  ]
}

Incoming WebhookでTeamsにメンション付きで通知するには、アダプティブカード形式で通知する必要がありますので、typeAdaptiveCardに設定する必要があります。

テンプレートのidnameは、メンション対象者に応じて変更してください。

  • id:ユーザーのメールアドレス(xxxx@example.com)を指定
  • name:ユーザー名(ユーザー名)を指定

また、メンションするには、ユーザー名を<at></at>で囲む必要がありますが、EventBridgeのテンプレートではこれを使用できないため、ユニコードエスケープシーケンス形式で指定します。

Teams側で<at></at>に変換され、結果としてメンションが可能になります。

ちなみに、\<at\>のようにエスケープ処理だとエラーになりました。

表形式

続いて、検知内容を表形式で表示し、メンションを含めてTeamsに通知するテンプレートについて解説します。

テンプレートは、下記の通りです。

テンプレート

{
  "type": "message",
  "attachments": [
    {
      "contentType": "application/vnd.microsoft.card.adaptive",
      "content": {
        "type": "AdaptiveCard",
        "body": [
          {
            "type": "TextBlock",
            "text": "\u003cat\u003e平井裕二\u003c/at\u003e",
            "weight": "bolder",
            "size": "medium"
          },
          {
            "type": "TextBlock",
            "text": "SecurityHubで重大度<SeverityLabel>のアラートを検知しました",
            "size": "Large",
            "weight": "Bolder"
          },
          {
            "type": "Table",
            "columns": [
              {
                "width": 1
              },
              {
                "width": 2
              }
            ],
            "rows": [
              {
                "type": "TableRow",
                "cells": [
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "タイトル",
                        "weight": "Bolder"
                      }
                    ]
                  },
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "wrap": true,
                        "text": "<Title>"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "TableRow",
                "cells": [
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "重要度",
                        "weight": "Bolder"
                      }
                    ]
                  },
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "wrap": true,
                        "text": "<SeverityLabel>"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "TableRow",
                "cells": [
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "修復手順",
                        "weight": "Bolder"
                      }
                    ]
                  },
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "wrap": true,
                        "text": "[こちらをクリック](<RecommendationUrl>)"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "TableRow",
                "cells": [
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "アカウントID",
                        "weight": "Bolder"
                      }
                    ]
                  },
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "wrap": true,
                        "text": "<AwsAccountId>"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "TableRow",
                "cells": [
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "リージョン",
                        "weight": "Bolder"
                      }
                    ]
                  },
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "wrap": true,
                        "text": "<Region>"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "TableRow",
                "cells": [
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "リソースタイプ",
                        "weight": "Bolder"
                      }
                    ]
                  },
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "wrap": true,
                        "text": "<ResourceType>"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "TableRow",
                "cells": [
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "リソースID",
                        "weight": "Bolder"
                      }
                    ]
                  },
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "wrap": true,
                        "text": "<ResourceId>"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "TableRow",
                "cells": [
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "初回検出日時",
                        "weight": "Bolder"
                      }
                    ]
                  },
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "wrap": true,
                        "text": "<FirstObservedAt>"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "TableRow",
                "cells": [
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "最終検出日時",
                        "weight": "Bolder"
                      }
                    ]
                  },
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "wrap": true,
                        "text": "<LastObservedAt>"
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ],
        "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
        "version": "1.5",
        "msteams": {
          "width": "full",
          "entities": [
            {
              "type": "mention",
              "text": "\u003cat\u003e平井裕二\u003c/at\u003e",
              "mentioned": {
                "id": "xxx@example.com",
                "name": "平井裕二"
              }
            }
          ]
        }
      }
    }
  ]
}

TableCellを使用して列を作成し、TableRowで行を構成します。Tableを使用して全体を表形式で通知できます。

また、wrapを使用して長いテキストを折り返すように設定します。

マネジメントコンソールに遷移

AWS マネジメントコンソールのSecurity Hubの対象コントロール画面に遷移させることも可能です。

例えば、以下の通知画面では、「詳細情報」をクリックすると、

以下のSecurity Hubの対象コントロール画面に遷移できます。

注意点としては、以下のリンク先が変わった場合は、対応できません。

  • https://ap-northeast-1.console.aws.amazon.com/securityhub/home?region=ap-northeast-1#/standards/aws-foundational-security-best-practices-1.0.0/EC2.18

上記の通知画面は、以下の入力パスと入力テンプレートから構築できます。

入力パス

{
  "AwsAccountId": "$.detail.findings[0].AwsAccountId",
  "FirstObservedAt": "$.detail.findings[0].FirstObservedAt",
  "LastObservedAt": "$.detail.findings[0].LastObservedAt",
  "RecommendationUrl": "$.detail.findings[0].ProductFields.RecommendationUrl",
  "Region": "$.detail.findings[0].Resources[0].Region",
  "ResourceId": "$.detail.findings[0].Resources[0].Id",
  "ResourceType": "$.detail.findings[0].Resources[0].Type",
  "SecurityControlId": "$.detail.findings[0].Compliance.SecurityControlId",
  "SeverityLabel": "$.detail.findings[0].Severity.Label",
  "Title": "$.detail.findings[0].Title"
}
入力テンプレートのコード (クリックすると展開します)

入力テンプレート

{
  "type": "message",
  "attachments": [
    {
      "contentType": "application/vnd.microsoft.card.adaptive",
      "content": {
        "type": "AdaptiveCard",
        "body": [
          {
            "type": "TextBlock",
            "text": "\u003cat\u003e平井裕二\u003c/at\u003e",
            "weight": "bolder",
            "size": "medium"
          },
          {
            "type": "TextBlock",
            "text": "SecurityHubで重大度<SeverityLabel>のアラートを検知しました",
            "size": "Large",
            "weight": "Bolder"
          },
          {
            "type": "Table",
            "columns": [
              {
                "width": 1
              },
              {
                "width": 2
              }
            ],
            "rows": [
              {
                "type": "TableRow",
                "cells": [
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "タイトル",
                        "weight": "Bolder"
                      }
                    ]
                  },
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "wrap": true,
                        "text": "<Title>"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "TableRow",
                "cells": [
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "重要度",
                        "weight": "Bolder"
                      }
                    ]
                  },
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "wrap": true,
                        "text": "<SeverityLabel>"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "TableRow",
                "cells": [
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "修復手順",
                        "weight": "Bolder"
                      }
                    ]
                  },
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "wrap": true,
                        "text": "[こちらをクリック](<RecommendationUrl>)"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "TableRow",
                "cells": [
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "詳細情報",
                        "weight": "Bolder"
                      }
                    ]
                  },
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "wrap": true,
                        "text": "[こちらをクリック](https://<Region>.console.aws.amazon.com/securityhub/home?region=<Region>#/standards/aws-foundational-security-best-practices-1.0.0/<SecurityControlId>) (AWSコンソールに遷移)"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "TableRow",
                "cells": [
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "アカウントID",
                        "weight": "Bolder"
                      }
                    ]
                  },
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "wrap": true,
                        "text": "<AwsAccountId>"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "TableRow",
                "cells": [
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "リソースタイプ",
                        "weight": "Bolder"
                      }
                    ]
                  },
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "wrap": true,
                        "text": "<ResourceType>"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "TableRow",
                "cells": [
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "リソースID",
                        "weight": "Bolder"
                      }
                    ]
                  },
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "wrap": true,
                        "text": "<ResourceId>"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "TableRow",
                "cells": [
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "初回検出日時",
                        "weight": "Bolder"
                      }
                    ]
                  },
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "wrap": true,
                        "text": "<FirstObservedAt>"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "TableRow",
                "cells": [
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "最終検出日時",
                        "weight": "Bolder"
                      }
                    ]
                  },
                  {
                    "type": "TableCell",
                    "items": [
                      {
                        "type": "TextBlock",
                        "wrap": true,
                        "text": "<LastObservedAt>"
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ],
        "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
        "version": "1.5",
        "msteams": {
          "width": "full",
          "entities": [
            {
              "type": "mention",
              "text": "\u003cat\u003e平井裕二\u003c/at\u003e",
              "mentioned": {
                "id": "xxx@example.com",
                "name": "平井裕二"
              }
            }
          ]
        }
      }
    }
  ]
}

箇条書き

最後に、検知内容を箇条書きで表示し、メンションを含めてTeamsに通知するテンプレートを解説します。

テンプレート

{
  "type": "message",
  "attachments": [
    {
      "contentType": "application/vnd.microsoft.card.adaptive",
      "content": {
        "type": "AdaptiveCard",
        "body": [
          {
            "type": "TextBlock",
            "text": "\u003cat\u003e平井裕二\u003c/at\u003e \n\n# 検知内容 \n\n- 件名 : **<Title>**\n\n- 重大度 : **<SeverityLabel>**\n\n- 修復手順 : [こちらをクリック](<RecommendationUrl>)\n\n- アカウントID : **<AwsAccountId>**\n\n- リージョン : **<Region>**\n\n- リソースタイプ : **<ResourceType>**\n\n- リソースID : **<ResourceId>**\n\n- 初回検知日時 : **<FirstObservedAt>**\n\n- 最終検知日時 : **<LastObservedAt>**"
          }
        ],
        "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
        "version": "1.0",
        "msteams": {
          "width": "full",
          "entities": [
            {
              "type": "mention",
              "text": "\u003cat\u003e平井裕二\u003c/at\u003e",
              "mentioned": {
                "id": "xxx@example.com",
                "name": "平井裕二"
              }
            }
          ]
        }
      }
    }
  ]
}

**でテキストを太字にし、-を利用することで箇条書きとなります。

Teamsへの通知内容

通知内容は、下記リンクのdesignerを利用することで、通知内容をリアルタイムで確認や修正できます。

アダプティブカードのサンプルJSON (クリックすると展開します)
<details>
<summary><font color="#ff0000"> <strong>コード </strong>(クリックすると展開します)</font></summary>
<div>

</div>
</details>

アダプティブカードのスキーマについては、以下のリンクにまとめられています。カスタマイズの際に参考にしてください。

最後に

この記事では、EventBridgeからMicrosoft Teamsにメンションや表形式、箇条書きで通知する方法を紹介しました。

アダプティブカードのスキーマに関するリンクも提供しましたので、カスタマイズの際に参考下さい、

参考