Author : MD TAREQ HASSAN | Updated : 2021/10/22
Prepare Pulumi Backend and Pulumi Project
In this article, for Pulumi backend
- Azure blob container will be used as backend (stack state backend)
- Azure KeyVault key (RSA, 2048) will be used for Pulumi secrets
- Required environemnt variables for Pulumi CLI
- A service principal will be used to access blob container and KeyVault key
- Pulumi CLI would expect credentials (“service principal credentials” and “storage account key or SAS token”) to be available as environment variables (in the host machine i.e. your own PC or Azure VM)
The whole process of preparing backend and creating project is described here: /pulumi/using-azure-blog-storage-as-backend.
(Make sure that you test once from your local machine before setting up Azure DevOps pipeline)
Check Service Principal Role
If service principal is created and roles are assigned according to the previous section (“Prepare Pulumi Backend and Pulumi Project”) of this article, then skip this section. Otherwise make sure that required roles are assigned to the service principal mentioned that the service principal credential will be used for:
- Access to KeyVault (key for Pulumi secrets and Linking KeyVault secrets to DevOps variable group)
- Creating Service Connection for DevOps Pipeline
Notes:
- For aaccess to blob container, Storage Account key will be used by Pulumi CLI (Account key is being used in this article, you should use SAS token instead).
- Since Storage Account is being used, no specific role is needed for service principal at Storage Account scope
Prepare DevOps Project and Repository
- Create DevOps project i.e. “pulumi-demo”
- A repository will be created by default with same name of project name (create repository if you want different name for repository)
- Push Pulumi project code to DevOps repository
git remote add origin git@ssh.dev.azure.com:v3/<org-name>/<project-name>/<repository-name>
git push -u origin --all
Create Service Connection
See:
Create Variable Group and Link KeyVault Secrets
- Service principal and storage account credentials are stored in Azure KeyVault as secrets
- Create variable group “pulumi-demo-vg” and link KayVault secrets: Linking KeyVault Secrets to Variable Group
- Variable group variables will be linked/exposed to pipeline (
azure-pipelines.yml
) at root level
pool:
vmImage: 'ubuntu-latest'
variables:
- group: "pulumi-demo-vg" # linking variable group at root level so that all stages can use it
# ... ... ...
Create Pipeline
- Over over “Pipelines” > Click “Pipelines”
- New Pipeline (Top right)
- Where is your code?: Azure Repos Git YAML > Select a repository
- Configure your pipeline: Starter Pipeline
- Remove all content and paste yaml below
- “Save and Run” drop down (Top right) > Save
PipelineTemplates/pulumi-task.yml
parameters:
- name: command
type: string
- name: stack
type: string
default: dev
steps:
- task: Pulumi@1
inputs:
azureSubscription: 'xxx-sc' # sc -> service connection
command: $
loginArgs: 'azblob://pulumi-backend-container'
args: '--yes'
stack: $
env:
AZURE_STORAGE_ACCOUNT: $(AZURE-STORAGE-ACCOUNT)
AZURE_STORAGE_KEY: $(AZURE-STORAGE-KEY)
AZURE_CLIENT_ID: $(AZURE-CLIENT-ID)
AZURE_CLIENT_SECRET: $(AZURE-CLIENT-SECRET)
AZURE_TENANT_ID: $(AZURE-TENANT-ID)
azure-pipelines.yml
# trigger:
# - master
#
# Agent pool
#
pool:
vmImage: 'ubuntu-latest'
#
# Import KeyVault secrets by linking Variable Group
#
variables:
- group: "demo-vg"
- name: TestVar
value: This is test variable at root level
stages:
#
# Deploy Stack -----------------------------------------------------------------------------------------------------------
#
- stage: PulumiUpStage
displayName: Stack Deployment Stage
dependsOn: []
jobs:
- job: PulumiUpJob
displayName: Stack Deployment Job
continueOnError: false
steps:
- task: UseDotNet@2
displayName: 'Use .NET 6.0 sdk'
inputs:
packageType: 'sdk'
version: '6.0.x'
includePreviewVersions: true
- template: PipelineTemplates/pulumi-task.yml
parameters:
command: up
#
# Destroy Stack ---------------------------------------------------------------------------------------------------------------------------------
#
- stage: PulumiDestroyStage
displayName: Pulumi Destroy Stage
dependsOn: []
jobs:
- job: PulumiDestroyJob
displayName: Pulumi Destroy Job
steps:
- template: PipelineTemplates/pulumi-task.yml
parameters:
command: destroy
Allow Pipeline to Use Service Connection
- Project Settings (bottom left) > Service connections
- Pipeline permissions > “+” (Add pipeline) > Search pipeline > Add
Test Pipeline
- Pipelines > select target pipeline > Run pipeline (top right)
- Run the pipeline and at first run it might ask to authorize to let pipeline use service connection
- Check that resources are created in the target Azure subscription