Providers, resources, modules: the Terraform trinity
Summary: three words come up constantly in any Terraform code, and they must be clearly distinguished. The provider is the bridge between Terraform and a platform (AWS, GCP, Azure, GitHub, Datadog, etc.). The resource is a concrete infrastructure brick created by Terraform (VM, database, DNS). The module is a packaged, reusable set of resources. This lesson dissects the trinity, adds a fourth key concept — the data source — and shows where to find them in the Terraform Registry.
1. Overview of the Terraform architecture
In one sentence: your code declares a provider, which gives you access to resources, which you can organize into modules shareable via the Registry.
2. Providers — the bridges to each platform
A provider is a plugin downloaded by Terraform that knows how to talk to the API of a given platform.
2.1 · What a provider brings
2.2 · How many providers exist?
More than 3500 providers are available in the Terraform Registry in 2026. They cover:
What makes Terraform so powerful: you can provision your AWS server, your Cloudflare DNS, your GitHub repo and your Datadog alert in a single HCL file. It is this multi-platform unification that built Terraform's dominance.
2.3 · The types of providers
Best practice: always favour official or partner providers. Community providers can be excellent, but their maintenance can stop overnight.
3. Resources — the concrete bricks
A Terraform resource represents an entity that can be created on a platform: a virtual machine, an S3 bucket, a DNS record, an IAM user, a GitHub repo, a Datadog alert.
3.1 · Anatomy of a resource
Syntax reminder:
resource "RESOURCE_TYPE" "LOGICAL_NAME" {
attribute_1 = value
attribute_2 = value
}
Concrete examples:
| Resource block | What it creates |
|---|---|
resource "aws_instance" "web" | An EC2 VM on AWS |
resource "google_compute_instance" "web" | A Compute Engine VM on GCP |
resource "azurerm_virtual_machine" "web" | A VM on Azure |
resource "kubernetes_deployment" "app" | A Kubernetes Deployment |
resource "github_repository" "docs" | A GitHub repo |
resource "cloudflare_record" "www" | A Cloudflare DNS record |
resource "datadog_monitor" "cpu" | A Datadog alert |
3.2 · Composed resources and dependencies
Resources compose in cascade to build complete architectures.
Remarkably: Terraform detects these dependencies automatically from the references (aws_vpc.main.id). You never have to specify the order — it infers it.
3.3 · Meta-arguments — fine-grained behaviour control
Some attributes are special — they do not represent a property of the cloud resource, but an instruction for Terraform itself.
These meta-arguments are Terraform's engine room — they let you tune the behaviour very finely.
4. Data sources — reading without creating
There is a cousin of resources you must know: data sources.
Fundamental difference:
- A
resource— creates a new entity. - A
data— reads an existing entity.
Example: you want to use the most recent Ubuntu AMI in your region, without hard-coding its identifier (which changes with every update).
data "aws_ami" "ubuntu_latest" {
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-*"]
}
}
resource "aws_instance" "web" {
# We use the ID found by the data source
ami = data.aws_ami.ubuntu_latest.id
instance_type = "t3.micro"
}
What this enables:
Data sources = read-only. No change is made to the infrastructure. It is your tool to connect Terraform to what already exists.
5. Modules — the unit of reuse
A Terraform module is a structured set of .tf files packaged for reuse.
5.1 · Anatomy of a module
A module can be local (in a subfolder of your project) or remote (downloaded from the Terraform Registry, GitHub, GitLab, S3…).
5.2 · Using a remote module — the magic example
In 5 lines of HCL, you can create a complete AWS VPC thanks to a renowned community module:
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.0.0"
name = "my-production-vpc"
cidr = "10.0.0.0/16"
azs = ["eu-west-1a", "eu-west-1b", "eu-west-1c"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
enable_nat_gateway = true
single_nat_gateway = false
}
What it actually creates: a VPC, 6 subnets, 3 NAT Gateways, a route table, an IGW, several default security groups… about 25 AWS resources. And you only wrote 10 lines.
That is all the magic of modules: the community has built and tested the standard infrastructure patterns, and you consume them like Lego bricks.
5.3 · The Terraform Registry — the global catalogue
The Terraform Registry is the marketplace where everyone publishes their modules and providers.
The star modules to know:
| Module | What it does |
|---|---|
terraform-aws-modules/vpc/aws | Complete AWS VPC with subnets, NAT, routing |
terraform-aws-modules/eks/aws | Turnkey EKS Kubernetes cluster |
terraform-aws-modules/rds/aws | RDS database with replication |
hashicorp/consul/aws | Consul cluster in HA |
cloudposse/vpc/aws | AWS VPC, Cloud Posse variant |
Always check:
- The number of downloads (adoption indicator).
- The date of the last update (ideally less than 6 months).
- The licence (MPL, Apache 2, MIT are reliable).
- The GitHub repo — active issues, multiple contributors.
6. Complete cycle — putting it all together
Here is how these four building blocks (provider, resource, data, module) fit together in a real project.
A mature Terraform project uses these four building blocks together, and 80% of its code consists of assembling existing modules rather than writing raw resources.
7. The classic beginner mistakes
A beginner typically makes the following mistakes.
The Premium Terraform Course puts a lot of emphasis on best practices of structure and avoids these pitfalls.
Remember in 30 seconds
- Provider = plugin that talks to an API (AWS, GCP, GitHub, Datadog). More than 3500 available.
- Resource = an entity that Terraform can create (VM, database, DNS). The heart of all Terraform code.
- Data source = read-only access to an existing entity — used to query without modifying.
- Module = reusable package of resources, with variables and outputs. The secret of scalability.
- Terraform Registry = global catalogue with 15,000+ public modules.
- Best practice: never reinvent a module that already exists in the Registry.