Amazon Security Lake を再有効化する時、注意したいことをまとめてみた

Amazon Security Lake を再有効化する時、注意したいことをまとめてみた

Clock Icon2025.02.25

あしざわです。

以前検証用途でSecurity Lake を有効化し、検証が終わったタイミングでサービスを停止したアカウントがあります。

このアカウントでまたSecurity Lake を検証する機会があり、再度有効化したところ、以下のようなエラーに遭遇しました。

CleanShot 2025-02-17 at 15.56.35@2x.png
有効化後に表示されたエラー

このエラーの調査・対応を行ったので、このブログではその過程と結果についてまとめます。

いきなりまとめ

  • 再有効化する際には既存のリソース、制限に気をつけよう
    • Security Lake はサービスを無効化した時にリソースが削除されないため(Glue Database など)
    • SCP による制限も追加で意識しよう
  • 再有効化エラーはCloudTrail に情報が残っていない場合があるため注意
    • 何か問題が起きた時はトラブルシューティングは Security Lake コンソールの 問題 を確認することから始めるべし
  • サービスリンクロールへの切り替えもやっておこう

調査

前述したエラーは見ての通り、「Security Lake が特定のリージョンで作成されなかった」という情報しかなく、何もわかりません。

CloudTrailならエラーが表示されているのでは?と思い、確認してみました。

イベントソースに securitylake.amazonaws.com を指定し全体を眺めてみたところ、CreateDataLakeというサービスを有効化するイベントがありました。

{
    "eventVersion": "1.09",
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "xxxxxxxxx:cm-ashizawa-hiroaki",
        "arn": "arn:aws:sts::123456789012:assumed-role/AWSReservedSSO_AWSAdministratorAccess_3d828f2bc9849828/cm-ashizawa-hiroaki",
        "accountId": "123456789012",
        "accessKeyId": "xxxxxxxxx",
        "sessionContext": {
            "sessionIssuer": {
                "type": "Role",
                "principalId": "xxxxxxxxx",
                "arn": "arn:aws:iam::123456789012:role/aws-reserved/sso.amazonaws.com/ap-northeast-1/AWSReservedSSO_AWSAdministratorAccess_3d828f2bc9849828",
                "accountId": "123456789012",
                "userName": "AWSReservedSSO_AWSAdministratorAccess_3d828f2bc9849828"
            },
            "attributes": {
                "creationDate": "2025-02-17T06:43:33Z",
                "mfaAuthenticated": "false"
            }
        }
    },
    "eventTime": "2025-02-17T06:56:26Z",
    "eventSource": "securitylake.amazonaws.com",
    "eventName": "CreateDataLake",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "104.28.204.107",
    "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36",
    "requestParameters": {
        "metaStoreManagerRoleArn": "arn:aws:iam::123456789012:role/service-role/AmazonSecurityLakeMetaStoreManagerV2",
        "configurations": [
            {
                "region": "ap-northeast-3",
                "encryptionConfiguration": {
                    "kmsKeyId": "S3_MANAGED_KEY"
                },
                "lifecycleConfiguration": {
                    "transitions": []
                }
            },
            {
                "region": "ap-northeast-1",
                "encryptionConfiguration": {
                    "kmsKeyId": "S3_MANAGED_KEY"
                },
                "lifecycleConfiguration": {
                    "transitions": []
                }
            },
            {
                "region": "eu-central-1",
                "encryptionConfiguration": {
                    "kmsKeyId": "S3_MANAGED_KEY"
                },
                "lifecycleConfiguration": {
                    "transitions": []
                }
            },
            {
                "region": "us-east-1",
                "encryptionConfiguration": {
                    "kmsKeyId": "S3_MANAGED_KEY"
                },
                "lifecycleConfiguration": {
                    "transitions": []
                }
            }
        ]
    },
    "responseElements": {
        "Access-Control-Expose-Headers": "x-amzn-RequestId,x-amzn-ErrorType,x-amzn-ErrorMessage,Date,smithy-protocol",
        "dataLakes": [
            {
                "createStatus": "INITIALIZED",
                "dataLakeArn": "arn:aws:securitylake:ap-northeast-3:123456789012:data-lake/default",
                "encryptionConfiguration": {
                    "kmsKeyId": "S3_MANAGED_KEY"
                },
                "lifecycleConfiguration": {
                    "transitions": []
                },
                "region": "ap-northeast-3"
            },
            {
                "createStatus": "INITIALIZED",
                "dataLakeArn": "arn:aws:securitylake:ap-northeast-1:123456789012:data-lake/default",
                "encryptionConfiguration": {
                    "kmsKeyId": "S3_MANAGED_KEY"
                },
                "lifecycleConfiguration": {
                    "transitions": []
                },
                "region": "ap-northeast-1"
            },
            {
                "createStatus": "INITIALIZED",
                "dataLakeArn": "arn:aws:securitylake:eu-central-1:123456789012:data-lake/default",
                "encryptionConfiguration": {
                    "kmsKeyId": "S3_MANAGED_KEY"
                },
                "lifecycleConfiguration": {
                    "transitions": []
                },
                "region": "eu-central-1"
            },
            {
                "createStatus": "INITIALIZED",
                "dataLakeArn": "arn:aws:securitylake:us-east-1:123456789012:data-lake/default",
                "encryptionConfiguration": {
                    "kmsKeyId": "S3_MANAGED_KEY"
                },
                "lifecycleConfiguration": {
                    "transitions": []
                },
                "region": "us-east-1"
            }
        ]
    },
    "requestID": "8acc2231-2606-45a3-b999-9dc25005add5",
    "eventID": "cba5e6a0-ae74-46d6-b96e-b68259d9a5ad",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "123456789012",
    "eventCategory": "Management"
}

