diff --git a/samtranslator/internal/schema_source/aws_serverless_statemachine.py b/samtranslator/internal/schema_source/aws_serverless_statemachine.py index f2b73f857..8bd90f144 100644 --- a/samtranslator/internal/schema_source/aws_serverless_statemachine.py +++ b/samtranslator/internal/schema_source/aws_serverless_statemachine.py @@ -159,6 +159,7 @@ class Properties(BaseModel): Definition: DictStrAny | None = properties("Definition") DefinitionSubstitutions: DictStrAny | None = properties("DefinitionSubstitutions") DefinitionUri: Union[str, PassThroughProp] | None = properties("DefinitionUri") + EncryptionConfiguration: PassThroughProp | None = properties("EncryptionConfiguration") Events: dict[str, Union[ScheduleEvent, ScheduleV2Event, CloudWatchEvent, EventBridgeRuleEvent, ApiEvent]] | None = ( properties("Events") ) diff --git a/samtranslator/internal/schema_source/sam-docs.json b/samtranslator/internal/schema_source/sam-docs.json index 7804e0032..fe0ee774c 100644 --- a/samtranslator/internal/schema_source/sam-docs.json +++ b/samtranslator/internal/schema_source/sam-docs.json @@ -892,6 +892,7 @@ "Definition": "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\\.", "DefinitionSubstitutions": "A string\\-to\\-string map that specifies the mappings for placeholder variables in the state machine definition\\. This enables you to inject values obtained at runtime \\(for example, from intrinsic functions\\) into the state machine definition\\. \n*Type*: Map \n*Required*: No \n*AWS CloudFormation compatibility*: This property is similar to the [`DefinitionSubstitutions`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html#cfn-stepfunctions-statemachine-definitionsubstitutions) property of an `AWS::StepFunctions::StateMachine` resource\\. If any intrinsic functions are specified in an inline state machine definition, AWS SAM adds entries to this property to inject them into the state machine definition\\.", "DefinitionUri": "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\\.", + "EncryptionConfiguration": "Settings to configure server\\-side encryption for the state machine\\. By default, Step Functions provides transparent server\\-side encryption\\. With this configuration, you can specify a customer managed AWS KMS key for encryption\\. \n*Type*: [EncryptionConfiguration](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-stepfunctions-statemachine-encryptionconfiguration.html) \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`EncryptionConfiguration`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html#cfn-stepfunctions-statemachine-encryptionconfiguration) property of an `AWS::StepFunctions::StateMachine` resource\\.", "DeploymentPreference": "The settings that enable and configure gradual state machine deployments\\. To learn more about Step Functions gradual deployments, see [ Manage continuous deployments with versions and aliases](https://docs.aws.amazon.com/step-functions/latest/dg/concepts-cd-aliasing-versioning.html) in the *AWS Step Functions Developer Guide*\\. \nSpecify `AutoPublishAlias` before configuring this property\\. Your `DeploymentPreference` settings will be applied to the alias specified with `AutoPublishAlias`\\. \nWhen you specify `DeploymentPreference`, AWS SAM generates the `StateMachineVersionArn` sub\\-property value automatically\\. \n*Type*: [DeploymentPreference](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-stepfunctions-statemachinealias-deploymentpreference.html) \n*Required*: No \n*AWS CloudFormation compatibility*: AWS SAM generates and attaches the `StateMachineVersionArn` property value to `DeploymentPreference` and passes `DeploymentPreference` to the [`DeploymentPreference`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachinealias.html#cfn-stepfunctions-statemachinealias-deploymentpreference) property of an `AWS::StepFunctions::StateMachineAlias` resource\\.", "Events": "Specifies the events that trigger this state machine\\. Events consist of a type and a set of properties that depend on the type\\. \n*Type*: [EventSource](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-statemachine-statemachineeventsource.html) \n*Required*: No \n*AWS CloudFormation compatibility*: This property is unique to AWS SAM and doesn't have an AWS CloudFormation equivalent\\.", "Logging": "Defines which execution history events are logged and where they are logged\\. \n*Type*: [LoggingConfiguration](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html#cfn-stepfunctions-statemachine-loggingconfiguration) \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`LoggingConfiguration`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html#cfn-stepfunctions-statemachine-loggingconfiguration) property of an `AWS::StepFunctions::StateMachine` resource\\.", diff --git a/samtranslator/model/sam_resources.py b/samtranslator/model/sam_resources.py index 0a3a9ba29..ab2430bbd 100644 --- a/samtranslator/model/sam_resources.py +++ b/samtranslator/model/sam_resources.py @@ -2295,6 +2295,7 @@ class SamStateMachine(SamResourceMacro): "Role": PropertyType(False, IS_STR), "RolePath": PassThroughProperty(False), "DefinitionSubstitutions": PropertyType(False, IS_DICT), + "EncryptionConfiguration": PassThroughProperty(False), "Events": PropertyType(False, dict_of(IS_STR, IS_DICT)), "Name": PropertyType(False, IS_STR), "Type": PropertyType(False, IS_STR), @@ -2314,6 +2315,7 @@ class SamStateMachine(SamResourceMacro): Role: Intrinsicable[str] | None RolePath: PassThrough | None DefinitionSubstitutions: dict[str, Any] | None + EncryptionConfiguration: PassThrough | None Events: dict[str, Any] | None Name: Intrinsicable[str] | None Type: Intrinsicable[str] | None @@ -2350,6 +2352,7 @@ def to_cloudformation(self, **kwargs): # type: ignore[no-untyped-def] policies=self.Policies, permissions_boundary=self.PermissionsBoundary, definition_substitutions=self.DefinitionSubstitutions, + encryption_configuration=self.EncryptionConfiguration, role=self.Role, role_path=self.RolePath, state_machine_type=self.Type, diff --git a/samtranslator/model/stepfunctions/generators.py b/samtranslator/model/stepfunctions/generators.py index 6ed1ca301..15b46e836 100644 --- a/samtranslator/model/stepfunctions/generators.py +++ b/samtranslator/model/stepfunctions/generators.py @@ -55,6 +55,7 @@ def __init__( # type: ignore[no-untyped-def] # noqa: PLR0913 auto_publish_alias=None, deployment_preference=None, use_alias_as_event_target=None, + encryption_configuration=None, ): """ Constructs an State Machine Generator class that generates a State Machine resource @@ -70,6 +71,7 @@ def __init__( # type: ignore[no-untyped-def] # noqa: PLR0913 :param policies: Policies attached to the execution role :param permissions_boundary: The ARN of the policy used to set the permissions boundary for the role :param definition_substitutions: Variable-to-value mappings to be replaced in the State Machine definition + :param encryption_configuration: Server-side encryption configuration for the State Machine :param role: Role ARN to use for the execution role :param role_path: The file path of the execution role :param state_machine_type: Type of the State Machine @@ -97,6 +99,7 @@ def __init__( # type: ignore[no-untyped-def] # noqa: PLR0913 self.policies = policies self.permissions_boundary = permissions_boundary self.definition_substitutions = definition_substitutions + self.encryption_configuration = encryption_configuration self.role = role self.role_path = role_path self.type = state_machine_type @@ -161,6 +164,7 @@ def to_cloudformation(self): # type: ignore[no-untyped-def] self.state_machine.StateMachineName = self.name self.state_machine.StateMachineType = self.type + self.state_machine.EncryptionConfiguration = self.encryption_configuration self.state_machine.LoggingConfiguration = self.logging self.state_machine.TracingConfiguration = self.tracing self.state_machine.Tags = self._construct_tag_list() diff --git a/samtranslator/model/stepfunctions/resources.py b/samtranslator/model/stepfunctions/resources.py index 3d8303695..d57f36a3d 100644 --- a/samtranslator/model/stepfunctions/resources.py +++ b/samtranslator/model/stepfunctions/resources.py @@ -10,6 +10,7 @@ class StepFunctionsStateMachine(Resource): "Definition": GeneratedProperty(), "DefinitionString": GeneratedProperty(), "DefinitionS3Location": GeneratedProperty(), + "EncryptionConfiguration": GeneratedProperty(), "LoggingConfiguration": GeneratedProperty(), "RoleArn": GeneratedProperty(), "StateMachineName": GeneratedProperty(), @@ -22,6 +23,7 @@ class StepFunctionsStateMachine(Resource): Definition: dict[str, Any] | None DefinitionString: str | None DefinitionS3Location: dict[str, Any] | None + EncryptionConfiguration: dict[str, Any] | None LoggingConfiguration: dict[str, Any] | None RoleArn: str StateMachineName: str | None diff --git a/samtranslator/schema/schema.json b/samtranslator/schema/schema.json index 182f52e75..3d3243132 100644 --- a/samtranslator/schema/schema.json +++ b/samtranslator/schema/schema.json @@ -372924,6 +372924,15 @@ "DeploymentPreference": { "$ref": "#/definitions/PassThroughProp" }, + "EncryptionConfiguration": { + "allOf": [ + { + "$ref": "#/definitions/PassThroughProp" + } + ], + "markdownDescription": "Settings to configure server\\-side encryption for the state machine\\. By default, Step Functions provides transparent server\\-side encryption\\. With this configuration, you can specify a customer managed AWS KMS key for encryption\\. \n*Type*: [EncryptionConfiguration](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-stepfunctions-statemachine-encryptionconfiguration.html) \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`EncryptionConfiguration`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html#cfn-stepfunctions-statemachine-encryptionconfiguration) property of an `AWS::StepFunctions::StateMachine` resource\\.", + "title": "EncryptionConfiguration" + }, "Events": { "additionalProperties": { "anyOf": [ diff --git a/schema_source/sam.schema.json b/schema_source/sam.schema.json index ffc0b7b66..ca2e2c4e0 100644 --- a/schema_source/sam.schema.json +++ b/schema_source/sam.schema.json @@ -9703,6 +9703,15 @@ "DeploymentPreference": { "$ref": "#/definitions/PassThroughProp" }, + "EncryptionConfiguration": { + "allOf": [ + { + "$ref": "#/definitions/PassThroughProp" + } + ], + "markdownDescription": "Settings to configure server\\-side encryption for the state machine\\. By default, Step Functions provides transparent server\\-side encryption\\. With this configuration, you can specify a customer managed AWS KMS key for encryption\\. \n*Type*: [EncryptionConfiguration](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-stepfunctions-statemachine-encryptionconfiguration.html) \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`EncryptionConfiguration`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html#cfn-stepfunctions-statemachine-encryptionconfiguration) property of an `AWS::StepFunctions::StateMachine` resource\\.", + "title": "EncryptionConfiguration" + }, "Events": { "additionalProperties": { "anyOf": [ diff --git a/tests/translator/input/state_machine_with_encryption_configuration.yaml b/tests/translator/input/state_machine_with_encryption_configuration.yaml new file mode 100644 index 000000000..5fcb9ca8b --- /dev/null +++ b/tests/translator/input/state_machine_with_encryption_configuration.yaml @@ -0,0 +1,36 @@ +Resources: + StateMachineKmsKey: + Type: AWS::KMS::Key + Properties: + KeyPolicy: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + AWS: !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:root' + Action: 'kms:*' + Resource: '*' + + StateMachine: + Type: AWS::Serverless::StateMachine + Properties: + Name: MyStateMachineWithEncryption + Type: STANDARD + Definition: + Comment: A Hello World example of the Amazon States Language using Pass states + StartAt: Hello + States: + Hello: + Type: Pass + Result: Hello + End: true + EncryptionConfiguration: + Type: CUSTOMER_MANAGED_KMS_KEY + KmsKeyId: !GetAtt StateMachineKmsKey.Arn + KmsDataKeyReusePeriodSeconds: 300 + Policies: + - Version: '2012-10-17' + Statement: + - Effect: Deny + Action: '*' + Resource: '*' diff --git a/tests/translator/output/aws-cn/state_machine_with_encryption_configuration.json b/tests/translator/output/aws-cn/state_machine_with_encryption_configuration.json new file mode 100644 index 000000000..d02fe15a9 --- /dev/null +++ b/tests/translator/output/aws-cn/state_machine_with_encryption_configuration.json @@ -0,0 +1,114 @@ +{ + "Resources": { + "StateMachine": { + "Properties": { + "DefinitionString": { + "Fn::Join": [ + "\n", + [ + "{", + " \"Comment\": \"A Hello World example of the Amazon States Language using Pass states\",", + " \"StartAt\": \"Hello\",", + " \"States\": {", + " \"Hello\": {", + " \"End\": true,", + " \"Result\": \"Hello\",", + " \"Type\": \"Pass\"", + " }", + " }", + "}" + ] + ] + }, + "EncryptionConfiguration": { + "KmsDataKeyReusePeriodSeconds": 300, + "KmsKeyId": { + "Fn::GetAtt": [ + "StateMachineKmsKey", + "Arn" + ] + }, + "Type": "CUSTOMER_MANAGED_KMS_KEY" + }, + "RoleArn": { + "Fn::GetAtt": [ + "StateMachineRole", + "Arn" + ] + }, + "StateMachineName": "MyStateMachineWithEncryption", + "StateMachineType": "STANDARD", + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::StepFunctions::StateMachine" + }, + "StateMachineKmsKey": { + "Properties": { + "KeyPolicy": { + "Statement": [ + { + "Action": "kms:*", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Sub": "arn:${AWS::Partition}:iam::${AWS::AccountId}:root" + } + }, + "Resource": "*" + } + ], + "Version": "2012-10-17" + } + }, + "Type": "AWS::KMS::Key" + }, + "StateMachineRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "states.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [], + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "*", + "Effect": "Deny", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "StateMachineRolePolicy0" + } + ], + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + } + } +} diff --git a/tests/translator/output/aws-us-gov/state_machine_with_encryption_configuration.json b/tests/translator/output/aws-us-gov/state_machine_with_encryption_configuration.json new file mode 100644 index 000000000..d02fe15a9 --- /dev/null +++ b/tests/translator/output/aws-us-gov/state_machine_with_encryption_configuration.json @@ -0,0 +1,114 @@ +{ + "Resources": { + "StateMachine": { + "Properties": { + "DefinitionString": { + "Fn::Join": [ + "\n", + [ + "{", + " \"Comment\": \"A Hello World example of the Amazon States Language using Pass states\",", + " \"StartAt\": \"Hello\",", + " \"States\": {", + " \"Hello\": {", + " \"End\": true,", + " \"Result\": \"Hello\",", + " \"Type\": \"Pass\"", + " }", + " }", + "}" + ] + ] + }, + "EncryptionConfiguration": { + "KmsDataKeyReusePeriodSeconds": 300, + "KmsKeyId": { + "Fn::GetAtt": [ + "StateMachineKmsKey", + "Arn" + ] + }, + "Type": "CUSTOMER_MANAGED_KMS_KEY" + }, + "RoleArn": { + "Fn::GetAtt": [ + "StateMachineRole", + "Arn" + ] + }, + "StateMachineName": "MyStateMachineWithEncryption", + "StateMachineType": "STANDARD", + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::StepFunctions::StateMachine" + }, + "StateMachineKmsKey": { + "Properties": { + "KeyPolicy": { + "Statement": [ + { + "Action": "kms:*", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Sub": "arn:${AWS::Partition}:iam::${AWS::AccountId}:root" + } + }, + "Resource": "*" + } + ], + "Version": "2012-10-17" + } + }, + "Type": "AWS::KMS::Key" + }, + "StateMachineRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "states.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [], + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "*", + "Effect": "Deny", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "StateMachineRolePolicy0" + } + ], + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + } + } +} diff --git a/tests/translator/output/state_machine_with_encryption_configuration.json b/tests/translator/output/state_machine_with_encryption_configuration.json new file mode 100644 index 000000000..d02fe15a9 --- /dev/null +++ b/tests/translator/output/state_machine_with_encryption_configuration.json @@ -0,0 +1,114 @@ +{ + "Resources": { + "StateMachine": { + "Properties": { + "DefinitionString": { + "Fn::Join": [ + "\n", + [ + "{", + " \"Comment\": \"A Hello World example of the Amazon States Language using Pass states\",", + " \"StartAt\": \"Hello\",", + " \"States\": {", + " \"Hello\": {", + " \"End\": true,", + " \"Result\": \"Hello\",", + " \"Type\": \"Pass\"", + " }", + " }", + "}" + ] + ] + }, + "EncryptionConfiguration": { + "KmsDataKeyReusePeriodSeconds": 300, + "KmsKeyId": { + "Fn::GetAtt": [ + "StateMachineKmsKey", + "Arn" + ] + }, + "Type": "CUSTOMER_MANAGED_KMS_KEY" + }, + "RoleArn": { + "Fn::GetAtt": [ + "StateMachineRole", + "Arn" + ] + }, + "StateMachineName": "MyStateMachineWithEncryption", + "StateMachineType": "STANDARD", + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::StepFunctions::StateMachine" + }, + "StateMachineKmsKey": { + "Properties": { + "KeyPolicy": { + "Statement": [ + { + "Action": "kms:*", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Sub": "arn:${AWS::Partition}:iam::${AWS::AccountId}:root" + } + }, + "Resource": "*" + } + ], + "Version": "2012-10-17" + } + }, + "Type": "AWS::KMS::Key" + }, + "StateMachineRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "states.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [], + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "*", + "Effect": "Deny", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "StateMachineRolePolicy0" + } + ], + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + } + } +}