Providers and Resources
To build any "Industrial Level" infrastructure, you need two things: A place to build it (Provider) and The things you want to build (Resources).
In Terraform, we define these using simple blocks of code. Think of the Provider as the "Cloud Platform" and the Resource as the "Cloud Service."
1. The Provider: The "Who"โ
A Provider is a plugin that Terraform uses to translate your code into API calls for a specific platform. Without a provider, Terraform is just a text processor with no way to talk to the outside world.
How to Configure a Providerโ
In your main.tf file, you must declare which provider you are using. For our CodeHarborHub projects, we primarily use AWS.
# 1. Define the Provider
provider "aws" {
region = "ap-south-1" # Mumbai Region
}
You can use multiple providers in the same project! For example, you could have an AWS Provider to launch a server and a GitHub Provider to create a repository for that server's code.
2. The Resource: The "What"โ
A Resource is the most important element in the Terraform language. It describes one or more infrastructure objects, such as virtual networks, compute instances, or higher-level components such as DNS records.
Resource Syntaxโ
The syntax follows a strict pattern: resource "TYPE" "LOCAL_NAME" { ... }
resource "aws_s3_bucket" "my_learning_assets" {
bucket = "codeharborhub-assets-2026"
tags = {
Environment = "Dev"
Owner = "CodeHarborHub"
}
}
- Type (
aws_s3_bucket): The specific AWS service. This is defined by the provider. - Local Name (
my_learning_assets): A name used only inside your Terraform code to refer to this resource. - Arguments: The configuration settings for that resource (e.g.,
bucketname).
Dependency: The "Order of Operations"โ
Terraform is intelligent enough to know which resource to build first. This is called Resource Dependency.
- Implicit Dependency
- Explicit Dependency
The Automatic Way. If Resource B uses an attribute from Resource A, Terraform automatically builds A first.
resource "aws_instance" "web" {
# Terraform sees this reference and builds the subnet FIRST
subnet_id = aws_subnet.main.id
}
resource "aws_subnet" "main" {
vpc_id = "vpc-12345"
}
The Manual Way. Sometimes resources depend on each other but don't share data. You can force an order using depends_on.
resource "aws_instance" "web" {
ami = "ami-xyz"
instance_type = "t2.micro"
# Wait for the S3 bucket to exist before starting the server
depends_on = [aws_s3_bucket.example]
}
Mapping Theory to Codeโ
| Terraform Code | AWS Console Equivalent |
|---|---|
resource "aws_vpc" | Creating a Virtual Private Cloud. |
resource "aws_instance" | Launching an EC2 Instance. |
resource "aws_security_group" | Configuring Firewall Rules. |
resource "aws_db_instance" | Provisioning an RDS Database. |
The "Lifecycle" of a Resourceโ
When you change your code and run terraform apply, Terraform does one of three things based on the provider's logic:
- Update in Place: Changes a setting (like a Tag) without destroying the resource.
- Destroy and Re-create: If you change a setting that cannot be edited (like the AZ of a server), Terraform deletes the old one and builds a new one.
- No-op: If the code matches the cloud, it does nothing.
Learning Challengeโ
- Create a folder named
terraform-lab. - Create a file named
main.tf. - Add a provider block for AWS.
- Add a resource block for an S3 Bucket with a unique name.
- Run
terraform initandterraform planto see the blueprint!