エラーを出力するようなイベントではなさそうです。

有効化したリージョンは他にもあったので、そのうちの1つであるバージニア北部リージョンを確認してもイベントソース securitylake.amazonaws.com の書き込みイベントは見つかりませんでした。

途方に暮れそうになっていたところ、Security Lake のコンソールの 問題 というページを発見しました。

まさにこれでした。

CleanShot 2025-02-21 at 17.39.18@2x.png
問題のページ

それぞれ詳細を見ていくと:

software.amazon.awssdk.services.glue.model.AccessDeniedException: User: arn:aws:sts::123456789012:assumed-role/AWSReservedSSO_AWSAdministratorAccess_3d828f2bc9849828/cm-ashizawa-hiroaki is not authorized to perform: glue:GetDatabase on resource: arn:aws:glue:eu-central-1:123456789012:catalog with an explicit deny in a service control policy (Service: Glue, Status Code: 400, Request ID: 96e76b47-b4d4-4ff6-9cb5-719968761014)

フランクフルト・大阪リージョンでは、SCP によるexplicit denyにより拒否されたことがわかります

この検証環境ではバージニア北部・東京リージョン以外のリージョンでのAPI実行を拒否するSCP を設定しており、それによるエラーであると判断できます。

The CreateDataLake operation failed due to a pre-existing Glue Database.

東京・バージニア北部リージョンでは、Glue Database が既に存在していることによるエラーだったとわかります。

以前、Security Lake を無効化したときにリソースの削除をしていなかったので、そのせいだと理解しました。

それぞれのリージョンのGlue Databaseを確認しました。Created Onが2023年の日付になっているリソースが存在しており、これが原因だと判断しました。

CleanShot 2025-02-17 at 16.27.35@2x.png
画像はバージニア北部リージョン

エラー対応

SCPでブロックされていたフランクフルト、大阪リージョンは本来有効化する必要がないリージョンだったため、東京・バージニア北部で再有効化を進めます。

手順は割愛しますが、東京・バージニア北部リージョンのGlue Databaseを削除しました。実データはS3 に保存されているので影響はないはずです。

削除後にもう一度、Security Lake を東京・バージニア北部リージョンで有効化したところ、うまくいきました。

CleanShot 2025-02-17 at 16.59.05@2x.png

Glue Database は同じ名称の新しいリソースが作成されていますね。

CleanShot 2025-02-25 at 17.49.56.png
画像はバージニア北部リージョン

データレイクとなる新規のS3バケットが作成されており、新しい環境のログはこのバケットに集約されていました。

CleanShot 2025-02-25 at 17.53.47.png

これで再有効化が完了しました。

(参考) 追加のエラー対応

話の本筋であるSecurity Lake の再有効化自体はここまでで完了していますが、その後コンソールを眺めていたところ、追加で対応が必要そうなエラーがいくつか見つかったので参考までに記載しておきます。

  1. リージョン制限SCP によって有効化していないリージョンのエラーが残っている
  2. Security Lake のサービスロール関連のエラー

