4

I have keyvault named myKeyVault and there might be a key inside called myKey. I'm reading documentation of Azure CLI: https://learn.microsoft.com/en-us/cli/azure/keyvault/key?view=azure-cli-latest#az_keyvault_key_list but I can't figure out how to check if the key of given name actually exists.

If I go with that:

az keyvault key show --vault-name myKeyVault --name keythatdoesntexist I do get ResourceNotFoundError: (KeyNotFound) error, but what I need is to get true or false if the key exists.

Yoda
  • 17,363
  • 67
  • 204
  • 344
  • 1
    The CLI command will not return a boolean value to you. You need to judge yourself. Perhaps it's better that use the `list` and check if the given name is in the list. – Charles Xu Nov 30 '20 at 01:51

5 Answers5

4

Although the above ways may work but it is done via checking null value returned over a failed command az keyvault show <none existent secret> I believe the following is a better way of dealing with this scenario, especially in automated infra release pipelines

# get Command Line Args
keyVaultName=$1
secretName=$2

# Check if secret exists
secret_exists=$(az keyvault secret list --vault-name $keyVaultName --query "contains([].id, 'https://$keyVaultName.vault.azure.net/secrets/$secretName')")


if [ $secret_exists == true ]; then
    echo "Secret '$secretName' exists! fetching..."
    secret_val=$(az keyvault secret show --name $secretName --vault-name $keyVaultName --query "value")
    echo "##vso[task.setvariable variable=ssh_value]$secret_val"
else
    echo "Secret '$secretName' do not exist! creating..."
    ssh-keygen  -f ~/.ssh/id_rsa_infra -q -P ""
    ssh_value=$(<~/.ssh/id_rsa_infra.pub)
    echo "##vso[task.setvariable variable=ssh_value]$ssh_value"
    az keyvault secret set --vault-name $keyVaultName --name $secretName -f ~/.ssh/id_rsa_infra.pub >/dev/null
fi
Roozbeh
  • 523
  • 4
  • 11
  • UPDATE: For automated pipelines use `-o tsv` to get rid of the quotes `secret_val=$(az keyvault secret show --name $secretName --vault-name $keyVaultName --query "value") -o tsv` – Roozbeh Jul 14 '21 at 09:23
  • Note: If the secret_exists fails, it will create a new secret and override the existing one. (but restoring is pretty simple in AKV) – Rubatharisan Thirumathyam Dec 28 '21 at 15:56
2

Might find the following useful ...

You need the vaultUri property for JMESPath contains() later so ...

($resource = az resource show --subscription ($subscription = 'MY_SUBSCRIPTION') --resource-group ($resourceGroup = 'MY_RESOURCE_GROUP') --resource-type 'Microsoft.KeyVault/vaults' --name ($resourceName = 'MY_KEYVAULT_NAME') --output json | ConvertFrom-Json) | Format-List

Use az keyvault key list --query to return whether NAME_OF_KEY exists or not - as suggested by roozbeh

(az keyvault key list --subscription $subscription --vault-name $resourceName --query ("contains([].kid, '{0}keys/{1}')" -F $resource.Properties.vaultUri, ($keyName = "NAME_OF_KEY")))

and if MY_KEY_NAME exists then the following will return the enabled revisions in reversed createdBy order, i.e. latest revision as [0]

($listVersions = az keyvault key list-versions --subscription $subscription --vault-name $resourceName --name $keyName --query "reverse(sort_by([?attributes.enabled], &attributes.created))" --output json | ConvertFrom-Json) | Format-List

I couldn't get the datetime for NotBefore & Expires to work within JMESPath so the PowerShell equivalent is ...

($activeVersions = $listVersions | Where-Object { (($null -eq $_.attributes.notbefore) -or ($_.attributes.notbefore -le ($Now = [System.DateTime]::Now))) -and (($null -eq $_.attributes.expires) -or ($_.attributes.expires -gt $Now)) }) | Format-List

and then show details of the latest active version of MY_KEY_NAME using

($key = az keyvault key show --subscription $subscription --vault-name $resourceName --name $keyName --version ($activeVerions[0].kid -replace ('^.+/', '')) --output json | ConvertFrom-Json) | Format-List

although the latest version needs to be enabled for usage so the following is just fine:

($key = az keyvault key show --subscription $subscription --vault-name $resourceName --name $keyName --output json | ConvertFrom-Json) | Format-List
1

There is no direct 'if exists' api. But one easy way is to just capture output of az keyvault key show --vault-name myKeyVault --name keythatdoesntexist in a variable and check null. Below example is in powershell.

$key = az keyvault key show --vault-name myKeyVault --name keythatdoesntexist
if ($key -ne $null) {
  write-host 'Exists'
}
else {
  write-host 'Does not exist'
}
krishg
  • 5,935
  • 2
  • 12
  • 19
  • If the key is not found it throws en error `KeyNotFound` – Yoda Nov 27 '20 at 11:39
  • The error is printed in console. But if your purpose is programmatically do something based on if key exists or not, the code in my answer works fine and the error does not stop execution. It's just that if some red text bothers you too much, that's other thing :). – krishg Nov 27 '20 at 12:40
1

You could try the below

#To suppress the error
$ErrorActionPreference= 'silentlycontinue'

#if($(output), exists,not exists)

If($(az keyvault key show --vault-name YOURVAULTNAME --name YOURKEYNAME))
{
$exist = True
write-host 'Exists'
}
else

{
$exist = False
write-host 'Not Exists'
}
#Setting the ErrorActionPrefence to the Default
$ErrorActionPreference= 'Continue'
Satya V
  • 3,811
  • 1
  • 6
  • 9
1

Simple Bash script:

keyVaultName=myKeyVault
secretName=myKey

secretExists=$(az keyvault secret list --vault-name $keyVaultName --query "contains([].name, '$secretName')")
if [ "$secretExists" == "true" ]; then
    echo Secret exists
fi

or another way:

keyVaultName=myKeyVault
secretName=myKey

if az keyvault secret list --vault-name $keyVaultName --query "[].name" | grep $secretName
then
    echo Secret exists
fi
Vlad Rudenko
  • 2,363
  • 1
  • 24
  • 24