diff --git a/requirements/dev.txt b/requirements/dev.txt
index 0d03166e75..07d399e592 100644
--- a/requirements/dev.txt
+++ b/requirements/dev.txt
@@ -2,7 +2,7 @@ coverage>=4.4.0
flake8>=3.3.0
tox>=2.2.1
pytest-cov>=2.4.0
-pylint>=1.7.2
+pylint>=1.7.2,<2.0
pyyaml>=4.2b1
# Test requirements
diff --git a/samtranslator/model/iam.py b/samtranslator/model/iam.py
index fc9039c28f..fe39be9623 100644
--- a/samtranslator/model/iam.py
+++ b/samtranslator/model/iam.py
@@ -9,7 +9,8 @@ class IAMRole(Resource):
'AssumeRolePolicyDocument': PropertyType(True, is_type(dict)),
'ManagedPolicyArns': PropertyType(False, is_type(list)),
'Path': PropertyType(False, is_str()),
- 'Policies': PropertyType(False, is_type(list))
+ 'Policies': PropertyType(False, is_type(list)),
+ 'PermissionsBoundary': PropertyType(False, is_str())
}
runtime_attrs = {
diff --git a/samtranslator/model/s3_utils/uri_parser.py b/samtranslator/model/s3_utils/uri_parser.py
index b276ad6b6e..371cfb923f 100644
--- a/samtranslator/model/s3_utils/uri_parser.py
+++ b/samtranslator/model/s3_utils/uri_parser.py
@@ -43,7 +43,7 @@ def to_s3_uri(code_dict):
raise TypeError("Code location should be a dictionary")
if version:
- uri += "?versionId=" + version
+ uri += "?versionId=" + version
return uri
diff --git a/samtranslator/model/sam_resources.py b/samtranslator/model/sam_resources.py
index 35207953cc..c9bdcfcb61 100644
--- a/samtranslator/model/sam_resources.py
+++ b/samtranslator/model/sam_resources.py
@@ -42,6 +42,7 @@ class SamFunction(SamResourceMacro):
'VpcConfig': PropertyType(False, is_type(dict)),
'Role': PropertyType(False, is_str()),
'Policies': PropertyType(False, one_of(is_str(), list_of(one_of(is_str(), is_type(dict), is_type(dict))))),
+ 'PermissionsBoundary': PropertyType(False, is_str()),
'Environment': PropertyType(False, dict_of(is_str(), is_type(dict))),
'Events': PropertyType(False, dict_of(is_str(), is_type(dict))),
'Tags': PropertyType(False, is_type(dict)),
@@ -239,6 +240,7 @@ def _construct_role(self, managed_policy_map):
execution_role.ManagedPolicyArns = list(managed_policy_arns)
execution_role.Policies = policy_documents or None
+ execution_role.PermissionsBoundary = self.PermissionsBoundary
return execution_role
diff --git a/samtranslator/plugins/globals/globals.py b/samtranslator/plugins/globals/globals.py
index 7864a2abd8..918f458451 100644
--- a/samtranslator/plugins/globals/globals.py
+++ b/samtranslator/plugins/globals/globals.py
@@ -29,7 +29,8 @@ class Globals(object):
"KmsKeyArn",
"AutoPublishAlias",
"Layers",
- "DeploymentPreference"
+ "DeploymentPreference",
+ "PermissionsBoundary"
],
# Everything except
diff --git a/samtranslator/translator/translator.py b/samtranslator/translator/translator.py
index f8b9618a4c..49cf2e7464 100644
--- a/samtranslator/translator/translator.py
+++ b/samtranslator/translator/translator.py
@@ -110,7 +110,7 @@ def translate(self, sam_template, parameter_values):
if 'Transform' in template:
del template['Transform']
- if len(document_errors) is 0:
+ if len(document_errors) == 0:
template = intrinsics_resolver.resolve_sam_resource_id_refs(template, changed_logical_ids)
template = intrinsics_resolver.resolve_sam_resource_refs(template, supported_resource_refs)
return template
diff --git a/tests/translator/input/function_with_permissions_boundary.yaml b/tests/translator/input/function_with_permissions_boundary.yaml
new file mode 100644
index 0000000000..5cad58b7f9
--- /dev/null
+++ b/tests/translator/input/function_with_permissions_boundary.yaml
@@ -0,0 +1,9 @@
+Resources:
+ MinimalFunction:
+ Type: 'AWS::Serverless::Function'
+ Properties:
+ CodeUri: s3://sam-demo-bucket/hello.zip
+ Handler: hello.handler
+ Runtime: python2.7
+ PermissionsBoundary: arn:aws:1234:iam:boundary/CustomerCreatedPermissionsBoundary
+
diff --git a/tests/translator/input/globals_for_function.yaml b/tests/translator/input/globals_for_function.yaml
index 202c32eac6..97fd5ae30c 100644
--- a/tests/translator/input/globals_for_function.yaml
+++ b/tests/translator/input/globals_for_function.yaml
@@ -16,6 +16,7 @@ Globals:
tag1: value1
Tracing: Active
AutoPublishAlias: live
+ PermissionsBoundary: arn:aws:1234:iam:boundary/CustomerCreatedPermissionsBoundary
Layers:
- !Sub arn:${AWS:Partition}:lambda:${AWS:Region}:${AWS:AccountId}:layer:MyLayer:1
@@ -41,6 +42,7 @@ Resources:
newtag1: newvalue1
Tracing: PassThrough
AutoPublishAlias: prod
+ PermissionsBoundary: arn:aws:1234:iam:boundary/OverridePermissionsBoundary
Layers:
- !Sub arn:${AWS:Partition}:lambda:${AWS:Region}:${AWS:AccountId}:layer:MyLayer2:2
diff --git a/tests/translator/output/aws-cn/function_with_permissions_boundary.json b/tests/translator/output/aws-cn/function_with_permissions_boundary.json
new file mode 100644
index 0000000000..1adb21c16a
--- /dev/null
+++ b/tests/translator/output/aws-cn/function_with_permissions_boundary.json
@@ -0,0 +1,52 @@
+{
+ "Resources": {
+ "MinimalFunctionRole": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "ManagedPolicyArns": [
+ "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ],
+ "PermissionsBoundary": "arn:aws:1234:iam:boundary/CustomerCreatedPermissionsBoundary",
+ "AssumeRolePolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Action": [
+ "sts:AssumeRole"
+ ],
+ "Effect": "Allow",
+ "Principal": {
+ "Service": [
+ "lambda.amazonaws.com"
+ ]
+ }
+ }
+ ]
+ }
+ }
+ },
+ "MinimalFunction": {
+ "Type": "AWS::Lambda::Function",
+ "Properties": {
+ "Handler": "hello.handler",
+ "Code": {
+ "S3Bucket": "sam-demo-bucket",
+ "S3Key": "hello.zip"
+ },
+ "Role": {
+ "Fn::GetAtt": [
+ "MinimalFunctionRole",
+ "Arn"
+ ]
+ },
+ "Runtime": "python2.7",
+ "Tags": [
+ {
+ "Value": "SAM",
+ "Key": "lambda:createdBy"
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/tests/translator/output/aws-cn/globals_for_function.json b/tests/translator/output/aws-cn/globals_for_function.json
index 82f9da5a54..e2115176f0 100644
--- a/tests/translator/output/aws-cn/globals_for_function.json
+++ b/tests/translator/output/aws-cn/globals_for_function.json
@@ -7,6 +7,7 @@
"arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
"arn:aws-cn:iam::aws:policy/AWSXrayWriteOnlyAccess"
],
+ "PermissionsBoundary": "arn:aws:1234:iam:boundary/OverridePermissionsBoundary",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
@@ -85,6 +86,7 @@
"arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
"arn:aws-cn:iam::aws:policy/AWSXrayWriteOnlyAccess"
],
+ "PermissionsBoundary": "arn:aws:1234:iam:boundary/CustomerCreatedPermissionsBoundary",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
@@ -198,4 +200,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/translator/output/aws-us-gov/function_with_permissions_boundary.json b/tests/translator/output/aws-us-gov/function_with_permissions_boundary.json
new file mode 100644
index 0000000000..510988482d
--- /dev/null
+++ b/tests/translator/output/aws-us-gov/function_with_permissions_boundary.json
@@ -0,0 +1,52 @@
+{
+ "Resources": {
+ "MinimalFunctionRole": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "ManagedPolicyArns": [
+ "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ],
+ "PermissionsBoundary": "arn:aws:1234:iam:boundary/CustomerCreatedPermissionsBoundary",
+ "AssumeRolePolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Action": [
+ "sts:AssumeRole"
+ ],
+ "Effect": "Allow",
+ "Principal": {
+ "Service": [
+ "lambda.amazonaws.com"
+ ]
+ }
+ }
+ ]
+ }
+ }
+ },
+ "MinimalFunction": {
+ "Type": "AWS::Lambda::Function",
+ "Properties": {
+ "Handler": "hello.handler",
+ "Code": {
+ "S3Bucket": "sam-demo-bucket",
+ "S3Key": "hello.zip"
+ },
+ "Role": {
+ "Fn::GetAtt": [
+ "MinimalFunctionRole",
+ "Arn"
+ ]
+ },
+ "Runtime": "python2.7",
+ "Tags": [
+ {
+ "Value": "SAM",
+ "Key": "lambda:createdBy"
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/tests/translator/output/aws-us-gov/globals_for_function.json b/tests/translator/output/aws-us-gov/globals_for_function.json
index ad68dde1bb..d001267095 100644
--- a/tests/translator/output/aws-us-gov/globals_for_function.json
+++ b/tests/translator/output/aws-us-gov/globals_for_function.json
@@ -7,6 +7,7 @@
"arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
"arn:aws-us-gov:iam::aws:policy/AWSXrayWriteOnlyAccess"
],
+ "PermissionsBoundary": "arn:aws:1234:iam:boundary/OverridePermissionsBoundary",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
@@ -85,6 +86,7 @@
"arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
"arn:aws-us-gov:iam::aws:policy/AWSXrayWriteOnlyAccess"
],
+ "PermissionsBoundary": "arn:aws:1234:iam:boundary/CustomerCreatedPermissionsBoundary",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
@@ -198,4 +200,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/translator/output/error_globals_unsupported_property.json b/tests/translator/output/error_globals_unsupported_property.json
index 87a48e5174..4805f3f4ee 100644
--- a/tests/translator/output/error_globals_unsupported_property.json
+++ b/tests/translator/output/error_globals_unsupported_property.json
@@ -1,8 +1,8 @@
{
"errors": [
{
- "errorMessage": "'Globals' section is invalid. 'SomeKey' is not a supported property of 'Function'. Must be one of the following values - ['Handler', 'Runtime', 'CodeUri', 'DeadLetterQueue', 'Description', 'MemorySize', 'Timeout', 'VpcConfig', 'Environment', 'Tags', 'Tracing', 'KmsKeyArn', 'AutoPublishAlias', 'Layers', 'DeploymentPreference']"
+ "errorMessage": "'Globals' section is invalid. 'SomeKey' is not a supported property of 'Function'. Must be one of the following values - ['Handler', 'Runtime', 'CodeUri', 'DeadLetterQueue', 'Description', 'MemorySize', 'Timeout', 'VpcConfig', 'Environment', 'Tags', 'Tracing', 'KmsKeyArn', 'AutoPublishAlias', 'Layers', 'DeploymentPreference', 'PermissionsBoundary']"
}
],
- "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. 'Globals' section is invalid. 'SomeKey' is not a supported property of 'Function'. Must be one of the following values - ['Handler', 'Runtime', 'CodeUri', 'DeadLetterQueue', 'Description', 'MemorySize', 'Timeout', 'VpcConfig', 'Environment', 'Tags', 'Tracing', 'KmsKeyArn', 'AutoPublishAlias', 'Layers', 'DeploymentPreference']"
-}
\ No newline at end of file
+ "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. 'Globals' section is invalid. 'SomeKey' is not a supported property of 'Function'. Must be one of the following values - ['Handler', 'Runtime', 'CodeUri', 'DeadLetterQueue', 'Description', 'MemorySize', 'Timeout', 'VpcConfig', 'Environment', 'Tags', 'Tracing', 'KmsKeyArn', 'AutoPublishAlias', 'Layers', 'DeploymentPreference', 'PermissionsBoundary']"
+}
diff --git a/tests/translator/output/function_with_permissions_boundary.json b/tests/translator/output/function_with_permissions_boundary.json
new file mode 100644
index 0000000000..ecd3a1e0b8
--- /dev/null
+++ b/tests/translator/output/function_with_permissions_boundary.json
@@ -0,0 +1,52 @@
+{
+ "Resources": {
+ "MinimalFunctionRole": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "ManagedPolicyArns": [
+ "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ],
+ "PermissionsBoundary": "arn:aws:1234:iam:boundary/CustomerCreatedPermissionsBoundary",
+ "AssumeRolePolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Action": [
+ "sts:AssumeRole"
+ ],
+ "Effect": "Allow",
+ "Principal": {
+ "Service": [
+ "lambda.amazonaws.com"
+ ]
+ }
+ }
+ ]
+ }
+ }
+ },
+ "MinimalFunction": {
+ "Type": "AWS::Lambda::Function",
+ "Properties": {
+ "Handler": "hello.handler",
+ "Code": {
+ "S3Bucket": "sam-demo-bucket",
+ "S3Key": "hello.zip"
+ },
+ "Role": {
+ "Fn::GetAtt": [
+ "MinimalFunctionRole",
+ "Arn"
+ ]
+ },
+ "Runtime": "python2.7",
+ "Tags": [
+ {
+ "Value": "SAM",
+ "Key": "lambda:createdBy"
+ }
+ ]
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/translator/output/globals_for_function.json b/tests/translator/output/globals_for_function.json
index 051c63fbe2..3006cce738 100644
--- a/tests/translator/output/globals_for_function.json
+++ b/tests/translator/output/globals_for_function.json
@@ -7,6 +7,7 @@
"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
"arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess"
],
+ "PermissionsBoundary": "arn:aws:1234:iam:boundary/OverridePermissionsBoundary",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
@@ -85,6 +86,7 @@
"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
"arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess"
],
+ "PermissionsBoundary": "arn:aws:1234:iam:boundary/CustomerCreatedPermissionsBoundary",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
@@ -198,4 +200,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/translator/test_translator.py b/tests/translator/test_translator.py
index a40b569c70..5f9d371ff0 100644
--- a/tests/translator/test_translator.py
+++ b/tests/translator/test_translator.py
@@ -206,6 +206,7 @@ class TestTranslatorEndToEnd(TestCase):
'function_with_global_layers',
'function_with_layers',
'function_with_many_layers',
+ 'function_with_permissions_boundary',
'function_with_policy_templates',
'function_with_sns_event_source_all_parameters',
'globals_for_function',
diff --git a/tests/translator/validator/test_validator.py b/tests/translator/validator/test_validator.py
index 34f0fdac4b..ebf1ad6a87 100644
--- a/tests/translator/validator/test_validator.py
+++ b/tests/translator/validator/test_validator.py
@@ -57,6 +57,7 @@
'function_with_resource_refs',
'function_with_deployment_and_custom_role',
'function_with_deployment_no_service_role',
+ 'function_with_permissions_boundary',
'function_with_policy_templates',
'function_with_sns_event_source_all_parameters',
'globals_for_function',
diff --git a/versions/2016-10-31.md b/versions/2016-10-31.md
index ad6fea0a8e..f3a8b60883 100644
--- a/versions/2016-10-31.md
+++ b/versions/2016-10-31.md
@@ -113,6 +113,7 @@ MemorySize | `integer` | Size of the memory allocated per invocation of the func
Timeout | `integer` | Maximum time that the function can run before it is killed in seconds. Defaults to 3.
Role | `string` | ARN of an IAM role to use as this function's execution role. If omitted, a default role is created for this function.
Policies | `string` | List of `string` | [IAM policy document object](http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies.html) | List of [IAM policy document object](http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies.html) | List of [SAM Policy Templates](../docs/policy_templates.rst) | Names of AWS managed IAM policies or IAM policy documents or SAM Policy Templates that this function needs, which should be appended to the default role for this function. If the Role property is set, this property has no meaning.
+PermissionsBoundary | `string` | ARN of a permissions boundary to use for this function's execution role.
Environment | [Function environment object](#environment-object) | Configuration for the runtime environment.
VpcConfig | [VPC config object](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-vpcconfig.html) | Configuration to enable this function to access private resources within your VPC.
Events | Map of `string` to [Event source object](#event-source-object) | A map (string to [Event source object](#event-source-object)) that defines the events that trigger this function. Keys are limited to alphanumeric characters.