This post series is to help you into the world of stateful Infrastructure as Code with Pulumi. We're going to use Azure Native as resource provider to provision our desired infrastructure. For the Azure Cloud, it is also possible to use the Azure Classic package, but Azure Native usually gets updated more quickly on changes in the Azure Cloud.
The aim of this post is to prepare yourself a self-managed backend that will bring you up to speed in your project.
Pulumi as an Infrastructure as Code tool provides stateful deployments. That means it creates a to-do list for every deployment by comparing what is deployed in the cloud and what is specified in the code. This is handled via a Statefile. In this file Pulumi is documenting deployed and imported cloud resources. The resources are noted down as JSON objects, including some of their configuration but mainly their Resource Id.
The handling of the Statefile for Pulumi can happen in multiple options. The simplest option is to just have the Statefile located in the file system of your device. This is set up very fast and useful for quick tests around cloud infrastructure, but this option does not allow team collaboration.
Alternatives are to use the Pulumi Cloud to handle your Statefile or to create a self-managed backend for your Statefile. This can be done by connecting Pulumi to the storage resource of your Cloud and is what we want to achieve here.
For the self-managed backend, you need to set up the following things:
- Install Pulumi
- Create a Storage Account
- Create a empty directory
To use the Storage Account, you need to create a Blob Container, that is later used to store the State File(s) of your Infrastructure. In my case, the Container is just called
Pulumi. An additional that is optional but recommended is to encrypt the Storage Account with your own key. Therefore, you have to create a Key Vault and follow the Steps here.
The next step is to log in with the Azure CLI. This is not necessary for setting up the self-managed Pulumi Backend, but still will be handy, since connecting Pulumi to the Storage Account will require the Key of the Storage account.
az login --tenant xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
or with MFA required:
az login --tenant xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx --use-device-code
And make sure you are using the correct Subscription:
az account set --subscripion xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
One hint for any international Readers, by e.g. the Azure China cloud with the CLI Pulumi will also aim for China.
Out of just being used to it, I go with a mix of the Azure CLI and PowerShell for the commands, of course you can go with bash as well. For Azure PowerShell fans, I've got bad news here, Pulumi only does support the Azure CLI. But fear not - as soon as you got your CI/CD Pipelines set up, you don't have to touch it anymore.
For the Pulumi Login, you need the following Variables:
These are used for Pulumi to Identify your storage account. Additionally Pulumi needs the following Environment Variables setup to login into your backend:
$env:AZURE_STORAGE_KEY=(az storage account keys list --account-name $storageAccountName | ConvertFrom-Json).value
I am using the Azure CLI to avoid copying the Storage Account Key into my Console. With the Variable setup, we can now login with Pulumi.
The Pulumi Login can be done with:
pulumi login azblob://$containerPath
Congratulations, now your Device is connected to a Storage Account and Pulumi is able to either create, or access any Statefiles that are located in the specified Container.
One hint for those of you wondering why you had to log in with the Azure CLI and still provide the Storage Account Key. Accessing the Storage Account via RBAC is not supported for now.