-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
add support for region ref in mappings inside condition CFn #11671
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally LGTM!
I have some minor concerns around clarity in the extended code here.
Keeping those cases separate makes it easier for us to decompose this into utils at some point and refactor it when we can finally tackle a full engine rewrite.
As this is blocking some users, feel free to address this in a follow-up though!
param = parameters.get(ref_name) or resolve_pseudo_parameter( | ||
account_id, region_name, ref_name, stack_name | ||
) | ||
if not param: | ||
raise TemplateError( | ||
f"Invalid reference: '{ref_name}' does not exist in parameters: '{parameters}'" | ||
) | ||
map_name = param.get("ResolvedValue") or param.get("ParameterValue") | ||
map_name = ( | ||
(param.get("ResolvedValue") or param.get("ParameterValue")) | ||
if isinstance(param, dict) | ||
else param | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I think it would be clearer here to keep those cases (parameters vs. pseudo-parameters) better separated for clarity. E.g. explicitly handling resolve_pseudo_parameter
when the value starts with a AWS::...
instead of using it as a fallback here. (same applies for the cases further below)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestion. It's implemented int #11693
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good apart from some suggestions on refactoring. Thanks!
Edit: sorry just saw @dominikschubert picked up on the same thing as I did.
param = parameters.get(ref_name) or resolve_pseudo_parameter( | ||
account_id, region_name, ref_name, stack_name | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we should be a bit more deliberate in trying to resolve pseudo parameters? E.g. only try to resolve pseudo parameters if ref_name
starts with AWS::
?
I don't really like the way we are treating two different data types (dict
s when the map name is a parameter, or a str
when the ref is a pseudo parameter) and trying the different options depending on the type. I would prefer to be more explicit that the two sources of information should be treated differently.
In that case, we can be more specific about the error message below as well. E.g. something like:
if ref_name.startswith("AWS::"):
map_name = resolve_pseudo_parameter(...)
if map_name is None:
raise TemplateError(f"Invalid pseudo parameter '{ref_name}'")
else:
param = parameters.get(ref_name)
if not param:
raise TemplateError(
f"Invalid reference: '{ref_name}' does not exist in parameters: '{parameters}'"
)
map_name = param.get("ResolvedValue") or param.get("ParameterValue")
WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome. It's a lot better. I put it in #11693
@@ -184,30 +184,50 @@ def resolve_condition( | |||
map_name, top_level_key, second_level_key = v | |||
if isinstance(map_name, dict) and "Ref" in map_name: | |||
ref_name = map_name["Ref"] | |||
param = parameters.get(ref_name) | |||
param = parameters.get(ref_name) or resolve_pseudo_parameter( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the map name ever be a pseudo parameter?!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Takes a bit of work but AWS supports AWS:: in the mapping name. Please checkout #11693
Thank you for the reviews. I'm merging now to unblock the user and I will open a new PR with the suggested change. |
Motivation
This PR adds support for AWS References inside a Mapping inside a Conditional of a CFn template
Changes
Testing