CloudTrail のイベントを EventBridge で検知するためのイベントパターンの設定を教えてください

2022.08.09

困っていた内容

CloudTrail で特定のイベントが記録された際に、EventBridge で検知して Lambda 関数の処理を実行することを検討しています。

テストとして、以下のような EventBridge のイベントパターンを設定しましたが、CloudTrail でのイベント記録を検知できませんでした。

{
  "source": ["aws.ec2"],
  "detail-type": ["AWS API Call via CloudTrail"],
  "userName": ["user-name"],
  "eventSource": ["ec2.amazonaws.com"],
  "eventName": ["RunInstances"]
}

CloudTrail のイベントを EventBridge で検知するためのイベントパターンの設定を教えてください。

どう対応すればいいの?

イベントパターンを設定するためには、CloudTrail に記録されるイベントの JSON の内容を把握する必要があります。

JSON では階層構造として記録されている内容もあるので、イベントパターン設定時にも階層構造を考慮する必要があります。

例えば、CloudTrail で以下のような EC2 の RunInstances イベントが記録された場合で考えてみます。 RunInstances で EC2 インスタンスを起動したユーザーが、特定のユーザーの場合のみ、EventBridge で検知するという内容を想定します。

{
  "eventVersion": "1.08",
  "userIdentity": {
    "type": "AssumedRole",
    "principalId": "{principal-id}:{user-name}",
    "arn": "arn:aws:sts::{account-id}:assumed-role/{user-name}/{user-name}",
    "accountId": "{account-id}",
    "accessKeyId": "{access-key-id}",
    "sessionContext": {
      "sessionIssuer": {
        "type": "Role",
        "principalId": "{principal-id}",
        "arn": "arn:aws:iam::{account-id}:role/{user-name}",
        "accountId": "{account-id}",
        "userName": "{user-name}"
      },
      "webIdFederationData": {},
      "attributes": {
        "creationDate": "2022-07-23T07:51:52Z",
        "mfaAuthenticated": "true"
      }
    }
  },
  "eventTime": "2022-07-23T08:17:05Z",
  "eventSource": "ec2.amazonaws.com",
  "eventName": "RunInstances",
  "awsRegion": "ap-northeast-1",
  "sourceIPAddress": "AWS Internal",
  "userAgent": "AWS Internal",
  "requestParameters": {
    "instancesSet": {
      "items": [
        {
          "imageId": "ami-0b7546e839d7ace12",
          "minCount": 1,
          "maxCount": 1
        }
      ]
    },
    "instanceType": "t2.micro",
    "blockDeviceMapping": {},
    "monitoring": {
      "enabled": false
    },
    "disableApiTermination": false,
    "disableApiStop": false,
    "networkInterfaceSet": {
      "items": [
        {
          "deviceIndex": 0,
          "associatePublicIpAddress": true,
          "groupSet": {
            "items": [
              {
                "groupId": "{sg-id}"
              }
            ]
          }
        }
      ]
    },
    "ebsOptimized": false,
    "tagSpecificationSet": {
      "items": [
        {
          "resourceType": "instance",
          "tags": [
            {
              "key": "Name",
              "value": "test"
            }
          ]
        }
      ]
    },
    "privateDnsNameOptions": {
      "hostnameType": "ip-name",
      "enableResourceNameDnsARecord": true,
      "enableResourceNameDnsAAAARecord": false
    }
  },
  "responseElements": {
    "requestId": "4cc3f128-5d9b-403d-b610-b3eed74ddf3a",
    "reservationId": "r-04a009282de1aa984",
    "ownerId": "{account-id}",
    "groupSet": {},
    "instancesSet": {
      "items": [
        {
          "instanceId": "i-0eff910f31cc85ee3",
          "imageId": "ami-0b7546e839d7ace12",
          "instanceState": {
            "code": 0,
            "name": "pending"
          },
          "privateDnsName": "ip-172-31-1-9.ap-northeast-1.compute.internal",
          "amiLaunchIndex": 0,
          "productCodes": {},
          "instanceType": "t2.micro",
          "launchTime": 1658564225000,
          "placement": {
            "availabilityZone": "ap-northeast-1c",
            "tenancy": "default"
          },
          "monitoring": {
            "state": "disabled"
          },
          "subnetId": "{subnet-id}",
          "vpcId": "{vpc-id}",
          "privateIpAddress": "172.31.1.9",
          "stateReason": {
            "code": "pending",
            "message": "pending"
          },
          "architecture": "x86_64",
          "rootDeviceType": "ebs",
          "rootDeviceName": "/dev/xvda",
          "blockDeviceMapping": {},
          "virtualizationType": "hvm",
          "hypervisor": "xen",
          "tagSet": {
            "items": [
              {
                "key": "Name",
                "value": "test"
              }
            ]
          },
          "groupSet": {
            "items": [
              {
                "groupId": "{sg-id}",
                "groupName": "default"
              }
            ]
          },
          "sourceDestCheck": true,
          "networkInterfaceSet": {
            "items": [
              {
                "networkInterfaceId": "eni-05fae8e171b36e104",
                "subnetId": "{subnet-id}",
                "vpcId": "{vpc-id}",
                "ownerId": "{account-id}",
                "status": "in-use",
                "macAddress": "0a:47:8e:d7:f0:d9",
                "privateIpAddress": "172.31.1.9",
                "privateDnsName": "ip-172-31-1-9.ap-northeast-1.compute.internal",
                "sourceDestCheck": true,
                "interfaceType": "interface",
                "groupSet": {
                  "items": [
                    {
                      "groupId": "{sg-id}",
                      "groupName": "default"
                    }
                  ]
                },
                "attachment": {
                  "attachmentId": "eni-attach-0939111d62cc6f699",
                  "deviceIndex": 0,
                  "networkCardIndex": 0,
                  "status": "attaching",
                  "attachTime": 1658564225000,
                  "deleteOnTermination": true
                },
                "privateIpAddressesSet": {
                  "item": [
                    {
                      "privateIpAddress": "172.31.1.9",
                      "privateDnsName": "ip-172-31-1-9.ap-northeast-1.compute.internal",
                      "primary": true
                    }
                  ]
                },
                "ipv6AddressesSet": {},
                "tagSet": {}
              }
            ]
          },
          "ebsOptimized": false,
          "enaSupport": true,
          "cpuOptions": {
            "coreCount": 1,
            "threadsPerCore": 1
          },
          "capacityReservationSpecification": {
            "capacityReservationPreference": "open"
          },
          "enclaveOptions": {
            "enabled": false
          },
          "metadataOptions": {
            "state": "pending",
            "httpTokens": "optional",
            "httpPutResponseHopLimit": 1,
            "httpEndpoint": "enabled",
            "httpProtocolIpv4": "enabled",
            "httpProtocolIpv6": "disabled",
            "instanceMetadataTags": "disabled"
          },
          "maintenanceOptions": {
            "autoRecovery": "default"
          },
          "privateDnsNameOptions": {
            "hostnameType": "ip-name",
            "enableResourceNameDnsARecord": true,
            "enableResourceNameDnsAAAARecord": false
          }
        }
      ]
    }
  },
  "requestID": "4cc3f128-5d9b-403d-b610-b3eed74ddf3a",
  "eventID": "cde16a06-946a-48b8-b552-046ed8a22d99",
  "readOnly": false,
  "eventType": "AwsApiCall",
  "managementEvent": true,
  "recipientAccountId": "{account-id}",
  "eventCategory": "Management",
  "sessionCredentialFromConsole": "true"
}

