AWS Parameter Store Quick Start

I’ve seen a few different ways of storing secrets and parameter values for deployments. Some include puppet, storing on S3 and DynamoDB. But look no further, AWS have a service called AWS Parameter Store which allows you to store parameter values, encrypt them if required and even audit changes to parameters. So let’s see how you can quickly get AWS Parameter Store working with a custom encryption key.

The main steps are:

  • STEP 1: Create Policies and Roles
  • STEP 2: Create a CMK
  • STEP 3: Add Key ID to Roles
  • STEP 4: Create some parameters
  • STEP 5: Create EC2 instances
  • STEP 6: Access parameters
  • STEP 07: Check parameter history (Auditing)

———–

STEP 1: Create Policies and Roles

You will need a few policies and roles to get started with.

KMSAdminRole:

This role is required to administer the CMK (Customer Management Key) or custom key that will be used for encryption. IMPORTANT NOTE! This role will get attached to the CMK when it is created in Step 2. Do NOT delete this role. If you do delete the role you will not be able to manage key as the only time you get to assign a role to the CMK is upon creation. If you do accidentally delete this role you will need to contact AWS support to get them to regain control of the key.

Add the following Trust Relationship and Policy:

Trust Relationship:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

KMSAdminPolicy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "KMSAdminPolicy20171029",
            "Effect": "Allow",
            "Action": [
                "kms:CancelKeyDeletion",
                "kms:CreateAlias",
                "kms:CreateGrant",
                "kms:CreateKey",
                "kms:DeleteAlias",
                "kms:DeleteImportedKeyMaterial",
                "kms:DescribeKey",
                "kms:DisableKey",
                "kms:DisableKeyRotation",
                "kms:EnableKey",
                "kms:EnableKeyRotation",
                "kms:GenerateDataKey",
                "kms:GenerateDataKeyWithoutPlaintext",
                "kms:GenerateRandom",
                "kms:GetKeyPolicy",
                "kms:GetKeyRotationStatus",
                "kms:GetParametersForImport",
                "kms:ImportKeyMaterial",
                "kms:ListAliases",
                "kms:ListGrants",
                "kms:ListKeyPolicies",
                "kms:ListKeys",
                "kms:ListResourceTags",
                "kms:ListRetirableGrants",
                "kms:PutKeyPolicy",
                "kms:RevokeGrant",
                "kms:ScheduleKeyDeletion",
                "kms:TagResource",
                "kms:UntagResource",
                "kms:UpdateAlias",
                "kms:UpdateKeyDescription"
            ],
            "Resource": [
                "arn:aws:kms:us-east-1:REPLACE_WITH_AWS_ACCOUNT_ID:key/REPLACE_WITH_KEYID_LATER"
            ]
        }
    ]
}

Note: you will need to create the role so you can attach it to the CMK, however later in Step 3 you will be asked to edit the attached policy with the Key ID in Step 2. For now create it with an arbitrary value.

EC2ProdServiceRole/EC2DevServiceRole:

These roles will have policies to allow the EC2 instances assuming this role to use the CMK for decryption and also access the specified parameters.

Add the following to both EC2ProdServiceRole and EC2DevServiceRole roles

Trust Relationship:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

KMSEC2Policy:

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": [
            "kms:Encrypt",
            "kms:Decrypt"
        ],
        "Resource": [
            "arn:aws:kms:us-east-1:REPLACE_WITH_AWS_ACCOUNT_ID:key/REPLACE_WITH_KEYID_LATER
"
        ]
    }
}

Note: you will need to create the role so you can attach it to the CMK, however later on in Step 3 you will be asked to edit the attached policy with the Key ID in Step 2. For now create it with an arbitrary value.

Add the following to EC2ProdServiceRole

