How to Sync a Kubernetes Secret to AWS Secrets Manager
A Kubernetes Secret is only base64-encoded in etcd - not versioned, rotated, or audited. This project walks you through copying a Secret value (the password s3cr3t-pw) into AWS Secrets Manager as prod/db/password so the credential has a managed home outside the cluster. Here's how to do it with kubectl and the AWS CLI.
Why copy a k8s Secret into Secrets Manager
A Kubernetes Secret is not encrypted by default - it is base64-encoded data sitting in etcd. Anyone who can read the Secret can decode it, and there is no built-in versioning, rotation, or audit trail. AWS Secrets Manager adds all three: automatic rotation, access logging through CloudTrail, and a single source of truth that services outside the cluster can read.
A common migration and sync task is to take a credential that already lives
in a k8s Secret and give it a managed home in Secrets Manager, keeping the
two values identical. This project does exactly that with one credential -
the database password s3cr3t-pw.
Step 1 - create (or read) the Kubernetes Secret
Create the Secret with kubectl from a literal value:
kubectl create secret generic db-creds \
--from-literal=password=s3cr3t-pw
If the Secret already exists, decode the value so you know exactly what you
are about to store. The value in .data.password is base64-encoded, so pipe
it through base64 -d:
kubectl get secret db-creds -o jsonpath='{.data.password}' | base64 -d
That prints s3cr3t-pw. An empty result means the Secret does not exist yet.
Step 2 - store the same value in AWS Secrets Manager
First confirm the AWS CLI resolves credentials:
aws sts get-caller-identity
Then create the secret in Secrets Manager under the name prod/db/password,
passing the decoded value as the secret string:
aws secretsmanager create-secret \
--name prod/db/password \
--secret-string s3cr3t-pw
create-secret fails if the secret name already exists. To make the sync
re-runnable, fall back to put-secret-value, which writes a new version of
an existing secret:
aws secretsmanager create-secret --name prod/db/password --secret-string s3cr3t-pw \
|| aws secretsmanager put-secret-value --secret-id prod/db/password --secret-string s3cr3t-pw
This is the idempotent pattern - the first run creates the secret, and every later run updates it in place instead of erroring out.
Step 3 - verify both values match
Read the value back out of Secrets Manager and confirm it equals the k8s
Secret. The --query SecretString --output text flags strip the JSON
envelope so you get the raw value:
aws secretsmanager get-secret-value \
--secret-id prod/db/password \
--query SecretString --output text
You should see s3cr3t-pw - the same value the k8s Secret decodes to. To
list what already exists on either side while you work:
kubectl get secrets
aws secretsmanager list-secrets
With both stores holding the identical value, the credential now has a managed source of truth. In production, an external-secrets operator automates the reverse direction - pulling from Secrets Manager back into k8s Secrets - so applications keep reading a native Secret while Secrets Manager owns rotation.
Want to try it hands-on? HeyDevJob gives you this exact setup in a live cloud workspace in your browser - edit it, run it, and see it work. Free, nothing to install.
Try it in a workspace →What you'll practice
- Decoding a Kubernetes Secret value with kubectl get secret -o jsonpath and base64 -d
- Creating and updating a secret in AWS Secrets Manager with create-secret and put-secret-value
- Reading a value back with get-secret-value --query SecretString --output text to verify a sync
FAQ
How do I store a Kubernetes Secret value in AWS Secrets Manager?
Decode the k8s Secret with kubectl get secret db-creds -o jsonpath='{.data.password}' | base64 -d, then pass that value to aws secretsmanager create-secret --name prod/db/password --secret-string <value>. Read it back with get-secret-value to confirm both stores match.
What is the difference between create-secret and put-secret-value in AWS Secrets Manager?
create-secret creates a brand-new secret and fails if the name already exists. put-secret-value writes a new version of a secret that already exists. Chain create-secret with a put-secret-value fallback to make a sync script safe to re-run.
Why move a credential out of a Kubernetes Secret?
Kubernetes Secrets are only base64-encoded in etcd, with no built-in versioning, rotation, or audit trail. AWS Secrets Manager adds automatic rotation, CloudTrail access logging, and a single source of truth that services outside the cluster can read.
How do I read a value back from AWS Secrets Manager on the command line?
Run aws secretsmanager get-secret-value --secret-id prod/db/password --query SecretString --output text. The query and output flags strip the JSON envelope so you get the raw credential string, which you can compare directly against the decoded k8s Secret.
Keep learning
Learn it by doing. Open this in a live cloud workspace, make the change yourself, and keep a record of the work you can share.
Open the workspace →