Skip to content

Instantly share code, notes, and snippets.

@hpurmann
Last active June 10, 2019 15:22
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save hpurmann/fa5bcfc5c3ac392cf8ef6a4d9a7f48b6 to your computer and use it in GitHub Desktop.
Update all sealed secrets by manually converting the `data` value to base64 before running `kubeseal`
apiVersion: v1
kind: Secret
metadata:
name: mysecret
namespace: production
type: Opaque
data:
config.yml: |
database:
username: {{ vault "secret/database" "username" }}
password: {{ vault "secret/database" "password" }}
#!/bin/bash
set -e
# Check precondition for script execution
if [[ ! $(command -v kubeseal) ]]; then
>&2 echo "Error: kubeseal is not installed"
exit 1
fi
export OWN_PATH="${0%/*}"
export SCRIPT_BASE64_SECRET_FILE="${OWN_PATH}/base64-secret-data.sh" # content of this file is https://github.com/actano/transform-yaml/blob/a6e8965220c86f5dbcf256615ed9391b34f6c252/example/run.sh
DEFAULT_PATHS="${OWN_PATH}/paths.txt"
# Either use the provided paths arguments or the default path file
if [[ -z "$1" ]]
then
SECRET_PATHS="${OWN_PATH}/../helm"
echo "No paths supplied, using the default paths '${SECRET_PATHS}'"
else
SECRET_PATHS="$@"
fi
function render_template() {
# Vault settings
VAULT_ADDR="https://vault.yourcompany.com"
VAULT_TOKEN_PATH="${HOME}/.vault-token"
local TEMPLATE_FILE=$1
local BASENAME_TEMPLATE_FILE=$(basename ${TEMPLATE_FILE})
local DIRNAME_TEMPLATE_FILE=$(dirname ${TEMPLATE_FILE})
local NAME="${BASENAME_TEMPLATE_FILE%.template.yaml}"
# Path of the rendered secret, ignored in git
SECRET_BASEPATH="tmp_secret"
SECRET_PATH="${SECRET_BASEPATH}/${NAME}.yaml"
SECRET_TMP_PATH="${SECRET_BASEPATH}/${NAME}_tmp.yaml"
# Remove tmp secret folder after script execution
trap 'rm -r ${SECRET_BASEPATH}' EXIT
# Render secret template
docker run --rm \
-v ${VAULT_TOKEN_PATH}:/root/token \
-v $(pwd)/${TEMPLATE_FILE}:/root/secret.template.yaml \
-v $(pwd)/${SECRET_BASEPATH}:/root/${SECRET_BASEPATH} \
rplan/vault-template:1.0.1 \
--vault ${VAULT_ADDR} \
--vault-token-file /root/token \
--template /root/secret.template.yaml \
--output /root/${SECRET_PATH}
# Base64 convert values in data
# kubeseal doesn't support `stringData`, so we have to convert to base64 beforehand
docker run --rm \
-v $(pwd)/${SECRET_PATH}:/data/secret.yaml \
-v $(pwd)/${SCRIPT_BASE64_SECRET_FILE}:/data/run.sh \
rplan/transform-yaml \
> ${SECRET_TMP_PATH}
# Encrypt secret file with kubeseal
cat "${SECRET_TMP_PATH}" | kubeseal --controller-namespace sealed-secrets \
--cert ${OWN_PATH}/mycert.pem \
--format yaml \
> ${DIRNAME_TEMPLATE_FILE}/../templates/${NAME}.sealed.yaml
echo "Sealed secret written to ${DIRNAME_TEMPLATE_FILE}/../templates/${NAME}.sealed.yaml"
}
function update_sealed_secrets_in_path() {
local SECRET_PATH=$1
# Template files to read vault secret paths from
export -f render_template
find ${SECRET_PATH} -name "*.template.yaml" -exec bash -c 'render_template "$0"' {} \;
}
# Update sealed secrets for each path
for SECRET_PATH in ${SECRET_PATHS}
do
update_sealed_secrets_in_path ${SECRET_PATH}
done
@hpurmann
Copy link
Author

hpurmann commented Mar 4, 2019

The script requires kubeseal as a local binary available in your PATH. It expects a path as first argument and uses that to recursively search for *.template.yaml files which contain the secret template. See the secret.template.yaml for an example of this.

Secret templates are living in directories on the same level as the templates directory of the helm charts. The script will take the template and render it into templates, preserving the <secret-name> as a file prefix.

folder
├── secret-templates
│   └── <secret-name>.template.yaml
└── templates
    └── <secret-name>.sealed.yaml

@Renz2018
Copy link

Renz2018 commented Mar 6, 2019

Thanks a lot!!!

@hpurmann
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment