Terraform Explained for Beginners

Cloud technology is taking over the modern business world, and IaC has come to the rescue. But what is IaC, and what is Terraform?

Infrastructure as Code

Infrastructure as Code is a model that codifies everything in your infrastructure to bring numerous benefits to growing your business. It tries to ensure that the cloud migration of the business processes and operations and handled efficiently while also considering constant data availability, stability, and top-of-the-line cybersecurity throughout the migration. Infrastructure as Code is used to automate tasks in different categories for different phases:

  1. Initial Architecture Setup
  2. Infrastructure Management of this Architecture
  3. Initial Application Setup
  4. Application Management

There are a lot of advantages of using the Infrastructure as Code approach:

  1. The calls are made from either the GUI, API/CLI calls, or scripts, so there are few rooms for human error and involvement. It also ensures consistency in configuration and setup.
  2. Flexibility and Elasticity of resources are immense, so there is no need for the long-term commitment of your resources to ensure a return of investment on them. Thus it ensures great turnovers during peak hours, sales, festivals, etc. as well.
  3. Transition of resource and CI/CD philosophy: In the old days, the philosophy was to keep updating and modifying the code and servers. Now it has been enhanced to keep the resources short-lived and immutable, and instead of modifying, just tear down the old one and just provision a brand new resource for it.

We can also see that the above distinguishment of phases describes how the DevOps flow progresses from the infrastructure provisioning to the application management. It is to be noted that there isn't a well-known or ideal tool that covers all of the above phases, there are some specific yet outstanding tools that can be combined to achieve results in the above phases. We will discuss them later in the blog.

Terraform

There have been many advancements in the provisioning of cloud resources, and one of them is the innovation of Terraform. Terraform is an open-source, Infrastructure as Code tool that lets you build, change, version, and reuse infrastructure programmatically in human-readable configuration files and ensures the infrastructure's safety and efficiency. This includes low-level components like compute instances (e.g., EC2s), storage, and networking; and high-level components like DNS entries and SaaS features.

Basic Terraform commands

While the magic lies in how we define and write the .tf configuration files, there are also a couple of Terraform commands that we should be aware of:

  • init : Prepare your working directory for other commands, initialize the project
  • validate : Check whether the configuration is valid
  • plan : Show changes required by the current configuration, takes the Terraform config file and compare it to the Terraform state file, and define a set of instructions for the transition
  • apply : Create or update infrastructure by applying the instructions derived in the previous command
  • destroy : Destroy previously-created infrastructure

Terraform has important segments like Terraform Core, Terraform State (JSON file where the current state of the Infrastructure is stored), and Terraform Config (where the desired modification and updates are being proposed). There are also providers which coordinate with the respective cloud providers and make this tool cloud agnostic.

Resources are the most important element in the Terraform language. Each resource block describes one or more infrastructure objects, such as virtual networks, compute instances, or higher-level components such as DNS records.

A module is a container for multiple resources with a standard configuration that are used together, thus it allows us to create logical abstraction on top of some resource set. Every Terraform configuration has at least one module, known as its root module, which consists of the resources defined in the .tf files in the main working directory. Thus, a module may contain a collection of .tf or .tf.json files kept together in a directory.

Meta-Arguments in Terraform

Meta-arguments are some special constructs in Terraform that help us in achieving certain requirements within the resource block and make customized configurations of the infrastructure based on our requirements. Here are a couple of important meta-arguments:

  1. depends_on: We explicitly define a list of dependencies to maintain a sequence of execution that cannot be automatically inferred by Terraform. Terraform generates a dependency graph for reference out of it,

  2. count: We use it to create multiple (nearly identical) resources from a single line of code, according to a count. This reduces the overhead of duplicating the resource block by that count. count.index is used to differentiate between the resource.

  3. for_each: This meta-argument is similar to count but allows us to have more control over the behavior of the resource. The argument accepts a mapping or set of strings and Terraform will create one instance of that resource for each member of that map or set, and allows flexibility through each.key and each.value.

  4. lifecycle: It defines the lifecycle of the resource and has a set of meta-arguments inside it to control the behavior of resources generally related to create and destroy of a resource. Some of them are: create_before_destroy, prevent_destroy, and ignore_changes.

  5. provider: We can specify the provider configuration to be used for a resource. If we do not mention the provider, then the default is selected by Terraform based on the resource type name. This is useful when we are using multiple providers which are usually used when we are creating multi-region resources. To differentiate between providers, we use an alias tag.

  6. provisioner: They are used to deal with the edge cases and behaviors that cannot be directly represented in Terraform's declarative model. However, it is suggested to supervise the functioning of this argument closely due to its complexity and uncertainty in Terraform usage.

Terraform Usage and Common Patterns

There are various use cases and tools that can be combined with Terraform to provide the best-in-class DevOps infrastructure.

Use Cases

  1. Multi-Cloud Deployment
  2. Application Infrastructure Deployment, Scaling, and Monitoring Tools
  3. Self-Service Clusters
  4. Policy Compliance and Management
  5. PaaS Application Setup
  6. Software Defined Networking
  7. Parallel Environments

Common Usage Patterns

  1. Terraform + Ansible: Terraform can be used to provision the infrastructure, such as the instances/servers and virtual machines, and then Ansible can be used to install dependencies on those virtual machines and provide software provisioning.
  2. Terraform + Packer: Terraform can be used for provisioning new infrastructure from stable, tested, and pre-configured machine instances from images generated by Packer. These can be considered analogous to custom Amazon Machine Images. Packer is made by HashiCorp as well.
  3. Terraform + Kubernetes: We can use Terraform to define the cloud resources, and then use Kubernetes to define how our Application is deployed and managed on them.

There is a lot of exciting stuff to cover in Terraform, such as managing multiple environments (workspaces vs file structure), using variables in config files, handling/passing sensitive data in files, using variables and templates to divide projects into dev, staging, and production environments, and more. I hope to blog about them soon, stay tuned!