Terraform으로 기존 GCP 리소스를 import block과 generate-config-out으로 가져오는 방법
Overview
섹션 제목: “Overview”기존 GCP 리소스를 Terraform 코드와 state에 반영하려면 import block 작성, terraform plan -generate-config-out, terraform apply 순서로 진행하면 된다.
이 문서는 이미 콘솔이나 다른 방식으로 생성된 GCP 리소스를 Terraform으로 편입할 때 참고하는 절차다.
새 리소스를 처음부터 Terraform으로 만드는 문서가 아니라, 기존 리소스를 가져오는 경우를 기준으로 정리한다.
흐름은 provider 설정, import block 작성, generate-config-out으로 코드 생성, terraform apply로 state 반영 순서다.
How to
섹션 제목: “How to”1) 로컬 환경 준비
섹션 제목: “1) 로컬 환경 준비”- 전제:
gcloudCLI가 설치되어 있어야 한다. - Terraform이나 SDK가 GCP에 접근할 수 있도록 일반 로그인과 Application Default Credentials를 모두 준비한다.
gcloud auth logingcloud config get-value projectgcloud auth application-default login2) provider 설정 후 terraform init
섹션 제목: “2) provider 설정 후 terraform init”provider.tf가 없으면terraform init을 진행할 수 없다.
provider "google" { project = "example-gcp-prj" region = "asia-northeast3"}terraform init3) import block 작성
섹션 제목: “3) import block 작성”id는 실제 GCP 리소스 식별자이고,to는 Terraform에서 사용할 리소스 주소다.to에 맞는 리소스 주소를 기준으로 Terraform이 생성 코드를 연결한다.
3-1) VPC
섹션 제목: “3-1) VPC”- 예시는 기존 VPC 네트워크를 Terraform으로 가져오는 코드다.
import { id = "projects/PROJECT_ID/global/networks/VPC_NAME" to = google_compute_network.main_vpc}3-2) Cloud Run (v2 서비스)
섹션 제목: “3-2) Cloud Run (v2 서비스)”- 예시는 기존 Cloud Run 서비스를 Terraform으로 가져오는 코드다.
import {id = "projects/프로젝트ID/locations/지역(예: asia-northeast1)/services/클라우드런서비스명"to = google_cloud_run_v2_service.app}- 2개의 서비스를 가져와야한다면 각각 적어야한다.
import { id = "projects/프로젝트ID/locations/asia-northeast1/services/클라우드런서비스A" to = google_cloud_run_v2_service.app_a}
import { id = "projects/프로젝트ID/locations/asia-northeast1/services/클라우드런서비스B" to = google_cloud_run_v2_service.app_b}3-3) Artifact Registry (도커 레포지토리)
섹션 제목: “3-3) Artifact Registry (도커 레포지토리)”- 예시는 기존 Artifact Registry 를 Terraform으로 가져오는 코드다.
import { id = "projects/프로젝트ID/locations/asia-northeast1/repositories/레포지토리명" to = google_artifact_registry_repository.app_repo}3-4) Load Balancer 관련
섹션 제목: “3-4) Load Balancer 관련”-
예시는 기존 Load Balancer의 Backend Service 및 Backend Bucket을 Terraform으로 가져오는 코드다.
-
Backend Service (Cloud Run 연결용)
import { id = "projects/프로젝트ID/global/backendServices/백엔드서비스명" to = google_compute_backend_service.default}- Backend Bucket (GCS 이미지 캐싱용)
- GCS 의 버킷명이 아니라 백엔드버킷으로 지정한 리소스의 Name 을 적어야한다.
import { id = "projects/프로젝트ID/global/backendBuckets/백엔드버킷명" to = google_compute_backend_bucket.default}3-5) Cloud Armor
섹션 제목: “3-5) Cloud Armor”- 예시는 기존 Cloud Armor 의 Policy 를 Terraform으로 가져오는 코드다.
import { id = "projects/프로젝트ID/global/securityPolicies/클라우드아머정책명" to = google_compute_security_policy.cloud_armor}3-6) Cloud Storage (GCS 버킷)
섹션 제목: “3-6) Cloud Storage (GCS 버킷)”- 예시는 기존 Cloud Storage Bucket을 Terraform으로 가져오는 코드다.
- GCS 버킷은 앞의 projects 경로 없이 오직 ‘버킷명’만 ID로 사용한다.
import { id = "클라우드스토리지의 버킷명" to = google_storage_bucket.image_bucket}3-6) Firestore (NoSQL 데이터베이스)
섹션 제목: “3-6) Firestore (NoSQL 데이터베이스)”- 예시는 기존 Firestore 를 Terraform으로 가져오는 코드다.
- 기본 데이터베이스를 사용하는 경우 데이터베이스 ID는 “(default)” 이다.
import { id = "projects/프로젝트ID/databases/(default)" to = google_firestore_database.default}4) generate-config-out으로 코드 생성
섹션 제목: “4) generate-config-out으로 코드 생성”- 아래 명령으로 Terraform 설정 파일을 생성한다.
- 이 단계는 인프라를 변경하지 않지만, 로컬에는 새
.tf파일을 만든다.
terraform plan -generate-config-out=generated.tf5) 생성된 코드 검토
섹션 제목: “5) 생성된 코드 검토”- 생성된
.tf파일의 속성값이 현재 운영 환경과 맞는지 확인한다. - 불필요한 필드나 팀 규칙에 맞지 않는 이름이 있으면 이 단계에서 정리한다.
terraform plan
...
Plan: 3 to import, 0 to add, 0 to change, 0 to destroy.6) terraform apply로 state 반영
섹션 제목: “6) terraform apply로 state 반영”importblock만 작성한 상태에서는 아직 state에 반영되지 않는다.terraform apply를 실행해야 import 결과가tfstate에 기록된다.
terraform apply7) import 완료 후 정리
섹션 제목: “7) import 완료 후 정리”- 적용이 끝난 뒤 다시
terraform plan을 실행해 변경 사항이 없는지 확인한다. - 문제가 없으면
importblock은 삭제해도 된다.
terraform plan
...
No changes. Your infrastructure matches the configuration.Notes
섹션 제목: “Notes”1) terraform import 명령과 import block은 동작 방식이 다르다
섹션 제목: “1) terraform import 명령과 import block은 동작 방식이 다르다”terraform import RESOURCE ADDRESS명령은 실행 즉시 state를 갱신한다.- 반면
importblock 방식은terraform apply를 해야 state에 반영된다.
2) generate-config-out은 코드 생성용이다
섹션 제목: “2) generate-config-out은 코드 생성용이다”terraform plan -generate-config-out=...은 인프라를 직접 변경하지 않는다.- 대신 로컬 작업 디렉터리에 Terraform 설정 파일을 생성한다.
3) import block을 너무 일찍 지우면 create로 해석될 수 있다
섹션 제목: “3) import block을 너무 일찍 지우면 create로 해석될 수 있다”terraform apply전에importblock을 삭제하면 Terraform은 해당 리소스를 import 대상이 아니라 새로 생성할 리소스로 해석할 수 있다.- 반드시 state 반영이 끝난 뒤 삭제한다.
4) Terraform 버전 확인
섹션 제목: “4) Terraform 버전 확인”importblock과generate-config-out은 Terraformv1.5+기준으로 사용하는 편이 안전하다.
terraform version5) GCP 리소스 ID 형식은 리소스마다 다르다
섹션 제목: “5) GCP 리소스 ID 형식은 리소스마다 다르다”- 예시의 VPC처럼
projects/...형식을 쓰는 리소스가 많지만, 모든 GCP 리소스가 같은 형식을 쓰는 것은 아니다. - 예를 들어 VPC는
projects/PROJECT_ID/global/networks/VPC_NAME처럼 쓰지만, Artifact Registry 저장소는 위치가 포함된 다른 형식을 사용할 수 있다. - 정확한
id형식은 각 리소스 문서나terraform import예시를 같이 확인하는 편이 안전하다.
6) 테라폼 출력 종류 (동작 상태 메시지)
섹션 제목: “6) 테라폼 출력 종류 (동작 상태 메시지)”terraform plan실행 시 리소스 이름 옆에 표시되는 문구는 테라폼이 실제 GCP 인프라와 장부(tfstate)에 어떤 행동을 할 것인가를 결정한다.-
출력 문구 안전도 의미와 동작 방식 will be imported최상 (안전) GCP에 존재하는 리소스를 테라폼 장부(tfstate)에 관리 대상으로 등록만 하는 단계다. 실제 리소스에는 아무런 영향도 주지 않는다. will be updated in-place상 (안전) 리소스를 삭제하지 않고 구동 중인 상태 그대로 특정 설정(메모리, 환경변수 등)만 수정한다. 서비스 중단이 없다. will be created중 (주의) 클라우드에 존재하지 않는 새로운 리소스를 처음부터 생성한다. will be replaced하 (위험) 수정이 불가능한 속성(이름, 지역 등)이 변경되어, 기존 리소스를 **삭제(Destroy)한 후 다시 생성(Create)**한다. 서비스 중단이 발생.
7) 내부 메타데이터 동기화 현상
섹션 제목: “7) 내부 메타데이터 동기화 현상”terraform plan을 실행했을 때, 속성 변경 사항(예:~ 속성명 = 값)이 화면에 표시되지 않으면서will be updated in-place가 뜨는 경우가 있다.-
Terminal window ~ XXX will be updated in-place...# (10 unchanged attributes hidden)# (2 unchanged blocks hidden) -
원인: 실제 서비스 설정(포트, 타임아웃 등)은 바뀐 게 없지만, 구글 API가 반환하는 내부 데이터의 포맷이나 순서가 테라폼 장부(tfstate)와 미세하게 어긋날 때 발생
-
특징: 서비스 운영에 영향을 주는 중요 설정이 바뀌는 것이라면 무조건 화면에 속성명이 노출된다. 숨겨진 채(
hidden) 나오는 것은 알맹이가 없는 빈 껍데기 변경이다.
- 조치: 서비스에 100% 안전하므로,
terraform apply를 실행하여 테라폼 장부와 GCP 상태를 한 번 깨끗하게 동기화해주면 다음부터는 나타나지 않는다.
-