Skip to main content
Terraform beginner Lesson 5 of 11

Providers and Resources (the building blocks of Terraform)

Learn providers, resources, arguments, attributes, and how Terraform maps configuration to real infrastructure.

Terraform is built from:

  • Providers: integrations with cloud APIs
  • Resources: real infrastructure objects you manage

Learning outcomes

You’ll learn:

  • how to configure a provider
  • how resources are declared
  • how Terraform references resource attributes

1) Providers

A provider block configures connection settings for a platform.

Example (AWS):

provider "aws" {
  region = var.aws_region
}

Provider configuration can include credentials, endpoints, and more.

2) Resources

A resource declares infrastructure you want Terraform to manage.

Generic shape:

resource "<provider_resource_type>" "<name>" {
  # arguments...
}

AWS S3 bucket example

resource "aws_s3_bucket" "example" {
  bucket = "my-unique-bucket-name-12345" # must be globally unique
}

Terraform identifies resources as:

  • resource type: aws_s3_bucket
  • name: example

So the full reference is:

  • aws_s3_bucket.example

3) Arguments vs attributes

  • Arguments are what you set:
    • bucket = "..."
  • Attributes are what Terraform gets (often after apply):
    • aws_s3_bucket.example.bucket

Example output:

output "bucket_name" {
  value = aws_s3_bucket.example.bucket
}

4) Referencing resources (dependency wiring)

When you reference an attribute, Terraform can infer dependencies.

Example: create an S3 bucket and use its name elsewhere.

resource "aws_s3_bucket" "uploads" {
  bucket = "my-unique-uploads-bucket-12345"
}

resource "aws_s3_bucket_versioning" "uploads_versioning" {
  bucket = aws_s3_bucket.uploads.id

  versioning_configuration {
    status = "Enabled"
  }
}

Because bucket = aws_s3_bucket.uploads.id, Terraform knows it must create the bucket first.

5) Required provider + version constraints

Use terraform { required_providers ... } to lock down versions.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

6) Resource meta-arguments (useful building blocks)

Terraform supports meta-arguments such as:

  • count
  • for_each
  • depends_on

We’ll cover these patterns in the next tutorials.

7) Small complete example

main.tf

terraform {
  required_version = ">= 1.6.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = var.aws_region
}

resource "aws_s3_bucket" "example" {
  bucket = "my-unique-bucket-name-12345"
}

output "bucket_name" {
  value = aws_s3_bucket.example.bucket
}

variables.tf

variable "aws_region" {
  type    = string
  default = "us-east-1"
}

Run:

terraform init
terraform validate
terraform plan
terraform apply

Replace the bucket name with a globally unique name.

Frequently Asked Questions

What is a provider in Terraform?
A provider is a plugin that knows how to talk to a specific API (AWS, Azure, GCP, etc.) and manage resources.
What’s the difference between arguments and attributes?
Arguments are inputs you set in config. Attributes are values Terraform reads from the provider (often exposed after apply).