EC2ProdServicePolicy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:DescribeParameters",
                "ssm:GetParameter",
                "ssm:GetParametersByPath"
            ],
            "Resource": [
                "arn:aws:ssm:us-east-1:REPLACE_WITH_AWS_ACCOUNT_ID
:parameter/prod/*"
            ]
        }
    ]
}

Add the following to EC2DevServiceRole

EC2DevServicePolicy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:DescribeParameters",
                "ssm:GetParameter",
                "ssm:GetParametersByPath"
            ],
            "Resource": [
                "arn:aws:ssm:us-east-1:REPLACE_WITH_AWS_ACCOUNT_ID
:parameter/dev/*"
            ]
        }
    ]
}

STEP 2: Create a CMK

You can decide to optionally encrypt the values stored in Parameter Store. To do this you can use the default AWS key provided in every AWS account per region or you can create your own encryption key called a CMK (Customer Master Key). This needs to be created in KMS (Key Management System) under IAM (Identity and Access Management).

Navigate to the IAM role service and select the “Encryption keys” option from the left navigation pane. Now make sure you select the region you will be working in from the “Region” drop down. IAM roles are global but encryption keys are specific to a region. Then select “Create Key”.

Navigate: IAM >> Encryption key >> Select Region from dropdown >> Create Key

Give the key an alias, description and leave the Key Material Origin as KMS.

Figure 01: Create Key Alias

You can skip the Add Tags Step.

When defining the Administrative Key specify the KMSAdminRole created in Step1.

When defining the Key Usage Permissions specify the EC2ServiceRole created in Step1.

Lastly preview the policy and click “Finish”

This will create key with a Key ID

Figure 02: New key created

STEP 3: Add Key ID to Roles

Now you will have to edit the above policy resources and replace the “REPLACE_WITH_KEYID_LATER” text with the Key ID that you got at the end of Step 2. In other words add the Key ID ARN as the KMS Resource in the KMSAdminPolicy and the KMSEC2Policy.

STEP 4: Create some parameters

Navigate to the EC2 Service and select the “Parameter Store” option from the left navigation pane. Now click the “Create Parameter” button.

You will need to enter a Name, Description (Optional), Select a Type (String, String List, Secure String) and a Value. If Secure String type is selected you will also be asked to select a KMS Key ID.

When defining a name note you can specify a hierarchy like /prod/pwkey and /dev/pwkey. This type of naming convention comes in handy later on if you want to use environment variable to access the parameter values and sort the parameters you store in some logical hierarchy. Also note that best practice is not to name parameters as “password” as this becomes an obvious attack zone if your account is somehow compromised.

Types:

  • String: An unencrypted string value
  • String List: Unencrypted list of strings that are separated by comma.
  • Secure String: An encrypted string. You can specify which encryption (CMK) key to use when encrypting.

Create a String type parameter

Figure 03: String type parameter creation

Create a Secure String type parameter

Figure 04: Secure String type parameter creation

For this demo purpose I have created four parameters as follows

Figure 05: Testing parameters

STEP 5: Create EC2 instances

To demonstrate how to access parameters we need to setup two EC2 instances. Will demonstrate how the dev parameters will only be available for parameters assigned to the dev EC2 instance and the likewise for prod.

Create the first EC2 instance with IAM Role EC2ProdServiceRole. Create the second EC2 instance with IAM Role EC2DevServiceRole. Make sure you assign a security group that allows you to ssh onto the instances.

STEP 6: Access parameters

First ssh onto the Prod server.

Run the following command to get the String type parameter:

Syntax:

aws ssm get-parameter --name "<PARAM NAME>" --region <REGION ID>

Example:

aws ssm get-parameter --name "/prod/dbuser" --region us-east-1
{
    "Parameter": {
        "Type": "String", 
        "Name": "/prod/dbuser", 
        "Value": "idmgruserSDF687"
    }
}

Run the following command to get the decrypted Secure String type parameter:

Syntax:

aws ssm get-parameter --name "<PARAM NAME" --region <REGION ID> --with-decryption

Example:

aws ssm get-parameter --name "/prod/dbpwd" --region us-east-1 --with-decryption
{
    "Parameter": {
        "Type": "SecureString", 
        "Name": "/prod/dbpwd", 
        "Value": "passwordasdnbu6f$^&T&UVG"
    }
}

Note: if you try to run the commands to get the prod parameters you will get an Access Denied error message. This is because the EC2 attached IAM role only gives access to the dev hierarchy parameters.

aws ssm get-parameter --name "/dev/dbpwd" --region us-east-1 --with-decryption

An error occurred (AccessDeniedException) when calling the GetParameter operation: User: arn:aws:sts::5XXXXXXXXXX6:assumed-role/EC2ServiceUseRole/i-0fc59e259b559b5ac is not authorized to perform: ssm:GetParameter on resource: arn:aws:ssm:us-east-1:5XXXXXXXXXX6:parameter/dev/dbpwd

Try the same commands on the dev instance and you will notice that the dev parameters are accessible and the prod parameters are not.

STEP 07: Check parameter history (Auditing)

To check what changes have been made to a parameter you can navigate to the parameter and notice the tab that says “History”. This shows who and when parameter details were changed.

Figure 06: Parameter auditing

———–

Accessing parameters can also be done within ECS Containers and Lambda functions. The main take away is that parameters and CMKs can be controlled using IAM roles. These roles can be assumed by EC2 and other services. Hopefully the above guide will give you some idea on how you can manage secrets and parameters within you AWS environment.


Continue reading...

Everything you missed at DevDay
Natalie Byrgiotis
October 30, 2018
Chameleon SMS
Ibrahim Tareq
October 29, 2018
MessageMedia x Auth0
Ibrahim Tareq
October 25, 2018