1. リージョン制限SCP によって有効化していないリージョンのエラーが残っている

Security Lake コンソールのリージョンを確認すると、リージョン制限SCP の影響で有効化しなかった大阪・フランクフルトリージョンのところに「データレイクを作成できませんでした」と表示されたままになっていました。

CleanShot 2025-02-25 at 18.20.20.png

おそらく、SCP の影響で実リソースの作成はできなかったが、Security Lake のコントロールプレーン上の設定情報だけが残ってしまっている状態だと理解しました。

この設定は不要なものなのでどちらも削除しました。

CleanShot 2025-02-25 at 18.31.42.png
画像は大阪リージョンのみ

2. Security Lake のサービスロール関連のエラー

Security Lake コンソールの問題を確認すると、以下のエラーが出ていました。

Security Lake couldn't assume AWSServiceRoleForSecurityLakeResourceManagement for account 123456789012.

CleanShot 2025-02-25 at 18.34.39.png

修復手順も記載がありました。

You must install AWSServiceRoleForSecurityLakeResourceManagement for account 021312657858. If you have already completed the action, this message will clear and no further action is needed.

有効化時に実行されたCreateDataLakeのAPI リクエストにも記載があった通り、現在使っていたサービスロールはAmazonSecurityLakeMetaStoreManagerV2でした。

    "requestParameters": {
        "metaStoreManagerRoleArn": "arn:aws:iam::123456789012:role/service-role/AmazonSecurityLakeMetaStoreManagerV2",
    〜略〜
    }

このロールをサービスリンクロールであるAWSServiceRoleForSecurityLakeResourceManagementに切り替えるように求められていました。

以前はサービスアクセスロールを明示的に関連づける形式でしたが、直近の

b67b85d443dc0d481d03003357f5a071.jpeg
引用:[アップデート]組織内のセキュリティデータをAWS上で一元管理できる!Amazon Security LakeがGA(一般利用開始)されましたより

本件は以下ドキュメントに

Security Lake コンソールの要約にサービスリンクロールを有効化のリンクが表示されていました。

CleanShot 2025-02-25 at 18.54.26.png

こちらをクリックして有効化を進めました。

CleanShot 2025-02-25 at 19.00.22-4.png

更新はすぐ完了しました。

AmazonSecurityLakeMetaStoreManagerV2AWSServiceRoleForSecurityLakeResourceManagementの差分を大まかに説明すると「既存の管理機能の強化と不要な権限の削除」で、よくあるサービスリンクロールの更新内容かと思います。

公式ドキュメントによると、サービスリンクロールに切り替えてできるようになることは以下のようです。

  • Apache Iceberg マニフェストファイルの圧縮によるクエリのパフォーマンス向上、Lambda の処理時間とコスト削減
  • SQSの状態をモニタリング、取り込みの問題の検出
  • クロスリージョンデータレプリケーションの最適化(メタデータファイルの除外)
