Skip to content

Commit 75b7858

Browse files
authored
Merge pull request #3225 from aws/release-v1.70.0
Release 1.70.0 (to main)
2 parents 063ac27 + fdaa826 commit 75b7858

File tree

42 files changed

+1529
-5
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1529
-5
lines changed

.cfnlintrc.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,12 @@ ignore_templates:
118118
- tests/translator/output/**/state_machine_with_event_schedule_state.json
119119
- tests/translator/output/**/state_machine_with_schedule.json
120120
- tests/translator/output/**/state_machine_with_schedule_dlq_retry_policy.json
121+
- tests/translator/output/**/state_machine_with_auto_publish_alias.json
122+
- tests/translator/output/**/state_machine_with_deployment_preference_all_at_once.json
123+
- tests/translator/output/**/state_machine_with_deployment_preference_canary.json
124+
- tests/translator/output/**/state_machine_with_deployment_preference_linear.json
125+
- tests/translator/output/**/state_machine_with_deletion_policy.json
126+
- tests/translator/output/**/state_machine_with_update_replace_policy.json
121127
- tests/translator/output/**/globals_for_function.json # RuntimeManagementConfig
122128
- tests/translator/output/**/function_with_runtime_config.json # RuntimeManagementConfig
123129
- tests/translator/output/**/managed_policies_minimal.json # Intentionally has non-existent managed policy name

samtranslator/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "1.69.0"
1+
__version__ = "1.70.0"

samtranslator/internal/schema_source/aws_serverless_function.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,8 @@ class SelfManagedKafkaEventProperties(BaseModel):
441441
"KafkaBootstrapServers"
442442
)
443443
SourceAccessConfigurations: PassThroughProp = selfmanagedkafkaeventproperties("SourceAccessConfigurations")
444+
StartingPosition: Optional[PassThroughProp] # TODO: add documentation
445+
StartingPositionTimestamp: Optional[PassThroughProp] # TODO: add documentation
444446
Topics: PassThroughProp = selfmanagedkafkaeventproperties("Topics")
445447

446448

samtranslator/internal/schema_source/aws_serverless_statemachine.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ class Properties(BaseModel):
171171
Tags: Optional[DictStrAny] = properties("Tags")
172172
Tracing: Optional[PassThroughProp] = properties("Tracing")
173173
Type: Optional[PassThroughProp] = properties("Type")
174+
AutoPublishAlias: Optional[PassThroughProp]
175+
DeploymentPreference: Optional[PassThroughProp]
174176

175177

176178
class Resource(ResourceAttributes):

samtranslator/model/__init__.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ def __init__(self, required: bool) -> None:
7474
super().__init__(required, any_type(), False)
7575

7676

