Skip to content

Instantly share code, notes, and snippets.

@asc-adean
Last active June 21, 2019 15:31
Show Gist options
  • Save asc-adean/750186735851406f24fbd64a37641cc9 to your computer and use it in GitHub Desktop.
Save asc-adean/750186735851406f24fbd64a37641cc9 to your computer and use it in GitHub Desktop.
Grabs all secrets from Azure Key Vault for a Kubernetes secret yaml creation
from azure.keyvault import KeyVaultClient
from azure.common.credentials import ServicePrincipalCredentials
import re
import argparse
import json
import yaml # use pyyaml please
import base64
# Ensure the account you are pulling these secrets as has at *least* Read permissions on the Key Vault (check IAM)
# Azure has naming requirements that do not allow underscores, so we will convert dashes/spaces to underscores
# Store the secret value as-is, do NOT convert it to base64 first (unless the value in the Pod is expected to be base64, then we
# need to double-base64, so store it as such, such as an HTTP Auth Header)
# An example command line usage looks like this:
# python .\secrets.py \
# --vaultid 'https://your-vault-name.vault.azure.net' \
# --clientid 'f8127076-ab03-4b45-ac67-c084ddaa247d' \
# --clientsecret 'XXXXXXXXXXXXX' \
# --tenantid '670b3689-739b-43b3-8390-436ef938e19b' \
# --secretfile kubernetes_secrets
parser = argparse.ArgumentParser(description='Process Azure Credentials')
parser.add_argument('--vaultid', metavar='vaultid',
help='The name of the vault, e.g. "your-vault-name" if your vault is reached at "https://your-vault-name.vault.azure.net"', required=True)
parser.add_argument('--clientid', metavar='clientid',
help='The Client/Application ID of the Account accessing the keyvault (this is a GUID)', required=True)
parser.add_argument('--clientsecret', metavar='clientsecret',
help='The client secret', required=True)
parser.add_argument('--tenantid', metavar='tenantid',
help='The Tenant Id the Account is in (this is a GUID)', required=True)
parser.add_argument('--secretfile', metavar='secretfile',
help='The name of the actual secret resource in Kubernetes', required=True)
args = parser.parse_args()
# Parse args into simpler terms
vaultid = "https://"+args.vaultid+".vault.azure.net"
clientid = args.clientid
clientsecret = args.clientsecret
tenantid = args.tenantid
secretfile = args.secretfile
credentials = ServicePrincipalCredentials(
client_id=clientid,
secret=clientsecret,
tenant=tenantid
)
client = KeyVaultClient(credentials)
# Gets all secrets and their versions and puts it in a dict called secret_ids
secret_ids = {}
all_secrets = client.get_secrets(vaultid)
for s in all_secrets:
id = s.id.rsplit('/', 1)[-1]
get_version = client.get_secret_versions(vaultid, id)
for secret in get_version:
version = secret.id.rsplit('/', 1)[-1]
secret_ids.update({id: version})
secrets_dict = {}
for k, v in secret_ids.items():
get_secret_value = client.get_secret(vaultid, k, v)
# Reformat before updating the dict
# This changes a secret id named AUTH-HEADER into AUTH_HEADER (Kubernetes requires keys to be a specific format)
# This changes a secret value into a base64 encoded version (required by Kubernetes)
dash_to_underscore = str(k).replace('-', '_')
remove_spaces = str(dash_to_underscore).replace(' ', '_')
base64_value = base64.b64encode(get_secret_value.value)
secrets_dict.update({remove_spaces: base64_value})
# Setup secrets in JSON format
secrets = {
"apiVersion": "v1",
"kind": "Secret",
"metadata": {
"name": secretfile
},
"type": "Opaque",
"data": secrets_dict
}
js = json.dumps(secrets)
# Convert and dump JSON formatted secrets as yaml
with open(secretfile + '.yaml', 'w') as outfile:
yaml.safe_dump(json.loads(js), outfile, default_flow_style=False)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment