Your First Terraform Configuration from Scratch
Scenario
You have just installed Terraform on your machine and want to understand the absolute basics: how to tell Terraform which version to use, how to declare a cloud provider, how to define a resource, and how to run the core workflow — init, plan, apply, and destroy.
To keep things dead simple, you will create a single S3 bucket. The goal is not to learn S3 — it's to learn how Terraform files are structured and how the workflow executes.
- Create a terraform {} block that pins the Terraform CLI version to >= 1.5.0 and declares the hashicorp/aws provider with version ~> 5.0.
- Configure the aws provider for the us-east-1 region.
- Create a single aws_s3_bucket resource with a unique bucket name and a ManagedBy = "terraform" tag.
- Run terraform init to download the provider plugin.
- Run terraform plan to preview the changes.
- Run terraform apply to create the bucket.
- Run terraform destroy to clean up.
Additional Context
The terraform {} block is the configuration's identity card. It tells anyone reading the code (and Terraform itself) what version of the CLI is expected and which provider plugins are required. Without required_providers, Terraform will still try to guess the provider from the resource type prefix, but being explicit avoids surprises — especially when providers share resource naming patterns.
The ~> 5.0 version constraint is called the pessimistic constraint operator. It means "any version >= 5.0 and < 6.0". This lets you get patch and minor updates automatically while preventing a major version upgrade that could contain breaking changes.
versions.tf
# versions.tf
# This block pins the Terraform CLI and provider versions.
# Always include this — reproducibility starts here.
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws" # Full address: registry.terraform.io/hashicorp/aws
version = "~> 5.0" # Allow 5.x updates, block 6.0+
}
}
}main.tf
# main.tf
# Configure the AWS provider — tells Terraform which region to target.
provider "aws" {
region = "us-east-1"
}
# Create a single S3 bucket.
# S3 bucket names must be globally unique across ALL AWS accounts.
resource "aws_s3_bucket" "my_first_bucket" {
bucket = "my-first-tf-bucket-demo-2024"
tags = {
Name = "my-first-bucket"
ManagedBy = "terraform"
}
}Workflow Commands
# Step 1: Initialise — downloads the AWS provider plugin into .terraform/
terraform init
# Step 2: Preview — shows what Terraform WILL do (no changes made yet)
terraform plan
# Step 3: Apply — creates the resources (type "yes" to confirm)
terraform apply
# Step 4: Verify — confirm the bucket exists
aws s3 ls | grep my-first-tf-bucket
# Step 5: Destroy — removes everything Terraform created
terraform destroyApply complete! Resources: 1 added, 0 changed, 0 destroyed.

