Skip to content

Glossary

This course’s vocabulary spans three layers: Terraform core (resource, provider, state, module, plan/apply/destroy) that works the same on every cloud; Terragrunt (unit, dependency, root config, stacks) that keeps many environments DRY; and AWS-specific pieces (the S3 backend’s native locking, IAM role assumption, Secrets Manager) that only make sense once you know which provider you’re reading. When a lesson uses a term you’re unsure about, or unsure whether it’s still current for Terraform 1.16 / Terragrunt 1.1, look it up here.

TermMeaningLesson
applyterraform apply executes the actions in a plan against real infrastructure — the only core-workflow command that actually creates, updates, or destroys anything; given no saved plan file it generates one first and asks for confirmation.The Terraform Workflow
assume_roleA block inside the AWS provider config that has the provider assume an IAM role (cross-account or elevated) for every API call it makes, instead of using the invoking credentials directly — the standard way to run Terraform against a different account than the one your CI role lives in.Secrets and Credential Management
aws_caller_identityA zero-argument data source returning the account ID, user ID, and ARN of whatever credentials the AWS provider is currently using — the standard way to confirm which account a plan is about to run against before you apply.HCL, Providers, and Resources
aws_iam_openid_connect_providerRegisters an OIDC identity provider (e.g. GitHub Actions’ token issuer, token.actions.githubusercontent.com) with IAM so a CI pipeline can assume a role via short-lived, federated tokens instead of long-lived AWS access keys stored as CI secrets.Secrets and Credential Management
backendThe plugin that decides where Terraform’s state is stored and how operations against it are locked — configured once in a terraform { backend "s3" {} } block; changing the block’s arguments requires re-running terraform init (with -migrate-state to move existing state).Remote Backends and Locking
TermMeaningLesson
catalog / scaffoldterragrunt catalog browses a configured set of module repositories and interactively scaffolds a new unit from one — writing its terragrunt.hcl and starter inputs for you — instead of hand-writing a unit from scratch every time.Terragrunt HCL and the Root Config
checkovA static-analysis scanner (Bridgecrew/Palo Alto) that runs against Terraform source before any plan, checking built-in policies (public S3 buckets, unencrypted volumes, open security groups, …) — run via checkov -d . or its GitHub Action, which must be pinned to a specific ref rather than @master since it can introduce breaking policy changes on any push.Policy as Code and Static Analysis
configuration_aliasesDeclared in a module’s required_providers block, it lists the named provider aliases (e.g. aws.east, aws.west) the module expects its caller to pass in via a providers = {} argument — without it, an aliased provider can’t cross a module boundary at all.Module Composition and Sources
countThe older, index-based way to turn a single resource/module block into N near-identical copies (resource.name[0], [1], …) — fragile to reordering, because removing a middle element from the source list shifts every index after it and forces those resources to be destroyed and recreated.Count and For Each
create_before_destroyThe lifecycle { create_before_destroy = true } meta-argument flips the default destroy-then-create replacement order to create-first — required whenever the old resource must keep serving traffic, or keep existing because something else still references it, until its replacement exists.HCL, Providers, and Resources
TermMeaningLesson
data sourceA read-only lookup (data "aws_ami" "..." {}) that fetches information about a resource Terraform doesn’t manage — either something that already exists (a shared VPC) or a provider computation (an AMI ID matching filters) — and can never be created, updated, or destroyed by Terraform itself.HCL, Providers, and Resources
default_tagsA block inside the AWS provider config applying a fixed set of tags to every taggable resource the provider manages, merged with (and overridden by) any tags set directly on a resource — the standard way to guarantee a cost-center or owner tag without repeating it on every resource block.HCL, Providers, and Resources
-detailed-exitcodeA flag on terraform plan that changes its exit code from the plain 0/1 to 0 (no changes), 1 (error), or 2 (changes present) — what a CI pipeline actually checks to decide whether a plan needs a human approval step or can be skipped.CI/CD for Infrastructure
dependency / dependenciesA Terragrunt dependency block reads another unit’s outputs as inputs (after running its own plan/apply first); the plural dependencies block instead just ensures ordering against one or more units without exposing their outputs.Dependencies Between Units
destroyterraform destroy (or apply -destroy) plans and executes the removal of every resource currently tracked in state — the same plan/apply pipeline as normal changes, just with every action set to delete.The Terraform Workflow
driftAny difference between what’s in state and what actually exists in AWS — caused by a manual console change, another tool, or an out-of-band process — that only terraform plan/refresh surfaces, since Terraform never polls continuously on its own.Drift Detection and Import
DynamoDB lock table (legacy)Before S3-native locking, the S3 backend’s dynamodb_table argument named a DynamoDB table (partition key LockID) used to hold a lock item during operations — still supported, but a new backend no longer needs one at all if it uses use_lockfile instead.Remote Backends and Locking
dynamic blockGenerates a repeated nested block (e.g. multiple ingress {} blocks inside a security group) from a list or map at runtime — the nested-block equivalent of for_each on a resource, needed because a resource’s own nested blocks can’t take for_each directly.Count and For Each
TermMeaningLesson
ephemeralAn ephemeral "..." {} resource or an ephemeral = true variable/output (Terraform 1.10+) exists only during a single plan/apply — never written to state or a plan file — the mechanism a short-lived credential or generated password can flow through without ever landing on disk.Sensitive Data and Team Workflows
error_hookA Terragrunt hook (inside terraform { error_hook "..." {} }) that runs only when the wrapped Terraform command fails, matched against the error output by on_errors regexes — used for cleanup or alerting that a plain before_hook/after_hook can’t express.Terragrunt HCL and the Root Config
--filterThe current Terragrunt flag for narrowing which units a run --all targets (by path, dependency direction, or a saved query) — the replacement for the older, now-removed --terragrunt-include-dir/--terragrunt-exclude-dir pair.Running Many Units at Once
find_in_parent_foldersAn include block’s find_in_parent_folders() function walks upward from a unit’s directory to locate a named file (usually root.hcl) — the mechanism that lets every unit include the same root config without hardcoding a relative path that breaks when units move.DRY Configuration with include
find / listterragrunt find and terragrunt list discover units under the current tree (optionally as JSON, optionally filtered by dependency) — the read-only discovery commands behind --filter and behind editor/CI tooling that needs to enumerate units without running anything.Running Many Units at Once
for_eachTurns a single resource/module block into one instance per entry of a map or set of strings, keyed by that map’s key (resource.name["prod"]) instead of a numeric index — removing an entry only affects that one instance, unlike count.Count and For Each
force-unlockterraform force-unlock <lock-id> removes a stuck state lock by ID without running any plan/apply — the escape hatch for a lock left behind by a crashed process or a killed CI job, and the one command where using it on a lock that’s still legitimately held can corrupt state.Remote Backends and Locking
TermMeaningLesson
generateA Terragrunt generate "..." {} block writes a file (a provider block, a backend block, a version constraint) into a unit’s working directory before Terraform runs — the mechanism that lets every unit share identical provider/backend boilerplate defined once in root.hcl.Terragrunt HCL and the Root Config
HCP TerraformHashiCorp’s managed remote-execution platform (formerly Terraform Cloud): runs plan/apply on its own workers, stores state, and gates applies behind approvals and Sentinel policy — a managed alternative to self-hosting an S3 backend plus a CI pipeline.CI/CD for Infrastructure
IAM policy (least privilege for a CI role)The JSON policy attached to the IAM role a CI pipeline assumes should list only the actions/resources that pipeline’s applies actually need — a role broad enough to iam:*/*:* turns any compromised pipeline into full account compromise, the single most common production-checklist finding.Secrets and Credential Management
ignore_changesInside lifecycle {}, ignore_changes = [tags] (or a specific list of attributes) tells Terraform to stop reporting — and stop reverting — drift on just those attributes, commonly used where another process (autoscaling, a tagging Lambda) legitimately owns them.Drift Detection and Import
import blockA declarative import { to = ..., id = ... } block (Terraform 1.5+) brings an existing resource under management by including it in a normal plan/apply, instead of the older imperative terraform import command — reviewable in a PR before anything actually changes.Drift Detection and Import
includeA Terragrunt include "root" { path = find_in_parent_folders() } block pulls another .hcl file’s configuration into the current unit, merging its generate/remote_state/inputs — the primary DRY mechanism, alongside dependency, for a multi-unit tree.DRY Configuration with include
InfracostEstimates the monthly cost delta a plan would introduce by matching planned resource changes against cloud pricing data — run against terraform show -json’s plan output, commonly posted as a PR comment alongside a policy-as-code gate.Policy as Code and Static Analysis
TermMeaningLesson
KMS encryption (kms_key_id)The S3 backend’s kms_key_id argument (with encrypt = true) has S3 encrypt the state object with a customer-managed KMS key instead of the default SSE-S3 key — needed wherever state itself must meet a customer-managed-key compliance requirement.Remote Backends and Locking
lifecycleThe lifecycle {} meta-argument block available on any resource, holding create_before_destroy, prevent_destroy, ignore_changes, and replace_triggered_by — the one place Terraform lets you override its default replace/destroy behavior per resource.HCL, Providers, and Resources
localA locals {} block names an expression once so it can be reused across a module without repeating it — never itself an input or an output, purely an internal, computed value.Outputs and Locals
lockThe record a backend writes before starting a state-modifying operation, preventing a second concurrent plan/apply from reading or writing the same state at the same time — S3’s native lock is a .tflock object created via a conditional (if-none-match) write.Remote Backends and Locking
TermMeaningLesson
mock_outputsInside a Terragrunt dependency block, mock_outputs supplies fake values for the dependency’s outputs so commands like validate/plan can run even before the dependency has ever been applied — restricted by default to plan-only via mock_outputs_allowed_terraform_commands so a real apply can’t silently run against fake data.Dependencies Between Units
mock_providerA terraform test construct (1.7+) that substitutes a real provider with a mock returning either computed placeholder values or an explicit override — the mechanism that lets a test run plan/apply with zero real credentials and zero real API calls.Testing Modules
moduleA reusable, self-contained group of .tf files taking variable inputs and exposing outputs — called from elsewhere with a module "name" { source = ... } block, the unit of composition and reuse above a single resource.Writing a Reusable Module
moved blockA declarative moved { from = ..., to = ... } block (Terraform 1.1+) records a resource/module rename or move in state as a refactor, not a destroy+create — reviewable in a plan, and safe to leave in the config indefinitely for anyone who applies from an older state.Drift Detection and Import
null_resource (legacy)The pre-1.4 way to attach provisioner/triggers behavior with no real infrastructure backing it — superseded by terraform_data, which does the same job as a first-class part of Terraform core instead of a separate provider dependency.Testing Modules
TermMeaningLesson
OIDCOpenID Connect: a CI pipeline exchanges its platform-issued, short-lived identity token for temporary cloud credentials via a trust relationship configured once — the mechanism that removes long-lived cloud access keys from CI secrets entirely.Secrets and Credential Management
outputExposes a value from a module (or the root module, where terraform output reads it) to whatever called it — a Terragrunt dependency block reads a unit’s outputs exactly this way.Outputs and Locals
override_resourceA terraform test construct that replaces one specific resource’s planned values (rather than an entire provider, like mock_provider) — used when only one resource in an otherwise-real plan needs a stand-in value.Testing Modules
TermMeaningLesson
planterraform plan computes and shows the actions needed to reach the desired state without executing any of them — read-only against real infrastructure, though it does read current state and (unless -refresh=false) refresh it.The Terraform Workflow
plugin cacheTF_PLUGIN_CACHE_DIR (or the CLI config’s plugin_cache_dir) points every terraform init at one shared directory of downloaded provider binaries instead of re-downloading the same provider version into every project’s own .terraform/providers — a meaningful speed and bandwidth win, but never safe for two concurrent inits to share unguarded.Installing Terraform and Project Structure
precondition / postconditionA condition {} block’s precondition checks an assumption before a resource/data source/output is evaluated (e.g. “this AMI must be in the account”); postcondition checks the result after — both fail the plan/apply with a custom message the moment the expression is false, rather than surfacing a confusing downstream error.Expressions, Functions, and Conditionals
prevent_destroyThe lifecycle { prevent_destroy = true } meta-argument makes Terraform refuse to plan a destroy of that resource at all — errors out the plan rather than silently protecting it, so a moved/removed refactor around it still needs care.HCL, Providers, and Resources
providerThe plugin translating HCL resource/data-source blocks into real API calls against one system — aws, azurerm, google, and hundreds more, each versioned and installed independently of Terraform core itself.HCL, Providers, and Resources
provider aliasA second (or third) configuration of the same provider, given a name via alias = "..." in a provider {} block, and referenced on a resource with provider = aws.east — how a single config manages resources across, e.g., two AWS regions in one apply.HCL, Providers, and Resources
provider protocolThe versioned RPC contract (protocol v6 since Terraform 1.4+/current providers) between Terraform core and any provider plugin — why a provider binary built against protocol 6 can’t be loaded by a CLI that only speaks protocol 5, independent of the provider’s own semantic version.Module Versioning and Registries
TermMeaningLesson
refreshRe-reads every managed resource’s real state from the provider and reconciles it into Terraform’s state file — happens automatically as part of plan/apply unless -refresh=false, or explicitly via terraform apply -refresh-only.Drift Detection and Import
registryThe Terraform Registry (registry.terraform.io) hosts versioned, publicly discoverable providers and modules — a module source like terraform-aws-modules/vpc/aws resolves here by default, no full Git URL needed.Module Versioning and Registries
remote_stateA Terragrunt remote_state { backend = "s3" ... } block generates the equivalent Terraform backend block for every unit that includes it, keeping bucket/key/region/lock config in exactly one place instead of copy-pasted per unit.Terragrunt HCL and the Root Config
removed blockA declarative removed { from = ... } block (Terraform 1.7+) drops a resource out of state — optionally with a nested lifecycle { destroy = false/true } — without needing the resource’s config to still exist at all, the safe replacement for terraform state rm when the config is also being deleted.Drift Detection and Import
renderterragrunt render prints a unit’s fully-resolved configuration (after include, generate, and function evaluation) as JSON or HCL — the way to see exactly what a unit will actually run without triggering plan/apply.Running Many Units at Once
replace_triggered_byInside lifecycle {}, replace_triggered_by = [aws_launch_template.this] forces this resource to be replaced whenever the referenced resource/attribute changes — even though nothing about this resource’s own arguments changed.HCL, Providers, and Resources
resourceThe core building block: a resource "aws_instance" "this" {} block declares one real, managed object whose full lifecycle (create/read/update/delete) Terraform owns end-to-end.HCL, Providers, and Resources
root moduleThe .tf files in the directory you actually run terraform from — every other module is a child module reached through it, and it’s the only place a provider {} block or a backend configuration can live.Writing a Reusable Module
root.hclThe conventional name (replacing the deprecated terragrunt.hcl root pattern) for the top-of-tree Terragrunt file every unit’s include block locates via find_in_parent_folders() — holds shared remote_state, generate, and provider config.Terragrunt HCL and the Root Config
run --all (formerly run-all/plan-all)Runs a Terraform command across every unit under the current directory in dependency order — the current syntax is terragrunt run --all apply; the older per-command forms (terragrunt plan-all, terragrunt run-all apply) are unrecognized commands on Terragrunt 1.1.Running Many Units at Once
TermMeaningLesson
S3 native locking (use_lockfile)The S3 backend’s use_lockfile = true argument locks state using a .tflock object and S3’s conditional-write (If-None-Match) support, introduced experimentally in Terraform 1.10 and stable since 1.11 — the replacement for a separate DynamoDB lock table.Remote Backends and Locking
S3 bucket versioningEnabling versioning on the bucket backing an S3 backend keeps every prior state object as a recoverable version — the practical recovery path after a bad apply corrupts state, since Terraform itself keeps no separate state history beyond the local terraform.tfstate.backup of the last run.Remote Backends and Locking
Secrets Manager vs SSM Parameter Storeaws_secretsmanager_secret/_version supports automatic rotation and resource policies but bills per secret; aws_ssm_parameter (SecureString type) is free up to a generous tier but has no built-in rotation — the practical reason a team picks one over the other for a given credential.Secrets and Credential Management
secret_string_woThe write-only counterpart (Terraform 1.11+) of aws_secretsmanager_secret_version’s secret_string — its value is sent to AWS and never persisted in state or a plan file, paired with a secret_string_wo_version you bump to force an update.Secrets and Credential Management
sensitiveMarking a variable/output with sensitive = true redacts its value from CLI output and plan/apply logs — it is still stored in plaintext in the state file itself, which is why sensitive state also needs backend-level encryption.Sensitive Data and Team Workflows
Sentinel / OPAPolicy-as-code engines that evaluate a plan’s show -json output against organization-written rules before an apply is allowed to proceed — Sentinel is HCP Terraform’s built-in engine; Open Policy Agent (via conftest) is the open-source, platform-agnostic equivalent.Policy as Code and Static Analysis
show -jsonterraform show -json <planfile> renders a saved plan (or state) as machine-readable JSON — what Sentinel/OPA, Infracost, and most custom CI gates actually parse, instead of scraping the human-readable plan output.The Terraform Workflow
stateThe JSON record (terraform.tfstate, or its remote-backend equivalent) mapping every config resource/module to the real object it manages — Terraform’s only source of truth for what it already created, never re-derived by scanning the cloud account.The State File
TermMeaningLesson
.terraform.lock.hclRecords the exact provider versions and their checksums (across every platform, unless pruned with -platform) that satisfied a terraform init — committed to version control so a second init on a different machine can’t silently resolve a different, unverified provider build.Module Versioning and Registries
terraform graphEmits the dependency graph Terraform actually built for the current config, in DOT format, piped to Graphviz (terraform graph | dot -Tsvg) to visualize why one resource depends on another.The Terraform Workflow
terraform testThe built-in test runner (.tftest.hcl files, Terraform 1.6+) that plans and optionally applies a configuration against real or mocked providers and asserts on the result — run with terraform test, no separate testing framework required.Testing Modules
.tftest.hclThe file extension terraform test looks for: one or more run blocks, each with a command (plan or apply) and assert blocks checking conditions against that run’s planned or applied values.Testing Modules
terraform_dataA first-class, provider-independent resource (Terraform 1.4+) holding arbitrary input/triggers_replace values with no real infrastructure behind it — the replacement for the community null_resource, commonly used to force a dependent resource’s replacement or to carry provisioner behavior.Testing Modules
terraform_remote_stateA data source reading another configuration’s state (and its outputs) directly out of its backend — the plain-Terraform equivalent of what a Terragrunt dependency block does through mock_outputs and generated wiring.Remote Backends and Locking
terragrunt stack / terragrunt.stack.hclA terragrunt.stack.hcl file declares a set of unit/stack blocks that terragrunt stack generate expands into a real directory tree of units (under .terragrunt-stack/) before stack run applies them — a higher-level way to template “one stack of units” than copy-pasting directories per environment.Running Many Units at Once
tflintA linter for Terraform source that catches provider-specific mistakes plan/apply won’t (a deprecated instance type, an invalid AWS region string) that terraform validate — which only checks HCL syntax and internal consistency — cannot.Policy as Code and Static Analysis
TermMeaningLesson
unitTerragrunt’s name for one directory containing one terragrunt.hcl plus the Terraform module it points at via terraform { source = ... } — the thing run --all, dependency, and --filter all operate on, analogous to a root module in plain Terraform.Terragrunt HCL and the Root Config
validationA variable’s validation { condition = ..., error_message = ... } block rejects an invalid value at plan time with a custom message; since Terraform 1.9, the condition may also reference other variables, so cross-variable rules no longer need a workaround via precondition.Input Variables
variableA named, typed input to a module or the root config, given a value via .tfvars, -var, an environment variable (TF_VAR_name), or a default — the only way data flows into a module from outside it.Input Variables
version constraint (~>)The pessimistic-constraint operator: ~> 6.66 allows 6.66.x (patch upgrades only), while ~> 6.0 allows any 6.x (minor upgrades too) — the standard way to pin a provider loosely enough to get bugfixes but not a breaking major version.Module Versioning and Registries
workspaceTerraform’s built-in mechanism (terraform workspace new/select) for running one config against multiple named state files sharing the same backend — this course teaches Terragrunt’s directory-per-environment pattern instead, since workspaces silently share the same backend config and code across every environment, which is often the wrong tradeoff for prod vs. non-prod.Terraform Workspaces
write-onlyA variable/attribute marked write_only = true (Terraform 1.11+) is accepted on input but never stored in state or a plan file — paired with a _version argument you bump to signal “this write-only value changed, re-send it.”Sensitive Data and Team Workflows