DevOps – Infrastructure as Code on Azure Platform with Hashicorp Terraform Part 1

At Cheval Partners, we believe that infrastructure as code is essential to get most out of your cloud platforms. Infrastructure as code is also required to implement immutable infrastructure. Hashicorp has a suite of products that make it easy to implement infrastructure as code on numerous public and private cloud platforms. We have been leveraging Hashicorp tools for the past year for AWS implementations. We have many clients that are deploying applications on Azure Platform. We were unable to use Hashicorp tools with Azure because Azure Resource Manager support was missing. We were ecstatic to read this announcement from Hashicorp that Packer and Terraform now support Azure Resource manager.

https://www.hashicorp.com/blog/azure-packer-terraform.html

I will use this blog post to introduce you to using Terraform to provision Azure Resource Manager resources.

Imperative or Declarative

There are two different ways in which you can implement infrastructure as code.

Imperative

Imperative method uses scripts or code to provision your services. Here are a few examples:

AWS: You are using bash scripts that leverage AWS CLI. Another example of AWS is the excellent AWS python SDK boto3.

Azure: You use Azure PowerShell cmdlets to provision the services

Declarative

Here you are defining templates for your infrastructure. Some examples of this are:

AWS: CloudFormation

Azure: Azure Resource Manager

Terraform

Both Imperative and Declarative method of implementing infrastructure as code are better than manual error prone resource provisioning. However with imperative method you are responsible for deploying services in correct order and recovering from failures. As the number of services grows the scripts become brittle.

Terraform

Terraform provides a common configuration to launch infrastructure — from physical and virtual servers to email and DNS providers. Once launched, Terraform safely and efficiently changes infrastructure as the configuration is evolved.

Simple file based configuration gives you a single view of your entire infrastructure. Terraform is a declarative method of resource provisioning.

Terraform can be used to provision resources in Azure, AWS, Google, Openstack, Digital Ocean and many other providers and services. You can see the complete list of supported providers here:

https://www.terraform.io/docs/providers/index.html

Terraform uses Hashicorp configuration language(HCL) to define the infrastructure. Once you learn HCL, you will be able to use many different providers for public and private clouds to provision infrastructure.

I want to take this opportunity to make a case for Terraform. I have heard many different arguments against using Terraform.

1. Not multi-cloud: Even if you are not provisioning infrastructure in multiple clouds you will find learning HCL to be easier and intuitive. It will also give you an ability to provision infrastructure in other clouds in future.

2. Can’t keep up with cloud provider: I heard that most of the cloud providers(AWS, Azure) are constantly adding new services. So tools like Terraform will fall behind. However, open source community and Hashicorp has done an excellent job of keeping up and in some cases staying ahead of the cloud provider. This is especially true for their AWS provider. In mid December AWS released NAT Gateway. By the time I went to the google group for Terraform: https://groups.google.com/forum/#!forum/terraform-tool somebody had already asked about Terraform AWS Nat Gateway suppord and they were told that support is coming.  AWS Nat Gateway was supported by Terraform even before AWS CloudFormation.

4. What if a certain feature is not supported in Terraform? Terraform allows you to call AWS CloudFormation or ARM Templates, and you can also use a custom script that invokes CLI to provision resources that are not supported by Terraform. You can implement the feature and contribute it back to the community. If you still have concerns check out their change log and release schedule here: https://github.com/hashicorp/terraform/blob/master/CHANGELOG.md.

They have been releasing new features and services on a monthly basis.

5. What happens if Hashicorp ceases to exist? Hashicorp is a startup but most of their tools are open source. Vagrant is one of their first tool and it has been around for long time. No one can predict the future but the community is active and engaged and supporting Terraform. Containers, Microservices, Multi-cloud deployments are here to stay and Hashicorp tools can help.

Documentation

Azure Provider for Hashicorp is located here:

https://www.terraform.io/docs/providers/azurerm/index.html

Use cases: https://www.terraform.io/intro/use-cases.html

Terraform vs Other Software: https://www.terraform.io/intro/vs/index.html

Installation

Terraform is an open source tool developed in go language. Since it was developed in go language, it is can run on 6 different operating systems including Windows and Mac OS. Same is true for other Hashicorp tools as well. We will cover those in future blog posts.

Installation is as simple as downloading the version suitable for your operating system from here: https://www.terraform.io/downloads.html

It is an executable so you will just have to add it to your path to make it convenient for you to run it.

Verify installation

I installed Terraform on Windows I opened a cmd window and ran

terraform –version

to view its version. I got the following output.

image

Azure Credentials for Terraform

The process to get Azure credentials for Terraform is a bit convoluted.

