Getting Started with External Secrets Operator on Kubernetes using AWS Secrets Manager

Posted on May 16, 2022

Introduction

Kubernetes has a built-in feature for secrets management called a Secret. The Secret object is convenient to use but does not support storing or retrieving secret data from external secret management systems such as AWS Secrets Manager.

It’s often beneficial to use Kubernetes with an external secrets service that handles secret management. Due to this limitation, GoDaddy came up with an open-source solution called External Secrets Operator.

External Secrets Operator (ESO in short)

ESO provides the same ease of use as native Secret object and provides access to secrets stored externally. It does this by extending Kubernetes with Custom Resources, which define where secrets live and how to synchronize them.

In simple terms, ESO makes API calls to retrieve secret data from the external secrets service like AWS Secrets Manager and injects the secret data as Kubernetes Secrets object.

Key Concepts:


Integrating AWS Secrets Manager with Kubernetes

Install External Secrets Operator using Helm

TL;DR
helm repo add external-secrets https://charts.external-secrets.io
helm repo update

Install ESO in external-secrets namespace
helm upgrade --namespace external-secrets --create-namespace --install --wait external-secrets external-secrets/external-secrets

Verify ESO installation
kubectl -n external-secrets get all
Fig: Deployed resources: External secrets controller + CRDs, webhook + service and a cert controller.

Create an IAM user and attach the managed policy

aws iam create-user --user-name external-secrets

aws iam attach-user-policy --user-name external-secrets --policy-arn arn:aws:iam::aws:policy/SecretsManagerReadWrite

aws iam create-access-key --user-name external-secrets

echo -n "REPLACE_ME_WITH_YOUR_ACCESS_KEY" > access-key
echo -n "REPLACE_ME_WITH_YOUR_SECRET_KEY" > secret-access-key
kubectl create secret generic awssm-secret --from-file=./access-key --from-file=./secret-access-key

Create app secret in AWS Secret Manager

aws secretsmanager create-secret --name app-secret --secret-string '{"username":"bob","password":"abc123xyz456"}' --region us-east-1

And verify the secret from the AWS Secrets Manager console.

Create a cluster-scoped secret store

As mentioned before, a cluster-scoped secret store allows referencing the secret store from any namespaces, which is convenient to use as a central gateway to the secret provider, rather than creating a secret store per namespace.

cat > cluster-secret-store.yaml <<EOF
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
  name: global-secret-store
spec:
  provider:
    aws:
      service: SecretsManager
      region: us-east-1
      auth:
        secretRef:
          accessKeyIDSecretRef:
            name: awssm-secret
            key: access-key
            namespace: default
          secretAccessKeySecretRef:
            name: awssm-secret
            key: secret-access-key
            namespace: default
EOF

kubectl apply -f cluster-secret-store.yaml

kubectl describe clustersecretstore global-secret-store

Create ExternalSecret to fetch the secret data

kubectl create namespace app

cat > app-secret.yaml <<EOF
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: app-secret
spec:
  refreshInterval: 1m
  secretStoreRef:
    name: global-secret-store
    kind: ClusterSecretStore
  target:
    name: app-secret
    creationPolicy: Owner
  dataFrom:
  - extract:
      key: app-secret
EOF

kubectl -n app apply -f app-secret.yaml

kubectl -n app get externalsecret
kubectl -n app get secret app-secret

What just happened?

Consume the secret from the Pod

cat > app-pod.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
    - name: app
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      envFrom:
      - secretRef:
          name: app-secret
EOF

kubectl -n app apply -f app-pod.yaml

kubectl -n app logs app-pod | egrep 'username|password'

🎉 Congratulations on successfully integrating AWS Secrets Manger on Kubernetes using External Secrets Operator.

Summary

Kubernetes External Secrets is a mature and popular project with great community engagement. It is well-tested and stable for production workload with high-availability features for managing and synchronizing large-scale secrets and supports many popular external secrets providers like HashiCorp VaultGoogle Secrets ManagerAzure Key Vault, and many more.

Does Kubernetes and Cloud-native technologies excites you? Come join us!

Keep Reading

Take Advantage of the Cloud

Schedule a Call