Greetings to my fellow Technology Advocates and Specialists.
In this Session, I will demonstrate how to Create Service Principal and Store Secret in Key Vault Using Azure DevOps.
I had the Privilege to talk on this topic in THREE Azure Communities:-
NAME OF THE AZURE COMMUNITY | TYPE OF SPEAKER SESSION |
---|---|
Microsoft Azure Bern User Group | In Person |
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 Create Service Principal. |
Cloud Engineer CANNOT ELEVATE rights using PIM (Privileged Identity Management) to Create Service Principal. |
AUTOMATION OBJECTIVE:- |
---|
Validate If the Service Principal Exists. If Yes, 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 Create the Service Principal, Generate 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 with Required RBAC ( Contributor) applied on Subscription or Resource Group(s).
- Azure Resource Manager Service Connection in Azure DevOps.
HOW DOES MY CODE PLACEHOLDER LOOKS LIKE:- |
---|
PIPELINE CODE SNIPPET:- |
---|
AZURE DEVOPS YAML PIPELINE (azure-pipelines-spi-validate-create-store-in-KV-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: CREATE_SERVICE_PRINCIPAL
jobs:
- job: CREATE_SERVICE_PRINCIPAL
displayName: CREATE SERVICE PRINCIPAL
steps:
- task: AzureCLI@2
displayName: VALIDATE AND CREATE SPI
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 -ne "${{ 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 }}") {
$spipasswd = az ad sp create-for-rbac -n ${{ parameters.SPINAME }} --query "password" -o tsv
az keyvault secret set --name ${{ parameters.SPINAME }} --vault-name ${{ parameters.KVNAME }} --value $spipasswd
echo "##################################################################"
echo "Service Principal ${{ parameters.SPINAME }} created successfully and the Secret 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 }} EXISTS and hence Cannot Proceed with Deployment!!!"
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 -ne "${{ 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 }}") {
$spipasswd = az ad sp create-for-rbac -n ${{ parameters.SPINAME }} --query "password" -o tsv
az keyvault secret set --name ${{ parameters.SPINAME }} --vault-name ${{ parameters.KVNAME }} --value $spipasswd
echo "##################################################################"
echo "Service Principal ${{ parameters.SPINAME }} created successfully and the Secret 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 }} EXISTS and hence Cannot Proceed with Deployment!!!"
echo "##################################################################"
exit 1
}
NOW ITS TIME TO TEST !!!...
TEST CASES:- |
---|
Hope You Enjoyed the Session!!!
Stay Safe | Keep Learning | Spread Knowledge