Creates a Lambda function that writes to an S3 bucket during deployment.
AWSTemplateFormatVersion: 2010-09-09
Transform: 'AWS::Serverless-2016-10-31'
Description: A CloudFormation Custom Resource and a Lambda function to create an S3 object. (uksb-1tthgi812) (tag:cfn-custom-resource-s3-create)
# Global values that are applied to all applicable resources in this template
Globals:
Function:
CodeUri: ./src
Runtime: nodejs20.x
MemorySize: 128
Timeout: 15
Parameters:
ExistingS3Bucket:
Description: Name of an existing S3 bucket, or leave blank to create a new S3 bucket.
Type: String
MaxLength: 63
AllowedPattern: ^[a-z0-9.-]*$
Conditions:
CreateS3Bucket: !Equals [!Ref ExistingS3Bucket, ""]
Resources:
# If an exsiting S3 bucket name was not provided a new S3 bucket will be created
NewS3Bucket:
Type: 'AWS::S3::Bucket'
Condition: CreateS3Bucket
Properties:
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
# Lambda function to create an S3 object:
# This function would normally be deployed in a separate CloudFormation template.
# Then the function Arn would be referenced in other CloudFormation templates
# as a custom resource whenever an S3 object needs to be created.
FunctionS3Create:
Type: 'AWS::Serverless::Function'
Properties:
Handler: app.handler
Policies:
- S3CrudPolicy:
BucketName: !If [CreateS3Bucket, !Ref NewS3Bucket, !Ref ExistingS3Bucket]
# Example use of a CloudFormation custom resource:
# This custom resource can be used in other CloudFormation templates after the function above is deployed.
# If the CloudFormation stack is deleted, the S3 object will also be deleted.
# More info: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cfn-customresource.html
CustomResourceS3Create:
Type: 'Custom::S3Create'
Properties:
# If this custom resource is used in another CloudFormation template:
# Modify the ServiceToken property to retrieve the function Arn from CloudFormation Exports.
# For example: ServiceToken: !ImportValue function-s3-create
# However for this example, the function Arn is retrieved from a resource within this template:
ServiceToken: !GetAtt FunctionS3Create.Arn
# Define the resource properties that the function requires to create the S3 object:
# The Body property defines the content of the S3 object.
# In this example, an html document named "index.html" is being created.
# The html document includes a variable value that equals the S3 bucket name.
Bucket: !If [CreateS3Bucket, !Ref NewS3Bucket, !Ref ExistingS3Bucket]
Key: index.html
ContentType: text/html # application/json, text/css, text/html, text/plain
Body: !Sub
- |
Index
This object was created by using a CloudFormation custom resource.
The S3 bucket name is: ${varS3Bucket}
- varS3Bucket: !If [CreateS3Bucket, !Ref NewS3Bucket, !Ref ExistingS3Bucket]
Outputs:
S3BucketName:
Description: Name of the S3 bucket
Value: !If [CreateS3Bucket, !Ref NewS3Bucket, !Ref ExistingS3Bucket]
FunctionS3CreateArn:
Description: Arn of the Lambda function to create an S3 object
Value: !GetAtt FunctionS3Create.Arn
# The name used to reference the function Arn in CloudFormation Exports:
Export:
Name: function-s3-create
ResponseObjectKey:
Description: ObjectKey from Lambda function response
Value: !GetAtt CustomResourceS3Create.ObjectKey
Visit the GitHub repo for this pattern.
git clone https://github.com/aws-samples/serverless-patterns/ cd serverless-patterns/cfn-custom-resource-s3-create
sam deploy --guided
sam delete --stack-name STACK_NAME
.aws cloudformation list-stacks --query "StackSummaries[?contains(StackName,'STACK_NAME')].StackStatus"