GCP 서비스 계정 역할 관리 (Terraform)
개요
이 문서는 Terraform을 사용하여 Google Cloud Platform (GCP) 서비스 계정에 할당된 역할을 관리하는 방법을 설명합니다. 특히 기존 서비스 계정에 새로운 역할(커스텀 역할 포함)을 추가하는 방법에 중점을 둡니다.
DTA-WIDE 시스템에서는 다양한 환경(개발, 스테이징, 프로덕션)에서 Terraform 서비스 계정이 인프라를 관리하는 데 필요한 권한을 자동화된 방식으로 부여하기 위해 이 모듈을 사용합니다.
구성 및 아키텍처
- 관리 대상: 서비스 계정(
terraform@dta-cloud-de-[dev|stage|prod].iam.gserviceaccount.com) - 관리 수준: 프로젝트 레벨 역할 할당
- 관리 도구: Terraform, Terragrunt
- 형상 관리: Git (이 저장소)
디렉토리 구조
서비스 계정별로 구분된 구조를 사용하여 관리의 명확성을 높였습니다:
infrastructure/
├── terraform/
│ └── modules/
│ └── iam_service_account_roles/ # 공통 모듈 (재사용 가능)
└── terragrunt/
├── root.hcl # 모든 환경에 공통 설정
├── dev/
│ └── iam/
│ └── terraform_service_account/ # terraform@dta-cloude-de-dev 서비스 계정 전용
├── stage/
│ └── iam/
│ └── terraform_service_account/
└── prod/
└── iam/
└── terraform_service_account/
Terragrunt 구성
루트 설정 (root.hcl)
모든 Terragrunt 설정에 공통으로 적용되는 설정을 root.hcl 파일에 정의합니다:
# Google Cloud 공통 변수 정의
locals {
# 프로젝트 ID 접두사
project_prefix = "dta-cloud-de"
# 현재 경로에서 환경 이름 추출 (dev, stage, prod)
path_parts = split("/", path_relative_to_include())
env = path_parts[0]
# 환경별 프로젝트 ID 생성
project_id = "${local.project_prefix}-${local.env}"
}
# 모든 Terragrunt 모듈에서 사용할 원격 상태 설정
remote_state {
backend = "gcs"
config = {
project = local.project_id
location = "europe-west3"
bucket = "${local.project_id}-terraform-state"
prefix = "${path_relative_to_include()}/terraform.tfstate"
}
}
서비스 계정별 설정
각 서비스 계정에 대한 Terragrunt 설정 파일은 다음과 같이 구성됩니다:
include {
path = find_in_parent_folders("root.hcl")
}
terraform {
source = "../../../../terraform/modules/iam_service_account_roles"
}
inputs = {
project_id = "dta-cloud-de-dev"
service_account_email = "terraform@dta-cloud-de-dev.iam.gserviceaccount.com"
roles = [
# 기존 역할들
"roles/cloudbuild.builds.builder",
# ... 기타 역할들 ...
# 새 커스텀 역할
"projects/dta-cloud-de-dev/roles/TerraformRole"
]
}
Terraform을 통한 서비스 계정 역할 관리
구현 요소
서비스 계정의 역할을 Terraform으로 관리하기 위해 다음 요소를 사용합니다:
- Terraform 모듈: 서비스 계정에 역할을 부여하는
google_project_iam_member리소스를 정의 (/infrastructure/terraform/modules/iam_service_account_roles/) - Terragrunt 구성: 환경별, 서비스 계정별 설정값 관리 (
/infrastructure/terragrunt/[dev|stage|prod]/iam/[service_account_name]/)
Terraform 모듈 구조 (/infrastructure/terraform/modules/iam_service_account_roles/)
모듈은 다음 파일들로 구성됩니다:
main.tf: 서비스 계정에 역할을 할당하는 리소스 정의variables.tf: 입력 변수 정의 (프로젝트 ID, 서비스 계정 이메일, 역할 목록)outputs.tf: 출력값 정의 (할당된 역할 목록, 서비스 계정 이메일)
주요 리소스는 다음과 같습니다:
resource "google_project_iam_member" "service_account_roles" {
count = length(var.roles)
project = var.project_id
role = var.roles[count.index]
member = "serviceAccount:${var.service_account_email}"
}
이 리소스는 서비스 계정에 지정된 역할 목록을 각각 할당합니다. count를 사용하여 여러 역할을 순회하며 할당합니다.
새로운 서비스 계정 추가 방법
새로운 서비스 계정에 대한 역할 관리가 필요한 경우, 다음 단계를 따릅니다:
-
디렉토리 생성: 각 환경에 해당 서비스 계정 이름을 딴 디렉토리를 생성합니다.
mkdir -p infrastructure/terragrunt/dev/iam/new_service_account_name
mkdir -p infrastructure/terragrunt/stage/iam/new_service_account_name
mkdir -p infrastructure/terragrunt/prod/iam/new_service_account_name -
Terragrunt 설정 생성: 각 디렉토리에
terragrunt.hcl파일을 생성하고 해당 서비스 계정의 정보와 역할을 설정합니다.include {
path = find_in_parent_folders("root.hcl")
}
terraform {
source = "../../../../terraform/modules/iam_service_account_roles"
}
inputs = {
project_id = "dta-cloud-de-dev"
service_account_email = "new-account@dta-cloud-de-dev.iam.gserviceaccount.com"
roles = [ ... ]
} -
기존 역할 확인: 서비스 계정의 현재 역할을 확인하고 Terragrunt 설정에 포함합니다.
gcloud projects get-iam-policy PROJECT_ID --format=json | jq '.bindings[] | select(.members[] | contains("SERVICE_ACCOUNT_EMAIL"))'
배포 방법
사전 요구 사항
- 대상 환경의 GCP 프로젝트(
dta-cloud-de-[dev|stage|prod])가 존재해야 합니다. - 서비스 계정이 이미 생성되어 있어야 합니다.
- Terraform 및 Terragrunt가 로컬 또는 CI/CD 환경에 설치되어 있어야 합니다.
- 배포를 실행하는 주체(사용자 또는 서비스 계정)는 대상 프로젝트에 대한
roles/resourcemanager.projectIamAdmin권한을 가지고 있어야 합니다.
기존 역할 확인
서비스 계정의 현재 역할을 확인하기 위해 다음 명령어를 실행합니다:
gcloud projects get-iam-policy dta-cloud-de-dev --format=json | jq '.bindings[] | select(.members[] | contains("terraform@dta-cloud-de-dev.iam.gserviceaccount.com"))'
위 명령어 결과를 참고하여 Terragrunt 설정 파일의 roles 목록을 업데이트합니다.
배포 단계
각 환경별, 서비스 계정별 디렉토리로 이동하여 다음 명령어를 실행합니다:
- 역할 설정 배포:
cd infrastructure/terragrunt/dev/iam/terraform_service_account
terragrunt init
terragrunt plan # 변경 사항 확인
terragrunt apply # 확인 후 적용
모범 사례
- 서비스 계정별 분리: 각 서비스 계정의 역할은 별도의 디렉토리에서 관리하여 명확성을 높입니다.
- 기존 역할 유지: 서비스 계정이 이미 가진 역할을 Terragrunt 설정에 포함하여 실수로 제거되지 않도록 합니다.
- 최소 권한 원칙: 서비스 계정에는 필요한 최소한의 권한만 부여합니다.
- 환경별 분리: 개발, 스테이징, 프로덕션 환경마다 적절한 권한 세트를 별도로 관리합니다.
- 정기적 검토: 서비스 계정의 역할 목록을 주기적으로 검토하여 불필요한 권한을 제거합니다.
문제 해결
- 권한 충돌: 동일한 역할이 다른 방식(예: GCP 콘솔)으로 추가된 경우, Terraform 적용 시 오류가 발생할 수 있습니다. 이 경우
terragrunt import명령을 사용하여 상태를 동기화해야 할 수 있습니다. - 역할 미적용: 서비스 계정에 적용한 역할이 즉시 반영되지 않는 경우, GCP의 캐시 시간(최대 몇 분) 때문일 수 있습니다. 잠시 기다렸다가 다시 확인합니다.
- Terragrunt 중첩 포함 오류: Terragrunt 구성에서
find_in_parent_folders()를 여러 레벨에서 사용하면 중첩 포함 오류가 발생할 수 있습니다. 이 경우find_in_parent_folders("root.hcl")과 같이 구체적인 파일명을 지정해야 합니다.
변경 이력
| 버전 | 날짜 | 작성자 | 변경 내용 |
|---|---|---|---|
| 0.1.0 | 2025-03-29 | (Gemini) | 서비스 계정 역할 관리 문서 초기 생성 |
| 0.2.0 | 2025-03-29 | (Gemini) | 서비스 계정별 디렉토리 구조로 변경 |
| 0.3.0 | 2025-03-29 | (Gemini) | Terragrunt 구성 개선 (root.hcl 사용) |