参考:AWSServiceRoleForSecurityLakeResourceManagement のポリシードキュメントはこちら
[
  {
    "Sid": "ReadEventBridgeRules",
    "Effect": "Allow",
    "Action": [
      "events:ListRules"
    ],
    "Resource": "*",
    "Condition": {
      "StringEquals": {
        "aws:ResourceAccount": "${aws:PrincipalAccount}"
      }
    }
  },
  {
    "Sid": "ManageSecurityLakeEventRules",
    "Effect": "Allow",
    "Action": [
      "events:PutRule"
    ],
    "Resource": "arn:aws:events:*:*:rule/AmazonSecurityLake-*",
    "Condition": {
      "StringEquals": {
        "aws:ResourceAccount": "${aws:PrincipalAccount}"
      }
    }
  },
  {
    "Sid": "ManageSecurityLakeLambdaConfigurations",
    "Effect": "Allow",
    "Action": [
      "lambda:GetEventSourceMapping",
      "lambda:GetFunction",
      "lambda:PutFunctionConcurrency",
      "lambda:GetProvisionedConcurrencyConfig",
      "lambda:GetFunctionConcurrency",
      "lambda:GetRuntimeManagementConfig",
      "lambda:PutProvisionedConcurrencyConfig",
      "lambda:PublishVersion",
      "lambda:DeleteFunctionConcurrency",
      "lambda:DeleteEventSourceMapping",
      "lambda:GetAlias",
      "lambda:GetPolicy",
      "lambda:GetFunctionConfiguration",
      "lambda:UpdateFunctionConfiguration"
    ],
    "Resource": [
      "arn:aws:lambda:*:*:function:SecurityLake_Glue_Partition_Updater_Lambda*",
      "arn:aws:lambda:*:*:function:AmazonSecurityLakeMetastoreManager-*-*"
    ],
    "Condition": {
      "StringEquals": {
        "aws:ResourceAccount": "${aws:PrincipalAccount}"
      }
    }
  },
  {
    "Sid": "AllowListLambdaEventSourceMappings",
    "Effect": "Allow",
    "Action": [
      "lambda:ListEventSourceMappings"
    ],
    "Resource": "*",
    "Condition": {
      "StringEquals": {
        "aws:ResourceAccount": "${aws:PrincipalAccount}"
      }
    }
  },
  {
    "Sid": "AllowUpdateLambdaEventSourceMapping",
    "Effect": "Allow",
    "Action": [
      "lambda:UpdateEventSourceMapping"
    ],
    "Resource": "*",
    "Condition": {
      "StringEquals": {
        "aws:ResourceAccount": "${aws:PrincipalAccount}"
      },
      "StringLike": {
        "lambda:FunctionArn": "arn:aws:lambda:*:*:function:AmazonSecurityLakeMetastoreManager-*-*"
      }
    }
  },
  {
    "Sid": "AllowUpdateLambdaConfigs",
    "Effect": "Allow",
    "Action": [
      "lambda:UpdateFunctionConfiguration"
    ],
    "Resource": "arn:aws:lambda:*:*:function:AmazonSecurityLakeMetastoreManager-*-*",
    "Condition": {
      "StringEquals": {
        "aws:ResourceAccount": "${aws:PrincipalAccount}"
      }
    }
  },
  {
    "Sid": "ManageSecurityLakeGlueResources",
    "Effect": "Allow",
    "Action": [
      "glue:CreatePartition",
      "glue:BatchCreatePartition",
      "glue:GetTable",
      "glue:GetTables",
      "glue:UpdateTable",
      "glue:GetDatabase"
    ],
    "Resource": [
      "arn:aws:glue:*:*:table/amazon_security_lake_glue_db*/*",
      "arn:aws:glue:*:*:database/amazon_security_lake_glue_db*",
      "arn:aws:glue:*:*:catalog"
    ],
    "Condition": {
      "StringEquals": {
        "aws:ResourceAccount": "${aws:PrincipalAccount}"
      }
    }
  },
  {
    "Sid": "AllowDataLakeConfigurationManagement",
    "Effect": "Allow",
    "Action": [
      "s3:ListBucket",
      "s3:PutObject",
      "s3:GetObjectAttributes",
      "s3:GetBucketNotification",
      "s3:PutBucketNotification",
      "s3:GetLifecycleConfiguration",
      "s3:PutLifecycleConfiguration",
      "s3:GetEncryptionConfiguration",
      "s3:GetReplicationConfiguration"
    ],
    "Resource": [
      "arn:aws:s3:::aws-security-data-lake*"
    ],
    "Condition": {
      "StringEquals": {
        "aws:ResourceAccount": "${aws:PrincipalAccount}"
      }
    }
  },
  {
    "Sid": "AllowMetaDataCompactionAndManagement",
    "Effect": "Allow",
    "Action": [
      "s3:GetObject",
      "s3:DeleteObject",
      "s3:RestoreObject"
    ],
    "Resource": [
      "arn:aws:s3:::aws-security-data-lake*/metadata/*.avro",
      "arn:aws:s3:::aws-security-data-lake*/metadata/*.metadata.json"
    ],
    "Condition": {
      "StringEquals": {
        "aws:ResourceAccount": "${aws:PrincipalAccount}"
      }
    }
  },
  {
    "Sid": "ReadSecurityLakeLambdaLogs",
    "Effect": "Allow",
    "Action": [
      "logs:DescribeLogStreams",
      "logs:StartQuery",
      "logs:GetLogEvents",
      "logs:GetQueryResults",
      "logs:GetLogRecord"
    ],
    "Resource": [
      "arn:aws:logs:*:*:log-group:/aws/lambda/AmazonSecurityLakeMetastoreManager-*-*"
    ],
    "Condition": {
      "StringEquals": {
        "aws:ResourceAccount": "${aws:PrincipalAccount}"
      }
    }
  },
  {
    "Sid": "ManageSecurityLakeSQSQueue",
    "Effect": "Allow",
    "Action": [
      "sqs:StartMessageMoveTask",
      "sqs:DeleteMessage",
      "sqs:GetQueueUrl",
      "sqs:ListDeadLetterSourceQueues",
      "sqs:ChangeMessageVisibility",
      "sqs:ListMessageMoveTasks",
      "sqs:ReceiveMessage",
      "sqs:SendMessage",
      "sqs:GetQueueAttributes",
      "sqs:SetQueueAttributes"
    ],
    "Resource": [
      "arn:aws:sqs:*:*:SecurityLake_*",
      "arn:aws:sqs:*:*:AmazonSecurityLakeManager-*"
    ],
    "Condition": {
      "StringEquals": {
        "aws:ResourceAccount": "${aws:PrincipalAccount}"
      }
    }
  },
  {
    "Sid": "AllowDataLakeManagement",
    "Effect": "Allow",
    "Action": [
      "lakeformation:GetDataLakeSettings",
      "lakeformation:ListPermissions"
    ],
    "Resource": "*",
    "Condition": {
      "StringEquals": {
        "aws:ResourceAccount": "${aws:PrincipalAccount}"
      }
    }
  }
]
参考:AmazonSecurityLakeMetaStoreManagerV2 のポリシードキュメントはこちら
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowWriteLambdaLogs",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "logs:CreateLogGroup"
            ],
            "Resource": [
                "arn:aws:logs:*:*:log-group:/aws/lambda/AmazonSecurityLake*",
                "arn:aws:logs:*:*:/aws/lambda/AmazonSecurityLake*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:ResourceAccount": "${aws:PrincipalAccount}"
                }
            }
        },
        {
            "Sid": "AllowGlueManage",
            "Effect": "Allow",
            "Action": [
                "glue:CreatePartition",
                "glue:BatchCreatePartition",
                "glue:GetTable",
                "glue:UpdateTable"
            ],
            "Resource": [
                "arn:aws:glue:*:*:table/amazon_security_lake_glue_db*/*",
                "arn:aws:glue:*:*:database/amazon_security_lake_glue_db*",
                "arn:aws:glue:*:*:catalog"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:ResourceAccount": "${aws:PrincipalAccount}"
                }
            }
        },
        {
            "Sid": "AllowToReadFromSqs",
            "Effect": "Allow",
            "Action": [
                "sqs:ReceiveMessage",
                "sqs:DeleteMessage",
                "sqs:GetQueueAttributes"
            ],
            "Resource": [
                "arn:aws:sqs:*:*:AmazonSecurityLake*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:ResourceAccount": "${aws:PrincipalAccount}"
                }
            }
        },
        {
            "Sid": "AllowMetaDataReadWrite",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:PutObject",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::aws-security-data-lake*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:ResourceAccount": "${aws:PrincipalAccount}"
                }
            }
        },
        {
            "Sid": "AllowMetaDataCleanup",
            "Effect": "Allow",
            "Action": [
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::aws-security-data-lake*/metadata/*.avro",
                "arn:aws:s3:::aws-security-data-lake*/metadata/*.metadata.json"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:ResourceAccount": "${aws:PrincipalAccount}"
                }
            }
        }
    ]
}

まとめ

  • 再有効化する際には既存のリソース、制限に気をつけよう
    • Security Lake はサービスを無効化した時にリソースが削除されないため(Glue Database など)
    • SCP による制限も追加で意識しよう
  • 再有効化エラーはCloudTrail に情報が残っていない場合があるため注意
    • 何か問題が起きた時はトラブルシューティングは Security Lake コンソールの 問題 を確認することから始めるべし
  • サービスリンクロールへの切り替えもやっておこう

最後に

以上、「Amazon Security Lake を再有効化する時注意したいことをまとめてみた」でした。

ニッチな内容ですが、この内容が役に立つ方がいたら幸いです。

最後まで読んでいただきありがとうございました。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.