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

Posted

技术标签:

【中文标题】AWS Cloudformation:有条件地创建资源的属性【英文标题】:AWS Cloudformation: Conditionally create properties of resources 【发布时间】:2019-05-07 00:06:07 【问题描述】:

我知道可以通过使用Conditions 有条件地(还有什么?)创建资源。

我正在尝试找到一种方法来有条件地创建资源属性;

在我的情况下,我在默认公共 ip 分配 = false 的子网中创建多个 EC2 实例。

有时出于调试目的,我希望我的实例获得公共 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,这对您的情况有用吗? 【参考方案1】:

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

从AWS docs,您可以使用 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 属性。

【讨论】:

这个“AWS::NoValue”是我几个月来一直在寻找的,用于基于参数为 CodeBuild 项目启用 webhook。只是我,还是没有足够的记录?谢谢大佬! 太棒了!我想我以前试过这个,但是我把 !If 语句放在 NetworkInterfaces 上面而不是在它里面,我没有成功。我很高兴我的同事给我发了一个链接!【参考方案2】:

也许我理解错了,但这听起来像是一个参数用例,而不是一个条件用例。我这么说是因为你没有说在什么条件下你想要一个公共 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

【讨论】:

以上是关于AWS Cloudformation:有条件地创建资源的属性的主要内容,如果未能解决你的问题,请参考以下文章

AWS学习笔记--利用CloudFormation管理AWS资源

AWS CloudFormation 创建堆栈与部署

AWS CloudFormation 可以调用 AWS API 吗?

如何在 aws Secrets Manager 服务中管理 aws RDS(由 cloudformation 创建)的主用户凭证?

AWS Cloudformation - Stack drift

AWS Cloudformation 将 API 密钥链接到 API 网关