TT Lab
Get started
Learn Learning paths Courses

Terraform/OpenTofu Fundamentals

Your First Declaration and Reading the State File

Continue in TT Lab

Goal

You confirm by hand that a single declaration produces two results at once, the real file and the state file, and learn to open the state and read resource addresses, serial, and dependencies.

Why it matters

When you first meet a declarative tool it looks like "memorizing commands," but what you actually need to learn is on what basis the tool decides. Terraform builds a plan by comparing three things: the code (the desired state), the state file (the last known state), and the actual infrastructure (what exists now). So if you lose the state file, the tool regards resources that already exist as "never seen" and tries to create them again, and it says "I will delete" for ghost resources left in the state. This is why in this lab you open the state directly with jq. One more thing: whether to hardcode or reference a value is not a matter of taste but a matter of the graph. Only when you reference does the tool know the order, and when the earlier resource later changes, the later resource is updated along with it.

Steps

  1. Copy /opt/lab/fixtures/terraform/starter/main.tf to /root/tf/first/main.tf and initialize in that directory. The required_providers block must remain as it is, and after initialization /root/tf/first/.terraform.lock.hcl and /root/tf/first/.terraform/providers must exist, and the local provider must be listed in the lock file.
  2. In main.tf, declare a resource whose type is local_file and whose name is hello. The filename is /root/tf/first/out/hello.txt, and the argument that holds the content is named content.
  3. Apply to create /root/tf/first/out/hello.txt. Set the content to hello opentofu. After applying, in /root/tf/first/terraform.tfstate, local_file.hello must be registered, the content recorded in the state must be exactly the same as the actual file content, and the version of the state must be 4.
  4. Add a resource whose type is random_pet and whose name is suffix, and apply. Set length to 2 and do not give prefix. random_pet.suffix must appear in the state, and the generated name must be in the form 단어-단어 (word-word).
  5. Change the content of hello to hello labhub and apply again. Both the file content and the content recorded in the state must be exactly hello labhub, and the serial of the state must be 2 or more.
  6. Create a resource whose type is local_file and whose name is temp once, as /root/tf/first/out/temp.txt, and then remove it again. Save the output from the removal to /root/tf/first/out/destroy.txt. Afterward, the temp.txt file and local_file.temp in the state must be gone, and local_file.hello must remain.
  7. Save the list of resource addresses registered in the state to /root/tf/first/out/state-list.txt. local_file.hello and random_pet.suffix must each appear on one line, and local_file.temp must not (extract it after finishing step 6).
  8. Create a resource whose type is local_file and whose name is summary as /root/tf/first/out/summary.txt. The content must include both the name made by random_pet.suffix and hello labhub, and you must put in both values by referencing attributes of other resources. After applying, for local_file.summary in the state, its dependencies must show random_pet.suffix.

Notes

Initialize the working directory and download the provider

Copy /opt/lab/fixtures/terraform/starter/main.tf to /root/tf/first/main.tf and initialize in that directory. The required_providers block must remain as it is, and after initialization /root/tf/first/.terraform.lock.hcl and /root/tf/first/.terraform/providers must exist, and the local provider must be listed in the lock file.

The fixture's starter file already contains required_providers. If you copy that file to the working directory and initialize, the lock file and .terraform/providers are created. This environment downloads from the filesystem mirror inside the image instead of the internet.

Declare a local_file resource

In main.tf, declare a resource whose type is local_file and whose name is hello. The filename is /root/tf/first/out/hello.txt, and the argument that holds the content is named content.

In resource "타입" "이름" (type, name), the second label becomes the latter part of the address. Note that the argument that holds the file content is not in the plural form.

Apply to create the file and the state together

Apply to create /root/tf/first/out/hello.txt. Set the content to hello opentofu. After applying, in /root/tf/first/terraform.tfstate, local_file.hello must be registered, the content recorded in the state must be exactly the same as the actual file content, and the version of the state must be 4.

When the apply finishes, the actual file and terraform.tfstate are created together. Compare whether the content recorded in the state is the same as the actual file content — a state in which the two diverge is exactly drift. Also check what the version field is.

Make a random name with random_pet

Add a resource whose type is random_pet and whose name is suffix, and apply. Set length to 2 and do not give prefix. random_pet.suffix must appear in the state, and the generated name must be in the form 단어-단어 (word-word).

random_pet makes a name of words joined by hyphens. Find which argument sets the number of words, and do not give a prefix.

Change the declaration and apply again

Change the content of hello to hello labhub and apply again. Both the file content and the content recorded in the state must be exactly hello labhub, and the serial of the state must be 2 or more.

If you change only the content and apply again, the serial of the state goes up. The value recorded in the state and the actual file must be exactly the same, so do not let a newline slip in at the end.

Delete only the temporary resource

Create a resource whose type is local_file and whose name is temp once, as /root/tf/first/out/temp.txt, and then remove it again. Save the output from the removal to /root/tf/first/out/destroy.txt. Afterward, the temp.txt file and local_file.temp in the state must be gone, and local_file.hello must remain.

If you delete the block from the declaration and apply again, only that resource disappears. Before deleting, read the output first and check that a resource you should keep is not also a target.

Extract the addresses registered in the state

Save the list of resource addresses registered in the state to /root/tf/first/out/state-list.txt. local_file.hello and random_pet.suffix must each appear on one line, and local_file.temp must not (extract it after finishing step 6).

There is a subcommand that shows only the addresses of what is in the state. If a resource you already deleted remains in the list, you have taken the steps in the wrong order.

Make a summary file with references

Create a resource whose type is local_file and whose name is summary as /root/tf/first/out/summary.txt. The content must include both the name made by random_pet.suffix and hello labhub, and you must put in both values by referencing attributes of other resources. After applying, for local_file.summary in the state, its dependencies must show random_pet.suffix.

If you reference another resource's attribute with an expression, a dependency arises automatically. If you type a value you saw by eye into a string, the file content is right but dependencies is empty and it fails.