如何使用 Cloudformation 模板中的参数获取 AWS 安全组的 CIDR IP 列表

How to get the list of CIDR IPs for AWS Security Group using parameters in Cloudformation template

我正在使用以下代码段根据输入参数创建具有 CIDR IP 的安全组。如果输入参数中有 1 个 CIDR IP,则创建安全组时应仅附加 1 个出口,但如果输入参数中有 2 个 CIDR IP,则创建安全组时应附加 2 个出口。我收到 cfn-lint 错误 [cfn-lint] E0000:found unexpected ':' 在 AWS::NoValue。

如果我用引号(单引号或双引号)将其括起来,例如“AWS::NoValue”,我会收到以下 lint 错误

[cfn-lint] E2523:Only one of [CidrIp, CidrIpv6, DestinationSecurityGroupId, DestinationPrefixListId] should be specified when condition "CIDRIP1Provided" is False at Resources/MySecurityGroup/Properties/SecurityGroupEgress/0

还有其他方法可以实现我的目标吗?提前致谢

Parameters:
  VPCid:
    Default: /app/network/VPCId
    Type: 'AWS::SSM::Parameter::Value<String>'
  CIDRIPs:
    Description: Comma-delimited list of CIDR IPs in the format "CIDRIP1,CIDRIP2". Limit of 2
    Type: CommaDelimitedList
Conditions:
  CIDRIP1Provided: 
    Fn::Not: 
      - Fn::Equals:
        - Fn::Select:
          - 0
          - Fn::Split:
            - ","
            - Fn::Sub:
              - "${IP},,"
              - IP: !Join [',', !Ref CIDRIPs] 
        - ""
  CIDRIP2Provided: 
    Fn::Not: 
      - Fn::Equals:
        - Fn::Select:
          - 1
          - Fn::Split:
            - ","
            - Fn::Sub:
              - "${IP},,"
              - IP: !Join [',', !Ref CIDRIPs] 
        - ""
Resources:
          
  MySecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: My Security Group
      GroupName: my-security-group
      VpcId: !Ref 'VPCid'
      SecurityGroupEgress:
      - IpProtocol: tcp
        ToPort: 443
        FromPort: 443
        CidrIp: !If [CIDRIP1Provided, !Select [ 0, !Ref CIDRIPs ], !Ref AWS::NoValue]
      - IpProtocol: tcp
        ToPort: 443
        FromPort: 443
        CidrIp: !If [CIDRIP2Provided, !Select [ 1, !Ref CIDRIPs ], !Ref AWS::NoValue]

这将通过对资源项目使用 Condition: ConditionItem 来实现。

Resources:
  MySecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref VPCid
      GroupDescription: Sample source security group
  OutboundRule1:
    Condition: CIDRIP1Provided
    Type: AWS::EC2::SecurityGroupEgress
    Properties:
      IpProtocol: tcp
      FromPort: 443
      ToPort: 443
      CidrIp: !Select [0, !Ref CIDRIPs]
      GroupId:
        Fn::GetAtt:
          - MySecurityGroup
          - GroupId
  OutboundRule2:
    Condition: CIDRIP2Provided
    Type: AWS::EC2::SecurityGroupEgress
    Properties:
      IpProtocol: tcp
      FromPort: 443
      ToPort: 443
      CidrIp: !Select [1, !Ref CIDRIPs]
      GroupId:
        Fn::GetAtt:
          - MySecurityGroup
          - GroupId

请注意,如果 rule1 和 rule2 都不匹配,sg 会创建允许所有流量的默认出站规则,这似乎没有被 Cfn 删除。要取消此默认规则,创建条件评估 1 和 2 失败 (isDummyRequired) 并像这样设置虚拟 ip。

  DummyRule:
    Condition: isDummyRequired
    Type: AWS::EC2::SecurityGroupEgress
    Properties:
      IpProtocol: tcp
      FromPort: 65000
      ToPort: 65000
      CidrIp: '255.255.255.255/32'
      GroupId:
        Fn::GetAtt:
          - MySecurityGroup
          - GroupId