Hello dear readers!
It’s been a while since I wrote some stuff over here. So it’s about time.
This time I’ll write about AWS and Terraform!
Overview
Terraform offers a modularized way to deploy your infrastructure. It offers a lot of providers that you can leverage in order to deploy on AWS, Azure, Google Cloud and other Cloud providers.
It offers a zero-installation approach composed of 1 single executable file that you can run wherever you need it. I copied that to a location that is already in my PATH so that I could call it from anywhere in my workstation.
The so-called modules are basically the building blocks for our infrastructure. You can have them as decoupled as you want or as big as a full stack. Both approaches have pros and cons you’ll have to consider when making a decision on how to code your infrastructure.
The Terraform Mythos
Myth #1. “Terraform is platform agnostic”
False! While it allows you to use a ton of different providers, if you want the same infrastructure on different providers you’ll need different code for each provider. So, there’s no such thing as a high level Infrastructure Code that can be “translated” by Terraform depending on the provider.
Let’s go over the simpler example.
Let’s create a VPC on AWS, Azure and Google Cloud
For each Cloud provider, resource “types” are absolutely tied to the provider, making terraform only a “common” language to describe cloud objects, but always using the provider’s names for those objects.
Google Cloud
# --- Google Cloud --- resource "google_compute_network" "example" { name = "example_network" auto_create_subnetworks = "true" }
AWS requires stuff ike a cidr_block, and if you fail to provide it, Terraform will faill and tell you that you need to give it a cidr_block.
# --- AWS VPC --- resource "aws_vpc" "example_vpc" { cidr_block = "10.0.0.0/16" instance_tenancy = "dedicated" tags { Name = "example_vpc_name" } }
AWS has it’s own resource for subnets. See below that Azure requires the subnets added in the same resource which is not even close to the AWS “version” of the code
# --- AzureRM VNresource "azurerm_virtual_network" "network" { name = "production-network" address_space = ["10.0.0.0/16"] location = "${azurerm_resource_group.network.location}" resource_group_name = "${azurerm_resource_group.network.name}" subnet { name = "subnet1" address_prefix = "10.0.1.0/24" } subnet { name = "subnet2" address_prefix = "10.0.2.0/24" } subnet { name = "subnet3" address_prefix = "10.0.3.0/24" } }
Myth #2 Terraform can track changes
True! Terraform indeed can track changes as long as it has a special file with the .tfstate extension where it is run.
Myth #3 Terraform is open source
True and False! To some extent, yes, it is open source. Nevertheless it has it’s “Enterprise Edition” which features are not generally available.
The real deal
Once we have a full overview of what we can do and what we can’t, let’s talk about it.
Terraform will allow you to manage your Infrastructure as Code in an easy way provided that you maintain your code organized. For this, I would highly recommend reading some documentation over in https://www.terraform.io before engaging in any coding at all.
Terraform has some great advantages like: it won’t make any changes unless you say “YES” literally.
I would also recommend to have a folder structure that allows you to simplify identifying your deployers and modules easily.
terraform_root -- <provider> -- -- <environment> -- -- -- <deployer> -- -- -- -- <deployer>_main.tf -- -- -- -- <deployer>_outputs.tf -- -- -- -- <deployer>_provider.tf -- -- -- -- <deployer>_variables.tf -- -- -- -- terraform.tfvars -- -- -- modules -- -- -- -- <module name> -- -- -- -- -- <module name>_data.tf -- -- -- -- -- <module name>_main.tf -- -- -- -- -- <module name>_outputs.tf -- -- -- -- -- <module name>_variables.tf
Where the <> stand for:
- <provider>: The actual provider to use
- {aws | azurerm | alicloud | google | … }
- <environment>: In the case you manage more than a production environment
- { development | uat | stress-test | qa | … }
- <deployer>: The module orchestrator for deploying your infrastructure fully or partially complete
- { network | security | database | ec2_instance | … }
- <module name>: The module name which is somewhat tied to the provider
- { vpc | security_groups | ec2-instance | autoscaling_group | … }
And the files have the following contents:
- *_data.tf: Here you query your provider to give you information on existing infrastructure
- *_main.tf: Here are the infrastructure resources to be created/updated
- *_outputs.tf: Here, the output “variables” are defined, so that the <deployer> can pass them as variables to other modules.
- *_variables.tf: Here, the variables are defined, and even default values can be passed to avoid missing important information.
- terraform.tfvars: This file contains hardcoded data. It shoulden’t be sensitive information as it’s in plain text. Also is highly recommended to avoid putting this file in git or any other version control system.
How does it work?
Simple. Download aws-cli and terraform. Configure aws-cli and then terraform init after you have a very small “infrastructure” to test.
Then the steps will be:
- terraform init: Get the provider plugins and check the code
- terraform plan: connect to the provider and check what the state of the infrastructure and what has to be done
- terraform apply: make the changes happen.
Last words
My advice is that you give it a try. You already have more knowledge than I when I first started testing it.
I will post some more about mixing Terraform with other tools for automation in the future.
Go and have fun! Happy Terraforming!