This Terraform Q&A answers the most common questions I am asked by colleagues, clients, and engineers who are starting to use HashiCorp Terraform.
Terraform is one of the most widely used infrastructure-as-code tools. It lets you define cloud, on-premises, SaaS, and platform resources in configuration files, then use a repeatable workflow to create, change, and manage that infrastructure safely. HashiCorp describes Terraform as an infrastructure-as-code tool for building, changing, and versioning both cloud and on-premises resources.
Terraform is commonly used with AWS, Azure, Google Cloud, VMware vSphere, Kubernetes, GitHub, DNS providers, monitoring platforms, and many other services. It is not just an AWS tool, and it is not limited to public cloud environments.
What Is Terraform?
Terraform is an infrastructure-as-code tool created by HashiCorp. It allows you to describe infrastructure using configuration files written in the HashiCorp Configuration Language, commonly abbreviated as HCL.
Instead of manually creating servers, networks, databases, security groups, DNS records, and other resources through a web console, you define the desired state in code. Terraform then compares that code with the real infrastructure and determines what needs to be created, updated, or removed.
A typical Terraform workflow looks like this:
- Write the Terraform configuration.
- Plan the changes before making them.
- Apply the approved changes.
- Store state so Terraform can track what it manages.
Terraform uses state to map real infrastructure resources back to your configuration. Without state, Terraform would not know which real-world object belongs to which resource block in your code. HashiCorp recommends using HCP Terraform or a remote backend for shared state when teams collaborate.
What Is HCP Terraform?
HCP Terraform is the current name for what was formerly known as Terraform Cloud. HashiCorp renamed Terraform Cloud to HCP Terraform on 22 April 2024. The core product remains the hosted platform for running Terraform, managing remote state, connecting to version control, sharing variables, enforcing policies, and collaborating as a team.
HCP Terraform is useful when you want Terraform runs to happen in a consistent remote environment rather than on someone’s laptop. It can connect to a Git repository, run plans automatically when pull requests are opened, require approval before applying changes, securely store state, and control who can change production infrastructure.
HCP Terraform is not the same thing as the Terraform CLI. The Terraform CLI is the command-line tool you can install locally. HCP Terraform is the hosted platform that helps teams run Terraform together. HashiCorp’s current documentation describes HCP Terraform as a platform that runs Terraform on demand or in response to events, offering deeper integration with Terraform workflows than a general-purpose CI system.
Is Terraform Cloud Still Available?
Terraform Cloud still exists in practice, but the official product name is now HCP Terraform. Older articles, tutorials, module references, and code examples may still mention Terraform Cloud or app.terraform.io. Those references are usually still understandable, but new documentation should use the current product name.
For new content, use this wording:
HCP Terraform, formerly Terraform Cloud, is HashiCorp’s hosted Terraform platform for remote runs, state management, policy enforcement, private modules, team access controls, and workflow automation.
What Should I Use Terraform For?
Terraform is best used for provisioning and managing infrastructure resources.
Good Terraform use cases include:
- Creating AWS VPCs, subnets, route tables, security groups, IAM roles, EC2 instances, RDS databases, ECS clusters, EKS clusters, S3 buckets, CloudFront distributions, and Route 53 records.
- Managing Azure resource groups, virtual networks (VNets), storage accounts, virtual machines, AKS clusters, and role assignments.
- Managing Google Cloud networks, IAM, GKE clusters, Cloud SQL, storage buckets, and service accounts.
- Provisioning VMware vSphere virtual machines, networks, and related resources.
- Managing Kubernetes namespaces, Helm releases, and cluster-level resources.
- Creating DNS records, monitoring resources, SaaS settings, GitHub repositories, and other API-driven resources.
Terraform is strongest when you need predictable, repeatable infrastructure lifecycle management. It is especially useful when infrastructure changes need to be reviewed, version-controlled, and promoted through environments.
What Should I Not Use Terraform For?
Terraform is not the best tool for every automation task.
Avoid using Terraform as your main tool for:
- Installing packages inside servers.
- Patching operating systems.
- Running one-off scripts repeatedly.
- Managing highly dynamic application runtime state.
- Performing detailed configuration management inside existing machines.
For those tasks, tools such as Ansible, cloud-init, shell scripts, image pipelines, Kubernetes controllers, or platform-specific automation may be a better fit.
A common pattern is to use Terraform for provisioning and Ansible for configuration management. For example, Terraform can create the EC2 instance, security group, IAM role, and DNS record, while Ansible can configure packages, users, services, and application settings within the operating system.
Is Terraform Only for the Cloud?
No. Terraform is not limited to public cloud environments.
Terraform can manage any platform supported by a provider. HashiCorp explains that Terraform uses providers to interact with cloud platforms, SaaS platforms, self-hosted systems, and other APIs. Each provider adds resource types and data sources that Terraform can manage.
That means Terraform can be used for:
- AWS
- Azure
- Google Cloud
- Oracle Cloud
- VMware vSphere
- Kubernetes
- Helm
- GitHub
- Cloudflare
- Datadog
- Grafana
- DNS platforms
- SaaS APIs
- Internal platforms with custom providers
I have found Terraform particularly useful for AWS and VMware vSphere environments because it provides a consistent way to define infrastructure, review changes, and rebuild environments as needed.
How Does Terraform Communicate With AWS?
Terraform communicates with AWS through the AWS provider. The provider is a plugin that can call AWS APIs and manage AWS resource types.
A minimal AWS provider configuration looks like this:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
}
}
provider "aws" {
region = "eu-west-2"
}
Terraform then uses AWS credentials available to the provider. Those credentials can come from several places, including environment variables, AWS profiles, AWS SSO sessions, instance roles, container roles, or dynamic credentials in HCP Terraform.
For local development, an AWS CLI profile is usually a good option:
aws configure sso
export AWS_PROFILE=my-dev-profile
terraform init
terraform plan
For automation, avoid hard-coding AWS access keys in Terraform files. A better approach is to use short-lived credentials, workload identity, OIDC, or an IAM role assumed by your CI/CD platform.
HCP Terraform supports dynamic provider credentials for AWS using OpenID Connect. This allows HCP Terraform to request temporary AWS credentials for each run instead of storing long-lived static access keys. HashiCorp recommends this approach because static credentials in workspaces or stacks create security risk, even when rotated.
How Do I Create an AWS VPC With Terraform?
You can create an AWS VPC with the aws_vpc resource from the AWS provider.
Here is a simple example:
terraform {
required_version = ">= 1.6.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
}
}
provider "aws" {
region = var.aws_region
}
variable "aws_region" {
type = string
default = "eu-west-2"
}
variable "project_name" {
type = string
default = "demo"
}
variable "vpc_cidr" {
type = string
default = "10.10.0.0/16"
}
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "${var.project_name}-vpc"
Environment = "dev"
ManagedBy = "terraform"
}
}
That creates the VPC itself. For a working network, you will normally add subnets, route tables, an internet gateway, NAT gateways, network ACLs, VPC endpoints, and security groups.
Here is a slightly more practical example with a public subnet and internet route:
data "aws_availability_zones" "available" {
state = "available"
}
resource "aws_vpc" "main" {
cidr_block = "10.10.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "demo-vpc"
}
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "demo-igw"
}
}
resource "aws_subnet" "public_a" {
vpc_id = aws_vpc.main.id
cidr_block = "10.10.1.0/24"
availability_zone = data.aws_availability_zones.available.names[0]
map_public_ip_on_launch = true
tags = {
Name = "demo-public-a"
}
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
tags = {
Name = "demo-public-rt"
}
}
resource "aws_route" "internet" {
route_table_id = aws_route_table.public.id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
resource "aws_route_table_association" "public_a" {
subnet_id = aws_subnet.public_a.id
route_table_id = aws_route_table.public.id
}
To run this locally:
terraform init
terraform fmt
terraform validate
terraform plan
terraform apply
To run it through HCP Terraform, store the code in a Git repository, create a workspace, connect the repository, configure variables and credentials, then run a plan and apply from the HCP Terraform workflow.
What Is Terraform in DevOps?
In DevOps, Terraform is used to bring infrastructure into the same kind of controlled workflow as application code.
That means infrastructure changes can be:
- Stored in Git.
- Reviewed through pull requests.
- Tested before deployment.
- Planned before being applied.
- Promoted through development, staging, and production.
- Audited later if something changes.
Terraform helps reduce manual infrastructure changes. Instead of clicking through a console and hoping the same steps are repeated correctly next time, you define the infrastructure once and apply it consistently.
This is useful for platform teams, DevOps engineers, SREs, cloud engineers, and security teams because it creates a clear record of what infrastructure should exist and how it is configured.
Which Is Better for Infrastructure Creation: Terraform or Ansible?
Terraform and Ansible overlap in some areas, but they are designed for different primary jobs.
Terraform is usually the better choice for provisioning infrastructure resources such as networks, load balancers, databases, IAM roles, virtual machines, Kubernetes clusters, and cloud services.
Ansible is usually the better choice for configuring operating systems, installing packages, managing files, restarting services, and running procedural automation across existing machines.
A practical way to think about it is:
- Use Terraform to create the infrastructure.
- Use Ansible to configure what runs inside that infrastructure.
For example, Terraform can create an EC2 instance, attach an IAM role, open the correct security group ports, and create a DNS record. Ansible can then install NGINX, copy configuration files, create Linux users, and start the service.
For small projects, Ansible may be enough. For larger infrastructure estates, Terraform’s state management, provider ecosystem, module support, and plan/apply workflow usually make it the better choice for infrastructure provisioning.
Is Terraform Better Than CloudFormation?
It depends on the environment.
Terraform is often the better choice when you need a multi-cloud or multi-platform infrastructure-as-code tool. It can manage AWS, Azure, Google Cloud, Kubernetes, VMware, SaaS providers, DNS platforms, monitoring tools, and many other systems.
CloudFormation is AWS-native. It is a strong option when you manage only AWS resources and want a service fully integrated with AWS without introducing another tool. AWS describes CloudFormation as an infrastructure-as-code service for modeling, provisioning, and managing AWS and third-party resources.
Use Terraform when:
- You manage more than AWS.
- You want one workflow across multiple platforms.
- You prefer HCL and Terraform modules.
- You need a large provider ecosystem.
- You want to manage SaaS, DNS, monitoring, and cloud resources together.
Use CloudFormation when:
- You are AWS-only.
- You want native AWS integration.
- Your team already uses CloudFormation deeply.
- You want AWS-managed stack operations.
- You want to avoid external state tooling.
For many AWS-heavy teams, Terraform is still the more flexible choice. For AWS-only teams with mature CloudFormation practices, CloudFormation can still be the right tool.
Is Terraform Still Open Source?
This needs a careful answer.
HashiCorp changed the license for future releases of Terraform and other HashiCorp products from Mozilla Public License v2.0 to the Business Source License v1.1 in August 2023.
For most internal infrastructure teams, Terraform remains freely available. The license change matters most for vendors building products or services that compete with HashiCorp offerings.
The license change also led to the creation of OpenTofu, a Linux Foundation-hosted fork of Terraform. OpenTofu describes itself as an open-source, community-driven infrastructure-as-code tool and a drop-in replacement for Terraform that preserves existing workflows and configurations.
If you are choosing a tool today, the practical decision is usually:
- Use Terraform if you are comfortable with HashiCorp’s licensing and want the official HashiCorp ecosystem.
- Consider OpenTofu if open-source licensing, neutral governance, or long-term vendor independence are important to your organization.
How Do I Learn Terraform for AWS?
The best way to learn Terraform for AWS is to build small, real examples and understand the workflow properly.
Start with these topics:
- Installing the Terraform CLI.
- Understanding providers.
- Creating a simple AWS resource.
- Running
terraform init,terraform plan, andterraform apply. - Understanding Terraform state.
- Using variables and outputs.
- Creating reusable modules.
- Storing state remotely.
- Using workspaces or separate root modules for environments.
- Running Terraform through CI/CD or HCP Terraform.
A good first AWS project is:
- Create a VPC.
- Add public and private subnets.
- Add route tables.
- Add an internet gateway.
- Add a NAT gateway.
- Add security groups.
- Add an EC2 instance.
- Output the instance IP address.
Once you understand that workflow, move on to more realistic patterns such as RDS, ECS, EKS, IAM roles, S3 backends, and reusable modules.
For certification, HashiCorp currently offers Terraform Associate and Terraform Authoring and Operations Professional certifications. The Terraform Associate validates foundational Terraform knowledge, while the professional exam focuses on configuring and managing infrastructure over time.
How Do I Download and Install Terraform?
Terraform is installed as a command-line tool. HashiCorp distributes Terraform as a binary package, and it can also be installed through supported package managers. The current HashiCorp install page lists Terraform 1.15.8 as the latest version.
On Ubuntu or Debian, you can install Terraform from HashiCorp’s package repository:
sudo apt-get update
sudo apt-get install -y gnupg software-properties-common
wget -O- https://apt.releases.hashicorp.com/gpg | \
gpg --dearmor | \
sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg > /dev/null
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(grep -oP '(?<=UBUNTU_CODENAME=).*' /etc/os-release || lsb_release -cs) main" | \
sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update
sudo apt-get install terraform
Verify the installation:
terraform version
On macOS with Homebrew:
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
terraform version
On Windows, you can download the binary from HashiCorp or install it with a package manager such as Chocolatey:
choco install terraform
terraform version
What Are Terraform Providers?
Providers are plugins that allow Terraform to talk to external platforms and APIs.
For example:
- The AWS provider manages AWS resources.
- The AzureRM provider manages Azure resources.
- The Google provider manages Google Cloud resources.
- The Kubernetes provider manages Kubernetes resources.
- The Cloudflare provider manages Cloudflare resources.
- The GitHub provider manages GitHub repositories and settings.
Terraform itself does not know how to create an AWS VPC or an Azure resource group until the correct provider is installed and configured. HashiCorp’s documentation explains that a provider implements every resource type, and without providers Terraform cannot manage infrastructure.
A provider requirement is usually declared like this:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
}
}
Pinning provider versions is important in production. Providers are released separately from Terraform itself, and new provider versions can introduce changes. HashiCorp recommends constraining acceptable provider versions so terraform init does not automatically install an incompatible version.
What Are Terraform Modules?
Terraform modules are reusable blocks of Terraform configuration.
A module can define a common pattern once, such as a VPC, an ECS service, an RDS database, an IAM role, or a monitoring setup. Other projects can then call that module instead of copying the same code everywhere.
A simple module call might look like this:
module "network" {
source = "./modules/vpc"
project_name = "demo"
vpc_cidr = "10.10.0.0/16"
aws_region = "eu-west-2"
}
Modules are useful because they standardize how infrastructure is built. They also reduce copy-and-paste configuration, make reviews easier, and help teams apply consistent naming, tagging, security, and networking patterns.
What Is Terraform State?
Terraform state is how Terraform remembers what it manages.
When Terraform creates a resource, it records information about that resource in state. On the next run, Terraform compares your configuration, the state file, and the actual infrastructure to determine what has changed.
For local testing, Terraform stores state in a local terraform.tfstate file by default. For team environments, local state is not enough. You should use a remote backend or HCP Terraform so state can be stored securely, shared between team members, and locked during runs.
State can contain sensitive information, so it should be protected carefully. Do not commit state files to Git.
Should I Use HCP Terraform, a Remote Backend, or Local State?
Use local state only for learning, testing, and throwaway projects.
Use a remote backend or HCP Terraform for real environments.
A simple rule is:
- Local state: acceptable for tutorials and experiments.
- Remote backend: good for teams that want to manage their own workflow.
- HCP Terraform: good for teams that want remote runs, secure state, policy controls, approvals, VCS integration, private modules, and team access controls.
For AWS projects, many teams use an S3 backend with locking. Others use HCP Terraform to centralize state and workflows on a single platform.
Final Thoughts
Terraform remains one of the most useful infrastructure-as-code tools for cloud and platform engineering. It is particularly strong when you need repeatable infrastructure, code review, remote state, reusable modules, and a consistent workflow across multiple providers.
The biggest changes to be aware of today are the rename from Terraform Cloud to HCP Terraform, the Terraform license change, the growth of OpenTofu, and the move away from long-lived static cloud credentials towards short-lived identity-based authentication.
For AWS engineers, Terraform remains a practical choice. Start with the basics, learn state properly, avoid hard-coded credentials, use modules carefully, and treat infrastructure code with the same discipline as application code.


Leave a Reply