What are plan, apply, and destroy in Terraform?

Updated: February 3, 2024 By: Guest Contributor Post a comment

Introduction

Terraform, a popular infrastructure as code (IaC) tool, enables users to define and provision data center infrastructure utilizing a high-level configuration language known as HCL (HashiCorp Configuration Language) or JSON. Among its core commands, plan, apply, and destroy play crucial roles in managing the lifecycle of infrastructure with precision and predictability. This tutorial delves into these commands with examples, progressing from basic to advanced usage.

Understanding Terraform’s Core Commands

Before jumping into code examples, it’s vital to grasp what each command does:

  • Plan: Creates an execution plan. Terraform performs a refresh, unless explicitly told not to, and then determines what actions are necessary to achieve the desired state specified in the configuration files.
  • Apply: Executes the actions proposed in a Terraform plan. This command is the means by which Terraform makes the described infrastructure changes.
  • Destroy: Removes all resources defined in the Terraform configuration. This command is used to tear down the infrastructure managed by Terraform.

Basic Example: A Simple AWS EC2 Instance

Let’s start with a fundamental example: provisioning a single EC2 instance in AWS.

// Define provider
provider "aws" {
  region = "us-east-1"
}

// Define an EC2 instance
resource "aws_instance" "example" {
  ami           = "ami-123456"
  instance_type = "t2.micro"
}

To see what Terraform will do with this configuration, we use the plan command:

$ terraform plan

This will display an execution plan, showing what Terraform intends to do. If the plan is acceptable, you apply it:

$ terraform apply

Finally, to destroy the infrastructure you’ve created:

$ terraform destroy

The output clearly shows each resource that will be removed.

Intermediate Example: Utilizing Variables and Outputs

To make our examples more dynamic and reusable, let’s introduce variables and outputs into our configuration.

// Define variables
variable "instance_type" {
  type    = "string"
  default = "t2.micro"
}

// Use the variable
resource "aws_instance" "example_var" {
  ami           = "ami-123456"
  instance_type = var.instance_type
}

// Define output
output "instance_id" {
  value = aws_instance.example_var.id
}

We run the plan and apply commands again, this time, changes are based on the values defined in variables. The output will display the instance ID upon completion.

Advanced Example: Working with Multiple Environments

Managing different environments (e.g., development, staging, production) becomes more sophisticated with Terraform workspaces. Workspaces allow you to maintain separate state files for different environments within the same configuration.

// Initialize workspace
$ terraform workspace new development
$ terraform workspace new production

// Use the workspace to manage resources
resource "aws_instance" "example_env" {
  count = terraform.workspace == "production" ? 2 : 1
  ami = "ami-123456"
  instance_type = "t2.micro"
}

This configuration provisions one instance for development and two for production. Selection and switching between workspaces are done using the workspace command:

$ terraform workspace select development
$ terraform apply
// Switch to production:
$ terraform workspace select production
$ terraform apply

Destroying resources in workspace-specific environments requires selecting the appropriate workspace first:

$ terraform workspace select development
$ terraform destroy

Conclusion

Terraform’s plan, apply, and destroy commands offer a methodical approach to infrastructure management, enabling precise control over deployment and teardown processes. Through example-driven learning, this guide aims to equip you with the knowledge to effectively utilize these core commands and explore more complex Terraform configurations.