Terraform on Azure WebApps- Part I

This is going to be the first part of my Terraform Adventure in Azure series. The first time I played with Terraform last year, App Services [Web Apps main concern here] were not supported yet, PAAS is a better fit for my clients mostly for Azure,  so I thought either learn Go, write the resources, or be lazy and wait another year. Recently, this resource added, and looks more production ready! While I will cover basics, my aim is to get something more than a POC, and I will cover the design/security/automation considerations for larger scale projects.

  1. Prerequisites
  2. Terminology
  3. Basic ResourceGroup-StorageAccount
  4. Managing Outputs
  5. Backend – Keeping State


Extensions: mandatory:Terraform
for syntax highlighting, optional:
Terraform Snippets Generator for coding faster]
b. Terraform
Download the binary  to a system-wide place [/usr/bin, c:\terraform], and add this path to your path environment variable.
c. Git
c. Azure subscription [FreePass]
d. A service principal ID, and a key/secret.
My previous post on this.

2. Terminology:

a. Design:

Terraform has an absolutely easy to learn/use DSL called HashiCorp Configuration Language Each type of configuration you want to use is called a provider such as AzureRM, AWS, VMWare. Each component for the providers to be configured is called a resource such as resource group, virtual machine.


Terraform takes action within a folder. A classical Terraform workspace would have these files, extensions, and folders:

  • main.tf: Your starting point is the main.tf file which has the provider definition, and all resources related. You can split this into multiple .tf files, such as security.tf
  • variables.tfvarsYou call variables from vars.tf file along with variables.tfvars, which I will cover in part II in detail, you don’t want to check your credentials to any source control yet
  • outputs.tf: Any output is defined with output keyword, you can collect them together in the outputs.tf file. On the window output of tf apply we can see these values, which is section 4 below.
  • terraform.tfstate: Terraform keeps track of your resources by this file on the main folder [if you have not configured remote state/backend], which contains all the information about your published environment as well as a backup file to compare terraform.tfstate.backup.
  • .terraform/:This is the folder generated by  terraform init.It may serve 3 functions:[possibly more, this is all I know today:)]
    a. plugins folder
    1.  contains plugin(s) for your provider(s) as the version is mentioned in provider stanza.
    2.  lock.json file to isolate your update on target resourceslock.json
    b. terraform.state file if you are keeping your state as a backend/remotely.
  • terraform.plan: For automation, you may want to separate the output of the plan action, and input of the terraform apply action. It is common to use  this file [with extra convient tags in the name] between these steps. For more on automation.

b. Action

Our main command is terraform. There are 5 main subcommands I will cover here: init, plan, apply, graph, destroy

  1. terraform init: initialise the state by checking available plugins [azurerm plugin in our scenario] and downloads the latest version unless you tell explicitly in the provider snatza. If you want to declare explicitly, you can either:
    – version = “0.2”, will download version 0.2 plugin,
    – version = “~> 0.2”, will download the latest available version [0.3.3 as of today]Alternatively, you can prepopulate the folder:
    terraform init -plugin-dir=/terraform.d/plugins/OS_ARCH
    Also, avoiding the download of missing plugins:
    terraform init -get-plugins=false
  2. terraform plan: Decides which files to be created/destroyed comparing to an existing state. In our resource group example, there is a single component change as addition, so it is here:
    Plan: 1 to add, 0 to change, 0 to destroy.
  3. terraform apply : Applies the proposed changes with a confirmation message: yes/no.
    For automation purposes, you can use -auto-approve=true flag [with extra care!].
  4. terraform graph: Generates a digraph in DOT language which can be visualised by a tool like GraphVizOnline.
  5. terraform destroy: Removes all items in the planned stage. No turning back from this point on….

3. Basic Resources:

Now, we want to create storage account.

We will also need some outputs to be used to configure the backend, thus we put the values to outputs.tf file.

terraform plan -out terraform.plan
terraform apply terraform.plan


4. Backend as State Management

Terraform by default was caching your state in local via .tfstate and .tfstate.backup files, which is a major deal breaker for automation and multiple people working on the same file, leave alone all secrets being explicit on the precious file. With PR https://github.com/hashicorp/terraform/pull/11286, Terraform supports Backend as a mean to control remote state easily.
Backend keeps your remote state safe in a central place. Azure is one of the providers, and Azure Storage does not provide the versioning as S3, but still escalates the security issue to a different level.
To use Azure backend, we need

  1. Backend stanza, either added to the main.tf/any tf file, or even its own tf file.
  2. A parameter file params.tfvars, which has the first 4 values from the output. beparams_accesskey

When we run
terraform init -backend-config=params.tfvars
We can see that our configuration has moved to Azure, and terraform.tfstate file is empty, and a new state file created in .terraform/ folder. (Those who are still with me, yes, we could do -force-copy to avoid prompt.)

And ta da, your state is all in the Azure storage container, downloadable, secure! I hope it was a bit deep insight on Terraform setup. How is your setup different than mine?  containerstate