Amazon Security Lake を再有効化する時、注意したいことをまとめてみた
あしざわです。
以前検証用途でSecurity Lake を有効化し、検証が終わったタイミングでサービスを停止したアカウントがあります。
このアカウントでまたSecurity Lake を検証する機会があり、再度有効化したところ、以下のようなエラーに遭遇しました。
有効化後に表示されたエラー
このエラーの調査・対応を行ったので、このブログではその過程と結果についてまとめます。
いきなりまとめ
- 再有効化する際には既存のリソース、制限に気をつけよう
- 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 のコンソールの 問題 というページを発見しました。
まさにこれでした。
問題のページ
それぞれ詳細を見ていくと:
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年の日付になっているリソースが存在しており、これが原因だと判断しました。
画像はバージニア北部リージョン
エラー対応
SCPでブロックされていたフランクフルト、大阪リージョンは本来有効化する必要がないリージョンだったため、東京・バージニア北部で再有効化を進めます。
手順は割愛しますが、東京・バージニア北部リージョンのGlue Databaseを削除しました。実データはS3 に保存されているので影響はないはずです。
削除後にもう一度、Security Lake を東京・バージニア北部リージョンで有効化したところ、うまくいきました。
Glue Database は同じ名称の新しいリソースが作成されていますね。
画像はバージニア北部リージョン
データレイクとなる新規のS3バケットが作成されており、新しい環境のログはこのバケットに集約されていました。
これで再有効化が完了しました。
(参考) 追加のエラー対応
話の本筋であるSecurity Lake の再有効化自体はここまでで完了していますが、その後コンソールを眺めていたところ、追加で対応が必要そうなエラーがいくつか見つかったので参考までに記載しておきます。
- リージョン制限SCP によって有効化していないリージョンのエラーが残っている
- Security Lake のサービスロール関連のエラー
1. リージョン制限SCP によって有効化していないリージョンのエラーが残っている
Security Lake コンソールのリージョンを確認すると、リージョン制限SCP の影響で有効化しなかった大阪・フランクフルトリージョンのところに「データレイクを作成できませんでした」と表示されたままになっていました。
おそらく、SCP の影響で実リソースの作成はできなかったが、Security Lake のコントロールプレーン上の設定情報だけが残ってしまっている状態だと理解しました。
この設定は不要なものなのでどちらも削除しました。
画像は大阪リージョンのみ
2. Security Lake のサービスロール関連のエラー
Security Lake コンソールの問題を確認すると、以下のエラーが出ていました。
Security Lake couldn't assume AWSServiceRoleForSecurityLakeResourceManagement for account 123456789012.
修復手順も記載がありました。
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
に切り替えるように求められていました。
以前はサービスアクセスロールを明示的に関連づける形式でしたが、直近の
引用:[アップデート]組織内のセキュリティデータをAWS上で一元管理できる!Amazon Security LakeがGA(一般利用開始)されましたより
本件は以下ドキュメントに
Security Lake コンソールの要約にサービスリンクロールを有効化
のリンクが表示されていました。
こちらをクリックして有効化を進めました。
更新はすぐ完了しました。
AmazonSecurityLakeMetaStoreManagerV2
とAWSServiceRoleForSecurityLakeResourceManagement
の差分を大まかに説明すると「既存の管理機能の強化と不要な権限の削除」で、よくあるサービスリンクロールの更新内容かと思います。
公式ドキュメントによると、サービスリンクロールに切り替えてできるようになることは以下のようです。
- 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 を再有効化する時注意したいことをまとめてみた」でした。
ニッチな内容ですが、この内容が役に立つ方がいたら幸いです。
最後まで読んでいただきありがとうございました。