Prerequisites before all of this.
Have a basic understanding of how to use Terraform and what it does. This is covered pretty well in the Hashicorp Docs here (single page read <5 minutes) and if you have a LinkedIn Learning account check out my Terraform course “Learning Terraform“.
Beyond that some basic CLI/terminal knowledge, understand where environment variables (as I detail here, here, and here for some starters) are, and miscellaneous knowledge. You’ll also need knowledge and user experience with Git. Most of these things I’ll detail explicitly but otherwise I’ll either link to or provide context for additional information throughout the article.
1: Terraform
Download
You’ll need to first install Terraform and make it available for use on your machine. To do this navigate over to the Hashicorp TerraformTerraform site and to the download section. As of this time 0.12.6 is available, and for the foreseeable future this version or versions coming will be just fine.
Install
You’ll need to unzip this somewhere in a directory that you’ve got the path mapped for execution. In my case I’ve setup a directly I call “Apps” and put all of my CLI apps in that directory. Then add it to my path environment variable and then terraform becomes available to me from any terminal wherever I need it. My path variable export on Linux and Mac look like this.
[code]export PATH=$PATH:/home/adron/Apps[/code]
Now you can verify that the Terraform CLI is available by typing terraform
in any terminal and you should get a read out of the available Terraform commands.
For those of you who might be trying to install this on the WSL (Windows Subsystem for Linux), on Windows itself, or some variance there is specific instructions for that too. Check out Hashicorp’s installation instructions for more details on several methods and a tutorial video, plus the Microsoft Docs on installing Terraform on the WSL.
Verification Checklist
- Terraform is installed and executable from the terminal in whichever folder on the system.
2: Azure CLI
For this tutorial, there are several ways for Terraform to authenticate to Azure, I’ll be using the Azure CLI authentication method as detailed in this tutorial from Hashicorp. There are also some important notes about the Azure CLI. The Azure CLI method in conjunction with the AzureRM Terraform Provider is used to build out resources using infrastructure as code paradigms, because of this it is important also to insure we have the right versions of everything to work together.
The Caveats
For the AzureRM, which will be downloaded automatically when we setup the repository and initialize it with the terraform init
command, we’ll want to make sure we have version 1.20 or greater. Previous versions of the AzureRM Provider used a method of authorizing that reset credentials after an hour. A clear issue.
Terraform also only support authenticating using the az
CLI and it must be avilable in the path of the system, same as the way terraform
is available via the path. In other words, if both terraform
and az
can be executed from anywhere in the terminal we’re all set. Using the older methods of Powershell Cmdlets or azure
CLI methods aren’t supported anymore.
Authenticating via the Azure CLI is only supported when using a “User Account” and not via Service Principal (ex: az login --service-principal
). This works perfectly since these environments I’m building are specifically for my development needs. If you’d like to use this example as a more production focused example, then using something like Service Principals or another systems level verification, authentication, and authorization model should be used. For other examples check out authentication via a Service Principal and Client Secret, Service Principal and Client Certificate, or Managed Service Identity.
Installing
To get the Azure CLI installed I followed the manual installation on Debian/Ubuntu Linux process. For Windows installation check out these instructions.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Update the latest packages and make sure certs, curl, https transport, and related packages are updated. | |
sudo apt-get update | |
sudo apt-get install ca-certificates curl apt-transport-https lsb-release gnupg | |
# Download and install the Microsoft signing key. | |
curl -sL https://packages.microsoft.com/keys/microsoft.asc | \ | |
gpg –dearmor | \ | |
sudo tee /etc/apt/trusted.gpg.d/microsoft.asc.gpg > /dev/null | |
# Add the software repository of the Azure CLI. | |
AZ_REPO=$(lsb_release -cs) | |
echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $AZ_REPO main" | \ | |
sudo tee /etc/apt/sources.list.d/azure-cli.list | |
# Update the repository information and install the azure-cli package. | |
sudo apt-get update | |
sudo apt-get install azure-cli |
Login & Setup
az login
It’ll bring up a browser that’ll give you a standard Microsoft auth login for your Azure Account.
When that completes successfully a response is returned in the terminal as shown.
Pieces of this information will be needed later on so I always copy this to a text file for easy access. I usually put this file in a folder I call “DELETE THIS CUZ SECURITY” so that I remember to delete it shortly thereafter so it doesn’t fall into the hands of evil!
For all the other operating systems and places that the Azure CLI can be installed, check out the docs here.
Once logged in a list of accounts can be retrieved too. Run az account list
to get the list of accounts available. If you only have one account (re: subscriptions) then you’ll just see exactly what was displayed when you logged in. However if you have other peripheral information, those accounts will be shown here.
If there is more than one subscription, one needs selected and set. To do that execute the following command by passing the subscription id. That’s the second value in that list of values above. Yes, it is kind of odd that they use account and subscription interchangeably in this situation, and that subscription id isn’t exactly obvious if this data is identified as an account and not a subscription, but we’ll give Microsoft a pass for now. Suffice it to say, account id and subscription id in this data is the stand alone id field in the aforementioned data.
az account set --subscription="id"
where id is subscription id, or as shown in az account list
the id there, whatever one wants to call it.
Configuring Terraform Azure CLI Auth
To do this we will go ahead and setup the initial repository and files. What I’ve done specifically for this is to navigate to Github to the new repository path https://github.com/new. Then I selected the following options:
- Repository Name: terraform-todo-list
- Description: This is the infrastructure project that I’ll be using to “turn on” and “turn off” my development environment every day.
- Public Repo
- I checked Initialize this repository with a README and then added the .gitignore file with the Terraform template, and the Apache License 2.0.
This repository is now available at https://github.com/Adron/terraformer-todo-list. All of the steps and details outlined in this blog entry will be available in this repository plus any of my ongoing work on bastion servers, clusters, kubernetes, or other related items specific to my development needs.
With the repository cloned locally via git clone git@github.com:Adron/terraformer-todo-list.git
there needs to be a main.tf
file created. Once created I’ve added the azurerm provider block provider "azurerm" { version = "=1.27.0" }
into the file. This enables Terraform to be executed from this repository directory with terraform init
. Running this will pull down the azurerm provider dependency. If everything succeeds you’ll get a response from the command.
However if it fails, routinely I’ve ended up out of sync with Terraform version vs. provider version. As mentioned above we definitely need 1.20.0 or greater for the examples in this post. However, I’m also running Terraform at version 0.12.6 which requires at least 1.27.0 of the azurerm or better. If you see an error like this, it’s usually informative and you’ll just need to change the version number so the version of Terraform you’re using will pull down the right version.
Next I run terraform plan
and everything should respond with no change to infrastructure requested response.
At this point I want to verify authentication against my Azure account with my Terraform CLI, to do this there are two additional fields that need to be added to the provider: subscription_id and tenant_id. The configuration will look similar to this, except with the subscription id and tenant id from the az account list
data that was retrieved earlier when setting up and finding the the Azure account details from the Azure CLI.
Run terraform plan
again to see the authentication results, which will look just like the terraform plan
results above. With this done there’s just one more thing to do so that we have a good work space in which to work with Terraform against Azure. I always, at this point of any project with Terraform and Azure, setup a Resource Group.
Verification Checklist
- Terraform is installed and executable from the terminal in whichever folder on the system.
- Azure CLI is installed and executable from the terminal in whichever folder on the system.
- The Azure CLI has been used to login to the Azure account and the subscription/account set for use as the default subscription/account for the Azure CLI commands.
- A repository has been setup on Github (here) that has a main.tf file that I used to create a single Azure Resource Group in which to do future work within.
3: Azure Resource Group
Just for clarity, a few details about the resource group. A Resource Group in Azure is a grouping that should share the same lifecycle, which is exactly what I’m aiming to do with all of these resources on a day to day basis for development. Every day I intend to start these resources in this Resource Group and then shut them all down at the end of the day.
There are other specifics about what exactly a Resource Group is, but I’ll leave the documentation to be read to elaborate further, for my mission today I just want to have a Resource Group available for further Terraform work. In Terraform the way I go about creating a Resource Group is by adding the following to my main.tf
file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
provider "azurerm" { | |
version = "=1.27.0" | |
subscription_id = "00000000-0000-0000-0000-000000000000" | |
tenant_id = "11111111-1111-1111-1111-111111111111" | |
} | |
resource "azurerm_resource_group" "adrons_resource_group_workspace" { | |
name = "adrons_workspace" | |
location = "West US 2" | |
tags = { | |
environment = "Development" | |
} | |
} |
Run terraform plan
to see the changes. Then run terraform apply
to make the changes, which will need a confirmation of yes
.
Once I’m done with that I go ahead and issue a terraform destroy
command, giving it a yes
confirmation when asked, to destroy and wrap up this work for now.
Verification Checklist
- Terraform is installed and executable from the terminal in whichever folder on the system.
- Azure CLI is installed and executable from the terminal in whichever folder on the system.
- The Azure CLI has been used to login to the Azure account and the subscription/account set for use as the default subscription/account for the Azure CLI commands.
- A repository has been setup on Github (here) that has a main.tf file that I used to create a single Azure Resource Group in which to do future work within.
- I ran
terraform destroy
to clean up for this set of work.
4: Using Environment Variables
There is one more thing before I want to commit this code to the repository. I need to get the subscription id and tenant id out of the main.tf file. One wouldn’t want to post their cloud access and identification information to a public repository, or ideally to any repository. The easy fix for this is to implement some interpolated variables to pull from environment variables. I can then set the environment variables via my startup script (such as .bash_profile or .bashrc or even the IDE I’m running the Terraform from like Intellij or Webstorm for example). In that script setting the variables would look something like this.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export TF_VAR_subscription_id="00000000-0000-0000-0000-000000000000" | |
export TF_VAR_tenant_id="11111111-1111-1111-1111-111111111111" |
Note that each variable is prepended with TF_VAR
. This is the convention so that Terraform will look through and pick up all of the variables that it needs to work with. Once these variables are added to the startup script, run a source ~/.bashrc
(linux) or source ~/.bash_profile
(on Mac) to set those variables. For Windows check out this to set the environment variables. With that set there are a few more steps.
In the repository create a file named variables.tf
and add the two variables variable "subscription_id" {}
and variable "tenant_id" {}
. Then in the main.tf
file change the subscription_id and tenant_id fields to be assigned variables like subscription_id = var.subscription_id
and tenant_id = var.tenant_id
. Now run terraform plan
and these results should display.
Now the terraform apply
can be applied or terraform destroy
to create or destroy the Resource Group. The last step now is to just commit this infrastructure code with the variables now removed from the main.tf file.
git add -A
git commit -m 'First executable resource.'
git rebase
to pull in all the remote default files and such and merge those with the local additions.
git push -u origin master
then to push the changes and set the master local branch to track with the remote branch master.
Verification Checklist
- Terraform is installed and executable from the terminal in whichever folder on the system.
- Azure CLI is installed and executable from the terminal in whichever folder on the system.
- The Azure CLI has been used to login to the Azure account and the subscription/account set for use as the default subscription/account for the Azure CLI commands.
- A repository has been setup on Github (here) that has a main.tf file that I used to create a single Azure Resource Group in which to do future work within.
- I ran
terraform destroy
to clean up for this set of work. - Private sensitive data has been moved from the main.tf file into environment variables so that it isn’t copied to the repository.
- A variables.tf file has been added for the aforementioned variables that map to environment variables.
- The code base has been committed to Github at https://github.com/Adron/terraformer-todo-list.
- Both
terraform plan
andterraform apply
deploy as expected andterraform destroy
removes infrastructure cleanly as expected.
Next steps coming soon!
You must be logged in to post a comment.