By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
(For AWS Solutions Architect – Associate & Real-World Cloud Engineers)
You’re a cloud engineer at a fintech startup. Your team just migrated a monolithic app to AWS, and the database credentials are hardcoded in a config.py file. Your CISO flags this as a critical security risk—if the repo leaks, attackers get the keys to your production database. Worse, rotating credentials means manually updating every service that uses them.
config.py
This is where AWS Secrets Manager and Parameter Store come in.Both services let you store, retrieve, and rotate secrets (passwords, API keys, DB credentials) securely, but they’re not interchangeable. Picking the wrong one can: - Break your app (if you need automatic rotation but use Parameter Store).- Blow your budget (Secrets Manager costs 10x more for the same secret).- Fail compliance audits (if you need encryption with customer-managed KMS keys but use the wrong service).
Real-world scenario:You’re deploying a serverless app with Lambda, RDS, and API Gateway. You need: 1. Database credentials (rotated every 30 days).2. API keys (static, used by multiple services).3. Environment variables (like STAGE=prod).
STAGE=prod
Which service do you use for each? This guide will answer that—and show you how to implement it.
When to use which?- Use Secrets Manager if: - You need automatic rotation (e.g., RDS, Redshift, or third-party API keys). - You need audit logs for secret access (CloudTrail). - You’re PCI-DSS or HIPAA compliant (Secrets Manager is pre-approved).- Use Parameter Store if: - You need free/cheap storage for configs (e.g., DB_HOST=prod-db.example.com). - You’re storing non-sensitive data (e.g., feature flags, environment variables). - You need hierarchical paths (e.g., /prod/app/db-url).
DB_HOST=prod-db.example.com
/prod/app/db-url
✅ AWS account with admin IAM permissions (or at least secretsmanager:* and ssm:*).✅ AWS CLI installed (aws --version).✅ A test secret (e.g., DB_PASSWORD=SuperSecret123!).
secretsmanager:*
ssm:*
aws --version
DB_PASSWORD=SuperSecret123!
Goal: Securely store an RDS password and enable automatic rotation.
aws secretsmanager create-secret \ --name "prod/rds/master-password" \ --description "Master password for prod RDS instance" \ --secret-string '{"username":"admin","password":"SuperSecret123!"}' \ --kms-key-id "alias/aws/secretsmanager" # Use default KMS key
Expected output:
{ "ARN": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/rds/master-password-abc123", "Name": "prod/rds/master-password", "VersionId": "abc123-456-def-789" }
aws secretsmanager rotate-secret \ --secret-id "prod/rds/master-password" \ --rotation-lambda-arn "arn:aws:lambda:us-east-1:123456789012:function:SecretsManagerRotation" \ --rotation-rules "{\"AutomaticallyAfterDays\": 30}"
⚠️ Note:- You must have a Lambda function for rotation (AWS provides a template).- For RDS, AWS has a pre-built rotation Lambda (search for AWSSecretsManagerRDSMySQLRotationSingleUser in Lambda).
AWSSecretsManagerRDSMySQLRotationSingleUser
import boto3 import json def lambda_handler(event, context): client = boto3.client('secretsmanager') response = client.get_secret_value(SecretId='prod/rds/master-password') secret = json.loads(response['SecretString']) db_user = secret['username'] db_pass = secret['password'] print(f"Connecting to DB with user: {db_user}") # Use db_pass to connect to RDS return {"status": "success"}
{"status": "success"}
Goal: Store a static API key (no rotation needed) in Parameter Store.
aws ssm put-parameter \ --name "/prod/api/stripe-key" \ --value "sk_test_51ABC123..." \ --type "SecureString" \ --key-id "alias/aws/ssm" # Use default KMS key
{ "Version": 1, "Tier": "Standard" }
import boto3 def lambda_handler(event, context): client = boto3.client('ssm') response = client.get_parameter( Name='/prod/api/stripe-key', WithDecryption=True ) api_key = response['Parameter']['Value'] print(f"Using Stripe API key: {api_key[:5]}...") # Don't log full key! return {"status": "success"}
Goal: Estimate monthly costs for 100 secrets.
Production insight:- If you don’t need rotation, Parameter Store (Standard) is free.- If you need rotation, Secrets Manager is mandatory (but costs more).
✅ Least privilege IAM policies:- Never use secretsmanager:* or ssm:* in production.- Example policy for Lambda: json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "secretsmanager:GetSecretValue", "ssm:GetParameter" ], "Resource": [ "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/*", "arn:aws:ssm:us-east-1:123456789012:parameter/prod/*" ] } ] }
json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "secretsmanager:GetSecretValue", "ssm:GetParameter" ], "Resource": [ "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/*", "arn:aws:ssm:us-east-1:123456789012:parameter/prod/*" ] } ] }
✅ Enable CloudTrail logging for secret access:
aws cloudtrail create-trail --name SecretsAudit --s3-bucket-name my-audit-logs
✅ Use customer-managed KMS keys (not AWS-managed) for compliance:
aws kms create-key --description "Key for Secrets Manager"
✅ Use Parameter Store for static configs (free tier).✅ Use Secrets Manager only for rotating secrets (e.g., RDS, API keys).✅ Delete unused secrets (Secrets Manager charges per secret, even if unused).
✅ Use hierarchical naming (e.g., /prod/app/db-url, /dev/app/db-url).✅ Tag secrets for cost allocation:
/dev/app/db-url
aws secretsmanager tag-resource \ --secret-id "prod/rds/master-password" \ --tags Key=Environment,Value=Production Key=Team,Value=Backend
✅ Enable versioning (both services support it).
✅ Monitor secret access with CloudWatch:
aws logs put-metric-filter \ --log-group-name "/aws/secretsmanager" \ --filter-name "SecretAccess" \ --filter-pattern "{ $.eventName = \"GetSecretValue\" }" \ --metric-transformations metricName=SecretAccess,metricNamespace=Secrets,metricValue=1
✅ Set up alerts for failed rotations (Secrets Manager).
String
SecureString
secretsmanager:GetSecretValue
❌ Parameter Store (even Advanced).
"You need to store a 5KB API key. Which service should you use?"
❌ Parameter Store (max 4KB for Standard, 8KB for Advanced).
"You need to store 1,000 environment variables for free. Which service?"
❌ Secrets Manager ($0.40/secret/month).
"Which service is PCI-DSS compliant by default?"
You’re deploying a Lambda function that needs: 1. A database password (rotated every 30 days).2. A Stripe API key (static, no rotation).3. An environment variable (STAGE=prod).
Which AWS service should you use for each, and how would you retrieve them in Python?
import boto3 import os def lambda_handler(event, context): # 1. Database password (Secrets Manager - rotation needed) secrets_client = boto3.client('secretsmanager') db_secret = secrets_client.get_secret_value(SecretId='prod/rds/master-password') db_creds = json.loads(db_secret['SecretString']) # 2. Stripe API key (Parameter Store - static) ssm_client = boto3.client('ssm') stripe_key = ssm_client.get_parameter( Name='/prod/api/stripe-key', WithDecryption=True )['Parameter']['Value'] # 3. Environment variable (Lambda env vars - simplest) stage = os.environ['STAGE'] return { "db_user": db_creds['username'], "stripe_key_prefix": stripe_key[:5], # Don't log full key! "stage": stage }
Why this works:- Secrets Manager for the rotating DB password (compliance + automation).- Parameter Store for the static Stripe key (cheaper, no rotation needed).- Lambda env vars for non-sensitive configs (simplest option).
# Create a secret aws secretsmanager create-secret --name "prod/db/password" --secret-string '{"username":"admin","password":"..."}' # Rotate a secret (30 days) aws secretsmanager rotate-secret --secret-id "prod/db/password" --rotation-lambda-arn "arn:aws:lambda:..." --rotation-rules '{"AutomaticallyAfterDays": 30}' # Retrieve a secret (CLI) aws secretsmanager get-secret-value --secret-id "prod/db/password" # Retrieve a secret (Python) import boto3 client = boto3.client('secretsmanager') secret = client.get_secret_value(SecretId='prod/db/password')
# Store a secure parameter aws ssm put-parameter --name "/prod/api/key" --value "sk_test_..." --type "SecureString" # Retrieve a parameter (CLI) aws ssm get-parameter --name "/prod/api/key" --with-decryption # Retrieve a parameter (Python) import boto3 client = boto3.client('ssm') param = client.get_parameter(Name='/prod/api/key', WithDecryption=True)
⚠️ Secrets Manager costs $0.40/secret/month (even if unused).⚠️ Parameter Store (Standard) has a 4KB size limit.⚠️ Rotation Lambda must be in the same region as the secret.⚠️ KMS encryption is mandatory for Secrets Manager (optional for Parameter Store).
Now go delete those hardcoded passwords from your config.py files! ?
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.