Terraform exams care less about memorizing commands and more about whether you understand state management and the safety of changes.
Many questions map directly to real-world pitfalls: concurrent runs, missing backend configuration, breaking changes in modules, and misuse of -target to cut dependencies.
Associate-level questions test whether you can explain the roles of plan/apply/destroy and what a plan is based on (the .tf declarations, the current tfstate, and the diff against real infrastructure). The Pro exam adds team-operation scenarios such as reviews, concurrent runs, and CI integration.
Classic gotchas include believing plan produces side effects, or not knowing that -refresh-only can surface drift without changing configuration.
How plan/apply interact with remote state and locking
Developer CLI Remote Backend (S3/Azure/GCS) Provider API
| | |
| terraform plan | |
|-------------------------->| 読み取り: tfstate |
| |-------------------------->|
| |<--------------------------|
|<--------------------------| 計画に必要な状態取得 |
| | |
| terraform apply | |
|-------------------------->| ロック取得 (DynamoDB等) |
| |=== LOCK === |
| |-------------------------->|
| |<--------------------------|
|<--------------------------| 変更反映後に状態書き込み |
| |--- UNLOCK --------------- |Minimal configuration example (observe plan diffs via outputs)
terraform {
required_version = ">= 1.0"
}
variable "project_name" {
type = string
default = "demo"
}
locals {
tag = "app-${var.project_name}"
}
output "tag_example" {
value = local.tag
sensitive = false
}
# var.project_name を変更して plan を比較し、apply 前に差分を理解するState is not just a cache — it is the source of truth for the objects Terraform creates and manages. Manual edits are discouraged; the state subcommand is the safe way to manipulate it.
Associate questions cover the basics of state list/show/mv/rm and import. Pro questions lean into drift reconciliation, selective migration, and standardized procedures for team operations.
CLI command examples
# 管理下のリソース一覧
terraform state list
# 単一リソースの詳細(ID・属性)
terraform state show aws_s3_bucket.logs
# モジュール化に伴うアドレス移行
terraform state mv aws_s3_bucket.logs module.storage.aws_s3_bucket.logs
# 既存 VPC の取り込み(ID は実リソースの識別子)
terraform import aws_vpc.main vpc-0abc1234def567890
# ドリフト確認のみ
terraform plan -refresh-onlyA remote backend provides a single source of truth and locking, and is a prerequisite for team operations. When using S3, it is easy to forget DynamoDB-based locking — and without it, concurrent applies cause destructive conflicts.
Exam questions routinely ask which backends support locking, how encryption and permission models differ, and which configuration traps are easy to fall into.
| Backend | Locking | Encryption at Rest | Auth / Permissions Model |
|---|---|---|---|
| S3 (+ DynamoDB) | Lockable via DynamoDB | SSE-S3/KMS | IAM roles / policies |
| azurerm (Blob) | Native locking | Storage default encryption | Azure AD + RBAC |
| gcs | Generations + locking | Server-side encryption | Service accounts + IAM |
| local | None | Optional | Local permissions |
S3 backend (with DynamoDB locking)
terraform {
backend "s3" {
bucket = "tfstate-prod"
key = "network/terraform.tfstate"
region = "ap-northeast-1"
dynamodb_table = "tfstate-lock"
encrypt = true
}
}
# 事前に S3 バケット(バージョニング有効) と DynamoDB テーブル(パーティションキー: LockID) を用意Associate questions focus on module invocation and passing variables and outputs. Pro questions cover version pinning, for_each vs. count, input validation, and resisting the urge to over-generalize.
Key stability is critical for for_each. To avoid destroys, use immutable keys tied to the entity (such as a name).
Module invocation and input validation example
module "vpc" {
source = "git::https://example.com/terraform-modules.git//vpc?ref=v1.4.2"
name = var.project
cidr = var.cidr
azs = var.azs
}
variable "project" {
type = string
validation {
condition = length(var.project) <= 12
error_message = "project は 12 文字以内にしてください。"
}
}
variable "cidr" {
type = string
}
output "vpc_id" {
value = module.vpc.id
sensitive = false
}Lifecycle controls help avoid destructive changes, but overusing them adds complexity. Prefer implicit dependencies (via references) and reach for depends_on only when necessary.
Provisioners are a last resort. Prefer cloud-native configuration mechanisms (User Data, launch templates, etc.) or external tools instead.
Lifecycle and dependency example
resource "aws_launch_template" "app" {
name_prefix = "app-"
image_id = var.ami
instance_type = var.instance_type
lifecycle {
create_before_destroy = true
prevent_destroy = false
}
}
resource "aws_autoscaling_group" "asg" {
name = "app-asg"
desired_capacity = 3
max_size = 5
min_size = 3
launch_template {
id = aws_launch_template.app.id
version = "$Latest"
}
depends_on = [aws_launch_template.app]
}
# プロビジョナの代わりに起動時ユーザーデータ等で初期化Workspaces separate state for the same configuration across environments, but they are not a full security boundary. The recommended approach is to separate buckets and permissions per environment.
Policy tools (such as Terraform Cloud Sentinel or OPA) put guardrails in front of dangerous changes and block them before review.
import associates an existing resource with state. It does not generate configuration files, so you must define the matching resource block in advance.
Workspace and import examples
# 環境用ワークスペース
terraform workspace new staging
terraform workspace select staging
# 既存リソースの取り込み
# 先に対応する resource ブロックを定義しておく
terraform import aws_iam_role.app_role app-role
# Sentinel/OPA は CI/Remote 実行で plan にフックして評価する運用が一般的Associate / Pro
問題 1
Your team uses an S3 backend, but occasional concurrent terraform apply runs have nearly corrupted the state file. Which is the most appropriate remediation?
正解: A
The S3 backend on its own does not provide locking, so enabling locking with a companion DynamoDB table is correct. -lock-timeout only adjusts the wait time; it is not a substitute for a locking mechanism. Workspaces separate state but do not solve concurrent updates to the same environment. Managing tfstate in Git is discouraged.
What is the main difference between terraform plan and apply?
plan only proposes changes with no side effects. apply executes the plan and actually modifies real infrastructure. Reviews and policy checks run against the plan output.
When is it appropriate to use -target?
Reserve it for emergency, narrowly scoped changes such as incident response. Because it ignores parts of the dependency graph, avoid it in routine operations or normal change workflows.
How should sensitive values and credentials be handled?
Use environment variables, the Terraform Cloud variable store, or each cloud's secret manager. Never leave plaintext in tfvars or state files, and minimize exposure with sensitive outputs.
Practice with certification-focused question sets
無料で問題を解いてみるNicheeLab Editorial Team
NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.
HCL Syntax: Terraform's Configuration Language (2026)
HCL2 fundamentals for Terraform — blocks, attributes, expres...
Terraform Authoring & Operations Pro: Complete Guide (2026)
Tactics for the Terraform Pro exam — module authoring, works...
Terraform Providers: Plugin Management Fundamentals (2026)
Provider mechanics — required_providers, versions, mirrors, ...
Terraform Resource Blocks: Declarative Infra Units (2026)
Resource block fundamentals — addresses, references, common ...
Terraform Data Sources: Read-Only External Data (2026)
Data source basics — declaration, refresh behavior, dependen...