diff --git a/localstack-core/localstack/services/stepfunctions/resource_providers/aws_stepfunctions_statemachine.py b/localstack-core/localstack/services/stepfunctions/resource_providers/aws_stepfunctions_statemachine.py index c2a65a4bfe508..e550a43b2fd41 100644 --- a/localstack-core/localstack/services/stepfunctions/resource_providers/aws_stepfunctions_statemachine.py +++ b/localstack-core/localstack/services/stepfunctions/resource_providers/aws_stepfunctions_statemachine.py @@ -216,9 +216,10 @@ def update( if not model.get("Arn"): model["Arn"] = request.previous_state["Arn"] + definition_str = self._get_definition(model, request.aws_client_factory.s3) params = { "stateMachineArn": model["Arn"], - "definition": model["DefinitionString"], + "definition": definition_str, } step_function.update_state_machine(**params) diff --git a/tests/aws/services/cloudformation/resources/test_stepfunctions.py b/tests/aws/services/cloudformation/resources/test_stepfunctions.py index 86ceb6bfccc3d..0925c3aec449b 100644 --- a/tests/aws/services/cloudformation/resources/test_stepfunctions.py +++ b/tests/aws/services/cloudformation/resources/test_stepfunctions.py @@ -3,6 +3,7 @@ import urllib.parse import pytest +from localstack_snapshot.snapshots.transformer import JsonpathTransformer from localstack import config from localstack.testing.pytest import markers @@ -281,3 +282,73 @@ def test_cfn_statemachine_with_dependencies(deploy_cfn_template, aws_client): statemachines = [sm for sm in rs["stateMachines"] if sm_name in sm["name"]] assert not statemachines + + +@markers.aws.validated +@markers.snapshot.skip_snapshot_verify( + paths=["$..encryptionConfiguration", "$..tracingConfiguration"] +) +def test_cfn_statemachine_default_s3_location( + s3_create_bucket, deploy_cfn_template, aws_client, sfn_snapshot +): + sfn_snapshot.add_transformers_list( + [ + JsonpathTransformer("$..roleArn", "role-arn"), + JsonpathTransformer("$..stateMachineArn", "state-machine-arn"), + JsonpathTransformer("$..name", "state-machine-name"), + ] + ) + cfn_template_path = os.path.join( + os.path.dirname(__file__), + "../../../templates/statemachine_machine_default_s3_location.yml", + ) + + stack_name = f"test-cfn-statemachine-default-s3-location-{short_uid()}" + + file_key = f"file-key-{short_uid()}.json" + bucket_name = s3_create_bucket() + state_machine_template = { + "Comment": "step: on create", + "StartAt": "S0", + "States": {"S0": {"Type": "Succeed"}}, + } + + aws_client.s3.put_object( + Bucket=bucket_name, Key=file_key, Body=json.dumps(state_machine_template) + ) + + stack = deploy_cfn_template( + stack_name=stack_name, + template_path=cfn_template_path, + max_wait=150, + parameters={"BucketName": bucket_name, "ObjectKey": file_key}, + ) + + stack_outputs = stack.outputs + statemachine_arn = stack_outputs["StateMachineArnOutput"] + + describe_state_machine_output_on_create = aws_client.stepfunctions.describe_state_machine( + stateMachineArn=statemachine_arn + ) + sfn_snapshot.match( + "describe_state_machine_output_on_create", describe_state_machine_output_on_create + ) + + file_key = f"2-{file_key}" + state_machine_template["Comment"] = "step: on update" + aws_client.s3.put_object( + Bucket=bucket_name, Key=file_key, Body=json.dumps(state_machine_template) + ) + deploy_cfn_template( + stack_name=stack_name, + template_path=cfn_template_path, + is_update=True, + parameters={"BucketName": bucket_name, "ObjectKey": file_key}, + ) + + describe_state_machine_output_on_update = aws_client.stepfunctions.describe_state_machine( + stateMachineArn=statemachine_arn + ) + sfn_snapshot.match( + "describe_state_machine_output_on_update", describe_state_machine_output_on_update + ) diff --git a/tests/aws/services/cloudformation/resources/test_stepfunctions.snapshot.json b/tests/aws/services/cloudformation/resources/test_stepfunctions.snapshot.json new file mode 100644 index 0000000000000..df07ef28a658a --- /dev/null +++ b/tests/aws/services/cloudformation/resources/test_stepfunctions.snapshot.json @@ -0,0 +1,70 @@ +{ + "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_cfn_statemachine_default_s3_location": { + "recorded-date": "17-12-2024, 16:06:46", + "recorded-content": { + "describe_state_machine_output_on_create": { + "creationDate": "datetime", + "definition": { + "Comment": "step: on create", + "StartAt": "S0", + "States": { + "S0": { + "Type": "Succeed" + } + } + }, + "encryptionConfiguration": { + "type": "AWS_OWNED_KEY" + }, + "loggingConfiguration": { + "includeExecutionData": false, + "level": "OFF" + }, + "name": "", + "roleArn": "", + "stateMachineArn": "", + "status": "ACTIVE", + "tracingConfiguration": { + "enabled": false + }, + "type": "STANDARD", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe_state_machine_output_on_update": { + "creationDate": "datetime", + "definition": { + "Comment": "step: on update", + "StartAt": "S0", + "States": { + "S0": { + "Type": "Succeed" + } + } + }, + "encryptionConfiguration": { + "type": "AWS_OWNED_KEY" + }, + "loggingConfiguration": { + "includeExecutionData": false, + "level": "OFF" + }, + "name": "", + "revisionId": "", + "roleArn": "", + "stateMachineArn": "", + "status": "ACTIVE", + "tracingConfiguration": { + "enabled": false + }, + "type": "STANDARD", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + } +} diff --git a/tests/aws/services/cloudformation/resources/test_stepfunctions.validation.json b/tests/aws/services/cloudformation/resources/test_stepfunctions.validation.json new file mode 100644 index 0000000000000..bfd2fc0768091 --- /dev/null +++ b/tests/aws/services/cloudformation/resources/test_stepfunctions.validation.json @@ -0,0 +1,5 @@ +{ + "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_cfn_statemachine_default_s3_location": { + "last_validated_date": "2024-12-17T16:06:46+00:00" + } +} diff --git a/tests/aws/templates/statemachine_machine_default_s3_location.yml b/tests/aws/templates/statemachine_machine_default_s3_location.yml new file mode 100644 index 0000000000000..cf89842900637 --- /dev/null +++ b/tests/aws/templates/statemachine_machine_default_s3_location.yml @@ -0,0 +1,33 @@ +AWSTemplateFormatVersion: '2010-09-09' + +Parameters: + BucketName: + Type: String + + ObjectKey: + Type: String + +Resources: + StateMachineRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: states.amazonaws.com + Action: sts:AssumeRole + + StateMachine: + Type: AWS::StepFunctions::StateMachine + Properties: + StateMachineType: STANDARD + RoleArn: !GetAtt StateMachineRole.Arn + DefinitionS3Location: + Bucket: !Ref BucketName + Key: !Ref ObjectKey + +Outputs: + StateMachineArnOutput: + Value: !Ref StateMachine