Comparing Azure ARM and Terraform

Terraform and ARM infrastructure code in a family portrait.

Introduction

This is the final blog post regarding the AWS and Azure intro demonstrations that I created using native tools (AWS: CloudFormation and Azure: ARM) and Terraform. The previous articles in this series are:

Terraform vs ARM

In this chapter I compare the two tools based on my experience when using them. I also give (very opinionated and personal) points (0–5, 5 highest) to tools regarding how I feel they excel in that category. At the end of the chapter I gather the results and give my personal recommendation which tool to use. The evaluation process is therefore pretty similar that I already used in my previous blog post: “Comparing AWS CloudFormation and Terraform” (and actually most of Terraform’s pros are pretty similar in these two articles).

1. Cross Platform

Terraform’s major benefit is that you can use it with many cloud providers: you just need to learn one language (hcl) and workflow and use it with AWS, Azure, GCP etc. This is a real benefit for developers like me who do both AWS and Azure (and studying GCP at the moment) — one of the reasons why Terraform is my choice of IaC tool.

2. Language

I like Terraform’s hcl language. Hcl’s interpolation syntax is very powerful and it lets you to reference variables, attributes etc. Combined with a good IDE plugin this makes infrastructure coding a breeze.

3. Modularity

Modularity is a bit more natural using Terraform than using ARM. For a software developer background guy like me Terraform’s modules are a very natural way to modularize and reuse your infrastructure code.

4. Validation

Both tools provide a validation mechanism before you apply the infrastructure code, but a bit differently. Using ARM you can use command “az group deployment validate” to validate the syntax of the ARM template — if you want to validate the deployment you actually have to deploy the ARM template. Terraform provides a real cloud validation with the plan phase which actually checks the current deployment in the terraform state file, refreshes the status of the actual cloud configuration and calculates the delta between the current configuration and the target configuration (your Terraform infrastructure code).

5. Readability

Look at the family portrait screen shot at the beginning of this blog post. I think Terraform is a lot more readable than the bare JSON format of the ARM template. Terraform’s modularity also makes the code more readable. Some ARM template developers may not agree with me regarding the curly braces and dollar signs but once you know the syntax those make perfect sense for readability. Comments help readability — you can use comments in Terraform code but not in JSON.

6. Maintainability

Personally I think Terraform is more maintainable due to its better modularity and how you can create resources like functions. ARM templates are not that easy to read and also the fact that you cannot store nested templates in your local workstation is a bit clumsy.

7. Tooling

I really love IntelliJ IDEA’s Terraform / HCL plugin. Using the plugin with IntelliJ idea makes the infrastructure coding a breeze — your IDE is aware of all available parameters of the resource you are editing, IDE suggests other modules, hcl variables and locals in your code. I also installed the Azure plugin to IntelliJ but I had interesting instability issues with it — the first time I actually had to contact IntelliJ support. I therefore used Visual Studio Code as an IDE when working with ARM templates, and installed Azure Resource Manager Tools plugin.

8. Azure Portal Support

Since ARM templating is a native Azure IaC tool it provides good support in the Azure Portal, of course. You can use the Azure Portal to monitor the progress of the deployment, see all deployment events, check various errors etc. For Terraform there is no Azure Portal support.

9. Workflow

I already covered the Terraform workflow quite well in my previous blog post so I’m not iterating it here. Let’s just say that Terrform’s workflow — “create all resources you can and stop if some service deployment fails” is a natural fit for a developer. ARM templates actually provide the same workflow and also are capable to rollback to the previous successful deployment (as CloudFormation) using the “-- rollback-on-error” option.

10. Error Message Understandability

Most of the error messages Terraform spits are pretty obvious. But if something weird happens Terraform error messages can be rather difficult to interpret, especially for novices. ARM and using the Azure Portal on the other hand makes error messages more readable.

11. Infrastructure State Management

Both tools provide good state management. Terraform provides a backend state mechanism. ARM is capable to rollback to a previous successful deployment (I interpret this to be a kind of state aware thing even though in some ARM documentation they said that ARM is “stateless”).

12. Infrastructure Changes Auditing Support

Since ARM is a native Azure IaC tool I would have assumed that it integrates with Azure Log Analytics (as CloudTrail in the AWS side) to let you see who did and what with ARM deployments. However I didn’t quickly find an exact match to audit the deployments in the Log Analytics the same way I can use CloudTrail to audit deployments in the AWS side — most probably just because I have used AWS much more than Azure.

Summary

Here are the results of my opinionated and skewed comparison. I use a factor (“Fa”: 1–2) to provide some emphasis how important this feature is for me as an infrastructure developer (a SysOps guy might choose different factors and different original points). So, the fields are: Fa = Factor (1–2), OP = Original points, FP = Factored Points. I see one major problem with this comparison and that is the fact that I haven’t used that much ARM — a seasoned ARM user most probably has found a standard way or at least some workaround for those issues I complained in this blog post. Maybe I update this blog post after some ARM project when I have gathered more ARM experience.

Conclusions

Both Terraform and ARM are pretty good when it comes to infrastructure coding for Azure. The most important decision is to use an IaC tool than which tool to use (I covered this decision a bit in my previous articles “How to Create Infrastructure as Code for AWS and Azure” and “How to Create and Manage Resources in Amazon Web Services Infrastructure?”).

I’m a Software architect and developer. Currently implementing systems on AWS / GCP / Azure / Docker / Kubernetes using Java, Python, Go and Clojure.