notaproatbash
notaproatbash

Reputation: 456

How to obtain bucket name from cloudwatch event?

I am writing a lambda function that is triggered by the cloudwatch event "createbucket" when trying to execute the lambda function which is;

import json

s3 = boto3.client('s3')

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

    bucket_name = event['detail']['requestParameters']['bucketName']
print(bucket_name) 

#        if record['eventName'] == "CreateBucket":
#            bucket =record['detail']['requestParameters']['bucketName']
#            print(bucket)
#            bucket_name =bucket
    # 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": [
                        "AES256",
                        "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)

I get an error that has to deal with

module initialization error: name 'bucket_name' is not defined any ideas? I must get the name of the bucket picked up by the create bucket event yet it never seems to pass through to the lambda function. Is there any way I can pass the name of the new bucket to the function?

EDIT The new error I get is

{
  "stackTrace": [
    [
      "/var/task/lambda_function.py",
      11,
      "lambda_handler",
      "bucket_name = event['detail']['requestParameters']['bucketName']"
    ]
  ],
  "errorType": "KeyError",
  "errorMessage": "'detail'"
}

CW Event config:

  "source": [
    "aws.s3"
  ],
  "detail-type": [
    "AWS API Call via CloudTrail"
  ],
  "detail": {
    "eventSource": [
      "s3.amazonaws.com"
    ],
    "eventName": [
      "CreateBucket"
    ]
  }
}

Upvotes: 0

Views: 1255

Answers (1)

Chris Williams
Chris Williams

Reputation: 35146

Edit

In addition to the indent issues, this appears to be the result of an error from using the default Lambda event template which does not match the syntax for CloudWatch events.

Original

This is an indentation issue. The s3.put_bucket_policy(Bucket=bucket_name, Policy=bucket_policy) function call would have been executed outside of the lambda_handler

I have fixed the indentation of the Lambda function below

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']
    print(bucket_name) 

#        if record['eventName'] == "CreateBucket":
#            bucket =record['detail']['requestParameters']['bucketName']
#            print(bucket)
#            bucket_name =bucket
    # 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)

Upvotes: 1

Related Questions