Skip to content

add: TaggingService functionality to Lambda Provider #11745

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

Merged
merged 3 commits into from
Oct 29, 2024

Conversation

gregfurman
Copy link
Contributor

@gregfurman gregfurman commented Oct 24, 2024

Motivation

Changes

  • Extended TestLambdaTag suite to include tagging tests for Event Source Mappings
  • Refactored/reworked the internal tag_resource, list_tags, and untag_resource Lambda provider functions to use a provider-wde TaggingService. This allows for tagging of Lambda Event Source Mapping or Lambda Function resources (with support for CSC but this is not yet implemented).

Testing

@gregfurman gregfurman added aws:lambda AWS Lambda semver: minor Non-breaking changes which can be included in minor releases, but not in patch releases labels Oct 24, 2024
@gregfurman gregfurman added this to the Playground milestone Oct 24, 2024
@gregfurman gregfurman self-assigned this Oct 24, 2024
Copy link

github-actions bot commented Oct 24, 2024

LocalStack Community integration with Pro

    2 files  ±  0      2 suites  ±0   1h 20m 58s ⏱️ - 20m 42s
2 585 tests  - 925  2 269 ✅  - 828  316 💤  - 97  0 ❌ ±0 
2 587 runs   - 925  2 269 ✅  - 828  318 💤  - 97  0 ❌ ±0 

Results for commit 4c00bab. ± Comparison against base commit 0338932.

This pull request removes 930 and adds 5 tests. Note that renamed tests count towards both.
tests.aws.scenario.bookstore.test_bookstore.TestBookstoreApplication ‑ test_lambda_dynamodb
tests.aws.scenario.bookstore.test_bookstore.TestBookstoreApplication ‑ test_opensearch_crud
tests.aws.scenario.bookstore.test_bookstore.TestBookstoreApplication ‑ test_search_books
tests.aws.scenario.bookstore.test_bookstore.TestBookstoreApplication ‑ test_setup
tests.aws.scenario.kinesis_firehose.test_kinesis_firehose.TestKinesisFirehoseScenario ‑ test_kinesis_firehose_s3
tests.aws.scenario.lambda_destination.test_lambda_destination_scenario.TestLambdaDestinationScenario ‑ test_destination_sns
tests.aws.scenario.lambda_destination.test_lambda_destination_scenario.TestLambdaDestinationScenario ‑ test_infra
tests.aws.scenario.loan_broker.test_loan_broker.TestLoanBrokerScenario ‑ test_prefill_dynamodb_table
tests.aws.scenario.loan_broker.test_loan_broker.TestLoanBrokerScenario ‑ test_stepfunctions_input_recipient_list[step_function_input0-SUCCEEDED]
tests.aws.scenario.loan_broker.test_loan_broker.TestLoanBrokerScenario ‑ test_stepfunctions_input_recipient_list[step_function_input1-SUCCEEDED]
…
tests.aws.services.lambda_.test_lambda_api.TestLambdaTag ‑ test_create_tag_on_esm_create
tests.aws.services.lambda_.test_lambda_api.TestLambdaTag ‑ test_tag_exceptions[event_source_mapping]
tests.aws.services.lambda_.test_lambda_api.TestLambdaTag ‑ test_tag_exceptions[lambda_function]
tests.aws.services.lambda_.test_lambda_api.TestLambdaTag ‑ test_tag_lifecycle[event_source_mapping]
tests.aws.services.lambda_.test_lambda_api.TestLambdaTag ‑ test_tag_lifecycle[lambda_function]

♻️ This comment has been updated with latest results.

@gregfurman gregfurman marked this pull request as ready for review October 25, 2024 13:39
stored_tags = function.tags or {}
stored_tags |= tags
self._store_tags(function=function, tags=stored_tags)
tag_svc_adapted_tags = [{"Key": key, "Value": value} for key, value in tags.items()]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We need to adapt the tags TaggingService <-> LambdaProvider when doing storage and retrieval of tags.

Copy link
Member

Choose a reason for hiding this comment

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

It seems Lambda is doing something custom here (tag adaptation). Does it still make sense to use the TaggingService?

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 like the unified approach to tagging. Even though adapting in this way is a bit janky, I think the benefits of a single svc outweighs the costs of adapting to suit it.

In future, maybe we can extend the tag svc to better account for cases like this.

case "event-source-mapping":
self._get_esm(resource_identifier, account_id, region)
case "code-signing-config":
raise NotImplementedError("Resource tagging on CSC not yet implemented.")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We haven't implemented tagging on Code SIgning Configuration as of yet, but we can easily extend the above to include it.

fn = self._get_function(function_name=fn_name, account_id=account_id, region=region)

self._update_tags(fn, tags)
if (resource_id := extract_resource_from_arn(resource)) and resource_id.startswith(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately we need to run these dirty checks to ensure a Revision ID gets updated

Copy link
Member

Choose a reason for hiding this comment

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

yeah, I see that we haven't found a good solution yet for dealing with the revision id updates in general 🤔

A small concern here is that the function and function version update are not synchronized with the tagging service, leading to potential race conditions (tag update and revision id updates not synchronized; quite unlikely, and consequences should be negligible). Would function locking via with function.lock around the _store_tags prevent the race condition?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Think we should rather look at improving this entire approach in a follow-up

Copy link
Member

Choose a reason for hiding this comment

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

+1, good idea

Copy link
Member

@joe4dev joe4dev left a comment

Choose a reason for hiding this comment

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

Great tagging test additions 💯

As discussed, it might be worth unifying the tags to avoid confusion and improve maintainability 🚀

fn = self._get_function(function_name=fn_name, account_id=account_id, region=region)

self._update_tags(fn, tags)
if (resource_id := extract_resource_from_arn(resource)) and resource_id.startswith(
Copy link
Member

Choose a reason for hiding this comment

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

yeah, I see that we haven't found a good solution yet for dealing with the revision id updates in general 🤔

A small concern here is that the function and function version update are not synchronized with the tagging service, leading to potential race conditions (tag update and revision id updates not synchronized; quite unlikely, and consequences should be negligible). Would function locking via with function.lock around the _store_tags prevent the race condition?

stored_tags = function.tags or {}
stored_tags |= tags
self._store_tags(function=function, tags=stored_tags)
tag_svc_adapted_tags = [{"Key": key, "Value": value} for key, value in tags.items()]
Copy link
Member

Choose a reason for hiding this comment

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

It seems Lambda is doing something custom here (tag adaptation). Does it still make sense to use the TaggingService?

function = self._get_function(name, account, region)
with function.lock:
function.tags = tags
# dirty hack for changed revision id, should reevaluate model to prevent this:
Copy link
Member

Choose a reason for hiding this comment

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

style: yeah, this starts spreading like cancer 😅
maybe, we could consider extracting a helper method for this hack

Copy link
Member

@joe4dev joe4dev left a comment

Choose a reason for hiding this comment

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

Great work @gregfurman 👏

Thank you for the comprehensive test coverage and unifying tag storage ✨

sidenote: the PR description mentions "Fixes issue#x", which auto-closes the issue. We typically ask the customer for feedback using the response-required tag and stale bot to foster feedback instead of directly closing upon merge. It also avoids notifying the customer too early before an ext image is shipped

@gregfurman gregfurman merged commit f67ad4d into master Oct 29, 2024
33 checks passed
@gregfurman gregfurman deleted the add/lambda/tag-svc branch October 29, 2024 08:43
@gregfurman gregfurman modified the milestones: Playground, 4.0 Nov 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
aws:lambda AWS Lambda semver: minor Non-breaking changes which can be included in minor releases, but not in patch releases
Projects
None yet
Development

Successfully merging this pull request may close these issues.

bug: Terraform deployment for Event Source Mapping failing with ResourceNotFoundException
2 participants