Plans Introduction
In this lesson, we will learn what Terraform plans are, how they work, and how you can use them in your Terraform project.
We'll cover the following
Terraform plans#
A plan is essentially Terraform showing you how it plans to change the world to fit the desired state specified in your code. Terraform plans provide you with the following details:
- What Terraform will create,
- What Terraform will destroy, and
- What Terraform will update.
This gives you an idea of what Terraform will do before you ask Terraform to do it. Terraform summarises how many creates, updates, and destroys it will do at the bottom of the plan.
In this lesson#
So far in this course, we have been running terraform apply
, which will automatically do a plan first and then wait for you to confirm. When Terraform pauses, it gives you time to review the plan to make sure it is correct before executing it. In this lesson, we will learn how to read plans and go over some key things to look out for.
Project example#
Let’s create a small project so we can explore how plans work:
/
- main.tf
By now, you should be able to understand what the HCL above is going to do. Namely, it is going to set up the AWS provider and create a queue with the name test_queue
.
📝Note: Clicking the run button will run
terraform init
and thenterraform apply
. When prompted, do not typeyes
just yet.
First plan#
You should see a plan that looks something like this:
The plan above is going to create a single SQS queue (as we were expecting). Everything that Terraform is going to create is marked with a +
symbol. The line + resource "aws_sqs_queue" "test_queue"
is showing that Terraform is going to create a new resource. Because of this, every attribute is also marked with +
. This may be obvious when you are creating a new resource, but the attribute markings will be more important later on.
At the bottom of the plan is the summary Plan: 1 to add, 0 to change, 0 to destroy.
. In
the summary, Terraform adds up all of the resources it is going to:
- Create (add),
- Update (change), and
- Destroy.
It is good practice to look at this line first and consider whether any of the numbers look completely wrong. For example, if you are expecting to be creating some new resources and Terraform says 0 to add, 4 to change, 4 to destroy
, then you know Terraform will not be creating anything
and you will want to review the plan carefully.
The plan above is what we are expecting, so let’s confirm it by typing yes
and pressing enter.
Second plan#
Once Terraform has applied those changes, update the aws_sqs_queue
resource to the following:
Now run terraform apply
again. You should see a plan like this:
Notice that this time the resource is marked with ∼
, which means the resource will be updated in place.
An update in place means the resource can be updated without destroying it and recreating it. It is important to spot when an update can happen in place, which is generally safe, and when a resource has to be destroyed first and then recreated (we will cover this case soon). The ∼
symbol next to the visibility_timeout_seconds
attribute is showing that this attribute will be changed if you confirm this apply. You can see that the value is changing from 30
to 45
.
Apply this plan by typing yes
and pressing enter
. This will now modify the queue so that it has a
visibility timeout of 45
seconds
Third plan#
Update the aws_sqs_queue
resource again with the following code:
We are changing the name of the SQS queue from test_queue
to my_queue
. In AWS, there is no way
to change the name of an SQS queue once it is created. To do this, you have to destroy your old queue
and create a new one. Let’s see how Terraform handles the update we have made to our code. Run
terraform apply
and view the plan, which should look something like this:
The symbol next to the aws_sqs_queue
is -/+
. This is a special type of update where Terraform has to destroy your resource and then create a new one to make the change. It is important to note that destroy-then-creates are potentially dangerous, as it means your resource may not be available for a while. Thus, this type of change should be applied with caution. At the bottom,
the summary of the plan states 1 to add, 0 to change, 1 to destroy
, which shows that we are
destroying the resource and then recreating it, even though all we did was update the name of the
queue.
When you apply the change above, there will be a period of time where no SQS queue will exist. What Terraform will do is:
-
First destroy the old queue.
-
Only once the queue is destroyed will it create the new one.
It is possible to create the new queue before deleting the old one by using a resource lifecycle, which will be covered in a later chapter.
As a small aside, if you want to change the name of an SQS queue, a better technique would be to create a new SQS queue in one release so that both queues exist side by side. Once you have both queues, you can switch your application over to the new queue and then do another Terraform release to delete the original queue.
Fourth plan#
Now remove the aws_sqs_queue
resource in the main.tf
file.
Run terraform apply
and, this time, you will see a plan such as:
As we have removed the SQS queue from our Terraform code, you will see that Terraform wants to
remove the SQS queue from AWS. The -
symbol next to the aws_sqs_queue
resource depicts the fact
that Terraform wants to destroy the resource. The summary of the plan also shows that Terraform
has one item to destroy.
Destroys and destroy-then-creates are the key things to look out for when reviewing a Terraform plan. Once a resource is destroyed, any state that was part of the resource could be lost and, obviously, if deleting a key part of your infrastructure could cause an outage.
When reviewing a plan, a good mindset to cultivate is to think about the changes you have made to your Terraform code and see if the plan matches what you are expecting. Start with the summary and see if you are seeing roughly the right amount of adds, updates, and destroys, and then work up from there.
When changing a resource property, carefully check whether a destroy-then-create is needed. If you find the documentation for the resource, it will say force_create
next to the attributes that will cause a destroy-then-create if they are changed. This is what we saw in the SQS example we went through where we updated the name.