Kubernetes secret management using the External Secrets Operator-EKS

A wonderful serenity has taken possession of my entire soul.

Kubernetes secret management using the External Secrets Operator-EKS

In this blog post, I am going to examine the External Secrets Operator and demonstrate how to store your secrets externally on the AWS Secrets Manager.

Kubernetes includes native capabilities for managing secrets in the form of Kubernetes Secrets to satisfy the requirement of safely delivering secrets to running applications. To improve security, administration, and the ability to track how secrets are used, centralized secret management can be carried out outside of Kubernetes clusters using an external secret store such as Hashicorp Vault, AWS Secrets Manager, etc. One way to store secrets outside the K8s cluster is with the help of the External Secrets Operator open-source project. 

What Is the Function of the External Secrets Operator?

The External Secrets Operator's objective is to synchronize secrets from external APIs with Kubernetes. The ESO manages secrets via Custom Resource Definitions. ExternalSecret, SecretStore, and ClusterSecretStore are user-friendly wrappers around the external API that store and manage secrets on your behalf.

Your secrets are managed by the "ExternalSecret" CRD and the controller uses ExternalSecret’s data to create secrets. When you use External Secrets to read secrets from an external secret store, the data is stored in the Kubernetes control plane as native Kubernetes Secrets. 

SecretStore and ExternalSecret CRDs are important to understand this demo and how ESO works.

SecretStore CRD is used for the authentication and access management of the external secret store.

ExternalSecret CRD is used for the specific secret that is going to be pulled. The controller uses ExternalSecret’s data to create secrets and sync them at a time interval you choose.



Let's Practice a Little Bit

This tutorial will show you how to sync a secret from the AWS Secrets Manager to your EKS cluster using the External Secrets Operator.

To properly follow this tutorial, make sure you have installed the following tools:


pasted image 0-2

Creating an EKS Cluster

If you already have an EKS Cluster, you can skip this step. I am going to deploy my own EKS Cluster using eksctl, which is a simple CLI tool for creating and managing EKS Clusters.

The following commands will create my EKS Cluster.


eksctl create cluster -f cluster-config.yaml

The code example below provides an overview of the cluster-config.yaml file.

kind: ClusterConfig

  name: eso-test-cluster
  region: eu-central-1

  - name: ng-1
    instanceType: t3.medium
    desiredCapacity: 2
    volumeSize: 20
      allow: true

Use the following command to get kube-config.

aws eks update-kubeconfig --name=eso-test-cluster --region=eu-central-1

After these steps are complete, run the following command to verify.

kubectl get nodes

NAME                                              STATUS   ROLES    AGE     VERSION   Ready    <none>   3m31s   v1.22.12-eks-ba74326    Ready    <none>   3m31s   v1.22.12-eks-ba74326


As there are no errors, the EKS Cluster is ready for usage.


Installing the External Secrets Operator

The External Secrets Operator offers Helm Charts for deployment convenience, and I am going to use Helm for deploying the External Secrets Operator.


The following commands will deploy an External Secrets Operator to my EKS Cluster.


helm repo add external-secrets

helm install external-secrets \
   external-secrets/external-secrets \
   -n external-secrets \
   --create-namespace \
   --set installCRDs=true \
   --set webhook.port=9443 

After the `external-secrets has been deployed successfully!` message, run the following command to verify external secret operator resources.


kubectl get pods -n external-secrets

Expected Output:


NAME                                                READY   STATUS    RESTARTS   AGE
external-secrets-7886b578b4-k27m4                   1/1     Running   0          2m32s
external-secrets-cert-controller-5578bf565f-nxhs7   1/1     Running   0          2m32s
external-secrets-webhook-84c7d457f4-r6cp6           1/1     Running   0          2m32s

IAM Roles For Service Accounts (IRSA)

