Skip to content

Commit 82673ec

Browse files
author
Sid Madipalli
committed
Adding condition for IAM resource
1 parent b01c455 commit 82673ec

File tree

8 files changed

+288
-3
lines changed

8 files changed

+288
-3
lines changed

samtranslator/model/sam_resources.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ def to_cloudformation(self, **kwargs): # type: ignore[no-untyped-def] # noqa: P
394394
intrinsics_resolver,
395395
get_managed_policy_map,
396396
)
397-
self._make_lambda_role(lambda_function, intrinsics_resolver, execution_role, resources)
397+
self._make_lambda_role(lambda_function, intrinsics_resolver, execution_role, resources, conditions)
398398

399399
try:
400400
resources += self._generate_event_resources(
@@ -418,6 +418,7 @@ def _make_lambda_role(
418418
intrinsics_resolver: IntrinsicsResolver,
419419
execution_role: IAMRole,
420420
resources: List[Any],
421+
conditions: Dict[str, Any],
421422
) -> None:
422423
lambda_role = lambda_function.Role
423424

@@ -432,8 +433,17 @@ def _make_lambda_role(
432433
role_resolved_value = intrinsics_resolver.resolve_parameter_refs(self.Role)
433434
role_list = role_resolved_value.get("Fn::If")
434435

435-
# both are none values then we need to create a role
436-
if is_intrinsic_no_value(role_list[1]) and is_intrinsic_no_value(role_list[2]):
436+
is_both_intrinsic_no_values = is_intrinsic_no_value(role_list[1]) and is_intrinsic_no_value(role_list[2])
437+
438+
# When either one of the condition is a non no value we need to conditionally
439+
# create IAM role, This requires generating a condition that negates the condition check
440+
# passed for IAM role creation and use that for the new role being created
441+
if not is_both_intrinsic_no_values:
442+
execution_role.set_resource_attribute("Condition", f"NOT{role_list[0]}")
443+
conditions[f"NOT{role_list[0]}"] = make_not_conditional(role_list[0])
444+
445+
# both are none values, we need to create a role
446+
if is_both_intrinsic_no_values:
437447
lambda_function.Role = execution_role.get_runtime_attr("arn")
438448

439449
# first value is none so we should create condition ? create : [2]
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Parameters:
2+
iamRoleArn:
3+
Type: String
4+
Description: The ARN of an IAM role to use as this function's execution role.
5+
If a role isn't specified, one is created for you with a logical ID of <function-logical-id>Role.
6+
7+
Conditions:
8+
RoleExists: !Not [!Equals ['', !Ref iamRoleArn]]
9+
10+
Resources:
11+
MinimalFunction:
12+
Type: AWS::Serverless::Function
13+
Properties:
14+
CodeUri: s3://sam-demo-bucket/hello.zip
15+
Handler: hello.handler
16+
Runtime: python3.10
17+
Role: !If
18+
- RoleExists
19+
- !Ref "AWS::NoValue"
20+
- !Ref "AWS::NoValue"

tests/translator/output/aws-cn/function_with_iam_role.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
{
22
"Conditions": {
3+
"NOTRoleExists": {
4+
"Fn::Not": [
5+
{
6+
"Condition": "RoleExists"
7+
}
8+
]
9+
},
310
"RoleExists": {
411
"Fn::Not": [
512
{
@@ -52,6 +59,7 @@
5259
"Type": "AWS::Lambda::Function"
5360
},
5461
"MinimalFunctionRole": {
62+
"Condition": "NOTRoleExists",
5563
"Properties": {
5664
"AssumeRolePolicyDocument": {
5765
"Statement": [
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{
2+
"Conditions": {
3+
"RoleExists": {
4+
"Fn::Not": [
5+
{
6+
"Fn::Equals": [
7+
"",
8+
{
9+
"Ref": "iamRoleArn"
10+
}
11+
]
12+
}
13+
]
14+
}
15+
},
16+
"Parameters": {
17+
"iamRoleArn": {
18+
"Description": "The ARN of an IAM role to use as this function's execution role. If a role isn't specified, one is created for you with a logical ID of <function-logical-id>Role.",
19+
"Type": "String"
20+
}
21+
},
22+
"Resources": {
23+
"MinimalFunction": {
24+
"Properties": {
25+
"Code": {
26+
"S3Bucket": "sam-demo-bucket",
27+
"S3Key": "hello.zip"
28+
},
29+
"Handler": "hello.handler",
30+
"Role": {
31+
"Fn::GetAtt": [
32+
"MinimalFunctionRole",
33+
"Arn"
34+
]
35+
},
36+
"Runtime": "python3.10",
37+
"Tags": [
38+
{
39+
"Key": "lambda:createdBy",
40+
"Value": "SAM"
41+
}
42+
]
43+
},
44+
"Type": "AWS::Lambda::Function"
45+
},
46+
"MinimalFunctionRole": {
47+
"Properties": {
48+
"AssumeRolePolicyDocument": {
49+
"Statement": [
50+
{
51+
"Action": [
52+
"sts:AssumeRole"
53+
],
54+
"Effect": "Allow",
55+
"Principal": {
56+
"Service": [
57+
"lambda.amazonaws.com"
58+
]
59+
}
60+
}
61+
],
62+
"Version": "2012-10-17"
63+
},
64+
"ManagedPolicyArns": [
65+
"arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
66+
],
67+
"Tags": [
68+
{
69+
"Key": "lambda:createdBy",
70+
"Value": "SAM"
71+
}
72+
]
73+
},
74+
"Type": "AWS::IAM::Role"
75+
}
76+
}
77+
}

tests/translator/output/aws-us-gov/function_with_iam_role.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
{
22
"Conditions": {
3+
"NOTRoleExists": {
4+
"Fn::Not": [
5+
{
6+
"Condition": "RoleExists"
7+
}
8+
]
9+
},
310
"RoleExists": {
411
"Fn::Not": [
512
{
@@ -52,6 +59,7 @@
5259
"Type": "AWS::Lambda::Function"
5360
},
5461
"MinimalFunctionRole": {
62+
"Condition": "NOTRoleExists",
5563
"Properties": {
5664
"AssumeRolePolicyDocument": {
5765
"Statement": [
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{
2+
"Conditions": {
3+
"RoleExists": {
4+
"Fn::Not": [
5+
{
6+
"Fn::Equals": [
7+
"",
8+
{
9+
"Ref": "iamRoleArn"
10+
}
11+
]
12+
}
13+
]
14+
}
15+
},
16+
"Parameters": {
17+
"iamRoleArn": {
18+
"Description": "The ARN of an IAM role to use as this function's execution role. If a role isn't specified, one is created for you with a logical ID of <function-logical-id>Role.",
19+
"Type": "String"
20+
}
21+
},
22+
"Resources": {
23+
"MinimalFunction": {
24+
"Properties": {
25+
"Code": {
26+
"S3Bucket": "sam-demo-bucket",
27+
"S3Key": "hello.zip"
28+
},
29+
"Handler": "hello.handler",
30+
"Role": {
31+
"Fn::GetAtt": [
32+
"MinimalFunctionRole",
33+
"Arn"
34+
]
35+
},
36+
"Runtime": "python3.10",
37+
"Tags": [
38+
{
39+
"Key": "lambda:createdBy",
40+
"Value": "SAM"
41+
}
42+
]
43+
},
44+
"Type": "AWS::Lambda::Function"
45+
},
46+
"MinimalFunctionRole": {
47+
"Properties": {
48+
"AssumeRolePolicyDocument": {
49+
"Statement": [
50+
{
51+
"Action": [
52+
"sts:AssumeRole"
53+
],
54+
"Effect": "Allow",
55+
"Principal": {
56+
"Service": [
57+
"lambda.amazonaws.com"
58+
]
59+
}
60+
}
61+
],
62+
"Version": "2012-10-17"
63+
},
64+
"ManagedPolicyArns": [
65+
"arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
66+
],
67+
"Tags": [
68+
{
69+
"Key": "lambda:createdBy",
70+
"Value": "SAM"
71+
}
72+
]
73+
},
74+
"Type": "AWS::IAM::Role"
75+
}
76+
}
77+
}

tests/translator/output/function_with_iam_role.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
{
22
"Conditions": {
3+
"NOTRoleExists": {
4+
"Fn::Not": [
5+
{
6+
"Condition": "RoleExists"
7+
}
8+
]
9+
},
310
"RoleExists": {
411
"Fn::Not": [
512
{
@@ -52,6 +59,7 @@
5259
"Type": "AWS::Lambda::Function"
5360
},
5461
"MinimalFunctionRole": {
62+
"Condition": "NOTRoleExists",
5563
"Properties": {
5664
"AssumeRolePolicyDocument": {
5765
"Statement": [
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{
2+
"Conditions": {
3+
"RoleExists": {
4+
"Fn::Not": [
5+
{
6+
"Fn::Equals": [
7+
"",
8+
{
9+
"Ref": "iamRoleArn"
10+
}
11+
]
12+
}
13+
]
14+
}
15+
},
16+
"Parameters": {
17+
"iamRoleArn": {
18+
"Description": "The ARN of an IAM role to use as this function's execution role. If a role isn't specified, one is created for you with a logical ID of <function-logical-id>Role.",
19+
"Type": "String"
20+
}
21+
},
22+
"Resources": {
23+
"MinimalFunction": {
24+
"Properties": {
25+
"Code": {
26+
"S3Bucket": "sam-demo-bucket",
27+
"S3Key": "hello.zip"
28+
},
29+
"Handler": "hello.handler",
30+
"Role": {
31+
"Fn::GetAtt": [
32+
"MinimalFunctionRole",
33+
"Arn"
34+
]
35+
},
36+
"Runtime": "python3.10",
37+
"Tags": [
38+
{
39+
"Key": "lambda:createdBy",
40+
"Value": "SAM"
41+
}
42+
]
43+
},
44+
"Type": "AWS::Lambda::Function"
45+
},
46+
"MinimalFunctionRole": {
47+
"Properties": {
48+
"AssumeRolePolicyDocument": {
49+
"Statement": [
50+
{
51+
"Action": [
52+
"sts:AssumeRole"
53+
],
54+
"Effect": "Allow",
55+
"Principal": {
56+
"Service": [
57+
"lambda.amazonaws.com"
58+
]
59+
}
60+
}
61+
],
62+
"Version": "2012-10-17"
63+
},
64+
"ManagedPolicyArns": [
65+
"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
66+
],
67+
"Tags": [
68+
{
69+
"Key": "lambda:createdBy",
70+
"Value": "SAM"
71+
}
72+
]
73+
},
74+
"Type": "AWS::IAM::Role"
75+
}
76+
}
77+
}

0 commit comments

Comments
 (0)