How can I update a secret on Kubernetes when it is generated from a file?

8/25/2017

I've created a secret using kubectl create secret generic production-tls --from-file=./tls.key --from-file=./tls.crt.

If I'd like to update the values - how can I do this?

-- Chris Stryczynski
kubectl
kubernetes

5 Answers

11/4/2019

For more specific cases you might need to specify your namespace that the cert need to be renewed and delete the old one.

**For deletion of the cert **
kubectl delete secret -n `namespace`

**For creation of new cert to specific namespace **
kubectl create secret {your-cert-name} --key /etc/certs/{name}.com.key --cert /etc/certs/{name}.com.crt -n {namespace} ```
-- JohnBegood
Source: StackOverflow

8/25/2017

This should work:

kubectl create secret generic production-tls \
    --from-file=./tls.key --from-file=./tls.crt --dry-run -o yaml | 
  kubectl apply -f -
-- Janos Lenart
Source: StackOverflow

8/25/2017

You can delete and immediately recreate the secret:

kubectl delete secret production-tls
kubectl create secret generic production-tls --from-file=./tls.key --from-file=./tls.crt

I put these commands in a script, on the first call you get a warning about the (not yet) existent secret, but this works.

-- P.J.Meisch
Source: StackOverflow

11/16/2018

Alternatively, you can also use jq's = or |= operator to update secrets on the fly.

TLS_KEY=$(base64 < "./tls.key" | tr -d '\n')
TLS_CRT=$(base64 < "./tls.crt" | tr -d '\n')
kubectl get secrets production-tls -o json \
        | jq '.data["tls.key"] |= "$TLS_KEY"' \
        | jq '.data["tls.crt"] |= "$TLS_CRT"' \
        | kubectl apply -f -

Although it might not be as elegant or simple as the kubectl create secret generic --dry-run approach, technically, this approach is truly updating values rather than deleting/recreating them. You'll also need jq and base64 (or openssl enc -base64) commands available, tr is a commonly-available Linux utility for trimming trailing newlines.

See here for more details about jq update operator |=.

-- Devy
Source: StackOverflow

2/21/2020

As I wasn't able to reply to Devy's answer above, which I like because it will preserve Ownership where deleting and recreating has the potential to lose any extra information in the record. I'm adding this for the newer people who may not immediately understand whey their variables aren't being interpolated.

TLS_KEY=$(base64 < "./tls.key" | tr -d '\n')
TLS_CRT=$(base64 < "./tls.crt" | tr -d '\n')
kubectl get secrets production-tls -o json \
        | jq ".data[\"tls.key\"] |= \"$TLS_KEY\"" \
        | jq ".data[\"tls.crt\"] |= \"$TLS_CRT\"" \
        | kubectl apply -f -

This lead me to attempting to use the 'patch' method of kubectl, which also seems to work.

kubectl \
        patch \
        secret \
        production-tls \
        -p "{\"data\":{\"tls.key\":\"${TLS_KEY}\",\"tls.crt\":\"${TLS_CRT}\"}}"

Thanks Devy for the answer that best met my needs.

-- CJ Maahs
Source: StackOverflow