π― Goal
Create a simple EC2 instance using:
- Variables β for AMI, instance_type, tags
- Locals β for naming
- Outputs β instance_id, public_ip
- Remote backend β S3
- State locking β DynamoDB
Using your backend resources:
- S3 bucket: tf-backend-lab-123
- DynamoDB table: tf-state-lock
π Folder Structure
We keep it clean for this task:
terraform-ec2-basic/
βββ backend.tf
βββ main.tf
βββ variables.tf
βββ outputs.tf
βββ terraform.tfvars
π§© backend.tf
terraform {
backend "s3" {
bucket = "tf-backend-lab-123"
key = "ec2/basic/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "tf-state-lock"
}
}
π variables.tf
We define input variables:
variable "instance_type" {
description = "EC2 instance type"
type = string
default = "t3.micro"
}
variable "ami_id" {
description = "AMI ID for EC2 instance"
type = string
}
variable "env" {
description = "Environment name"
type = string
default = "dev"
}
variable "owner" {
description = "Owner/Team name"
type = string
}
π§ locals
Locals are used to build consistent resource names.
Add this inside main.tf or create locals.tf
locals {
name_prefix = "${var.env}-${var.owner}"
common_tags = {
Environment = var.env
Owner = var.owner
ManagedBy = "Terraform"
}
}
Interview Tip:
Locals help avoid repeating variables and maintain consistent naming conventions.
π main.tf
provider "aws" {
region = "us-east-1"
}
resource "aws_instance" "server" {
ami = var.ami_id
instance_type = var.instance_type
tags = merge(
local.common_tags,
{
Name = "${local.name_prefix}-ec2"
}
)
}
π€ outputs.tf
output "instance_id" {
value = aws_instance.server.id
description = "EC2 Instance ID"
}
output "public_ip" {
value = aws_instance.server.public_ip
description = "Public IP address of the EC2 instance"
}
output "tags_used" {
value = local.common_tags
}
π terraform.tfvars
Provide your values:
ami_id = "ami-0c02fb55956c7d316" # Amazon Linux 2 in us-east-1
owner = "lachu"
env = "dev"
instance_type = "t3.micro"
βΆοΈ Commands
terraform init
terraform validate
terraform plan
terraform apply -auto-approve
If you can check with dynamoDB table
π§ Interview Notes (Very Important)
β Why use variables?
- Reusability
- Runtime flexibility
- Parameterizing environment-specific values
β Why use locals?
- Avoid repeating variable values
- Standardize naming conventions
- Reduce mistakes in big projects
β Why use outputs?
- To expose useful information after apply
- Helpful for automation (CI/CD, scripts)
- Used by other Terraform modules
β Why S3 + DynamoDB?
- S3 β stores remote state
- DynamoDB β prevents two people from running apply at the same time
β Typical interview question:
How does Terraform handle state locking?
Answer:
When using S3 backend with DynamoDB, Terraform creates a lock entry in DynamoDB during operations such as plan or apply. This prevents concurrent modifications of the state, ensuring consistency.
π Thanks for reading! If this post added value, a like β€οΈ, follow, or share would encourage me to keep creating more content.
β Latchu | Senior DevOps & Cloud Engineer
βοΈ AWS | GCP | βΈοΈ Kubernetes | π Security | β‘ Automation
π Sharing hands-on guides, best practices & real-world cloud solutions



Top comments (0)