Table of Contents
Introduction
Terraform is a tool that lets you describe networks and infrastructure in simple text files, then automatically create, change, and destroy that infrastructure in a controlled way. It is one of the most widely used tools for Infrastructure as Code in both cloud and on‑premises environments. In the context of networking, Terraform can define things like virtual networks, subnets, firewalls, load balancers, VPNs, and DNS records, then keep them consistent across environments.
This chapter focuses on what is specific to Terraform itself. Concepts like “Why Automation?” or “APIs” are covered in their own sections, so here we concentrate on how Terraform works, how its files look, and what makes it useful for network engineers.
Core Terraform Concepts
Terraform is built around a few key ideas that appear everywhere in its configuration language.
A provider is a plugin that knows how to talk to a specific platform. For networking work, common providers include cloud providers such as AWS, Azure, and Google Cloud, but there are also providers for on‑premises platforms, network vendors, and DNS services. Each provider translates Terraform’s generic description of resources into the right API calls for that platform.
A resource is a single piece of infrastructure that Terraform manages. In networking, a resource might be a virtual network, a subnet, a firewall rule, a VPN tunnel, or a DNS record. You describe each resource in a Terraform file, and Terraform ensures that it exists with the specified settings.
A data source lets Terraform read existing information from a provider without creating or changing it. For example, Terraform can look up an existing network or a list of availability zones and then use that information when defining new resources.
Finally, Terraform maintains a state file that records what it believes exists in the real world. This state is essential for Terraform to understand what needs to be created, changed, or destroyed. In shared environments, this state is often stored remotely so that teams can work together safely.
Terraform relies on its state file to know what exists. Never edit the state file manually unless you fully understand the consequences.
Declarative Configuration Style
Terraform uses a declarative approach. You describe what you want, not how to do it. For example, you might declare that you want a specific number of subnets and a load balancer pointing at a group of servers. Terraform then calculates the sequence of operations that will create or update these objects.
This is different from writing a script that runs API calls step by step. With Terraform, you can change your configuration text and Terraform figures out the minimal changes needed to reach the new desired state. This property is especially valuable in networking, where accidental manual changes can cause outages.
Terraform’s language is called HCL, the HashiCorp Configuration Language. It is human‑readable and designed for infrastructure. A simple configuration file can be read and understood even by someone new to programming, which is helpful for network engineers who are starting with automation.
Files, Structure, and Syntax
Terraform configurations are usually stored as a collection of files ending in .tf in a directory. Terraform treats all .tf files in a directory as a single configuration. This allows you to separate resources by purpose, such as one file for networks, another for security rules, and another for DNS.
The basic elements in a Terraform file are blocks. Common block types include provider, resource, data, variable, and output. Each block has a type, labels, and a body enclosed in braces.
A resource block typically looks like this pattern:
resource "provider_resource_type" "local_name" {
argument1 = value1
argument2 = value2
}The first string identifies the resource type as understood by the provider. The second string is a local name that you use elsewhere in the configuration to refer to this resource. Arguments inside the braces specify the properties of the resource.
Although the exact resources differ per platform, the structure remains the same. That consistency is one reason Terraform can be used across multiple environments without learning a completely new syntax each time.
The Terraform Workflow
Working with Terraform usually follows a predictable cycle. From a user’s point of view, this involves three central commands that appear in most sessions: init, plan, and apply.
The terraform init command prepares the working directory. It downloads the required providers and sets up backend configuration for state storage if you are using a remote backend. You typically run this command once when you start a new configuration or whenever you add or update providers.
The terraform plan command compares your configuration files with the current state and generates an execution plan. This plan describes what Terraform will create, change, or destroy. It does not change any real infrastructure. For network work, this plan step is particularly important, because you can review potential changes to sensitive resources such as firewalls or routing policies before they actually happen.
The terraform apply command takes a plan and executes it. Terraform calls the provider APIs in the correct order, respecting dependencies. For example, it creates networks before instances, and instances before load balancers that depend on them. When apply completes, the state file is updated to reflect the new reality.
You can also use terraform destroy to remove everything defined in your configuration. This command is powerful and useful in testing or lab environments but must be used carefully in production.
Always review the terraform plan output before running terraform apply, especially for networking changes that can affect connectivity.
Variables and Outputs
To avoid hard coding values such as IP ranges, region names, or DNS zones, Terraform lets you define variables. Variables make configurations flexible and reusable across environments like development, testing, and production.
Variables are declared using a variable block. You can specify descriptions, default values, and types. Values can then be passed from the command line, environment variables, or separate variable definition files. This allows you to keep one generic configuration while changing details per environment.
Outputs let Terraform print or expose information about resources after an apply. For networking, outputs can provide important values such as assigned IP addresses, subnet IDs, or URLs of services behind load balancers. Other tools or modules can consume these outputs, which makes it easier to integrate Terraform with the wider automation ecosystem.
Variables and outputs are fundamental to turning a one‑off Terraform file into a shared, production‑ready configuration that can be used across many projects and teams.
Dependencies and Resource Graph
Terraform automatically figures out the order in which resources must be created or updated. It builds a dependency graph that shows which resources depend on others. For example, a subnet might depend on a virtual network, and a firewall rule might depend on both the subnet and a security group.
You do not usually have to specify these dependencies manually. Terraform infers them from references in your configuration. If one resource refers to an attribute of another, Terraform knows that the referenced resource must be created first.
This dependency graph is what allows Terraform to safely handle complex network setups that involve many interconnected parts. It also allows Terraform to perform operations in parallel when possible, which can speed up large deployments.
If necessary, you can influence dependency behavior using specific Terraform features, but in most basic networking scenarios, the automatic graph is sufficient and reliable.
Modules and Reusability
As configurations grow, repeating the same patterns for every project becomes tedious and error prone. Terraform solves this with modules, which are reusable packages of Terraform configuration.
A module is simply a directory that contains Terraform files. When you call a module, you can pass variables into it and receive outputs from it. For network engineering, you might build a module that creates a standard network layout for a new application, such as a set of subnets, routing rules, and security policies. Different teams can then use the same module with different variable values.
Modules can live in local directories, version control systems, or private registries. Using modules encourages standardization, improves security by reusing tested patterns, and cuts down on the time needed to set up new environments.
Treat shared Terraform modules as controlled building blocks. Changes to a widely used module can affect many environments at once, so always test module updates carefully.
State Management and Collaboration
Terraform’s state is more than a simple list of resources. It stores mappings between Terraform resource names and real world IDs, plus cached attributes. For a small personal project, keeping this state locally as a file works. For team work or production use, state is usually stored remotely.
Remote backends such as object storage or Terraform specific services allow multiple people to share the same state safely. Some backends also provide locking so that only one apply runs at a time. This reduces the risk of conflicting changes.
Good state management is essential in collaborative networking projects. It lets the whole team see and modify the same view of the infrastructure, instead of each person manually changing devices or services in isolation.
You can inspect state with commands such as terraform state list or terraform state show, which can be useful when you need to understand how Terraform sees existing resources before making changes.
Terraform in Network Automation
In day to day practice, Terraform is often part of a larger automation toolset. While other tools in this course focus on interacting with network devices and APIs directly, Terraform excels at defining the desired overall layout and letting its engine handle ordering and dependencies.
For networks, Terraform is especially suited for cloud networking layers such as virtual private clouds, subnets, load balancers, and DNS, as well as for some on‑premises systems where providers are available. It provides a consistent workflow for planning and applying changes and a single source of truth in the form of version controlled configuration files.
Teams can track every change to the network definition in version control, review proposed updates through code review, and roll back to previous configurations if needed. This approach brings software engineering practices into networking work, which is one of the central goals of Infrastructure as Code.
By understanding Terraform’s concepts, workflow, and structure, you gain a foundation that can be applied to many platforms and providers, whether you are building small test labs or large production networks.