prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  E2004 issue with AWS::SSM::Parameter::Value<String> Parameters
  *cfn-lint version: (`cfn-lint --version`)*
  0.33.0
  
  *Description of issue.*
  When using an SSM paramter store lookup to get a CIDR Range to use in a Security group, cfn-lint raised an E2004 error.
  
  ```yaml
  Parameters:
    VpcID:
      Description: ID of VPC
      Type: "AWS::SSM::Parameter::Value<String>"
      Default: VpcId
      AllowedValues:
        - VpcId
  
    VpcCidrRange:
      Description: CIDR range of VPC
      Type: "AWS::SSM::Parameter::Value<String>"
      Default: VpcCIDRRange
      AllowedValues:
        - VpcCIDRRange
  
  Resources:
    SecurityGroup:
      Type: AWS::EC2::SecurityGroup
      Properties:
        GroupDescription: Allow HTTP egress
        VpcId: !Ref VpcID
        SecurityGroupEgress:
          - IpProtocol: tcp
            FromPort: 80
            ToPort: 80
            CidrIp: !Ref VpcCidrRange
  ```
  
  Error is `E2004 Cidr should be a Cidr Range based string for VpcCIDRRange product.template.yaml:9:3`
  
  If I'm not misunderstanding, cfn-lint seems to be complaining that the String `VpcCIDRRange` is not a valid CIDR, where in fact during runtime CloudFormation will lookup the value of `VpcCIDRRange` in SSM Parameter Store and use that instead.
  
  I guess a sensible approach here would be to disable E2004 for parameters that have a type of `AWS::SSM::Parameter::Value<String>` maybe?
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `src/cfnlint/rules/parameters/CidrAllowedValues.py`
  Content:
  ```
  1 """
  2 Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3 SPDX-License-Identifier: MIT-0
  4 """
  5 import re
  6 from cfnlint.rules import CloudFormationLintRule
  7 from cfnlint.rules import RuleMatch
  8 
  9 from cfnlint.helpers import REGEX_CIDR
  10 
  11 
  12 class CidrAllowedValues(CloudFormationLintRule):
  13     """CIDR checks"""
  14     id = 'E2004'
  15     shortdesc = 'CIDR Allowed Values should be a Cidr Range'
  16     description = 'Check if a parameter is being used as a CIDR. ' \
  17                   'If it is make sure allowed values are proper CIDRs'
  18     source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html'
  19     tags = ['parameters', 'cidr']
  20 
  21     def __init__(self):
  22         """Init"""
  23         super(CidrAllowedValues, self).__init__()
  24         resource_type_specs = [
  25             'AWS::EC2::ClientVpnAuthorizationRule',
  26             'AWS::EC2::ClientVpnEndpoint',
  27             'AWS::EC2::ClientVpnRoute',
  28             'AWS::EC2::NetworkAclEntry',
  29             'AWS::EC2::Route',
  30             'AWS::EC2::SecurityGroupEgress',
  31             'AWS::EC2::SecurityGroupIngress',
  32             'AWS::EC2::Subnet',
  33             'AWS::EC2::TransitGatewayRoute',
  34             'AWS::EC2::VPC',
  35             'AWS::EC2::VPCCidrBlock',
  36             'AWS::EC2::VPNConnectionRoute',
  37             'AWS::RDS::DBSecurityGroupIngress',
  38             'AWS::Redshift::ClusterSecurityGroupIngress',
  39         ]
  40 
  41         property_type_specs = [
  42             'AWS::EC2::SecurityGroup.Egress',
  43             'AWS::EC2::SecurityGroup.Ingress',
  44             'AWS::EC2::VPNConnection.VpnTunnelOptionsSpecification',
  45             'AWS::MediaLive::InputSecurityGroup.InputWhitelistRuleCidr',
  46             'AWS::RDS::DBSecurityGroup.Ingress',
  47             'AWS::SES::ReceiptFilter.IpFilter',
  48         ]
  49 
  50         for resource_type_spec in resource_type_specs:
  51             self.resource_property_types.append(resource_type_spec)
  52         for property_type_spec in property_type_specs:
  53             self.resource_sub_property_types.append(property_type_spec)
  54 
  55     # pylint: disable=W0613
  56     def check_cidr_ref(self, value, path, parameters, resources):
  57         matches = []
  58 
  59         if value in parameters:
  60             parameter = parameters.get(value, {})
  61             allowed_values = parameter.get('AllowedValues', None)
  62             if allowed_values:
  63                 for cidr in allowed_values:
  64                     if not re.match(REGEX_CIDR, cidr):
  65                         cidr_path = ['Parameters', value]
  66                         message = 'Cidr should be a Cidr Range based string for {0}'
  67                         matches.append(RuleMatch(cidr_path, message.format(cidr)))
  68 
  69         return matches
  70 
  71     def check(self, properties, resource_type, path, cfn):
  72         """Check itself"""
  73         matches = []
  74 
  75         for cidrString in [
  76                 'CIDRIP',
  77                 'Cidr',
  78                 'CidrBlock',
  79                 'CidrIp',
  80                 'ClientCidrBlock',
  81                 'DestinationCidrBlock',
  82                 'TargetNetworkCidr',
  83                 'TunnelInsideCidr',
  84         ]:
  85             matches.extend(
  86                 cfn.check_value(
  87                     properties, cidrString, path,
  88                     check_value=None, check_ref=self.check_cidr_ref,
  89                     check_find_in_map=None, check_split=None, check_join=None
  90                 )
  91             )
  92 
  93         return matches
  94 
  95     def match_resource_sub_properties(self, properties, property_type, path, cfn):
  96         """Match for sub properties"""
  97         matches = []
  98 
  99         matches.extend(self.check(properties, property_type, path, cfn))
  100 
  101         return matches
  102 
  103     def match_resource_properties(self, properties, resource_type, path, cfn):
  104         """Check CloudFormation Properties"""
  105         matches = []
  106 
  107         matches.extend(self.check(properties, resource_type, path, cfn))
  108 
  109         return matches
  110
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/src/cfnlint/rules/parameters/CidrAllowedValues.py b/src/cfnlint/rules/parameters/CidrAllowedValues.py
  --- a/src/cfnlint/rules/parameters/CidrAllowedValues.py
  +++ b/src/cfnlint/rules/parameters/CidrAllowedValues.py
  @@ -58,6 +58,11 @@
   
           if value in parameters:
               parameter = parameters.get(value, {})
  +            parameter_type = parameters.get(value, {}).get('Type', '')
  +            if parameter_type == 'AWS::SSM::Parameter::Value<String>':
  +                # If we are reading from the Parameter store we can no longer
  +                # check the value of the allowed values
  +                return matches
               allowed_values = parameter.get('AllowedValues', None)
               if allowed_values:
                   for cidr in allowed_values:
  
verification_info: {"golden_diff": "diff --git a/src/cfnlint/rules/parameters/CidrAllowedValues.py b/src/cfnlint/rules/parameters/CidrAllowedValues.py\n--- a/src/cfnlint/rules/parameters/CidrAllowedValues.py\n+++ b/src/cfnlint/rules/parameters/CidrAllowedValues.py\n@@ -58,6 +58,11 @@\n \n         if value in parameters:\n             parameter = parameters.get(value, {})\n+            parameter_type = parameters.get(value, {}).get('Type', '')\n+            if parameter_type == 'AWS::SSM::Parameter::Value<String>':\n+                # If we are reading from the Parameter store we can no longer\n+                # check the value of the allowed values\n+                return matches\n             allowed_values = parameter.get('AllowedValues', None)\n             if allowed_values:\n                 for cidr in allowed_values:\n", "issue": "E2004 issue with AWS::SSM::Parameter::Value<String> Parameters\n*cfn-lint version: (`cfn-lint --version`)*\r\n0.33.0\r\n\r\n*Description of issue.*\r\nWhen using an SSM paramter store lookup to get a CIDR Range to use in a Security group, cfn-lint raised an E2004 error.\r\n\r\n```yaml\r\nParameters:\r\n  VpcID:\r\n    Description: ID of VPC\r\n    Type: \"AWS::SSM::Parameter::Value<String>\"\r\n    Default: VpcId\r\n    AllowedValues:\r\n      - VpcId\r\n\r\n  VpcCidrRange:\r\n    Description: CIDR range of VPC\r\n    Type: \"AWS::SSM::Parameter::Value<String>\"\r\n    Default: VpcCIDRRange\r\n    AllowedValues:\r\n      - VpcCIDRRange\r\n\r\nResources:\r\n  SecurityGroup:\r\n    Type: AWS::EC2::SecurityGroup\r\n    Properties:\r\n      GroupDescription: Allow HTTP egress\r\n      VpcId: !Ref VpcID\r\n      SecurityGroupEgress:\r\n        - IpProtocol: tcp\r\n          FromPort: 80\r\n          ToPort: 80\r\n          CidrIp: !Ref VpcCidrRange\r\n```\r\n\r\nError is `E2004 Cidr should be a Cidr Range based string for VpcCIDRRange product.template.yaml:9:3`\r\n\r\nIf I'm not misunderstanding, cfn-lint seems to be complaining that the String `VpcCIDRRange` is not a valid CIDR, where in fact during runtime CloudFormation will lookup the value of `VpcCIDRRange` in SSM Parameter Store and use that instead.\r\n\r\nI guess a sensible approach here would be to disable E2004 for parameters that have a type of `AWS::SSM::Parameter::Value<String>` maybe?\n", "before_files": [{"content": "\"\"\"\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\nimport re\nfrom cfnlint.rules import CloudFormationLintRule\nfrom cfnlint.rules import RuleMatch\n\nfrom cfnlint.helpers import REGEX_CIDR\n\n\nclass CidrAllowedValues(CloudFormationLintRule):\n    \"\"\"CIDR checks\"\"\"\n    id = 'E2004'\n    shortdesc = 'CIDR Allowed Values should be a Cidr Range'\n    description = 'Check if a parameter is being used as a CIDR. ' \\\n                  'If it is make sure allowed values are proper CIDRs'\n    source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html'\n    tags = ['parameters', 'cidr']\n\n    def __init__(self):\n        \"\"\"Init\"\"\"\n        super(CidrAllowedValues, self).__init__()\n        resource_type_specs = [\n            'AWS::EC2::ClientVpnAuthorizationRule',\n            'AWS::EC2::ClientVpnEndpoint',\n            'AWS::EC2::ClientVpnRoute',\n            'AWS::EC2::NetworkAclEntry',\n            'AWS::EC2::Route',\n            'AWS::EC2::SecurityGroupEgress',\n            'AWS::EC2::SecurityGroupIngress',\n            'AWS::EC2::Subnet',\n            'AWS::EC2::TransitGatewayRoute',\n            'AWS::EC2::VPC',\n            'AWS::EC2::VPCCidrBlock',\n            'AWS::EC2::VPNConnectionRoute',\n            'AWS::RDS::DBSecurityGroupIngress',\n            'AWS::Redshift::ClusterSecurityGroupIngress',\n        ]\n\n        property_type_specs = [\n            'AWS::EC2::SecurityGroup.Egress',\n            'AWS::EC2::SecurityGroup.Ingress',\n            'AWS::EC2::VPNConnection.VpnTunnelOptionsSpecification',\n            'AWS::MediaLive::InputSecurityGroup.InputWhitelistRuleCidr',\n            'AWS::RDS::DBSecurityGroup.Ingress',\n            'AWS::SES::ReceiptFilter.IpFilter',\n        ]\n\n        for resource_type_spec in resource_type_specs:\n            self.resource_property_types.append(resource_type_spec)\n        for property_type_spec in property_type_specs:\n            self.resource_sub_property_types.append(property_type_spec)\n\n    # pylint: disable=W0613\n    def check_cidr_ref(self, value, path, parameters, resources):\n        matches = []\n\n        if value in parameters:\n            parameter = parameters.get(value, {})\n            allowed_values = parameter.get('AllowedValues', None)\n            if allowed_values:\n                for cidr in allowed_values:\n                    if not re.match(REGEX_CIDR, cidr):\n                        cidr_path = ['Parameters', value]\n                        message = 'Cidr should be a Cidr Range based string for {0}'\n                        matches.append(RuleMatch(cidr_path, message.format(cidr)))\n\n        return matches\n\n    def check(self, properties, resource_type, path, cfn):\n        \"\"\"Check itself\"\"\"\n        matches = []\n\n        for cidrString in [\n                'CIDRIP',\n                'Cidr',\n                'CidrBlock',\n                'CidrIp',\n                'ClientCidrBlock',\n                'DestinationCidrBlock',\n                'TargetNetworkCidr',\n                'TunnelInsideCidr',\n        ]:\n            matches.extend(\n                cfn.check_value(\n                    properties, cidrString, path,\n                    check_value=None, check_ref=self.check_cidr_ref,\n                    check_find_in_map=None, check_split=None, check_join=None\n                )\n            )\n\n        return matches\n\n    def match_resource_sub_properties(self, properties, property_type, path, cfn):\n        \"\"\"Match for sub properties\"\"\"\n        matches = []\n\n        matches.extend(self.check(properties, property_type, path, cfn))\n\n        return matches\n\n    def match_resource_properties(self, properties, resource_type, path, cfn):\n        \"\"\"Check CloudFormation Properties\"\"\"\n        matches = []\n\n        matches.extend(self.check(properties, resource_type, path, cfn))\n\n        return matches\n", "path": "src/cfnlint/rules/parameters/CidrAllowedValues.py"}], "after_files": [{"content": "\"\"\"\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\nimport re\nfrom cfnlint.rules import CloudFormationLintRule\nfrom cfnlint.rules import RuleMatch\n\nfrom cfnlint.helpers import REGEX_CIDR\n\n\nclass CidrAllowedValues(CloudFormationLintRule):\n    \"\"\"CIDR checks\"\"\"\n    id = 'E2004'\n    shortdesc = 'CIDR Allowed Values should be a Cidr Range'\n    description = 'Check if a parameter is being used as a CIDR. ' \\\n                  'If it is make sure allowed values are proper CIDRs'\n    source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html'\n    tags = ['parameters', 'cidr']\n\n    def __init__(self):\n        \"\"\"Init\"\"\"\n        super(CidrAllowedValues, self).__init__()\n        resource_type_specs = [\n            'AWS::EC2::ClientVpnAuthorizationRule',\n            'AWS::EC2::ClientVpnEndpoint',\n            'AWS::EC2::ClientVpnRoute',\n            'AWS::EC2::NetworkAclEntry',\n            'AWS::EC2::Route',\n            'AWS::EC2::SecurityGroupEgress',\n            'AWS::EC2::SecurityGroupIngress',\n            'AWS::EC2::Subnet',\n            'AWS::EC2::TransitGatewayRoute',\n            'AWS::EC2::VPC',\n            'AWS::EC2::VPCCidrBlock',\n            'AWS::EC2::VPNConnectionRoute',\n            'AWS::RDS::DBSecurityGroupIngress',\n            'AWS::Redshift::ClusterSecurityGroupIngress',\n        ]\n\n        property_type_specs = [\n            'AWS::EC2::SecurityGroup.Egress',\n            'AWS::EC2::SecurityGroup.Ingress',\n            'AWS::EC2::VPNConnection.VpnTunnelOptionsSpecification',\n            'AWS::MediaLive::InputSecurityGroup.InputWhitelistRuleCidr',\n            'AWS::RDS::DBSecurityGroup.Ingress',\n            'AWS::SES::ReceiptFilter.IpFilter',\n        ]\n\n        for resource_type_spec in resource_type_specs:\n            self.resource_property_types.append(resource_type_spec)\n        for property_type_spec in property_type_specs:\n            self.resource_sub_property_types.append(property_type_spec)\n\n    # pylint: disable=W0613\n    def check_cidr_ref(self, value, path, parameters, resources):\n        matches = []\n\n        if value in parameters:\n            parameter = parameters.get(value, {})\n            parameter_type = parameters.get(value, {}).get('Type', '')\n            if parameter_type == 'AWS::SSM::Parameter::Value<String>':\n                # If we are reading from the Parameter store we can no longer\n                # check the value of the allowed values\n                return matches\n            allowed_values = parameter.get('AllowedValues', None)\n            if allowed_values:\n                for cidr in allowed_values:\n                    if not re.match(REGEX_CIDR, cidr):\n                        cidr_path = ['Parameters', value]\n                        message = 'Cidr should be a Cidr Range based string for {0}'\n                        matches.append(RuleMatch(cidr_path, message.format(cidr)))\n\n        return matches\n\n    def check(self, properties, resource_type, path, cfn):\n        \"\"\"Check itself\"\"\"\n        matches = []\n\n        for cidrString in [\n                'CIDRIP',\n                'Cidr',\n                'CidrBlock',\n                'CidrIp',\n                'ClientCidrBlock',\n                'DestinationCidrBlock',\n                'TargetNetworkCidr',\n                'TunnelInsideCidr',\n        ]:\n            matches.extend(\n                cfn.check_value(\n                    properties, cidrString, path,\n                    check_value=None, check_ref=self.check_cidr_ref,\n                    check_find_in_map=None, check_split=None, check_join=None\n                )\n            )\n\n        return matches\n\n    def match_resource_sub_properties(self, properties, property_type, path, cfn):\n        \"\"\"Match for sub properties\"\"\"\n        matches = []\n\n        matches.extend(self.check(properties, property_type, path, cfn))\n\n        return matches\n\n    def match_resource_properties(self, properties, resource_type, path, cfn):\n        \"\"\"Check CloudFormation Properties\"\"\"\n        matches = []\n\n        matches.extend(self.check(properties, resource_type, path, cfn))\n\n        return matches\n", "path": "src/cfnlint/rules/parameters/CidrAllowedValues.py"}]}