Terraform with Packer - Build and Deploy Custom AMIs
Use Packer and Terraform together to build custom AMIs and deploy them. Golden image pipeline, HCP Packer integration, and automated image lifecycle.
Terraform
A beginner-friendly Terraform AWS guide with provider setup, S3 bucket, EC2 instance, VPC networking, remote state, and best practices for safe deployments.
Install Terraform, configure AWS CLI credentials, write a .tf file with the AWS provider and a resource, then run terraform init && terraform plan && terraform apply. That's it — your first AWS resource is live.
# Install AWS CLI
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip && sudo ./aws/install
# Configure credentials
aws configure
# Enter: Access Key ID, Secret Access Key, Region (us-east-1), Output (json)
# Install Terraform
# See: /articles/install-terraform-debian/
terraform version# main.tf
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.40"
}
}
}
provider "aws" {
region = var.region
}
variable "region" {
type = string
default = "us-east-1"
}resource "aws_s3_bucket" "demo" {
bucket = "my-terraform-demo-${random_id.suffix.hex}"
}
resource "random_id" "suffix" {
byte_length = 4
}
output "bucket_name" {
value = aws_s3_bucket.demo.id
}terraform init # Download providers
terraform plan # Preview changes
terraform apply # Create resourcesdata "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
}
}
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
tags = {
Name = "my-first-instance"
}
}
output "public_ip" {
value = aws_instance.web.public_ip
}resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
tags = { Name = "main-vpc" }
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
map_public_ip_on_launch = true
availability_zone = "${var.region}a"
tags = { Name = "public-subnet" }
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
}
resource "aws_route_table_association" "public" {
subnet_id = aws_subnet.public.id
route_table_id = aws_route_table.public.id
}terraform state list # List all managed resources
terraform state show aws_instance.web # Show details
terraform output # Show outputsterraform destroy # Removes ALL resources — avoid chargesWrite .tf files → terraform init → terraform plan → terraform apply
↓
terraform destroy (when done)version = "~> 5.40" prevents surprisesterraform plan before every apply — always review changesName, Environment, ManagedBy = "terraform"vpc.tf, ec2.tf, s3.tf for clarityOnce the server exists, you can configure it with Ansible and then orchestrate workloads with Kubernetes:
Terraform on AWS follows a simple loop: write HCL, init, plan, apply. Start with S3 or EC2, add VPC networking, then move to remote state when you're ready for team collaboration. The AWS provider covers 1,000+ resource types across every AWS service.
Use Packer and Terraform together to build custom AMIs and deploy them. Golden image pipeline, HCP Packer integration, and automated image lifecycle.
Build a production-ready AWS VPC with Terraform. Covers subnets, route tables, NAT gateways, security groups, and network ACLs step by step.
Deploy an AWS EC2 instance with Terraform step by step. Complete guide with VPC, security groups, key pairs, user data, and production-ready configuration.
Learn to use Terraform data sources to query existing infrastructure. Covers AWS AMI lookup, VPC discovery, AZ listing, and cross-state data access patterns.