Repository: localstack/localstack

Issue:
bug: "not enough values to unpack" when resolving refs to secrets manager
### Is there an existing issue for this?

- [X] I have searched the existing issues

### Current Behavior

When creating a `DBInstance` with username and password from the secrets manager, I get this error in the localstack debug output:
```
2022-11-16T16:59:04.763 DEBUG --- [functhread31] l.u.c.template_deployer    : Request for resource type "SecretsManager::Secret" in region us-east-1: create_secret {'Name': 'my-stack-DatabaseSecret-8e991c0f', 'SecretString': '{"username": "username", "password": "PqrCVh!F[UR8xyi6"}'}
2022-11-16T16:59:04.786 DEBUG --- [functhread31] l.u.c.template_deployer    : Extract resource attribute: Parameter Ref
2022-11-16T16:59:04.791 DEBUG --- [functhread31] l.u.c.template_deployer    : Error applying changes for CloudFormation stack "my-stack": not enough values to unpack (expected 3, got 1) Traceback (most recent call last):
File "/opt/code/localstack/localstack/utils/cloudformation/template_deployer.py", line 1412, in _run
self.do_apply_changes_in_loop(changes, stack)
File "/opt/code/localstack/localstack/utils/cloudformation/template_deployer.py", line 1461, in do_apply_changes_in_loop
should_deploy = self.prepare_should_deploy_change(
File "/opt/code/localstack/localstack/utils/cloudformation/template_deployer.py", line 1527, in prepare_should_deploy_change
resolve_refs_recursively(stack, resource)
File "/opt/code/localstack/.venv/lib/python3.10/site-packages/localstack_ext/services/cloudformation/cloudformation_extended.py.enc", line 61, in resolve_refs_recursively
File "/opt/code/localstack/localstack/utils/functions.py", line 80, in func
return wrapped(*args, **kwargs)
File "/opt/code/localstack/localstack/utils/cloudformation/template_deployer.py", line 411, in resolve_refs_recursively
result = _resolve_refs_recursively(stack, value)
File "/opt/code/localstack/localstack/utils/functions.py", line 80, in func
return wrapped(*args, **kwargs)
File "/opt/code/localstack/localstack/utils/cloudformation/template_deployer.py", line 607, in _resolve_refs_recursively
value[key] = resolve_refs_recursively(stack, val)
File "/opt/code/localstack/.venv/lib/python3.10/site-packages/localstack_ext/services/cloudformation/cloudformation_extended.py.enc", line 61, in resolve_refs_recursively
File "/opt/code/localstack/localstack/utils/functions.py", line 80, in func
return wrapped(*args, **kwargs)
File "/opt/code/localstack/localstack/utils/cloudformation/template_deployer.py", line 411, in resolve_refs_recursively
result = _resolve_refs_recursively(stack, value)
File "/opt/code/localstack/localstack/utils/functions.py", line 80, in func
return wrapped(*args, **kwargs)
File "/opt/code/localstack/localstack/utils/cloudformation/template_deployer.py", line 607, in _resolve_refs_recursively
value[key] = resolve_refs_recursively(stack, val)
File "/opt/code/localstack/.venv/lib/python3.10/site-packages/localstack_ext/services/cloudformation/cloudformation_extended.py.enc", line 61, in resolve_refs_recursively
File "/opt/code/localstack/localstack/utils/functions.py", line 80, in func
return wrapped(*args, **kwargs)
File "/opt/code/localstack/localstack/utils/cloudformation/template_deployer.py", line 455, in resolve_refs_recursively
[json_key, version_stage, version_id] = parts[1].split(":")
ValueError: not enough values to unpack (expected 3, got 1)
```

### Expected Behavior

When creating the same `DBInstance` in AWS, it deploys without errors.

### How are you starting LocalStack?

With the `localstack` script

### Steps To Reproduce

#### How are you starting localstack (e.g., `bin/localstack` command, arguments, or `docker-compose.yml`)

```
. ./tox/py38/bin/activate
DEBUG=1 localstack start
```

#### Client commands (e.g., AWS SDK code snippet, or sequence of "awslocal" commands)

