모든 것을 만들지 말라: Terraform 데이터 소스의 예술

발행: (2025년 12월 8일 오전 09:09 GMT+9)
7 min read
원문: Dev.to

Source: Dev.to

소개

AWS 챌린지 13일 차이며, 오늘은 인프라스트럭처를 코드로 관리한다는 관점을 완전히 바꿔놓은 것을 배웠습니다: 모든 것을 직접 관리할 필요는 없습니다.

지금까지 제가 했던 모든 Terraform 작업은 리소스를 생성하는 것이었습니다—VPC, 서브넷, 보안 그룹 등. 실제 조직에서는 여러 팀이 인프라의 서로 다른 부분을 소유합니다. 네트워킹 팀은 VPC를 만들고, 보안 팀은 보안 그룹을 관리하며, 여러분의 역할은 그 기존 인프라에 애플리케이션을 배포하는 것입니다.

그때 등장하는 것이 바로 데이터 소스이며, 이는 완전히 게임 체인저입니다.

리소스 vs. 데이터 소스

리소스 블록

resource "aws_vpc" "my_vpc" {
  cidr_block = "10.0.0.0/16"
  # Terraform이 생성·업데이트·삭제를 담당합니다
}

데이터 블록

data "aws_vpc" "existing_vpc" {
  filter {
    name   = "tag:Name"
    values = ["shared-network-vpc"]
  }
  # Terraform은 읽기만 할 뿐, 절대 건드리지 않습니다
}

구분은 간단합니다:

  • 리소스 – “이것은 내가 소유한다. 전체 수명 주기를 관리한다.”
  • 데이터 소스 – “이것은 이미 존재한다. 나는 단지 참조만 하면 된다.”

그 의미는 엄청납니다.

왜 중요한가: 다팀 현실

귀사의 조직 구조

  • 모든 VPC와 서브넷을 관리하는 네트워킹 팀
  • 보안 그룹과 IAM 정책을 유지하는 보안 팀
  • 애플리케이션을 배포하는 인프라 팀(바로 여러분!)

데이터 소스 없이

  • 모든 팀의 Terraform 상태 파일에 접근해야 합니다(쉽지 않죠)
  • ID를 직접 복사‑붙여넣기 해야 합니다
  • 중복 리소스를 만들게 되어 충돌이 발생할 수 있습니다

데이터 소스와 함께

필요한 것을 간단히 조회하면 됩니다:

# 클라우드 네트워킹 팀이 만든 VPC 찾기
data "aws_vpc" "company_vpc" {
  filter {
    name   = "tag:ManagedBy"
    values = ["cloud-networking-team"]
  }
}

# 보안 팀이 관리하는 보안 그룹 찾기
data "aws_security_group" "approved_sg" {
  filter {
    name   = "tag:ManagedBy"
    values = ["security-team"]
  }
}

# 그들의 인프라를 활용해 애플리케이션 배포
resource "aws_instance" "my_app" {
  ami                     = data.aws_ami.latest_amazon_linux.id
  subnet_id               = data.aws_subnet.app_subnet.id
  vpc_security_group_ids = [data.aws_security_group.approved_sg.id]
}

결과: 깔끔하고 협업이 가능하며 충돌이 없는 환경.

직접 해보는 데모: 세 가지 필수 데이터 소스

설정: 기존 인프라 시뮬레이션

# 이것은 네트워킹 팀이 이미 배포한 것을 시뮬레이션합니다
resource "aws_vpc" "shared" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "shared-network-vpc"
  }
}

resource "aws_subnet" "shared" {
  vpc_id     = aws_vpc.shared.id
  cidr_block = "10.0.1.0/24"
  tags = {
    Name = "shared-primary-subnet"
  }
}

이것을 적용한 뒤, 마치 큰 조직에서처럼 “존재한다는 것을 잊어버렸다”고 가정해 보세요.

데이터 소스 #1: VPC 찾기

data "aws_vpc" "shared" {
  filter {
    name   = "tag:Name"
    values = ["shared-network-vpc"]
  }
}

동작 방식

  • 지정된 태그를 가진 VPC를 AWS에 질의합니다
  • VPC ID, CIDR 블록 및 기타 모든 속성을 반환합니다
  • terraform apply 시마다 새로 고침됩니다

콘솔 테스트

terraform console
> data.aws_vpc.shared.id
"vpc-0a1b2c3d4e5f6"
> data.aws_vpc.shared.cidr_block
"10.0.0.0/16"

데이터 소스 #2: 서브넷 찾기 (체인!)

data "aws_subnet" "shared" {
  filter {
    name   = "tag:Name"
    values = ["shared-primary-subnet"]
  }
  vpc_id = data.aws_vpc.shared.id  # VPC 데이터 소스를 사용
}

핵심 포인트

  • 데이터 소스는 체인될 수 있으며, 하나가 다른 하나에 입력됩니다
  • vpc_id 로 검색 범위를 좁혀, 동일한 태그를 가진 여러 서브넷이 있을 때 실수 매치를 방지합니다

데이터 소스 #3: 최신 AMI (동적)

data "aws_ami" "amazon_linux_2" {
  most_recent = true
  owners      = ["amazon"]

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

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

왜 멋진가

  • most_recent = true 로 항상 최신 매칭 AMI를 가져옵니다
  • 와일드카드(*) 로 유연한 패턴 매칭이 가능합니다
  • 여러 필터를 조합해 정확히 원하는 이미지만 얻어, 인스턴스를 자동으로 최신 상태로 유지합니다

모두 합치기: 최종 리소스

resource "aws_instance" "main" {
  ami           = data.aws_ami.amazon_linux_2.id
  instance_type = "t2.micro"
  subnet_id     = data.aws_subnet.shared.id
  private_ip    = "10.0.1.50"

  tags = {
    Name = "day13-instance"
  }
}

terraform plan 실행 결과:

Plan: 1 to add, 0 to change, 0 to destroy.

생성되는 리소스는 하나뿐—EC2 인스턴스. VPC와 서브넷은 단지 참조될 뿐 관리되지 않습니다.

강력한 팁: Terraform Console 테스트

terraform console

# VPC 데이터 소스 테스트
> data.aws_vpc.shared.id
"vpc-0a1b2c3d4e5f6"

# 서브넷 데이터 소스 테스트
> data.aws_subnet.shared.cidr_block
"10.0.1.0/24"

# AMI 데이터 소스 테스트
> data.aws_ami.amazon_linux_2.name
"amzn2-ami-hvm-2.0.20231218.0-x86_64-gp2"

콘솔을 활용해 실제 배포 전에 필터와 값을 검증하세요.

실제로 자주 쓰는 데이터 소스

네트워크 리소스

# VPC 조회
data "aws_vpc" "main" { ... }

# 서브넷 조회
data "aws_subnet" "main" { ... }

# 보안 그룹 조회
data "aws_security_group" "main" { ... }

# 현재 리전의 모든 가용 영역
data "aws_availability_zones" "available" {
  state = "available"
}

컴퓨트 리소스

# 최신 AMI (엄청 흔함)
data "aws_ami" "latest" { ... }

# 기존 EC2 인스턴스
# data "aws_instance" "existing" { ... }

이러한 데이터 소스들은 기존 클라우드 리소스와 연동해야 하는 모든 Terraform 구성의 핵심이 됩니다.

Back to Blog

관련 글

더 보기 »

Terraform 데이터 소스 (AWS)

Terraform 데이터 소스란 무엇인가요? 데이터 소스는 Terraform에서 기존 리소스를 읽기 전용으로 조회하는 기능입니다. 새로운 리소스를 생성하는 대신, Terraform은 ...

Day-13: Terraform의 데이터 소스

Data Sources란 무엇인가요? 데이터 소스를 사용하면 기존 VPC, 서브넷, AMI, 보안 그룹 등과 같은 정보를 가져올 수 있습니다. hcl data 'data_source_type' 'dat...

13일 차: Terraform 데이터 소스

Data Source 데이터 소스를 전화번호부와 같이 사용자 이름과 전화번호가 key‑value 쌍으로 API를 통해 접근되는 것으로 생각해 보세요. 값을 hard‑coding 하는 대신…

AWS Terraform 라이프사이클 규칙

소개 인프라스트럭처 코드(IaC)는 업데이트, 교체 및 삭제 시 리소스가 어떻게 동작하는지에 대한 완전한 제어가 있을 때 가장 강력합니다. Terr...