由 createbucket 事件触发的此 lambda 函数出错

Getting an error with this lambda function that is triggered by the createbucket event

我设置了触发此自动策略生成脚本的 Cloudwatch 事件 CreateBucket

import json

s3 = boto3.client('s3')

def lambda_handler(event, context):

    # Get bucket name from the S3 event
    bucket_name = event['Records'][0]['s3']['bucket']['name']


    # Create a bucket policy
    bucket_policy =json.dumps({
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "MustBeEncryptedAtRest",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": [
                "arn:aws:s3:::{bucket_name}",
                "arn:aws:s3:::{bucket_name}/*"
            ],
            "Condition": {
                "StringNotEquals": {
                    "s3:x-amz-server-side-encryption": [
         
                        "aws:kms"
                    ]
                }
            }
        },
        {
            "Sid": "MustBeEncryptedInTransit",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::{bucket_name}",
                "arn:aws:s3:::{bucket_name}/*"
            ],
            "Condition": {
                "Bool": {
                    "aws:SecureTransport": "false"
                    }
            }
        } ] })


    # Set the new policy
    s3.put_bucket_policy(Bucket=bucket_name, Policy=bucket_policy)

此 lambda 函数应 运行 并将此策略放入创建的存储桶中。但是,它没有 运行 正确地通过 lambda 接口测试给我这个错误:

  "stackTrace": [
    [
      "/var/task/lambda_function.py",
      9,
      "lambda_handler",
      "bucket_name = event['Records'][0]['s3']['bucket']['name']"
    ]
  ],
  "errorType": "KeyError",
  "errorMessage": "'Records'"
}

我每次都需要将该策略附加到新存储桶,无论名称如何,但似乎无法弄清楚为什么它不起作用

编辑::

  File "/var/task/lambda_function.py", line 10, in lambda_handler
    bucket_name = event['details']['requestParameters']['bucketName']
KeyError: 'details'```

Is the new error i get.

您使用的结构对于事件不正确,事实上 AWS 在他们的文档中有 examples of events

真实事件如下图json

{
    "version": "0",
    "id": "36eb8523-97d0-4518-b33d-ee3579ff19f0",
    "detail-type": "AWS API Call via CloudTrail",
    "source": "aws.s3",
    "account": "123456789012",
    "time": "2016-02-20T01:09:13Z",
    "region": "us-east-1",
    "resources": [],
    "detail": {
        "eventVersion": "1.03",
        "userIdentity": {
            "type": "Root",
            "principalId": "123456789012",
            "arn": "arn:aws:iam::123456789012:root",
            "accountId": "123456789012",
            "sessionContext": {
                "attributes": {
                    "mfaAuthenticated": "false",
                    "creationDate": "2016-02-20T01:05:59Z"
                }
            }
        },
        "eventTime": "2016-02-20T01:09:13Z",
        "eventSource": "s3.amazonaws.com",
        "eventName": "CreateBucket",
        "awsRegion": "us-east-1",
        "sourceIPAddress": "100.100.100.100",
        "userAgent": "[S3Console/0.4]",
        "requestParameters": {
            "bucketName": "bucket-test-iad"
        },
        "responseElements": null,
        "requestID": "9D767BCC3B4E7487",
        "eventID": "24ba271e-d595-4e66-a7fd-9c16cbf8abae",
        "eventType": "AwsApiCall"
    }
}

要解决此错误,您的 Lambda 需要使用此结构来访问存储桶名称 属性。

为此更新您的代码以分配 bucket_name 如下所示的变量。

bucket_name = event['detail']['requestParameters']['bucketName']

以上事件作为测试事件。

工作函数如下

import json
import boto3

s3 = boto3.client('s3')

def lambda_handler(event, context):
    # Get bucket name from the S3 event
    print(event)

    bucket_name = event['detail']['requestParameters']['bucketName']

    # Create a bucket policy
    bucket_policy =json.dumps({
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "MustBeEncryptedAtRest",
                "Effect": "Deny",
                "Principal": "*",
                "Action": "s3:PutObject",
                "Resource": [
                    "arn:aws:s3:::{}".format(bucket_name),
                    "arn:aws:s3:::{}/*".format(bucket_name)
                ],
                "Condition": {
                    "StringNotEquals": {
                        "s3:x-amz-server-side-encryption": [
                            "AES256",
                            "aws:kms"
                        ]
                    }
                }
            },
            {
                "Sid": "MustBeEncryptedInTransit",
                "Effect": "Deny",
                "Principal": "*",
                "Action": "s3:*",
                "Resource": [
                    "arn:aws:s3:::{}".format(bucket_name),
                    "arn:aws:s3:::{}/*".format(bucket_name)
                ],
                "Condition": {
                    "Bool": {
                        "aws:SecureTransport": "false"
                        }
                }
            } ] })


    # Set the new policy
    s3.put_bucket_policy(Bucket=bucket_name, Policy=bucket_policy)