terraform data 블록

도은호·2025년 9월 17일

terraform

목록 보기
3/32

이미 존재하는 클라우드/외부 정보 조회용 블록. 리소스를 생성하지 않고 읽어와 다른 리소스 정의에 활용한다.

  • 문법: data "<provider>_<type>" "<name>" { ... } → 참조: data.<provider>_<type>.<name>.<attr>
  • 용도: 기존 VPC/서브넷, 최신 AMI, 계정/리전 메타데이터, 다른 스택 outputs 등을 가져오기
  • 시점: 주로 plan 때 조회(그래프에 따라 apply에서도). 생성/삭제 없음
  • 주의: “최신” 값을 매 배포마다 끌어오면 결과가 흔들릴 수 있음 → 운영은 버전 고정/태깅 고려

data가 필요한가?

  • 콘솔에서 이미 만들어둔 VPC/서브넷/키페어 등 기존 인프라를 재활용할 때
  • “공식 최신 AMI” 같은 변동 값을 안전하게 가져와 신규 리소스에 주입할 때
  • 모놀리식 대신 스택을 쪼갰을 때, **다른 스택의 outputs**를 읽어와 조립할 때

빠르게 이해하기: resource vs data

구분resourcedata
목적리소스 생성/변경/삭제조회(읽기 전용)
상태(tfstate)리소스 ID 등 관리 대상생성 없음(결과만 참조)
생명주기create / update / destroy없음
예시aws_instance, aws_s3_bucketaws_ami, aws_vpc, terraform_remote_state

필수 문법 & 참조 규칙

# 정의
data "aws_vpc" "default" {
  default = true
}

# 참조
subnet_vpc = data.aws_vpc.default.id
  • for_each/count 사용 가능(읽기 반복)
  • 의존성은 보통 암시적으로 해결되지만, 정말 필요할 때만 depends_on 사용

베스트 6 시나리오(서울 리전 기준)

1) 최신 AMI 가져오기(SSM 권장)

data "aws_ssm_parameter" "al2023" {
  name = "/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64"
}
locals { ami_id = data.aws_ssm_parameter.al2023.value }

resource "aws_instance" "web" {
  ami           = local.ami_id
  instance_type = "t3.micro"
}

2) 기존 VPC/서브넷에 붙이기

data "aws_vpc" "default" { default = true }
data "aws_subnet_ids" "default" { vpc_id = data.aws_vpc.default.id }

resource "aws_security_group" "web" {
  vpc_id = data.aws_vpc.default.id
  # ...
}

resource "aws_instance" "web" {
  subnet_id = tolist(data.aws_subnet_ids.default.ids)[0]
}

3) 계정/리전 메타데이터 출력

data "aws_caller_identity" "me" {}
data "aws_region" "current" {}
output "account_id" { value = data.aws_caller_identity.me.account_id }
output "region"     { value = data.aws_region.current.name }

4) 다른 스택의 outputs 재사용(원격 상태)

data "terraform_remote_state" "network" {
  backend = "s3"
  config = {
    bucket = "my-tf-state-bucket"
    key    = "network/terraform.tfstate"
    region = "ap-northeast-2"
  }
}

locals {
  public_subnet_ids = data.terraform_remote_state.network.outputs.public_subnet_ids
}

5) 안전한 IAM Policy JSON 생성

data "aws_iam_policy_document" "sg_read_only" {
  statement {
    actions   = ["ec2:DescribeSecurityGroups"]
    resources = ["*"]
  }
}
resource "aws_iam_policy" "sg_ro" {
  policy = data.aws_iam_policy_document.sg_read_only.json
}

6) AMI를 필터로 직접 검색(소유자 고정 필수)

data "aws_ami" "al2023" {
  most_recent = true
  owners      = ["137112412989"] # Amazon 공식
  filter { name = "name"          values = ["al2023-ami-*-kernel-6.1-*"] }
  filter { name = "architecture"  values = ["x86_64"] }
}

평가/실행 시점 이해(중요)

  • plan 중 provider API를 호출하여 값을 가져온다
  • 동일한 plan 결과를 apply에 그대로 쓰려면 plan -outapply plan.bin 패턴 사용
  • 외부 리소스가 바뀌면 다음 plan에서 변경점이 다시 계산된다(드리프트 아님, 외부 변경)

운영 팁

  • AMI/이미지 조회: 반드시 owners 지정(공식/내 계정)로 공급자 고정
  • “최신” 남용 주의: 매 배포마다 값 달라짐 → 운영은 태그/버전으로 핀(고정)
  • 의존성: 새로 만든 리소스 직후 그 리소스를 기반으로 조회해야 한다면 그때만 depends_on
  • 성능: 다량 조회 시 for_each + toset()/tomap()로 결과 정리
  • 보안: 원격 상태(S3+DynamoDB 락) + S3 퍼블릭 차단 + KMS 암호화 권장

자주 쓰는 AWS data 소스

  • aws_ssm_parameter — 공식 최신 AMI ID(SSM 파라미터)
  • aws_ami — 필터 기반 AMI 검색(소유자 고정 필수)
  • aws_vpc, aws_subnet_ids, aws_security_group — 기존 네트워크 정보
  • aws_availability_zones — 사용 가능한 AZ 목록
  • aws_caller_identity, aws_region — 계정/리전
  • aws_iam_policy_document — 안전한 Policy JSON 생성
  • terraform_remote_state — 다른 스택 outputs 재사용

예제

terraform {
  required_version = "~> 1.9"
  required_providers {
    aws = { source = "hashicorp/aws", version = "~> 5.0" }
  }
}
provider "aws" { region = "ap-northeast-2" } # 서울

# 1) 최신 AMI 조회(SSM)
data "aws_ssm_parameter" "al2023" {
  name = "/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64"
}

# 2) 기존 VPC/서브넷 조회
data "aws_vpc" "default" { default = true }
data "aws_subnet_ids" "default" { vpc_id = data.aws_vpc.default.id }

# 3) EC2 생성 시 data 값 사용
resource "aws_instance" "web" {
  ami                    = data.aws_ssm_parameter.al2023.value
  instance_type          = "t3.micro"
  subnet_id              = tolist(data.aws_subnet_ids.default.ids)[0]
  vpc_security_group_ids = []
  user_data = <<-EOF
              #!/bin/bash
              dnf -y install nginx
              systemctl enable --now nginx
              EOF
  tags = { Name = "tf-web" }
}

output "ami_id"   { value = data.aws_ssm_parameter.al2023.value }
output "subnet_0" { value = tolist(data.aws_subnet_ids.default.ids)[0] }

명령 흐름:

terraform init
terraform validate
terraform plan -out=plan.bin
terraform apply plan.bin

실습

resource "local_file" "abc" {
    content = "123!!!"
    filename = "${path.module}/abc.txt"
}

data "local_file" "abc" {
  filename = local_file.abc.filename
}

resource "local_file" "def" {
  content = data.local_file.abc.content
  filename = "${path.module}/def.txt"
}
  • 파일 내용이 123!!!인 abc.txt와 def.txt 파일이 생성된다.
profile
`•.¸¸.•´´¯`••._.• 🎀 𝒸𝓇𝒶𝓏𝓎 𝓅𝓈𝓎𝒸𝒽💞𝓅𝒶𝓉𝒽 🎀 •._.••`¯´´•.¸¸.•`

0개의 댓글