In this section, we will learn how to set up lifecycle rules in Terraform.
Previously, we saw that when Terraform updates a resource
it frees the infrastructure to be immutable,
and first deletes a resource before creating a new one
with the updated configuration.
For example,
if we update the file permissions on our local file resource from 777 to 700,
and then run terraform apply,
you would see that the older file is deleted first
and then the new file is created.
Now, this may not be a desirable approach in all cases.
Sometimes you may want the updated version of the resource to be created first
before the older one is deleted,
or you may not want the resource to be deleted at all,
even if there was a change made in its local configuration.
This can be achieved in Terraform by making use of lifecycle rules.
These rules make use of the same block syntax that we have seen many times so far,
and they go directly inside the resource block whose behavior we want to change.
The syntax of a resource block with a lifecycle rule looks like this.
Inside the lifecycle block,
we add the rule which we want Terraform to adhere to while updating resources.
One such argument, or a rule, is the create_before_destroy rule.
Here, we have the same resource block that has been updated
with the lifecycle rule of create_before_destroy set to true.
This rule ensures that
when a change in configuration forces the resource to be recreated,
a new resource is created first before deleting the old one.
Now, there would be cases where we do not want a resource to be destroyed for any reason.
For this, we can make use of the prevent_destroy option.
When it is set to true, Terraform will reject any changes
that will result in the resource getting destroyed
and display an error message like this.
This is especially useful to prevent your resources
from getting accidentally deleted.
For example, a database resource such as MySQL or PostgreSQL
may not be something that we want to delete once it's provisioned.
One important thing to note here is that
the resource can still be destroyed if we make use of the terraform destroy command.
This rule will only prevent resource deletion
from changes that are made to the configuration and a subsequent apply.
The last argument type that we're going to see here
is the ignore changes rule.
This lifecycle rule when applied will prevent a resource from being updated
based on a list of attributes that we define within the lifecycle block.
To understand this better, let's make use of a sample EC2 instance,
which is a virtual machine on the AWS cloud.
This EC2 instance is to be used as a web server
and can be created with a simple resource block like this.
Now, don't worry if this resource block and the arguments look unfamiliar,
we will cover it in much more detail in the EC2 section of the course.
For now, please note that the resource called web server
makes use of three arguments.
The AMI and the instance type are used to deploy a specific type of VM
with a predefined specification.
In this case, the values that we've chosen
deploys a Ubuntu server with one CPU and 1GB of RAM.
We're also making use of a tag called Name,
which has a value of ProjectA-Webserver using the tags argument which is of type map.
When we are on terraform apply, the EC2 instance is created as expected
with a tag called Name and value of ProjectA-Webserver.
Now, if changes are made to any of these arguments,
Terraform will attempt to fix it during the next apply as expected.
For example, if we modify the tag called Name
and change its value from ProjectA-Webserver
to, say, ProjectB-Webserver
either manually or using any other tool, Terraform will detect this change
and it will attempt to change it back to what it was originally,
which is ProjectA-Webserver.
In some rare cases, we may actually want the change in the name
via any other method to be acceptable,
and we want to prevent Terraform from reverting back to the old tag.
To do this, we can make use of the lifecycle block
with ignore changes argument like this.
The ignore changes argument accepts a list as indicated by the square brackets,
and it will accept any valid resource attribute.
In this particular case, we have asked Terraform to ignore changes
which are made to the tags attribute of the specific EC2 instance.
If a change is made to the tags, a subsequent terraform apply
should now show that there are no changes to apply.
The change made to the tags of a server outside of Terraform
is now completely ignored.
Since it's a list, we can update more elements like this.
You can also replace the list with the All keyword.
This is especially useful if you do not want the resource to be modified
for changes in any resource attributes.
We will learn more about lifecycle rules later in the course
when we work with AWS resources.
For now, here's a quick summary of the three-argument types
that we have seen in this lecture.
Now, let's head over to the hands-on labs
and practice working with lifecycle rules in Terraform.