Updated: Aug 9, 2020
When you are building infrastructure with Terraform config, a state file, called terraform.tfstat, gets generated locally in the .terraform directory. This state file contains information about the infrastructure and configuration that terraform is managing. When working on a team, it is better to store this state file remotely so that more folks can access it to make changes to the infrastructure.
What is a tfstate file?
The state file contains information about what real resources exist for each object defined in the terraform config files. For example, if you have a DNS zone resource created in your Terraform config, then the state file contains info about the actual resource that was created on AWS.
Here is an example of creating a DNS zone with Terraform along with its state file:
Store tfstate file remotely in S3
Instead of storing the file locally on the system, terraform provides us a way with which we can store the tfstate file in an S3 bucket.
For demo, follow the below code
Note that bucket to be used as back-end must exist prior to we can use it.
As your Terraform usage becomes more advanced, there are some cases where you may need to modify the Terraform state.
It is important to never modify the state file directly. Instead, make use of terraform state command.
There are multiple sub-commands that can be used with terraform state, these include:
The terraform state list command is used to list resources within a Terraform state.
Sub Command - Move
The terraform state mv command is used to move items in a Terraform state.
This command is used in many cases in which you want to rename an existing resource without destroying and recreating it.
Due to the destructive nature of this command, this command will output a backup copy of the state prior to saving any changes
terraform state mv [options] SOURCE DESTINATION
Sub Command - Pull
The terraform state pull command is used to manually download and output the state from a remote state.
This is useful for reading values out of state (potentially pairing this command with something like jq).
Sub Command - Push
The terraform state push command is used to manually upload a local state file to a remote state.
This command should rarely be used.
Sub Command - Remove
The terraform state rm command is used to remove items from the Terraform state.
Items removed from the Terraform state are not physically destroyed.
Items removed from the Terraform state are only no longer managed by Terraform
For example, if you remove an AWS instance from the state, the AWS instance will continue running, but terraform plan will no longer see that instance.
Sub Command - Show
The terraform state show command is used to show the attributes of a single resource in the Terraform state.
State file locking
If the state file is stored remotely so that many people can access it, then you risk multiple people attempting to make changes to the same file at the exact same time. So, we need to provide a mechanism that will “lock” the state if it is currently in-use by another user. We can accomplish this by creating a DynamoDB table for Terraform to use.
Whenever you are performing a write operation, terraform would lock the state file.
This is very important as otherwise during your ongoing terraform apply operations, if others also try for the same, it would corrupt your state file.
Person A is terminating the RDS resource which has associated rds.tfstate file
Person B has now tried resizing the same RDS resource at the same time.
For the S3 backend, you can make use of the DynamoDB for state file locking functionality.
Importing existing resources with Terraform
It might happen that there is a resource that is already created manually.
In such a case, any change you want to make to that resource must be done manually.
Terraform is able to import existing infrastructure. This allows you to take resources you've created by some other means and bring it under Terraform management.
The current implementation of Terraform import can only import resources into the state. It does not generate configuration. A future version of Terraform will also generate configuration.
Because of this, prior to running terraform import it is necessary to write manually a resource configuration block for the resource, to which the imported object will be mapped.
To demonstrate the use of terraform import, we are going to create a security group manually and import it with terraform import
All the code is available at: Linuxadvise Github Repo
That's all for this article.
Happy learning :)