77+
class MutatedPassThroughProperty(PassThroughProperty):
78+
"""
79+
Mutated pass-through property.
80+
81+
SAM Translator may read and add/remove/modify the value before passing it to underlaying CFN resources.
82+
"""
83+
84+
7785
class GeneratedProperty(PropertyType):
7886
"""
7987
Property of a generated CloudFormation resource.
@@ -629,6 +637,7 @@ def get_resource_by_logical_id(self, _input: str) -> Dict[str, Any]:
629637
"PropertyType",
630638
"Property",
631639
"PassThroughProperty",
640+
"MutatedPassThroughProperty",
632641
"Resource",
633642
"ResourceMacro",
634643
"SamResourceMacro",

samtranslator/model/sam_resources.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
from samtranslator.intrinsics.resolver import IntrinsicsResolver
4141
from samtranslator.metrics.method_decorator import cw_timer
4242
from samtranslator.model import (
43+
MutatedPassThroughProperty,
4344
PassThroughProperty,
4445
Property,
4546
PropertyType,
@@ -1736,6 +1737,8 @@ class SamStateMachine(SamResourceMacro):
17361737
"Policies": PropertyType(False, one_of(IS_STR, list_of(one_of(IS_STR, IS_DICT, IS_DICT)))),
17371738
"Tracing": PropertyType(False, IS_DICT),
17381739
"PermissionsBoundary": PropertyType(False, IS_STR),
1740+
"AutoPublishAlias": PassThroughProperty(False),
1741+
"DeploymentPreference": MutatedPassThroughProperty(False),
17391742
}
17401743

17411744
Definition: Optional[Dict[str, Any]]
@@ -1751,6 +1754,8 @@ class SamStateMachine(SamResourceMacro):
17511754
Policies: Optional[List[Any]]
17521755
Tracing: Optional[Dict[str, Any]]
17531756
PermissionsBoundary: Optional[Intrinsicable[str]]
1757+
AutoPublishAlias: Optional[PassThrough]
1758+
DeploymentPreference: Optional[PassThrough]
17541759

17551760
event_resolver = ResourceTypeResolver(
17561761
samtranslator.model.stepfunctions.events,
@@ -1787,6 +1792,8 @@ def to_cloudformation(self, **kwargs): # type: ignore[no-untyped-def]
17871792
resource_attributes=self.resource_attributes,
17881793
passthrough_resource_attributes=self.get_passthrough_resource_attributes(),
17891794
get_managed_policy_map=get_managed_policy_map,
1795+
auto_publish_alias=self.AutoPublishAlias,
1796+
deployment_preference=self.DeploymentPreference,
17901797
)
17911798

17921799
return state_machine_generator.to_cloudformation()
Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1-
__all__ = ["StepFunctionsStateMachine", "StateMachineGenerator", "events"]
1+
__all__ = [
2+
"StepFunctionsStateMachine",
3+
"StepFunctionsStateMachineVersion",
4+
"StepFunctionsStateMachineAlias",
5+
"StateMachineGenerator",
6+
"events",
7+
]
28

39
from . import events
410
from .generators import StateMachineGenerator
5-
from .resources import StepFunctionsStateMachine
11+
from .resources import StepFunctionsStateMachine, StepFunctionsStateMachineAlias, StepFunctionsStateMachineVersion

samtranslator/model/stepfunctions/generators.py

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@
99
from samtranslator.model.resource_policies import ResourcePolicies
1010
from samtranslator.model.role_utils import construct_role_for_resource
1111
from samtranslator.model.s3_utils.uri_parser import parse_s3_uri
12-
from samtranslator.model.stepfunctions.resources import StepFunctionsStateMachine
12+
from samtranslator.model.stepfunctions.resources import (
13+
StepFunctionsStateMachine,
14+
StepFunctionsStateMachineAlias,
15+
StepFunctionsStateMachineVersion,
16+
)
1317
from samtranslator.model.tags.resource_tagging import get_tag_list
1418
from samtranslator.model.xray_utils import get_xray_managed_policy_name
1519
from samtranslator.utils.cfn_dynamic_references import is_dynamic_reference
@@ -48,6 +52,8 @@ def __init__( # type: ignore[no-untyped-def] # noqa: too-many-arguments
4852
resource_attributes=None,
4953
passthrough_resource_attributes=None,
5054
get_managed_policy_map=None,
55+
auto_publish_alias=None,
56+
deployment_preference=None,
5157
):
5258
"""
5359
Constructs an State Machine Generator class that generates a State Machine resource
@@ -73,6 +79,8 @@ def __init__( # type: ignore[no-untyped-def] # noqa: too-many-arguments
7379
:param tags: Tags to be associated with the State Machine resource
7480
:param resource_attributes: Resource attributes to add to the State Machine resource
7581
:param passthrough_resource_attributes: Attributes such as `Condition` that are added to derived resources
82+
:param auto_publish_alias: Name of the state machine alias to automatically create and update
83+
:deployment_preference: Settings to enable gradual state machine deployments
7684
"""
7785
self.logical_id = logical_id
7886
self.depends_on = depends_on
@@ -100,6 +108,8 @@ def __init__( # type: ignore[no-untyped-def] # noqa: too-many-arguments
100108
)
101109
self.substitution_counter = 1
102110
self.get_managed_policy_map = get_managed_policy_map
111+
self.auto_publish_alias = auto_publish_alias
112+
self.deployment_preference = deployment_preference
103113

104114
@cw_timer(prefix="Generator", name="StateMachine")
105115
def to_cloudformation(self): # type: ignore[no-untyped-def]
@@ -152,6 +162,9 @@ def to_cloudformation(self): # type: ignore[no-untyped-def]
152162
self.state_machine.TracingConfiguration = self.tracing
153163
self.state_machine.Tags = self._construct_tag_list()
154164

165+
managed_traffic_shifting_resources = self._generate_managed_traffic_shifting_resources()
166+
resources.extend(managed_traffic_shifting_resources)
167+
155168
event_resources = self._generate_event_resources()
156169
resources.extend(event_resources)
157170

@@ -241,6 +254,72 @@ def _construct_tag_list(self) -> List[Dict[str, Any]]:
241254
sam_tag = {self._SAM_KEY: self._SAM_VALUE}
242255
return get_tag_list(sam_tag) + get_tag_list(self.tags)
243256

257+
def _construct_version(self) -> StepFunctionsStateMachineVersion:
258+
"""Constructs a state machine version resource that will be auto-published when the revision id of the state machine changes.
259+
260+
:return: Step Functions state machine version resource
261+
"""
262+
263+
# Unlike Lambda function versions, state machine versions do not need a hash suffix because
264+
# they are always replaced when their corresponding state machine is updated.
265+
# I.e. A SAM StateMachine resource will never have multiple version resources at the same time.
266+
logical_id = f"{self.logical_id}Version"
267+
attributes = self.passthrough_resource_attributes.copy()
268+
269+
# Both UpdateReplacePolicy and DeletionPolicy are needed to protect previous version from deletion
270+
# to ensure gradual deployment works.
271+
if "DeletionPolicy" not in attributes:
272+
attributes["DeletionPolicy"] = "Retain"
273+
if "UpdateReplacePolicy" not in attributes:
274+
attributes["UpdateReplacePolicy"] = "Retain"
275+
276+
state_machine_version = StepFunctionsStateMachineVersion(logical_id=logical_id, attributes=attributes)
277+
state_machine_version.StateMachineArn = self.state_machine.get_runtime_attr("arn")
278+
state_machine_version.StateMachineRevisionId = self.state_machine.get_runtime_attr("state_machine_revision_id")
279+
280+
return state_machine_version
281+
282+
def _construct_alias(self, version: StepFunctionsStateMachineVersion) -> StepFunctionsStateMachineAlias:
283+
"""Constructs a state machine alias resource pointing to the given state machine version.
284+
:return: Step Functions state machine alias resource
285+
"""
286+
logical_id = f"{self.logical_id}Alias{self.auto_publish_alias}"
287+
attributes = self.passthrough_resource_attributes
288+
289+
state_machine_alias = StepFunctionsStateMachineAlias(logical_id=logical_id, attributes=attributes)
290+
state_machine_alias.Name = self.auto_publish_alias
291+
292+
state_machine_version_arn = version.get_runtime_attr("arn")
293+
294+
deployment_preference = {}
295+
if self.deployment_preference:
296+
deployment_preference = self.deployment_preference
297+
else:
298+
deployment_preference["Type"] = "ALL_AT_ONCE"
299+
300+
deployment_preference["StateMachineVersionArn"] = state_machine_version_arn
301+
state_machine_alias.DeploymentPreference = deployment_preference
302+
303+
return state_machine_alias
304+
305+
def _generate_managed_traffic_shifting_resources(
306+
self,
307+
) -> List[Any]:
308+
"""Generates and returns the version and alias resources associated with this state machine's managed traffic shifting.
309+
310+
:returns: a list containing the state machine's version and alias resources
311+
:rtype: list
312+
"""
313+
if not self.auto_publish_alias and not self.deployment_preference:
314+
return []
315+
if not self.auto_publish_alias and self.deployment_preference:
316+
raise InvalidResourceException(
317+
self.logical_id, "'DeploymentPreference' requires 'AutoPublishAlias' property to be specified."
318+
)
319+
320+
state_machine_version = self._construct_version()
321+
return [state_machine_version, self._construct_alias(state_machine_version)]
322+
244323
def _generate_event_resources(self) -> List[Dict[str, Any]]:
245324
"""Generates and returns the resources associated with this state machine's event sources.
246325

samtranslator/model/stepfunctions/resources.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,20 @@ class StepFunctionsStateMachine(Resource):
3333
runtime_attrs = {
3434
"arn": lambda self: ref(self.logical_id),
3535
"name": lambda self: fnGetAtt(self.logical_id, "Name"),
36+
"state_machine_revision_id": lambda self: fnGetAtt(self.logical_id, "StateMachineRevisionId"),
3637
}
38+
39+
40+
class StepFunctionsStateMachineVersion(Resource):
41+
resource_type = "AWS::StepFunctions::StateMachineVersion"
42+
43+
property_types = {"StateMachineArn": GeneratedProperty(), "StateMachineRevisionId": GeneratedProperty()}
44+
45+
runtime_attrs = {"arn": lambda self: ref(self.logical_id)}
46+
47+
48+
class StepFunctionsStateMachineAlias(Resource):
49+
resource_type = "AWS::StepFunctions::StateMachineAlias"
50+
property_types = {"Name": GeneratedProperty(), "DeploymentPreference": GeneratedProperty()}
51+
52+
runtime_attrs = {"arn": lambda self: ref(self.logical_id)}

samtranslator/schema/schema.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239352,6 +239352,12 @@
239352239352
"markdownDescription": "An array of the authentication protocol, VPC components, or virtual host to secure and define your event source\\. \n*Valid values*: `BASIC_AUTH | CLIENT_CERTIFICATE_TLS_AUTH | SASL_SCRAM_256_AUTH | SASL_SCRAM_512_AUTH | SERVER_ROOT_CA_CERTIFICATE` \n*Type*: List of [SourceAccessConfiguration](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-eventsourcemapping-sourceaccessconfiguration.html) \n*Required*: Yes \n*AWS CloudFormation compatibility*: This property is passed directly to the `[ SourceAccessConfigurations](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html#cfn-lambda-eventsourcemapping-sourceaccessconfigurations)` property of an `AWS::Lambda::EventSourceMapping` resource\\.",
239353239353
"title": "SourceAccessConfigurations"
239354239354
},
239355+
"StartingPosition": {
239356+
"$ref": "#/definitions/PassThroughProp"
239357+
},
239358+
"StartingPositionTimestamp": {
239359+
"$ref": "#/definitions/PassThroughProp"
239360+
},
239355239361
"Topics": {
239356239362
"allOf": [
239357239363
{
@@ -243033,6 +243039,9 @@
243033243039
"samtranslator__internal__schema_source__aws_serverless_statemachine__Properties": {
243034243040
"additionalProperties": false,
243035243041
"properties": {
243042+
"AutoPublishAlias": {
243043+
"$ref": "#/definitions/PassThroughProp"
243044+
},
243036243045
"Definition": {
243037243046
"markdownDescription": "The state machine definition is an object, where the format of the object matches the format of your AWS SAM template file, for example, JSON or YAML\\. State machine definitions adhere to the [Amazon States Language](https://docs.aws.amazon.com/step-functions/latest/dg/concepts-amazon-states-language.html)\\. \nFor an example of an inline state machine definition, see [Examples](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/#sam-resource-statemachine--examples.html#sam-resource-statemachine--examples)\\. \nYou must provide either a `Definition` or a `DefinitionUri`\\. \n*Type*: Map \n*Required*: Conditional \n*AWS CloudFormation compatibility*: This property is unique to AWS SAM and doesn't have an AWS CloudFormation equivalent\\.",
243038243047
"title": "Definition",
@@ -243055,6 +243064,9 @@
243055243064
"markdownDescription": "The Amazon Simple Storage Service \\(Amazon S3\\) URI or local file path of the state machine definition written in the [Amazon States Language](https://docs.aws.amazon.com/step-functions/latest/dg/concepts-amazon-states-language.html)\\. \nIf you provide a local file path, the template must go through the workflow that includes the `sam deploy` or `sam package` command to correctly transform the definition\\. To do this, you must use version 0\\.52\\.0 or later of the AWS SAM CLI\\. \nYou must provide either a `Definition` or a `DefinitionUri`\\. \n*Type*: String \\| [S3Location](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html#cfn-stepfunctions-statemachine-definitions3location) \n*Required*: Conditional \n*AWS CloudFormation compatibility*: This property is passed directly to the [`DefinitionS3Location`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html#cfn-stepfunctions-statemachine-definitions3location) property of an `AWS::StepFunctions::StateMachine` resource\\.",
243056243065
"title": "DefinitionUri"
243057243066
},
243067+
"DeploymentPreference": {
243068+
"$ref": "#/definitions/PassThroughProp"
243069+
},
243058243070
"Events": {
243059243071
"additionalProperties": {
243060243072
"anyOf": [

0 commit comments

Comments
 (0)