Reputation: 87
I have a custom CloudFormation resource that creates an S3 bucket if it doesn't exist. Here is the code:
S3CustomResource:
Type: Custom::S3CustomResource
Properties:
ServiceToken: !GetAtt AWSLambdaFunction.Arn
the_bucket: !Ref S3BucketName
AWSLambdaFunction:
Type: "AWS::Lambda::Function"
Properties:
Description: "Work with S3 Buckets!"
FunctionName: !Sub '${AWS::StackName}-${AWS::Region}-lambda'
Handler: index.handler
Role: !GetAtt AWSLambdaExecutionRole.Arn
Timeout: 360
Runtime: python3.6
Code:
ZipFile: |
import boto3
import cfnresponse
def handler(event, context):
# Init ...
the_event = event['RequestType']
print("The event is: ", str(the_event))
response_data = {}
s_3 = boto3.client('s3')
# Retrieve parameters
the_bucket = event['ResourceProperties']['the_bucket']
try:
if the_event in ('Create', 'Update'):
print("Requested to create S3 bucket: ", str(the_bucket))
for bucket_name in the_bucket:
print("Creating: ", str(bucket_name))
s_3.create_bucket(Bucket=the_bucket)
elif the_event == 'Delete':
print("Whoopsie, this bucket has some seriuos information in it - let's not delete it")
# Everything OK... send the signal back
print("Execution succesfull!")
cfnresponse.send(event,
context,
cfnresponse.SUCCESS,
response_data)
except Exception as e:
print("Execution failed...")
print(str(e))
response_data['Data'] = str(e)
cfnresponse.send(event,
context,
cfnresponse.FAILED,
response_data)
I would like to reference the ARN of this bucket in my other CloudFormation resources. The S3CustomResource resource only shows the PhysicalID of the CloudWatch Log name. How can I get CloudFormation to show the bucket ARN as a PhysicalID in the Resource tab?
Upvotes: 3
Views: 472
Reputation: 238747
Bucket ARNs have fixed format, so you just use that in your code (assuming aws
partition):
bucket_arn = "arn:aws:s3:::" + bucket_name
and you return them in response_data
. Below is fully working, amended code that can create multiple buckets using custom resource and returns their ARN to cloudformation for future use. The code has a lot of room for improvement, e.g. return arns of buckets if they exist, check if buckets were correctly created and more. Thus its not ideal code, but it works and shows the key elements:
Parameters:
S3BucketName:
Type: CommaDelimitedList
Default: test-bucket-312ddfff,test-bucket3333-312ddfff
Resources:
S3CustomResource:
Type: Custom::S3CustomResource
Properties:
ServiceToken: !GetAtt AWSLambdaFunction.Arn
the_bucket: !Ref S3BucketName
AWSLambdaFunction:
Type: "AWS::Lambda::Function"
Properties:
Description: "Work with S3 Buckets!"
FunctionName: !Sub '${AWS::StackName}-${AWS::Region}-lambda'
Handler: index.handler
Role: !GetAtt AWSLambdaExecutionRole.Arn
Timeout: 360
Runtime: python3.6
Code:
ZipFile: |
import boto3
import cfnresponse
s_3 = boto3.client('s3')
s3_waiter = s_3.get_waiter('bucket_exists')
def handler(event, context):
# Init ...
print(event)
the_event = event['RequestType']
print("The event is: ", str(the_event))
response_data = {}
# Retrieve parameters
the_bucket = event['ResourceProperties']['the_bucket']
print("the_bucket", the_bucket)
bucket_arns = []
try:
if the_event in ('Create', 'Update'):
print("Requested to create S3 bucket: ",
str(the_bucket))
for bucket_name in the_bucket:
print("Creating: ", str(bucket_name))
s_3.create_bucket(Bucket=bucket_name)
s3_waiter.wait(Bucket=bucket_name)
bucket_arn = "arn:aws:s3:::" + bucket_name
bucket_arns.append(bucket_arn)
elif the_event == 'Delete':
print("Whoopsie, this bucket has some"
"seriuos information in it "
"- let's not delete it")
cfnresponse.send(event, context,
cfnresponse.SUCCESS,
response_data)
return
# Everything OKindex... send the signal back
print("Execution successful!")
response_data['arns'] = ','.join(bucket_arns)
cfnresponse.send(event,
context,
cfnresponse.SUCCESS,
response_data)
except Exception as e:
print("Execution failed...")
print(str(e))
response_data['Data'] = str(e)
cfnresponse.send(event,
context,
cfnresponse.FAILED,
response_data)
AWSLambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal: {'Service': ['lambda.amazonaws.com']}
Action: ['sts:AssumeRole']
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AWSLambdaExecute
- arn:aws:iam::aws:policy/AmazonS3FullAccess
Path: '/'
Outputs:
BucketArns:
Value: !GetAtt S3CustomResource.arns
Upvotes: 2