Repository: aws-cloudformation/cfn-lint

Issue:
Issue with E3008 and W2030
### CloudFormation Lint Version

0.74.3

### What operating system are you using?

Mac

### Describe the bug

I show the exception trace and later some detailed description:

```bash
E0002 Unknown exception while processing rule E3008: Traceback (most recent call last):
  File "cfnlint/rules/__init__.py", line 320, in run_check
    return check(*args)
  File "cfnlint/rules/__init__.py", line 44, in wrapper
    results = match_function(self, filename, cfn, *args, **kwargs)
  File "cfnlint/rules/__init__.py", line 220, in matchall_resource_sub_properties
    return self.match_resource_sub_properties(  # pylint: disable=E1102
  File "cfnlint/rules/resources/properties/ValueRefGetAtt.py", line 287, in match_resource_sub_properties
    matches.extend(self.check(cfn, properties, specs, property_specs, path))
  File "cfnlint/rules/resources/properties/ValueRefGetAtt.py", line 254, in check
    cfn.check_value(
  File "cfnlint/template.py", line 764, in check_value
    check_ref(
  File "cfnlint/rules/resources/properties/ValueRefGetAtt.py", line 53, in check_value_ref
    value_specs = kwargs.get("value_specs", {}).get("Ref")
  File "cfnlint/rules/resources/properties/ValueRefGetAtt.py", line 53, in check_value_ref
    value_specs = kwargs.get("value_specs", {}).get("Ref")

test.yml:1:1

E0002 Unknown exception while processing rule W2030: Traceback (most recent call last):
  File "cfnlint/rules/__init__.py", line 320, in run_check
    return check(*args)
  File "cfnlint/rules/__init__.py", line 44, in wrapper
    results = match_function(self, filename, cfn, *args, **kwargs)
  File "cfnlint/rules/__init__.py", line 220, in matchall_resource_sub_properties
    return self.match_resource_sub_properties(  # pylint: disable=E1102
  File "cfnlint/rules/parameters/AllowedValue.py", line 144, in match_resource_sub_properties
    matches.extend(self.check(cfn, properties, specs, property_specs, path))
  File "cfnlint/rules/parameters/AllowedValue.py", line 115, in check
    cfn.check_value(
  File "cfnlint/template.py", line 764, in check_value
    check_ref(
  File "cfnlint/rules/parameters/AllowedValue.py", line 50, in check_value_ref
    allowed_value_specs = kwargs.get("value_specs", {}).get("AllowedValues", {})
AttributeError: 'str' object has no attribute 'get'

test.yml:1:1
```

I am getting these exceptions because kwargs.get("value_specs", {}) is returning the value "CACHED". I saw that @kddejong solved it for some Errors and Warnings in this PR: https://github.com/aws-cloudformation/cfn-lint/pull/2628/files . But still a solution is needed for these two cases.

Thank you in advance ;)

### Expected behavior

A expected behaviour would be without exceptions by controlling kwargs.get("value_specs", {}) value when it is "CACHED".

### Reproduction template

As we are using our own extension of the cfn-lint, the reproduction template won't be valid to reproduce the error with just aws-cfn-lint, but I show you the template that woul give the exceptions shown in the description of the bug:

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Metadata:
  AlertIdentifier: "service"
  Tags:
    CostCenter: "service"
Parameters:
  SearchInstanceType:
    Type: "String"
    Default: "t3.medium.elasticsearch"

Resources:
  SearchCluster:
    Type: AWS::Elasticsearch::Domain
    UpdatePolicy:
      EnableVersionUpgrade: true
    Properties:
      ElasticsearchClusterConfig:
        InstanceType: !Ref SearchInstanceType
      EBSOptions:
        EBSEnabled: true
        VolumeType: "gp2"
      ElasticsearchVersion: "7.10"
      SnapshotOptions:
        AutomatedSnapshotStartHour: 2
      Tags:
        - Key: "Name"
          Value: "search-cluster"
        - Key: "AppGroup"
          Value: "AppGroup"
        - Key: "Environment"
          Value: "Environment"
