Repository: cloudtools/troposphere

Issue:
Function Role property doesn't work with string value
The following results in a TypeError for the Role property type. I don't get a TypeError if I use GetAtt for Role's type, but I need to use a string. Looks like an issue in which the expected type is a list of possible types, but the validation on types then thinks the value should be a list instead of being one of the types in the list.

```
code = Code(
            S3Bucket=self.s3Bucket,
            S3Key=self.s3Key
        )

func = Function(
        "title",
        Code=code,
        Handler="index.handler",
        Role="role-arn-here",
        Runtime="nodejs",
    )
```

```
  File "C:\Users\bmorin\AppData\Local\Programs\Python\Python35\lib\site-packages\troposphere\__init__.py", line 66, in __init__
    self.__setattr__(k, v)
  File "C:\Users\bmorin\AppData\Local\Programs\Python\Python35\lib\site-packages\troposphere\__init__.py", line 110, in __setattr__
    self._raise_type(name, value, expected_type)
  File "C:\Users\bmorin\AppData\Local\Programs\Python\Python35\lib\site-packages\troposphere\__init__.py", line 145, in _raise_type
    expected_type))
TypeError: <class 'troposphere.awslambda.Function'>: EventssomeFunction.Role is <class 'str'>, expected [<class 'str'>, <class 'troposphere.GetAtt'>]
```

Suspected issue spot in `__init__.py:`

```
# If we're expecting a list, then make sure it is a list
if not isinstance(value, list):
    self._raise_type(name, value, expected_type)
```

And the definition of Role in `awslambda.py:`

```
class Function(AWSObject):
    resource_type = "AWS::Lambda::Function"

    props = {
        'Code': (Code, True),
        'Description': (str, False),
        'Handler': (str, True),
        'MemorySize': (positive_integer, False),
        'Role': ([str, GetAtt], True),
        'Runtime': (str, True),
        'Timeout': (positive_integer, False),
    }
```



Discussion:
This bug is blocking me as well. +1 for getting a fix for this!

Every other place I've seen that a Role ARN is needed in troposphere, a simple string is taken. I'd like to understand why this is different.

Try this quick patch which should allow both the string version and the GetAtt to work:

```
diff --git a/troposphere/awslambda.py b/troposphere/awslambda.py
index b30f6e7..586cf71 100644
--- a/troposphere/awslambda.py
+++ b/troposphere/awslambda.py
@@ -51,7 +51,7 @@ class Function(AWSObject):
         'Description': (basestring, False),
         'Handler': (basestring, True),
         'MemorySize': (positive_integer, False),
-        'Role': ([basestring, GetAtt], True),
+        'Role': (basestring, True),
         'Runtime': (basestring, True),
         'Timeout': (positive_integer, False),
     }
```

Thanks @markpeek, that works. Are you going to create a pull request for this or would you like me to?


Resolving patch:
diff --git a/troposphere/awslambda.py b/troposphere/awslambda.py
--- a/troposphere/awslambda.py
+++ b/troposphere/awslambda.py
@@ -1,4 +1,4 @@
-from . import AWSObject, AWSProperty, GetAtt
+from . import AWSObject, AWSProperty
 from .validators import positive_integer
 
 
@@ -51,7 +51,7 @@ class Function(AWSObject):
         'Description': (basestring, False),
         'Handler': (basestring, True),
         'MemorySize': (positive_integer, False),
-        'Role': ([basestring, GetAtt], True),
+        'Role': (basestring, True),
         'Runtime': (basestring, True),
         'Timeout': (positive_integer, False),
     }


Test patch: