Terraform for Azure: Basics (1)

Terraform

Introduction and Prerequisites

Introduction

I’ve been architecting Microsoft Azure platforms for a good few years now, and whilst I’ve been fully aware of the benefits of Infrastructure as Code (IaC), I’m not a developer (back in the 1980s I used to copy code from magazines into my Sinclair ZX81, but that’s about it), and any deployments I’ve done myself have been via the portal. I’ve left it mainly to expert DevOps consultants to do the real heavy lifting where code has been required.

I’ve realised now however that I’ve got to get my backside in gear and figure out at least the basics of IaC, before I’m left behind and unable to design or deploy any solutions.

I’m starting with HashiCorp Terraform, because it’s widely adopted, well known and has great Azure support.

This series of blog posts is as much a personal reference for me to fall back on as it is general advice to others. If it helps you, brilliant, feel free to let me know in the comments! The content is unlikely to be best practice, or technically in-depth, but it’s defining my own journey into the world of Terraform code and DevOps for Azure, and should give anyone reading the background needed to be able to deploy simple resources in a repeatable manner, and build from there.

Before I start, I need to give credit to a friend and colleague, James Meegan, for his original documents that helped me on this journey and put me on the path to writing this series.

Prerequisites

So where does one start learning how to deploy resources to Microsoft Azure using code, and how to troubleshoot that code? For me, I need to learn while I “do”. I’m not great at picking things up from watching videos or reading text, I need to actually physically do something in order for my brain to take it in. That means just getting the tools in place and making a start. Other people learn in different ways, and you could do worse than take out a free trial subscription to PluralSight and follow one of their introduction to Terraform courses. There are also other resources such as Udemy and of course the ubiquitous YouTube.

By following this series, you should be able to pick up the basics, understand all the moving parts, understand, work with and troubleshoot IaC environments, and hopefully, have a little fun. You’ll get to understand some basics of the online version of Azure DevOps, and some insight into the basics of Terraform. Each part will build on the previous one to build your skillset, your understanding and your confidence. I’ve tried to write in plain English, for the non-developer, and help you to understand why something is done rather than just giving a list of instructions to follow. It’s worth noting that all the technologies used in this series change with time, features are added and deprecated, so by the time you read it things may have moved on slightly.

Computer

OK, so you need a computer – that’s fairly obvious, but your computer will also need the following tools and configuration if you want to follow along with how I’m learning. I’m using Windows (11), and all the instructions are based on that, but some things may vary if your operating system is different. I’m not going to go into the basics of how to install an app or change windows settings – if you’re not at that stage, it’s worth getting up to speed first.

PowerShell

Make sure you have PowerShell 7 or later installed. It comes with additional Azure cmdlets. It’s worth understanding how to use PowerShell, and how to automate with it, but not necessary for these articles.

Terraform

As Terraform is the IaC tool of choice for this series, you’re going to need to download that. It’s platform agnostic so learning about this will help you whether you work with Azure, AWS, GCP or one of the many other public clouds. Get and extract the Terraform executable from the HashiCorp website and put it somewhere on your disk that you can easily reference.

Add Terraform to the system path

In your system properties, edit the “Path” system variable to add the location of the Terraform executable that you extracted earlier.

Install Visual Studio Code

VS Code is my tool of choice for learning IaC with Terraform and Azure, but you might want to use a different one. All this series assumes you are using VS Code. It’s free, widely used, and there’s lots of information out there on how to use it if you fancy digging a little deeper. Download from here and install.

Add the Terraform extensions to VS Code

Open VS code and select the extensions tab (or press <ctrl>+<shift>+<x>). In the search bar type “Terraform” then click the install icon for both “HashiCorp Terraform” and “Azure Terraform”:

Add the PowerShell extension to VS Code

In the extensions tab, search for “PowerShell” and install that extension:

Open a terminal and check the Terraform Version

In VS Code, select “View / Terminal”, then click in the resulting terminal window and type “Terraform version” (note that the word “version” is case sensitive):

GIT

Git is used for code management and source control. It helps keep track of code changes, allowing you to recall older versions and roll back if required. It also allows collaboration on the same code by multiple people. It is the software tool I’ve chosen to create repositories (repos) in Azure DevOps, and synchronising or cloning those repositories to your computer. It’s another tool that is worth learning more about, but again that’s not required for this series. Download from here and install (I found the defaults were fine).

Your computer is now ready to go. You’ve got all the necessary tools installed and configured. It’s time to move on to the cloud…

Azure

Subscription

