AWS Parameter Store

Parameter Store
A ParameterStore points to AWS SSM Parameter Store in a certain account within a
defined region. You should define Roles that define fine-grained access to
individual secrets and pass them to ESO using spec.provider.aws.role. This
way users of the SecretStore can only access the secrets necessary.
apiVersion: external-secrets.io/v1
kind: SecretStore
metadata:
name: parameterstore
spec:
provider:
aws:
service: ParameterStore
# define a specific role to limit access
# to certain secrets
role: arn:aws:iam::123456789012:role/external-secrets
region: eu-central-1
auth:
secretRef:
accessKeyIDSecretRef:
name: awssm-secret
key: access-key
secretAccessKeySecretRef:
name: awssm-secret
key: secret-access-key
NOTE: In case of a ClusterSecretStore, Be sure to provide namespace in accessKeyIDSecretRef and secretAccessKeySecretRef with the namespaces where the secrets reside.
API Pricing & Throttling
The SSM Parameter Store API is charged by throughput and is available in different tiers, see pricing. Please estimate your costs before using ESO. Cost depends on the RefreshInterval of your ExternalSecrets.
IAM Policy
Fetching Parameters
The example policy below shows the minimum required permissions for fetching SSM parameters. This policy permits pinning down access to secrets with a path matching dev-*. Other operations may require additional permission. For example, finding parameters based on tags will also require ssm:DescribeParameters and tag:GetResources permission with "Resource": "*". Generally, the specific permission required will be logged as an error if an operation fails.
For further information see AWS Documentation.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:GetParameter*",
],
"Resource": "arn:aws:ssm:us-east-2:1234567889911:parameter/dev-*"
}
]
}
Pushing Parameters
The example policy below shows the minimum required permissions for pushing SSM parameters. Like with the fetching policy it restricts the path in which it can push secrets too.
{
"Action": [
"ssm:GetParameter*",
"ssm:PutParameter*",
"ssm:AddTagsToResource",
"ssm:ListTagsForResource"
],
"Effect": "Allow",
"Resource": "arn:aws:ssm:us-east-2:1234567889911:parameter/dev-*"
}
JSON Secret Values
You can store JSON objects in a parameter. You can access nested values or arrays using gjson syntax:
Consider the following JSON object that is stored in the Parameter Store key friendslist:
{
"name": {"first": "Tom", "last": "Anderson"},
"friends": [
{"first": "Dale", "last": "Murphy"},
{"first": "Roger", "last": "Craig"},
{"first": "Jane", "last": "Murphy"}
]
}
This is an example on how you would look up nested keys in the above json object:
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: extract-data
spec:
# [omitted for brevity]
data:
- secretKey: my_name
remoteRef:
key: friendslist
property: name.first # Tom
- secretKey: first_friend
remoteRef:
key: friendslist
property: friends.1.first # Roger
# metadataPolicy to fetch all the tags in JSON format
- secretKey: tags
remoteRef:
metadataPolicy: Fetch
key: database-credentials
# metadataPolicy to fetch a specific tag (dev) from the source secret
- secretKey: developer
remoteRef:
metadataPolicy: Fetch
key: database-credentials
property: dev
Parameter Versions
ParameterStore creates a new version of a parameter every time it is updated with a new value. The parameter can be referenced via the version property
SetSecret
The SetSecret method for the Parameter Store allows the user to set the value stored within the Kubernetes cluster to the remote AWS Parameter Store.
Creating a Push Secret
---
# The source secret that will be pushed to the destination secret by PushSecret.
apiVersion: v1
kind: Secret
metadata:
name: pushsecret-example
stringData:
best-pokemon-src: "Pikachu"
---
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
name: pushsecret-example # Customisable
namespace: default # Same of the SecretStores
spec:
updatePolicy: Replace # Policy to overwrite existing secrets in the provider on sync
deletionPolicy: Delete # the provider' secret will be deleted if the PushSecret is deleted
refreshInterval: 1h0m0s # Refresh interval for which push secret will reconcile
secretStoreRefs: # A list of secret stores to push secrets to
- name: aws-parameterstore
kind: SecretStore
selector:
secret:
name: pokedex-credentials # Source Kubernetes secret to be pushed
# Alternatively, you can point to a generator that produces values to be pushed
generatorRef:
apiVersion: generators.external-secrets.io/v1alpha1
kind: ECRAuthorizationToken
name: prod-registry-credentials
template:
metadata:
annotations: { }
labels: { }
data:
# If the key source secret key has dashes, then it cannot be accessed directly,
# and the "index" function should be used.
best-pokemon: "{{ index . \"best-pokemon-src\" | toString | upper }} is the really best!"
# Also, it's possible to use an existing template from configmap where Secret is fetched,
# merged and templated within the referenced configMap data.
# It does not update the configmap, it creates a secret with: data["config.yml"] = ...result...
templateFrom:
- configMap:
name: application-config-tmpl
items:
- key: config.yml
data:
- conversionStrategy: None # Also supports the ReverseUnicode strategy
match:
# The secretKey is used within PushSecret (it should match key under spec.template.data)
secretKey: best-pokemon
remoteRef:
remoteKey: destination-secret # The destination secret object name (where the secret is going to be pushed)
property: best-pokemon-dst # The key within the destination secret object.
Additional Metadata for PushSecret
Optionally, it is possible to configure additional options for the parameter. These are as follows: - type - keyID - tier & policies - encodeAsDecoded
To control this behaviour you can set the following provider's metadata:
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
name: pushsecret-example # Customisable
namespace: default # Same of the SecretStores
spec:
deletionPolicy: Delete # the provider' secret will be deleted if the PushSecret is deleted
refreshInterval: 1h0m0s # Refresh interval for which push secret will reconcile
secretStoreRefs: # A list of secret stores to push secrets to
- name: aws-parameterstore
kind: SecretStore
selector:
secret:
name: pokedex-credentials # Source Kubernetes secret to be pushed
data:
- match:
remoteRef:
remoteKey: my-first-parameter # Remote reference (where the secret is going to be pushed)
metadata:
apiVersion: kubernetes.external-secrets.io/v1alpha1
kind: PushSecretMetadata
spec:
description: "This is a secret for the API credentials"
secretType: SecureString
kmsKeyID: bb123123-b2b0-4f60-ac3a-44a13f0e6b6c
tier:
type: Advanced # default is Standard
policies:
- type: "Expiration"
version: "1.0"
attributes:
timestamp: "2024-12-02T21:34:33.000Z"
- type: "ExpirationNotification"
version: "1.0"
attributes:
before: "2"
unit: "Days"
- type: "ExpirationNotification"
version: "1.0"
attributes:
before: "30"
unit: "Days"
- type: "NoChangeNotification"
version: "1.0"
attributes:
after: "30"
unit: "Days"
tags:
environment: sandbox
team: pokedex
secret-store: aws-parameterstore
refresh-interval: 1h
secretTypetakes three options.String,StringList, andSecureString, whereStringis the defaultkmsKeyIDtakes a KMS Key$IDor$ARN(in case a key source is created in another account) as a string, wherealias/aws/ssmis the default. This property is only used ifsecretTypeis set asSecureString.- tier & policies contains advanced policy configs such as
ExpirationNotification. - encodeAsDecoded if set to true will get the secrets and push them as plain values when pushing the entire secret (instead of encoding them) instead of base64 encoding the []byte values from the secret.
Check successful secret sync
To be able to check that the secret has been successfully synced you can run the following command:
kubectl get pushsecret pushsecret-example
If the secret has synced successfully it will show the status as "Synced".
Test new secret using AWS CLI
To View your parameter on AWS Parameter Store using the AWS CLI, install and login to the AWS CLI using the following guide: AWS CLI.
Run the following commands to get your synchronized parameter from AWS Parameter Store:
aws ssm get-parameter --name=my-first-parameter --region=us-east-1
You should see something similar to the following output:
{
"Parameter": {
"Name": "my-first-parameter",
"Type": "String",
"Value": "charmander",
"Version": 4,
"LastModifiedDate": "2022-09-15T13:04:31.098000-03:00",
"ARN": "arn:aws:ssm:us-east-1:1234567890123:parameter/my-first-parameter",
"DataType": "text"
}
}