Versioning, hierarchy and advanced parameters in Parameter Store
AWS Parameter Store is a fully-managed service for storing strings, string lists and encrypted strings.
It’s an important building block in securing applications. Stored secrets can be detached from the application and can be used by multiple services.
1. Assumptions
1.1. Account and CLI
You’ll need to have a free AWS account, user credentials for programmatic access to AWS services and the AWS CLI installed on your computer if you want to successfully submit the following CLI commands.
You’ll also need the necessary IAM permissions to create, update and delete parameters. If you are an admin user in your account, this won’t be an issue.
1.2. Parameter
I’ll use the secret I created for the last post. If you don’t have a secret stored in Parameter Store, you can quickly create one:
aws ssm put-parameter --name JWT-Secret --type SecureString --value 'secret-string'
I can check if I have a parameter in the Parameter Store:
aws ssm describe-parameters
This command should return an object similar to this:
{
"Parameters": [
{
"Name": "JWT-Secret",
"Type": "SecureString",
"KeyId": "alias/aws/ssm",
"LastModifiedDate": 1575153932.655,
"LastModifiedUser": "arn:aws:iam::123456789123:user/<USER>",
"Version": 1,
"Tier": "Standard",
"Policies": []
}
]
}
The response shows everything I need to know about parameters. Most of these properties will be discussed below.
The Type
of the parameter can be String
, StringList
or SecureString
. Secure strings are encrypted using KMS while strings and string lists (comma separated strings) are not.
2. Versioning
Versioning in Parameter Store (just like in any other services supporting versions) protects the user from accidentally overriding parameters.
Let’s prove this statement by making another PutParameter
API call. This time I’ll try to overwrite the value of JWT-Secret
:
aws ssm put-parameter --name JWT-Secret --type SecureString --value 'another-string'
Parameter Store should return a ParameterAlreadyExists
error, which means (guess what) that the parameter already exists, which is absolutely true because I’ve just created one with the same name.
By default Parameter Store assign version 1
to a new parameter. I’ll need to use the overwrite
option to update the parameter, hence I’ll create a new version:
aws ssm put-parameter --name JWT-Secret --type SecureString \\
--value 'another-value' --overwrite
overwrite
is a boolean option with the default setting being true
, so I don’t need to explicitly define the value.
The response should show the version:
{
"Version": 2
}
From now on, if I call the DescribeParameters
API (or any API that returns the parameter), the response will show the latest version:
aws ssm describe-parameters
This command will result in something similar:
{
"Parameters": [
{
"Name": "JWT-Secret",
"Type": "SecureString",
"KeyId": "alias/aws/ssm",
"LastModifiedDate": 1575834019.215,
"LastModifiedUser": "arn:aws:iam::123456789123:user/<USER>",
"Version": 2,
"Tier": "Standard",
"Policies": []
}
]
}
If you are not convinced, I can show you the value of the parameter:
aws ssm get-parameter --name JWT-Secret --with-decryption
The response confirms that I have received the latest version (2
):
{
"Parameter": {
"Name": "JWT-Secret",
"Type": "SecureString",
"Value": "another-value",
"Version": 2,
"LastModifiedDate": 1575834019.215,
"ARN": "arn:aws:ssm:us-west-2:123456789123:parameter/JWT-Secret"
}
}
But if I explicitly state which version I want to get, I can display the old value of the parameter:
aws ssm get-parameter --name JWT-Secret:1 --with-decryption
Now I have version 1
:
{
"Parameter": {
"Name": "JWT-Secret",
"Type": "SecureString",
"Value": "secret-string",
"Version": 1,
"Selector": ":1",
"LastModifiedDate": 1575153932.655,
"ARN": "arn:aws:ssm:us-west-2:123456789123:parameter/JWT-Secret"
}
}
The with-decryption
option will display the decrypted secure string. If this option is not stated, the encrypted secret will be displayed.
3. Hierarchy
Hierarchy in Parameter Store means that I name the parameter as a path starting with the /
character.
This way the parameters are easier to manage (especially if I already have thousands of parameters) and search.
JWT-Secret
is a root level parameter because it doesn’t contain any paths in the name.
But I could have used a hierarchy structure instead. For example, a popular way to organize parameters looks like this:
/ENVIRONMENT/APPLICATION/PARAMETER
In practice, this means that I name my parameter like /dev/my-app/JWT-Secret
or /staging/my-app/JWT-Secret
. This way I can refer to the parameter in my code as such:
const params = {
Name: `/${process.env.ENVIRONMENT}/my-app/JWT-Secret`,
};
const secret = (await ssm.getParameter(params).promise()).Parameter.Value;
ENVIRONMENT
can be dev
, staging
or production
or whatever I want (I usually want these, though).
Now I feel better and more organized that I create my parameters this way, but hierarchy brings me other benefits.
I can search parameters by path:
aws ssm get-parameters-by-path --path /dev/my-app
The GetParametersByPath
API call will return all parameters under the /dev/my-app
path. If I have 22 parameters starting with /dev/my-app
, the API response will contain 22 parameters. This is more than just cool.
On the top of that, it’s possible to create IAM policies and allow/deny access to path parameters. This feature has the advantage of allowing developers to access dev
and staging
parameters, but denying access to everything in production
.
4. Advanced parameters
The third feature I discuss today is the tier
of the parameter.
By default Parameter Store creates standard parameters. They can hold a maximum of 4 kB data and they all come for free.
Sometimes I want to store more than 4 kB, or it can happen that the size of an existing parameter will go above 4 kB. If this is the case, I need to create an advanced parameter.
I can upgrade a standard parameter to an advanced one but I can’t go backwards. This has some practical reasons, for example, the size of the parameter will be truncated down to 4 kB and there will be a data loss.
Advanced parameters can store up to 8 kB, which is still not that much, but it’s more than enough for storing secrets, passwords, URLs etc. Parameter Store is not suitable for storing long essays.
Advanced parameters cost money: it’s 5 cents per month, which is pro-rated if the parameter is less than a month old. They also use parameter policies.
To create advanced parameters I’ll need to specify the tier
option (the default value is standard
):
aws ssm put-parameter --name /dev/my-app/Advanced-Secret --type SecureString \\
--value 'advanced secret-string' --tier Advanced
There’s a third option for tier
, which is the Intelligent-Tiering
. This option will take a look at the parameter and based on the length and the defined options Parameter Store will place the parameter into either the Standard
or Advanced
tier.
5. Summary
Parameter Store is a flexible and secure service to store secrets and other important strings.
It offers versioning, hierarchy for better organization and advanced tier for advanced use cases.
Thanks for reading and see you next time.