Now that you deeply understand state, it's time to master the operational lifecycle. This objective covers three key areas that every Terraform practitioner needs in production:
Below is a breakdown of the sub-objectives we will cover in this section: Feel free to jump to any section directly, but I recommend going through them in order for the best learning experience.
We'll examine each sub-objective with the full code explanations you've asked for, and then test your understanding with a comprehensive gauntlet.
Source: Import Terraform configuration, Import an existing resource, Command: import
Most organizations don't start with a greenfield Terraform deployment. They have existing infrastructure EC2 instances, S3 buckets, databases—that was created manually through the AWS Console, CLI scripts, or other tools. Terraform knows nothing about these resources.
Import is the process of bringing this existing "brownfield" infrastructure under Terraform management without destroying and recreating it.
What import does: It writes the resource's real-world ID and attributes into your Terraform state file, creating a binding between a resource block in your configuration and an existing cloud resource. From that point forward, Terraform manages the resource as if it had created it.
The modern, recommended approach uses the import block. It's declarative, version-controlled, and integrates with the plan/apply workflow.
Step 1: Write the destination resource block.
You must define the resource in your configuration before importing it. At minimum, the block needs the required arguments for that resource type. You don't need all the fancy settings—just enough that Terraform can plan against it after import.
# We'll import an existing S3 bucket that was created manually.
# This is the "destination" resource that will represent it in Terraform.
resource "aws_s3_bucket" "legacy_assets" {
# 'bucket' is a required argument for aws_s3_bucket.
# The value MUST exactly match the existing bucket's name.
bucket = "my-company-legacy-assets"
}Explanation:
resource "aws_s3_bucket" "legacy_assets" {— Declares the resource block.aws_s3_bucketis the resource type from the AWS provider.legacy_assetsis the local name you're giving it in Terraform. This local name can be anything you want; it doesn't need to match the real bucket name.bucket = "my-company-legacy-assets"— This is a required argument that tells the AWS provider which bucket to manage. The value must be exactly the name of the existing S3 bucket in AWS.
Step 2: Write the import block.
# The import block tells Terraform: "There's already an S3 bucket
# with this ID in AWS. Please associate it with the resource block
# I just defined so Terraform can start managing it."
import {
# 'id' is the cloud provider's unique identifier for the resource.
# For an S3 bucket, the identifier is simply the bucket name.
id = "my-company-legacy-assets"
# 'to' is the Terraform resource address to import into.
# It follows the format: RESOURCE_TYPE.LOCAL_NAME
to = aws_s3_bucket.legacy_assets
}Explanation:
import {— Declares an import block. You can have multipleimportblocks per configuration, one for each resource you're importing.id = "my-company-legacy-assets"— The identifier that the cloud provider uses to uniquely locate this resource. Foraws_s3_bucket, the identifier is the bucket name. Foraws_instance, it would be the instance ID (i-12345). Foraws_vpc, it's the VPC ID (vpc-abc123). This is provider-specific; always check the provider documentation for the correct ID format.to = aws_s3_bucket.legacy_assets— The destination resource address. This must exactly match the resource type and local name you defined in Step 1. Terraform will bind the existing resource to this address in the state file.
Step 3: Run terraform plan.
terraform planTerraform will read the import block, query AWS for the bucket's current attributes, and show you that it will import the resource. It will also show any configuration attributes it will update after import (e.g., if your resource block has additional settings that differ from the actual bucket).
Step 4: Optionally generate configuration.
If you're importing a complex resource and don't know all its current attributes, you can ask Terraform to generate the full configuration for you:
terraform plan -generate-config-out=generated.tfThis creates a file generated.tf with all the resource's arguments filled in based on its actual state. You can then review this file, keep what you need, remove what you don't, and move the relevant parts into your main configuration.
Step 5: Run terraform apply.
terraform applyTerraform imports the resource into the state file. From this point forward, Terraform manages the bucket as if it created it.
Step 6: (Optional) Remove the import block.
Once the import is complete and the resource is in state, the import block has done its job. You can remove it or keep it as a historical record of where the resource came from. The block is idempotent—if you run apply again with the block still present, Terraform sees the resource is already in state and does nothing.
You can import multiple instances of a resource using for_each or count in the import block.
# Import multiple EC2 instances using for_each.
# Assume we have three instances: i-abc, i-def, i-ghi.
resource "aws_instance" "legacy_servers" {
for_each = {
"web" = "i-abc123"
"api" = "i-def456"
"worker" = "i-ghi789"
}
ami = "ami-12345"
instance_type = "t3.micro"
}
import {
for_each = {
"web" = "i-abc123"
"api" = "i-def456"
"worker" = "i-ghi789"
}
id = each.value # The instance ID from the map
to = aws_instance.legacy_servers[each.key] # The resource instance address
}Explanation:
for_each = { ... }— Defines a map where keys are the Terraform instance keys (web,api,worker) and values are the cloud identifiers (i-abc123, etc.).id = each.value— For each iteration, sets the import ID to the cloud resource identifier.to = aws_instance.legacy_servers[each.key]— Specifies the exact resource instance address using theeach.keyas the index.
Before the import block existed, you had to use the CLI command:
terraform import aws_s3_bucket.legacy_assets my-company-legacy-assetsFormat: terraform import RESOURCE_ADDRESS CLOUD_ID
This command directly writes the resource into the state file. It does not generate or validate any configuration. You must manually write the matching resource block afterward. There is no plan step, no review, it's immediate and irreversible on the state file.
The exam may still reference terraform import command syntax, but the import block is the modern best practice.
The official study guide lists these critical limitations:
- Import reads the current state reported by the provider. It cannot determine the intent, health, or history of the resource.
- Import does not generate resource relationships. If your S3 bucket has lifecycle policies, event notifications, or depends on other resources, the
importblock doesn't capture these dependencies. You must manually add those relationships in your configuration. - Import does not detect which arguments you can omit. The generated configuration includes every possible argument, including defaults and empty values. You must prune the generated configuration.
- Not all resources support import. Check the provider documentation for each resource type.
- Import does not guarantee Terraform can manage all aspects of the resource. Some resources created externally may have configurations that Terraform cannot update without recreation.
We'll simulate importing an existing file that was created outside Terraform.
Directory: obj7a-lab
Step 1: Create a file outside Terraform.
# Simulate manually creating a "cloud resource"
echo "This file was created manually, outside Terraform." > manual-resource.txtStep 2: Write the Terraform configuration.
# main.tf
terraform {
required_providers {
local = {
source = "hashicorp/local"
version = "~> 2.5"
}
}
}
# Define the resource we want to import the existing file into.
# The 'filename' argument must match the existing file's path.
resource "local_file" "imported_file" {
filename = "${path.module}/manual-resource.txt"
# 'content' will be overwritten to match the current file content after import
}
# The import block tells Terraform to find the existing file and bind it.
import {
# For the local provider, the file's ID is its SHA256 checksum.
# We provide the file path as the identifier—the provider knows how to resolve it.
id = "${path.module}/manual-resource.txt"
to = local_file.imported_file
}Line-by-line:
import {— Declares the import block for this resource.id = "${path.module}/manual-resource.txt"— The identifier. Forlocal_file, theidis the SHA256 hash of the file content. However, the import process accepts the file path as the identifier and computes the hash internally.${path.module}is a built-in value that evaluates to the absolute path of the directory containing the module where this expression appears.to = local_file.imported_file— Ties the import to theresource "local_file" "imported_file"block we defined.
Step 3: Run the import workflow.
terraform init
terraform plan
# Observe that Terraform will import the file and then show that 'content' will be set to the actual file content.
terraform apply
# Terraform imports the file into state. The file content in state will match the file on disk.Step 4: Verify.
terraform state show local_file.imported_file
# Shows the resource with the imported attributes.Step 5: Clean up.
# Optionally remove the import block from main.tf (it's idempotent, but clean code is better)
# Now Terraform manages the file. Any changes you make to the file will be detected.- True/False: After running
terraform import aws_instance.web i-12345, the matchingresourceblock is automatically generated in your configuration. - Multiple Choice: In an
importblock, what does theidargument represent? A. The Terraform resource address. B. The local name of the resource in the configuration. C. The cloud provider's unique identifier for the existing resource. D. The state file serial number. - Multiple Answer: Which of the following are limitations of
terraform import? (Select TWO) A. It cannot import resources that usefor_each. B. It does not generate resource dependency relationships. C. It cannot import resources created by another IaC tool. D. Not all resource types support import.
Show Answers
- False - The
terraform importcommand does not generate any configuration. You must manually write the matchingresourceblock after the import. Theimportblock in Terraform 1.5+ is the modern way to handle imports, but it also requires you to define the resource block first. - C - The
idargument in animportblock is the cloud provider's unique identifier for the existing resource. This is how Terraform locates the resource to import it into state. - B, D -
terraform importdoes not generate resource dependency relationships (B), and not all resource types support import (D).terraform importcan be used with resources that usefor_eachorcountif you structure the import correctly.
Source: Manage resources in Terraform state, terraform state command
The Terraform CLI provides a suite of subcommands under terraform state for inspecting and manipulating the state file without directly editing the JSON. These commands are your primary debugging tools.
Lists all resource addresses in the state file.
terraform state listOutput example:
random_pet.server
local_file.config
module.vpc.aws_vpc.main
module.vpc.aws_subnet.public[0]
module.vpc.aws_subnet.public[1]
data.aws_ami.ubuntu
Key points:
- Resources are listed in module depth order, then alphabetically.
- Resources with
countorfor_eachshow their instance index ([0],[1],["key"]). - Data sources that are cached in state also appear (prefixed with
data.). - Modules are prefixed with
module.MODULE_NAME.
Filtering:
# List only resources in the vpc module
terraform state list module.vpc.*
# List only aws_instance resources
terraform state list aws_instance.*
# List a specific named resource
terraform state list aws_instance.webDisplays the full attributes of a single resource from the state file.
terraform state show local_file.configOutput example:
# local_file.config:
resource "local_file" "config" {
content = "Hello, Terraform!"
content_base64sha256 = "abc123..."
content_base64sha512 = "def456..."
content_md5 = "ghi789..."
content_sha1 = "jkl012..."
content_sha256 = "mno345..."
content_sha512 = "pqr678..."
directory_permission = "0777"
file_permission = "0777"
filename = "./config.txt"
id = "abc123def456ghi789"
}
Use cases:
- Quickly check the current value of a resource attribute without opening the JSON.
- Verify that the state reflects what you expect after an import.
- Debug why a resource is being recreated: check if its computed attributes differ from what's in state.
Display the entire state in human-readable format (or JSON with -json).
# Human-readable output of the entire state
terraform show
# JSON output for scripting
terraform show -jsonJSON output is useful for:
- Integrating with external tools.
- Parsing resource attributes programmatically.
- Comparing state between environments.
terraform show -json produces a machine-friendly JSON representation of the state which is useful for automation. Example: extract all aws_s3_bucket names with jq:
terraform show -json | jq -r '.values.root_module.resources[] | select(.type=="aws_s3_bucket") | .values.bucket'Note: the JSON schema may change between Terraform versions; pin your Terraform version in CI when relying on this output.
These commands interact directly with the configured backend to download or upload state.
# Download the current state from the remote backend and output as JSON to stdout
terraform state pull > current-state.json# Upload a state file to the remote backend (EXTREMELY DANGEROUS)
terraform state push current-state.jsonWarnings from the study guide:
terraform state pushwill overwrite the remote state. Terraform protects against accidental push by checking thelineageandserialvalues.- If the
serialin the pushed state is lower than the current remote state, Terraform rejects the push (because the remote state has changed since you pulled). - Use
-forceto bypass these protections only if you are absolutely certain. - Always back up the remote state before pushing.
This section collects common command patterns, flags, and CI-friendly examples to help you operate Terraform safely in production.
Key patterns:
- Create and save a plan for review or CI-driven apply:
terraform plan -out=tfplan
# Save machine-readable plan for auditing
terraform show -json tfplan > tfplan.json- Apply a previously saved plan (CI or manual approval):
terraform apply "tfplan"- Use
-detailed-exitcodein CI to detect changes without failing on "no changes":
terraform plan -detailed-exitcode -out=tfplan || PLAN_EXIT=$?
if [ "$PLAN_EXIT" -eq 2 ]; then
echo "Changes detected"
# Optionally fail the pipeline or post a message to PR
fi- Formatting and validation gates (pre-merge):
terraform fmt -check -recursive
terraform validate- Produce JSON state for automated checks and drift detection:
terraform show -json > state.json
jq -r '.values.root_module.resources[] | select(.type=="aws_instance") | .address' state.jsonCI workflow example (simplified):
terraform fmt -check -recursiveterraform init -input=falseterraform validateterraform plan -detailed-exitcode -out=tfplan- If changes, optionally require manual approval then
terraform apply tfplan
-
Notes & best practices:
-
For a concise command reference and CI examples, see the CLI appendix: CLI-Appendix.md.
-
Pin Terraform version in CI to ensure consistent
show -jsonoutput. -
Always run
terraform initearly in CI to download providers and set up the backend. -
Store credentials in secure variables (CI secrets) and prefer short-lived or role-based credentials.
-
Limit
terraform state pushusage; preferterraform import/state mvfor controlled edits.
We'll use the state file from any previous lab (e.g., the obj6d-lab or create a quick one).
Directory: obj7b-lab
File: main.tf
terraform {
required_providers {
random = { source = "hashicorp/random", version = "~> 3.6" }
local = { source = "hashicorp/local", version = "~> 2.5" }
}
}
resource "random_pet" "demo" {
length = 2
}
resource "local_file" "log" {
filename = "${path.module}/${random_pet.demo.id}.log"
content = "Log for ${random_pet.demo.id}"
}Steps:
terraform init && terraform apply -auto-approve- Run
terraform state listto see both resources. - Run
terraform state show random_pet.demoto see its attributes. - Run
terraform showto see the full state in human-readable format. - Run
terraform state pull > state-backup.jsonto save a copy of the state. - Run
terraform state show local_file.logto see the filename and content.
- True/False:
terraform state listshows only managed resources; data sources are excluded. - Multiple Choice: Which command would you use to see the detailed attributes of a specific resource from the state file?
A.
terraform planB.terraform state listC.terraform state showD.terraform output - True/False:
terraform state pushwill unconditionally overwrite the remote state without any safety checks.
Show Answers
- False -
terraform state listwill include cached data sources if they are present in the state; it is not limited to only managed resources. - C -
terraform state showdisplays detailed attributes for a single resource from the state file. - False -
terraform state pushhas safety checks (it validateslineageandserial) and will not unconditionally overwrite the remote state without explicit force.
Source: Debugging Terraform, Enable Terraform logs
When Terraform behaves unexpectedly, a plan shows changes it shouldn't, an apply fails with a cryptic error, a provider returns an API error, you need more information than the CLI provides by default. Terraform has a comprehensive logging system that can be enabled via environment variables.
The primary environment variable is TF_LOG. It controls the verbosity of Terraform's own logs.
# Enable Terraform core logging at DEBUG level
export TF_LOG=DEBUGLog Levels (in order of decreasing verbosity):
| Level | Description |
|---|---|
TRACE |
Most verbose. Shows every internal operation, graph walk, RPC call. |
DEBUG |
Detailed operational information. Useful for debugging configuration behavior. |
INFO |
General operational messages. Good for understanding high-level flow. |
WARN |
Warning messages that don't stop operation. |
ERROR |
Only error messages that cause operation failure. |
Setting the log path:
export TF_LOG_PATH=terraform.logThis redirects all logs to a file instead of stderr. The file will be created or appended in the current working directory.
Example session:
export TF_LOG=TRACE
export TF_LOG_PATH=debug-apply.log
terraform apply
# After completion, review debug-apply.log for detailed informationYou can enable logging only for provider plugins, separate from Terraform Core:
# Only log provider operations, not core Terraform internals
export TF_LOG_PROVIDER=TRACEThis is useful when you suspect a bug in a specific provider but want to avoid the noise from core logging.
You can also target specific providers by combining TF_LOG_PROVIDER with a specific provider log level:
# Only debug the AWS provider
export TF_LOG=INFO # Core at INFO level
export TF_LOG_PROVIDER_AWS=TRACE # AWS provider at TRACE levelProduction debugging:
- An
applyfails with an API error from a cloud provider. EnableTF_LOG=DEBUGand re-run to see the exact API request and response. - A plan shows unexpected resource recreation. Enable
TF_LOG=TRACEto trace the dependency graph and state refresh logic.
Bug reporting:
- When filing a GitHub issue for Terraform Core or a provider, always include
TRACE-level logs. - The study guide recommends using
TF_LOG=TRACEfor bug reports because it provides the highest level of detail for developers.
CI/CD pipelines:
- Set
TF_LOG=WARNfor routine runs to catch any unexpected behaviors without overwhelming the log output. - Set
TF_LOG_PATHto capture logs for post-mortem analysis.
By default, logs are formatted as human-readable text lines. For machine consumption, set:
export TF_LOG=JSONThis produces JSON-encoded log lines at the TRACE level or higher, suitable for parsing by log aggregation tools.
Warning from the study guide: The JSON encoding format is not a stable interface. It may change between Terraform versions. Only use it for tooling that you maintain and update alongside Terraform.
TF_LOG_CORE: Enables logging only for Terraform Core (the orchestration layer).TF_LOG_PROVIDER: Enables logging only for all providers.TF_LOG_PROVIDER_<PROVIDER_NAME>: Enables logging for a specific provider (e.g.,TF_LOG_PROVIDER_AWS).
We'll enable logging for a simple operation and inspect the output.
Directory: obj7c-lab
Step 1: Create a simple configuration.
# main.tf
resource "local_file" "test" {
filename = "${path.module}/log-test.txt"
content = "Testing logging."
}Step 2: Enable logging and run apply.
terraform init
# Set environment variables for verbose logging
export TF_LOG=TRACE
export TF_LOG_PATH=apply-trace.log
terraform apply -auto-approveStep 3: Inspect the log file.
cat apply-trace.log | head -50You'll see detailed entries about:
- Provider initialization
- State file reading
- Plan generation
- Resource creation
- State writing
Step 4: Disable logging.
unset TF_LOG
unset TF_LOG_PATH- True/False: Setting
TF_LOG=INFOprovides more verbose output thanTF_LOG=TRACE. - Multiple Choice: Which environment variable would you set to capture Terraform logs to a file instead of the terminal?
A.
TF_LOG_FILEB.TF_LOG_PATHC.TF_DEBUG_PATHD.TF_LOG_OUTPUT - Multiple Answer: Which of the following are valid
TF_LOGlevels? (Select THREE) A.TRACEB.DEBUGC.VERBOSED.WARNE.ERROR
Show Answers
1. False - `TF_LOG=TRACE` is more verbose than `TF_LOG=INFO`. The order of verbosity from most to least is: `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`. 2. B - `TF_LOG_PATH` is the environment variable used to specify a file path for Terraform logs. Setting this variable directs all logs to the specified file instead of `stderr`. 3. A, B, D - Valid `TF_LOG` levels include `TRACE`, `DEBUG`, `INFO`, `WARN`, and `ERROR`. For this question (choose three), `TRACE`, `DEBUG`, and `WARN` are valid examples. `VERBOSE` is not valid.Sometimes you need to rename resources, move them between modules, or change the logical addressing without recreating the real-world resource. Terraform supports safe refactoring via CLI commands and configuration helpers.
terraform state mv OLD_ADDR NEW_ADDR— Move a resource or an instance within the state file. This does not change the real resource, only the state mapping.
Example: move a resource into a module after refactoring your configuration:
# Move aws_instance.web to module.web.aws_instance.web
terraform state mv aws_instance.web module.web.aws_instance.web-
terraform state rm ADDR— Remove a resource from state without destroying the underlying resource (useful when you intentionally want Terraform to stop managing it). -
movedblock in configuration (Terraform 1.4+) — Declare stable migrations so Terraform can automatically rewrite state duringterraform init/applywithout manual CLI state moves. Usemovedto record renames safely in VCS.
Example moved block:
# In your root module
moved {
from = aws_instance.old_name
to = module.web.aws_instance.web
}This tells Terraform that the resource address aws_instance.old_name has moved to module.web.aws_instance.web. When you run terraform init or terraform apply, Terraform updates the state accordingly.
Hands-On Lab — Move a resource into a module
- Create a simple config with
resource "local_file" "orphan" { ... }andterraform apply. - Create a
moduledirectory and move thelocal_fileblock into the module, changing the address tomodule.m.local_file.orphan. - Add a
movedblock in the root module mapping the old address to the new module address. - Run
terraform initthenterraform planand verify no recreation occurs.
Terraform (and providers) sometimes surface secrets in logs, state, or configuration. Follow these rules to reduce risk:
- Mark outputs and variables as
sensitive = truewhen they contain secrets soterraform outputand plan output do not print them. - Avoid hard-coding secrets in
.tffiles or checked-in files. Use environment variables, secret managers (Vault, AWS Secrets Manager, Azure Key Vault), or CI/CD secret stores. - Do not enable
TF_LOG=TRACE/DEBUGin production for long periods; logs may contain credential material. If you must capture verbose logs for troubleshooting, rotate the credentials immediately afterward. - Use remote backends with encryption-at-rest (S3 with SSE, GCS, Azure Blob Storage) and restrict access with IAM roles. For extra safety, enable server-side encryption with customer-managed keys.
Secrets Lab — Use a secret manager
- Store a secret in Vault or your cloud provider's secret manager.
- Configure your provider to read the secret at runtime (provider-specific example:
data "vault_generic_secret" ...). - Reference the secret in resources/locals but mark outputs referencing it as
sensitive = true. - Run
terraform planand verify secrets do not appear in plan output orterraform showunless explicitly requested with-json(which should be used cautiously).
- Avoid enabling
TF_LOG=TRACE/DEBUGin environments where secrets (API keys, client secrets) might be emitted to logs. Provider requests and responses can include sensitive fields. - In CI, prefer
TF_LOG=WARNand capture logs to an artifact only for failed runs. Use your CI provider's log-redaction features to mask known secret patterns. - If you must collect verbose logs for support, rotate any credentials used during the debug session and store logs in a restricted location.
--
Good luck, Have Fun 😎 and don't forget to Debug your way through these series of questions below
Question 1 (True/False):
The import block can generate a complete Terraform configuration for the imported resource using the -generate-config-out flag during terraform plan.
Question 2 (Multiple Choice):
You have an existing EC2 instance i-abc123 that you want to bring under Terraform management. You write a resource "aws_instance" "managed" block and an import block with id = "i-abc123" and to = aws_instance.managed. What command do you run to complete the import?
⬜ `terraform import`
⬜ `terraform apply`
⬜ `terraform plan -import`
⬜ `terraform state push`
Question 3 (True/False):
After a successful import, you can remove the import block from your configuration, and Terraform will continue to manage the resource normally.
Question 4 (Multiple Choice):
Which CLI command lists all resources currently tracked in the Terraform state file?
⬜ `terraform state show`
⬜ `terraform show`
⬜ `terraform state list`
⬜ `terraform state pull`
Question 5 (Multiple Answer):
Which of the following are valid terraform state subcommands? (Select THREE)
⬜ `terraform state list`
⬜ `terraform state read`
⬜ `terraform state mv`
⬜ `terraform state rm`
⬜ `terraform state refresh`
Question 6 (True/False):
terraform state push can overwrite the remote state file unconditionally, without any safety checks.
Question 7 (Multiple Choice):
What is the recommended TF_LOG level for capturing detailed information needed for a bug report?
⬜ `INFO`
⬜ `DEBUG`
⬜ `TRACE`
⬜ `WARN`
Question 8 (Multiple Answer):
Which of the following environment variables affect Terraform's logging behavior? (Select TWO)
⬜ `TF_LOG`
⬜ `TF_VAR_log_level`
⬜ `TF_LOG_PATH`
⬜ `TF_LOG_CONSOLE`
Question 9 (True/False):
The terraform state show command can display the attributes of a data source if it is present in the state file.
Question 10 (Multiple Choice):
You want to import multiple existing S3 buckets into a single Terraform configuration. What is the best approach with Terraform 1.5+?
⬜ Run `terraform import` once for each bucket.
⬜ Use one `import` block with `for_each` and a destination resource with `for_each`.
⬜ Manually add each bucket's ID to the state file using a text editor.
⬜ Use the `terraform state merge` command.
Question 11 (True/False):
Setting TF_LOG_PROVIDER=DEBUG enables debug logging for Terraform Core but not for any providers.
Question 12 (Multiple Choice):
What does the terraform state rm command do?
⬜ It destroys the resource in the cloud and removes it from state.
⬜ It removes the resource from the state file without destroying it.
⬜ It renames the resource in the state file.
⬜ It moves the resource to a different state file.
Question 13 (True/False):
The import block supports importing resources into child modules using the to = module.MODULE_NAME.RESOURCE_TYPE.NAME address format.
Question 14 (Multiple Answer):
Which of the following are limitations of the import block? (Select TWO)
⬜ It cannot import resources that were created by Terraform.
⬜ It does not automatically detect and add resource dependencies.
⬜ Not all provider resource types support import.
⬜ It requires the resource to be destroyed before import.
Question 15 (True/False):
terraform show -json provides a machine-readable output that is considered a stable interface and safe for production tooling.
Show Answers
- True - The
importblock can generate a complete Terraform configuration for the imported resource using the-generate-config-outflag duringterraform plan. This is a modern feature that helps you quickly create a configuration that matches the imported resource's current state. terraform apply- After defining theimportblock, you runterraform applyto execute the import process. Theimportblock is declarative and integrated into the plan/apply workflow, so you don't use the oldterraform importcommand.- True - After a successful import, the
importblock has done its job of bringing the resource into state. You can remove theimportblock from your configuration, and Terraform will continue to manage the resource as normal. terraform state list- This command lists all resource addresses currently tracked in the Terraform state file. It shows both managed resources and cached data sources.terraform state list,terraform state mv,terraform state rm- These are validterraform statesubcommands.terraform state readis not a valid command; you useterraform state showto read resource attributes.terraform state refreshis also not a valid command; you useterraform refreshto update the state with real-world values.- False -
terraform state pushhas safety checks that prevent unintentional overwrites. It checks thelineageandserialvalues to ensure you are not pushing an outdated state. You must use-forceto bypass these checks, which is not recommended unless you are certain. TRACE- TheTRACElog level provides the most detailed information, which is recommended for bug reports to give developers the best chance of diagnosing the issue.TF_LOG,TF_LOG_PATH- These environment variables control Terraform's logging behavior.TF_LOGsets the log level, whileTF_LOG_PATHspecifies a file to write logs to.TF_VAR_log_levelis not a valid environment variable for logging, andTF_LOG_CONSOLEdoes not exist.- True - If a data source is present in the state file (e.g., because it was cached during a plan),
terraform state showcan display its attributes just like any other resource. - Use one
importblock withfor_eachand a destination resource withfor_each- This is the most efficient way to import multiple resources in Terraform 1.5+. You can define a singleimportblock that iterates over a map of identifiers and resource addresses, rather than running separate commands for each bucket. - False - Setting
TF_LOG_PROVIDER=DEBUGenables debug logging for all providers, but it does not affect Terraform Core logging. To enable debug logging for Terraform Core, you would setTF_LOG=DEBUG. - It removes the resource from the state file without destroying it - The
terraform state rmcommand removes the specified resource from the state file, but it does not destroy the actual resource in the cloud. This can be useful for "orphaning" a resource that you want to manage outside of Terraform. - True - The
importblock supports importing resources into child modules using the appropriate resource address format. You can specify the destination asto = module.MODULE_NAME.RESOURCE_TYPE.NAMEto import directly into a module's resource block. - It does not automatically detect and add resource dependencies, Not all provider resource types support import - The
importblock does not analyze the resource's relationships or dependencies, so you must manually add any necessarydepends_onor other references in your configuration. Additionally, not all resource types in every provider support import, so you should check the provider documentation for limitations. - False - The
terraform show -jsonoutput is not considered a stable interface. The study guide explicitly warns that the JSON format may change between Terraform versions, so it should only be used for tooling that you maintain and update alongside Terraform. It is not guaranteed to be stable for long-term production use.
You have come a long way from what is Terraform to how to maintain infrastructure with Terraform. In the next and final objective, we will explore HCP Terraform, HashiCorp's managed Terraform service that provides additional features for collaboration, governance, and automation.
Let's proceed to Objective 8: Use HCP Terraform, the final objective of the Associate certification.