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

Time:03-29

I am using the below snippet for creating security group with CIDR IPs based on the input parameter. if the input parameter has 1 CIDR IP in it then the security group should be created with only 1 egress attached to it but if the input parameter has 2 CIDR IPs in it the security group should be created with 2 egress attached to it. I am getting cfn-lint error [cfn-lint] E0000:found unexpected ':' at AWS::NoValue.

If I wrap it around quotes(single or double) like "AWS::NoValue", I get the following lint error

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

Is there any other way to achieve my goal? Thanks in advance

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]

CodePudding user response:

The code that you provided is fine and there is nothing wrong with it. Your error must be due to some code which you are not showing or due to the fact that your actual template is different that what you posted in the question.

CodePudding user response:

It's complicated, but AWS doc says:

AWS::NoValue

Removes the corresponding resource property when specified as a return value in the Fn::If intrinsic function.

This is for removing properties. In your case, trying to remove values.

Using Type: AWS::EC2::SecurityGroupEgress would be no lint error.

Resources:
  MySecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: My Security Group
      GroupName: my-security-group
      VpcId: !Ref 'VPCid'
  MySecurityGroupEgress:
    Type: AWS::EC2::SecurityGroupEgress
    Properties:
      IpProtocol: tcp
      ToPort: 443
      FromPort: 443
      CidrIp:
        If [CIDRIP1Provided, !Select [0, !Ref CIDRIPs], !Ref AWS::NoValue]
      GroupId:
        Fn::GetAtt:
          - MySecurityGroup
          - GroupId

The above works for 1 IP. It might be complicated if CidrIp holds 2 IPs, need to use nested if statement.

(Not tested)

      CidrIp:
        !If [
          CIDRIP1Provided,
          !If [CIDRIP2Provided, !Ref CIDRIPs, !Select [0, !Ref CIDRIPs]],
          !If [CIDRIP2Provided, !Select [1, !Ref CIDRIPs], !Ref AWS::NoValue],
        ]
  • Related