The Beginner’s Guide to immutable infrastructure with Terraform and vRealize Automation

If you've been living under a rock for a while, you could be forgiven for not knowing about Terraform and how awesome it is. Today, Terraform is one of the hottest new tools in the Cloud Automation space. Terraform can allow you to manage infrastructure as code for nearly any cloud platform, such as AWS, Azure, Google Cloud Platform, vRA, Kubernetes the list goes on. It's an easy to use tool that has tremendous potential for efficiency for anyone that deploys infrastructure using any popular cloud platform.

In a few words, let yo mama know: Terraform is a big deal.

The reason this is so interesting for the VMware community is because just recently, VMware released a plugin that allow you to use Terraform with vRealize Automation 7.x. This is what we'll be covering in this article. So before we get into the meat of this subject, let's spend a bit of time breaking down what Terraform is and why you should care.

terraform init – What is Terraform?

Terraform is an open source tool created by HashiCorp to provision and manage infrastructure components. It is often referred to as "Configuration Management for Infrastructure". In other words it is comparable to tools like Chef, Puppet or Ansible, but it works on a different level than those tools do, on the infrastructure automation level, rather than on the VM configuration/orchestration level.

Terraform uses a proprietary configuration language called the HashiCorp Configuration Language or HCL. It is essentially a language that allows you to write configuration files, using a declarative model to manage infrastructure as code. It uses the principle of applying a "Desired State Configuration". That's basically where the term "Immutable Infrastructure" comes from. Since Infrastructure components are so easily replaceable using a cloud platform and Terraform (or other tools like it), it makes more sense to destroy and recreate objects than to actually care for existing objects and bring them up to par, configuration-wise.

Terraform is distributed as a simple executable for Windows, Mac or Linux. It functions using a client-only architecture, meaning you don't need to have a dedicated Terraform server, you can run it from your laptop or jump server. Normally you would add the folder in which the Terraform executable file is found in your Operating System's "$PATH" variable to make sure you can run it no matter where you are. When you run terraform (through the command-line, always), it will look in the CLI working directory for configuration files with the ".tf" file extension and will read those as configuration files. You can also have separate "Variable" files with the .tfvars file extension to keep your usernames, passwords and other sensitive information hidden away.

That's the basis of how Terraform works, here's a bit of lingo you'll need to get by in the Terraform game:

  • Providers: A provider is a type of API endpoint. AWS, vRealize Automation, vSphere, vCloud Director, GCP, Microsoft Azure and OpenStack are all Providers. For example, to connect to a provider you need to specify a url/server name, a username and a password. Keep in mind there are a boatload of Providers that Terraform can talk to. Here is the full list of Providers Terraform supports. Here is an example of what a Provider declaration looks like in the HCL language :

  • Resources: A resource is something that is created and managed by Terraform. For many Terraform Providers, a VM is a good example of a resource. In the case of AWS, any object you create has its own Resource type, it can be anything, from a VM to a Subnet to a VPN, to a Routing Table and so on. Sticking to our vRA use case though, a Resource can be anything provisioned via a blueprint, VMs (via IaaS blueprints) or (with very limited functionality) even XaaS blueprints. Here is a syntax example of provisioning from an IaaS blueprint :

  • Provisioners: Provisioners are a function in Terraform that allows you to execute a task while it is applying your configuration. The typical use case for Provisioners is to call a Configuration Management tool such as Puppet or Ansible after a VM has been provisioned. But it can also be used to execute pretty much any task via API call or command line, such as adding a new server to a monitoring console or kicking off an antivirus scan. Here's an example using the "remote-exec" provisioner to run a script on a new AWS instance, from the Terraform website :
  • State : Terraform keeps a .tfstate file when it creates, modifies or destroys resources. This contains information on the state of the resource provisioned by Terraform and is key to much of Terraform's core functionality as an infrastructure automation tool. It is written in a human readable format, but you should never modify it! You can get an output of what your tfstate looks like by using the terraform show command.

There is of course a ton more complexity to using Terraform to its fullest potential, but for the purposes of this article, this is essentially all you will need to know to be able to use Terraform with vRA.


terraform plan – How to use Terraform with vRealize Automation

When you start using any infrastructure as code tool, you need to get your workspace set up. I like to use Microsoft Visual Studio Code (it's free!) to code Terraform. VS Code has a Terraform plugin for syntax highlighting that makes your code nice and colorful. You'll also want to use a Source Code versioning tool, or any private Git/SVN server will do. Next comes installing Terraform and the vRA Provider plugin. Terraform itself is, like I mentioned, just an executable that you will need to download and execute. Whereas for the "vRealize Automation Provider for Terraform plugin", that's another story. You're going to need to follow the instructions on this Github page to compile the executable and you'll need to keep that with you to use vRA as a Terraform Provider.

As far as functionality goes, at this point in time, the Terraform Provider plugin for vRealize Automation 7.x is pretty basic. It's doubtful that it will be able to cover all the use cases of when you need to create/modify/delete infrastructure components through vRA, so you shouldn't plan to cut off access to the vRA GUI just yet. However, if you can benefit from even this basic functionality and enjoy learning new technologies, then you can have quite a bit of fun combining Terraform and vRA, as did I. Keep in mind, this plugin is very new, it's only a few weeks old. It is definitely a work in progress and new changes are being made to it regularly. If you're reading this article in 2019, a lot might have changed with the state of the plugin since late 2017.

As it stands today however, here's the functionality you can get out of the vRA plugin for Terraform: 

  • Provision blueprints – This works for IaaS or XaaS blueprints.
  • Destroy deployments – This is limited to IaaS deployments. You can only destroy deployments that were created using Terraform, not deployments done outside of it.
  • Modify deployments – This functionality is very basic and is limited to IaaS deployments. Essentially, you can't really modify deployments, because most of the time Terraform will just destroy your existing deployment and recreate it as a new deployment as soon as you apply a slightly different configuration than the original one. A little more flexibility here will probably come at a later stage for the plugin. The reason for this behavior is related to the below note on Terraform State limitations.

A few limitations to be aware of:

  • Terraform State tracking when using the vRA Provider is VERY basic. The plugin still only tracks Request Status' instead of actual infrastructure, which means that your tfstate file will only know of the configuration you initially applied. If you compare the State functionality between the vRA Provider and the AWS Provider, AWS is much more advanced and tracks resource status much more granularly and allows you to have a lot more flexibility when modifying resources.
  • For vRA IaaS blueprints, a "Deployment" is the atomic (smallest) unit that Terraform can deploy & destroy, but cannot modify. A concrete example of that statement is that if you try to modify a deployment by adding or removing components to it, Terraform is not yet integrated with vRA's Scale in/out feature, so the best it can do is delete the deployment and recreate it with the right number of components. So if you don't mind having multiple vRA Deployments for something that typically contained in a single Deployment (for example, 3 identical web servers), you might be better off using the built-in "count" function in Terraform, which works around the limitation by creating 1 deployment per VM. 
  • The Terraform plugin is not yet able to destroy Items provisioned by the XaaS blueprints. Probably because it simply does not know how.

You will probably encounter more limitations like these ones as you start to use the plugin for your use case.

I realize that so far, I probably haven't convinced you to use Terraform with vRA yet, because after all, the limitations and the immaturity of the plugin are pretty imposing. So let's move on to a few scenarios where you could benefit from using Terraform.


terraform apply – Why should I use Terraform?

A few use cases I've come across for using Terraform are :

  • Building a new datacenter: You can use Terraform with vRA (or even plain old vSphere!) to provision all the core infrastructure components you need to build up a new datacenter.
  • Building a new vCenter: You can use Terraform with vSphere to build out a vCenter configuration including folders, datacenters, datastores and more. If you build vCenters regularly, this could save you a lot of time.
  • Building out new "cookie-cutter" environments: In my environment, we host customer infrastructures in our vRA cloud, where every customer has its own dedicated VMs, VMware NSX components, NFS shares, AD User accounts & groups, etc.. Each of these components is provisioned by a vRealize Automation blueprint. So building a complete customer environment means I have to make about 25-30 individual blueprint requests in vRA. This is where Terraform comes in. It is the glue that ties everything together. I have one Terraform configuration file per customer that contains the specification of that customer's environment. The main benefits of using this approach are :
  1. Building out those environments is no longer an exercise of patience with your mouse hand, clicking your life away in vRA to deploy a ton of blueprints, one after the other. Everything is built out in the order set in the Terraform configuration file and if necessary, dependencies can be specified. One blueprint's request is started only after all of its dependencies have been met. So in summary, the first benefit is that there is a lot less human interaction involved in the process building out infrastructures.
  2. The environments that you build with Terraform will benefit from its 'idempotent' declarative model. That means if their configuration deviates from what it should be, Terraform gives you a very easy way to bring it back in order.
  3. The environment's entire configuration is available to you in an easy to read text format that can easily be versioned. This is what Infrastructure as Code is all about!

As Terraform and its integration with vRA become more mature, the list of use cases will surely grow and give more and more power to Terraform to control vRA.


terraform refresh – Alternatives to Terraform

From the list of use cases above, you might be thinking that you can already do some of those things using other methods or tools. So let's explore other options and alternatives to Terraform.


  • Nested vRA blueprints:  I know some of you might be thinking "why not use nested blueprints?", the answer to that is that it would create one massive blueprint whose deployment would fail if any one of its components fails. As the nested blueprints grow, too many dependencies and risks make it more of a potential waste of time, than a potential time saver. I've personally been down that path before and I've learned the hard way that building bigger blueprints doesn't always mean reaping bigger benefits.
  • PowervRA script: PowerVRA is an awesome tool and I use it for many different management tasks. Like any script, PowerVRA works great when you have a specific need, but when it comes to provisioning and "chaining" blueprint requests, a lot of that stuff would need to be hardcoded in a script that would not be easily reusable. The script would lack flexibility, reusability and it would probably take a lot of maintenance work over time. In my opinion, Terraform is just a better suited tool for the use case of provisioning blueprints.
  • Custom REST API scripts, vRO workflows: This is definitely the alternative that gives you the most granularity and control over what you are provisioning, but again, the flexibility and reusability of scripts & workflows just doesn't cut it for me. Maintenance of such a solution can become a major concern.

All in all, the Terraform integration with vRA is not perfect. But for the use case we are focused on in this article, which is for provisioning environments using many different vRA blueprints, it fits the bill quite well and can make you significantly more efficient.


terraform show – Learn more about Terraform

If you want learn more about Terraform, here are some resources to get you started:


terraform destroy – The Bottom Line

If you build your blueprints in a certain way, where Terraform can be the one to call them in a given order or just in batches, you just might be able to create the perfect recipe with Terraform to significantly increase your efficiency when deploying them. As time goes on, the Terraform and vRA combination will only get sweeter. The Terraform plugin for vRA came out of its shell just a few short weeks ago and is already showing its awesome potential and it will only get better as the community contributes to the project.


Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: