Overview
Terraform is an awesome tool for created and managing infrastructure resources. However, before you can use it there is setup work you need to do on your workstation. To save time I’ve documented the entire process to get your workstation setup and ready to do terraform development targeting Microsoft Azure.
Part of the reason I’m writing this is because I had to do it for myself first and then I’ve had to teach other developers on my team how to do it. To save myself time in the future, I’m taking the time now to document the steps.
Additionally, my workstation is a Mac Studio running Parallels, so I switch between Mac OS and Windows 11 as I’m working. Both my Mac and Windows machines can do Terraform development. The differences in setup between the two are minimal so I’ll cover both.
What won’t be covered
I won’t be covering Terraform itself in this post. I’ll provide a very simple terraform script that creates a resource group that we’ll use to test that our workstation has been configured correctly; but the details of terraform won’t be discussed.
We’ll be using a lot of PowerShell and Azure CLI throughout this post. However, I won’t be going in to details about how PowerShell scripting works or details about Azure CLI.
I’m just providing what you need to get going. I’ll go into detail about Terraform, PowerShell and Azure CLI in follow up posts.
Assumptions
To begin with, I’m going to assume that you already have a Microsoft Azure account with contributor rights (or you’re the owner of the account). I’m also going to assume we’re starting off with a ‘clean’ workstation. If your workstations already has some of this stuff setup, just skip the step and move on. I’m also assuming you have control of your workstation and can install packages on it.
Getting Started
Here is our itinerary for setting up and configuring our workstation:
- Install a package manager (either Homebrew on the mac or Chocolatey on Windows).
- Install PowerShell (Mac)
- Install VS Code.
- Install Azure CLI.
- Install Terraform.
- Install git.
- Setup an Azure Key Vault to store secrets.
- Create a managed service identity in Azure.
- Save the MSI’s info to the key vault.
- Create a PowerShell script to configure Terraform so we can perform plans and then apply them to Azure.
- Test Terraform by creating a resource group.
Only the first 4 steps change between Mac and Windows. Technically, you could do this on Linux as well, but I’m not going to get in to the differences between the different distros.
Package Manager
If you’re on a Mac, you’re going to use Homebrew as your package manager. To install it go to https://brew.sh and follow the directions. Seriously, right at the top of the page they give you the command that will do all the work for you.
If you’re on Windows, you’re going to use Chocolatey as your package manager. To install it go to https://chocolatey.org/install and follow the directions. In this case though you need to make sure you’re running PowerShell as the administrator.
Overall though, easy day.
Install Our Tools
Now that we have a package manager pulling in our tools becomes trivial.
This is the major difference between Windows and Mac: We have to install PowerShell on our Mac. To do that, just execute the following in the terminal window you used to setup Homebrew:
brew install powershell/tap/powershell
Now we can get on to installing everything else. First we’ll do a Mac and then we’ll do Windows. On the Mac, from the same terminal window, first install VS Code with the following command:
brew install --cask visual-studio-code
After that completes, install Azure CLI:
brew install azure-cli
And then install Terraform:
brew install terraform
Finally, install git:
Brew install git
On the Windows side, using the same PowerShell window you installed Chocolatey with, run the following commands.
To install VS Code:
choco install vscode.install
Install Azure CLI:
choco install azure-cli
Install Terraform:
choco install terraform
And finally, install git:
choco install git.install
Easy living. We’re done installing stuff.
On the Mac, you’ll want to start PowerShell in your terminal window. Just type pwsh and it’ll be started for you.
Login to Azure
Before we start the cool stuff we need to get logged in to Azure so the CLI will have a context for where it’s taking action. Logging in is a two step process, first authenticate and then setting the subscription we’re going to work with. The following command gets us logged in:
az login
This will open a web-browser for you to enter your credentials. After successfully logging in, you’ll see a bunch of information on the screen about your account and subscriptions. We’ll need to select a subscription. To get a list of subscriptions use this command:
az account subscription list
This will show the subscriptions you have access to. If you’re using a personal account, it should be just one. If you’re using your work account, you might have a bunch. In my case, my personal account has several subscriptions associated with it. To get the default I can use the following command:
az account list --query “[?isDefault]”
This will show all the information about my default subscription. However, we only need the id, so this works even better:
az account list --query “[?isDefault].id”
Copy the GUID and paste it into this command:
az account set --subscription [subscription id]
That’s it, we’re all set to get down to work.
Setup Infrastructure
Before we start getting our configuration together, we need to setup some infrastructure. Mostly we need key vault. The reason we want a key vault is because we’ll be generating some secrets you never want stored in a project’s source repo.
We need to create a resource group to put our key vault in. To do that, use these commands:
$resNumber = (get-random -minimum 1000 -maximum 9999 | out-string) -replace "`n", ""
$resourceGroupName = ‘yourinitialsResources’ + $resNumber
az group create --locaton southcentralus –name $resourceGroupName
This is a little more complicated that previous, but names must be unique. To do that we first get a random number and assign it to a variable called $resNumber. Then we create the resource group name by appending the random number to a string. Completely up to you, but I’d repace ‘yourinitials’ with something like your initials. However, resource group names can be up to 90 characters so do as you wish.
Now that we have a resource group we can create the key vault. Do the following to create the keyvault:
$keyvaultName = ‘yourinitialsVault’+$resNumber
az keyvault create --resource-group $resourceGroupName --name $keyvaultName
As before we have to setup a unique name for the key vault. However, this time we’re limited to a max of 24 characters. Using your initials makes a lot of sense.
You should keep in mind that you’ll want to keep this key vault long term to hold your secrets. As such, make a name you can live with.
Configuration (Finally)
Now that we have our key vault, we can setup a managed service identity and store all of our configuration information in the key vault.
To create a managed service identity (MSI), we need to get our subscription id to create the MSI. To get the subscription id, you can use the following PowerShell:
$subscription = (az account list --query "[?isDefault]" | out-string | convertfrom-json)
$subscription will be an object representing your default Azure subscription. To get the subscription id, just type
$subscription.id
Now we can create the MSI:
$tfmsi = (az ad sp create-for-rbac --name mytf-msi --role Contributor --scopes “/subscriptions/$($subscription.id)” | out-string | convertfrom-json)
$tfmsi will contain the information about our MSI that we need. Specifically, we need the AppId and password (app secret) and tenant. We’ll store all of these, and the subscription id, in our keyvault.
To create the secrets in the keyvault use the following commands:
First, store the app id in the key vault:
az keyvault secret set –name “tfClientId” –vault-name [vault] –value $tfmsi.appId
Next, store the password:
az keyvault secret set –name “tfClientSecret” –vault-name [vault] –value $tfmsi.password
Next, store the subscription:
az keyvault secret set –name “subscriptionId” –vault-name [vault] –value $subscription.id
Finally, store the tenant id:
az keyvault secret set –name “tenantId” –vault-name [vault] –value $subscription.tenantId
Next we’ll setup a script that fetches all of the secrets from the key vault and assigns them to environment variables that terraform will automatically use. Here is how that script looks:
$keyVaultName="youKVNameHERE"
# get values from the KV
$env:ARM_SUBSCRIPTION_ID =(az keyvault secret show --vault-name $keyVaultName --name "SubscriptionId" --query "value") -replace '"', ''
$env:ARM_CLIENT_ID = (az keyvault secret show --vault-name $keyVaultName --name "tfClientId" --query "value") -replace '"', ''
$env:ARM_CLIENT_SECRET = (az keyvault secret show --vault-name $keyVaultName --name "tfClientSecret" --query "value") -replace '"', ''
$env:ARM_TENANT_ID = (az keyvault secret show --vault-name $keyVaultName --name "tenantId" --query "value") -replace '"', ''
You’ll have to change $keyVaultName to whatever name you’re using for your key vault. You’ll also want to save this in a ps1 file so you can run it. You’ll have to run this script before you start doing Terraform development so all of the environment variables will be setup. You could also add this to your PowerShell profile script so it runs automatically each time you start PowerShell.
Now we’re ready to test our workstation to see if we can move on and start writing terraform. For the test we’ll just pull down my test repo to your workstation:
Git clone https://github.com/jakewatkins/jkwTerraformAzure.git
Now we’ll do some actual terraform. CD to the demo-terraform directory and run the terraform config script we just wrote so our environment variables will be set. Next, initialize the workspace:
terraform init
Then we create a new workspace called dev
terraform workspace new dev
Now we’ll do a terraform apply.
terraform apply -auto-approve
You should see a bunch of status information telling you want Terraform is going to do and then information telling you what it is creating. When it’s all done, you can open your Azure console to see the resource group you created.
That’s it. You’re ready to start working with Terraform and Azure.