【アップデート】 VPC LambdaがCloudTrailのデータイベントにENI IDを出力するようになりました #reinvent

地味ですが監査目的に有用なアップデートです
2021.12.04

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

MAD事業部@大阪の岩田です。本日のアップデートによりVPC LambdaがCloudTrailのデータイベントにENI IDを出力するようになりました。

VPC Lambdaが利用するENIはLambdaに紐づくサブネットとセキュリティグループの組み合わせごとに作成されます。つまり、サブネットとセキュリティグループの組み合わせが同一であればLambda1~10が1つのENIを共有利用するようなアーキテクチャです。このあたりはアーキテクチャの変更が発表された際にブログ化しているので、よければ参考にして下さい。

このアップデートにより、あるENIが承認済のLambdaからのみ利用されていることを監査できるようになりました。上記のAWSブログではユースケースとして金融サービス、ヘルスケアセクターの顧客などを挙げています。

やってみる

実際にCloudTrailの証跡を設定してログの内容を確認してみます。

まずはCloudTrailのマネコンから新しい証跡を作成します。今回はお試し目的なのでログファイルの検証や暗号化オプションは全て無効にしています。

続いてログイベントの選択です。ノイズが混ざらないようにLamdbaのデータイベントのみ出力されるよう指定しています。

このまま証跡を作成し、適当なVPC Lambda作成後にテストイベントを実行してしばらく待ちましょう。

指定したS3バケットにログが出力されたことが確認できたらログの中身を確認してみます。ログは以下のような構造でした

{
  "Records": [
    {
      "eventVersion": "1.08",
      "userIdentity": {
        "type": "AssumedRole",
        "principalId": "ABCDEFGHIJKLMNOPQRST:some-user",
        "arn": "arn:aws:sts::123456789012:assumed-role/some-role/some-user",
        "accountId": "123456789012",
        "accessKeyId": "ABCDEFGHIJKLMNOPQRST",
        "sessionContext": {
          "sessionIssuer": {
            "type": "Role",
            "principalId": "ABCDEFGHIJKLMNOPQRST",
            "arn": "arn:aws:iam::123456789012:role/some-role",
            "accountId": "123456789012",
            "userName": "some-role"
          },
          "attributes": {
            "creationDate": "2021-12-04T03:12:23Z",
            "mfaAuthenticated": "true"
          }
        }
      },
      "eventTime": "2021-12-04T03:25:21Z",
      "eventSource": "lambda.amazonaws.com",
      "eventName": "Invoke",
      "awsRegion": "ap-northeast-1",
      "sourceIPAddress": "1.2.3.4",
      "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36",
      "requestParameters": {
        "functionName": "arn:aws:lambda:ap-northeast-1:123456789012:function:vpc-lambda-1",
        "invocationType": "RequestResponse",
        "logType": "Tail",
        "contentType": "application/json"
      },
      "responseElements": null,
      "additionalEventData": {
        "customerEniId": "eni-045d450a2100243b1",
        "functionVersion": "arn:aws:lambda:ap-northeast-1:123456789012:function:vpc-lambda-1:$LATEST"
      },
      "requestID": "11bdbfa8-940e-491a-ba4c-7fcd85993886",
      "eventID": "50a87550-dfa6-4445-b0fe-f4850d739882",
      "readOnly": false,
      "resources": [
        {
          "accountId": "123456789012",
          "type": "AWS::Lambda::Function",
          "ARN": "arn:aws:lambda:ap-northeast-1:123456789012:function:vpc-lambda-1"
        }
      ],
      "eventType": "AwsApiCall",
      "managementEvent": false,
      "recipientAccountId": "123456789012",
      "eventCategory": "Data"
    }
  ]
}

以前は存在しなかったadditionalEventDataという項目が追加されており、その中にcustomerEniIdという項目名でENIのIDが出力されています。

      "additionalEventData": {
        "customerEniId": "eni-045d450a2100243b1",
        "functionVersion": "arn:aws:lambda:ap-northeast-1:123456789012:function:vpc-lambda-1:$LATEST"
      },

このENI IDをEC2のマネコンから確認すると「説明」の列にAWS Lambda VPC ENI-<Lambda Fuction名>....と記載されており、VPC Lambdaが利用しているENIで間違い無さそうです。

続いてAthenaのクエリでENI & Lambdaの組み合わせごとの実行回数をクエリしてみましょう。以下のSQLを実行してみます。

SELECT
  json_extract(additionaleventdata, '$.customerEniId') eniId,
	json_extract(requestParameters, '$.functionName') functionName,
	COUNT(*) cnt
FROM
  <ATHENAのテーブル名>
WHERE
  json_extract(additionaleventdata, '$.customerEniId') IS NOT NULL
GROUP BY
  json_extract(requestParameters, '$.functionName'),
	json_extract(additionaleventdata, '$.customerEniId')

実行結果です。

うまく集計できています。

まとめ

re:Inventで大量のアップデートが発表されるなかで見落とされてしまいそうな地味なアップデートですが、一部のユーザーにとっては嬉しいアップデートだと思います。

監査以外にも特定の時間帯におけるENIに紐づくLambdaの実行回数を集計し、ENI単位でのスパイクアクセス有無を判断するといった用途も考えられます。特定のENIに紐づくLambda1~10の合計実行回数が多くなっている場合はDNSのスロットリング対策としてダミーとセキュリティグループを作成してLambdaにアタッチすることで

  • Lambda1~5 <-> ENI A
  • Lambda6~10 <-> ENI B

といった構成に移行するといった判断がしやすくなりそうです。

ENI単位でのLambda実行回数はCloudWatchのメトリクスから追いかけていくことも可能ですが、多数のLambdaでENIを共有している場合は各Lambdaの実行回数を集計するのは少し面倒です。CloudTrailでLambdaのデータイベントをロギングしているような環境であればAthenaを使ってENIの負荷を分析するという選択肢もアリではないでしょうか?

参考