aws-cloudformation / rain

A development workflow tool for working with AWS CloudFormation.
Apache License 2.0
784 stars 70 forks source link

Package Command Ignores Code Paths #146

Closed null93 closed 1 year ago

null93 commented 1 year ago

Description

The rain pkg command does not do the same thing as the aws cloudformation package command because it ignores uploading assets for resources like AWS::Lambda::Function.

Example

Lets assume we have these files in our example:

.
├── lambda
│   └── autoscaling.py
├── src
│   └── test.yml

If we have a template file located at ./src/test.yml and it looks like this:

Resources:
  LifecycleFunction:
    Type: AWS::Lambda::Function
    Properties:
      Code: ./lambda/autoscaling.py
      Handler: autoscaling.handler
      Runtime: python3.8
      # ...

Running rain pkg ./src/test.yml will result in the following:

Resources:
  LifecycleFunction:
    Type: AWS::Lambda::Function
    Properties:
      Code: ./lambda/autoscaling.py
      Handler: autoscaling.handler
      Runtime: python3.8

      # ...

If we use aws cloudformation package --template-file ./src/test.yml --s3-bucket some-bucket-name instead, it produces the following:

Resources:
  LifecycleFunction:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        S3Bucket: some-bucket-name
        S3Key: 411a4f3ffde6297b302879f15d8c5942
      Handler: autoscaling.handler
      Runtime: python3.8

Similarly if the value of Resources.LifecycleFunction.Properties.Code is an S3 URI, the aws cloudformation package command parses it and breaks it down to an object containing the correct S3Bucket and S3Key keys as well.

Since the rain pkg command describes itself as:

Performs the same functions as "aws cloudformation package" but with added functionality`

I think this functionality is vital. Otherwise we are forced to package the template with rain's package command and then with aws' package command.

I am more than willing to try to dive into this and come up with a PR but I would like to know if this is actually an issue first. Maybe I am missing something? 😁

Caveats

The aws package command resolves relative paths based on PWD while rain resolves relative paths using the file's location.

Possible Solutions

  1. Use AWS SDK to package template after rain packages it?
  2. Add yet another rain-specific directive (!Rain::S3Code or something similar) that outputs an object instead of a URI.
ericzbeard commented 1 year ago

Here's an example of the way I normally do this with rain: https://github.com/aws-cloudformation/community-registry-extensions/blob/main/release/common.yml#L274

 Properties:
      Code: !Rain::S3 
        Path: webhook.py
        Zip: true
        BucketProperty: S3Bucket
        KeyProperty: S3Key

You can use a file or a directory for the path.

null93 commented 1 year ago

This should do the trick, thank you @ericzbeard! Sorry about the unnecessary issue.