Introduction to Terraform

What is Terraform?

I’ll lift this directly from their website :

Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions.

Configuration files describe to Terraform the components needed to run a single application or your entire datacenter. Terraform generates an execution plan describing what it will do to reach the desired state, and then executes it to build the described infrastructure. As the configuration changes, Terraform is able to determine what changed and create incremental execution plans which can be applied.

The infrastructure Terraform can manage includes low-level components such as compute instances, storage, and networking, as well as high-level components such as DNS entries, SaaS features, etc.

Creation Flow

The flowchart below shows the steps for creating your infrastructure via Terraform:

Configuration Files#

Infrastructure is created based on the Terraform configuration files provided. The configuration files are written using HCL, designed to be easy for humans to read and write. The configurations can also be written in JSON. You can learn more about the syntax here [https://www.terraform.io/docs/configuration/syntax.html].

Here we have a simple configuration file to create an AWS EC2 instance. We’ll go over the different sections.

provider "aws" {
  profile    = "default"
  region     = "us-east-1"
}

data "aws_ami" "amzn-2" {
  most_recent = true
  owners = ["amazon"]

  filter {
    name   = "name"
    values = [kl"]
  }
}

resource "aws_instance" "example" {
  ami           = data.aws_ami.amzn-2.id
  instance_type = "t2.micro"
}

Provider#

The provider is responsible for creation and management of resources. It has a plugin that terraform uses to translate the API interactions to the service.

You can have multiple provider blocks in your configuration files. This allows you to create and manage infrastructure from different providers. Just add the provider blocks and the associated resource in the configuration files.

For the example above, it will use AWS as the provider. It will look for authentication details for the profile “default” in your settings. The default settings location is $HOME/.aws/credentials and $HOME/.aws/config. You can also run aws configure in your terminal if you have the CLI installed.

Resource#

resource sections specify the resources you want to create and manage with Terraform. This varies depending on the provider but Terraform provides a very wide selection of available resources for creation. To view the list of possible resources, visit the documentation at https://www.terraform.io/docs/providers/aws/

Data Source#

Sometimes the resource you want to use has already been created before. In our example above, we use an existing AMI, Amazon Linux 2, to launch our EC2 instance. A data section indicates that you want an existing resource to be used. It searches for an existing resource based on the parameters provided. To view the list of possible data sources, visit the documentation at https://www.terraform.io/docs/providers/aws/

Initialization#

In this step, Terraform initializes your local environment so that you can start using Terraform. It downloads the necessary plugins to run the configuration files.

IMPORTANT: Terraform scans the current folder where you are running the command. It will run all Terraform commands based on the configuration files of your current working directory.

To initialize, run terraform init. If you run the command in the same folder with our configuration above, it should download the AWS plugin. Installations are saved in a hidden subdirectory.

Format and Validation#

This step is optional but you can run terraform fmt to automatically update your configuration files for readability and consistency.

You can also run terraform validate to check for errors within modules, attributes, and value types.

Plan#

terraform plan will give you a preview of what terraform will create. It will give a summary of what it will create once you decide to apply the configuration files.

Apply#

terraform apply will apply the changes in your configuration. If this is a new setup, it will create all resources.

State files#

Once terraform has created all resources, it will generate a state file which contains the state of the infrastructure it is managing. State files are stored in current folder and have the extension .tfstate. There is an option to store the .tfstate file remotely so that it can be shared with other users.

It is important to note that the state file checks the current state on the provider (ex. AWS) and compares it to your configuration files. If the state does not match, it will apply what is stated in your configuration file.

Updating Infrastructure

Changes via Terraform Configuration#

Updating the infrastructure is done by updating the configuration files. After this, you run terraform apply and the changes will be implemented. Some changes will require resources to be recreated (ex. changing the AMI) and this is done by destroying the resource and creating a new one. If a resource is dependent on a recreated resource, this will also need to be recreated since there will be a new reference to the new resource. There are also changes that don’t require recreation (ex. changing security group).

Manual Changes#

Manual changes, or changes done outside terraform (via CLI, UI, management console) are not reflected in terraform.

Some issues to note when doing manual changes:

  • When terraform refreshes the state from the provider, it will see that there are differences between the state and the configuration. Running terraform apply will make the infrastructure conform with the configurations in terraform. There is a chance that manual changes will be undone.
  • If a manually added resource is dependent on a terraform-managed resource, that relationship is not stored in terraform. So if a resource needs to be destroyed or recreated, that might fail since the provider will not allow it since it is still being used by the manually-created resource.

Cleanup#

Terraform also manages the cleanup of your resources. Running terraform destroy will delete all the resources managed by terraform.

Summary

In this post, we’ve shown a simple configuration for creating an AWS EC2 instance using terraform. Terraform allows us to control our infrastructure using configuration files which makes it easier to maintain and manage.