AWSTemplateFormatVersion: 2010-09-09 Transform: 'AWS::Serverless-2016-10-31' Description: A CloudFormation Custom Resource and a Lambda function to create an S3 object. # Global values that are applied to all applicable resources in this template Globals: Function: CodeUri: ./src Runtime: nodejs14.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 - | <!DOCTYPE html> <head> <title>Index</title> </head> <body> <p>This object was created by using a CloudFormation custom resource.</p> <p>The S3 bucket name is: ${varS3Bucket}</p> </body> </html> - 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