diff --git a/src/cfnlint/rules/parameters/DynamicReferenceSecret.py b/src/cfnlint/rules/parameters/DynamicReferenceSecret.py index fc4fe2a576..1bcd4924bc 100644 --- a/src/cfnlint/rules/parameters/DynamicReferenceSecret.py +++ b/src/cfnlint/rules/parameters/DynamicReferenceSecret.py @@ -5,6 +5,7 @@ from typing import Any +from cfnlint.helpers import FUNCTIONS from cfnlint.jsonschema import ValidationError, Validator from cfnlint.rules.jsonschema import CfnLintKeyword @@ -44,6 +45,9 @@ def __init__(self) -> None: self.parent_rules = ["E1020"] def validate(self, validator: Validator, _, instance: Any, schema: Any): + functions = set(FUNCTIONS) - set(["Fn::If"]) + if any(p in functions for p in validator.context.path.path): + return value = instance.get("Ref") if not validator.is_type(value, "string"): diff --git a/test/unit/rules/parameters/test_dynamic_reference_secret.py b/test/unit/rules/parameters/test_dynamic_reference_secret.py index 867c0f9c3b..fe6c663ed4 100644 --- a/test/unit/rules/parameters/test_dynamic_reference_secret.py +++ b/test/unit/rules/parameters/test_dynamic_reference_secret.py @@ -3,9 +3,11 @@ SPDX-License-Identifier: MIT-0 """ +from collections import deque + import pytest -from cfnlint.context import create_context_for_template +from cfnlint.context import Path, create_context_for_template from cfnlint.jsonschema import CfnTemplateValidator, ValidationError from cfnlint.rules.parameters.DynamicReferenceSecret import DynamicReferenceSecret from cfnlint.template import Template @@ -39,21 +41,24 @@ def context(cfn): @pytest.mark.parametrize( - "name,instance,expected", + "name,instance,path,expected", [ ( "REFing a parameter without a string", {"Ref": []}, + deque([]), [], ), ( "REFing a resource=", {"Ref": "MyResource"}, + deque([]), [], ), ( "REFing a parameter", {"Ref": "MyParameter"}, + deque([]), [ ValidationError( "Use dynamic references over parameters for secrets", @@ -61,9 +66,15 @@ def context(cfn): ) ], ), + ( + "REFing a parameter in a sub", + {"Ref": "MyParameter"}, + deque(["Fn::Sub"]), + [], + ), ], ) -def test_validate(name, instance, expected, rule, context, cfn): - validator = CfnTemplateValidator(context=context, cfn=cfn) +def test_validate(name, instance, path, expected, rule, context, cfn): + validator = CfnTemplateValidator(context=context.evolve(path=Path(path)), cfn=cfn) errs = list(rule.validate(validator, {}, instance, {})) assert errs == expected, f"Test {name!r} got {errs!r}"