cloudtools / troposphere

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

The Tags parameter definition is inconsistent across resources. #2034

Closed szymic1 closed 1 year ago

szymic1 commented 2 years ago

For example in elasticache.ReplicationGroup we have to define Tag as: Tags=Tags({'Creator': creator_name}, {'Environment': env_type}) but in ec2.SecurityGroup we have to define as follow:

    Tags=[Tag("Creator", creator_name),
          Tag("Environment", env_type)])
markpeek commented 2 years ago

The early implementation of Tags in troposphere objects was a list of Tags. To reduce the amount of wrapping items with Tag() we switched over to the Tags() object. For backwards compatibility, in a small subset of troposphere, some Tags properties will accept either a list of Tag objects or a Tags object. But all newer troposphere resources only accept the Tags variant. For your example above, ec2.SecurityGroup does support the Tags variant as well:

$ cat tag.py
from troposphere import Tags
from troposphere.ec2 import SecurityGroup

sg = SecurityGroup(
    "sg",
    GroupDescription="blank",
    Tags=Tags({'Creator': "name"}, {'Environment': "env"}),
)
print(sg.to_dict())

$ python tag.py
{'Properties': {'GroupDescription': 'blank', 'Tags': [{'Key': 'Creator', 'Value': 'name'}, {'Key': 'Environment', 'Value': 'env'}]}, 'Type': 'AWS::EC2::SecurityGroup'}

You should be able to standardize on the Tags() variant across these implementations.

Having said the above, there are other variants of Tags within CloudFormation and, thus, troposphere. There is a json variant which takes a dict and AutoScaling has a special implementation due to the addition of PropagateAtLaunch.

JohnPreston commented 2 years ago

To make matters worse some AWS resources tags are a mapping, not a list, or not called Tags either

szymic1 commented 2 years ago

To be honest for VPCEndpoint we can add tags using CLI but you cannot add using CF :)