SSM Parameter Store
Every application needs settings: a database host, a feature flag, an API key, a log level. You could hard-code these, but then changing one means redeploying your app. SSM Parameter Store is a free, managed service (part of AWS Systems Manager, often shortened to SSM) that holds these values centrally so your code can fetch them at runtime. It can store plain text or encrypted secrets, organizes everything into a folder-like hierarchy, and locks down access with IAM (Identity and Access Management — AWS’s permissions system). This page shows how to create, read, and secure parameters, and when to use Parameter Store versus the pricier Secrets Manager.
What a parameter is
A parameter is a single named key with a value. The name uses a slash-separated path so you can group related settings, for example /myapp/prod/db/host. Those slashes create a hierarchy (a tree, like folders), which lets you read a whole branch at once and apply permissions to an entire prefix.
Each parameter has a type:
| Type | What it holds | Encrypted? |
|---|---|---|
String | A single plain-text value | No |
StringList | Comma-separated values | No |
SecureString | A secret value encrypted with AWS KMS (Key Management Service — AWS’s service for managing encryption keys) | Yes |
When to use this: for any configuration your app reads at runtime — non-secret values like a region or feature flag (String), and simple secrets like an API key or password (SecureString). When NOT to: if you need automatic password rotation or very large/high-throughput secrets, reach for Secrets Manager instead (covered at the end of this page).
Standard vs advanced tier
Parameter Store has two tiers. The standard tier is free and fine for almost everyone. The advanced tier costs money but raises the limits.
| Feature | Standard (free) | Advanced (paid) |
|---|---|---|
| Parameters per account/Region | 10,000 | 100,000 |
| Maximum value size | 4 KB | 8 KB |
| Parameter policies (expiration, etc.) | No | Yes |
| Higher API throughput | No (use --no-... default limits) | Yes (with the higher-throughput setting) |
| Cost | $0 for storage | $0.05 per advanced parameter per month |
Cost tip: Standard parameters are completely free to store. You only ever pay for higher-throughput API calls or advanced parameters. For typical apps, Parameter Store costs nothing.
Creating a parameter
Console steps
- Open the AWS Management Console and go to Systems Manager.
- In the left menu, under Application Management, click Parameter Store.
- Click Create parameter.
- Enter a Name using a path, e.g.
/myapp/prod/db/host. - Choose the Tier (
Standard). - Choose the Type — pick
Stringfor plain config orSecureStringfor a secret. - If you chose
SecureString, leave the KMS key asalias/aws/ssm(the default AWS-managed key) unless you need your own. - Enter the Value, e.g.
db.internal.example.com. - Click Create parameter.
CLI equivalent
For a plain config value:
aws ssm put-parameter \
--name "/myapp/prod/db/host" \
--type String \
--value "db.internal.example.com"
For an encrypted secret, use SecureString. AWS encrypts it for you using KMS:
aws ssm put-parameter \
--name "/myapp/prod/db/password" \
--type SecureString \
--value "s3cr3t-Pa55!"
Output:
{
"Version": 1,
"Tier": "Standard"
}
To update an existing parameter, add --overwrite to the same command.
Reading parameters
Your application fetches values at runtime. By default a SecureString is returned still encrypted, so you add --with-decryption to get the plain value (the caller must have KMS permission to decrypt).
aws ssm get-parameter \
--name "/myapp/prod/db/password" \
--with-decryption
Output:
{
"Parameter": {
"Name": "/myapp/prod/db/password",
"Type": "SecureString",
"Value": "s3cr3t-Pa55!",
"Version": 1,
"ARN": "arn:aws:ssm:us-east-1:111122223333:parameter/myapp/prod/db/password"
}
}
Because the names form a hierarchy, you can grab a whole branch in one call with get-parameters-by-path. This is great for loading all of an environment’s settings at startup:
aws ssm get-parameters-by-path \
--path "/myapp/prod" \
--recursive \
--with-decryption
Controlling access with IAM
Access is enforced by IAM policies. You grant read access to a path prefix, so an app only sees its own settings. The wildcard * matches everything under the path.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["ssm:GetParameter", "ssm:GetParametersByPath"],
"Resource": "arn:aws:ssm:us-east-1:111122223333:parameter/myapp/prod/*"
},
{
"Effect": "Allow",
"Action": "kms:Decrypt",
"Resource": "arn:aws:kms:us-east-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"
}
]
}
Security gotcha: Reading a
SecureStringneeds both thessm:GetParameterpermission andkms:Decryptpermission on the KMS key. If you forget the KMS permission, the call fails with anAccessDeniedExceptioneven though the SSM permission is correct.
Defining parameters as code
You can also manage parameters with infrastructure as code so they live in version control. Here is a CloudFormation snippet (note: CloudFormation cannot create SecureString values directly, so use it for String config and create secrets separately):
Resources:
DbHost:
Type: AWS::SSM::Parameter
Properties:
Name: /myapp/prod/db/host
Type: String
Value: db.internal.example.com
Parameter Store vs Secrets Manager
Both can store secrets, so which do you pick? The short answer: start with Parameter Store to save money, and switch to Secrets Manager only when you need its extra features.
| Feature | Parameter Store (standard) | Secrets Manager |
|---|---|---|
| Plain config values | Yes | No (secrets only) |
| Encrypted secrets | Yes (SecureString) | Yes |
| Automatic rotation | No | Yes, built in |
| Max value size | 4 KB (8 KB advanced) | 64 KB |
| Cost | Free (standard) | ~$0.40 per secret/month + API calls |
Rule of thumb: Use Parameter Store for plain configuration and simple secrets that you rotate rarely or by hand. Reach for Secrets Manager when you specifically need automatic credential rotation, larger secret values, or very high request throughput.
Best practices
- Use a consistent path scheme like
/app/environment/component/keyso permissions and lookups are predictable. - Store secrets as
SecureString, never as plainString, and grantkms:Decryptonly to the roles that truly need it. - Stay on the free standard tier unless you hit the 10,000-parameter or 4 KB limits — most apps never do.
- Load a whole config branch at startup with
get-parameters-by-pathinstead of making one API call per value. - Use IAM path prefixes to give each app or environment access to only its own parameters.
- Turn on AWS CloudTrail to keep an audit log of who read or changed each parameter.
- When you genuinely need rotation or large secrets, move that single value to Secrets Manager rather than upgrading the whole store.