AWS CloudFormation: 有条件地创建资源的属性

37

我知道可以通过使用条件来有条件地(还能怎么说呢?)创建资源。

然而,我正在尝试找到一种方法,以有条件地创建资源的属性;

在我的情况下,我正在创建一个子网中的多个EC2实例,并将默认的公共IP分配设置为false

然而有时出于调试目的,我希望我的实例获得公共IP。

现在我必须注释或取消注释下面的SG/Subnet和NetworkInterfaces属性(它们不能同时存在)

  myEC2:
    Type: AWS::EC2::Instance
    Metadata:
      Comment: My EC2 Instance
      AWS::CloudFormation::Init:
        config:
          commands:
            01_provision:
              command:
                !Sub |
                  sed -i "s/somestring/${somevar}/" /some/path/
    CreationPolicy:
      ResourceSignal:
        Timeout: PT4M
    Properties:
      ImageId: !FindInMap [ MyAamiMap, 'myami', amiid ]
      InstanceType: "t2.2xlarge"
      # SubnetId: !Ref SBNDemo1
      # SecurityGroupIds: [!Ref SGInternalDemo]
      NetworkInterfaces:
        - AssociatePublicIpAddress: "true"
          DeviceIndex: "0"
          GroupSet:
            - Ref: "SGInternalDemo"
          SubnetId:
            Ref: "SBNDemo1"
      UserData:
        "Fn::Base64":
          !Sub |
            #!/bin/bash -xe
            # Start cfn-init
            /usr/local/bin/cfn-init -s ${AWS::StackId} -r myEC2 --region ${AWS::Region} || echo 'Failed to run cfn-init'
            # All done so signal success
            /usr/local/bin/cfn-signal -e $? --stack ${AWS::StackId} --resource myEC2 --region ${AWS::Region}

有什么建议吗?


你知道现在可以在云形成中使用AWS Lambda吗?这对你有用吗? - varnit
2个回答

85

可能有点晚了,但我最近有同样的问题。

根据AWS文档,您可以使用Fn :: If相应地设置属性。

模板将如下所示:

Properties:
  ImageId: !FindInMap [ MyAamiMap, 'myami', amiid ]
  InstanceType: "t2.2xlarge"
  # SubnetId: !Ref SBNDemo1
  # SecurityGroupIds: [!Ref SGInternalDemo]
  NetworkInterfaces:
    !If
    - YourCondition
    - 
      AssociatePublicIpAddress: "true"
      DeviceIndex: "0"
      GroupSet:
        - Ref: "SGInternalDemo"
      SubnetId:
        Ref: "SBNDemo1"
    - !Ref "AWS::NoValue"
AWS::NoValue 表示不会设置 NetworkInterfaces 属性。

2
这个 "AWS::NoValue" 是我寻找已久的,可基于参数条件启用 CodeBuild 项目 webhook 的方法。难道只有我觉得文档不够详细吗?谢谢! - Dalmiro Granas
太棒了!我想我之前尝试过这个,但是我把!If语句放在NetworkInterfaces上面而不是里面,所以没有成功。我很高兴我的同事给我发了这个链接! - Brandon
尝试使用无服务器 Lambda 函数,但没有成功。事件: !Ref "AWS::NoValue" - kumarahul

1
也许我误解了,但这似乎是一个参数用例,而不是条件用例。我这样说是因为你没有说明在什么条件下需要公共ip。只是“有时用于调试目的”。模板如何知道您正在调试?您必须使用参数告诉它。
请查看文档https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html 因此,您可以具有公共IP参数和子网ID参数,并在堆栈创建时传递您喜欢的内容。
条件有用的一种方式是创建一个调试参数,该参数将切换公共/私有IP和子网。这是你想到的吗?
要在属性上使用条件,请使用IF函数。

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-conditions.html

我建议在启动时将您的公共子网设置为提供公共IP,并确保您的私有子网不这样做。然后只需将子网作为参数传递即可。

https://docs.aws.amazon.com/vpc/latest/userguide/vpc-ip-addressing.html#subnet-public-ip


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接