Repository: aws-cloudformation/cfn-lint

Issue:
E3008 Property "ServiceRole" has no valid Refs to Resources at Resources/CodeBuildProject/Properties/ServiceRole/Ref
*cfn-lint version: (`cfn-lint --version`)*
cfn-lint 0.18.1

*Description of issue.*

Using the default example template for CodeBuild (https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codebuild-project.html)

Get the following:
```
E3008 Property "ServiceRole" has no valid Refs to Resources at Resources/CodeBuildProject/Properties/ServiceRole/Ref
x.yaml:6:7
```

Please provide as much information as possible:
* Template linting issues:
  * Please provide a CloudFormation sample that generated the issue.

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codebuild-project.html

  * If present, please add links to the (official) documentation for clarification.
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codebuild-project.html

  * Validate if the issue still exists with the latest version of `cfn-lint` and/or the latest Spec files

Cfn-lint uses the [CloudFormation Resource Specifications](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html) as the base to do validation. These files are included as part of the application version. Please update to the latest version of `cfn-lint` or update the spec files manually (`cfn-lint -u`)

Confirmed. Still exists.



Discussion:
I do like doing this
But I need to go find some money around where I can get the money I minded for early its everywhere it's been taking from 3 time and I need to try and get for my kids.
I will be back

Resolving patch:
diff --git a/src/cfnlint/rules/resources/iam/RefWithPath.py b/src/cfnlint/rules/resources/iam/RefWithPath.py
new file mode 100644
--- /dev/null
+++ b/src/cfnlint/rules/resources/iam/RefWithPath.py
@@ -0,0 +1,70 @@
+"""
+  Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this
+  software and associated documentation files (the "Software"), to deal in the Software
+  without restriction, including without limitation the rights to use, copy, modify,
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+  permit persons to whom the Software is furnished to do so.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+  INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+  PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""
+from cfnlint import CloudFormationLintRule
+from cfnlint import RuleMatch
+
+
+class RefWithPath(CloudFormationLintRule):
+    """Check if IAM Policy Version is correct"""
+    id = 'E3050'
+    shortdesc = 'Check if REFing to a IAM resource with path set'
+    description = 'Some resources don\'t support looking up the IAM resource by name. ' \
+                  'This check validates when a REF is being used and the Path is not \'/\''
+    source_url = 'https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html'
+    tags = ['properties', 'iam']
+
+    def __init__(self):
+        """Init"""
+        super(RefWithPath, self).__init__()
+        self.resources_and_keys = {
+            'AWS::CodeBuild::Project': 'ServiceRole',
+        }
+
+        for resource_type in self.resources_and_keys:
+            self.resource_property_types.append(resource_type)
+
+    def check_ref(self, value, parameters, resources, path):  # pylint: disable=W0613
+        """ Check Ref """
+        matches = []
+
+        iam_path = resources.get(value, {}).get('Properties', {}).get('Path')
+        if not iam_path:
+            return matches
+
+        if iam_path != '/':
+            message = 'When using a Ref to IAM resource the Path must be \'/\'.  Switch to GetAtt if the Path has to be \'{}\'.'
+            matches.append(
+                RuleMatch(path, message.format(iam_path)))
+
+        return matches
+
+    def match_resource_properties(self, properties, resourcetype, path, cfn):
+        """Check CloudFormation Properties"""
+        matches = []
+
+        key = None
+        if resourcetype in self.resources_and_keys:
+            key = self.resources_and_keys.get(resourcetype)
+
+        matches.extend(
+            cfn.check_value(
+                properties, key, path,
+                check_ref=self.check_ref
+            )
+        )
+
+        return matches


Test patch:
diff --git a/test/fixtures/templates/bad/resources/iam/ref_with_path.yaml b/test/fixtures/templates/bad/resources/iam/ref_with_path.yaml
new file mode 100644
--- /dev/null
+++ b/test/fixtures/templates/bad/resources/iam/ref_with_path.yaml
@@ -0,0 +1,81 @@
+---
+AWSTemplateFormatVersion: "2010-09-09"
+Resources:
+  CodeBuildProject:
+    Type: AWS::CodeBuild::Project
+    Properties:
+      ServiceRole: !Ref CodeBuildRole
+      Artifacts:
+        Type: CODEPIPELINE
+      Environment:
+        Type: LINUX_CONTAINER
+        ComputeType: BUILD_GENERAL1_SMALL
+        Image: aws/codebuild/ubuntu-base:14.04
+        EnvironmentVariables:
+          - Name: varName1
+            Value: varValue1
+          - Name: varName2
+            Value: varValue2
+            Type: PLAINTEXT
+          - Name: varName3
+            Value: /CodeBuild/testParameter
+            Type: PARAMETER_STORE
+      Source:
+        Type: CODEPIPELINE
+      TimeoutInMinutes: 10
+      VpcConfig:
+        VpcId: !Ref CodeBuildVPC
+        Subnets: [!Ref CodeBuildSubnet]
+        SecurityGroupIds: [!Ref CodeBuildSecurityGroup]
+      Cache:
+        Type: S3
+        Location: mybucket/prefix
+  CodeBuildRole:
+    Type: AWS::IAM::Role
+    Properties:
+      AssumeRolePolicyDocument:
+        Statement:
+        - Action: ['sts:AssumeRole']
+          Effect: Allow
+          Principal:
+            Service: [codebuild.amazonaws.com]
+        Version: '2012-10-17'
+      Path: /test/
+      Policies:
+        - PolicyName: CodeBuildAccess
+          PolicyDocument:
+            Version: '2012-10-17'
+            Statement:
+              - Action:
+                - 'logs:*'
+                - 'ec2:CreateNetworkInterface'
+                - 'ec2:DescribeNetworkInterfaces'
+                - 'ec2:DeleteNetworkInterface'
+                - 'ec2:DescribeSubnets'
+                - 'ec2:DescribeSecurityGroups'
+                - 'ec2:DescribeDhcpOptions'
+                - 'ec2:DescribeVpcs'
+                - 'ec2:CreateNetworkInterfacePermission'
+                Effect: Allow
+                Resource: '*'
+  CodeBuildVPC:
+    Type: AWS::EC2::VPC
+    Properties:
+      CidrBlock: 10.0.0.0/16
+      EnableDnsSupport: True
+      EnableDnsHostnames: True
+      Tags:
+        - Key: name
+          Value: codebuild
+  CodeBuildSubnet:
+    Type: AWS::EC2::Subnet
+    Properties:
+      VpcId:
+        Ref: CodeBuildVPC
+      CidrBlock: 10.0.1.0/24
+  CodeBuildSecurityGroup:
+    Type: AWS::EC2::SecurityGroup
+    Properties:
+      GroupName: Codebuild Internet Group
+      GroupDescription: 'CodeBuild SecurityGroup'
+      VpcId: !Ref CodeBuildVPC
diff --git a/test/fixtures/templates/good/resources/iam/ref_with_path.yaml b/test/fixtures/templates/good/resources/iam/ref_with_path.yaml
new file mode 100644
--- /dev/null
+++ b/test/fixtures/templates/good/resources/iam/ref_with_path.yaml
@@ -0,0 +1,81 @@
+---
+AWSTemplateFormatVersion: "2010-09-09"
+Resources:
+  CodeBuildProject:
+    Type: AWS::CodeBuild::Project
+    Properties:
+      ServiceRole: !Ref CodeBuildRole
+      Artifacts:
+        Type: CODEPIPELINE
+      Environment:
+        Type: LINUX_CONTAINER
+        ComputeType: BUILD_GENERAL1_SMALL
+        Image: aws/codebuild/ubuntu-base:14.04
+        EnvironmentVariables:
+          - Name: varName1
+            Value: varValue1
+          - Name: varName2
+            Value: varValue2
+            Type: PLAINTEXT
+          - Name: varName3
+            Value: /CodeBuild/testParameter
+            Type: PARAMETER_STORE
+      Source:
+        Type: CODEPIPELINE
+      TimeoutInMinutes: 10
+      VpcConfig:
+        VpcId: !Ref CodeBuildVPC
+        Subnets: [!Ref CodeBuildSubnet]
+        SecurityGroupIds: [!Ref CodeBuildSecurityGroup]
+      Cache:
+        Type: S3
+        Location: mybucket/prefix
+  CodeBuildRole:
+    Type: AWS::IAM::Role
+    Properties:
+      AssumeRolePolicyDocument:
+        Statement:
+        - Action: ['sts:AssumeRole']
+          Effect: Allow
+          Principal:
+            Service: [codebuild.amazonaws.com]
+        Version: '2012-10-17'
+      Path: /
+      Policies:
+        - PolicyName: CodeBuildAccess
+          PolicyDocument:
+            Version: '2012-10-17'
+            Statement:
+              - Action:
+                - 'logs:*'
+                - 'ec2:CreateNetworkInterface'
+                - 'ec2:DescribeNetworkInterfaces'
+                - 'ec2:DeleteNetworkInterface'
+                - 'ec2:DescribeSubnets'
+                - 'ec2:DescribeSecurityGroups'
+                - 'ec2:DescribeDhcpOptions'
+                - 'ec2:DescribeVpcs'
+                - 'ec2:CreateNetworkInterfacePermission'
+                Effect: Allow
+                Resource: '*'
+  CodeBuildVPC:
+    Type: AWS::EC2::VPC
+    Properties:
+      CidrBlock: 10.0.0.0/16
+      EnableDnsSupport: True
+      EnableDnsHostnames: True
+      Tags:
+        - Key: name
+          Value: codebuild
+  CodeBuildSubnet:
+    Type: AWS::EC2::Subnet
+    Properties:
+      VpcId:
+        Ref: CodeBuildVPC
+      CidrBlock: 10.0.1.0/24
+  CodeBuildSecurityGroup:
+    Type: AWS::EC2::SecurityGroup
+    Properties:
+      GroupName: Codebuild Internet Group
+      GroupDescription: 'CodeBuild SecurityGroup'
+      VpcId: !Ref CodeBuildVPC
diff --git a/test/module/config/test_config_mixin.py b/test/module/config/test_config_mixin.py
--- a/test/module/config/test_config_mixin.py
+++ b/test/module/config/test_config_mixin.py
@@ -123,4 +123,4 @@ def test_config_expand_ignore_templates(self, yaml_mock):
 
         # test defaults
         self.assertNotIn('test/fixtures/templates/bad/resources/iam/resource_policy.yaml', config.templates)
-        self.assertEqual(len(config.templates), 3)
+        self.assertEqual(len(config.templates), 4)
diff --git a/test/rules/resources/iam/test_ref_with_path.py b/test/rules/resources/iam/test_ref_with_path.py
new file mode 100644
--- /dev/null
+++ b/test/rules/resources/iam/test_ref_with_path.py
@@ -0,0 +1,37 @@
+"""
+  Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this
+  software and associated documentation files (the "Software"), to deal in the Software
+  without restriction, including without limitation the rights to use, copy, modify,
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+  permit persons to whom the Software is furnished to do so.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+  INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+  PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""
+from cfnlint.rules.resources.iam.RefWithPath import RefWithPath  # pylint: disable=E0401
+from ... import BaseRuleTestCase
+
+
+class TestRefWithPath(BaseRuleTestCase):
+    """Test IAM Policies"""
+    def setUp(self):
+        """Setup"""
+        super(TestRefWithPath, self).setUp()
+        self.collection.register(RefWithPath())
+        self.success_templates = [
+            'test/fixtures/templates/good/resources/iam/ref_with_path.yaml'
+        ]
+
+    def test_file_positive(self):
+        """Test Positive"""
+        self.helper_file_positive()
+
+    def test_file_negative(self):
+        """Test failure"""
+        self.helper_file_negative('test/fixtures/templates/bad/resources/iam/ref_with_path.yaml', 1)