cloudtools / troposphere

troposphere - Python library to create AWS CloudFormation descriptions
BSD 2-Clause "Simplified" License
4.93k stars 1.44k forks source link

Need AWS::Include #1282

Open blian7432 opened 5 years ago

blian7432 commented 5 years ago

Hi, Is possible to add AWS::Include?

I am using troposphere to build API solutions via serverless model. AWS::Include could help to import API doco into cloud formation script.

Reference AWS website: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/create-reusable-transform-function-snippets-and-add-to-your-template-with-aws-include-transform.html

markpeek commented 5 years ago

While there isn't explicit support for AWS::Include, there is support for setting the Transform. Let me know if this works for you or feel free to propose a different solution:

$ cat transform.py
from troposphere import Template

template = Template()
template.add_transform({
    "Name": "AWS::Include",
    "Parameters": {
        "Location": "s3:://somebucket/test.json",
     },
})

print template.to_yaml()
print
print template.to_json()
$ python transform.py
Resources: {}
Transform:
  Name: AWS::Include
  Parameters:
    Location: s3:://somebucket/test.json

{
    "Resources": {},
    "Transform": {
        "Name": "AWS::Include",
        "Parameters": {
            "Location": "s3:://somebucket/test.json"
        }
    }
}
blian7432 commented 5 years ago

Hi @maikelpenz Thank you for reply. I think I need the Intrinsic function Fn::Transform to implement this feature.

As the AWS doco mentioned: "To include a transform that is embedded within a section, use the Fn::Transform intrinsic function and the following syntax."

Is possible to add this function in?

Thank you

isuftin commented 5 years ago

I end up doing something like:

template.add_mapping('EnvironmentMapping',
                             {
                                 'Fn::Transform': {
                                     'Name': 'AWS::Include',
                                     'Parameters': {
                                         'Location':
                                         {
                                             'Fn::Sub': 's3://my-bucket/snippets/${Environment}.json'
                                         }
                                     }
                                 }
                             }
                             )

Which ends up looking like:

"Mappings": {
        "EnvironmentMapping": {
            "Fn::Transform": {
                "Name": "AWS::Include",
                "Parameters": {
                    "Location": {
                        "Fn::Sub": "s3://my-bucket/snippets/${Environment}.json"
                    }
                }
            }
        }
    }
pha6d commented 4 years ago

Another example with api gateway RestAPI. Usage of long_from is mandatory

    self.template.add_resource(RestApi(
        "APIG",
        Name='api',
        Body={
            'Fn::Transform': {
                'Name': 'AWS::Include',
                'Parameters': {
                    'Location':
                    {
                        'Fn::Sub': 's3://${ApigS3BucketParam}/${ApigS3KeyParam}'
                    }
                }
        }}
    ))
    self.template.to_yaml(long_form=True)