Repository: aws-cloudformation/cfn-lint

Issue:
Condition: <list> on Resource triggers "Unknown exception while processing rule"
*cfn-lint version: (`cfn-lint --version`)*
cfn-lint 0.21.4

*Description of issue.*
A resource with a Condition property defined as a list triggers:
```
E0002 Unknown exception while processing rule E8002: unhashable type: 'list_node'
/tmp/cfn-lint-condition-list-error.yaml:1:1
```
I believe that the use of lists / multiple values for a Condition property of a Resource is probably not legal (although I was unable to find clear confirmation of that in the documentation during a quick scan), but it should probably trigger a lint error rather than an exception.

It would also be helpful, if possible, to include the template line-number where the exception was triggered, rather than line:char 1:1 to make tracking the cause of such problems easier.

I have also seen the same exception, but for rule W1001, I though it was the same cause, but my reproduce test didn't re-trigger the W1001 case.

*Reproduce example*
```
AWSTemplateFormatVersion: 2010-09-09
Description: "cfn-lint condition list error"

Conditions:
    Cond1: !Equals [ !Ref 'AWS::Region', 'us-east-1' ]
    Cond2: !Equals [ !Ref 'AWS::Region', 'eu-west-1' ]

Resources:

    EIP1:
        Type: AWS::EC2::EIP
        Condition:
          - Cond1
          - Cond2
        Properties:
            Domain: 'vpc'

    EIP2:
        Type: AWS::EC2::EIP
        Condition: Cond1
        Properties:
            Domain: 'vpc'

    EIP3:
        Type: AWS::EC2::EIP
        Condition: Cond2
        Properties:
            Domain: 'vpc'
```



Discussion:

Resolving patch:
diff --git a/src/cfnlint/rules/conditions/Exists.py b/src/cfnlint/rules/conditions/Exists.py
--- a/src/cfnlint/rules/conditions/Exists.py
+++ b/src/cfnlint/rules/conditions/Exists.py
@@ -46,9 +46,10 @@ def match(self, cfn):
 
         # Get resource's Conditions
         for resource_name, resource_values in cfn.get_resources().items():
-            if 'Condition' in resource_values:
+            condition = resource_values.get('Condition')
+            if isinstance(condition, six.string_types):  # make sure its a string
                 path = ['Resources', resource_name, 'Condition']
-                ref_conditions[resource_values['Condition']] = path
+                ref_conditions[condition] = path
 
         # Get conditions used by another condition
         condtrees = cfn.search_deep_keys('Condition')
diff --git a/src/cfnlint/rules/resources/Configuration.py b/src/cfnlint/rules/resources/Configuration.py
--- a/src/cfnlint/rules/resources/Configuration.py
+++ b/src/cfnlint/rules/resources/Configuration.py
@@ -14,6 +14,7 @@
   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 """
+import six
 from cfnlint import CloudFormationLintRule
 from cfnlint import RuleMatch
 import cfnlint.helpers
@@ -82,6 +83,15 @@ def match(self, cfn):
                             ['Resources', resource_name, property_key],
                             message.format(property_key, resource_name)))
 
+                # validate condition is a string
+                condition = resource_values.get('Condition', '')
+                if not isinstance(condition, six.string_types):
+                    message = 'Condition for resource {0} should be a string'
+                    matches.append(RuleMatch(
+                        ['Resources', resource_name, 'Condition'],
+                        message.format(resource_name)
+                    ))
+
                 resource_type = resource_values.get('Type', '')
                 if not resource_type:
                     message = 'Type not defined for resource {0}'


Test patch:
diff --git a/test/fixtures/templates/bad/resources/configuration.yaml b/test/fixtures/templates/bad/resources/configuration.yaml
new file mode 100644
--- /dev/null
+++ b/test/fixtures/templates/bad/resources/configuration.yaml
@@ -0,0 +1,16 @@
+---
+AWSTemplateFormatVersion: "2010-09-09"
+Conditions:
+  isUsEast1: !Equals [!Ref 'AWS::Region', 'us-east-1']
+Resources:
+  AWSIAMRole1:
+    Type: AWS::IAM::Role
+    Condition:
+    - isUsEast1
+    Properties:
+      AssumeRolePolicyDocument: {}
+  AWSIAMRole2:
+    Type: AWS::IAM::Role
+    Condition: False
+    Properties:
+      AssumeRolePolicyDocument: {}
diff --git a/test/rules/conditions/test_exists.py b/test/rules/conditions/test_exists.py
--- a/test/rules/conditions/test_exists.py
+++ b/test/rules/conditions/test_exists.py
@@ -35,4 +35,4 @@ def test_file_positive(self):
 
     def test_file_negative(self):
         """Test failure"""
-        self.helper_file_negative('test/fixtures/templates/bad/conditions.yaml', 3)
+        self.helper_file_negative('test/fixtures/templates/bad/conditions.yaml', 2)
diff --git a/test/rules/resources/test_configurations.py b/test/rules/resources/test_configurations.py
--- a/test/rules/resources/test_configurations.py
+++ b/test/rules/resources/test_configurations.py
@@ -32,3 +32,4 @@ def test_file_positive(self):
     def test_file_negative(self):
         """Test failure"""
         self.helper_file_negative('test/fixtures/templates/bad/generic.yaml', 2)
+        self.helper_file_negative('test/fixtures/templates/bad/resources/configuration.yaml', 2)