Copy Azure KeyVault secrets to another KeyVault using Azure CLI

I am going to show how you can copy Azure KeyVault secrets to another KeyVault using Azure CLI.

I have two key vaults,

keyvaultold – Contains secrets1 to secret7

keyvaultnewtest – Contains secret7

I want to copy secrets that are not already present in keyvaultnewtest from keyvaultold

I created a bash script using Azure CLI, I was able to achieve this!

#!/bin/bash

SOURCE_KEYVAULT="keyvaultold"
DESTINATION_KEYVAULT="keyvaultnewtest"

SECRETS+=($(az keyvault secret list --vault-name $SOURCE_KEYVAULT --query "[].id" -o tsv))

for SECRET in "${SECRETS[@]}"; do

SECRETNAME=$(echo "$SECRET" | sed 's|.*/||')

SECRET_CHECK=$(az keyvault secret list --vault-name $DESTINATION_KEYVAULT --query "[?name=='$SECRETNAME']" -o tsv)


if [ -n "$SECRET_CHECK" ]
then
    echo "A secret with name $SECRETNAME already exists in $DESTINATION_KEYVAULT"
else
    echo "Copying $SECRETNAME to KeyVault: $DESTINATION_KEYVAULT"
    SECRET=$(az keyvault secret show --vault-name $SOURCE_KEYVAULT -n $SECRETNAME --query "value" -o tsv)
    az keyvault secret set --vault-name $DESTINATION_KEYVAULT -n $SECRETNAME --value "$SECRET" >/dev/null
fi

done

Output sample from running the script

Awesome! Checking keyvaultnewtest I can see the secrets that were not present are now copied successfully from keyvaultold

Hopefully this bash/Azure CLI script will assist you – thanks for reading!

GitHub Repository

GitHub Gist

11 comments

  1. Thanks for the script!

    Small typo on line 12 though:
    SECRET_CHECK=$(az keyvault secret list –vault-name keyvaultnewtest –query “[?name==’$SECRETNAME’]” -o tsv)

    Should be:

    SECRET_CHECK=$(az keyvault secret list –vault-name $DESTINATION_KEYVAULT –query “[?name==’$SECRETNAME’]” -o tsv)

  2. Good Article.
    Not an issue, but the az keyvault secret set supports -o none for “don’t output my secret to standard out” if you want to use that instead of >/dev/null

  3. Hello all! If you just want to copy some secrets, you can edit the query string with this: –query “[?contains(name, ‘sftp’)].{id: id}”
    In this case, the script will copy all the secrets with “sftp” as a part of their name.

    1. Hi Guillermo,

      Yup that is true – thanks for commenting this and it may assist others!

      Thanks

      Thomas

  4. I’ve detected a small or big problem here. If the secret already exist, but source has another version of the secret, the script skip it, don’t generating the new version into the destination secret. So, if you update your SRC secret, and execute the script, the new version don’t be replicated into DST KV

    1. Thanks for the comment, I created this blog post as essentially, direct copy to new Key Vault. You can ammend this script to include additional logic for the above^

  5. Yeap. I know that and I really appreciate it. Let me check how can I add that and I’ll share the solution here with all!
    Regards @Thomas

Leave a Reply