Whilst Terraform supports multiple platforms, the focus of this series is Microsoft Azure, which means you will need a subscription to connect with and deploy your resources into. If you don’t already have one, there are usually free trials around, after which you can convert to pay as you go (which I find is very cheap for learning purposes). Have a look here for the latest subscription offers, and sign up. It’s worth thinking about what naming conventions you might want to use, as we can take advantage of Terraform’s ability to build resource names based around those.

State File Storage Account

Terraform understands if resources already exist in your target environment and won’t create duplicates if you apply the same deployment configuration multiple times. It tracks those resources using a “state” file, which contains all those resources’ relevant details. The file is created automatically when we initialise Terraform (which we’ll cover in a later post) and has the file extension of .tfstate. If you have multiple environments in your deployment (e.g. “DEV” and “TEST”, there may be multiple state files created. While these state files can be stored locally on your computer, best practice and collaboration require that it is stored within your Azure environment.

To host our state file(s), we need a Storage Account in Azure, which has a dependency on a resource group. These will be created manually (command line or portal, I’ll be using the portal) for the purpose of this series, but it is possible to do this using code.

Create the Resource Group

Again, it’s worth considering your naming convention. Also, think about which Azure region(s) you want to use while learning. I’m in England so I choose the UK South and UK West regions, with UK South being my primary because it has more services (e.g. availability zones) than UK West.

Log into the portal and create a resource group within your subscription:

Create the Storage Account

In the resource group you just created, create an Azure Storage Account. Think about the naming convention for this storage account, and also consider Microsoft’s best practice recommendations when creating storage accounts. For the short term, public access will be allowed to the storage account, but we will be using IaC to automate access to the account in a later post. Within the storage account, create a container for the state file(s):

Azure DevOps

Microsoft Azure DevOps is the Continuous Integration / Continuous Deployment (CI/CD) tool that I’ve chosen for this series. Others are available, and you may prefer something like GitHub, however all the specific instructions in these posts will refer to Azure DevOps.

Create a new DevOps organisation (if you don’t already have one) at https://dev.azure.com. When you have your organisation, create a new project, ensuring that the visibility is private:

Terraform code is deployed to Azure using Pipelines in the DevOps project. If this is a new DevOps organisation that has never had pipelines run against it, you must advise Microsoft so that they don’t prevent them from running, which can take up to 24 hours. Do this by filling in the form here.

Add the Terraform Plug-In

When you have your project, go here to add the Terraform plug-in to Azure DevOps:

Again, although it’s not necessary to follow this series, it’s worth taking a look at the Microsoft Learn modules to understand what Azure DevOps is and how it works.

Service Principal

To give your Azure DevOps project permissions to deploy resources to your Azure subscription, you will require a managed identity, created in your Azure tenant (the Entra ID directory that hosts your subscription), known as a service principal. This service principal is best created in a command window within your Azure tenant as this gives it the opportunity to connect to multiple subscriptions, rather than just one if created within Azure DevOps. I will use a cloud shell in my portal, but you might want to use a remote command window. Enter the command:

az ad sp create-for-rbac -n "http://terraform-series-sp" --role="Contributor" --scopes="/subscriptions/<subid>"
* where <subid> is the id of your subscription

Take a note of the details that have been output and keep them secure. You will need them in order to create your service connection in Azure DevOps, and they can grant anybody who has visibility of them access to your subscription.

Service Connection

The last of our prerequisites is to connect our DevOps project to our subscription. This is done by creating a service connection within the project, using the service principal details created above.

Within your DevOps project, select “Project Settings” and then “Service Connections”:

After clicking “Create service connection”, select “Azure Resource Manager” and click “Next”:

Select “Service principal (manual)” and click “Next”:

This is where we enter the details of our service principal that were generated in the cloud shell earlier. Note that the fields have different names, and map to:

  • Subscription ID – the IDsubscription you’re connecting to
  • Subscription Name – that subscription’s name
  • Service Principal ID – the “appID” value for the service principal
  • Service Principal Key – the “password” value for the service principal
  • Tenant ID – the ID of the Entra ID tenant

After entering all the relevant information, click “Verify”:

When verification is marked as succeeded, enter a service connection name as per your own naming conventions, allow permissions to all pipelines then click “Verify and save”:

This service connection will only grant access to a single subscription, however multiple service connections can be created using the same service principal, as long as they are all part of the same Entra ID tenant.

Conclusion

And that’s it! Congratulations, your prerequisites are all there. You can start building pipelines, creating code and deploying resources. The next post in this series will discuss repositories and pipelines, creating YAML files and all sorts of other fun things!

Until next time…

The Zoo Keeper!

By TheZooKeeper

An Azure Cloud Architect with a background in messaging and infrastructure (Wintel). Bearded dog parent who likes chocolate, doughnuts and Frank's RedHot sauce, but has not yet attempted to try all three in combination!