Greetings to my fellow Technology Advocates and Specialists.
In this Session, I will demonstrate How to Reset Service Principal Secret and Store in Key Vault Using Azure DevOps.
I had the Privilege to talk on this topic in TWO Azure Communities:-
| NAME OF THE AZURE COMMUNITY | TYPE OF SPEAKER SESSION |
|---|---|
| Journey to the Cloud 9.0 | Virtual |
| Festive Tech Calendar 2022 | Virtual |
| LIVE RECORDED SESSION:- |
|---|
| LIVE DEMO was Recorded as part of my Presentation in JOURNEY TO THE CLOUD 9.0 Forum/Platform |
| Duration of My Demo = 55 Mins 42 Secs |
| LIVE DEMO was Recorded as part of my Presentation in FESTIVE TECH CALENDAR 2022 Forum/Platform |
| Duration of My Demo = 1 Hour 05 Mins 08 Secs |
| USE CASE:- |
|---|
| Cloud Engineer DOES NOT have access to Azure Active Directory (AAD) to Reset Service Principal Secret. |
| Cloud Engineer CANNOT ELEVATE rights using PIM (Privileged Identity Management) to Reset Service Principal Secret. |
| AUTOMATION OBJECTIVE:- |
|---|
| Validate If the Service Principal Exists. If No, Pipeline will FAIL. |
| Validate If Resource Group Containing Key Vault Exists. If No Resource Group Found, Pipeline will FAIL. |
| Validate If Key Vault Exists inside the Specified Resource Group. If No Key Vault Found, Pipeline will FAIL. |
| If All of the above validation is SUCCESSFUL, Pipeline will then Reset the Service Principal Secret and Store it in the Key Vault. |
| IMPORTANT NOTE:- |
|---|
The YAML Pipeline is tested on WINDOWS BUILD AGENT Only!!!
| REQUIREMENTS:- |
|---|
- Azure Subscription.
- Azure DevOps Organisation and Project.
- Service Principal either assigned Global Administrator Privileged Identity Management (PIM) Azure AD Role or Required Microsoft Graph API Rights (Directory.ReadWrite.All: Read and Write Directory Data).
- Service Principal with Required RBAC ( Contributor) applied on Subscription or Resource Group(s).
- Azure Resource Manager Service Connection in Azure DevOps.
| CODE REPOSITORY:- | |||||||||
|---|---|---|---|---|---|---|---|---|---|
|
| NAME OF THE AZURE COMMUNITY | TYPE OF SPEAKER SESSION |
|---|---|
| Journey to the Cloud 9.0 | Virtual |
| Festive Tech Calendar 2022 | Virtual |
| USE CASE:- |
|---|
| Cloud Engineer DOES NOT have access to Azure Active Directory (AAD) to Reset Service Principal Secret. |
| Cloud Engineer CANNOT ELEVATE rights |
| HOW DOES MY CODE PLACEHOLDER LOOKS LIKE:- |
|---|
| PIPELINE CODE SNIPPET:- |
|---|
| AZURE DEVOPS YAML PIPELINE (azure-pipelines-spi-reset-secret-v1.0.yml):- |
|---|
trigger:
none
######################
#DECLARE PARAMETERS:-
######################
parameters:
- name: SubscriptionID
displayName: Subscription ID Details Follow Below:-
type: string
default: 210e66cb-55cf-424e-8daa-6cad804ab604
values:
- 210e66cb-55cf-424e-8daa-6cad804ab604
- name: RGNAME
displayName: Please Provide the Resource Group Name:-
type: object
default:
- name: KVNAME
displayName: Please Provide the Keyvault Name:-
type: object
default:
- name: SPINAME
displayName: Please Provide the Service Principal Name:-
type: object
default:
######################
#DECLARE VARIABLES:-
######################
variables:
ServiceConnection: amcloud-cicd-service-connection
BuildAgent: windows-latest
#########################
# Declare Build Agents:-
#########################
pool:
vmImage: $(BuildAgent)
###################
# Declare Stages:-
###################
stages:
- stage: RESET_SECRET_SERVICE_PRINCIPAL
jobs:
- job: RESET_SECRET_SERVICE_PRINCIPAL
displayName: RESET SECRET SERVICE PRINCIPAL
steps:
- task: AzureCLI@2
displayName: Reset SPI Secret
inputs:
azureSubscription: $(ServiceConnection)
scriptType: ps
scriptLocation: inlineScript
inlineScript: |
az --version
az account set --subscription ${{ parameters.SubscriptionID }}
az account show
$i = az ad sp list --display-name ${{ parameters.SPINAME }} --query [].appDisplayName -o tsv
if ($i -eq "${{ parameters.SPINAME }}") {
$j = az group exists -n ${{ parameters.RGNAME }}
if ($j -eq "true") {
$k = az keyvault list --resource-group ${{ parameters.RGNAME }} --query [].name -o tsv
if ($k -eq "${{ parameters.KVNAME }}") {
$spiappid = az ad sp list --display-name ${{ parameters.SPINAME }} --query [].appId -o tsv
$spireset = az ad sp credential reset --id $spiappid --query "password" -o tsv
az keyvault secret set --name ${{ parameters.SPINAME }} --vault-name ${{ parameters.KVNAME }} --value $spireset
echo "##################################################################"
echo "The Reset of Service Principal ${{ parameters.SPINAME }} secret was successful. The New Secret was then Stored inside Key Vault ${{ parameters.KVNAME }} in the Resource Group ${{ parameters.RGNAME }}!!!"
echo "##################################################################"
}
else {
echo "####################################################################################################"
echo "Key Vault ${{ parameters.KVNAME }} DOES NOT EXISTS in Resource Group ${{ parameters.RGNAME }}!!!"
echo "####################################################################################################"
exit 1
}
}
else {
echo "##################################################################"
echo "Resource Group ${{ parameters.RGNAME }} DOES NOT EXISTS!!!"
echo "##################################################################"
exit 1
}
}
else {
echo "####################################################################################################################"
echo "Service Principal ${{ parameters.SPINAME }} DOES NOT EXISTS and hence Cannot Proceed with the Reset of Secret!!!"
echo "####################################################################################################################"
exit 1
}
Now, let me explain each part of YAML Pipeline for better understanding.
| PART #1:- |
|---|
| BELOW FOLLOWS PIPELINE RUNTIME VARIABLES CODE SNIPPET:- |
|---|
######################
#DECLARE PARAMETERS:-
######################
parameters:
- name: SubscriptionID
displayName: Subscription ID Details Follow Below:-
type: string
default: 210e66cb-55cf-424e-8daa-6cad804ab604
values:
- 210e66cb-55cf-424e-8daa-6cad804ab604
- name: RGNAME
displayName: Please Provide the Resource Group Name:-
type: object
default:
- name: KVNAME
displayName: Please Provide the Keyvault Name:-
type: object
default:
- name: SPINAME
displayName: Please Provide the Service Principal Name:-
type: object
default:
| PART #2:- |
|---|
| BELOW FOLLOWS PIPELINE VARIABLES CODE SNIPPET:- |
|---|
######################
#DECLARE VARIABLES:-
######################
variables:
ServiceConnection: amcloud-cicd-service-connection
BuildAgent: windows-latest
| NOTE:- |
|---|
| Please change the values of the variables accordingly. |
| The entire YAML pipeline is build using Runtime Parameters and Variables. No Values are Hardcoded. |
| PART #3:- |
|---|
| BELOW FOLLOWS THE CONDITIONS AND LOGIC DEFINED IN THE PIPELINE (AS MENTIONED ABOVE IN THE "AUTOMATION OBJECTIVE"):- |
|---|
inlineScript: |
az --version
az account set --subscription ${{ parameters.SubscriptionID }}
az account show
$i = az ad sp list --display-name ${{ parameters.SPINAME }} --query [].appDisplayName -o tsv
if ($i -eq "${{ parameters.SPINAME }}") {
$j = az group exists -n ${{ parameters.RGNAME }}
if ($j -eq "true") {
$k = az keyvault list --resource-group ${{ parameters.RGNAME }} --query [].name -o tsv
if ($k -eq "${{ parameters.KVNAME }}") {
$spiappid = az ad sp list --display-name ${{ parameters.SPINAME }} --query [].appId -o tsv
$spireset = az ad sp credential reset --id $spiappid --query "password" -o tsv
az keyvault secret set --name ${{ parameters.SPINAME }} --vault-name ${{ parameters.KVNAME }} --value $spireset
echo "##################################################################"
echo "The Reset of Service Principal ${{ parameters.SPINAME }} secret was successful. The New Secret was then Stored inside Key Vault ${{ parameters.KVNAME }} in the Resource Group ${{ parameters.RGNAME }}!!!"
echo "##################################################################"
}
else {
echo "####################################################################################################"
echo "Key Vault ${{ parameters.KVNAME }} DOES NOT EXISTS in Resource Group ${{ parameters.RGNAME }}!!!"
echo "####################################################################################################"
exit 1
}
}
else {
echo "##################################################################"
echo "Resource Group ${{ parameters.RGNAME }} DOES NOT EXISTS!!!"
echo "##################################################################"
exit 1
}
}
else {
echo "####################################################################################################################"
echo "Service Principal ${{ parameters.SPINAME }} DOES NOT EXISTS and hence Cannot Proceed with the Reset of Secret!!!"
echo "####################################################################################################################"
exit 1
}
NOW ITS TIME TO TEST !!!...
| TEST CASES:- |
|---|
| TEST CASE #1: SERVICE PRINCIPAL NAME EXISTS, RESOURCE GROUP AND KEY VAULT EXISTS:- |
|---|
| DESIRED OUTPUT: PIPELINE EXECUTED SUCCESSFULLY. SERVICE PRINCIPAL SECRET GOT RESET AND STORED IN KEY VAULT. |
| SERVICE PRINCIPAL IN PLACE:- |
| PIPELINE RUNTIME VARIABLES VALUE:- |
| PIPELINE EXECUTED SUCCESSFULLY:- |
![]() |
![]() |
| SERVICE PRINCIPAL RESET SECRET STORED IN KEY VAULT:- |
| TEST CASE #2: SERVICE PRINCIPAL DOES NOT EXISTS, RESOURCE GROUP AND KEY VAULT EXISTS:- |
| DESIRED OUTPUT: PIPELINE FAILS STATING THAT THE SERVICE PRINCIPAL DOES NOT EXISTS. |
| PIPELINE FAILED:- |
![]() |
![]() |
| TEST CASE #3: SERVICE PRINCIPAL AND KEYVAULT EXISTS BUT RESOURCE GROUP DOES NOT EXISTS:- |
| DESIRED OUTPUT: PIPELINE FAILS STATING THAT THE RESOURCE GROUP DOES NOT EXISTS. |
| PIPELINE FAILED:- |
![]() |
![]() |
| TEST CASE #4: SERVICE PRINCIPAL AND RESOURCE GROUP EXISTS BUT KEY VAULT DOES NOT EXISTS:- |
| DESIRED OUTPUT: PIPELINE FAILS STATING THAT THE KEY VAULT DOES NOT EXISTS. |
| PIPELINE FAILED:- |
![]() |
![]() |
| IMPORTANT OBSERVATION:- |
|---|
| The Service Principal Reset Secret Entry Does Not appear in Azure Portal though available in Key Vault. |
| SECRET DETAILS IN KEY VAULT AFTER RESET:- |
| SECRET DETAILS IN AZURE PORTAL APP REGISTRATION GUI AFTER RESET:- |
Hope You Enjoyed the Session!!!
Stay Safe | Keep Learning | Spread Knowledge










Top comments (0)