TFLAB08-Data Sources: Reading Existing Infrastructure

Data Sources: Reading Existing Infrastructure

🔧 Terraform Core ⭐ Beginner data aws_caller_identity aws_region aws_vpc Filters Read-Only

Scenario

Your configuration needs to reference infrastructure that already exists — the current AWS account ID, the current region, the default VPC ID. You shouldn't hardcode these values because they change between accounts and regions. Instead, you need to query them at plan time using data sources.

Data sources read existing infrastructure without creating or modifying anything. They are the read-only counterpart to resource blocks.

Your Objectives
  • Use data "aws_caller_identity" to get the current account ID.
  • Use data "aws_region" to get the current region name.
  • Use data "aws_vpc" with a filter to find the default VPC.
  • Reference data source attributes in a resource using data.TYPE.NAME.attribute syntax.
  • Output all queried values to confirm they were fetched correctly.

Additional Context

Data sources execute during terraform plan. Terraform calls the cloud provider's API to read the current state of the referenced resource. The result is available as attributes you can reference anywhere in your config.

Key difference: resource = Terraform manages the lifecycle (create, update, delete). data = Terraform only reads; the resource is managed by someone else (another team, the AWS console, another Terraform config).

main.tf

# main.tf

terraform {
  required_version = ">= 1.5.0"
  required_providers {
    aws = { source = "hashicorp/aws", version = "~> 5.0" }
  }
}

provider "aws" { region = "us-east-1" }

# ─── DATA SOURCES ─── Read existing infrastructure without modifying it

# Get the current AWS account ID and user/role info
data "aws_caller_identity" "current" {}

# Get the current region (reads from provider config)
data "aws_region" "current" {}

# Find the default VPC using a filter
# Every AWS account has a default VPC — this finds it without hardcoding the ID
data "aws_vpc" "default" {
  default = true   # simple flag — returns the default VPC
}

# ─── RESOURCE ─── Uses data source values (no hardcoding)
resource "aws_s3_bucket" "datasource_demo" {
  # Bucket name includes account ID and region from data sources
  bucket = "datasource-demo-${data.aws_caller_identity.current.account_id}-${data.aws_region.current.name}"

  tags = {
    AccountID  = data.aws_caller_identity.current.account_id
    Region     = data.aws_region.current.name
    DefaultVPC = data.aws_vpc.default.id
    ManagedBy  = "terraform"
  }
}

outputs.tf

# outputs.tf

output "account_id"     { value = data.aws_caller_identity.current.account_id }
output "caller_arn"     { value = data.aws_caller_identity.current.arn }
output "current_region" { value = data.aws_region.current.name }
output "default_vpc_id" { value = data.aws_vpc.default.id }
output "vpc_cidr"       { value = data.aws_vpc.default.cidr_block }
output "bucket_name"    { value = aws_s3_bucket.datasource_demo.id }

Workflow Commands

terraform init && terraform apply

# All queried values are available as outputs
terraform output account_id
terraform output default_vpc_id
terraform output vpc_cidr

terraform destroy
✓ Expected Output After Apply
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

account_id     = "123456789012"
caller_arn     = "arn:aws:iam::123456789012:user/terraform-user"
current_region = "us-east-1"
default_vpc_id = "vpc-0abc1234def56789"
vpc_cidr       = "172.31.0.0/16"
bucket_name    = "datasource-demo-123456789012-us-east-1"