Day 07 – Using Data Sources in Terraform (VPC, Security Groups & AMI)

Abdul RaheemAbdul Raheem
2 min read

One of the best practices in Terraform is to avoid hardcoding IDs (like VPCs, Subnets, Security Groups, or AMIs). Instead, we can use Terraform Data Sources to dynamically fetch existing infrastructure or latest AMIs.

Today, I explored how to:

  • Fetch an existing VPC

  • Fetch an existing Security Group

  • Fetch the latest Amazon Linux 2 AMI

  • Deploy an EC2 instance using these data sources


🔹 What are Data Sources?

In Terraform, a Data Source allows you to query AWS for existing resources instead of creating new ones.

  • They are read-only (don’t modify infra).

  • Super useful when you need to reference existing infra (like a shared VPC).

  • Makes your Terraform DRY, reusable, and cloud-friendly.


🔹 Terraform Code

main.tf

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "6.9.0"
    }
  }
}

provider "aws" {
  region = "ap-south-1"
}

# 1. Fetch existing VPC
data "aws_vpc" "default" {
  default = true
}

# 2. Fetch existing Security Group by name
data "aws_security_group" "default_sg" {
  filter {
    name   = "group-name"
    values = ["default"]
  }

  vpc_id = data.aws_vpc.default.id
}

# 3. Fetch latest Amazon Linux 2 AMI
data "aws_ami" "amazon_linux" {
  most_recent = true

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["amazon"]
}

# 4. Launch EC2 using the data sources
resource "aws_instance" "example" {
  ami                         = data.aws_ami.amazon_linux.id
  instance_type               = "t2.micro"
  subnet_id                   = data.aws_vpc.default.id
  vpc_security_group_ids      = [data.aws_security_group.default_sg.id]
  associate_public_ip_address = true

  user_data = <<-EOF
              #!/bin/bash
              sudo yum install nginx -y
              sudo systemctl start nginx
              EOF

  tags = {
    Name = "Day07-DataSource-EC2"
  }
}

# Outputs
output "instance_ip" {
  value = aws_instance.example.public_ip
}

output "instance_url" {
  value = "http://${aws_instance.example.public_ip}"
}

🔹 Key Learnings

  1. Data Sources save time → No need to copy-paste IDs from the AWS Console.

  2. Future-proof AMIs → Always fetch the latest Amazon Linux 2 AMI.

  3. Reusable infra → Easily reference shared VPCs or security groups.

  4. Clean & professional Terraform code → DRY principle in practice.


👉 Follow my journey Here:

0
Subscribe to my newsletter

Read articles from Abdul Raheem directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Abdul Raheem
Abdul Raheem

Cloud DevOps | AWS | Terraform | CI/CD | Obsessed with clean infrastructure. Cloud DevOps Engineer 🚀 | Automating Infrastructure & Securing Pipelines | Bridging Gaps Between Code and Cloud ☁️ I’m on a mission to master DevOps from the ground up—building scalable systems, automating workflows, and integrating security into every phase of the SDLC. Currently working with AWS, Terraform, Docker, CI/CD, and learning the art of cloud-native development.