Jimson James
Jimson James

Reputation: 3317

Authenticated File Downloads to S3 Bucket with CloudFormation

Authenticated file download to EC2 instance is documented everywhere. But I want to download files to a bucket, not into and EC2 instance.

For eaxmple, lets say, I'm building a serverless static website and my index.html is available in a git repo or another bucket. How can I download that file into the newly created bucket in my cloudformation script?

Ref: Authenticated File Downloads with CloudFormation

Upvotes: 0

Views: 263

Answers (2)

Jimson James
Jimson James

Reputation: 3317

Well, stumbled on the answer while searching for something else very unrelated.

The answer is exactly what @jarmod suggested, my answer is a mere pointer to an existing cloudformation example by AWS implementing the same.

Quoting from the below link, so as not to put just a link in here,

Using this pattern, only one bucket needs to contain the Lambda zip file in advance, and no additional work is required to have newly launched Regions supported. Because of its flexibility, this is the preferred approach for most use cases. It does, however, require the most additional resources in the template: an inline Lambda function with the code to copy the zips, an associated Identity and Access Management (IAM) role, an Amazon S3 bucket, and the custom resource.

The following snippet creates a new Amazon S3 bucket in the AWS CloudFormation stack Region (LambdaZipsBucket) and then copies zip files (CopyZips.Properties.Objects) from a source bucket (CopyZips.Properties.SourceBucket) into the new bucket.

  Resources:
    LambdaZipsBucket:
        Type: AWS::S3::Bucket
    CopyZips:
        Type: Custom::CopyZips
        Properties:
          ServiceToken: !GetAtt 'CopyZipsFunction.Arn'
          DestBucket: !Ref 'LambdaZipsBucket'
          SourceBucket: !Ref 'QSS3BucketName'
          Prefix: !Ref 'QSS3KeyPrefix'
          Objects:
            - functions/packages/MyFunction/lambda.zip

Notice that Objects takes a list of paths, so that if you have multiple Lambda functions in your template, all the zips can be added to a single CopyZips resource.

Now to declare our Lambda function and point it to the newly created bucket.

When creating the function, we point MyFunction.Properties.Code.S3Bucket to LambdaZipsBucket.

  MyFunction:
    DependsOn: CopyZips
    Type: AWS::Lambda::Function
    Properties:
      Code:
        S3Bucket: !Ref 'LambdaZipsBucket'
        S3Key: !Sub '${QSS3KeyPrefix}functions/packages/MyFunction/lambda.zip'
      ...

Notice the DependsOn key pointing to our CopyZips custom resource. By default, AWS CloudFormation will attempt to launch resources that are not dependent on each other in parallel, so this is required to be sure that the zips have already been copied before our Lambda function is created.

To implement this in your own template you will need the CopyZips Lambda code and the related IAM role deployed as well. A full example implementation is available in the AWS Quick Start examples repository.

https://aws.amazon.com/blogs/infrastructure-and-automation/deploying-aws-lambda-functions-using-aws-cloudformation-the-portable-way/

Upvotes: 0

jarmod
jarmod

Reputation: 78693

You can do custom provisioning like this using a Custom Resource. This gives you the flexibility to run custom provisioning logic any time you create, update, or delete stacks.

Upvotes: 1

Related Questions