Repository: getmoto/moto
Pull request: AWS Lambda: Add Role validation when creating functions
Fixes #2546

Adds three validation steps for the IAM role when creating a Lambda function:
 - Does the role follow the appropriate regex
 - Does the role have the current account ID?
 - Does the role exist?

Problem statement:
AWS Lambda - Missing validation for roles when creating functions
When creating a Lambda function, there is no validation whether the role passed in actually exists/is valid.
Every test is set up like this:
```
conn.create_function(
    ....
    Role="test-iam-role",
    ....
```
, circumventing the role-behaviour entirely.

PR to add basic validation will follow shortly

Hints from issue discussion:

Commit message: Implement CloudFormations IAMRole::GetArn

Patch to review:
diff --git a/moto/awslambda/models.py b/moto/awslambda/models.py
index a58582599339..2f00fa94e5ba 100644
--- a/moto/awslambda/models.py
+++ b/moto/awslambda/models.py
@@ -26,6 +26,8 @@
 import boto.awslambda
 from moto.core import BaseBackend, BaseModel
 from moto.core.exceptions import RESTError
+from moto.iam.models import iam_backend
+from moto.iam.exceptions import IAMNotFoundException
 from moto.core.utils import unix_time_millis
 from moto.s3.models import s3_backend
 from moto.logs.models import logs_backends