```
The exact place where it fails is:
```yaml 
InstanceType: !Ref SearchInstanceType
```



Discussion:
Hey @kddejong 👋🏻 

This one should be similar to the one you've fixed recently 😄 

Resolving patch:
diff --git a/src/cfnlint/rules/parameters/AllowedValue.py b/src/cfnlint/rules/parameters/AllowedValue.py
--- a/src/cfnlint/rules/parameters/AllowedValue.py
+++ b/src/cfnlint/rules/parameters/AllowedValue.py
@@ -28,6 +28,14 @@ def initialize(self, cfn):
         ):
             self.resource_sub_property_types.append(property_type_spec)
 
+    def _get_value_specs(self, value_type, region):
+        value_specs = RESOURCE_SPECS.get(region).get("ValueTypes").get(value_type, {})
+        if value_specs == "CACHED":
+            value_specs = (
+                RESOURCE_SPECS.get("us-east-1").get("ValueTypes").get(value_type, {})
+            )
+        return value_specs
+
     def check_value_ref(self, value, path, **kwargs):
         """Check Ref"""
         matches = []
@@ -111,15 +119,14 @@ def check(self, cfn, properties, value_specs, property_specs, path):
                         property_type = (
                             property_specs.get("Properties").get(prop).get("Type")
                         )
+                        type_specs = self._get_value_specs(value_type, cfn.regions[0])
                         matches.extend(
                             cfn.check_value(
                                 p_value,
                                 prop,
                                 p_path,
                                 check_ref=self.check_value_ref,
-                                value_specs=RESOURCE_SPECS.get(cfn.regions[0])
-                                .get("ValueTypes")
-                                .get(value_type, {}),
+                                value_specs=type_specs,
                                 cfn=cfn,
                                 property_type=property_type,
                                 property_name=prop,
diff --git a/src/cfnlint/rules/resources/properties/ValueRefGetAtt.py b/src/cfnlint/rules/resources/properties/ValueRefGetAtt.py
--- a/src/cfnlint/rules/resources/properties/ValueRefGetAtt.py
+++ b/src/cfnlint/rules/resources/properties/ValueRefGetAtt.py
@@ -234,6 +234,14 @@ def check_value_getatt(self, value, path, **kwargs):
 
         return matches
 
+    def _get_value_specs(self, value_type, region):
+        value_specs = RESOURCE_SPECS.get(region).get("ValueTypes").get(value_type, {})
+        if value_specs == "CACHED":
+            value_specs = (
+                RESOURCE_SPECS.get("us-east-1").get("ValueTypes").get(value_type, {})
+            )
+        return value_specs
+
     def check(self, cfn, properties, value_specs, property_specs, path):
         """Check itself"""
         matches = []
@@ -247,6 +255,12 @@ def check(self, cfn, properties, value_specs, property_specs, path):
                         property_type = (
                             property_specs.get("Properties").get(prop).get("Type")
                         )
+                        value_type_specs = self._get_value_specs(
+                            value_type, cfn.regions[0]
+                        )
+                        list_value_specs = self._get_value_specs(
+                            list_value_type, cfn.regions[0]
+                        )
                         matches.extend(
                             cfn.check_value(
                                 p_value,
@@ -254,12 +268,8 @@ def check(self, cfn, properties, value_specs, property_specs, path):
                                 p_path,
                                 check_ref=self.check_value_ref,
                                 check_get_att=self.check_value_getatt,
-                                value_specs=RESOURCE_SPECS.get(cfn.regions[0])
-                                .get("ValueTypes")
-                                .get(value_type, {}),
-                                list_value_specs=RESOURCE_SPECS.get(cfn.regions[0])
-                                .get("ValueTypes")
-                                .get(list_value_type, {}),
+                                value_specs=value_type_specs,
+                                list_value_specs=list_value_specs,
                                 cfn=cfn,
                                 property_type=property_type,
                                 property_name=prop,


Test patch: