Terraform Import 마이그레이션

Terraform Import란?

Terraform Import는 이미 존재하는 인프라 리소스를 Terraform State에 등록하여 코드로 관리할 수 있게 만드는 기능입니다. 콘솔에서 수동 생성한 리소스, 다른 도구로 프로비저닝한 리소스를 IaC(Infrastructure as Code)로 전환할 때 필수적입니다.

Terraform State 관리 심화에서 다룬 것처럼 State는 실제 인프라와 코드의 매핑 테이블입니다. Import는 이 테이블에 기존 리소스를 수동으로 추가하는 작업입니다.

CLI Import vs Import Block

Terraform 1.5부터 import 블록이 도입되어 두 가지 방식이 공존합니다.

CLI 방식 (terraform import)

# 1. 먼저 빈 리소스 블록 작성
resource "aws_s3_bucket" "legacy_data" {}

# 2. CLI로 import 실행
terraform import aws_s3_bucket.legacy_data my-legacy-bucket-2024

CLI 방식은 한 번에 하나의 리소스만 처리하며, 실행 즉시 State에 반영됩니다.

Import Block 방식 (Terraform 1.5+)

# import.tf
import {
  to = aws_s3_bucket.legacy_data
  id = "my-legacy-bucket-2024"
}

import {
  to = aws_iam_role.app_role
  id = "my-app-role"
}

import {
  to = aws_security_group.web_sg
  id = "sg-0a1b2c3d4e5f"
}
# plan으로 미리 확인 후 apply
terraform plan
terraform apply
기준 CLI Import Import Block
다중 리소스 하나씩 실행 여러 개 한 번에
Plan 미리보기 ❌ 바로 적용 ✅ plan 가능
코드 리뷰 ✅ PR로 리뷰 가능
자동 코드 생성 ✅ (1.5+)
CI/CD 호환 스크립트 필요 기존 워크플로 그대로

코드 자동 생성: terraform plan -generate-config-out

Import Block과 함께 사용하면 Terraform이 리소스 코드를 자동 생성합니다.

# import 블록만 작성 (resource 블록 없이)
import {
  to = aws_vpc.imported
  id = "vpc-0abc123def456"
}

# 코드 자동 생성
terraform plan -generate-config-out=generated.tf

생성된 generated.tf:

resource "aws_vpc" "imported" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true
  enable_dns_support   = true
  instance_tenancy     = "default"

  tags = {
    Name = "production-vpc"
  }
}

자동 생성된 코드는 반드시 검토해야 합니다. 불필요한 기본값이 포함되거나, 민감한 값이 하드코딩될 수 있기 때문입니다.

실전 워크플로: 대규모 마이그레이션

수십 개의 리소스를 한 번에 Import하는 실전 워크플로입니다.

1단계: 리소스 목록 수집

# AWS CLI로 기존 리소스 ID 수집
aws ec2 describe-instances --query 'Reservations[].Instances[].InstanceId' --output text
aws s3api list-buckets --query 'Buckets[].Name' --output text
aws rds describe-db-instances --query 'DBInstances[].DBInstanceIdentifier' --output text

2단계: Import Block 일괄 생성

#!/bin/bash
# generate-imports.sh
for bucket in $(aws s3api list-buckets --query 'Buckets[].Name' --output text); do
  safe_name=$(echo "$bucket" | tr '-.' '_')
  echo "import {"
  echo "  to = aws_s3_bucket.${safe_name}"
  echo "  id = "${bucket}""
  echo "}"
  echo ""
done > imports.tf

3단계: 코드 생성 및 검증

# 코드 자동 생성
terraform plan -generate-config-out=generated.tf

# diff 확인 — 변경사항이 없어야 정상
terraform plan
# "No changes. Your infrastructure matches the configuration."

4단계: 정리

# import 블록 제거 (apply 후에는 불필요)
rm imports.tf

# 생성된 코드를 모듈별로 정리
# generated.tf → modules/s3/main.tf, modules/ec2/main.tf 등

for_each와 Import Block 조합

동일 타입의 리소스가 여러 개일 때 for_each와 함께 Import합니다.

locals {
  existing_buckets = {
    "logs"    = "company-logs-prod"
    "assets"  = "company-assets-prod"
    "backups" = "company-backups-prod"
  }
}

import {
  for_each = local.existing_buckets
  to       = aws_s3_bucket.managed[each.key]
  id       = each.value
}

resource "aws_s3_bucket" "managed" {
  for_each = local.existing_buckets
  bucket   = each.value
}

주의사항과 트러블슈팅

문제 원인 해결
Plan에서 destroy+create 코드와 실제 설정 불일치 코드를 실제 값에 맞게 수정
Import 후 drift 발생 리소스 외부에서 변경됨 terraform refresh 후 코드 동기화
ID를 모르는 경우 Provider마다 ID 형식 다름 Provider 문서의 Import 섹션 확인
민감한 값 노출 State에 평문 저장 S3 backend 암호화 + sensitive 변수
모듈 내부 리소스 Import 주소 형식이 다름 module.name.resource 형식 사용
# 모듈 내부 리소스 Import 예시
import {
  to = module.networking.aws_vpc.main
  id = "vpc-0abc123"
}

# 인덱스가 있는 리소스
import {
  to = aws_subnet.private["ap-northeast-2a"]
  id = "subnet-0abc123"
}

moved 블록과의 차이

import는 외부 리소스를 State에 추가하고, moved는 이미 State에 있는 리소스의 주소를 변경합니다. Terraform lifecycle에서 다룬 것처럼, 리팩토링 시 moved를 활용하면 리소스 재생성 없이 코드 구조를 변경할 수 있습니다.

# 리소스 이름 변경
moved {
  from = aws_s3_bucket.old_name
  to   = aws_s3_bucket.new_name
}

# 모듈로 이동
moved {
  from = aws_s3_bucket.data
  to   = module.storage.aws_s3_bucket.data
}

정리

Terraform Import는 기존 인프라를 IaC로 전환하는 핵심 기능입니다. Terraform 1.5+의 Import Block을 사용하면 Plan 미리보기, 코드 자동 생성, PR 기반 리뷰가 가능해져 안전한 마이그레이션이 가능합니다. 대규모 전환 시에는 스크립트로 Import Block을 일괄 생성하고, -generate-config-out으로 코드를 자동 생성한 뒤 검증하는 워크플로를 추천합니다.

위로 스크롤
WordPress Appliance - Powered by TurnKey Linux