Pro ยท Lesson 3 of 12

HCL, providers, resources, and data

HCL is the language. A provider is a plugin. A resource is something the plugin manages. A data source is a read.

Sign in to save your place.

Picture it this way

The provider is the shop. A resource is an item you asked the shop to keep on the shelf. A data source is you asking the shop what is already on the shelf, without ordering a new one.

Blocks you will see every day

terraform sets the required version and providers. provider configures one plugin. resource declares an object. data reads an existing object. Arguments use = and blocks use braces. terraform fmt rewrites spacing. It does not check whether AWS will accept the values.

terraform validate checks syntax and references. It does not prove the cloud account allows the change. Only a plan against that account, or a test you wrote, goes further.

Init downloads providers

terraform init reads the lock file if you have one, downloads providers, and configures the backend. Commit .terraform.lock.hcl so the next machine does not silently pick a different provider build. Do not commit the .terraform directory or a state file full of ids.

Command Touches the cloud?
fmt No. It edits local files.
validate No. It checks the configuration.
plan It reads state and the provider. A refresh can read the cloud.
apply Yes. It changes resources.

Data sources are not resources

A data source looks up something that already exists, such as an AMI or a network. It does not create it. If the object is gone, the plan fails. That is different from a resource, which Terraform would offer to create.

Who talks to the cloud

  1. HCL
  2. Provider
  3. API

Step 1 of 3HCL is local text until a provider is configured.

Lab: a local resource with no cloud account

This uses terraform_data, which ships with Terraform, so plan can run without AWS keys. The required_version floor is a hint. If your binary is older, read the error and install a newer Terraform or skip to the version lesson.

cat > main.tf <<'EOF'
terraform {
  required_version = ">= 1.7.0"
}

resource "terraform_data" "note" {
  input = "hello from the lab"
}

output "note" {
  value = terraform_data.note.output
}
EOF
terraform fmt
terraform init
terraform validate

Concept summary

Knowledge check

What does terraform validate prove?

A data source for a subnet fails because the subnet was deleted. Why is that different from a resource?

What should you commit?

Official sources

Checked against the linked documentation in October 2026. A later release can move a flag, a price, or a supported pair. Use the page for the version you installed.