If you’ve been working with both AWS and Azure you should have noticed that each of them have their own advantages.
Tools like Terraform might be very helpful if you’re not familiar with both CloudFormation and Azure RM. However don’t consider Terraform as a nonpareil (this is not true at all), it is a simple tool for simple tasks. So in this post, I’ll tell you about Terraform terms and concepts and show an example with AWS & Azure.

For a bit more complicated infrastructure you’ll have to use CloudFormation and Azure RM
Broadly speaking, Terraform is an orchestrator which allows you not to use APIs if you don’t want to.
But what if you already have an infrastructure to manage? Well, Terraform has the ability to import resources, but it’s currently a really poor one, so we’ll start from scratch in this example.

As an orchestrator Terraform supports lots of providers such as AWS, Azure, GitHub and even MySQL.
If you’re using a cloud provider, you might want to create the most popular resource – virtual machines. As soon as a VM is created you want it to do some tasks in your infrastructure, so you have to install and configure some software on it.
To achieve it we’ll use provisioners to run a DSC tool, Ansible in my example.
And if you want to get rid of provisioners and providers you can use modules to get what you need very fast or you can even create your own module and distribute it over Terraform registry, GitHub or AWS S3.
Whichever way you choose, you will deal with the state concept. Long story short, (as you have noticed, Terraform has very good documentation), state is used to map your configuration entities (like “db_svr”) to real entities (like “i-07a4dbf12c50dae76”) and store metadata f.e. dependencies and time stamps.
If you’re working alone or if your team executes Terraform from a single machine, like Jenkins, storing states locally will be fine, but if you’re working with a team you must consider centralized storage like Terraform Enterprise or AWS S3.

Terraform syntax is very easy when you’re using Terraform format and a bit more complicated using JSON.
Before start a coding update, your global gitignore with this records –
.terraform/ – in this dir plugins are stored, no need to put binaries to VCS
*.tfstate* – states put to VCS can produce conflicts, so use Remote state
*.tfvars – these files will keep your secrets like API keys, passwords, connection strings, etc. and VCS is not an option for that
Well, now it’s time to have a look at some real examples and we’ll start with AWS because they provide a default network and you don’t have to create storage accounts.
Because we don’t want to maintain huge configs let’s create config for variables:

We can have multiple providers, so let’s create dedicated config to describe them:

Finally let’s create our main config which will create our instance:

As you can see, we’ll use Ansible to install the required software, here’s a super simple playbook for nginx installation:

For learning purposes we have to create one more resource (Elastic IP) and attach it to the instance created above:

Ok, let’s install the necessary stuff with terraform init command:

Before we start applying it, let’s check what will be done using the Terraform plan command:

Looks good, so execute the Terraform application:

Does it look better than CloudFormation or Azure RM output? In my opinion: yes, much better =)
And you can destroy resources in the same simple and obvious way via terraform destroy (but don’t forget to type “yes” manually):

Now let’s have a look at Azure which is a bit more difficult. First of all you have to get auth stuff (for AWS we used API keys).
Follow Terraform instruction or this script to get subscription_id , client_id , client_secret , tenant_id
Start with defining variables:

Define provider:

Create resource group:

Create VNet and subnets:

For this example let’s create Network Security Group (we’ve skipped Security Groups for AWS because they’re too simple):

Now create Network Interface:

Finally create Public IP:

We’re done with the network part, and I don’t want to use Managed disks in this demo, so let’s create a Storage account and container:

Looks like everything is done and it means that we can create a VM (pay extra attention on SSH for Linux VM, it’s not as obvious as when using AWS):

The Ansible playbook is the same:

Init, Plan and Apply steps are the same so let’s have a look at the results:

Now you’ve seen the power of Terraform and it’s time to clone or fork my public repos for AWS and Azure and start using it in your lab or dev env!