Skip to content
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

Conditionally adding metadata to translated resources #2224

Merged
merged 2 commits into from Jan 25, 2022

Conversation

andrew-glenn
Copy link
Contributor

@andrew-glenn andrew-glenn commented Nov 15, 2021

Exposing an additional translated_resource_mapping property in the Translator class allows downstream consumers to apply logic to translated resources.

An example use case: copying cfn-lint metadata to new resources so that rule exceptions are honored.

See: aws-cloudformation/cfn-lint#2173

Copy link
Contributor

@moelasmar moelasmar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you please add some unit testing cases for this new change?

moelasmar
moelasmar previously approved these changes Nov 16, 2021
@jfuss
Copy link
Contributor

jfuss commented Nov 16, 2021

@andrew-glenn It isn't clear what the purpose of this is for. Is it only for local tooling support? Why do you want to mutate underlying resources instead of the SAM Resources itself?

Copy link
Contributor

@jfuss jfuss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Request changes" to indicate not to merge until the use-case is more understood.

@andrew-glenn
Copy link
Contributor Author

@jfuss As an example, cfn-lint supports metadata per-resource to define specific configuration options. A byproduct of the SAM Translator is that a single resource is split off into multiple, without the original metadata being copied to the new resources.

Rather than mess with the translator logic - which I'm not familiar with, and has a massive blast radius - I opted to surface a mapping of original SAM resource names --> Generated CFN Resources.

Providing this mapping allows me (downstream) to iterate over the map and perform whatever actions I wish based on this data.

Admittedly, this property wouldn't be used directly via the SAM CLI, but rather those that import SAM as a python library.

@moelasmar
Copy link
Contributor

@jfuss .. my understanding is that change will not affect the transformation logic, but will add some value for the sam translator library.

@jfuss
Copy link
Contributor

jfuss commented Nov 17, 2021

@moelasmar

@andrew-glenn and I discussed over slack yesterday afternoon. It is true this wouldn't impact the service but does mean we have to support this "overriding" locally. In the ideal world, I would like cfn-lint to lint the SAM Resources not the underlying ones but that requires a spec from SAM (this also decouples cfn-lint and SAM, which is an added benefit). I want to understand more of the intention behind the change and why we should support this. Not trying to say this isn't something we should do but there might be other ways to do the same thing. For example, maybe SAM should be taking the Metadata and applying it to all the underlying resources. Then we don't have to this local only "patching" mechanism, making support easier on us.

I scoped some time for myself on Thursday to think a little deeper and reach back out to @andrew-glenn to understand what he is trying to achieve with this and cfn-lint. That should give me a better understanding on what we may want to do here. My initially thinking is either 1) apply Metadata to generated resources or 2) Apply Metadata to generated resources so but make it a flag in the transform call.

Open to other ideas here, just general cautious of features that only apply locally.

@andrew-glenn
Copy link
Contributor Author

For what it's worth to the studio audience, I'm now convinced having SAM copy the metadata is a better approach. I'll sync up with @jfuss tomorrow to determine the details

@andrew-glenn andrew-glenn changed the title Adding Translator.translated_resource_mapping property Conditionally adding metadata to translated resources Nov 19, 2021
@andrew-glenn
Copy link
Contributor Author

@jfuss @moelasmar

I've updated the PR to reflect the new approach (adding metadata in translation). I've set it to default disabled for backwards compatibility.

@codecov-commenter
Copy link

codecov-commenter commented Nov 19, 2021

Codecov Report

Merging #2224 (bca27e4) into develop (e7a1496) will increase coverage by 0.81%.
The diff coverage is 96.85%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #2224      +/-   ##
===========================================
+ Coverage    93.58%   94.40%   +0.81%     
===========================================
  Files           90       97       +7     
  Lines         6124     7092     +968     
  Branches      1260     1436     +176     
