如何用AWS Lambda为所有新建S3桶自动附加指定权限策略?
Got it, let's break this down into actionable steps to get your Lambda function up and running. You already have a solid policy template—we just need to wire up the trigger, give Lambda the right permissions, and write the code to inject the bucket name and apply the policy.
Step 1: Set Up the Event Trigger (EventBridge + CloudTrail)
S3 doesn't natively send events for bucket creation, so we'll use CloudTrail to capture the CreateBucket action, then EventBridge to trigger your Lambda function when that event happens.
- First, make sure CloudTrail is enabled in your AWS account/region:
- Go to the CloudTrail console, create a trail (or use an existing one) that includes S3 events. Ensure "Log S3 bucket-level actions" is enabled.
- Next, create an EventBridge rule to match the
CreateBucketevent:- Go to the EventBridge console, create a new rule.
- For "Event source", select "AWS events or EventBridge partner events".
- Use this event pattern to target S3 bucket creation:
{ "source": ["aws.s3"], "detail-type": ["AWS API Call via CloudTrail"], "detail": { "eventName": ["CreateBucket"], "eventSource": ["s3.amazonaws.com"] } } - Set the target to your Lambda function (we'll create the function next).
Step 2: Configure Lambda IAM Permissions
Your Lambda function needs permissions to apply bucket policies to S3 buckets, plus basic permissions to run and log. Create an IAM role with these policies:
Basic Lambda Execution Policy (for logging)
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:*:*:*" } ] }
S3 Bucket Policy Permission
Add this statement to the role to let Lambda apply policies to all buckets (restrict the resource if needed for tighter security):
{ "Effect": "Allow", "Action": "s3:PutBucketPolicy", "Resource": "arn:aws:s3:::*" }
Step 3: Write the Lambda Code
We'll use Python (the most common Lambda runtime) to extract the bucket name from the EventBridge event, inject it into your policy template, and apply it to the new bucket.
Here's the full code:
import boto3 import json s3 = boto3.client('s3') def lambda_handler(event, context): # Extract the bucket name from the CloudTrail event try: bucket_name = event['detail']['requestParameters']['bucketName'] print(f"Processing new bucket: {bucket_name}") except KeyError as e: print(f"Failed to extract bucket name: {str(e)}") return { 'statusCode': 400, 'body': json.dumps('Invalid event format') } # Your policy template—replace the bucket name placeholders with the actual bucket name policy_template = { "Version": "2008-10-17", "Statement": [ { "Sid": "DenyS3PublicObjectACL", "Effect": "Deny", "Principal": "*", "Action": "s3:PutObjectAcl", "Resource": [ f"arn:aws:s3:::{bucket_name}/*", f"arn:aws:s3:::{bucket_name}" ], "Condition": { "StringEqualsIgnoreCaseIfExists": { "s3:x-amz-acl": [ "public-read", "public-read-write", "authenticated-read" ] } } } ] } # Convert policy to JSON string policy_json = json.dumps(policy_template) # Apply the policy to the bucket try: s3.put_bucket_policy( Bucket=bucket_name, Policy=policy_json ) print(f"Successfully applied policy to bucket: {bucket_name}") return { 'statusCode': 200, 'body': json.dumps(f"Policy applied to {bucket_name}") } except Exception as e: print(f"Failed to apply policy: {str(e)}") return { 'statusCode': 500, 'body': json.dumps(f"Error applying policy: {str(e)}") }
Step 4: Test and Validate
- Deploy the Lambda function with the code above, using the IAM role you created.
- Create a new S3 bucket in your account/region.
- Check the Lambda function's CloudWatch Logs to confirm it ran successfully.
- Go to the new bucket's "Permissions" tab, check the "Bucket policy" section—you should see your policy applied with the correct bucket ARNs.
Key Notes
- Cross-Region Considerations: If you create buckets in multiple regions, ensure your CloudTrail trail is configured to log events from all regions, and your EventBridge rule is set to the "us-east-1" region (since S3 bucket creation events are global and sent to us-east-1 by default).
- Security Best Practices: If you don't need to apply this policy to every bucket, modify the EventBridge rule to filter specific bucket names, or restrict the Lambda's S3 permission to specific bucket ARNs.
内容的提问来源于stack exchange,提问作者Sam Pitman