```
aws cloudformation deploy --stack-name my-stack --template-file template.yml --endpoint-url http://localhost:4566
```
Where `template.yml` contains this relevant part:
```
  DatabaseSecret:
    Type: AWS::SecretsManager::Secret
    Properties:
      GenerateSecretString:
        SecretStringTemplate: !Sub '{"username": "${DatabaseUsername}"}'
        GenerateStringKey: password
        PasswordLength: 16
        ExcludeCharacters: '"@/\'

  Database:
    Type: AWS::RDS::DBInstance
    DependsOn:
      - DatabaseSecret
    DeletionPolicy: Delete
    Properties:
      DBName: !Ref DatabaseName
      AllocatedStorage: 100
      DBInstanceClass: db.m5.large
      Engine: "postgres"
      MasterUsername: !Sub '{{resolve:secretsmanager:${DatabaseSecret}:SecretString:username}}'
      MasterUserPassword: !Sub '{{resolve:secretsmanager:${DatabaseSecret}:SecretString:password}}'
      BackupRetentionPeriod: 0
      DBSubnetGroupName: !Ref DatabaseSubnetGroup
      VPCSecurityGroups:
        - !Ref DatabaseSecurityGroup
      MaxAllocatedStorage: 1000
```

### Environment

```markdown
- OS: Ubuntu 20.04
- LocalStack: 1.2.0
```


### Anything else?

Same behavior when I try to resolve with a join:
```
      MasterUsername: !Join ['', ['{{resolve:secretsmanager:', !Ref DatabaseSecret, ':SecretString:username}}' ]]
      MasterUserPassword: !Join ['', ['{{resolve:secretsmanager:', !Ref DatabaseSecret, ':SecretString:password}}' ]]
```


Discussion:
Welcome to LocalStack! Thanks for reporting your first issue and our team will be working towards fixing the issue for you or reach out for more background information. We recommend joining our [Slack Community](https://localstack.cloud/contact/) for real-time help and drop a message to LocalStack Pro Support if you are a Pro user! If you are willing to contribute towards fixing this issue, please have a look at our [contributing guidelines](https://github.com/localstack/.github/blob/main/CONTRIBUTING.md) and our [developer guide](https://docs.localstack.cloud/developer-guide/).

Resolving patch:
diff --git a/localstack/utils/cloudformation/template_deployer.py b/localstack/utils/cloudformation/template_deployer.py
--- a/localstack/utils/cloudformation/template_deployer.py
+++ b/localstack/utils/cloudformation/template_deployer.py
@@ -452,7 +452,8 @@ def resolve_refs_recursively(stack, value):
                 if "SecretString" in reference_key:
                     parts = reference_key.split(":SecretString:")
                     secret_id = parts[0]
-                    [json_key, version_stage, version_id] = parts[1].split(":")
+                    # json-key, version-stage and version-id are optional.
+                    [json_key, version_stage, version_id] = f"{parts[1]}::".split(":")[:3]
 
                 kwargs = {}  # optional args for get_secret_value
                 if version_id:


Test patch:
diff --git a/tests/integration/cloudformation/test_engine.py b/tests/integration/cloudformation/test_engine.py
--- a/tests/integration/cloudformation/test_engine.py
+++ b/tests/integration/cloudformation/test_engine.py
@@ -326,7 +326,12 @@ def test_resolve_ssm_secure(self, create_parameter, cfn_client, deploy_cfn_templ
 
 class TestSecretsManagerParameters:
     @pytest.mark.parametrize(
-        "template_name", ["resolve_secretsmanager_full.yaml", "resolve_secretsmanager.yaml"]
+        "template_name",
+        [
+            "resolve_secretsmanager_full.yaml",
+            "resolve_secretsmanager_partial.yaml",
+            "resolve_secretsmanager.yaml",
+        ],
     )
     def test_resolve_secretsmanager(
         self,
diff --git a/tests/integration/templates/resolve_secretsmanager_partial.yaml b/tests/integration/templates/resolve_secretsmanager_partial.yaml
new file mode 100644
--- /dev/null
+++ b/tests/integration/templates/resolve_secretsmanager_partial.yaml
@@ -0,0 +1,27 @@
+Parameters:
+  DynamicParameter:
+    Type: String
+
+Resources:
+  topic69831491:
+    Type: AWS::SNS::Topic
+    Properties:
+      TopicName:
+        Fn::Join:
+          - ""
+          - - "{{resolve:secretsmanager:arn:"
+            - Ref: AWS::Partition
+            - ":secretsmanager:"
+            - Ref: AWS::Region
+            - ":"
+            - Ref: AWS::AccountId
+            - ":secret:"
+            - Ref: DynamicParameter
+            -  ":SecretString:}}"
+
+Outputs:
+  TopicName:
+    Value:
+      Fn::GetAtt:
+        - topic69831491
+        - TopicName