Skip to main content

How to store and access secrets when deploying in AWS

As we move to a more automated system, with scripts, templates and playbooks containing all the deployment information for both infrastructure and code, handling secrets can become challenging. This is especially true when deploying into the cloud, where everything is done through the Internet and you need to ensure your keys, passwords, secrets and other parameters don’t show up in plain text in your code repositories.

To solve this issue, Amazon introduced the concept of a Parameters Store as part of its Systems Manager page. This can be used to store key/value pairs for free, of up to 4KB in length. They can also be encrypted using a KMS key, and retrieved by your code or through the command line. All you need is the right IAM permission, it doesn’t need to be tied to a SSM managed instance.

Creating our parameter

To create a parameter manually, log into your AWS console and go to the SSM page. Under the Parameters section, click on Add parameter. There, you can give it a name, a description, and select the type of parameter you want to store. If you pick SecureString then you have a specify a KMS key, either one of your own or the default one. Once done, you have your key/value pair accessible from the console:

Please note that while advanced parameters have more options, like a lifecycle policy, those also cost a monthly fee.

To automate the creation of a KMS key and a parameter from the command line, you can use these commands:

aws kms create-key --description ssm-kms-key --region us-west-2
aws ssm put-parameter --name test-key --value "This is a secret" --type SecureString --key-id ssm-kms-key --region us-west-2

Retrieving our parameter

Now that our test-key is created, all you need is to assign the ssm:GetParameters IAM permission to your role or user. Then you can use the command line interface to get your parameter:

$ aws ssm get-parameters --names "test-key" --with-decryption
{
    "InvalidParameters": [],
    "Parameters": [
        {
            "Name": "test-key",
            "LastModifiedDate": 1576793121.052,
            "Value": "This is a secret",
            "Version": 1,
            "Type": "SecureString",
            "ARN": "arn:aws:ssm:us-west-2:1234567890:parameter/test-key"
        }
    ]
}

Or, you can also access it through code, for example in Python:

import boto3
ssm = boto3.client('ssm', region_name='us-west-2')
ssm.get_parameters(Names=['test-key'], WithDecryption=True)

From there, you can use calls to SSM to get passwords and keys from your CI/CD pipelines, your Lambda functions and anything that resides in the cloud and has a need to access secrets which shouldn’t be stored in any git repository.