===========================================
+ Hits          5731     6695     +964     
+ Misses         183      181       -2     
- Partials       210      216       +6     
Impacted Files Coverage Δ
samtranslator/model/cognito.py 85.71% <ø> (ø)
samtranslator/model/api/http_api_generator.py 91.21% <75.00%> (+0.02%) ⬆️
samtranslator/model/api/api_generator.py 93.70% <89.28%> (-0.66%) ⬇️
samtranslator/model/apigateway.py 96.98% <96.15%> (-0.18%) ⬇️
samtranslator/__init__.py 100.00% <100.00%> (ø)
samtranslator/feature_toggle/dialup.py 100.00% <100.00%> (ø)
samtranslator/feature_toggle/feature_toggle.py 100.00% <100.00%> (+12.16%) ⬆️
samtranslator/intrinsics/actions.py 98.79% <100.00%> (+0.07%) ⬆️
samtranslator/metrics/method_decorator.py 100.00% <100.00%> (ø)
samtranslator/metrics/metrics.py 100.00% <100.00%> (ø)
... and 34 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4b446dd...bca27e4. Read the comment docs.

@jfuss jfuss self-assigned this Nov 23, 2021
{
"Resources": {
"Images": {
"Type": "AWS::S3::Bucket",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bucket is defined in the template above, I don't think we want SAM to mutate that resource. I know we do today, but that is in very specific use-cases (adding events triggers).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% seeing how this resource is being mutated, since it exists previously. What am I overlooking?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note, to save back and forth:

If we want to exclude certain resource types from the metadata passthrough, that's fine. I'll need a list of resource types that would apply here. I'm a little bit in the dark.

Edit: I see the issue here.

@@ -2,7 +2,7 @@
from samtranslator.parser.parser import Parser


def transform(input_fragment, parameter_values, managed_policy_loader, feature_toggle=None):
def transform(input_fragment, parameter_values, managed_policy_loader, feature_toggle=None, convert_metadata=False):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: We aren't really converting anything for metadata here. Maybe something like add_metadata or passthrough_metadata is more clear for naming?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, no problem.

@@ -152,7 +153,10 @@ def translate(self, sam_template, parameter_values, feature_toggle=None):
del template["Resources"][logical_id]
for resource in translated:
if verify_unique_logical_id(resource, sam_template["Resources"]):
template["Resources"].update(resource.to_dict())
_r = resource.to_dict()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why convert the resources to dict? Should we just model Metadata with the resource pojo's we have?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current implementation (Line 155) converts it to a dictionary. I assumed this was done for a Very Good(tm) reason, so I simply followed the existing pattern.

@@ -152,7 +153,10 @@ def translate(self, sam_template, parameter_values, feature_toggle=None):
del template["Resources"][logical_id]
for resource in translated:
if verify_unique_logical_id(resource, sam_template["Resources"]):
template["Resources"].update(resource.to_dict())
_r = resource.to_dict()
if resource_dict.get("Metadata") and convert_metadata:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a comment here could go a long away in understanding what is happening. It took me a while but I think what is happening is the following:
For each SAM resource in the source template, we translate to the underlying CloudFormation Resources. After we translate, we append any metadata in the SAM Resource to the translated CloudFormation Resources.

They generally works but I think there might be a couple edge cases outstanding:

  1. S3 buckets are updated (I made a comment below about this)
  2. I am not sure how generated resources work in this case. If you have an API Event on an AWS::Serverless::Function.Event what happens? Does the Metadata get pass through correctly? That is the Metadata on AWS::Serverless::Function gets added to all the API Gateway resources? This would be a good test case to add regardless of it it works in the current implementation or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. see above

  2. Yes. A single SAM resource translates to multiple CFN resources. The metadata on the single SAM resource is passed through to the generated CFN resources, regardless of what the resource type is.

@jfuss
Copy link
Contributor

jfuss commented Jan 24, 2022

@moelasmar Can you re-review this? Things have changed since you last review

@moelasmar moelasmar self-requested a review January 24, 2022 22:55
@moelasmar moelasmar dismissed their stale review January 24, 2022 22:59

need to re-review it again, PR changed since last time I reviewed it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants