[Demo Webinar] How to Orchestrate IaC Workflows with Spacelift

➡️ Register Now

Terraform

Terraform in DevOps – IaC, Workflow & Benefits

terraform devops

🚀 Level Up Your Infrastructure Skills

You focus on building. We’ll keep you updated. Get curated infrastructure insights that help you make smarter decisions.

In this article, we introduce Terraform to those new to it, explaining its features and workflow before showing how it works and why it has become a key tool in modern DevOps. We also discuss some key use cases that might apply to your environment and list the common challenges you will face when first getting up and running with Terraform to speed up your implementation. Let’s get acquainted!

  1. What is Terraform?
  2. How does Terraform work?
  3. Why is Terraform used in DevOps?
  4. Deploying Infrastructure as Code (IaC) with Terraform in DevOps
  5. Integrating Terraform with CI/CD tools
  6. Challenges when implementing Terraform in a DevOps setting
  7. Terraform best practices for successful DevOps implementation

What is Terraform?

Terraform is a key infrastructure-as-code (IaC) tool in the DevOps ecosystem. It is designed to manage and automate infrastructure provisioning through code.

Terraform’s declarative syntax lets you specify the desired state of your infrastructure while the tool determines the necessary steps to achieve it. It supports various cloud platforms and on-premises data centers through plugins called providers. These translate Terraform configurations into specific API calls for each platform.

Seamlessly integrating with CI/CD pipelines, Terraform automates infrastructure provisioning and changes, streamlining development workflows and ensuring repeatability across environments.

Terraform features aligned with DevOps practices

As well as the features mentioned above, Terraform also provides the following capabilities that help it fit perfectly into the DevOps pipelines:

Terraform feature Description
Multi-cloud provisioning Terraform supports a wide range of cloud providers, including AWS, Azure, Google Cloud, and other services (like GitHub, and Datadog) through a flexible plugin system. 

You can use Terraform to provision resources like servers, databases, firewalls, and more across different cloud platforms. Provisioners allow users to execute scripts or configuration management tools (like Ansible, Chef, or Puppet) to perform additional infrastructure setup steps.

Remote state management State files can be stored remotely (e.g., in AWS S3, HashiCorp Consul, Spacelift, or Terraform Cloud) to enable collaboration and maintain consistency across team members. 
Policy as code Terraform integrates with tools like HashiCorp Sentinel and OPA to enforce security and compliance policies as code. This ensures infrastructure configurations adhere to organizational standards. Read more: How to Enforce Policy as Code in Terraform
Reusability Modules are reusable configurations that can encapsulate complex resource setups. They help organize and reuse infrastructure code across projects. Terraform provides a public module registry for sharing and discovering modules. 

Terraform also allows you to create and share reusable infrastructure modules within your organization using a private module registry. This promotes code reuse and consistency across projects. You can write custom providers or modules, extending Terraform’s capabilities to meet specific needs.

Drift detection Terraform can continuously monitor your infrastructure and identify any changes that have occurred outside the IaC definitions to help maintain infrastructure consistency and security.
Dependency management Terraform builds a graph of all resources and their dependencies, ensuring that resources are created or destroyed in the correct order.
Parallelism By understanding resource dependencies, Terraform can optimize the provisioning process through parallel execution of independent resources.
Environment management Terraform workspaces allow users to manage multiple environments (like development, staging, and production) within the same configuration. Each workspace maintains its own state file.

How does Terraform work?

In a DevOps workflow, Terraform integrates with CI/CD pipelines to automate infrastructure deployment alongside application releases. Developers write configuration files specifying resources like servers, databases, and networks. Terraform then creates, updates, or destroys these resources as needed using its execution plan.

At its core, Terraform is an engine that reads your configuration and interacts with various providers. Providers enable Terraform to interact with specific cloud platforms or services such as AWS, Azure, Google Cloud, Kubernetes, and many more, with each provider offering access to the resources available on that platform via an API. 

You define your infrastructure using HashiCorp Configuration Language (HCL), which specifies its desired state. Essentially, you tell Terraform what you want, not how to achieve it.

terraform workflow

Terraform workflow in DevOps

One great feature of Terraform is its unified workflow. Infrastructure from multiple providers can be managed using a single configuration language and workflow. The core Terraform workflow consists of the steps described below:

  1. Write: Your desired infrastructure is defined in Terraform configuration files written in HCL. This also includes the provider setup (e.g. which platform you provision to and how to authenticate to it).
  2. Initialize: terraform init is run to initalize Terraform. At this stage, the necessary providers and plugins are downloaded depending on what you specified in your configuration.
  3. Plan: terraform plan generates an execution plan that shows what actions will be taken to reach the desired state of the infrastructure. This helps with understanding and validating the changes before they are applied. Should the plan show unexpected or undesirable changes, you can go back to the write stage and modify your configuration files without affecting your infrastructure.
  4. Apply: After reviewing the execution plan, users can run  terraform apply to apply the changes to update the infrastructure.
  5. Destroy: terraform destroy allows you to remove the infrastructure defined in your configuration files.

Why is Terraform used in DevOps?

Terraform is widely used in DevOps because it automates the provisioning and management of infrastructure, reducing manual work and ensuring consistent deployments. Unlike traditional configuration management tools, Terraform follows a declarative approach, meaning teams define the desired infrastructure state, and Terraform ensures it matches by creating, updating, or deleting resources as needed.

A key advantage is its multicloud support, allowing DevOps teams to manage resources across AWS, Azure, and Google Cloud with a single workflow. It also maintains a state file, which acts as a source of truth, preventing unintended changes and enabling efficient rollbacks.

In short, Terraform’s importance in DevOps lies in its ability to automate, standardize, and version-control infrastructure management, leading to more efficient, reliable, and scalable operations.

Let’s now look at some specific use cases.

Use case examples for Terraform in DevOps

Terraform is primarily used for cloud infrastructure provisioning. For example, it can be used to deploy and manage AWS environments, such as setting up a VPC with public and private subnets, EC2 instances with specific instance types and AMIs, RDS databases with configured backups, security groups with predefined ingress and egress rules, and ALB/NLB load balancers for scalable application delivery.

For containerized applications, Terraform provisions Amazon EKS or self-managed Kubernetes clusters, deploying workloads using Helm charts or Kubernetes manifests.  Immutable infrastructure ensures that deployments are predictable and repeatable. 

Terraform can provision serverless resources like AWS Lambda functions, API Gateway endpoints, DynamoDB tables, and S3 buckets, enabling full serverless deployments without manual configuration.

Network infrastructure automation includes IP whitelisting, VPC peering, VPN gateway setup, and private link configurations to securely connect cloud resources to on-premises environments. With cross-cloud provisioning, Terraform allows teams to manage AWS and Azure environments in parallel, useful for multi-region redundancy and disaster recovery. It automates failover configurations, database replicas, and snapshot policies, ensuring business continuity.

Terraform dynamically configures EC2 Auto Scaling Groups, ALB listener rules, and CloudFront distributions, adjusting resources based on traffic patterns. Workspaces and modules allow teams to maintain environment-specific configurations while centralizing common infrastructure components, improving consistency across development, staging, and production environments.

In addition to provisioning infrastructure, Terraform can enforce security policies across the provisioned infrastructure deployments—for example, using Terraform Cloud’s Sentinel policies or Open Policy Agent (OPA) integrations. This ensures all infrastructure adheres to organizational policies, improving security and compliance.

Deploying Infrastructure as Code (IaC) with Terraform in DevOps

Terraform is a powerful and flexible tool for implementing IaC that allows DevOps teams to automate and manage cloud infrastructure efficiently. The process below will get you started practically with Terraform deploying infrastructure to Microsoft Azure, aligning with DevOps best practices.

If you want to learn more, check out: Managing Infrastructure as Code (IaC) With Terraform.

Step 1: Install Terraform

First, download and install Terraform from the official website, or see our Terraform installation tutorial. Ensure Terraform is correctly installed by running:

terraform -v

Step 2: Define the Azure provider configuration

Create a file named provider.tf inside a new directory to configure Terraform to use the Azure provider.

# provider.tf
provider "azurerm" {
  features {}
}

This enables Terraform to interact with your Azure subscription. Authentication methods include service principal authentication, managed identities, and environment variables. Refer to the official documentation for setup steps.

Step 3: Define infrastructure as code (main.tf)

Create another file named main.tf to define the Terraform configuration. This is where you define your resources using the Terraform docs as a reference. 

The example Terraform code below shows how to define an Azure resource group, Virtual Network, and subnet resources with basic configuration.

resource "azurerm_resource_group" "main" {
  name     = "my-resource-group"
  location = "uksouth"
}

resource "azurerm_virtual_network" "myvnet" {
  name = "my-vnet"
  location = "uksouth"
  address_space = ["10.0.0.0/16"]
  resource_group_name = azurerm_resource_group.main.name
}

resource "azurerm_subnet" "mysubnet" {
  name                 = "my-subnet"
  resource_group_name  = azurerm_resource_group.main.name
  virtual_network_name = azurerm_virtual_network.myvnet.name
  address_prefixes     = ["10.0.0.0/24"]
}

Step 4: Initialize, plan, and apply changes

Navigate to your Terraform project directory and execute the following commands:

  • Run terraform init to initialize Terraform and download the Azure provider.
  • Run terraform plan to preview the changes Terraform will make based on your configuration. Always review the output to ensure accuracy before applying.
  • If the plan looks good, run terraform apply and confirm the execution when prompted. Terraform will provision the defined resources in Azure.

Step 5: Verify and maintain infrastructure

After deployment, use terraform show to inspect the current state or terraform destroy to clean up the resources if needed.

In a DevOps workflow, Terraform configurations should be stored in a version control system (e.g., GitHub, GitLab) and integrated into CI/CD pipelines for automated infrastructure provisioning.

Integrating Terraform with CI/CD tools

Terraform is really powerful, but to achieve an end-to-end secure GitOps approach, you need to use a product that can run your Terraform workflows. Spacelift takes managing Terraform to the next level by giving you access to a powerful CI/CD workflow and unlocking features such as:

  • Policies (based on Open Policy Agent) — You can control how many approvals you need for runs, the kind of resources you can create, and the kind of parameters these resources can have, and you can also control the behavior when a pull request is open or merged.
  • Multi-IaC workflows — Combine Terraform with Kubernetes, Ansible, and other IaC tools such as OpenTofu, Pulumi, and CloudFormation, create dependencies among them, and share outputs
  • Build self-service infrastructure — You can use Blueprints to build self-service infrastructure; simply complete a form to provision infrastructure based on Terraform and other supported tools.
  • Integrations with any third-party tools — You can integrate with your favorite third-party tools and even build policies for them. For example, you can Integrate security tools in your workflows using Custom Inputs.

Spacelift enables you to create private workers inside your infrastructure, which helps you execute Spacelift-related workflows on your end. The documentation provides more information on configuring private workers.

For more information, refer to this blog post, which details Spacelift’s remote state capabilities. 

Let’s look at a simple example of how to use Terraform inside Spacelift. For this example, we will assume you already have a VCS integration with Spacelift. If you don’t and you want to set one up, check out the documentation.

We have this simple Terraform repository that creates EC2 instances. Let’s create a Spacelift stack based on it. 

To do that, we will navigate to Stacks in our Spacelift account and select Create Stack. Then, we will add a name for the stack, select the Space for it (Spacelift resources are spaced, in a similar way that Kubernetes resources are namespaced), and we can add an optional description and labels:

terraform in devops create a stack

Next, we will select the repository and leave everything as default, because we want to run the code from the root directory of the repository:

terraform in devops connect to source code

Now, we will select the vendor we want to use. In this example, we will choose Terraform. We will let Spacelift manage the state for us:

terraform in devops choose vendor

Now that the stack is created, we will use my pre-existing cloud integration for AWS because we want to leverage dynamic credentials. 

If you want to build your own integration, check out the examples here:

terraform in devops cloud integration

As we have some default values for my variables, we can trigger a run, but if you want to make changes, you can go to the Environment tab and add the necessary variables easily there (prefixed with TF_VAR as you would normally do for any environment variables used by Terraform).

terraform in devops ec2 instances

We will add a single variable that changes the number of EC2 instances we will create from one to three, and we will trigger a run.

Remember that Spacelift’s runners go through multiple phases, and you can easily control what happens before and after each one, making the workflow as flexible as you want it to be. For this example, we won’t make any changes.

As soon as the planning phase finishes, you will be asked to confirm the run (this is the default behavior, but you can modify it to deploy your changes automatically).

terraform in devops run

Apart from managing everything for you, Spacelift also offers an AI integration called Saturnhead AI. Saturnhead AI is capable of summarizing a runner phase, but if there are issues with your run, it can also explain why it has failed and help you take action to solve them. You can check out this to enable Saturnhead AI.

Click on Summarize for this example to see the following details:

terraform in devops run summary

As we are happy with the plan and also with the AI summary, we will confirm the run, and the code will be applied. Because we’ve provided an invalid AMI, my code failed, and we clicked on Saturnhead AI’s explain method to find out what we can do to fix this:

terraform in devops ai summary

As soon as we fixed the ami issues, and committed the code to GitHub, a run was triggered automatically:

terraform in devops trigger run

The run finished successfully, and the EC2 instances were created:

terraform in devops created ec2 instances

Challenges when implementing Terraform in a DevOps setting

Implementing Terraform in a DevOps setting raises several challenges. Here are some key ones:

  1. State management complexity — Terraform uses a state file to track infrastructure changes, and managing it securely in a team environment can be difficult. Remote state storage and locking mechanisms (e.g., AWS S3 with DynamoDB) are required to prevent conflicts.
  2. Learning curve — Terraform has its own configuration language (HCL), which requires some learning investment. However, it is considered fairly easy to pick up compared with fully-fledged programming languages. Here is a good place to start learning Terraform: Getting Started With Terraform Tutorial.
  3. Security concerns — Terraform does not provide built-in secret management, so it is necessary to integrate tools like HashiCorp Vault or AWS Secrets Manager to prevent the exposure of sensitive credentials in configuration files.
  4. Potential for overcomplexity — For very simple deployments, Terraform might introduce unnecessary complexity, compared with manual configuration.

Terraform best practices for successful DevOps implementation

Here are five key Terraform best practices for successful DevOps implementation:

  • Use remote state storage with locking — Store Terraform state files remotely (e.g., AWS S3 with DynamoDB locking) to prevent conflicts and enable team collaboration.
  • Use version control for IaC —Store Terraform configurations in Git to track changes, enable rollbacks, and maintain IaC best practices.
  • Use terraform import to bring existing resources under management — Instead of recreating infrastructure from scratch, use terraform import to bring manually created or legacy resources into Terraform state, ensuring consistency without downtime.
  • Plan before apply — Always run terraform plan before terraform apply to preview changes, catch errors early, and avoid unintended modifications.
  • Follow a modular code structure — Organize configurations into reusable modules to improve scalability, maintainability, and consistency across environments.

Read more: 20 Terraform Best Practices to Improve Your Workflows

Key points

Terraform is an industry-standard, IaC tool for deploying resources across multiple cloud services and providers. Its configuration language and workflow are easy to understand, ensuring consistent and repeatable deployments and delivering the many other benefits listed above.

Note: New versions of Terraform are placed under the BUSL license, but everything created before version 1.5.x stays open-source. OpenTofu is an open-source version of Terraform that expands on Terraform’s existing concepts and offerings. It is a viable alternative to HashiCorp’s Terraform, being forked from Terraform version 1.5.6.

Manage Terraform better and faster

If you are struggling with Terraform automation and management, check out Spacelift. It helps you manage Terraform state, build more complex workflows, and adds several must-have capabilities for end-to-end infrastructure management.

Learn more

The Practitioner’s Guide to Scaling Infrastructure as Code

Transform your IaC management to scale

securely, efficiently, and productively

into the future.

ebook global banner
Share your data and download the guide