How to Create a VPC with Terraform - Complete AWS Networking Guide
Build a production-ready AWS VPC with Terraform. Covers subnets, route tables, NAT gateways, security groups, and network ACLs step by step.
AWS
Create a production-ready AWS S3 bucket with Terraform. Covers versioning, encryption, lifecycle rules, bucket policies, CORS, and static website hosting.
Create an S3 bucket with aws_s3_bucket, then add versioning, encryption, and public access blocks as separate resources. Terraform 4.x split S3 configuration into individual resources for better modularity.
aws configure)provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "main" {
bucket = "myapp-data-${var.environment}"
tags = {
Environment = var.environment
ManagedBy = "terraform"
}
}resource "aws_s3_bucket_versioning" "main" {
bucket = aws_s3_bucket.main.id
versioning_configuration {
status = "Enabled"
}
}resource "aws_s3_bucket_server_side_encryption_configuration" "main" {
bucket = aws_s3_bucket.main.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
}
bucket_key_enabled = true
}
}resource "aws_s3_bucket_public_access_block" "main" {
bucket = aws_s3_bucket.main.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}resource "aws_s3_bucket_lifecycle_configuration" "main" {
bucket = aws_s3_bucket.main.id
rule {
id = "archive-old-objects"
status = "Enabled"
transition {
days = 90
storage_class = "STANDARD_IA"
}
transition {
days = 180
storage_class = "GLACIER"
}
expiration {
days = 365
}
noncurrent_version_expiration {
noncurrent_days = 30
}
}
}data "aws_iam_policy_document" "enforce_ssl" {
statement {
sid = "EnforceSSL"
effect = "Deny"
actions = ["s3:*"]
resources = [
aws_s3_bucket.main.arn,
"${aws_s3_bucket.main.arn}/*"
]
principals {
type = "*"
identifiers = ["*"]
}
condition {
test = "Bool"
variable = "aws:SecureTransport"
values = ["false"]
}
}
}
resource "aws_s3_bucket_policy" "main" {
bucket = aws_s3_bucket.main.id
policy = data.aws_iam_policy_document.enforce_ssl.json
}# variables.tf
variable "bucket_name" { type = string }
variable "environment" { type = string }
# main.tf
resource "aws_s3_bucket" "main" {
bucket = var.bucket_name
tags = { Environment = var.environment, ManagedBy = "terraform" }
}
resource "aws_s3_bucket_versioning" "main" {
bucket = aws_s3_bucket.main.id
versioning_configuration { status = "Enabled" }
}
resource "aws_s3_bucket_server_side_encryption_configuration" "main" {
bucket = aws_s3_bucket.main.id
rule {
apply_server_side_encryption_by_default { sse_algorithm = "aws:kms" }
bucket_key_enabled = true
}
}
resource "aws_s3_bucket_public_access_block" "main" {
bucket = aws_s3_bucket.main.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
# outputs.tf
output "bucket_arn" { value = aws_s3_bucket.main.arn }
output "bucket_name" { value = aws_s3_bucket.main.id }
output "bucket_domain" { value = aws_s3_bucket.main.bucket_regional_domain_name }resource "aws_s3_bucket_website_configuration" "website" {
bucket = aws_s3_bucket.main.id
index_document { suffix = "index.html" }
error_document { key = "error.html" }
}| Mistake | Fix |
|---|---|
Inline versioning in aws_s3_bucket | Use separate aws_s3_bucket_versioning resource |
| Bucket name with underscores | Use hyphens — underscores break DNS |
| Missing public access block | Always add — blocks accidental public exposure |
| Hardcoded bucket name | Add environment suffix for uniqueness |
A production-ready S3 bucket needs versioning, encryption, public access blocks, and lifecycle rules — all as separate Terraform resources. Use bucket policies to enforce SSL and restrict access. Always use unique bucket names with environment prefixes.
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.
Learn the AWS services essential for Terraform — IAM for authentication, S3 for state storage, DynamoDB for state locking. Complete setup guide.