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

feat(parameters): accept boto3_client to support private endpoints and ease testing #1096

Merged
merged 21 commits into from
May 19, 2022

Conversation

ran-isenberg
Copy link
Contributor

@ran-isenberg ran-isenberg commented Apr 6, 2022

Fixes: #1079

Summary

Changes

Please provide a summary of what's being changed

This adds a new boto3_client constructor parameter to the Parameters feature to unblock customers using VPC endpoints.

I didn't add it to DynamoDB parameter because i'm not sure it's possible there. Fixed also the docs. All clients have it now, and DynamoDB has a note in docstrings + type referring to Resource Client (high-level) not Client (low-level) like SSM, SecretsManager and AppConfig.

User experience

Please share what the user experience looks like before and after this change

import boto3

from aws_lambda_powertools.utilities import parameters

# Initialize clients with custom VPC endpoint
ssm = boto3.client("ssm", endpoint_url="custom_endpoint")
secrets = boto3.client("secretsmanager", endpoint_url="custom_endpoint")
appconfig = boto3.client("appconfig", endpoint_url="custom_endpoint")


ssm_provider = parameters.SSMProvider(boto3_client=ssm)
secrets_provider = parameters.SecretsProvider(boto3_client=secrets)
appconf_provider = parameters.AppConfigProvider(environment="my_env", application="my_app", boto3_client=appconfig)

Checklist

If your change doesn't seem to apply, please leave them unchecked.

Is this a breaking change?

RFC issue number:

Checklist:

  • Migration process documented
  • Implement warnings (if it can live side by side)

Acknowledgment

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.


View rendered docs/utilities/parameters.md

@boring-cyborg boring-cyborg bot added area/utilities documentation Improvements or additions to documentation labels Apr 6, 2022
@pull-request-size pull-request-size bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Apr 6, 2022
@github-actions github-actions bot added the feature New feature or functionality label Apr 6, 2022
@codecov-commenter
Copy link

codecov-commenter commented Apr 6, 2022

Codecov Report

Merging #1096 (cec2f33) into develop (0777858) will increase coverage by 0.00%.
The diff coverage is 100.00%.

@@           Coverage Diff            @@
##           develop    #1096   +/-   ##
========================================
  Coverage    99.88%   99.88%           
========================================
  Files          119      119           
  Lines         5414     5425   +11     
  Branches       616      618    +2     
========================================
+ Hits          5408     5419   +11     
  Misses           2        2           
  Partials         4        4           
Impacted Files Coverage Δ
...ambda_powertools/utilities/parameters/appconfig.py 100.00% <100.00%> (ø)
aws_lambda_powertools/utilities/parameters/base.py 100.00% <100.00%> (ø)
...lambda_powertools/utilities/parameters/dynamodb.py 100.00% <100.00%> (ø)
..._lambda_powertools/utilities/parameters/secrets.py 100.00% <100.00%> (ø)
aws_lambda_powertools/utilities/parameters/ssm.py 100.00% <100.00%> (ø)

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 0777858...cec2f33. Read the comment docs.

@boring-cyborg boring-cyborg bot added the tests label Apr 6, 2022
@ran-isenberg
Copy link
Contributor Author

not really sure why codecov doesnt show an updated version. I added tests

@heitorlessa heitorlessa changed the title feat(parameters): Allow settings boto3.client() arguments fix(parameters): Allow settings boto3.client() arguments Apr 8, 2022
@github-actions github-actions bot added the bug Something isn't working label Apr 8, 2022
@heitorlessa
Copy link
Contributor

thanks for that @ran-isenberg - fixed the title as I see this as a bug as customers can't use the functionality we provide.

The pull request body is missing our required acknowledgements: are you okay if I edit the content to add them back as I can't review PRs without it?

Thanks a lot!

@ran-isenberg
Copy link
Contributor Author

@heitorlessa after all this time, do you really need to ask? :)
go for it

Copy link
Contributor

@heitorlessa heitorlessa left a comment

Choose a reason for hiding this comment

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

Two minor changes - 1/ Make use of forward reference for type annotation ( "SSMClient" from mypy_boto3_<service), and 2/ refactor branching logic into a static method to prevent logic discrepancy in a future change.

I ran out of time to look into the tests and DynamoDB, but I will as soon as I'm able.

Side note: Secrets Manager and SSM seem to be the only ones supporting endpoint_url according to this doc, yet boto3_client will benefit everyone's testing: https://docs.aws.amazon.com/vpc/latest/privatelink/integrated-services-vpce-list.html

docs/utilities/parameters.md Outdated Show resolved Hide resolved
aws_lambda_powertools/utilities/parameters/ssm.py Outdated Show resolved Hide resolved
aws_lambda_powertools/utilities/parameters/secrets.py Outdated Show resolved Hide resolved
aws_lambda_powertools/utilities/parameters/appconfig.py Outdated Show resolved Hide resolved
Comment on lines 80 to 85
if boto3_client is not None:
self.client = boto3_client
else:
session = boto3_session or boto3.session.Session()
self.client = session.client("appconfig", config=config)

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we turn this into a builder static method in the parent class? Return type could be Any as we will be able to cast the correct one for each client built w/ mypy_boto3.