@@ -667,6 +669,28 @@ def put_function(self, fn):
         :param fn: Function
         :type fn: LambdaFunction
         """
+        pattern = r"arn:(aws[a-zA-Z-]*)?:iam::(\d{12}):role/?[a-zA-Z_0-9+=,.@\-_/]+"
+        valid_role = re.match(pattern, fn.role)
+        if valid_role:
+            account = valid_role.group(2)
+            if account != ACCOUNT_ID:
+                raise ValueError(
+                    "AccessDeniedException", "Cross-account pass role is not allowed."
+                )
+            try:
+                iam_backend.get_role_by_arn(fn.role)
+            except IAMNotFoundException:
+                raise ValueError(
+                    "InvalidParameterValueException",
+                    "The role defined for the function cannot be assumed by Lambda.",
+                )
+        else:
+            raise ValueError(
+                "ValidationException",
+                "1 validation error detected: Value '{0}' at 'role' failed to satisfy constraint: Member must satisfy regular expression pattern: {1}".format(
+                    fn.role, pattern
+                ),
+            )
         if fn.function_name in self._functions:
             self._functions[fn.function_name]["latest"] = fn
         else:
diff --git a/moto/awslambda/responses.py b/moto/awslambda/responses.py
index 62265b3101fa..7734eab60488 100644
--- a/moto/awslambda/responses.py
+++ b/moto/awslambda/responses.py
@@ -214,11 +214,7 @@ def _create_function(self, request, full_url, headers):
         try:
             fn = self.lambda_backend.create_function(self.json_body)
         except ValueError as e:
-            return (
-                400,
-                {},
-                json.dumps({"Error": {"Code": e.args[0], "Message": e.args[1]}}),
-            )
+            return 400, {}, json.dumps({"__type": e.args[0], "message": e.args[1]})
         else:
             config = fn.get_configuration()
             return 201, {}, json.dumps(config)
diff --git a/moto/iam/models.py b/moto/iam/models.py
index 2a76e9126e6d..564a07afb4fc 100644
--- a/moto/iam/models.py
+++ b/moto/iam/models.py
@@ -370,7 +370,7 @@ def get_cfn_attribute(self, attribute_name):
         from moto.cloudformation.exceptions import UnformattedGetAttTemplateException
 
         if attribute_name == "Arn":
-            raise NotImplementedError('"Fn::GetAtt" : [ "{0}" , "Arn" ]"')
+            return self.arn
         raise UnformattedGetAttTemplateException()
 
     def get_tags(self):
diff --git a/tests/test_awslambda/test_lambda.py b/tests/test_awslambda/test_lambda.py
index 306deeea4812..2f104f0498ea 100644
--- a/tests/test_awslambda/test_lambda.py
+++ b/tests/test_awslambda/test_lambda.py
@@ -15,6 +15,7 @@
 from moto import (
     mock_dynamodb2,
     mock_lambda,
+    mock_iam,
     mock_s3,
     mock_ec2,
     mock_sns,
@@ -22,6 +23,7 @@
     settings,
     mock_sqs,
 )
+from moto.sts.models import ACCOUNT_ID
 from nose.tools import assert_raises
 from botocore.exceptions import ClientError
 
@@ -96,7 +98,7 @@ def test_invoke_requestresponse_function():
     conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"ZipFile": get_test_zip_file1()},
         Description="test lambda function",
@@ -129,7 +131,7 @@ def test_invoke_event_function():
     conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"ZipFile": get_test_zip_file1()},
         Description="test lambda function",
@@ -163,7 +165,7 @@ def test_invoke_function_get_ec2_volume():
         conn.create_function(
             FunctionName="testFunction",
             Runtime="python2.7",
-            Role="test-iam-role",
+            Role=get_role_name(),
             Handler="lambda_function.lambda_handler",
             Code={"ZipFile": get_test_zip_file2()},
             Description="test lambda function",
@@ -216,7 +218,7 @@ def test_invoke_function_from_sns():
     result = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"ZipFile": get_test_zip_file3()},
         Description="test lambda function",
@@ -260,7 +262,7 @@ def test_create_based_on_s3_with_missing_bucket():
     conn.create_function.when.called_with(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"S3Bucket": "this-bucket-does-not-exist", "S3Key": "test.zip"},
         Description="test lambda function",
@@ -285,7 +287,7 @@ def test_create_function_from_aws_bucket():
     result = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
         Description="test lambda function",
@@ -306,7 +308,7 @@ def test_create_function_from_aws_bucket():
                 _lambda_region
             ),
             "Runtime": "python2.7",
-            "Role": "test-iam-role",
+            "Role": result["Role"],
             "Handler": "lambda_function.lambda_handler",
             "CodeSha256": hashlib.sha256(zip_content).hexdigest(),
             "CodeSize": len(zip_content),
@@ -332,7 +334,7 @@ def test_create_function_from_zipfile():
     result = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"ZipFile": zip_content},
         Description="test lambda function",
@@ -353,7 +355,7 @@ def test_create_function_from_zipfile():
                 _lambda_region
             ),
             "Runtime": "python2.7",
-            "Role": "test-iam-role",
+            "Role": result["Role"],
             "Handler": "lambda_function.lambda_handler",
             "CodeSize": len(zip_content),
             "Description": "test lambda function",
@@ -381,7 +383,7 @@ def test_get_function():
     conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
         Description="test lambda function",
@@ -412,7 +414,7 @@ def test_get_function():
     result["Configuration"]["FunctionName"].should.equal("testFunction")
     result["Configuration"]["Handler"].should.equal("lambda_function.lambda_handler")
     result["Configuration"]["MemorySize"].should.equal(128)
-    result["Configuration"]["Role"].should.equal("test-iam-role")
+    result["Configuration"]["Role"].should.equal(get_role_name())
     result["Configuration"]["Runtime"].should.equal("python2.7")
     result["Configuration"]["Timeout"].should.equal(3)
     result["Configuration"]["Version"].should.equal("$LATEST")
@@ -449,7 +451,7 @@ def test_get_function_by_arn():
     fnc = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"S3Bucket": bucket_name, "S3Key": "test.zip"},
         Description="test lambda function",
@@ -475,7 +477,7 @@ def test_delete_function():
     conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
         Description="test lambda function",
@@ -510,7 +512,7 @@ def test_delete_function_by_arn():
     fnc = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"S3Bucket": bucket_name, "S3Key": "test.zip"},
         Description="test lambda function",
@@ -545,7 +547,7 @@ def test_publish():
     conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
         Description="test lambda function",
@@ -597,7 +599,7 @@ def test_list_create_list_get_delete_list():
     conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
         Description="test lambda function",
@@ -622,7 +624,7 @@ def test_list_create_list_get_delete_list():
             "FunctionName": "testFunction",
             "Handler": "lambda_function.lambda_handler",
             "MemorySize": 128,
-            "Role": "test-iam-role",
+            "Role": get_role_name(),
             "Runtime": "python2.7",
             "Timeout": 3,
             "Version": "$LATEST",
@@ -663,7 +665,7 @@ def lambda_handler(event, context):
     client.create_function(
         FunctionName="test-lambda-fx",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Description="test lambda function",
         Timeout=3,
@@ -696,7 +698,7 @@ def test_tags():
     function = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.handler",
         Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
         Description="test lambda function",
@@ -764,7 +766,7 @@ def test_invoke_async_function():
     conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"ZipFile": get_test_zip_file1()},
         Description="test lambda function",
@@ -788,7 +790,7 @@ def test_get_function_created_with_zipfile():
     result = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.handler",
         Code={"ZipFile": zip_content},
         Description="test lambda function",
@@ -817,7 +819,7 @@ def test_get_function_created_with_zipfile():
             "FunctionName": "testFunction",
             "Handler": "lambda_function.handler",
             "MemorySize": 128,
-            "Role": "test-iam-role",
+            "Role": get_role_name(),
             "Runtime": "python2.7",
             "Timeout": 3,
             "Version": "$LATEST",
@@ -833,7 +835,7 @@ def test_add_function_permission():
     conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=(get_role_name()),
         Handler="lambda_function.handler",
         Code={"ZipFile": zip_content},
         Description="test lambda function",
@@ -864,7 +866,7 @@ def test_get_function_policy():
     conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.handler",
         Code={"ZipFile": zip_content},
         Description="test lambda function",
@@ -904,7 +906,7 @@ def test_list_versions_by_function():
     conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="arn:aws:iam::123456789012:role/test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
         Description="test lambda function",
@@ -933,7 +935,7 @@ def test_list_versions_by_function():
     conn.create_function(
         FunctionName="testFunction_2",
         Runtime="python2.7",
-        Role="arn:aws:iam::123456789012:role/test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
         Description="test lambda function",
@@ -962,7 +964,7 @@ def test_create_function_with_already_exists():
     conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
         Description="test lambda function",
@@ -974,7 +976,7 @@ def test_create_function_with_already_exists():
     response = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
         Description="test lambda function",
@@ -1006,7 +1008,7 @@ def test_create_event_source_mapping():
     func = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"ZipFile": get_test_zip_file3()},
         Description="test lambda function",
@@ -1036,7 +1038,7 @@ def test_invoke_function_from_sqs():
     func = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"ZipFile": get_test_zip_file3()},
         Description="test lambda function",
@@ -1096,7 +1098,7 @@ def test_invoke_function_from_dynamodb():
     func = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"ZipFile": get_test_zip_file3()},
         Description="test lambda function executed after a DynamoDB table is updated",
@@ -1147,7 +1149,7 @@ def test_invoke_function_from_sqs_exception():
     func = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"ZipFile": get_test_zip_file4()},
         Description="test lambda function",
@@ -1206,7 +1208,7 @@ def test_list_event_source_mappings():
     func = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"ZipFile": get_test_zip_file3()},
         Description="test lambda function",
@@ -1238,7 +1240,7 @@ def test_get_event_source_mapping():
     func = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"ZipFile": get_test_zip_file3()},
         Description="test lambda function",
@@ -1268,7 +1270,7 @@ def test_update_event_source_mapping():
     func1 = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"ZipFile": get_test_zip_file3()},
         Description="test lambda function",
@@ -1279,7 +1281,7 @@ def test_update_event_source_mapping():
     func2 = conn.create_function(
         FunctionName="testFunction2",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"ZipFile": get_test_zip_file3()},
         Description="test lambda function",
@@ -1312,7 +1314,7 @@ def test_delete_event_source_mapping():
     func1 = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"ZipFile": get_test_zip_file3()},
         Description="test lambda function",
@@ -1348,7 +1350,7 @@ def test_update_configuration():
     fxn = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
         Description="test lambda function",
@@ -1393,7 +1395,7 @@ def test_update_function_zip():
     fxn = conn.create_function(
         FunctionName="testFunctionZip",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"ZipFile": zip_content_one},
         Description="test lambda function",
@@ -1428,7 +1430,7 @@ def test_update_function_zip():
             "FunctionName": "testFunctionZip",
             "Handler": "lambda_function.lambda_handler",
             "MemorySize": 128,
-            "Role": "test-iam-role",
+            "Role": fxn["Role"],
             "Runtime": "python2.7",
             "Timeout": 3,
             "Version": "2",
@@ -1451,7 +1453,7 @@ def test_update_function_s3():
     fxn = conn.create_function(
         FunctionName="testFunctionS3",
         Runtime="python2.7",
-        Role="test-iam-role",
+        Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
         Description="test lambda function",
@@ -1490,10 +1492,67 @@ def test_update_function_s3():
             "FunctionName": "testFunctionS3",
             "Handler": "lambda_function.lambda_handler",
             "MemorySize": 128,
-            "Role": "test-iam-role",
+            "Role": fxn["Role"],
             "Runtime": "python2.7",
             "Timeout": 3,
             "Version": "2",
             "VpcConfig": {"SecurityGroupIds": [], "SubnetIds": []},
         }
     )
+
+
+@mock_lambda
+def test_create_function_with_invalid_arn():
+    err = create_invalid_lambda("test-iam-role")
+    err.exception.response["Error"]["Code"].should.equal("ValidationException")
+    err.exception.response["Error"]["Message"].should.equal(
+        "1 validation error detected: Value 'test-iam-role' at 'role' failed to satisfy constraint: Member must satisfy regular expression pattern: arn:(aws[a-zA-Z-]*)?:iam::(\d{12}):role/?[a-zA-Z_0-9+=,.@\-_/]+"
+    )
+
+
+@mock_lambda
+def test_create_function_with_arn_from_different_account():
+    err = create_invalid_lambda("arn:aws:iam::000000000000:role/example_role")
+    err.exception.response["Error"]["Code"].should.equal("AccessDeniedException")
+    err.exception.response["Error"]["Message"].should.equal(
+        "Cross-account pass role is not allowed."
+    )
+
+
+@mock_lambda
+def test_create_function_with_unknown_arn():
+    err = create_invalid_lambda(
+        "arn:aws:iam::" + str(ACCOUNT_ID) + ":role/service-role/unknown_role"
+    )
+    err.exception.response["Error"]["Code"].should.equal(
+        "InvalidParameterValueException"
+    )
+    err.exception.response["Error"]["Message"].should.equal(
+        "The role defined for the function cannot be assumed by Lambda."
+    )
+
+
+def create_invalid_lambda(role):
+    conn = boto3.client("lambda", "us-west-2")
+    zip_content = get_test_zip_file1()
+    with assert_raises(ClientError) as err:
+        conn.create_function(
+            FunctionName="testFunction",
+            Runtime="python2.7",
+            Role=role,
+            Handler="lambda_function.handler",
+            Code={"ZipFile": zip_content},
+            Description="test lambda function",
+            Timeout=3,
+            MemorySize=128,
+            Publish=True,
+        )
+    return err
+
+
+def get_role_name():
+    with mock_iam():
+        iam = boto3.client("iam")
+        return iam.create_role(
+            RoleName="my-role", AssumeRolePolicyDocument="some policy", Path="/my-path/"
+        )["Role"]["Arn"]
diff --git a/tests/test_awslambda/test_lambda_eventsourcemappings.py b/tests/test_awslambda/test_lambda_eventsourcemappings.py
deleted file mode 100644
index e69de29bb2d1..000000000000
diff --git a/tests/test_cloudformation/test_cloudformation_stack_crud.py b/tests/test_cloudformation/test_cloudformation_stack_crud.py
index bfd66935a74f..efd4eb0fd3ed 100644
--- a/tests/test_cloudformation/test_cloudformation_stack_crud.py
+++ b/tests/test_cloudformation/test_cloudformation_stack_crud.py
@@ -4,6 +4,7 @@
 import json
 
 import boto
+import boto.iam
 import boto.s3
 import boto.s3.key
 import boto.cloudformation
@@ -20,6 +21,7 @@
     mock_route53_deprecated,
 )
 from moto.cloudformation import cloudformation_backends
+from moto.iam import mock_iam_deprecated
 
 dummy_template = {
     "AWSTemplateFormatVersion": "2010-09-09",
@@ -516,7 +518,7 @@ def test_create_stack_lambda_and_dynamodb():
                     "Code": {"S3Bucket": "bucket_123", "S3Key": "key_123"},
                     "FunctionName": "func1",
                     "Handler": "handler.handler",
-                    "Role": "role1",
+                    "Role": get_role_name(),
                     "Runtime": "python2.7",
                     "Description": "descr",
                     "MemorySize": 12345,
@@ -591,3 +593,12 @@ def test_create_stack_kinesis():
     stack = conn.describe_stacks()[0]
     resources = stack.list_resources()
     assert len(resources) == 1
+
+
+def get_role_name():
+    with mock_iam_deprecated():
+        iam = boto.connect_iam()
+        role = iam.create_role("my-role")["create_role_response"]["create_role_result"][
+            "role"
+        ]["arn"]
+        return role
diff --git a/tests/test_cloudformation/test_cloudformation_stack_integration.py b/tests/test_cloudformation/test_cloudformation_stack_integration.py
index ced6b2005a93..e789f6e6b84d 100644
--- a/tests/test_cloudformation/test_cloudformation_stack_integration.py
+++ b/tests/test_cloudformation/test_cloudformation_stack_integration.py
@@ -1773,11 +1773,25 @@ def lambda_handler(event, context):
                     "Handler": "lambda_function.handler",
                     "Description": "Test function",
                     "MemorySize": 128,
-                    "Role": "test-role",
+                    "Role": {"Fn::GetAtt": ["MyRole", "Arn"]},
                     "Runtime": "python2.7",
                     "Environment": {"Variables": {"TEST_ENV_KEY": "test-env-val"}},
                 },
-            }
+            },
+            "MyRole": {
+                "Type": "AWS::IAM::Role",
+                "Properties": {
+                    "AssumeRolePolicyDocument": {
+                        "Statement": [
+                            {
+                                "Action": ["sts:AssumeRole"],
+                                "Effect": "Allow",
+                                "Principal": {"Service": ["ec2.amazonaws.com"]},
+                            }
+                        ]
+                    }
+                },
+            },
         },
     }
 
@@ -1791,7 +1805,6 @@ def lambda_handler(event, context):
     result["Functions"][0]["Description"].should.equal("Test function")
     result["Functions"][0]["Handler"].should.equal("lambda_function.handler")
     result["Functions"][0]["MemorySize"].should.equal(128)
-    result["Functions"][0]["Role"].should.equal("test-role")
     result["Functions"][0]["Runtime"].should.equal("python2.7")
     result["Functions"][0]["Environment"].should.equal(
         {"Variables": {"TEST_ENV_KEY": "test-env-val"}}


Code review comments:
diff_hunk: @@ -667,6 +669,28 @@ def put_function(self, fn):
         :param fn: Function
         :type fn: LambdaFunction
         """
+        pattern = r"arn:(aws[a-zA-Z-]*)?:iam::(\d{12}):role/?[a-zA-Z_0-9+=,.@\-_/]+"
+        valid_role = re.match(pattern, fn.role)
+        if valid_role:
+            account = valid_role.group(2)
+            if account != ACCOUNT_ID:
+                raise ValueError(
path: moto/awslambda/models.py
text: @user1:
Please add the specific exceptions to the corresponding `exceptions.py` file to implement one of the moto exception classes.

diff_hunk: @@ -214,11 +214,7 @@ def _create_function(self, request, full_url, headers):
         try:
path: moto/awslambda/responses.py
text: @user1:
You can remove the `try...except` if you use one of the moto exception classes.