You need the subscription_id, client_id, client_secret, tenant_id.

1:  # Configure the Azure Resource Manager Provider  
2:  provider "azurerm" {  
3:   subscription_id = "..."  
4:   client_id    = "..."  
5:   client_secret  = "..."  
6:   tenant_id    = "..."  
7:  }  

 

You can use the new Azure Portal http://portal.azure.com to find subscription_id. You can browse the list of subscriptions and get the subscription_id.

image

You can get the value of client_id, client_secret and tenant_id using these steps:

  1. Creating Azure Active directory application
  2. Creating an authentication key
  3. Setting delegated permissions
  4. Assigning application to a role that has appropriate permissions to provision resources.

You will not have to perform this setup frequently so it may be easiest to use the portal.

https://azure.microsoft.com/en-us/documentation/articles/resource-group-create-service-principal-portal/

Here are the instructions If you want to use PowerShell to perform these steps:

https://azure.microsoft.com/en-us/documentation/articles/resource-group-authenticate-service-principal/

Show me HCL

The following script creates a new resource group and provisions a virtual network.

Lines 10-13 specify the name of the new resource group and its location.

Lines 15-25 define an ARM virtual network named “productionNetwork”. It also defined three subnets.

1:  # Configure the Azure Resource Manager Provider  
2:  provider "azurerm" {  
3:   subscription_id = "..."  
4:   client_id    = "..."  
5:   client_secret  = "..."  
6:   tenant_id    = "..."  
7:  }  
8:    
9:  # Create a resource group  
10:  resource "azurerm_resource_group" "production" {  
11:    name   = "production"  
12:    location = "West US"  
13:  }  
14:    
15:  # Create a virtual network in the web_servers resource group  
16:  resource "azurerm_virtual_network" "network" {  
17:   name        = "productionNetwork"  
18:   address_space    = ["10.0.0.0/16"]  
19:   location      = "West US"  
20:   resource_group_name = "${azurerm_resource_group.production.name}"  
21:    
22:   subnet {  
23:    name      = "subnet1"  
24:    address_prefix = "10.0.1.0/24"  
25:   }  
26:    
27:   subnet {  
28:    name      = "subnet2"  
29:    address_prefix = "10.0.2.0/24"  
30:   }  
31:    
32:   subnet {  
33:    name      = "subnet3"  
34:    address_prefix = "10.0.3.0/24"  
35:   }  
36:  }  
37:    

 

After saving the script you can first execute the statement

terraform plan

You can review the full help for terraform plan command here:

https://www.terraform.io/docs/commands/plan.html

This command examines your configuration and your current state. It lists resources it will create, destroy or modify. It is one of the best features of Terraform. Terraform allows you to organize your configuration into modules. My current example does not use modules. If you were using modules you will need to run the command:

terraform plan –module-depth=-1

As you can see from the output below it shows that a new resource group will be provisioned. It also shows that a new virtual network with 3 subnets will be provisioned.

image

terraform apply

If the plan shows you the services, you wanted to provision the next step is to provision the infrastructure. You need to use apply command to provision or update your infrastructure.

terraform apply –help

shows you various command line options that are available.

You can also see the detailed help here:

https://www.terraform.io/docs/commands/apply.html

image

terraform apply output is shown above. It shows that a new resource group and virtual network. You can use the portal and verify that these resources were created successfully. It also shows that the state of your infrastructure was saved successfully to terraform.tfstate file. This file needs to be saved and checked into source control. There are other options to store this file in a central location. They will be covered in a future blog post.

Remove the infrastructure

You can delete your entire infrastructure provisioned by terraform using the command.

terraform destroy command is used to destroy the infrastructure. You are prompted to confirm before the actual destruction takes place.

 

image

 

Closing Thoughts

I have introduced Terraform and shown how you can use it to provision resources on Azure Platform. Terraform Azure Resource Manager provider is less than a week old. It does not cover all the services yet. With their monthly releases, more services will be supported in near future. If you find issues or have feature requests you can log them here:

https://github.com/hashicorp/terraform/issues

If you want to contribute you can make a pull request here:

https://github.com/hashicorp/terraform

In part 2 of this blog post series I will added virtual machine, public IP’s and manage DNS using Azure DNS.

This entry was posted in ARM, Automation, Azure, DevOps, Hashicorp and tagged , , , , . Bookmark the permalink.
  • Saravanan R

    Nice! Good article to start learning Terraform. Thank you

    • http://rajinders.com rajisingh

      Saravanan,

      Are you at Honeywell?
      We are doing a project at Honeywell as well.

      We love Terraform.

      Raj