Author: Nagarjuna Rachakonda
What is Terraform?
Before we dive into the article and learn about the various Terraform State commands, let’s look at some of the fundamental concepts of Terraform.
Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. It can manage existing and popular service providers as well as custom in-house solutions.
Configuration files describe to Terraform the components needed to run a single application or your entire datacenter. Terraform generates an execution plan describing what it will do to reach the desired state, and then executes it to build the described infrastructure. As the configuration changes, Terraform is able to determine what changed and create incremental execution plans which can be applied.
The infrastructure Terraform can manage includes low-level components such as compute instances, storage, and networking, as well as high-level components such as DNS entries, SaaS features, etc.
Why do we need to use Terraform?
Let us say, you have a web application consisting of a UI, Back-end module and Database that you want to deploy in a cloud environment, for example AWS or Google Cloud or Microsoft Azure. Next question that will come to your mind is how do you create the servers or containers where your code will be deployed and how do you create the Database server? Would you do it manually using the consoles provided by the service providers? If you do it manually and create your dev environment, then how do you successfully replicate the same in your Production environment? What if you need to change a piece of infrastructure? You might need to make the same change in multiple environments manually which is prone to manual errors and inconsistent behaviours.
This often results in application downtime, loss of business availability etc. causing unexpected issues. That is where scripting your infrastructure is useful. If you create the infrastructure such as EC2 instances, EKS (Elastic Kubernetes Service) or ECS (Elastic Container Service) or RDS (Relational Database Service) using tools like Terraform, you can version your infrastructure code and deploy it in multiple environments in a consistent manner.
There are other tools available to create the cloud infrastructure but Terraform can manage and create the infrastructure for multiple service providers like AWS, Google Cloud and Azure etc. You only need to learn how to write terraform to create the resources in multiple cloud providers rather than learning each and every provider’s infrastructure creation tools and scripting languages.
Another benefit is that it will show you what changes it will make as a result of your configuration changes and you have the opportunity to decide if you want to go ahead before affecting the actual cloud environment. We often have manual approval steps between terraform plan and terraform apply to make sure that we are happy with the changes that terraform is going to make for us.
What is the Terraform State file?
Configuration of all the infrastructure resources that you create in a cloud environment is stored in a state file (JSON) by Terraform. It uses this file to maintain the actual state of the resources and when you run terraform plan, it can compare your configuration (from a local project resources or git repos) against the state file and display what changes will be made.
What if you need to modify Terraform State?
In most scenarios you don’t need to interfere with Terraform State as you would like to keep things as automated as possible.
But there may be scenarios where you would need to play with Terraform State like moving resources from one remote state file to another, destroying resources and removing resources from state etc.
One example of when you might want to do is, after setting up all your resources in a VPC (Virtual Private Cloud, you can think of it like a Data Center) in a certain region, if you need to re-create the VPC but you want to re-use some common non-VPC resources, for example Route 53 domains or S3 buckets etc, then these commands would be useful to you. This will also apply if you are moving to a different region and want to retain the common AWS resources instead of deleting them and re-creating them again. In some cases you will need the same name space servers or the domain name that you initially created.
Moving state between two remote Terraform State files
So the first thing to do is go to the root of your Terraform project from where you are trying to move the state and initialise the backend config.
The above command upgrades the terraform modules, downloads the git modules and initialises the backend.
The output of this command should be something like:
Terraform has been successfully initialized!
You can optionally do a Terraform plan here to make sure that you don’t have any infrastructure changes to make.
This will check your local configuration files and compare it with the terraform state file and display any changes that would be made. Ideally you shouldn’t have any changes to be made.
Now you can pull the state into a local state file.
You will see that a state file is now created in the directory one level up. You can repeat the above steps in another Terraform project to where you are trying to move the state. As a result of that you would have created say `state2.tfstate` file.
Now you can move the state from one file to another using the below command.
This command will copy the whole module to the state2.tfstate file. You can also move individual resources.
Now go to the root of your new Terraform project and execute the below command to push the Terraform State to your back end bucket.
You can push the state1.tfstate file as well to ensure that AWS resources that you moved to the new state are no longer managed by the old project.
So when you run terraform plan and apply next time from the new project, it won’t create the resources again. And you can happily keep your existing AWS or any other cloud resources.
Destroying resources created using Terraform
If you need to destroy resources like AWS EKS cluster, EC2 nodes, Security Groups etc., you don’t need to do that manually in AWS console. That will be a very tedious process and you will need to delete all the dependent resources yourself and it’s a pain identifying them.
The easiest way to do that is to use Terraform destroy command.
This command will display all the AWS resources that it will delete for you. It will identify all the dependent resources and list them as well. It will ask for confirmation before deleting the resources.
Once you confirm, all the resources listed will be deleted from your infrastructure and also from the terraform state file. If you run the same project again, like Terraform init, plan and apply scripts, terraform will create all those resources for you again. You can also destroy specific resources instead of the whole module.
Deleting resources in Terraform State
Sometimes you may decide to delete a resource from the AWS console. And you don’t want Terraform to create those resources again. In that scenario, you can delete the resources from the state file.
This will display the value of the output variable from the terraform state file.
I hope these commands are useful for you.
Sign up to our newsletter
If you enjoyed this blog by Nagarjuna, why not sign up to our monthly newsletter? We’ll keep you up-to-date with all the latest content from our editorial team. Plus you’ll get sneak previews of new material hot off the press.
Who contributed to this article
Nagarjuna RachakondaSenior Software Engineer, BlackCat
Nagarjuna Rachakonda is a Senior Software Engineer at BlackCat Technology Solutions and AWS certified Solutions Architect (associate). He has worked on IT systems across multiple industries such as Utilities, Insurance, Finance & Risk and Scientific Publishing Sectors. He has got vast experience working on various technologies including Java, Spring, React, AWS, Docker, Kubernetes etc. He is a nature lover, enjoys watching and playing cricket, loves traveling and has a passion for learning and sharing knowledge with others.