Skip to main content

A custom loader for Dynaconf that uses AWS Systems Manager Parameter Store as a source of truth.

Project description

When configured, this loader will permit Dynaconf to query AWS Systems Manager Parameter Store for slash-delimited hierarchical configuration data.

Loader Configuration

An example:

from dynaconf import Dynaconf

settings = Dynaconf(
    environments=True,
    settings_file="settings.toml",
    LOADERS_FOR_DYNACONF=[
        "dynaconf_aws_loader.loader",
        "dynaconf.loaders.env_loader"
    ],
)

Note that for the basic functioning of this loader, the environments option for Dynaconf must be set, and an environment must be used.

Configuration Variables

Both of the following configuration values should be set in the environment to avoid a chicken/egg scenario for initializing this custom loader:

  • SSM_PARAMETER_PROJECT_PREFIX_FOR_DYNACONF: Required. The project prefix in the parameter store path. For example, if the parameter hierarchy looks something like /baldur/development/database_uri, then in this case SSM_PARAMETER_PROJECT_PREFIX_FOR_DYNACONF=baldur.

  • SSM_PARAMETER_NAMESPACE_FOR_DYNACONF: Optional. This provides an additional level of grouping once the project and environment have been determined. For example, if the parameter hierarchy looks something like /baldur/pr-123/development/database_uri, then SSM_PARAMETER_NAMESPACE_FOR_DYNACONF=pr-123.

The following optional variables should be set in your settings.toml (or equivalent format), if desired:

  • SSM_ENDPOINT_URL_FOR_DYNACONF: If your AWS SSM uses a different endpoint than the AWS default. This can be useful for local development when you are running something like LocalStack.

  • SSM_SESSION_FOR_DYNACONF: If you require custom boto3.session.Session arguments, you can specify then as a dictionary here. Note that this will override the default boto3 credential configuration.

  • SSM_LOAD_DEFAULT_ENV_FOR_DYNACONF: Boolean, defaults to True. If you want the SSM loader to load keys under the default environment name. The key name itself can be set via the Dynaconf setting of DEFAULT_ENV_FOR_DYNACONF if you want it to be something other than default.

Parameter Store Details

The structure that this loader expects from the path-based organization in SSM is:

/<project-name>/<environment>/<parameter-name>

An optional namespace can be specified as a sub-project grouping for parameters:

/<project-name>/<environment>/<namespace>/<parameter-name>

Note that if you choose to use a namespace identifier, it must not conflict with existing environment identifiers.

If SSM_LOAD_DEFAULT_ENV_FOR_DYNACONF is set to True (which is the default value), the loader will add whatever the value of DEFAULT_ENV_FOR_DYNACONF as an environment key to load from SSM. The typical use case here is to have a default value for all environments that can be overriden on a per-environment basis as necessary.

Security Considerations

For this loader to function correctly and securely, the use of IAM policies to restrict which parameters can be read/mutated is highly encouraged.

Policies can be enacted on a glob-path basis, which will ensure that the only parameters that can be fetched/hydrated into the local object instance are the ones that the current environment is permitted to load.

The following policy for a fictional account allows a user to call the DescribeParameters and GetParameters API operations for parameters that begin with the path /testapp/production:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:DescribeParameters"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ssm:GetParameters"
            ],
            "Resource": "arn:aws:ssm:us-east-1:000000000000:parameter/testapp/production*"
        }
    ]
}

Setting Parameters via Boto3

Parameters may be set via the AWS Web Console UI, or one of their many client libraries. The boto3 library is perhaps the most well-known, and the process is relatively straightforward:

import boto3
ssm_client = boto3.client("ssm")

ssm_client.put_parameter(
    Name="/testapp/development/database/host",
    Value="localhost",
    Type="String",
)

ssm_client.put_parameter(
    Name="/testapp/production/database/password",
    Value="sekrit",
    Type="SecureString",
)

ssm_client.put_parameter(
    Name="/testapp/production/database/host",
    Value="db.example.com",
    Type="String",
)

ssm_client.put_parameter(
    Name="/testapp/production/admin_email",
    Value="help@example.com",
    Type="String",
)

This creates a parameter hierarchy with the following structure:

{
    "testapp": {
        "development": {"database": {"host": "localhost"}},
        "production": {
            "database": {"host": "db.example.com", "password": "sekrit"},
            "admin_email": "help@example.com",
        },
    },
}

Parameter Name Limitations

AWS SSM has the following key (and thus path) limitations:

  • Parameter names are case sensitive

  • A parameter name must be unique within an Amazon Web Services Region

  • A parameter name can’t be prefixed with “aws” or “ssm” (case-insensitive)

  • Parameter names can include only the following symbols and letters: a-zA-Z0-9_.-

  • The slash character ( / ) is used to delineate hierarchies in parameter names

  • A parameter name can’t include spaces

  • Parameter hierarchies are limited to a maximum depth of fifteen levels

Testing

  1. Have Docker installed and running

  2. Clone this repository

  3. Ensure you have poetry available on your system

  4. poetry run pytest

The test suite will spin up an ephemeral Docker container; it may take a few seconds for it to load. The relevant test fixtures will handle setting parameters and their values in the Localstack SSM service.

TODO

  • [ ] CI configuration for matrix-based python/dynaconf version testing

  • [ ] Handle Parameter Store references to AWS Secrets Manager

  • [ ] Make tests/docker-compose.yml more configurable, e.g. ports, in case a different Localstack container is already running for the user

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dynaconf_aws_loader-0.5.0.tar.gz (8.8 kB view hashes)

Uploaded Source

Built Distribution

dynaconf_aws_loader-0.5.0-py3-none-any.whl (11.4 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page