SSM Parameter Store

Used to store bits of system configuration in a secure and scalable way.

It’s a public service, so in order to access it the resource must have access to the AWS Public zone.

It’s basically a regional key-value store where you can store configuration and secrets. Apps, Lambda Functions and EC2 Instances can access it. Its access is managed by IAM.

It’s got a hierarchical structure and versioning.

You can store:

  • Strings

  • String Lists

  • Secure Strings (uses KMS to encrypt/decrypt the value, the caller needs permissions to use the involved keys)

Used for:

  • License keys

  • DB connection strings

  • Full configs

  • Passwords/API keys

Changes on parameters can create events on CloudWatch/EventBridge.

Hirarchy

If you need complex configs, you can use a hierarchical structure to store them.

For example:

  • /myApp/DB/DBPassword ⇒ Secure String

  • /myApp/redis/redisPassword ⇒ Secure String

  • /myApp/redis/redisHost ⇒ String

  • /myApp/redis/redisPort ⇒ String

  • /myApp/frontend/websocketUpgradeEnabled ⇒ String

  • /myApp/frontend/CORSAccessControlAllowOrigin ⇒ Strings List

Furthermore you cann access keys like redisHost by either using myApp/redis/redisHost or by pulling myApp/redis and then using redisHost.

Permissions can be set either on individual parameters or on a parent.

Public parameters

For instance the latest AMI per region. It’s maintained by AWS.

Working with the CLI

# Get rid of the pager
$ export AWS_PAGER=""

# Create a string parameter
$ aws ssm put-parameter \
        --name /myApp/redis/redisHost \
        --value "myredis.mydomain.com" \
        --type "String"

# Get a parameter
$ aws ssm get-parameter \
         --name /myApp/redis/redisHost

# Get a string parameter value
$ aws ssm get-parameter \
       --name /myApp/redis/redisHost \
       --query 'Parameter.Value'  # Or use jq

# Get a string parameter value in text format (no quotes)
$ aws ssm get-parameter \
        --name /myApp/redis/redisHost \
        --query 'Parameter.Value' \
        --output text   # Or use jq -r

# Delete a  parameter
$ aws ssm delete-parameter \
        --name /myApp/redis/redisHost

# Creating a StringList parameter
$ aws ssm put-parameter \
        --name /myApp/frontend/CORSAccessControlAllowOrigin \
        --value 'myapp.io,myapp.com' \
        --type StringList

# Create a SecureString parameter
# It'll be encrypted using the AWS Managed KMS key
# Add --key-id to use a custom KMS Key
$ aws ssm put-parameter \
        --name /myApp/redis/redisPassword \
        --value 'supersecurepassword' \
        --type SecureString

# Get the  parameter (The value is ENCRYPTED)
$ aws ssm get-parameter \
        --name /myApp/redis/redisPassword

# Get the  parameter (Descrypts the value)
# SSM knows what key was used, if you don't have permissions on that key you'll get an error
$ aws ssm get-parameter \
        --name /myApp/redis/redisPassword \
        --with-decryption

Versions

# Create a parameter
$ aws ssm put-parameter \
        --name /myApp/redis/redisHost \
        --value "myredis.mydomain.com" \
        --type "String" \

# --overwrite has a new version created
$ aws ssm put-parameter \
        --name /myApp/redis/redisHost \
        --value "myredis.mydomain.com" \
        --type "String" \
         --overwrite

# Get the old version
$ aws ssm get-parameter \
         --name /myApp/redis/redisHost:1


# Get the new one
$ aws ssm get-parameter \
         --name /myApp/redis/redisHost:2