This will prevent future an accidental logic discrepancy between them and localize change. It could accept the boto3_client, boto3_session, boto3_config, and boto3_service_name to initialize.

Let me know if it doesn't make sense

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 didnt add it to the dymamo class becuase we dont use a client there, not usre you can create a table from a client class.
so if it's not the dynamodb, it shouldn't be in the parent

@pull-request-size pull-request-size bot removed the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Apr 10, 2022
@boring-cyborg boring-cyborg bot added the dependencies Pull requests that update a dependency file label Apr 10, 2022
@pull-request-size pull-request-size bot added the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Apr 10, 2022
@michaelbrewer
Copy link
Contributor

michaelbrewer commented Apr 10, 2022

Two minor changes - 1/ Make use of forward reference for type annotation ( "SSMClient" from mypy_boto3_<service), and 2/ refactor branching logic into a static method to prevent logic discrepancy in a future change.

I ran out of time to look into the tests and DynamoDB, but I will as soon as I'm able.

Side note: Secrets Manager and SSM seem to be the only ones supporting endpoint_url according to this doc, yet boto3_client will benefit everyone's testing: docs.aws.amazon.com/vpc/latest/privatelink/integrated-services-vpce-list.html

@heitorlessa @ran-isenberg - should we be bundling boto3-stubs as part of the python runtime? self.client is typed as Any and so it only benefits internal usage and not external. And internally we just explode the sdk_options into the method. So very little benefit. It would be nice to keep this light before splitting up modules.

@heitorlessa heitorlessa linked an issue Apr 12, 2022 that may be closed by this pull request
@heitorlessa
Copy link
Contributor

Haven't forgotten @ran-isenberg. I'll look into as soon as I can this week.

@michaelbrewer
Copy link
Contributor

When this is released as is and it has to include a new runtime dependency for internal typing.

Can we include a warning in the changelog for customers like me at FiServ, who needs to scan for upstream issues and resolve conflicts if using a conflicting boto stubs.

Or change this make this optional dependency

@michaelbrewer
Copy link
Contributor

maybe 2 PRs

Copy link
Contributor

@heitorlessa heitorlessa left a comment

Choose a reason for hiding this comment

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

@ran-isenberg thanks for making those changes. I've made code change suggestions along with explanations about why they're needed - let me know if they don't make sense.

For the DynamoDB and parent static method piece, GitHub seems to have swallowed the review thread and I can't make comments anymore. I understand you concern about having a static method in the parent that's applicable to two clients (SSM, SecretsManager) but DynamoDB. I'd like to propose a solution to unblock this PR, as we still need to address DynamoDB regardless.

Suggestion: Add the same boto3_client in DynamoDB with an explicit resource type definition, plus doc strings as well as docs stating that we expect a DynamoDB resource client. I thought about boto3_resource_client but ultimately it will come down to practicality at this point, hence the suggestion of keeping boto3_client, as resource is also a client (high level vs low level).

aws_lambda_powertools/utilities/parameters/appconfig.py Outdated Show resolved Hide resolved
aws_lambda_powertools/utilities/parameters/appconfig.py Outdated Show resolved Hide resolved
aws_lambda_powertools/utilities/parameters/secrets.py Outdated Show resolved Hide resolved
aws_lambda_powertools/utilities/parameters/secrets.py Outdated Show resolved Hide resolved
aws_lambda_powertools/utilities/parameters/ssm.py Outdated Show resolved Hide resolved
aws_lambda_powertools/utilities/parameters/ssm.py Outdated Show resolved Hide resolved
docs/utilities/parameters.md Show resolved Hide resolved
pyproject.toml Outdated Show resolved Hide resolved
@heitorlessa heitorlessa removed the feature New feature or functionality label Apr 15, 2022
@michaelbrewer
Copy link
Contributor

@ran-isenberg thanks for making those changes. I've made code change suggestions along with explanations about why they're needed - let me know if they don't make sense.

For the DynamoDB and parent static method piece, GitHub seems to have swallowed the review thread and I can't make comments anymore. I understand you concern about having a static method in the parent that's applicable to two clients (SSM, SecretsManager) but DynamoDB. I'd like to propose a solution to unblock this PR, as we still need to address DynamoDB regardless.

Suggestion: Add the same boto3_client in DynamoDB with an explicit resource type definition, plus doc strings as well as docs stating that we expect a DynamoDB resource client. I thought about boto3_resource_client but ultimately it will come down to practicality at this point, hence the suggestion of keeping boto3_client, as resource is also a client (high level vs low level).

Great work in finding an alternative of doing typing checking during development time and not make a required runtime dependency.

But does this make sense as part of this pull request? At a minimum just the added client parameter is needed to resolve #1079

@heitorlessa heitorlessa changed the title fix(parameters): accept boto3_client to support private endpoints feat(parameters): accept boto3_client to support private endpoints May 18, 2022
@heitorlessa heitorlessa removed the bug Something isn't working label May 18, 2022
@github-actions github-actions bot added the feature New feature or functionality label May 18, 2022
@pull-request-size pull-request-size bot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels May 18, 2022
@heitorlessa
Copy link
Contributor

heitorlessa commented May 18, 2022

@heitorlessa @michaelbrewer I pushed the changes you wanted. I didnt do the dynamodb changes as I dont fully understand what you suggested. DynamoDB already gets an optional boto session, so not really sure what the client has to do with anything. We create a table from the session.
Feel free to make the changes yourself or explain them again :)

Thanks a lot for making those changes, Ran! I'll push the other changes and ping you for review later this week

As promised, I've transferred what I had in my local branch and made additional fixes. This is now ready for review.

@gshpychka - @sthulb will review and once approved we should release it ASAP to unblock the VPC private endpoints. We had a delay in getting this out to you due to a larger operational and internal work.

@heitorlessa heitorlessa requested a review from sthulb May 18, 2022 14:55
@michaelbrewer
Copy link
Contributor

@heitorlessa @michaelbrewer I pushed the changes you wanted. I didnt do the dynamodb changes as I dont fully understand what you suggested. DynamoDB already gets an optional boto session, so not really sure what the client has to do with anything. We create a table from the session.
Feel free to make the changes yourself or explain them again :)

Thanks a lot for making those changes, Ran! I'll push the other changes and ping you for review later this week

As promised, I've transferred what I had in my local branch and made additional fixes. This is now ready to be review.

@gshpychka - @sthulb will review and once approved we should release it ASAP to unblock the VPC private endpoints. We had a delay in getting this out to you due to a larger operational and internal work.

Would this be a major release update? Have you done integration testing (due to the large number of changes)

@@ -152,15 +158,19 @@ def __init__(
endpoint_url: Optional[str] = None,
config: Optional[Config] = None,
boto3_session: Optional[boto3.session.Session] = None,
boto3_client: Optional["DynamoDBServiceResource"] = None,

This comment was marked as resolved.

Copy link
Contributor

Choose a reason for hiding this comment

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

For this kind of change docs with examples should also be added to avoid confusion between using client vs resource.

note, the original request was for appconfig.

Copy link
Contributor

Choose a reason for hiding this comment

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

As a customer without clarification this would be confusing and not everyone uses mypy types

Copy link
Contributor

Choose a reason for hiding this comment

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

Agreed on the docs, I will make those changes tomorrow (docs, not param name) and merge it.

Copy link
Contributor

Choose a reason for hiding this comment

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

thanks clarity always helps.

Copy link
Contributor

Choose a reason for hiding this comment

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

overall for DynamoDBProvider the resource client so that you can set the endpoint url seems redundant when you already have endpoint_url as a parameter.

With 8 parameters now, this is borderline code smell.

Copy link
Contributor

Choose a reason for hiding this comment

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

@heitorlessa the docs definitely helps! It might be a good general call out to recommend people use boto3 session where possible

Copy link
Contributor

@sthulb sthulb left a comment

Choose a reason for hiding this comment

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

This PR looks fine to me.

My only qualm is about the order of session and clients in the providers, but given it's new functionality, it can be ignored

docs/utilities/parameters.md Show resolved Hide resolved
@sthulb
Copy link
Contributor

sthulb commented May 18, 2022

Would this be a major release update? Have you done integration testing (due to the large number of changes)

As per semver, this would require a minor release. 1.x.0, this doesn't remove any functionality or fundamentally change anything for users.

@michaelbrewer
Copy link
Contributor

michaelbrewer commented May 18, 2022

Would this be a major release update? Have you done integration testing (due to the large number of changes)

As per semver, this would require a minor release. 1.x.0, this doesn't remove any functionality or fundamentally change anything for users.

so a feature release ie: 1.26.0. I never expect this to be a 2.0.0 release.

@heitorlessa heitorlessa changed the title feat(parameters): accept boto3_client to support private endpoints feat(parameters): accept boto3_client to support private endpoints and ease testing May 19, 2022
@heitorlessa heitorlessa merged commit 45867fc into aws-powertools:develop May 19, 2022
heitorlessa added a commit to heitorlessa/aws-lambda-powertools-python that referenced this pull request May 20, 2022
* develop:
  chore: bump to 1.26.0
  chore(deps-dev): bump mypy-boto3-secretsmanager from 1.21.34 to 1.23.0.post1 (aws-powertools#1218)
  chore(deps-dev): bump mypy-boto3-appconfig from 1.21.34 to 1.23.0.post1 (aws-powertools#1219)
  chore(deps-dev): bump mypy-boto3-ssm from 1.21.34 to 1.23.0.post1 (aws-powertools#1220)
  chore(deps): bump pydantic from 1.9.0 to 1.9.1 (aws-powertools#1221)
  feat(parameters): accept boto3_client to support private endpoints and ease testing (aws-powertools#1096)
  fix(docs): remove Slack link (aws-powertools#1210)
@ran-isenberg ran-isenberg deleted the boto branch October 23, 2022 19:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation feature New feature or functionality size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat(parameters): Allow settings boto3.client() arguments
5 participants