Repository: bridgecrewio/checkov

Issue:
Error validando funciones en los tags
**Describe the issue**
We are trying to execute checkov in a template which makes use of a function (IF)  in the tags:

        - 'Fn::If':
           - cPdnEnv
           -
             Key: "Schedule"
             Value: "VISOR-02"
           - !Ref "AWS::NoValue"    

but it throws the following error message:

`Failed to parse tags for entity {'rEC2Instance': ...`

We updated to the latest version of checkov but the error continues

According to the AWS [documentation](https://docs.aws.amazon.com/es_es/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-if), this IF function can be used on tags.



Discussion:
hey @cajlopezor thanks for reaching out. Can you provide the whole resource as an example? from the error message it looks like you added tags to an EC2 instance, right?
Hi @gruebel, I shareyou the yaml of the resource and the error

```
Resources:

  rEC2Instance:
    Condition: cAditionalEc2
    Type: AWS::EC2::Instance
    Properties:
      DisableApiTermination: true 
      NetworkInterfaces: 
        - AssociatePublicIpAddress: "false"              
          DeviceIndex: "0"
          GroupSet: 
            - !Join ["", ["{{resolve:ssm:", !Ref pPSGASt, "}}"]]
          SubnetId: !Ref pSubnetPriv5
      InstanceType: !Ref pEC2InstanceTypeSSAStqP
      ImageId: !FindInMap
        - EnvironmentToAMI
        - !Ref pEnvironment
        - AMIID
      IamInstanceProfile: !Join ["", ["{{resolve:ssm:", !Ref pInstanceProfile, "}}"]]
      BlockDeviceMappings:
        - DeviceName: /dev/sda1
          Ebs:
            VolumeSize: !Ref pOSSizeDisk
            VolumeType: !Ref pTypeDisk          
            Encrypted: 'true' 
            KmsKeyId: !Join ["", ["{{resolve:ssm:", !Ref pPSKMSARN, "}}"]]
        - DeviceName: /dev/sdb
          Ebs:
            VolumeSize: 50
            VolumeType: !Ref pTypeDisk
            Encrypted: 'true' 
            KmsKeyId: !Join ["", ["{{resolve:ssm:", !Ref pPSKMSARN, "}}"]]
      UserData:
        Fn::Base64:
          Fn::Sub:
            - |
              <powershell>
               query here
              </powershell>
      Tags:
        - Key: Name
          Value: !Ref xxxx
        - 'Fn::If':
           - cPdnEnv
           -
             Key: "Schedule"
             Value: "xxxx"
           - !Ref "AWS::NoValue"
```  
The error is:

`Current File Scanned=/template (4).yaml2022-11-09 09:30:23,665 [ThreadPoolEx] [WARNI]  Failed to parse tags for entity {'rEC2Instance': {'Type': 'AWS::EC2::Instance', 'Properties': {'DisableApiTermination': True, 'NetworkInterfaces': [{'AssociatePublicIpAddress': 'false', 'DeviceIndex': '0', 'GroupSet': [{'Fn::Join': ['', ['{{resolve:ssm:', {'Ref': 'pPSGASt'}, '}}']]}], 'SubnetId': {'Ref': 'pSubnetPriv5'}, '__startline__': 134, '__endline__': 139}], 'InstanceType': {'Ref': 'pEC2InstanceTypeSSAStqP'}, 'ImageId': {'Fn::FindInMap': ['EnvironmentToAMI', {'Ref': 'pEnvironment'}, 'AMIID']}, 'IamInstanceProfile': {'Fn::Join': ['', ['{{resolve:ssm:', {'Ref': 'pInstanceProfile'}, '}}']]}, 'BlockDeviceMappings': [{'DeviceName': '/dev/sda1', 'Ebs': {'VolumeSize': {'Ref': 'pOSSizeDisk'}, 'VolumeType': {'Ref': 'pTypeDisk'}, 'Encrypted': 'true', 'KmsKeyId': {'Fn::Join': ['', ['{{resolve:ssm:', {'Ref': 'pPSKMSARN'}, '}}']]}, '__startline__': 148, '__endline__': 152}, '__startline__': 146, '__endline__': 152}, {'DeviceName': '/dev/sdb', 'Ebs': {'VolumeSize': 50, 'VolumeType': {'Ref': 'pTypeDisk'}, 'Encrypted': 'true', 'KmsKeyId': {'Fn::Join': ['', ['{{resolve:ssm:', {'Ref': 'pPSKMSARN'}, '}}']]}, '__startline__': 154, '__endline__': 158},`

thanks
great thanks!

Resolving patch:
diff --git a/checkov/cloudformation/cfn_utils.py b/checkov/cloudformation/cfn_utils.py
--- a/checkov/cloudformation/cfn_utils.py
+++ b/checkov/cloudformation/cfn_utils.py
@@ -17,6 +17,7 @@
 from checkov.common.models.consts import YAML_COMMENT_MARK
 
 CF_POSSIBLE_ENDINGS = frozenset([".yml", ".yaml", ".json", ".template"])
+TAG_FIELD_NAMES = ("Key", "Value")
 
 
 def get_resource_tags(entity: Dict[StrNode, DictNode], registry: Registry = cfn_registry) -> Optional[Dict[str, str]]:
@@ -43,8 +44,12 @@ def get_resource_tags(entity: Dict[StrNode, DictNode], registry: Registry = cfn_
 
 
 def parse_entity_tags(tags: Union[ListNode, Dict[str, Any]]) -> Optional[Dict[str, str]]:
-    if isinstance(tags, ListNode):
-        tag_dict = {get_entity_value_as_string(tag["Key"]): get_entity_value_as_string(tag["Value"]) for tag in tags}
+    if isinstance(tags, list):
+        tag_dict = {
+            get_entity_value_as_string(tag["Key"]): get_entity_value_as_string(tag["Value"])
+            for tag in tags
+            if all(field in tag for field in TAG_FIELD_NAMES)
+        }
         return tag_dict
     elif isinstance(tags, dict):
         tag_dict = {


Test patch:
diff --git a/tests/cloudformation/runner/test_runner.py b/tests/cloudformation/runner/test_runner.py
--- a/tests/cloudformation/runner/test_runner.py
+++ b/tests/cloudformation/runner/test_runner.py
@@ -183,20 +183,25 @@ def test_get_tags(self):
         entity = {resource_name: resource}
         entity_tags = cfn_utils.get_resource_tags(entity)
 
-        self.assertIsNone(entity_tags)
+        self.assertDictEqual(
+            entity_tags,
+            {
+                "Name": "TF-FulfillmentServer",
+                "terraform-server-tag-key": "terraform-server-tag-value",
+            }
+        )
 
         resource_name = 'EKSClusterNodegroup'
         resource = definitions['Resources'][resource_name]
         entity = {resource_name: resource}
         entity_tags = cfn_utils.get_resource_tags(entity)
 
-        self.assertEqual(len(entity_tags), 1)
-        tags = {
-            'Name': '{\'Ref\': \'ClusterName\'}-EKS-{\'Ref\': \'NodeGroupName\'}'
-        }
-
-        for name, value in tags.items():
-            self.assertEqual(entity_tags[name], value)
+        self.assertDictEqual(
+            entity_tags,
+            {
+                'Name': '{\'Ref\': \'ClusterName\'}-EKS-{\'Ref\': \'NodeGroupName\'}',
+            }
+        )
 
     def test_wrong_check_imports(self):
         wrong_imports = ["arm", "dockerfile", "helm", "kubernetes", "serverless", "terraform"]