10

How do I upload a file into my AWS S3 bucket CloudFormation template?

AWSTemplateFormatVersion: '2010-09-09'
Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      AccessControl: PublicRead
      BucketName: s3bucketuser
      VersioningConfiguration:
        Status: Enabled
5

You can't upload files through CloudFormation, that's not supported because CFN doesn't have access to your local filesystem.

What I usually do:

  • Call cloudformation task from Ansible
  • CFN creates the bucket and in the Outputs exports the bucket name
  • Ansible uploads the files using s3_sync in the next task once the CFN one is done.

Hope that helps :)

2
  • 1
    See other answer, it's perfectly doable. Also one can define a Lambda function inside the template which can be executed and do whatever you want. Using custom resources anyhow. Also see aws.amazon.com/premiumsupport/knowledge-center/…
    – scravy
    Nov 17 '20 at 4:22
  • I use custom lambda resource too for anything outside of CF capabilities. No dependency on any 3rd party this way. Oct 3 at 9:43
15

AWS provides a sample Macro that may help, depending on your use case: https://github.com/awslabs/aws-cloudformation-templates/tree/a11722d/aws/services/CloudFormation/MacrosExamples/S3Objects.

  1. Create a separate CloudFormation stack with macro.template. This creates the Transform Macro "S3Objects" that will then be available to any other stack in the region. The README.md explains how to "package" the macro template prior to adding to CloudFormation (it will need to include a separate source file for a Lambda function).
  2. The file example.template provides sample usage. Note the top-level Transform section that refers to S3Objects, which allows the use of Type: AWS::S3::Object.

In the provided example, the Body property allows for entering text directly in the YAML or JSON template. To expand on that, one can use Fn::Sub to create a file with parameters or properties from other resources:

---
AWSTemplateFormatVersion: '2010-09-09'

Transform: S3Objects

Parameters:
  ANameField:
    Type: String

Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      AccessControl: PublicRead
      BucketName: s3bucketuser
      VersioningConfiguration:
        Status: Enabled

  S3Object:
    Type: AWS::S3::Object
    Properties:
      Target:
        Bucket: !Ref S3Bucket
        Key: README.md
        ContentType: text/markdown
      Body: !Sub |
        # My text file

        This is my text file for ${ANameField}.
        The region is ${AWS::Region} and my account ID is ${AWS::AccountId}.
        This file is in the ${S3Bucket} bucket. The bucket ARN is ${S3Bucket.Arn},
        and its website endpoint is ${S3Bucket.WebsiteURL}
1
  • 1
    Weird that this is not a native type. Config files are very easily populated with the template's data.
    – Manatax
    Sep 4 '19 at 3:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.