For the external-secrets operator to be able to get secrets from the AWS Secrets Manager, I have to set a few configurations. You can manage the credentials for your applications with EKS's feature IRSA. This is similar to how Amazon EC2 instance profiles give credentials for Amazon EC2 instances. Instead of distributing AWS credentials or using the Amazon EC2 role, you can map an IAM role to a Kubernetes service account and set up your pods to use this service account. To use IRSA, it is mandatory to create an IAM OIDC Provider for the EKS cluster.


The following command will create an OIDC provider and associate it with my cluster.


$ eksctl utils associate-iam-oidc-provider --cluster=eso-test-cluster --approve --region eu-central-1


I am going to use eksctl to create a service account. The following command 'eksctl create iamserviceaccount' takes an IAM policy arn as an argument, creates an IAM role associated with the given policy, and maps a service account to that role.


eksctl create iamserviceaccount \
    --name esoblogsa \
    --namespace default \
    --cluster  \
    --role-name "esoBlogRole" \
    --attach-policy-arn <polıcy_arn> \
    --approve \


I have already created my secret in the AWS Secrets Manager and an IAM policy that lets it be retrieved and decrypted. The following image shows a secret with the name test/eso/testSecret.




    "Version": "2012-10-17",
    "Statement": [
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [

After these steps are completed, run the following command to verify the service account. 

$ kubectl describe sa esoblogsa

Name:                esoblogsa
Namespace:           default
Annotations: arn:aws:iam::<account_number>:role/esoBlogRole
Image pull secrets:  <none>
Mountable secrets:   esoblogsa-token-9l2zj
Tokens:              esoblogsa-token-9l2zj
Events:              <none>


Sync External Secrets to the AWS Secrets Manager Secret


I am going to create a SecretStore that references AWS Secrets Manager with a service account that I have already created, 'esoblogsa'. Run the following command to create the SecretStore.

cat <<EOF | kubectl apply -f -
kind: SecretStore
  name: eso-blog-secret-store
      service: SecretsManager
      region: eu-central-1
            name: esoblogsa

Run the following command to create an ExternalSecret. The Controller is going to create a secret with the name of "".

cat <<EOF | kubectl apply -f -
kind: ExternalSecret
  name: blogdemo
  refreshInterval: 1h
    name: eso-blog-secret-store
    kind: SecretStore
    name: esoblogsecret
    creationPolicy: Owner
  - secretKey: esoblog-test-password
      key: test/eso/testSecret #AWS secret name
      property: password #AWS secret key

Run the following command to verify the Kubernetes secret.

kubectl describe secret esoblogsecret

Name:         esoblogsecret
Namespace:    default
Annotations: 2ffa008bbbf55886723ea27d84ed84c4

Type:  Opaque

esoblog-test-password:  12 bytes


My ExternalSecret is synced to the secret stored in AWS Secrets Manager. The controller has already created the Kubernetes Secret and I can use that secret similar to how I use kubernetes secrets regularly. 


Don’t forget to destroy your resources after all of these steps. Run the following commands to destroy your resources.


kubectl delete
kubectl delete secretstore eso-blog-secret-store
eksctl delete iamserviceaccount \
    --name  \
    --namespace default \
helm uninstall external-secrets -n external-secrets

#If you didn't use eksctl, you can pass this line.
eksctl delete cluster --name  --region 

Alternative solution

AWS Secrets Manager and Config Provider for Secret Store CSI Driver (ASCP) :Secrets from AWS Secrets Manager are exposed to your pods as a mounted storage volume via ASCP using the Secrets Store CSI driver. The CSI Secret Store driver runs as a DaemonSet and DaemonSets are not supported on Fargate.


The External Secrets Operator is a useful tool if you want to utilize your external secrets in your K8s cluster. Rather than other solutions, ESO is compatible with a wide range of cloud secret store services such as AWS Secrets Manager, GCP Secret Manager, Azure Key Vault, etc., and for the EKS perspective, it is compatible with Fargate nodes too, which is not possible with ASCP.


>> Learn How to Run Amazon EKS Without an AWS Account

Cem Altuner

Cem is a cloud engineer at Kloia. He has studied Amazon Web Services and Kubernetes projects. He is also experimenting with serverless computing.