AWS for DevOps — Secrets Manager

2 minute read

11.2 — Secrets Manager

Secrets Manager is designed for storing and automatically rotating sensitive credentials like database passwords, API keys, and OAuth tokens.

Real-World Analogy

Secrets Manager is like a bank vault with a time lock. You store your most valuable items (passwords, keys) inside. The vault can automatically change the combination (rotate the secret) on a schedule, and only people with the right badge (IAM policy) can access it.

Creating a Secret

# Store database credentials
$ aws secretsmanager create-secret \
    --name myapp/production/db-credentials \
    --description "Production RDS credentials" \
    --secret-string '{
      "username": "app_user",
      "password": "InitialPassword123!",
      "engine": "mysql",
      "host": "prod-db.cluster-abc123.rds.amazonaws.com",
      "port": 3306,
      "dbname": "myapp"
    }'
{
    "ARN": "arn:aws:secretsmanager:ap-south-1:123456789012:secret:myapp/production/db-credentials-AbCdEf",
    "Name": "myapp/production/db-credentials",
    "VersionId": "abc123-def456"
}

# Store an API key
$ aws secretsmanager create-secret \
    --name myapp/production/stripe-api-key \
    --description "Stripe API key for production" \
    --secret-string "sk_live_abc123def456"

Retrieving a Secret

# Get the current secret value
$ aws secretsmanager get-secret-value \
    --secret-id myapp/production/db-credentials
{
    "Name": "myapp/production/db-credentials",
    "SecretString": "{\"username\":\"app_user\",\"password\":\"InitialPassword123!\",\"engine\":\"mysql\",\"host\":\"prod-db.cluster-abc123.rds.amazonaws.com\",\"port\":3306,\"dbname\":\"myapp\"}",
    "VersionId": "abc123-def456",
    "VersionStages": ["AWSCURRENT"]
}

Automatic Rotation

Secrets Manager can automatically rotate secrets using a Lambda function:

# Enable rotation (every 30 days)
$ aws secretsmanager rotate-secret \
    --secret-id myapp/production/db-credentials \
    --rotation-lambda-arn arn:aws:lambda:ap-south-1:123456789012:function:SecretsManagerRotation \
    --rotation-rules AutomaticallyAfterDays=30

Rotation Flow

  Day 1                  Day 30                 Day 60
  ─────┬────────────────────┬────────────────────┬────
       │                    │                    │
  Password: abc123     Password: xyz789     Password: qrs456
       │                    │                    │
       └── Lambda rotates ──┘── Lambda rotates ──┘
           1. Creates new password
           2. Updates RDS user
           3. Tests new password
           4. Sets as AWSCURRENT

Using in ECS Task Definitions

{
  "containerDefinitions": [
    {
      "name": "api",
      "image": "123456789012.dkr.ecr.ap-south-1.amazonaws.com/api:latest",
      "secrets": [
        {
          "name": "DB_USERNAME",
          "valueFrom": "arn:aws:secretsmanager:ap-south-1:123456789012:secret:myapp/production/db-credentials:username::"
        },
        {
          "name": "DB_PASSWORD",
          "valueFrom": "arn:aws:secretsmanager:ap-south-1:123456789012:secret:myapp/production/db-credentials:password::"
        }
      ]
    }
  ]
}

The format for referencing specific keys: SECRET_ARN:JSON_KEY:VERSION_STAGE:VERSION_ID

Resource Policy (Cross-Account Access)

$ aws secretsmanager put-resource-policy \
    --secret-id myapp/production/db-credentials \
    --resource-policy '{
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "AWS": "arn:aws:iam::987654321098:root"
          },
          "Action": "secretsmanager:GetSecretValue",
          "Resource": "*"
        }
      ]
    }'

Secret Versioning

Stage Meaning
AWSCURRENT The active secret value used by applications
AWSPENDING The new value during rotation (before validation)
AWSPREVIOUS The previous value (kept for rollback)

Common Mistakes

Mistake Why It Hurts Fix
Storing secrets in Parameter Store (String type) Not encrypted by default Use Secrets Manager or SecureString
Not enabling rotation Stale passwords are a risk Enable auto-rotation (30-90 days)
Logging secret values Secrets leak into CloudWatch Never log secret values; log secret names only
Hardcoding secret ARNs Breaks across accounts Use naming convention + construct ARN dynamically

Quick Reference

Task Command
Create secret aws secretsmanager create-secret --name NAME --secret-string VALUE
Get secret aws secretsmanager get-secret-value --secret-id NAME
Update secret aws secretsmanager update-secret --secret-id NAME --secret-string VALUE
Rotate secret aws secretsmanager rotate-secret --secret-id NAME --rotation-rules AutomaticallyAfterDays=30
Delete secret aws secretsmanager delete-secret --secret-id NAME --recovery-window-in-days 7
List secrets aws secretsmanager list-secrets

Next → SSM Session Manager

Updated: