How do I rename all secrets in an Azure Key Vault - azure

I need to add a prefix to all my secrets in an Azure Key Vault.
There seems to be no API or cmdlet for this, and not possible in the Azure Portal either.
How can I accomplish this?

The PowerShell script below creates new keys with a prefix added.
(az keyvault secret list --vault-name <AZURE_KEY_VAULT_NAME> | ConvertFrom-Json) | %{ az keyvault secret show --id $_.id | ConvertFrom-Json | %{ az keyvault secret set --vault-name ([uri]$_.id).Host.Split('.')[0] -n "<PREFIX>-$(([uri]$_.id).Segments[2].TrimEnd('/'))" --value `"$($_.value)`" } }
Make sure to replace <AZURE_KEY_VAULT_NAME> and <PREFIX> before running the script.
The az PowerShell module can be installed from https://learn.microsoft.com/en-us/powershell/azure/

Here is a example is Bash.
AZURE_KEY_VAULT_NAME=<Your KeyVault name>
PREFIX="-old"
for secret_name in $(az keyvault secret list --vault-name $AZURE_KEY_VAULT_NAME --query '[].[name]' -o tsv); do
echo "Rename ${secret_name} into ${secret_name}${PREFIX}"
secret=$(az keyvault secret show --vault-name $AZURE_KEY_VAULT_NAME --name ${secret_name} --query value -o tsv)
az keyvault secret set --vault-name $AZURE_KEY_VAULT_NAME --name ${secret_name}${PREFIX} --value $secret
# Delete original key if needed
# az keyvault secret delete --vault-name $AZURE_KEY_VAULT_NAME --name ${secret_name}
# Perminantly
# az keyvault secret purge --vault-name $AZURE_KEY_VAULT_NAME --name ${secret_name}
done
Instead of list over all keys, you could use grep to get a subset, or just provide a list (space seperated) of secrets, e.g.
$(az keyvault secret list --vault-name $AZURE_KEY_VAULT_NAME --query '[].[name]' -o tsv | grep example)
secret1 secret2 secret3

Related

Copying contents of one vault to another

Somewhere I read that I can copy backups from one vault to another. I have been unable to find anything leading me in the right direction.
My intent is to do so, so that I can work around the fact that one cannot rename vaults, once they have been created.
I have been all over the different vault options, but have not come across anything suggesting that I was on the right path.
This answer have been copied from How To Copy All Secrets From One KeyVault To Another In Azure
There are two options to make it:
Copy Azure KeyVault using the Powershell script
Copy Azure KeyVault using Azure CLI
Here, we are copying 4 secrets from the source keyvault called myKeyVault2020 for the demonstrations.
Option 1: Copy Azure KeyVault using Powershell script
Now we want to copy secrets that are not already present in the destination keyvault called kv-myapps-2021 using Azure Powershell.
Param(
[Parameter(Mandatory)]
[string]$sourceKvName,
[Parameter(Mandatory)]
[string]$destKvName
)
Connect-AzAccount
$secretNames = (Get-AzKeyVaultSecret -VaultName $sourceKvName).Name
$secretNames.foreach{
Set-AzKeyVaultSecret -VaultName $destKvName -Name $_ `
-SecretValue (Get-AzKeyVaultSecret -VaultName $sourceKvName -Name $_).SecretValue
}
We can see that all secrets have been copied successfully to kv-myapps-2021.
Option 2: Copy Azure KeyVault using Azure CLI
We can also copy all secrets using the below Bash script to a new destination keyvault called kv-myapps-2023.
Source_Kv_Name="myKeyVault2020"
Dest_Kv_Name="kv-myapps-2023"
SECRETS+=($(az keyvault secret list --vault-name $Source_Kv_Name --query "[].id" -o tsv))
for SECRET in "${SECRETS[#]}"; do
SECRETNAME=$(echo "$SECRET" | sed 's|.*/||')
SECRET_CHECK=$(az keyvault secret list --vault-name $Dest_Kv_Name --query "[?name=='$SECRETNAME']" -o tsv)
if [ -n "$SECRET_CHECK" ]
then
echo "$SECRETNAME already exists in $Dest_Kv_Name"
else
echo "Copying $SECRETNAME from Source KeyVault: $Source_Kv_Name to Destination KeyVault: $Dest_Kv_Name"
SECRET=$(az keyvault secret show --vault-name $Source_Kv_Name -n $SECRETNAME --query "value" -o tsv)
az keyvault secret set --vault-name $Dest_Kv_Name -n $SECRETNAME --value "$SECRET" >/dev/null
fi
done
Let’s check the destination key vault. Awesome! All secrets are copied.

AZ CLI loop to download

I am looking for a method to loops through using specifically az cli, in order to download for example secrets/keys. I already have an ideea of what I am trying to achieve, but I would like to do it through az cli and I can't seem to understand how to loops through, like a for loop to go through all the keys/secrets and download them locally.
is there a way ? any sort of example would be useful. It must be in az cli.
Using Powershell or Bash you could always list all the secrets in a vault, iterate and backup.
Here is a Powershell sample:
$keyVaultName = "<key vault name>"
# list secrets in a vault
$secrets = az keyvault secret list `
--vault-name $keyVaultName `
| ConvertFrom-Json
foreach ($secret in $secrets) {
# backup each secret
$filename = "$($secret.name).txt"
az keyvault secret backup `
--vault-name $keyVaultName `
--name $secret.name `
--file $filename
}

Create Azure Key Vault secret from variable with Azure CLI drops caret ^ character in value

I am trying to create a new Azure Key Vault secret using the Azure Cli v2.9.0 (we use this version in our pipelines and upgrading would be difficult at the moment.) via the command below,
$myValue = "abc^def"
az keyvault secret set --vault-name $myKeyVaultName -n $mySecretName --value #myValue
The value for #myValue is actually passed in as a parameter to the script.
The command is accepted and a new secret is created but it drops the caret (^) from the string and results in a secret value of abcdef instead of the intended abc^def.
I previously raised the question here and Joy Wang correctly stated that forming a string literal as '"abc^def"' would allow the value to be added correctly via Powershell. As an extension to that question I would like to know how to pass the same value into the az keyvault secret set cmdlet from a variable.
Doing this as below still drops the caret (^)
$myValue = "abc^def"
az keyvault secret set --vault-name $myKeyVaultName -n $mySecretName --value #myValue
$myValue = "abc^def"
az keyvault secret set --vault-name $myKeyVaultName -n $mySecretName --value $(#myValue)
Posting the script snippet for clarification
param (
[Parameter(Mandatory=$True)]
[ValidateNotNullorEmpty()]
[string]$KeyVaultResourceGroup,
[Parameter(Mandatory=$True)]
[ValidateNotNullorEmpty()]
[string]$KeyVaultInstanceName,
[Parameter(Mandatory=$True)]
[ValidateNotNullorEmpty()]
[string]$CCnB_FileServer_Password_Value
)
#####################################
###########Initialsiing##############
#####################################
$ErrorActionPreference = "Stop"
$WarningPreference = 'SilentlyContinue'
Set-Location $PSScriptRoot
[Console]::ResetColor()
#############################################################
########### Create new Gasmap Key Vault secrets #############
#############################################################
#Create Secrets
if ($secrets.name -NotContains "CCnBFileServerPassword"){
Write-Output "INFO: Creating CCnBFileServerPassword secret in key vault $KeyVaultInstanceName"
az keyvault secret set --vault-name $KeyVaultInstanceName -n "CCnBFileServerPassword" --value $CCnB_FileServer_Password_Value | Out-Null
} else {
Write-Output "INFO: CCnBFileServerPassword secret already exists in key vault $KeyVaultInstanceName"
}
return 0
Any idea how I can pass this value correctly?
You can save the value like below using CLI:
It will be saved like you want:
Not sure what is the meaning of # expression, in powershell, we always use $ to define a variable.
After doing some tests, you could use the CLI in PowerShell environment like below.
$myvalue = 'abc"^"def'
az keyvault secret set --vault-name joykeyvault -n testkey12 --value $myvalue

powershell script for deleting all secrets from azure key vaults

Looking for a Powershell script which will delete all secretes present in an given azure key vault.
I don't want to delete entire key vault, just want to delete secretes present in it.
Use Remove-AzKeyVaultSecret, Remove-AzKeyVaultCertificate & Remove-AzKeyVaultKey
With some powershell and the Azure CLI you can achieve this
az keyvault secret list --vault-name ${keyVaultName} | ConvertFrom-Json | ForEach-Object { az keyvault secret delete --vault-name ${keyVaultName} --name $($_ | Select-Object -ExpandProperty Name) }
What it does is
Get all the secrets from the fault name
Transforms the response into objects
For each item take the name from the object and run the az keyvault secret delete command.
The answer by Danny van der Sluis tries to delete all secrets at once in one command, which doesn't seem to work. Putting this in a ps1 script worked for me:
$SECRETS = az keyvault secret list --vault-name "mysupersecretvault" | ConvertFrom-Json;
$SECRETS | Select-Object -Property Name | ForEach-Object { az keyvault secret delete --vault-name "mysupersecretvault" --name $_.Name }
After this, you might want to purge your vault in case you want to remake some secrets using the same name. I found it easy enough to do this through the Azure Portal, but you can also use this command:
az keyvault key purge --name "mykeyname"
Yesman's version worked well for me, however, the purge command should be for secrets, not keys so if you want to delete and purge all secrets this works:
$SECRETS = az keyvault secret list --vault-name "mysupersecretvault" | ConvertFrom-Json;
$SECRETS | Select-Object -Property Name | ForEach-Object { az keyvault secret delete --vault-name "mysupersecretvault" --name $_.Name }
$SECRETS | Select-Object -Property Name | ForEach-Object { az keyvault secret purge --vault-name "mysupersecretvault" --name $_.Name }

Retrieve Azure storage account key using Azure CLI

In my release pipeline I'm using a Azure CLI to transfer my build files to a Azure storage blob:
call az storage blob upload-batch --source "$(System.DefaultWorkingDirectory)/_ClientWeb-Build-CI/ShellArtifact/out/build" --destination "$web" --account-key "****QxjclDGftOY/agnqUDzwNe/gOIAzsQ==" --account-name "*****estx"
This works, but I want to retrieve the account-key dynamically.
When I use:
az storage account keys list -g CustomersV2 -n ****estx
I get a array with 2 objects, both holding a key value:
[
{
"keyName": "key1",
"permissions": "Full",
"value": "f/eybpcl*****************Vm9uT1PwFC1D82QxjclDGftOY/agnqUDzwNe/gOIAzsQ=="
},
{
"keyName": "key2",
"permissions": "Full",
"value": "bNM**********L6OxAemK1U2oudW5WGRQW++/bzD6jVw=="
}
]
How do I use one of the two keys in my upload-batch command?
For your issue, if you just want one of the two keys for example, the first one. You can set a variable with the key as the value like this:
key=$(az storage account keys list -g CustomersV2 -n ****estx --query [0].value -o tsv)
And then use the variable key in the other command like this:
call az storage blob upload-batch --source "$(System.DefaultWorkingDirectory)/_ClientWeb-Build-CI/ShellArtifact/out/build" --destination "$web" --account-key $key --account-name "*****estx"
Or you can just put the command which gets the key in the other command directly like this:
call az storage blob upload-batch --source "$(System.DefaultWorkingDirectory)/_ClientWeb-Build-CI/ShellArtifact/out/build" --destination "$web" --account-key $(az storage account keys list -g CustomersV2 -n ****estx --query [0].value -o tsv) --account-name "*****estx"
Update
According to what you said, it seems you run the command in the windows command prompt, it's different from the Linux shell and PowerShell. You cannot set the environment variable with the value that the output of a command. You can do that like this:
az storage account keys list -g CustomersV2 -n ****estx --query [0].value -o tsv > key.txt
set /P key=<key.txt
az storage blob upload-batch --source "$(System.DefaultWorkingDirectory)/_ClientWeb-Build-CI/ShellArtifact/out/build" --destination "$web" --account-key %key% --account-name "*****estx"
And it seems you just can quote the environment variable as %variable_name%, so it seems it's a wrong way to use "$web" in your command.
I created a Azure Powershell task (version 4) that does:
az login -u **** -p ****
Write-Host "##vso[task.setvariable variable=storageKey;]az storage account keys list -g ***** -n ***** --query [0].value -o tsv"
$key = az storage account keys list -g ***** -n **** --query [0].value -o tsv
Write-Host "##vso[task.setvariable variable=something;]$key"
Then I can use the something variable in my Azure CLI task:
call az storage blob upload-batch --source "$(System.DefaultWorkingDirectory)/_ClientWeb-Build-CI/ShellArtifact/out/build" --destination "$web" --account-key $(something) --account-name "*****"
And this works. You'll probably need to put the -u and -p in a variable though.
#Charles thanks a lot for this line (az storage account keys list -g **** -n ****estx --query [0].value -o tsv) !

Resources