使用对流层进行云的形成,如何在发射时添加"传播"标签

时间:2014-12-26 18:57:44

标签: python amazon-cloudformation aws-cli troposphere

我使用python模块对流层在我的云形成模板中生成标签。当前脚本生成:

       "Tags": [{"Key":"Name", "Value":"MyTagName"}, 
                {"Key":"Version", "Value":"123456"}]

但我需要生成

       "Tags":[{"Key":"Name", "Value":"MyTagName", "PropagateAtLaunch":"true"},
               {"Key":"Version", "Value":"123456", "PropagateAtLaunch":"true"}]

适用的脚本部分是:

    asg = autoscaling.AutoScalingGroup("MyASG")
    asg.Tags = Tags(Name = "MyTagName", Version = "123456")
    t.add_resource(asg)

2 个答案:

答案 0 :(得分:1)

---- 更新 ---

该功能已添加到主分支中,我只留下我之前的答案以供参考,以防您无法访问最新版本的对流层(即如果您没有克隆存储库)。您仍然可以在代码中使用短函数(第3个选项),但它仍然可以使用。

“标签”帮助类(来自对流层模块)无法生成ASG标签列表(键/值/传播),只能生成基本标签列表(键/值 - 例如EC2)。 您可以使用 troposphere.autoscaling.Tags 类来代替模仿最新的类,并添加“propagate”属性。

你可以像这样使用它:

    asg.Tags = autoscaling.Tags(Name = 'MyTagName', Version = '123456')

您的所有代码都会将PropagateAtLaunch属性设置为“true”。如果你想要一个不同的PropagateAtLaunch属性,就这样写:

    asg.Tags = autoscaling.Tags(Name = 'MyTagName', Version = '123456', 
      NonPropagatedTag=('fail',False))

NonPropagatedTag标签不会传播(惊喜!)并且值为'fail'。


上一个回答:

您不能使用“Tags”辅助类(来自对流层模块)来生成ASG标记列表(键/值/传播),只能使用基本标记列表(键/值)。快速查看源代码将显示原因(https://github.com/cloudtools/troposphere/blob/master/troposphere/init.py

它为您提供了三个选项:

  • 长&困难的方式:ASG标签列表(在对流层)只是一个包含三个键的dicts的python列表:Name,Value和PropagateAtLaunch。所以你的代码看起来像:

    asg.Tags= [{'Key':'Name','Value':'MyTagName','PropagateAtLaunch':'true'}, 
      {'Key':'Version','Value':'123456','PropagateAtLaunch':'true'}]
    

    是的,丑陋。

  • 只是缩短了一点:你可以使用autoscaling.Tag助手类而不是dicts,它有3个参数:标签键,标签值,传播。你必须编码:

    asg.Tags= [autoscaling.Tag('Name','MyTagName','true'),
      autoscaling.Tag('Version','123456','true')]
    

    如果你没有很多标签,或者只是在一个地方使用它,那没关系。但是标签助手类非常好......

  • 使用另一个辅助类来生成ASG特定标记列表。我刚刚在troposphere github存储库上做了一个pull请求,只需添加一点:

    class TagsASG(troposphere.AWSHelperFn):
        defaultPropagateAtLaunch=True
        manyType=[type([]), type(())]
    
        def __init__(self, **kwargs):
            self.tags = []
            for k, v in sorted(kwargs.iteritems()):
                if type(v) in self.manyType:
                  propagate=str(v[1]).lower()
                  v=v[0]
                else:
                  propagate=str(self.defaultPropagateAtLaunch).lower()
                self.tags.append({
                    'Key': k,
                    'Value': v,
                    'PropagateAtLaunch':propagate,
                })
    
        def JSONrepr(self):
            return self.tags
    

现在,您可以像这样使用它:

    asg.Tags = TagsASG(Name = 'MyTagName', Version = '123456')

您的所有代码都会将PropagateAtLaunch属性设置为“true”。如果你想要一个不同的PropagateAtLaunch属性,就这样写:

    asg.Tags = TagsASG(Name = 'MyTagName', Version = '123456', 
      NonPropagatedTag=('fail',False))

NonPropagatedTag标签不会传播(惊喜!)并且值为'fail'。

答案 1 :(得分:0)

我为此专门开发了一个项目。 https://github.com/MacHu-GWU/troposphere_mate-project#batch-tagging

的想法是递归地迭代资源对象,并尝试查找是否有 Tags 属性。并尝试对其应用标签键值对

假设您有一个VPC,一个子网,一个SecurityGroup

from troposphere_mate import Template, ec2, Tags,
from functools import partial

tpl = Template()

my_vpc = ec2.VPC(
    "MyVPC",
    template=tpl,
    CidrBlock="10.0.0.0/16",
    Tags=Tags(
        Creator="Alice"
    )
)
my_sg = ec2.SecurityGroup(
    "MySG",
    template=tpl,
    GroupDescription="My",
    GroupName="MySG",
    VpcId=Ref(my_vpc),
)
my_subnet = ec2.Subnet(
    "MySubnet",
    template=tpl,
    CidrBlock="10.0.1.0/24",
    VpcId=Ref(my_vpc),
)

然后定义一些通用标签,比如项目名称和阶段。而且,您可以添加自定义逻辑来根据资源类型动态创建标签,而只需调用Template.update_tags()方法即可。当然,您可以选择是否覆盖现有的硬编码标签。

# custom logic to create tag if it is a SecurityGroup
def get_name(resource, project):
    if resource.resource_type == "AWS::EC2::SecurityGroup":
        return "{}/sg/{}".format(project, resource.GroupName)

common_tags = dict(
    Project="my-project",
    Name=functools.partial(get_name, project="my-project"),
    Creator="Bob",
)

# apply common tags to all aws resource
tpl.update_tags(common_tags, overwrite=False)

看,它有效。

assert tags_list_to_dct(tpl.to_dict()["Resources"]["MyVPC"]["Properties"]["Tags"]) == dict(
    Project="my-project",
    Creator="Alice",
)
assert tags_list_to_dct(tpl.to_dict()["Resources"]["MySG"]["Properties"]["Tags"]) == dict(
    Project="my-project",
    Name="my-project/sg/MySG",
    Creator="Bob",
)

如果您喜欢这个项目,很高兴您可以给它加注星标:)https://github.com/MacHu-GWU/troposphere_mate-project#batch-tagging