Reading Time: 6 minutes

The past few years, apart from DevOps there is another buzzword that is been heard more and more frequently in IT groups and events and is supposed to be the holy grail of deploying infrastructure resources nowadays. That buzzword is Infrastructure as Code or IaC as we like to acronymize everything in the IT realm.

As any quest for a holy grail, you need to be prudent in order not to get caught up in an endless chase. But let’s start by defining what is IaC.

What is IaC?

Infrastructure as code is the process of managing and provisioning computer data centers through machine-readable definition files, rather than physical hardware configuration or interactive configuration tools.

Wikipedia

In the past, when a business wanted to launch a new application the IT team needed to buy the related hardware to support the app based on the insight either from a senior developer or in best cases the architect of the application. Then the appropriate person(s) would deploy the servers either rack or as stand-alone and configure the operating system and its parameters for the app to work. The network layer was also part of this process as with no network there’s not much to work on.

The problem: part I

This process although worked for many decades (and still does) it is not scalable, reliable and fast enough for the fast-paced environment the companies compete today.

Enters Cloud computing.

The solution: part I

Cloud computing takes away the scalability and reliability burdon as well as the fast-pace needed especially for large scale projects or projects that the load could become unpredictable.

It is easy to deploy hundreds of VMs in a matter of a few clicks in order to withstand a load of i.e. a retail e-commerce shop on the first day of the season sales or a Black Friday.

At the same time cloud gives you the advantage of deploying the resources you need in a manner that suits your SLA in more than 3 or 4 9s or even higher depending on how much you are willing to spend.

The problem: part II

When deploying resources in the on-premises or cloud environment, since it is a reproduction of the same steps with different parameters (hardware, network, configuration, etc.) it is a process that can become error-prone and this can bring extra time and effort for a project to hit the market.

Enters Infrastructure as Code.

The solution: part II

By utilizing Infrastructure as Code (IaC) in our operations, we take away the error from a repetitive task for deploying resources in our cloud computing environment. It is a way to help us define in a descriptive way the resource we need to deploy and run our applications. It becomes more of a need when we have multiple data centers to perform the same operations and we have different sets of teams to manage and configure the same environment in another region of the world.

IaC makes a perfect match for CD oriented DevOps operating organization. It can become part of the deploy pipeline for creating a staging environment to roll out a new application version for our Q&A team to check. It can be an integrated member of the cycle and it is a way to maintain clarity on the infrastructure because it makes the deployment process repeatable and consistent.

Environment drifting is something that all companies have faced, no matter the size, and there is no easy way out unless IaC is used. Over time, environments become unique and difficult to reproduce from staging to UAT to production because of tweaking in different phases of the application lifecycle. With IaC different teams test the code in a production-like environment from the very beginning of the lifecycle till the production time.

The tooling

Now, there are different IaC tools to help one along the way to the quest but differ depending on the vendor one uses. For completeness, I will specify some of the most famous ones here and then I will go on with the Microsoft specific.

  • Azure ARM Templates
  • AWS CloudFormation
  • Terraform
  • Chef
  • Puppet
  • RedHat Ansible

There are differences between these tools like if it’s declarative or procedural or if it’s immutable or mutable and the architecture of each tool. The choice of tool can vary i.e. based on the platform you target, the team’s background (dev or admin), etc.

Spotlight on: Azure ARM Templates

Azure ARM Templates is the tool for delivering IaC the Microsoft-way. It integrates perfectly with Azure DevOps and the whole stack of Azure and specifically the Azure Resource Manager deployment model, hence the name.

ARM Templates offer an idempotent way of deploying and managing Infrastructure as Code through a declarative JSON formatted file that can be versioned and stored in a Git repo locally or Azure DevOps that a team shares and collabs upon.

You can author the files using Visual Studio Code that is free and cross-platform (link) and use the following extensions:

  • Azure Resource Manager (ARM) Tools (link) provides language support for ARM deployment templates and template language expressions
  • Azure Resource Manager Snippets (link) various snippets to aid in the fastest development of the templates
  • ARM Template Viewer (link) displays the JSON ARM template file in a visual format with the official Azure icons and how the resources link to each other
  • armviz.io (link) a website that toggles between visualizing an ARM Template file and the JSON code behind it. It also gives you the flexibility to load an ARM Template for the GitHub Azure repo with the Quickstart templates library.

An ARM Template has the following elements:

Element nameRequiredDescription
$schemaYesLocation of the JSON schema file that describes the version of the template language
contentVersionYesThe version of the template i.e. 1.0.0.0. This is user-provided and can bare any value that is significant to the version of the document.
apiProfileNoServes as a collection of API versions for resource types instead of defining an API version for each resource.
parametersNoValues provided at run-time to customize the resources deployed defined in the resources element of the JSON file
variablesNoAs normal programming variables used to ease and simplify the template and the expression within the template file
resourcesYesAzure resource types that are deployed or updated in a resource group or subscription
outputNoValues that are returned after the deployment of the template has finished and can be used as input parameters in other ARM templates when in used in linked templates.

Below an empty ARM template with all the elements:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "",
  "apiProfile": "",
  "parameters": {  },
  "variables": {  },
  "functions": [  ],
  "resources": [  ],
  "outputs": {  }
}

There are 3 ways to execute ARM Templates:

  • Validate, validates the template against AzureRM and it can be used to check any changes i.e. implementing new variables or checking input parameters.
  • Incremental, is the default mode of deploying resources using the ARM Templates and it does not remove any renamed resources it just adds them as new resources in the deployment i.e. you rename in your template a storage account and when you deploy the template a new storage account is created and the old one gets to stay as well. This can create clutter and orphan resources on the way.
  • Complete, is the mode that idempotency does its best work. By that we mean since the reasoning for use IaC in the first place is to have a repeatable and consistent way of deploying resources every time we press a button, it is only logical to run in “Complete” mode. When you rename or remove a resource altogether in the template at the time of the deployment the removed resource is also delete from AzureRM as well as the renamed is being created as new and the old one is also deleted from our resources on Azure.

The reasoning for use IaC in the first place, is to have a repeatable and consistent way of deploying resources. So, it is only logical to run in “Complete” mode when possible.

You can use any tool you feel comfortable with to deploy an ARM template i.e. PowerShell, Azure CLI, Azure DevOps, Cloud Shell, Azure Portal, REST API, etc. My preferred method, as you will see in other blog posts too, is Azure CLI.

Below you see the deployment of a storage account by executing an ARM template from a remote location.

az group create --name rg-sqltattoo-demo --location westeurope
Created resource group to hold the storage account
az group deployment create \
  --name sqltatooDemoDeployment \
  --resource-group rg-sqltattoo-demo \
  --template-uri "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-storage-account-create/azuredeploy.json" \
  --parameters storageAccountType=Standard_LRS
verbose output of storage account creation

Last but not least, when talking about cloud computing and deploying resources in regions around the globe for different projects and/or stakeholders, ARM Templates can be your ally in tagging the resources that will help in the reporting on the cost management and billing side of any project. Also, where compliance is strict and must be adhered at all levels, ARM Templates can assign policies and require or enforce different types and values so that all deployment stays within the compliance boundaries and everyone is happy.

As a primer, I think we touched the main points of ARM Templates so that on the next post to come we can focus on the best practices and practical howtos.

Cheers!