Skip to content

Commit 5d700f7

Browse files
Connor Robertsonhoffa
andauthored
feat: Add RolePath support for AWS::Serverless::StateMachine (#2684)
Co-authored-by: Chris Rehn <1280602+hoffa@users.noreply.github.com>
1 parent 1437497 commit 5d700f7

File tree

11 files changed

+304
-0
lines changed

11 files changed

+304
-0
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[
2+
{
3+
"LogicalResourceId": "MyBasicStateMachine",
4+
"ResourceType": "AWS::StepFunctions::StateMachine"
5+
},
6+
{
7+
"LogicalResourceId": "MyBasicStateMachineRole",
8+
"ResourceType": "AWS::IAM::Role"
9+
}
10+
]
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Resources:
2+
MyBasicStateMachine:
3+
Type: AWS::Serverless::StateMachine
4+
Properties:
5+
Type: STANDARD
6+
Definition:
7+
Comment: A Hello World example of the Amazon States Language using Pass states
8+
StartAt: Hello
9+
States:
10+
Hello:
11+
Type: Pass
12+
Result: Hello
13+
Next: World
14+
World:
15+
Type: Pass
16+
Result: World
17+
End: true
18+
RolePath: /foo/bar/
19+
Metadata:
20+
SamTransformTest: true

integration/single/test_basic_state_machine.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,18 @@ def test_basic_state_machine_with_tags(self):
3434
self._verify_tag_presence(tags, "TagOne", "ValueOne")
3535
self._verify_tag_presence(tags, "TagTwo", "ValueTwo")
3636

37+
def test_state_machine_with_role_path(self):
38+
"""
39+
Creates a State machine with a Role Path
40+
"""
41+
self.create_and_verify_stack("single/state_machine_with_role_path")
42+
43+
role_name = self.get_physical_id_by_type("AWS::IAM::Role")
44+
iam_client = self.client_provider.iam_client
45+
response = iam_client.get_role(RoleName=role_name)
46+
47+
self.assertEqual(response["Role"]["Path"], "/foo/bar/")
48+
3749
def _verify_tag_presence(self, tags, key, value):
3850
"""
3951
Verifies the presence of a tag and its value

samtranslator/model/sam_resources.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,6 +1691,7 @@ class SamStateMachine(SamResourceMacro):
16911691
"DefinitionUri": PropertyType(False, one_of(is_str(), is_type(dict))),
16921692
"Logging": PropertyType(False, is_type(dict)),
16931693
"Role": PropertyType(False, is_str()),
1694+
"RolePath": PassThroughProperty(False),
16941695
"DefinitionSubstitutions": PropertyType(False, is_type(dict)),
16951696
"Events": PropertyType(False, dict_of(is_str(), is_type(dict))),
16961697
"Name": PropertyType(False, is_str()),
@@ -1705,6 +1706,7 @@ class SamStateMachine(SamResourceMacro):
17051706
DefinitionUri: Optional[Intrinsicable[str]]
17061707
Logging: Optional[Dict[str, Any]]
17071708
Role: Optional[Intrinsicable[str]]
1709+
RolePath: Optional[PassThrough]
17081710
DefinitionSubstitutions: Optional[Dict[str, Any]]
17091711
Events: Optional[Dict[str, Any]]
17101712
Name: Optional[Intrinsicable[str]]
@@ -1738,6 +1740,7 @@ def to_cloudformation(self, **kwargs): # type: ignore[no-untyped-def]
17381740
permissions_boundary=self.PermissionsBoundary,
17391741
definition_substitutions=self.DefinitionSubstitutions,
17401742
role=self.Role,
1743+
role_path=self.RolePath,
17411744
state_machine_type=self.Type,
17421745
tracing=self.Tracing,
17431746
events=self.Events,

samtranslator/model/stepfunctions/generators.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ def __init__( # type: ignore[no-untyped-def]
4444
events,
4545
event_resources,
4646
event_resolver,
47+
role_path=None,
4748
tags=None,
4849
resource_attributes=None,
4950
passthrough_resource_attributes=None,
@@ -63,6 +64,7 @@ def __init__( # type: ignore[no-untyped-def]
6364
:param permissions_boundary: The ARN of the policy used to set the permissions boundary for the role
6465
:param definition_substitutions: Variable-to-value mappings to be replaced in the State Machine definition
6566
:param role: Role ARN to use for the execution role
67+
:param role_path: The file path of the execution role
6668
:param state_machine_type: Type of the State Machine
6769
:param tracing: Tracing configuration for the State Machine
6870
:param events: List of event sources for the State Machine
@@ -86,6 +88,7 @@ def __init__( # type: ignore[no-untyped-def]
8688
self.permissions_boundary = permissions_boundary
8789
self.definition_substitutions = definition_substitutions
8890
self.role = role
91+
self.role_path = role_path
8992
self.type = state_machine_type
9093
self.tracing = tracing
9194
self.events = events
@@ -220,6 +223,7 @@ def _construct_role(self): # type: ignore[no-untyped-def]
220223

221224
execution_role = construct_role_for_resource(
222225
resource_logical_id=self.logical_id,
226+
role_path=self.role_path,
223227
attributes=self.passthrough_resource_attributes,
224228
managed_policy_map=self.managed_policy_map,
225229
assume_role_policy_document=IAMRolePolicies.stepfunctions_assume_role_policy(), # type: ignore[no-untyped-call]

samtranslator/schema/aws_serverless_statemachine.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ class Properties(BaseModel):
145145
PermissionsBoundary: Optional[PassThrough] = properties("PermissionsBoundary")
146146
Policies: Optional[Union[str, DictStrAny, List[Union[str, DictStrAny]]]] = properties("Policies")
147147
Role: Optional[PassThrough] = properties("Role")
148+
RolePath: Optional[PassThrough] # TODO: Add docs
148149
Tags: Optional[DictStrAny] = properties("Tags")
149150
Tracing: Optional[PassThrough] = properties("Tracing")
150151
Type: Optional[PassThrough] = properties("Type")

samtranslator/schema/schema.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4900,6 +4900,9 @@
49004900
"description": "The ARN of an IAM role to use as this state machine's execution role\\. \nYou must provide either a `Role` or `Policies`\\. \n*Type*: String \n*Required*: Conditional \n*AWS CloudFormation compatibility*: This property is passed directly to the [`RoleArn`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html#cfn-stepfunctions-statemachine-rolearn) property of an `AWS::StepFunctions::StateMachine` resource\\.",
49014901
"markdownDescription": "The ARN of an IAM role to use as this state machine's execution role\\. \nYou must provide either a `Role` or `Policies`\\. \n*Type*: String \n*Required*: Conditional \n*AWS CloudFormation compatibility*: This property is passed directly to the [`RoleArn`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html#cfn-stepfunctions-statemachine-rolearn) property of an `AWS::StepFunctions::StateMachine` resource\\."
49024902
},
4903+
"RolePath": {
4904+
"title": "Rolepath"
4905+
},
49034906
"Tags": {
49044907
"title": "Tags",
49054908
"description": "A string\\-to\\-string map that specifies the tags added to the state machine and the corresponding execution role\\. For information about valid keys and values for tags, see the [Tags](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html#cfn-stepfunctions-statemachine-tags) property of an [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html) resource\\. \n*Type*: Map \n*Required*: No \n*AWS CloudFormation compatibility*: This property is similar to the [`Tags`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html#cfn-stepfunctions-statemachine-tags) property of an `AWS::StepFunctions::StateMachine` resource\\. AWS SAM automatically adds a `stateMachine:createdBy:SAM` tag to this resource, and to the default role that is generated for it\\.",
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Resources:
2+
MyBasicStateMachine:
3+
Type: AWS::Serverless::StateMachine
4+
Properties:
5+
Type: STANDARD
6+
Definition:
7+
Comment: A Hello World example of the Amazon States Language using Pass states
8+
StartAt: Hello
9+
States:
10+
Hello:
11+
Type: Pass
12+
Result: Hello
13+
Next: World
14+
World:
15+
Type: Pass
16+
Result: World
17+
End: true
18+
RolePath: /foo/bar/
19+
Metadata:
20+
SamTransformTest: true
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{
2+
"Metadata": {
3+
"SamTransformTest": true
4+
},
5+
"Resources": {
6+
"MyBasicStateMachine": {
7+
"Properties": {
8+
"DefinitionString": {
9+
"Fn::Join": [
10+
"\n",
11+
[
12+
"{",
13+
" \"Comment\": \"A Hello World example of the Amazon States Language using Pass states\",",
14+
" \"StartAt\": \"Hello\",",
15+
" \"States\": {",
16+
" \"Hello\": {",
17+
" \"Next\": \"World\",",
18+
" \"Result\": \"Hello\",",
19+
" \"Type\": \"Pass\"",
20+
" },",
21+
" \"World\": {",
22+
" \"End\": true,",
23+
" \"Result\": \"World\",",
24+
" \"Type\": \"Pass\"",
25+
" }",
26+
" }",
27+
"}"
28+
]
29+
]
30+
},
31+
"RoleArn": {
32+
"Fn::GetAtt": [
33+
"MyBasicStateMachineRole",
34+
"Arn"
35+
]
36+
},
37+
"StateMachineType": "STANDARD",
38+
"Tags": [
39+
{
40+
"Key": "stateMachine:createdBy",
41+
"Value": "SAM"
42+
}
43+
]
44+
},
45+
"Type": "AWS::StepFunctions::StateMachine"
46+
},
47+
"MyBasicStateMachineRole": {
48+
"Properties": {
49+
"AssumeRolePolicyDocument": {
50+
"Statement": [
51+
{
52+
"Action": [
53+
"sts:AssumeRole"
54+
],
55+
"Effect": "Allow",
56+
"Principal": {
57+
"Service": [
58+
"states.amazonaws.com"
59+
]
60+
}
61+
}
62+
],
63+
"Version": "2012-10-17"
64+
},
65+
"ManagedPolicyArns": [],
66+
"Path": "/foo/bar/",
67+
"Tags": [
68+
{
69+
"Key": "stateMachine:createdBy",
70+
"Value": "SAM"
71+
}
72+
]
73+
},
74+
"Type": "AWS::IAM::Role"
75+
}
76+
}
77+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{
2+
"Metadata": {
3+
"SamTransformTest": true
4+
},
5+
"Resources": {
6+
"MyBasicStateMachine": {
7+
"Properties": {
8+
"DefinitionString": {
9+
"Fn::Join": [
10+
"\n",
11+
[
12+
"{",
13+
" \"Comment\": \"A Hello World example of the Amazon States Language using Pass states\",",
14+
" \"StartAt\": \"Hello\",",
15+
" \"States\": {",
16+
" \"Hello\": {",
17+
" \"Next\": \"World\",",
18+
" \"Result\": \"Hello\",",
19+
" \"Type\": \"Pass\"",
20+
" },",
21+
" \"World\": {",
22+
" \"End\": true,",
23+
" \"Result\": \"World\",",
24+
" \"Type\": \"Pass\"",
25+
" }",
26+
" }",
27+
"}"
28+
]
29+
]
30+
},
31+
"RoleArn": {
32+
"Fn::GetAtt": [
33+
"MyBasicStateMachineRole",
34+
"Arn"
35+
]
36+
},
37+
"StateMachineType": "STANDARD",
38+
"Tags": [
39+
{
40+
"Key": "stateMachine:createdBy",
41+
"Value": "SAM"
42+
}
43+
]
44+
},
45+
"Type": "AWS::StepFunctions::StateMachine"
46+
},
47+
"MyBasicStateMachineRole": {
48+
"Properties": {
49+
"AssumeRolePolicyDocument": {
50+
"Statement": [
51+
{
52+
"Action": [
53+
"sts:AssumeRole"
54+
],
55+
"Effect": "Allow",
56+
"Principal": {
57+
"Service": [
58+
"states.amazonaws.com"
59+
]
60+
}
61+
}
62+
],
63+
"Version": "2012-10-17"
64+
},
65+
"ManagedPolicyArns": [],
66+
"Path": "/foo/bar/",
67+
"Tags": [
68+
{
69+
"Key": "stateMachine:createdBy",
70+
"Value": "SAM"
71+
}
72+
]
73+
},
74+
"Type": "AWS::IAM::Role"
75+
}
76+
}
77+
}

0 commit comments

Comments
 (0)