Skip to content
This repository was archived by the owner on Mar 23, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,11 @@ def _perform_dynamic_replacements(self, value: _T) -> _T:
region_name=self._change_set.region_name,
)
if new_value:
return REGEX_DYNAMIC_REF.sub(new_value, value)
# We need to use a function here, to avoid backslash processing by regex.
# From the regex sub documentation:
# repl can be a string or a function; if it is a string, any backslash escapes in it are processed.
# Using a function, we can avoid this processing.
return REGEX_DYNAMIC_REF.sub(lambda _: new_value, value)

return value

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ def on_before_start(self):
issue_url = "?".join([base, urlencode(query_args)])
LOG.info(
"You have opted in to the new CloudFormation deployment engine. "
"You can opt in to using the old engine by setting PROVIDER_OVERRIDE_CLOUDFORMATION=legacy. "
"You can opt in to using the old engine by setting PROVIDER_OVERRIDE_CLOUDFORMATION=engine-legacy. "
"If you experience issues, please submit a bug report at this URL: %s",
issue_url,
)
Expand Down
17 changes: 17 additions & 0 deletions tests/aws/services/cloudformation/test_template_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,23 @@ def test_resolve_secretsmanager(self, create_secret, deploy_cfn_template, templa
topic_name = result.outputs["TopicName"]
assert topic_name == parameter_value

@markers.aws.validated
def test_resolve_secretsmanager_with_backslashes(self, create_secret, deploy_cfn_template):
parameter_key = f"param-key-{short_uid()}"
secret_value = json.dumps({"password": r"p\\30\asw\\\ord"})

create_secret(Name=parameter_key, SecretString=secret_value)

result = deploy_cfn_template(
parameters={"DynamicParameter": parameter_key},
template_path=os.path.join(
os.path.dirname(__file__),
"../../templates/resolve_secretsmanager_with_backslashes.yaml",
),
)

assert secret_value == result.outputs["ParameterValue"]


class TestPreviousValues:
@pytest.mark.skip(reason="outputs don't behave well in combination with conditions")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@
"tests/aws/services/cloudformation/test_template_engine.py::TestPseudoParameters::test_stack_id": {
"last_validated_date": "2024-07-18T08:56:47+00:00"
},
"tests/aws/services/cloudformation/test_template_engine.py::TestSecretsManagerParameters::test_resolve_secretsmanager_with_backslashes": {
"last_validated_date": "2025-09-30T15:36:21+00:00",
"durations_in_seconds": {
"setup": 0.01,
"call": 11.22,
"teardown": 4.49,
"total": 15.72
}
},
"tests/aws/services/cloudformation/test_template_engine.py::TestSsmParameters::test_create_change_set_with_ssm_parameter_list": {
"last_validated_date": "2024-08-08T21:21:23+00:00"
},
Expand Down
24 changes: 24 additions & 0 deletions tests/aws/templates/resolve_secretsmanager_with_backslashes.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Parameters:
DynamicParameter:
Type: String

Resources:
MyParameter:
Type: AWS::SSM::Parameter
Properties:
Type: String
Value:
Fn::Join:
- ""
- - "{{resolve:secretsmanager:arn:"
- Ref: AWS::Partition
- ":secretsmanager:"
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- ":secret:"
- Ref: DynamicParameter
- ":SecretString:::}}"
Outputs:
ParameterValue:
Value: !GetAtt MyParameter.Value
Loading