

What is a Terraform Plan?
Terraform is a popular tool for managing infrastructure as code. It allows you to define and provision your resources in a declarative way, using a simple and human-readable language. But before you apply your configuration to create or update your infrastructure, you need to plan it. That's where Terraform Plan comes in and the topic of this blog post.
Video Walk-through
Our setup
Let's take a look at our setup.
Requirements
- A GitHub account (all the hands-on sections will utilize GitHub's Codespaces so you won't need to install anything on your machine)
Repository
TL;DR: You can find the repo here.
The Terraform Plan Command
Before jumping into the code example, let's understand some of the concepts around the Terraform Plan command.
Terraform Plan is a command that shows you what Terraform will do before it actually does it. It compares your current state (the existing resources) with your desired state (the configuration file) and generates a plan of action to achieve it. The plan shows you which resources will be created, modified, or destroyed, and how their attributes will change.
Purpose of Terraform Plan
Terraform Plan aims to help you review and verify your configuration before applying it. It gives you a chance to catch any errors or inconsistencies in your terraform code, and to make sure that you are not making any unwanted changes to your infrastructure. It also helps you communicate and collaborate with your team members, by showing them what you intend to do and getting their feedback.
Why is Terraform Plan important?
Planning your infrastructure changes is very important. Let's first talk about the challenges that you may encounter when you don't plan then discuss the importance of running plans.
Challenges without planning
Without planning you may run into the following challenges:
- Run the risk of applying changes that are not intended or expected, which can cause errors, downtime, or security issues.
- May not be aware of the dependencies or conflicts between your resources, which can lead to failures or inconsistencies.
- May not be able to estimate the cost or the impact of your changes, which can affect your budget or your performance.
The Importance of Terraform Plan
Planning helps you:
- Avoid the challenges mentioned above by showing you exactly what Terraform will do and allowing you to review it before executing it.
- Ensure that your configuration is valid and consistent with your desired state and follows the best practices and conventions of Terraform.
- Optimize your resources and reduce waste by showing you what resources are no longer needed and can be removed.
- Improve your collaboration and transparency by sharing your plan with your team members and stakeholders and getting their approval before applying it.
Terraform Plan in Action
To see how Terraform Plan works in action, let's look at a few use case examples based on pulling an NGINX docker image and creating a docker container with this image.
Use Case Examples
Creation of a new resource
The process of creating a new resource is simple and we will take it one step at a time.
- Write configuration files that define the resources and their attributes. Below you will see all the terraform files.
Here is the main.tf file:
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "3.0.2"
}
}
}
provider "docker" {}
resource "docker_image" "nginx_image" {
name = "${var.image_name}:${var.image_tag}"
}
resource "docker_container" "nginx_container" {
name = "web-server"
image = docker_image.nginx_image.image_id
ports {
internal = var.internal_port
external = var.external_port
}
restart = "always"
}
Then we have a variables.tf file that defines the following variables:
- image_name
- image_tag
- internal_port
- external_port
variable "image_name" {
type = string
description = "The name of the Docker image"
}
variable "image_tag" {
type = string
description = "The tag of the Docker image"
}
variable "internal_port" {
type = number
description = "The internal port number for the container"
default = 80
}
variable "external_port" {
type = number
description = "The external port number for the container"
default = 8080
}
We then have a terraform.tfvars file to assign the variable values.
image_name = "nginx"
image_tag = "1.23.3"
internal_port = 80
external_port = 8090
- Run terraform init command to initialize the Terraform folder.
terraform init

- Run the terraform plan command to see the execution plan and what resources will be created and how they will be configured.
terraform plan

- Review the plan and confirm that it matches your expectations.
- Run the terraform apply command to create the resources
terraform apply



Modification of an existing resource
Now let's say you want to modify the container's restart behavior from always restarting to restarting on-failure. Just modify the docker_container resource in the main.tf file as shown below.
resource "docker_container" "nginx_container" {
name = "web-server"
image = docker_image.nginx_image.image_id
ports {
internal = var.internal_port
external = var.external_port
}
restart = "on-failure"
}
terraform plan


Deletion of an existing resource
# resource "docker_container" "nginx_container" {
# name = "web-server"
# image = docker_image.nginx_image.image_id
# ports {
# internal = var.internal_port
# external = var.external_port
# }
# restart = "on-failure"
# }
terraform plan

terraform apply
Planning modes
- Normal mode is the default mode. It compares the current state with the desired state and generates a plan of action to achieve it.
Refresh-only mode is a special mode that only refreshes the state without generating a plan of action.
terraform apply
docker rmi nginx:1.23.3
terraform plan -refresh-only

{
"version": 4,
"terraform_version": "1.4.6",
"serial": 14,
"lineage": "233d2971-7895-7cf7-a361-148f8ca4418d",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "docker_image",
"name": "nginx_image",
"provider": "provider[\"registry.terraform.io/kreuzwerker/docker\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"build": [],
"force_remove": null,
"id": "sha256:ac232364af842735579e922641ae2f67d5b8ea97df33a207c5ea05f60c63a92dnginx:1.23.3",
"image_id": "sha256:ac232364af842735579e922641ae2f67d5b8ea97df33a207c5ea05f60c63a92d",
"keep_locally": null,
"name": "nginx:1.23.3",
"platform": null,
"pull_triggers": null,
"repo_digest": "nginx@sha256:f4e3b6489888647ce1834b601c6c06b9f8c03dee6e097e13ed3e28c01ea3ac8c",
"triggers": null
},
"sensitive_attributes": [],
"private": "bnVsbA=="
}
]
}
],
"check_results": []
}
terraform apply -refresh-only
{
"version": 4,
"terraform_version": "1.4.6",
"serial": 15,
"lineage": "233d2971-7895-7cf7-a361-148f8ca4418d",
"outputs": {},
"resources": [],
"check_results": []
}
Planning options
- The -out flag. This flag allows you to save the output of Terraform plan to a file.
terraform plan -out tfplan

terraform apply tfplan
- The -target flag.
- The -replace flag.
terraform plan -replace docker_container.nginx_container

terraform apply -replace docker_container.nginx_container
- The -var and -var-file flags.
# image_name = "nginx"
# image_tag = "1.23.3"
# internal_port = 80
# external_port = 8081

terraform plan -var image_name=nginx -var image_tag=1.23.3
image_name = "nginx"
image_tag = "1.23.3"
terraform plan -var-file a_random_directory/my_variables_file.txt
- The -destroy flag.
terraform plan -destroy

terraform apply -destroy
Resource Targeting
Resource targeting in Terraform is a feature that allows you to apply changes to only a subset of your infrastructure.
terraform plan -target aws_instance.web -target module.network
terraform apply
terraform plan

terraform plan -target docker_image.nginx_image

terraform apply -target docker_image.nginx_image

Best Practices
| The Practice | Details |
|---|---|
| Plan before Apply | Always run Terraform Plan before Terraform Apply, and review the plan carefully |
| Use Visualization Software | This helps you understand the proposed infrastructure changes. Examples: env0's pretty plan Rover |
| Use a Version Control System (VCS) | This helps you manage your configuration files and commit your changes before running terraform plan |
| Always run speculative Terraform plans | Execute Terraform Plan within your version control on every relevant Pull Request. env0 can help you with automatic plan on pull request |
| Terraform plan to output file | Use the terraform plan command to output to a file and include that file in your CI/CD pipeline and as part of the peer review process. |
| Use Terraform Automation and Collaboration Software (TACOS) | Tools such as env0 help store your state file remotely and securely. |
Conclusion
Terraform Plan is a powerful and useful command that lets you preview the changes that Terraform will make to your infrastructure before applying them. It helps you validate your configuration, avoid errors and unwanted changes, and collaborate with your team. In this blog post, we learned about the purpose and importance of Terraform Plan, and how to use it in different scenarios. We also saw how to save and apply a plan file, and how to use some of the options and flags that Terraform Plan supports. By using Terraform Plan, you can make your infrastructure as code more reliable, predictable, and transparent.

.webp)

![Using Open Policy Agent (OPA) with Terraform: Tutorial and Examples [2026]](https://cdn.prod.website-files.com/63eb9bf7fa9e2724829607c1/69d6a3bde2ffe415812d9782_post_th.png)