In most enterprise systems where software release cycles consist of separate environments like dev, stage, live, having multiple environments that can be dynamically configured is common. An application may have three different sets of database credentials for authentication. Each set of credentials would be respective to an instance for a particular environment. This approach essentially allows software developers to interact with a developer-friendly database when carrying out their day-to-day coding.
Kubernetes secrets is used to store very sensitive data in your Kubernetes cluster. Secrets are native Kubernetes resources saved in the cluster data store (i.e., etcd database) and can be made available to your containers at runtime. Managing these secrets is a challenging process so in this guide we will explore how to use External Secrets to simplify that.
Kubernetes External Secrets allows you to use external secret management systems like GCP Secrets manager, AWS Secrets Manager or HashiCorp Vault, to securely add secrets in Kubernetes.
An ExternalSecret
declares how to fetch the secret data, while the controller converts all ExternalSecrets
to Secrets
. The conversion is completely transparent to Pods
that can access Secrets
normally. By default Secrets
are not encrypted at rest and are open to attack, either via the etcd
server or via backups of etcd
data. To mitigate this risk, use an external secret management system with a KMS plugin to encrypt Secrets
stored in etcd
.
This is the workflow of how the External Secrets work:
ExternalSecrets
are added in the cluster (e.g.kubectl apply -f external-secret-example.yml
)- Controller fetches
ExternalSecrets
using the Kubernetes API - Controller uses
ExternalSecrets
to fetch secret data from external providers (e.g, AWS Secrets Manager) - Controller upserts
Secrets
Pods
can accessSecrets
normally
Checkout related content:
- How to use External Secrets with GCP Secrets manager
- How to create and manage Secrets in GCP Secret Manager using Terraform
Configuring AWS Access
We first starting by creating a policy named secrets-reader
:
|
|
We now create a group that will use this policy:
|
|
Next, we create an username and attach it to the recently created-group:
|
|
Finally, we create a set of credentials for that user, and add it as a secret in kubernetes:
|
|
Now, let’s add some secrets in our secret Store!
|
|
Installing External Secrets
External secrets is available officially as a helm chart in this repo. To add the repo and install it as external-secrets
in our cluster, use this:
|
|
You can also install it with kubectl
if you don’t want to use helm in your cluster by generating the manifests then applying:
|
|
The generated kubernetes manifests will be in ./output_dir
and can be applied to deploy kubernetes-external-secrets
to the cluster.
Deploy a Secret Store
The first thing we need to do is define a SecretStore
. A Secret Store is a namespaced resource that determines how your external Secret will be accessed from an authentication perspective. This resource is where all backend-related configuration is going to be stored, to allow external-secrets to reach out to Secrets-Manager.
It contains references to Secrets that have the credentials to access the external API. External Secrets also has a ClusterSecretStore which is a global or cluster-wide SecretStore that can be referenced from all namespaces to provide a central gateway to your secrets manager. In our case we will use a SecretStore.
Let us create a Secret store called aws-secret-manager
that will use the earlier defined secret aws-secret
.
|
|
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in accessKeyIDSecretRef
and secretAccessKeySecretRef
with the namespaces where the secrets reside.
|
|
We can confirm the secret store creation with this command:
|
|
Creating External Secrets
An ExternalSecret is a resource that declares the data you want to fetch from the external secrets manager. It will reference the SecretStore to know how to access sensitive data.
Let us create an external secret for our db secret. Here we are accessing the secret sm-citizix-db-secret
and creating a target citizix-db-secret
secret in kubernetes with a key db-url
:
|
|
We can confirm that the defined external secret is working as expected:
|
|
We can also check that it has created the respective kubernetes secret:
|
|
To confirm the content of the created secret, describe the secret:
|
|
Extracting json values
We can extract json key values as secret data. External secret provides the dataFrom attribute that does just that:
|
|
We can confirm that the defined external secret is working as expected:
|
|
We can also check that it has created the respective kubernetes secret:
|
|
To confirm the content of the created secret, describe the secret:
|
|
Conclusion
In this guide, we learnt what External Secrets are and how we can leverage them to populate our kubernetes secrets from AWS secret manager.