Contents
State is stored by default in a local file named terraform.tfstate.
Terraform uses state to determine which changes to make to your infrastructure. Prior to any operation, Terraform does a refresh to update the state with the real infrastructure.
Mapping to the Real World
Terraform requires some sort of database to map Terraform config to the real world. For example, when you have a resource resource "aws_instance" "foo" in your configuration, Terraform uses this mapping to know that it represents a real world object with the instance ID i-abcd1234 on a remote system.
Terraform expects that each remote object is bound to only one resource instance in the configuration.
Metadata
Alongside the mappings between resources and remote objects, Terraform must also track metadata such as resource dependencies.
Terraform typically uses the configuration to determine dependency order.
Manage Resource State
Examine State with CLI
Run terraform show to get a human-friendly output of the resources contained in your state.
$ terraform show
# data.aws_ami.ubuntu:
data "aws_ami" "ubuntu" {
architecture = "x86_64"
arn = "arn:aws:ec2:us-east-1::image/ami-027a754129abb5386"
block_device_mappings = [
##...
}
# aws_instance.example:
resource "aws_instance" "example" {
ami = "ami-027a754129abb5386"
arn = "arn:aws:ec2:us-east-1:123456789012:instance/i-05a8893f05c6a37be"
##...
}
# aws_security_group.sg_8080:
resource "aws_security_group" "sg_8080" {
arn = "arn:aws:ec2:us-east-1:123456789012:security-group/sg-0adfd0a0ade3eebdc"
description = "Managed by Terraform"
##...
}
Outputs:
aws_region = "us-east-1"
instance_id = "i-05a8893f05c6a37be"
public_ip = "18.212.104.187"
security_group = "sg-0adfd0a0ade3eebdc"Run terraform state list to get the list of resource names and local identifiers in your state file. This command is useful for more complex configurations where you need to find a specific resource without parsing state with terraform show.
$ terraform state list
data.aws_ami.ubuntu
aws_instance.example
aws_security_group.sg_8080
Replace a Resource with CLI
Terraform usually only updates your infrastructure if it does not match your configuration. You can use the -replace flag for terraform plan and terraform apply operations to safely recreate resources in your environment even if you have not edited the configuration, which can be useful in cases of system malfunction.
Replacing a resource is also useful in cases where a user manually changes a setting on a resource or when you need to update a provisioning script. This allows you to rebuild specific resources and avoid a full terraform destroy operation on your configuration. The -replace flag allows you to target specific resources and avoid destroying all the resources in your workspace just to fix one of them.
Run terraform plan -replace="aws_instance.example" to see the actions Terraform would take if you replaced the instance.
$ terraform plan -replace="aws_instance.example"
data.aws_ami.ubuntu: Reading...
aws_security_group.sg_8080: Refreshing state... [id=sg-0adfd0a0ade3eebdc]
data.aws_ami.ubuntu: Read complete after 1s [id=ami-027a754129abb5386]
aws_instance.example: Refreshing state... [id=i-05a8893f05c6a37be]
Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement
Terraform will perform the following actions:
# aws_instance.example will be replaced, as requested
-/+ resource "aws_instance" "example" {
~ arn = "arn:aws:ec2:us-east-1:123456789012:instance/i-05a8893f05c6a37be" -> (known after apply)
# ...
}
Plan: 1 to add, 0 to change, 1 to destroy.
Changes to Outputs:
~ instance_id = "i-05a8893f05c6a37be" -> (known after apply)
~ public_ip = "18.212.104.187" -> (known after apply)As shown in the output, when you apply this change, Terraform will destroy your running instance and create a new one.
Move a Resource to a Different State File
The terraform state mv command moves resources from one state file to another. You can also rename resources with mv. The move command will update the resource in state, but not in your configuration file. Moving resources is useful when you want to combine modules or resources from other states, but do not want to destroy and recreate the infrastructure.
Remove a Resource from State
Use a removed block to remove specific resources from your state. This does not destroy the infrastructure itself, instead it indicates that your Terraform configuration will no longer manage the resource.
Remove the aws_instance.example_new from your project’s state.
Comment out the entire resource "aws_instance" "example_new" block from main.tf and add a removed block to instruct Terraform to remove the resource from state, but not destroy it.
removed {
from = aws_instance.example_new
lifecycle {
destroy = false
}
}
# resource "aws_instance" "example_new" {
# ami = data.aws_ami.ubuntu.id
# instance_type = "t2.micro"
# vpc_security_group_ids = [aws_security_group.sg_8080.id]
# user_data = <<-EOF
# #!/bin/bash
# apt-get update
# apt-get install -y apache2
# sed -i -e 's/80/8080/' /etc/apache2/ports.conf
# echo "Hello World" > /var/www/html/index.html
# systemctl restart apache2
# EOF
# tags = {
# Name = "terraform-learn-state-ec2"
# }
# }Tip
The
removedblock was introduced in Terraform 1.7. Previous versions of Terraform used theterraform state rmcommand to remove resources from state. Ensure you are using the correct version of Terraform for this step.
Apply your configuration:
$ terraform apply
data.aws_ami.ubuntu: Reading...
aws_security_group.sg_8080: Refreshing state... [id=sg-0adfd0a0ade3eebdc]
aws_instance.example_new: Refreshing state... [id=i-084a99085ac1aab41]
data.aws_ami.ubuntu: Read complete after 0s [id=ami-027a754129abb5386]
aws_instance.example: Refreshing state... [id=i-0c517d96d291b7e26]
Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
Terraform will perform the following actions:
# aws_instance.example_new will no longer be managed by Terraform, but will not be destroyed
# (destroy = false is set in the configuration)
. resource "aws_instance" "example_new" {
id = "i-084a99085ac1aab41"
tags = {
"Name" = "terraform-learn-state-ec2"
}
# (32 unchanged attributes hidden)
# (8 unchanged blocks hidden)
}
Plan: 0 to add, 0 to change, 0 to destroy.
Changes to Outputs:
- security_group = "sg-0adfd0a0ade3eebdc" -> null
│ Warning: Some objects will no longer be managed by Terraform
│
│ If you apply this plan, Terraform will discard its tracking information for
│ the following objects, but it will not delete them:
│ - aws_instance.example_new
│
│ After applying this plan, Terraform will no longer manage these objects. You
│ will need to import them into Terraform to manage them again.
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
aws_region = "us-east-1"
instance_id = "i-0c517d96d291b7e26"
public_ip = "54.159.61.68"Confirm the change by reviewing the state with terraform state list:
$ terraform state list
data.aws_ami.ubuntu
aws_instance.example
aws_security_group.sg_8080