How to Load Config From AWS SSM Parameter Store
Fetching config from AWS SSM Parameter Store at boot - instead of reading raw environment variables - means you can rotate a database URL or API key with a parameter update and a process restart, no redeploy needed.
Why SSM Parameter Store instead of environment variables
The 12-factor app rule "store config in the environment" made sense when the alternative was hardcoding values. AWS SSM Parameter Store goes a step further: config lives in a managed store with versioning, IAM-gated access, and optional encryption (SecureString). Rotation becomes a parameter update + a process restart. No image rebuild, no Kubernetes rollout, no redeploy.
Reading a parameter with boto3
import os
import boto3
def load_database_url() -> str:
ssm = boto3.client(
"ssm",
endpoint_url=os.environ.get("AWS_ENDPOINT_URL"), # override for local/moto testing
region_name=os.environ.get("AWS_DEFAULT_REGION", "us-east-1"),
)
try:
return ssm.get_parameter(Name="/app/database/url")["Parameter"]["Value"]
except Exception:
# fall back to env if SSM is unreachable or the parameter is missing
return os.environ["DATABASE_URL"]
The ["Parameter"]["Value"] path is the standard shape for a plain String parameter.
For SecureString parameters add WithDecryption=True:
ssm.get_parameter(Name="/app/db/password", WithDecryption=True)["Parameter"]["Value"]
Verify the parameter exists before you deploy
aws ssm get-parameter --name /app/database/url
# {
# "Parameter": {
# "Name": "/app/database/url",
# "Type": "String",
# "Value": "postgresql://user:pass@db:5432/myapp",
# ...
# }
# }
Cache it - do not call SSM on every request
SSM GetParameter has a 40 req/s per-account rate limit and adds ~5-20 ms of latency.
Read once at boot and store in a module-level variable:
_db_url: str | None = None
def get_database_url() -> str:
global _db_url
if _db_url is None:
_db_url = load_database_url()
return _db_url
For applications that need to pick up rotations without restarting, refresh the cached value on a background timer (e.g. every 5 minutes) rather than on every call.
Naming convention
Use a hierarchical path like /app/<env>/<service>/<param> - it maps cleanly to
IAM resource ARNs, lets you lock down access by prefix, and makes it obvious which
parameters belong to which service:
/app/prod/api/database_url
/app/prod/api/stripe_secret_key
/app/staging/api/database_url
IAM can then grant a role access to /app/prod/api/* without exposing staging or
other services.
Want to try it hands-on? HeyDevJob gives you this exact setup in a live cloud workspace in your browser - edit it, run it, and see it work. Free, nothing to install.
Try it in a workspace →What you'll practice
- Calling boto3 ssm.get_parameter and extracting the Value
- Adding an env-var fallback for local development and resilience
- Caching the parameter value at process startup to avoid per-request SSM calls
FAQ
How do I read a parameter from AWS SSM Parameter Store in Python?
Use boto3: ssm = boto3.client('ssm'); val = ssm.get_parameter(Name='/your/param')['Parameter']['Value']. For SecureString (encrypted) parameters, add WithDecryption=True. Read once at startup and cache the result.
How is SSM Parameter Store different from environment variables?
SSM stores config centrally with versioning and IAM-gated access. You can rotate a value - update the parameter, restart the process - without rebuilding the Docker image or redeploying. Environment variables are baked in at container start and can't change without a restart + redeploy.
Should I call SSM Parameter Store on every request?
No. GetParameter has a 40 req/s rate limit and adds latency. Read at startup, cache the value in memory, and optionally refresh it on a background timer if you need to pick up rotations without restarting.
What is the difference between SSM Parameter Store and Secrets Manager?
Both store config and secrets, but Secrets Manager adds built-in automatic rotation and costs per secret; Parameter Store is free for standard parameters and simpler. Use Parameter Store for general config, Secrets Manager when you need managed rotation.
Keep learning
Learn it by doing. Open this in a live cloud workspace, make the change yourself, and keep a record of the work you can share.
Open the workspace →