AWS for DevOps — SSM Parameter Store

2 minute read

11.1 — SSM Parameter Store

Parameter Store is a free, centralized place to store configuration values. It supports hierarchical paths, versioning, and optional encryption.

Real-World Analogy

Parameter Store is like a shared team notebook where you write down configuration settings. Everyone on the team can look up the database host, the Redis endpoint, or the feature flag — all in one place. You can also lock certain pages with a key (KMS encryption).

Storing Parameters

# Store a plain-text parameter
$ aws ssm put-parameter \
    --name "/myapp/production/db_host" \
    --value "prod-db.cluster-abc123.ap-south-1.rds.amazonaws.com" \
    --type String
{
    "Version": 1,
    "Tier": "Standard"
}

# Store an encrypted parameter (SecureString)
$ aws ssm put-parameter \
    --name "/myapp/production/db_password" \
    --value "SuperSecret123!" \
    --type SecureString
{
    "Version": 1,
    "Tier": "Standard"
}

# Store a comma-separated list
$ aws ssm put-parameter \
    --name "/myapp/production/allowed_origins" \
    --value "https://app.example.com,https://admin.example.com" \
    --type StringList

Retrieving Parameters

# Get a single parameter
$ aws ssm get-parameter \
    --name "/myapp/production/db_host"
{
    "Parameter": {
        "Name": "/myapp/production/db_host",
        "Type": "String",
        "Value": "prod-db.cluster-abc123.ap-south-1.rds.amazonaws.com",
        "Version": 1
    }
}

# Get a SecureString (decrypted)
$ aws ssm get-parameter \
    --name "/myapp/production/db_password" \
    --with-decryption
{
    "Parameter": {
        "Name": "/myapp/production/db_password",
        "Type": "SecureString",
        "Value": "SuperSecret123!",
        "Version": 1
    }
}

# Get all parameters under a path
$ aws ssm get-parameters-by-path \
    --path "/myapp/production/" \
    --with-decryption \
    --recursive

Hierarchical Organization

  /myapp/
  ├── production/
  │   ├── db_host          = prod-db.cluster-abc.rds.amazonaws.com
  │   ├── db_password      = (SecureString)
  │   ├── redis_host       = prod-redis.abc.cache.amazonaws.com
  │   └── feature_flags/
  │       ├── dark_mode    = true
  │       └── new_checkout = false
  ├── staging/
  │   ├── db_host          = staging-db.cluster-xyz.rds.amazonaws.com
  │   ├── db_password      = (SecureString)
  │   └── feature_flags/
  │       ├── dark_mode    = true
  │       └── new_checkout = true
  └── shared/
      ├── company_name     = Acme Corp
      └── support_email    = support@acme.com

Using in ECS Task Definitions

Reference Parameter Store values directly in your ECS task definition:

{
  "containerDefinitions": [
    {
      "name": "api",
      "image": "123456789012.dkr.ecr.ap-south-1.amazonaws.com/api:latest",
      "secrets": [
        {
          "name": "DB_HOST",
          "valueFrom": "arn:aws:ssm:ap-south-1:123456789012:parameter/myapp/production/db_host"
        },
        {
          "name": "DB_PASSWORD",
          "valueFrom": "arn:aws:ssm:ap-south-1:123456789012:parameter/myapp/production/db_password"
        }
      ]
    }
  ]
}

Using in Lambda

# Lambda can read parameters at runtime
$ aws lambda update-function-configuration \
    --function-name my-api \
    --environment Variables='{
      PARAM_PATH=/myapp/production/
    }'

In your Lambda code, use the AWS SDK to call ssm.get-parameters-by-path() at startup.

Versioning

# Update a parameter (creates a new version)
$ aws ssm put-parameter \
    --name "/myapp/production/db_host" \
    --value "new-prod-db.cluster-def456.rds.amazonaws.com" \
    --type String \
    --overwrite
{
    "Version": 2,
    "Tier": "Standard"
}

# Get a specific version
$ aws ssm get-parameter \
    --name "/myapp/production/db_host:1"

# Get parameter history
$ aws ssm get-parameter-history \
    --name "/myapp/production/db_host"

Common Mistakes

Mistake Why It Hurts Fix
Using String for passwords Stored in plain text Always use SecureString for sensitive values
Flat naming (no hierarchy) Hard to find parameters Use /app/env/key hierarchy
No IAM restriction by path Any service can read any parameter Grant access by path prefix: /myapp/production/*
Hardcoding parameter names Breaks across environments Use path prefix from environment variable

Quick Reference

Task Command
Put parameter aws ssm put-parameter --name NAME --value VAL --type String\|SecureString\|StringList
Get parameter aws ssm get-parameter --name NAME --with-decryption
Get by path aws ssm get-parameters-by-path --path /prefix/ --recursive --with-decryption
Delete parameter aws ssm delete-parameter --name NAME
Get history aws ssm get-parameter-history --name NAME

Next → Secrets Manager

Updated: