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:- | |||||||||
---|---|---|---|---|---|---|---|---|---|
arindam0310018 / 17-Aug-2022-DevOps__Reset-SPI-Secret-Store-In-KVRESET SERVICE PRINCIPAL SECRET AND STORE IN KEY VAULT USING AZ DEVOPSRESET SERVICE PRINCIPAL SECRET AND STORE IN KEY VAULT USING AZ DEVOPSGreetings 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:-
|
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)