上記 CloudTrail のイベントが EventBridge に連携されると、以下の内容になります。

{
  "id": "6aa6af88-8ba7-b409-2d24-93f157bcd326",
  "detail-type": "AWS API Call via CloudTrail",
  "source": "aws.ec2",
  "account": "{account-id}",
  "time": "2022-07-23T08:17:05Z",
  "region": "ap-northeast-1",
  "resources": [],
  "detail": {
    "CloudTrail のイベント記録"
  }
}

上記のように、CloudTrail のイベント記録が detail というキーの中に含まれる内容となります。
この状態で、RunInstances を行った特定のユーザー名のみを検知する EventBridge のイベントパターンを設定すると、以下のようになります。

{
  "source": ["aws.ec2"],
  "detail-type": ["AWS API Call via CloudTrail"],
  "detail": {
    "userIdentity": {
      "sessionContext": {
        "sessionIssuer": {
          "userName": ["user-name"]
        }
      }
    },
    "eventSource": ["ec2.amazonaws.com"],
    "eventName": ["RunInstances"]
  }
}

上記の通り、JSON の階層構造を考慮して eventSourceeventNameuserName などを記述する必要があります。
実際に検知したいユーザー名は ["user-name"] の部分を置き換えます。

このイベントパターンで、EC2 の RunInstances を行った user-name という名前のユーザーに一致した場合のみ、EventBridge で検知することが可能となります。

参考資料