Secrets Manager and Parameter Store
Rotate database credentials automatically with Secrets Manager, store non-secret configuration in Parameter Store, and integrate both with Lambda and ECS.
Secrets Manager and Parameter Store is a free AWS Solutions Architect lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the AWS Solutions Architect learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
The Problem of Secrets in Code
A common and dangerous anti-pattern is storing secrets (database passwords, API keys, OAuth tokens) in application source code, environment variables, or configuration files checked into version control. When these repositories are exposed — accidentally made public, or accessed by an attacker — all secrets are compromised immediately. AWS provides two managed services to eliminate this problem: AWS Secrets Manager for credentials that need automatic rotation, and AWS Systems Manager Parameter Store for configuration values and non-rotating secrets.
# Anti-pattern: secrets in code (NEVER do this)
# db_password = 'supersecret123'
# api_key = 'sk-abc123def456'
# Best practice: retrieve at runtime
import boto3
client = boto3.client('secretsmanager', region_name='us-east-1')
response = client.get_secret_value(SecretId='prod/myapp/db-password')
password = response['SecretString'] # fresh value, always currentAWS Secrets Manager Overview
AWS Secrets Manager is a managed service for storing, retrieving, and automatically rotating secrets. It encrypts all secrets with KMS (by default using an AWS managed key, or your CMK). Secrets can store any structured data as a key-value JSON string. Secrets Manager charges $0.40/secret/month plus $0.05 per 10,000 API calls. Key differentiator from Parameter Store: built-in automatic rotation for RDS, Redshift, DocumentDB, and custom secrets via Lambda rotation functions — no application changes needed during rotation.
# Create a secret in Secrets Manager
aws secretsmanager create-secret \
--name 'prod/myapp/database' \
--description 'Production MySQL credentials' \
--secret-string '{"username":"admin","password":"changeme123","host":"mydb.rds.amazonaws.com","port":3306,"dbname":"orders"}'
# Retrieve the secret (by application)
aws secretsmanager get-secret-value \
--secret-id 'prod/myapp/database' \
--query 'SecretString' \
--output text | python3 -c 'import sys,json; s=json.load(sys.stdin); print(s["password"])'Automatic Rotation with Secrets Manager
Automatic rotation is Secrets Manager's most powerful feature. For RDS databases, Secrets Manager natively rotates passwords by: 1) Generating a new password. 2) Updating the database user's password in RDS. 3) Updating the secret with the new password. 4) Verifying the new credentials work. All of this happens while your application is running — zero downtime, no manual intervention. Applications always call get-secret-value to retrieve the current password, so they automatically use the rotated credentials.
# Enable automatic rotation for RDS secret
aws secretsmanager rotate-secret \
--secret-id 'prod/myapp/database' \
--rotation-rules AutomaticallyAfterDays=30 \
--rotation-lambda-arn arn:aws:lambda:us-east-1:123:function:SecretsManagerRDSMySQLRotationSingleUser
# AWS provides pre-built rotation Lambda functions for:
# - RDS MySQL/PostgreSQL/MariaDB/Oracle/SQL Server
# - DocumentDB
# - Redshift
# - Custom: write your own Lambda for other services
# Application code: always call GetSecretValue, never cache long-termCaching Secrets Locally
Calling Secrets Manager on every database query would be expensive and slow. Best practice is to cache the secret locally in memory for a short period. AWS provides official Secrets Manager caching clients for Java and Python that cache secrets for a configurable TTL. When the cache expires, the client re-fetches the secret from Secrets Manager. If an application receives an authentication error (indicating the password was rotated), it immediately refreshes the cache and retries. This pattern provides performance and freshness without hammering the Secrets Manager API.
# Python: Secrets Manager caching client
# pip install aws-secretsmanager-caching
from botocore.session import get_session
from aws_secretsmanager_caching import SecretCache, SecretCacheConfig
client = get_session().create_client('secretsmanager')
cache = SecretCache(
config=SecretCacheConfig(secret_refresh_interval=3600), # cache 1 hour
client=client
)
# Returns cached value unless refresh interval expired
secret = cache.get_secret_string('prod/myapp/database')AWS Systems Manager Parameter Store
AWS Systems Manager (SSM) Parameter Store is a free (for standard parameters) hierarchical key-value store for configuration data and secrets. It supports String, StringList, and SecureString parameter types. SecureString encrypts values with KMS. Unlike Secrets Manager, Parameter Store does NOT support automatic rotation — it is designed for configuration values that change infrequently. Standard parameters are free and can store up to 4 KB. Advanced parameters support larger values (up to 8 KB), parameter policies (expiration and rotation reminders), and cost $0.05/parameter/month.
# Create Parameter Store parameters
aws ssm put-parameter \
--name '/prod/myapp/db-host' \
--value 'mydb.cluster-abc.us-east-1.rds.amazonaws.com' \
--type String
aws ssm put-parameter \
--name '/prod/myapp/db-password' \
--value 'mysecretpassword' \
--type SecureString \
--key-id alias/my-kms-key
# Retrieve parameter
aws ssm get-parameter \
--name '/prod/myapp/db-password' \
--with-decryption \
--query 'Parameter.Value' --output textParameter Store Hierarchy and IAM
Organise Parameter Store values using a hierarchical path structure that mirrors your environment and application architecture. This allows fine-grained IAM policies that grant access to parameters by path prefix. For example, grant a Lambda function access only to parameters under /prod/payment-service/ — it cannot access other services' parameters. This principle of least privilege for configuration prevents one compromised service from reading another service's secrets.
# Parameter hierarchy
/prod/payment-service/db-password
/prod/payment-service/stripe-api-key
/prod/order-service/db-password
/prod/order-service/redis-url
/staging/payment-service/db-password
# IAM policy: payment-service Lambda can ONLY read its params
{
'Effect': 'Allow',
'Action': ['ssm:GetParameter', 'ssm:GetParameters', 'ssm:GetParametersByPath'],
'Resource': 'arn:aws:ssm:us-east-1:123:parameter/prod/payment-service/*'
}
# Get all parameters for an app at once
aws ssm get-parameters-by-path \
--path '/prod/payment-service/' \
--with-decryption --recursiveSecrets Manager vs Parameter Store: When to Use Each
Choose between the two services based on your requirements: Use Secrets Manager when: you need automatic secret rotation, you are storing database credentials, the secret must be shared across multiple AWS accounts, or compliance requires documented rotation policies. Use Parameter Store when: you need configuration values (non-secret), you want a free solution for simple key-value storage, you need hierarchical configuration with path-based access control, or you need to store parameter version history. Many architectures use both together: Parameter Store for config, Secrets Manager for credentials.
# Usage comparison:
# Secrets Manager:
# Cost: $0.40/secret/month
# Rotation: Automatic (RDS, custom Lambda)
# Cross-account: Yes
# Best for: Database passwords, API keys, OAuth tokens
# Parameter Store:
# Cost: Free (standard) / $0.05/month (advanced)
# Rotation: Manual only
# Cross-account: No (use Secrets Manager)
# Best for: Config values, feature flags, non-rotating secretsIntegrating with Lambda and ECS
Lambda functions and ECS tasks should retrieve secrets at startup, not at every invocation. For Lambda: retrieve secrets in the initialisation code (outside the handler function) and cache in global variables — the Lambda execution environment persists between invocations, so secrets are only fetched once per environment lifetime. For ECS: use the secrets field in the task definition to inject Secrets Manager values or Parameter Store SecureStrings as environment variables — ECS retrieves and injects them at task launch without any application code changes.
# ECS task definition: inject secret as environment variable
{
'containerDefinitions': [{
'name': 'api',
'image': 'my-api:latest',
'secrets': [
{
'name': 'DB_PASSWORD',
'valueFrom': 'arn:aws:secretsmanager:us-east-1:123:secret:prod/myapp/database:password::'
},
{
'name': 'API_KEY',
'valueFrom': '/prod/myapp/api-key'
}
]
}]
}
# Application reads DB_PASSWORD from env var
# ECS injects the current secret value at task startParameter Store for EC2 AMI IDs
A practical but often overlooked use of Parameter Store is storing AMI IDs and other deployment references. Instead of hardcoding AMI IDs in your CloudFormation templates (which become stale when new AMIs are released), reference a Parameter Store value. Your CI/CD pipeline updates the AMI ID in Parameter Store whenever a new golden AMI is built. CloudFormation reads the latest AMI ID from Parameter Store at deploy time. AWS also publishes the latest Amazon Linux AMI IDs in public Parameter Store paths that you can reference directly.
# Get AWS public AMI ID from Parameter Store
aws ssm get-parameter \
--name '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64' \
--query 'Parameter.Value' --output text
# CloudFormation: reference public AMI parameter
Parameters:
LatestAmiId:
Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
Default: '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64'
Resources:
MyEC2:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref LatestAmiIdAudit and Compliance for Secrets
Secrets governance requires knowing who accessed secrets and when. AWS CloudTrail records every API call to Secrets Manager and Parameter Store: GetSecretValue, PutParameter, GetParameter. This gives you a complete audit trail for compliance. Use CloudWatch Alarms on CloudTrail metrics to alert when secrets are accessed outside normal patterns — for example, if a production secret is accessed from an unusual IAM principal or from an IP not in your known range, fire an alert for investigation.
# CloudTrail metric filter: alert on unexpected secret access
aws logs put-metric-filter \
--log-group-name CloudTrail/management-events \
--filter-name 'SecretAccessOutsideHours' \
--filter-pattern '{ $.eventSource = "secretsmanager.amazonaws.com" && $.eventName = "GetSecretValue" && $.userAgent != "lambda.amazonaws.com" }' \
--metric-transformations \
metricName=UnexpectedSecretAccess,metricNamespace=Security,metricValue=1
# Then create CloudWatch alarm on this metric
# Alert fires when non-Lambda principal accesses secretsCross-Account Secret Sharing
In multi-account architectures, applications in one account sometimes need secrets managed in another account (e.g., a central Security account manages all RDS passwords). Secrets Manager resource policies allow cross-account access. Configure a resource-based policy on the secret that grants a role in the consuming account permission to call GetSecretValue. The consuming account role must also have an IAM policy allowing calls to the secret's ARN. KMS key policies must also grant the consuming account access to the CMK used to encrypt the secret.
# Secret resource policy: allow cross-account access
aws secretsmanager put-resource-policy \
--secret-id 'prod/shared/rds-password' \
--resource-policy '{
"Statement": [{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::999999999999:role/AppRole"
},
"Action": "secretsmanager:GetSecretValue",
"Resource": "*"
}]
}'
# KMS key policy must also allow account 999999999999
# IAM policy in 999999999999 must allow GetSecretValue on ARNQuick Check
Test your understanding of AWS Solutions Architect (SAA-C03) concepts from this lesson.
Lesson Recap
In this lesson you learned: Secrets Manager provides automatic rotation for database credentials and API keys, and is the preferred choice for secrets that must rotate, Parameter Store provides free hierarchical configuration storage with path-based IAM access control, and ECS and Lambda can inject secrets as environment variables without application code changes. CloudTrail provides audit trails for all secret access. Next up we explore WAF, Shield, and Network Firewall.
Frequently asked questions
Is the “Secrets Manager and Parameter Store” lesson free?
Yes — the full text of “Secrets Manager and Parameter Store” is free to read here on the web, and the AWS Solutions Architect course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the AWS Solutions Architect course, upgrade to CoddyKit PRO.
What will I learn in “Secrets Manager and Parameter Store”?
Rotate database credentials automatically with Secrets Manager, store non-secret configuration in Parameter Store, and integrate both with Lambda and ECS. You practise AWS Solutions Architect with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start AWS Solutions Architect?
No prior experience is required. AWS Solutions Architect on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Secrets Manager and Parameter Store” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this AWS Solutions Architect lesson?
Yes. Every AWS Solutions Architect lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- KMS, ACM, and Encryption Patterns
- GuardDuty, Inspector, and Macie
- Secrets Manager and Parameter Store
- WAF, Shield, and Network Firewall