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.
Terraform
Learn to use Terraform data sources to query existing infrastructure. Covers AWS AMI lookup, VPC discovery, AZ listing, and cross-state data access patterns.
Data sources let you read information from your cloud provider or other Terraform state without creating resources. Use them to look up AMIs, discover VPCs, list availability zones, and reference resources managed outside your current configuration.
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"]
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
}
}
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id # Dynamic AMI lookup
instance_type = "t3.micro"
}| Concept | Resources | Data Sources |
|---|---|---|
| Purpose | Create/manage infrastructure | Read existing infrastructure |
| Keyword | resource | data |
| State | Stored in state file | Refreshed every plan/apply |
| Reference | aws_instance.web.id | data.aws_ami.ubuntu.id |
data "aws_ami" "amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
}
output "ami_id" {
value = data.aws_ami.amazon_linux.id
}data "aws_availability_zones" "available" {
state = "available"
}
resource "aws_subnet" "private" {
count = 3
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
}# Look up VPC by tag
data "aws_vpc" "main" {
filter {
name = "tag:Name"
values = ["production-vpc"]
}
}
# Look up subnets in that VPC
data "aws_subnets" "private" {
filter {
name = "vpc-id"
values = [data.aws_vpc.main.id]
}
filter {
name = "tag:Tier"
values = ["private"]
}
}
resource "aws_lb" "main" {
name = "app-lb"
internal = true
load_balancer_type = "application"
subnets = data.aws_subnets.private.ids
}data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
output "account_id" {
value = data.aws_caller_identity.current.account_id
}
output "region" {
value = data.aws_region.current.name
}# Reference outputs from another Terraform configuration
data "terraform_remote_state" "network" {
backend = "s3"
config = {
bucket = "my-terraform-state"
key = "network/terraform.tfstate"
region = "us-east-1"
}
}
resource "aws_instance" "app" {
ami = data.aws_ami.amazon_linux.id
instance_type = "t3.micro"
subnet_id = data.terraform_remote_state.network.outputs.private_subnet_ids[0]
}data "aws_iam_policy_document" "s3_read" {
statement {
effect = "Allow"
actions = ["s3:GetObject", "s3:ListBucket"]
resources = [
aws_s3_bucket.data.arn,
"${aws_s3_bucket.data.arn}/*",
]
}
}
resource "aws_iam_policy" "s3_read" {
name = "s3-read-policy"
policy = data.aws_iam_policy_document.s3_read.json
}data "azurerm_resource_group" "existing" {
name = "my-rg"
}
data "azurerm_virtual_network" "main" {
name = "production-vnet"
resource_group_name = data.azurerm_resource_group.existing.name
}data "google_compute_network" "main" {
name = "default"
project = var.project_id
}aws_iam_policy_document over raw JSON| Error | Fix |
|---|---|
| "no matching data source found" | Check filters — too restrictive |
| "multiple results returned" | Add most_recent = true or more filters |
| "insufficient permissions" | IAM role needs describe/list permissions |
Data sources are the read-only counterpart to resources. Use them to dynamically look up AMIs, discover infrastructure, reference remote state, and build IAM policies. They keep your configs portable across regions and accounts — never hardcode what you can look up.
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 the AWS services essential for Terraform — IAM for authentication, S3 for state storage, DynamoDB for state locking. Complete setup guide.
Compare Terraform vs AWS CloudFormation — multi-cloud support, state management, language, ecosystem, and when to use each for infrastructure as code.