diff --git a/aws_lambda_powertools/utilities/parameters/ssm.py b/aws_lambda_powertools/utilities/parameters/ssm.py index e03eea9e31c..dec785b97a8 100644 --- a/aws_lambda_powertools/utilities/parameters/ssm.py +++ b/aws_lambda_powertools/utilities/parameters/ssm.py @@ -626,6 +626,8 @@ def get_parameters( """ Retrieve multiple parameter values from AWS Systems Manager (SSM) Parameter Store + For readability, we strip the path prefix name in the response. + Parameters ---------- path: str @@ -664,9 +666,8 @@ def get_parameters( >>> >>> for key, value in values.items(): ... print(key, value) - /my/path/prefix/a Parameter value a - /my/path/prefix/b Parameter value b - /my/path/prefix/c Parameter value c + config Parameter value (/my/path/prefix/config) + webhook/config Parameter value (/my/path/prefix/webhook/config) **Retrieves parameter values and decodes them using a Base64 decoder** diff --git a/docs/utilities/parameters.md b/docs/utilities/parameters.md index ade28bc49b7..97a7ab3156d 100644 --- a/docs/utilities/parameters.md +++ b/docs/utilities/parameters.md @@ -33,7 +33,7 @@ This utility requires additional permissions to work as expected. | SSM | **`get_parameters`**, **`SSMProvider.get_multiple`** | **`ssm:GetParametersByPath`** | | SSM | **`get_parameters_by_name`**, **`SSMProvider.get_parameters_by_name`** | **`ssm:GetParameter`** and **`ssm:GetParameters`** | | SSM | If using **`decrypt=True`** | You must add an additional permission **`kms:Decrypt`** | -| Secrets | **`get_secret`**, **`SecretsProvider.get`** | **`secretsmanager:GetSecretValue`** | +| Secrets | **`get_secret`**, **`SecretsProvider.get`** | **`secretsmanager:GetSecretValue`** | | DynamoDB | **`DynamoDBProvider.get`** | **`dynamodb:GetItem`** | | DynamoDB | **`DynamoDBProvider.get_multiple`** | **`dynamodb:Query`** | | AppConfig | **`get_app_config`**, **`AppConfigProvider.get_app_config`** | **`appconfig:GetLatestConfiguration`** and **`appconfig:StartConfigurationSession`** | @@ -53,26 +53,34 @@ For multiple parameters, you can use either: * `get_parameters_by_name` to fetch distinct parameters by their full name. It also accepts custom caching, transform, decrypt per parameter. === "getting_started_recursive_ssm_parameter.py" - ```python hl_lines="3 10 13" + This is useful when you want to fetch all parameters from a given path, say `/dev`, e.g., `/dev/config`, `/dev/webhook/config` + + To ease readability in deeply nested paths, we strip the path name. For example: + + * `/dev/config` -> `config` + * `/dev/webhook/config` -> `webhook/config` + + ```python hl_lines="3 11 18" --8<-- "examples/parameters/src/getting_started_recursive_ssm_parameter.py" ``` === "getting_started_parameter_by_name.py" - ```python hl_lines="3 14" + ```python hl_lines="3 15" --8<-- "examples/parameters/src/getting_started_parameter_by_name.py" ``` -???+ tip "`get_parameters_by_name` supports graceful error handling" - By default, we will raise `GetParameterError` when any parameter fails to be fetched. You can override it by setting `raise_on_error=False`. +=== "get_parameter_by_name_error_handling.py" + !!! tip "Failing gracefully if one or more parameters cannot be fetched or decrypted." - When disabled, we take the following actions: + By default, we will raise `GetParameterError` when any parameter fails to be fetched. - * Add failed parameter name in the `_errors` key, _e.g._, `{_errors: ["/param1", "/param2"]}` - * Keep only successful parameter names and their values in the response - * Raise `GetParameterError` if any of your parameters is named `_errors` + You can override it by setting `raise_on_error=False`. When disabled, we take the following actions: -=== "get_parameter_by_name_error_handling.py" - ```python hl_lines="3 5 12-13 15" + * Add failed parameter name in the `_errors` key, _e.g._, `{_errors: ["/param1", "/param2"]}` + * Keep only successful parameter names and their values in the response + * Raise `GetParameterError` if any of your parameters is named `_errors` + + ```python hl_lines="3 5 13-17" --8<-- "examples/parameters/src/get_parameter_by_name_error_handling.py" ``` @@ -389,16 +397,16 @@ You can use arbitrary keyword arguments to pass it directly to the underlying SD Here is the mapping between this utility's functions and methods and the underlying SDK: -| Provider | Function/Method | Client name | Function name | -| ------------------- | ------------------------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| SSM Parameter Store | `get_parameter` | `ssm` | [get_parameter](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ssm.html#SSM.Client.get_parameter){target="_blank"} | -| SSM Parameter Store | `get_parameters` | `ssm` | [get_parameters_by_path](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ssm.html#SSM.Client.get_parameters_by_path){target="_blank"} | -| SSM Parameter Store | `SSMProvider.get` | `ssm` | [get_parameter](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ssm.html#SSM.Client.get_parameter){target="_blank"} | -| SSM Parameter Store | `SSMProvider.get_multiple` | `ssm` | [get_parameters_by_path](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ssm.html#SSM.Client.get_parameters_by_path){target="_blank"} | -| Secrets Manager | `get_secret` | `secretsmanager` | [get_secret_value](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager.html#SecretsManager.Client.get_secret_value){target="_blank"} | -| Secrets Manager | `SecretsProvider.get` | `secretsmanager` | [get_secret_value](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager.html#SecretsManager.Client.get_secret_value){target="_blank"} | -| DynamoDB | `DynamoDBProvider.get` | `dynamodb` | ([Table resource](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#table){target="_blank"}) | [get_item](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#DynamoDB.Table.get_item) | -| DynamoDB | `DynamoDBProvider.get_multiple` | `dynamodb` | ([Table resource](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#table){target="_blank"}) | [query](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#DynamoDB.Table.query) | +| Provider | Function/Method | Client name | Function name | +| ------------------- | ------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| SSM Parameter Store | `get_parameter` | `ssm` | [get_parameter](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ssm.html#SSM.Client.get_parameter){target="_blank"} | +| SSM Parameter Store | `get_parameters` | `ssm` | [get_parameters_by_path](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ssm.html#SSM.Client.get_parameters_by_path){target="_blank"} | +| SSM Parameter Store | `SSMProvider.get` | `ssm` | [get_parameter](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ssm.html#SSM.Client.get_parameter){target="_blank"} | +| SSM Parameter Store | `SSMProvider.get_multiple` | `ssm` | [get_parameters_by_path](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ssm.html#SSM.Client.get_parameters_by_path){target="_blank"} | +| Secrets Manager | `get_secret` | `secretsmanager` | [get_secret_value](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager.html#SecretsManager.Client.get_secret_value){target="_blank"} | +| Secrets Manager | `SecretsProvider.get` | `secretsmanager` | [get_secret_value](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager.html#SecretsManager.Client.get_secret_value){target="_blank"} | +| DynamoDB | `DynamoDBProvider.get` | `dynamodb` | ([Table resource](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#table){target="_blank"}) | [get_item](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#DynamoDB.Table.get_item) | +| DynamoDB | `DynamoDBProvider.get_multiple` | `dynamodb` | ([Table resource](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#table){target="_blank"}) | [query](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#DynamoDB.Table.query) | | App Config | `get_app_config` | `appconfigdata` | [start_configuration_session](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/appconfigdata.html#AppConfigData.Client.start_configuration_session){target="_blank"} and [get_latest_configuration](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/appconfigdata.html#AppConfigData.Client.get_latest_configuration){target="_blank"} | ### Bring your own boto client diff --git a/examples/parameters/src/getting_started_recursive_ssm_parameter.py b/examples/parameters/src/getting_started_recursive_ssm_parameter.py index 5325a7fba96..96ec68b49f3 100644 --- a/examples/parameters/src/getting_started_recursive_ssm_parameter.py +++ b/examples/parameters/src/getting_started_recursive_ssm_parameter.py @@ -6,12 +6,16 @@ def lambda_handler(event: dict, context: LambdaContext): try: - # Retrieve multiple parameters from a path prefix - all_parameters: dict = parameters.get_parameters("/lambda-powertools/", max_age=20) + # Retrieve all parameters within a path e.g., /dev + # Say, you had two parameters under `/dev`: /dev/config, /dev/webhook/config + all_parameters: dict = parameters.get_parameters("/dev", max_age=20) endpoint_comments = None + # We strip the path prefix name for readability and memory usage in deeply nested paths + # all_parameters would then look like: + ## all_parameters["config"] = value # noqa: ERA001 + ## all_parameters["webhook/config"] = value # noqa: ERA001 for parameter, value in all_parameters.items(): - if parameter == "endpoint_comments": endpoint_comments = value