Azure Key Vault is a cloud service that works as a secure secrets store. You can securely store keys, passwords, certificates, and other secrets. You can use PowerShell to create a key vault and secrets and assign access policy to users, groups or Apps.

Save the below scripts in DevOps project-

#this scripts will create keyvault, assign permissions to users, apps, and groups.
#pipeline service principal App ObjectID will be assigned list,get and set permissions.


[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]$location,
[Parameter(Mandatory=$true)]$resourceGroupName,
[Parameter(Mandatory=$true)]$keyVaultName,
[Parameter(Mandatory=$true)]$secretName,
[Parameter(Mandatory=$true)]$secretValue,
[Parameter(Mandatory=$true)]$keyVaultUsers,
[Parameter(Mandatory=$true)]$svcPrincipalAppObjectId
)

Write-Host "Starting to Create the Key Vault" 

# Create new resource group if not exists.
$rgAvail = Get-AzResourceGroup -Name $resourceGroupName -Location $location -ErrorAction SilentlyContinue
if(!$rgAvail){
    New-AzResourceGroup -Name $resourceGroupName -Location $location
}



# Create new key vault if not exists. (enabling it for Disk Encryption, Deployment and Template Deployment)
$kvAvail = Get-AzKeyVault -VaultName $keyVaultName -ResourceGroupName $resourceGroupName -ErrorAction SilentlyContinue
if(!$kvAvail){
    New-AzKeyVault -VaultName $keyVaultName -ResourceGroupName $resourceGroupName -Location $location -Sku 'Standard' -EnabledForDiskEncryption -EnabledForDeployment -EnabledForTemplateDeployment
    # Wait few seconds for DNS entry to propagate
    Start-Sleep -Seconds 15

    #give permissions to service principal to create secrets
    Set-AzKeyVaultAccessPolicy -BypassObjectIdValidation -VaultName $keyVaultName -ResourceGroupName $resourceGroupName -ObjectId $svcPrincipalAppObjectId -PermissionsToKeys list,get -PermissionsToSecrets list,get,set -PermissionsToCertificates list,get
    # Add the Administrator policies to the Key Vault
    foreach ($adminUser in $keyVaultUsers.Split(',')) {
    #$UserObjectId = (Get-AzureRmADUser -SearchString $adminUser).Id
    #Write-Host "Connection Key Vault URL is " $adminUser
    Set-AzKeyVaultAccessPolicy -BypassObjectIdValidation -VaultName $keyVaultName -ResourceGroupName $resourceGroupName -ObjectId $adminUser -PermissionsToKeys list,get -PermissionsToSecrets list,get -PermissionsToCertificates list,get
}
}

# Add or update a secret to key vault.
$secretVal = ConvertTo-SecureString -String $secretValue -AsPlainText -Force
$secret =  Set-AzKeyVaultSecret -VaultName $keyVaultName -Name $secretName -SecretValue $secretVal

Write-Host "Connection Key Vault URL is " $secret

Details to use this script:

>>This script will create KeyVault based on “keyVaultName” provided. This KeyVault will be created in “resourceGroupName” and “location” provided. It will create the resource group if it is not existing. The users, groups and Apps will be assigned (list & get) access to Keys/Secrets/Certificates based “keyVaultUsers” list. Find the ObjectId of user or group or App and add to “keyVaultUsers” variable as comma separated. To add a secret to this KeyVault, provide the service principal App ObjectId in “svcPrincipalAppObjectId” variable. Once the service principal has  access (List,Get,Set) for Keys/Secrets/Certificates, it will be able to create the secrets provided in “secretName” and secret value provided in “secretValue“.

Steps to use this PowerShell script in Azure DevOps release pipeline:

Repos: The project file will look like below-

Pipelines–> Build: Create build pipeline. It will look like below-

Pipelines–>Release: Create release pipeline.

step1- Add artifact to the release pipeline

Step 2 – Add task to the Stage. Add Azure PowerShell task and configure it as shown.

Step 3 – Add Variables and values. Special care required to provide values for “keyVaultUsers” and “svcPrincipalAppObjectId“.

NOTE: If service principal which is configured to execute the release pipeline is not given access to KeyVault then it won’t be able to create secrets. Follow the steps below on how to get ObjectId of service principal.

If these are not set correctly, you may observe errors like below when release pipeline is run-

##[error]Operation returned an invalid status code ‘Forbidden’
OR
##[error]Access denied. Caller was not found on any access policy.
Caller: appid=***;oid=7990d41f682;numgroups=0;iss=https://sts.windows.net/***/

 

How to get correct ObjectId for user and Service principal:

Steps  for User/Group ObjectID:

>>Login to Portal.azure.com

>>Go to Azure Active Directory –>Users –> select user or group. The object Id will be as shown in the screenshot. This value should be provided in “keyVaultUsers” variable with comma separated.

 

 

Steps  for Service Principal ObjectID:

Step 1 – Go to Project setting in DevOps (https://deve.azure.com/<your project>

Step 2 – Click Service Connections. In release pipeline when you select the Azure subscription, it creates a service connection.

Step 3 – Select the Service connection being used in release pipeline and click “Manage Service Principal

 

Step 4 – It will take you to portal. Click on “Managed application in local directory“.

 

Step 5 – Copy the ObjectId as shown in the schreenshot. This is the Service Principal App ObjectId. This value should be provided in variable “svcPrincipalAppObjectId”

 

 

Now run the release pipeline and verify that the KeyVault, secrets and access policy is created with no issues. You can further improve the PowerShell script as per your requirement.