Cloud Foundation Toolkit 시작하기

1. CFT 101 소개

b1d2ab0f35bb62a8.png

최종 업데이트: 2022년 2월 11일

Cloud Foundation Toolkit이란 무엇인가요?

기본적으로 CFT는 Google Cloud Platform을 빠르게 시작할 수 있는 권장사항 템플릿을 제공합니다. 이 튜토리얼에서는 Cloud Foundation Toolkit에 기여하는 방법을 알아봅니다.

필요한 항목

  • GitHub 계정
  • 머신에 Docker가 설치되어 있거나 Cloud Shell 사용 ( Mac 설치, Windows 설치)
  • 코드를 수정하는 코드 편집기 (예: Visual Studio Code)
  • Git 및 GitHub에 대한 기본 지식
  • Terraform 및 코드형 인프라 사용 경험
  • 서비스 계정에 프로젝트 생성자 역할을 부여할 수 있는 권한
  • Google Cloud 조직, 테스트 폴더, 결제 계정

빌드할 항목

이 Codelab에서는 Cloud Foundation Toolkit (CFT)에 기여하는 방법을 알아봅니다.

실습할 내용은 다음과 같습니다.

  • CFT에 기여하기 위한 개발 환경 설정
  • CFT 모듈에 기능 추가
  • 추가된 기능에 대한 테스트 추가
  • CFT에서 통합 테스트 실행
  • 린트 테스트 실행
  • GitHub에 코드를 커밋하고 풀 요청 (PR) 제출

Google Cloud Storage CFT 모듈새 기능을 추가하여 위의 모든 단계를 실행합니다. GCS CFT 모듈을 통해 생성된 모든 버킷에 자동으로 추가되는 "silly_label"이라는 라벨을 추가합니다. 또한 테스트를 작성하여 기능을 검증하고 엔드 투 엔드 통합을 보장할 수 있습니다.

2. 개발 환경 설정

원하는 경우 개발 목적으로 Cloud Shell을 활용할 수 있습니다. CFT에 기여하는 데 Cloud Shell을 사용하지 않으려면 머신에 개발 환경을 설정하면 됩니다.

Git 설정

GitHub는 Git이라는 오픈소스 버전 제어 시스템 (VCS)을 기반으로 합니다. Git은 머신 또는 Cloud Shell에서 로컬로 발생하는 모든 GitHub 관련 작업을 담당합니다.

  1. Cloud Shell을 사용하는 경우 git이 사전 설치되어 있으므로 설치할 필요가 없습니다.
$ git --version
# This will display the git version on the Cloud Shell.

머신에 개발 환경을 설정하는 경우 Git을 설치해야 합니다.

Git에서 사용자 이름과 이메일 설정하기

Git은 사용자 이름을 사용하여 커밋을 ID와 연결합니다. Git 사용자 이름이 GitHub 사용자 이름과 같지 않습니다.

git config 명령어를 사용하여 Git 커밋과 연결된 이름을 변경할 수 있습니다. git config를 사용하여 Git 커밋과 연결된 이름을 변경하면 향후 커밋에만 영향을 미치며 이전 커밋에 사용된 이름은 변경되지 않습니다.

Git을 설정했으며 브랜치를 포크, 생성, 클론할 수 있습니다. 이 Codelab에서는 Git을 광범위하게 사용합니다.

3. CFT의 GCS 저장소 포크

CFT 저장소 포크

이전 단계에서 로컬 머신 또는 Cloud Shell에 Git을 설정했습니다. 이제 Google Cloud Storage CFT 저장소를 포크하여 기여를 시작해야 합니다.

포크는 저장소의 사본입니다. 저장소를 포크하면 원본 프로젝트에 영향을 주지 않고 자유롭게 변경사항을 실험할 수 있습니다.

일반적으로 포크는 다른 사용자의 프로젝트에 변경사항을 제안하거나 다른 사용자의 프로젝트를 내 아이디어의 시작점으로 사용하는 데 사용됩니다.

예를 들어 포크를 사용하여 버그 수정과 관련된 변경사항을 제안할 수 있습니다. 버그를 수정하려면 다음 단계를 따르세요.

  • 저장소를 포크합니다.
  • 수정합니다.
  • 프로젝트 소유자에게 풀 요청을 제출합니다.

CFT 저장소를 포크하는 단계는 다음과 같습니다.

  1. 웹브라우저를 열고 terraform-google-modules/terraform-google-cloud-storage 저장소로 이동합니다. 이 저장소는 Codelab 전체에서 사용됩니다.
  2. 페이지 오른쪽 상단에서 포크를 클릭합니다.

9dc18f15ca662b56.png

  1. 포크할 위치를 선택하는 옵션이 표시되면 프로필을 선택하고 저장소가 포크됩니다.

로컬에서 포크 클론하기

생성한 포크는 GCS 모듈 저장소의 사본입니다. 이제 이 저장소를 로컬 환경에 클론하여 새 기능을 추가합니다.

포크를 클론하는 단계는 다음과 같습니다.

  1. 웹브라우저를 열고 terraform-google-modules/terraform-google-cloud-storage에서 포크로 이동합니다.
  2. 오른쪽 상단에 있는 '코드' 버튼을 클릭합니다.

98f8be8df319dcd8.png

  1. '코드' 버튼을 클릭한 후 '복사' 아이콘을 클릭하여 포크의 URL을 복사합니다. 이 URL을 사용하여 포크를 로컬 환경에 클론합니다.

e61e1da6371f2a1d.png

  1. VSCode 또는 머신의 터미널로 이동하여 포크를 클론합니다.
$ git clone <url>
# This command will clone your fork locally.
# Paste the copied URL from the previous step.
  1. 포크를 로컬로 클론했으므로 저장소로 이동하여 포크에서 새 브랜치를 만들고 임시 브랜치에서 코드를 변경해야 합니다.

일반적으로 브랜치 이름은 다음과 같이 지정할 수 있습니다.

  • 기능 요청: feature/feature-name
  • 내부 업데이트의 경우 internal/change-name
  • 버그 수정: bugfix/issue-name

새 기능을 추가하므로 임시 브랜치를 feature/silly_label라고 지정할 수 있습니다.

$ cd terraform-google-cloud-storage
# This command takes you into the cloned directory on your local machine.

$ git branch
# This command tells your current branch
# When you run this for the first time after you have cloned, your 
# output should say "master", that is your fork.

$ git checkout -b feature/silly_label
# This command creates a new branch on your fork and switches your 
# branch to the newly created branch.

$ git branch
# This command will confirm your current branch to be "feature/silly_label"

이제 Cloud Foundation Toolkit 작업을 시작할 준비가 되었습니다.

4. 테스트 환경 만들기

표준 CFT 개발 프로세스는 테스트를 위해 격리된 테스트 프로젝트를 사용하는 것을 기반으로 합니다. 이 단계에서는 서비스 계정을 통해 표준 구성을 기반으로 테스트 프로젝트를 만드는 방법을 안내합니다.

0. Docker Engine 설치

개발 목적으로 머신을 사용하는 경우 Docker Engine을 설치해야 합니다.

1. Google Cloud SDK 설치

GCP Cloud Shell을 사용하는 경우 Google Cloud SDK를 설치하지 않아도 됩니다.

Google Cloud SDK로 이동하여 플랫폼용 대화형 설치 프로그램을 다운로드합니다.

2. 구성 설정

테스트 환경을 만들려면 Google Cloud 조직, 테스트 폴더, 결제 계정이 필요합니다. 이러한 값은 환경 변수를 통해 설정해야 합니다.

export TF_VAR_org_id="your_org_id"
export TF_VAR_folder_id="your_folder_id"
export TF_VAR_billing_account="your_billing_account_id"

3. 서비스 계정 설정

테스트 환경을 만들기 전에 서비스 계정 키를 테스트 환경에 다운로드해야 합니다. 이 서비스 계정에는 프로젝트 생성자, 결제 계정 사용자,조직 뷰어 역할이 필요합니다. 이 단계에서는 새 서비스 계정을 만드는 방법을 설명하지만 기존 계정을 재사용할 수도 있습니다.

3.1 시드 GCP 프로젝트 만들기 또는 선택

서비스 계정을 만들기 전에 서비스 계정을 호스팅할 프로젝트를 선택해야 합니다. 새 프로젝트를 만들 수도 있습니다.

gcloud config set core/project YOUR_PROJECT_ID

3.2 Google Cloud API 사용 설정

시드 프로젝트에서 다음 Google Cloud API를 사용 설정합니다.

gcloud services enable cloudresourcemanager.googleapis.com
gcloud services enable iam.googleapis.com
gcloud services enable cloudbilling.googleapis.com

3.3 서비스 계정 만들기

테스트 환경을 관리할 새 서비스 계정을 만듭니다.

# Creating a service account for CFT.
gcloud iam service-accounts create cft-onboarding \
  --description="CFT Onboarding Terraform Service Account" \
  --display-name="CFT Onboarding"

# Assign SERVICE_ACCOUNT environment variable for later steps
export SERVICE_ACCOUNT=cft-onboarding@$(gcloud config get-value core/project).iam.gserviceaccount.com

서비스 계정이 생성되었는지 확인합니다.

gcloud iam service-accounts list --filter="EMAIL=${SERVICE_ACCOUNT}"

3.4 서비스 계정에 프로젝트 생성자, 결제 계정 사용자, 조직 뷰어 역할 부여:

gcloud resource-manager folders add-iam-policy-binding ${TF_VAR_folder_id} \
  --member="serviceAccount:${SERVICE_ACCOUNT}" \
  --role="roles/resourcemanager.projectCreator"
gcloud organizations add-iam-policy-binding ${TF_VAR_org_id} \
  --member="serviceAccount:${SERVICE_ACCOUNT}" \
  --role="roles/billing.user"
gcloud beta billing accounts add-iam-policy-binding ${TF_VAR_billing_account} \
  --member="serviceAccount:${SERVICE_ACCOUNT}" \
  --role="roles/billing.user"
gcloud organizations add-iam-policy-binding ${TF_VAR_org_id} \
  --member="serviceAccount:${SERVICE_ACCOUNT}" \
  --role="roles/resourcemanager.organizationViewer"

이제 테스트 환경을 관리하는 데 사용할 수 있는 서비스 계정이 있습니다.

4. Terraform 사용자 인증 정보 준비

테스트 환경을 만들려면 서비스 계정 키를 셸에 다운로드해야 합니다.

4.1 서비스 계정 키

Terraform용 서비스 계정 키 만들기 및 다운로드

gcloud iam service-accounts keys create cft.json --iam-account=${SERVICE_ACCOUNT}

4.2 Terraform 사용자 인증 정보 설정

환경 변수 SERVICE_ACCOUNT_JSON를 사용하여 Terraform에 키를 제공하고 값을 서비스 계정 키의 콘텐츠로 설정합니다.

export SERVICE_ACCOUNT_JSON=$(< cft.json)

환경 변수에 사용자 인증 정보 정보를 저장한 후 키 파일을 삭제합니다. 필요한 경우 나중에 위의 동일한 명령어를 사용하여 키를 다시 만들 수 있습니다.

rm -rf cft.json

5. Terraform 배포용 테스트 프로젝트 만들기

이제 모든 것이 준비되었으므로 단일 명령어로 테스트 프로젝트를 만들 수 있습니다. terraform-google-cloud-storage 디렉터리 루트에서 다음 명령어를 실행합니다.

make docker_test_prepare

make docker_test_prepare를 실행하면 아래 출력이 표시됩니다. 마지막에 새 기능으로 Cloud Storage 모듈을 배포하고 테스트할 테스트 project_id가 생성됩니다. 결제 계정 연결에 문제가 있는 경우 문제 해결 단계를 참고하세요.

macbookpro3:terraform-google-cloud-storage user$ make docker_test_prepare
docker run --rm -it \
                -e SERVICE_ACCOUNT_JSON \
                -e TF_VAR_org_id \
                -e TF_VAR_folder_id \
                -e TF_VAR_billing_account \
                -v /Users/cft/terraform-google-cloud-storage:/workspace \
                gcr.io/cloud-foundation-cicd/cft/developer-tools:0.8.0 \
                /usr/local/bin/execute_with_credentials.sh prepare_environment
Activated service account credentials for: [cft-onboarding@<project_id>.iam.gserviceaccount.com]
Activated service account credentials for: [cft-onboarding@<project_id>.iam.gserviceaccount.com]
Initializing modules...

Initializing the backend...

Initializing provider plugins...

The following providers do not have any version constraints in configuration,
so the latest version was installed.

To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.

* provider.google-beta: version = "~> 3.9"
* provider.null: version = "~> 2.1"
* provider.random: version = "~> 2.2"

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
module.project.module.project-factory.null_resource.preconditions: Refreshing state... [id=8723188031607443970]
module.project.module.project-factory.null_resource.shared_vpc_subnet_invalid_name[0]: Refreshing state... [id=5109975723938185892]
module.project.module.gsuite_group.data.google_organization.org[0]: Refreshing state...
module.project.module.project-factory.random_id.random_project_id_suffix: Refreshing state... [id=rnk]
module.project.module.project-factory.google_project.main: Refreshing state... [id=<project-id>]
module.project.module.project-factory.google_project_service.project_services[0]: Refreshing state... [id=<project-id>/storage-api.googleapis.com]
module.project.module.project-factory.google_project_service.project_services[1]: Refreshing state... [id=<project-id>/cloudresourcemanager.googleapis.com]
module.project.module.project-factory.google_project_service.project_services[2]: Refreshing state... [id=<project-id>/compute.googleapis.com]
module.project.module.project-factory.data.null_data_source.default_service_account: Refreshing state...
module.project.module.project-factory.google_service_account.default_service_account: Refreshing state... [id=projects/ci-cloud-storage-ae79/serviceAccounts/project-service-account@<project-id>.iam.gserv
iceaccount.com]
module.project.module.project-factory.google_project_service.project_services[3]: Refreshing state... [id=<project-id>/serviceusage.googleapis.com]
module.project.module.project-factory.null_resource.delete_default_compute_service_account[0]: Refreshing state... [id=3576396874950891283]
google_service_account.int_test: Refreshing state... [id=projects/<project-id>/serviceAccounts/cft-onboarding@<project-id>.iam.gserviceaccount.com]
google_service_account_key.int_test: Refreshing state... [id=projects/<project-id>/serviceAccounts/cft-onboarding@<project-id>.iam.gserviceaccount.com/keys/351009a1e011e88049ab2097994d1c627a61
6961]
google_project_iam_member.int_test[1]: Refreshing state... [id=<project-id>/roles/iam.serviceAccountUser/serviceaccount:cft-onboarding@<project-id>.iam.gserviceaccount.com]
google_project_iam_member.int_test[0]: Refreshing state... [id=<project-id>/roles/storage.admin/serviceaccount:cft-onboarding@<project-id>.iam.gserviceaccount.com]

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

project_id = <test-project-id>
sa_key = <sensitive>
Found test/setup/make_source.sh. Using it for additional explicit environment configuration.

이제 콘솔 출력에서 볼 수 있듯이 project_id로 참조되는 테스트 프로젝트가 생성되었습니다. 개발 및 테스트 환경이 설정됩니다.

5. CFT 모듈에 새 기능 추가

이제 개발 및 테스트 환경이 설정되었으므로 google-cloud-storage CFT 모듈에 'silly_label' 기능을 추가해 보겠습니다.

terraform-google-cloud-storage에 있는지 확인하고 폴더 구조에서 아래와 같이 main.tf 파일을 엽니다.

ac1dba25408abd09.png

'silly_label'은 라벨이므로 아래와 같이 main.tf의 'labels' 변수 27번째 줄에 기능을 추가합니다.

terraform-google-cloud-storage/main.tf

resource "google_storage_bucket" "buckets" {
 <...>
 storage_class = var.storage_class
 // CODELAB:Add silly label in labels variable
 labels        = merge(var.labels, { name = replace("${local.prefix}${lower(each.value)}", ".", "-") }, { "silly" = var.silly_label })
 force_destroy = lookup(
 <...>
}

이제 위의 폴더 구조에 표시된 variables.tf에 silly_label 변수를 추가합니다.

아래 코드를 복사하여 variables.tf의 31번째 줄에 추가하고 추가한 변수 블록 위와 아래에 새 줄 문자가 있는지 확인합니다.

terraform-google-cloud-storage/variables.tf

variable "names" {
 description = "Bucket name suffixes."
 type        = list(string)
}

// CODELAB: Add "silly_label" variable to variables.tf between "names" and "location"
variable "silly_label" {
 description = "Sample label for bucket."
 type        = string
}

variable "location" {
 description = "Bucket location."
 default     = "EU"
}

6. 스토리지 버킷 예시에 새 기능 추가

모듈의 main.tf에 기능을 추가했으며 이제 예를 통해 추가된 기능을 테스트합니다.

'silly_label'은 examples/multiple-buckets/main.tf에 추가해야 합니다.

이 예는 다음 단계에서 통합 테스트를 실행하는 데 사용됩니다.

아래 silly_label 변수 행을 폴더 구조에 표시된 대로 terraform-google-cloud-storage/examples/multiple-buckets/ 의 main.tf에 27번째 행에 복사하여 붙여넣습니다.

5224fefbbcc61d89.png

terraform-google-cloud-storage/examples/multiple-buckets/main.tf

module "cloud_storage" {
 <...>
 // CODELAB: Add "silly_label" as an example to main.tf.
 silly_label        = "awesome"

 <..>
}

7. 기능을 확인하도록 청사진 테스트 업데이트

모듈의 main.tf에 기능을 추가한 다음 multiple_buckets 예시에 기능을 추가했습니다. 이제 Golang으로 작성된 블루프린트 통합 테스트를 통해 기능을 테스트해야 합니다.

아래 폴더 구조에 있는 multiple_buckets_test.go 파일에 새 테스트를 추가합니다.

72ea272d4792405.png

multiple_buckets 모듈을 통해 생성되는 모든 버킷에 'silly_label'을 추가했으며 이제 새 기능을 테스트하는 테스트를 작성해야 합니다.

아래 코드에서는 gcloud alpha storage 명령어를 통해 각 버킷의 라벨을 가져온 다음 명령어에서 반환된 출력을 확인합니다.

test/integration/multiple_buckets/multiple_buckets_test.go

func TestMultipleBuckets(t *testing.T) {
 <..>
op := gcloud.Run(t, fmt.Sprintf("alpha storage ls --buckets gs://%s", bucketName), gcloudArgs).Array()[0]

// verify silly label on each bucket
assert.Equal("awesome", op.Get("metadata.labels.silly").String(), "should have silly label set to awesome")

// verify lifecycle rules
...
}

8. CFT에서 통합 테스트 실행

통합 테스트

통합 테스트는 루트 모듈, 하위 모듈, 예의 동작을 확인하는 데 사용됩니다. 추가, 변경, 수정에는 테스트가 수반되어야 합니다.

통합 테스트는 청사진 테스트 프레임워크를 사용하여 작성되고 CFT CLI를 사용하여 실행됩니다. 이러한 도구는 편의를 위해 Docker 이미지 내에 패키징됩니다.

이러한 테스트의 일반적인 전략은 예시 모듈의 동작을 확인하여 루트 모듈, 하위 모듈, 예시 모듈이 모두 기능적으로 올바른지 확인하는 것입니다.

인터랙티브 실행에서는 여러 명령어를 통해 각 단계를 실행합니다.

  1. make docker_run를 실행하여 대화형 모드에서 테스트 Docker 컨테이너를 시작합니다.

Make는 타겟 프로그램을 파생하는 방법을 지정하는 Makefile이라는 파일을 읽어 소스 코드에서 실행 가능한 프로그램과 라이브러리를 자동으로 빌드하는 빌드 자동화 도구입니다. 파일을 변경하면 Docker 컨테이너가 자동으로 업데이트되어야 합니다.

make docker_run을 실행하면 Docker 컨테이너에서 워크스페이스를 만들고 서비스 계정의 사용자 인증 정보를 활성화합니다. 워크스페이스는 다음 단계에서 테스트를 실행하는 데 사용됩니다.

터미널에 다음과 같은 출력이 표시됩니다.

Activated service account credentials for: [cft@<PROJECT_ID>.iam.gserviceaccount.com]
  1. module-swapper -registry-prefix=terraform-google-modules를 실행하여 게시된 모듈 대신 로컬 파일에서 모듈을 가져오도록 예시 main.tf 파일을 조정합니다.

터미널에 다음과 같은 출력이 표시되어야 합니다.

[root@<CONTAINER_ID> workspace]# module-swapper -registry-prefix=terraform-google-modules
2025/08/04 19:26:29 Module name set from remote to cloud-storage
2025/08/04 19:26:29 Modifications made to file /workspace/examples/multiple_buckets/main.tf
2025/08/04 19:26:29 --- Original
+++ Modified
@@ -21,7 +21,7 @@
 }
 
 module "cloud_storage" {
-  source = "terraform-google-modules/cloud-storage/google"
+  source = "../.."
   # [restore-marker]   version = "~> 10.0"
 
   project_id = var.project_id
  1. cft test list를 실행하여 작업공간의 모든 청사진 테스트를 나열합니다.

터미널에 다음과 같은 출력이 표시됩니다.

[root@CONTAINER_ID workspace]# cft test list
 NAME                           | CONFIG                    | LOCATION                                                   
--------------------------------+---------------------------+------------------------------------------------------------
 TestAll/examples/simple_bucket | examples/simple_bucket    | test/integration/discover_test.go                          
 TestMultipleBuckets            | examples/multiple_buckets | test/integration/multiple_buckets/multiple_buckets_test.go 

  1. cft test run <EXAMPLE_NAME> --stage init를 실행하여 예시를 초기화합니다. 이 경우 TestMultipleBuckets 테스트 실행을 초기화하려면 cft test run TestMultipleBuckets --stage init을 사용합니다. 테스트를 실행할 때 --verbose 플래그를 사용하여 추가 정보를 가져올 수도 있습니다.

이 init 단계는 Terraform 예시를 초기화합니다.

터미널에 아래와 같은 출력이 표시됩니다.

[root@<CONTAINER_ID> workspace]# cft test run TestMultipleBuckets --stage init --verbose
INFO[02-09|08:24:31] using test-dir: test/integration 
...
TestMultipleBuckets 2022-02-09T08:24:35Z command.go:179: Terraform has been successfully initialized!
...
TestMultipleBuckets 2022-02-09T08:24:35Z command.go:100: Running command terraform with args [validate]
TestMultipleBuckets 2022-02-09T08:24:36Z command.go:179: Success! The configuration is valid.
...
--- PASS: TestMultipleBuckets (4.05s)
  1. cft test run <EXAMPLE_NAME> --stage apply를 실행하여 예시 모듈을 적용합니다.

이 단계에서는 이전 단계에서 초기화된 예시를 Codelab에서 이전에 만든 GCP 프로젝트에 적용합니다.

터미널에 아래와 같은 출력이 표시됩니다.

[root@<CONTAINER_ID> workspace]# cft test run TestMultipleBuckets --stage apply --verbose
INFO[02-09|08:28:11] using test-dir: test/integration
...
TestMultipleBuckets 2022-02-09T08:28:19Z command.go:179: Apply complete! Resources: 6 added, 0 changed, 0 destroyed.
TestMultipleBuckets 2022-02-09T08:28:19Z command.go:179: 
TestMultipleBuckets 2022-02-09T08:28:19Z command.go:179: Outputs:
TestMultipleBuckets 2022-02-09T08:28:19Z command.go:179: 
TestMultipleBuckets 2022-02-09T08:28:19Z command.go:179: names = {
TestMultipleBuckets 2022-02-09T08:28:19Z command.go:179:   "one" = "multiple-buckets-erp1-eu-one"
...
--- PASS: TestMultipleBuckets (6.51s)
PASS
ok      github.com/terraform-google-modules/terraform-google-cloud-storage/test/integration/multiple_buckets    6.548s
  1. cft test run <EXAMPLE_NAME> --stage verify를 실행하여 예시에서 예상한 인프라가 생성되었는지 확인합니다.

이 단계에서는 TestMultipleBuckets에서 확인 함수를 실행합니다. 일반적으로 확인은 gcloud 명령어를 실행하여 리소스의 현재 상태에 대한 JSON 출력을 가져오고 현재 상태가 예시에 선언된 대로인지 확인하는 방식으로 이루어집니다.

오류가 발생하면 테스트를 위해 명령어로 예상한 내용과 수신한 내용이 표시됩니다.

터미널에 아래와 같은 출력이 표시됩니다.

[root@<CONTAINER_ID> workspace]# cft test run TestMultipleBuckets --stage verify --verbose
INFO[02-09|08:30:19] using test-dir: test/integration
...
TestMultipleBuckets 2022-02-09T08:30:27Z command.go:100: Running command terraform with args [output -no-color -json names_list]
TestMultipleBuckets 2022-02-09T08:30:27Z command.go:179: ["multiple-buckets-erp1-eu-one","multiple-buckets-erp1-eu-two"]
TestMultipleBuckets 2022-02-09T08:30:27Z command.go:100: Running command gcloud with args [alpha storage ls --buckets gs://multiple-buckets-erp1-eu-one --project ci-cloud-storage-8ce9 --json]
TestMultipleBuckets 2022-02-09T08:30:28Z command.go:179: [
TestMultipleBuckets 2022-02-09T08:30:28Z command.go:179: {
TestMultipleBuckets 2022-02-09T08:30:28Z command.go:179:   "url": "gs://multiple-buckets-erp1-eu-one/",
...
TestMultipleBuckets 2022-02-09T08:30:33Z command.go:179: ]
2022/02/09 08:30:33 RUN_STAGE env var set to verify
2022/02/09 08:30:33 Skipping stage teardown
--- PASS: TestMultipleBuckets (12.32s)
PASS
ok      github.com/terraform-google-modules/terraform-google-cloud-storage/test/integration/multiple_buckets    12.359s
  1. cft test run <EXAMPLE_NAME> --stage teardown을 실행하여 예시를 해체합니다.

이 단계에서는 위의 단계에서 만든 인프라를 폐기합니다. 이 단계에서는 프로젝트에서 생성된 GCS 버킷과 GCS 모듈에 추가한 라벨도 삭제됩니다.

터미널에서 아래 출력을 확인할 수 있습니다.

[root@<CONTAINER_ID> workspace]# cft test run TestMultipleBuckets --stage teardown --verbose
INFO[02-09|08:36:02] using test-dir: test/integration
...
TestMultipleBuckets 2022-02-09T08:36:06Z command.go:100: Running command terraform with args [destroy -auto-approve -input=false -lock=false]
TestMultipleBuckets 2022-02-09T08:36:07Z command.go:179: module.cloud_storage.random_id.bucket_suffix: Refreshing state... [id=mNA]
TestMultipleBuckets 2022-02-09T08:36:07Z command.go:179: random_string.prefix: Refreshing state... [id=erp1]
TestMultipleBuckets 2022-02-09T08:36:08Z command.go:179: module.cloud_storage.google_storage_bucket.buckets["two"]: Refreshing state... [id=multiple-buckets-erp1-eu-two]
...
TestMultipleBuckets 2022-02-09T08:36:10Z command.go:179: Destroy complete! Resources: 6 destroyed.
TestMultipleBuckets 2022-02-09T08:36:10Z command.go:179: 
--- PASS: TestMultipleBuckets (6.62s)
PASS
ok      github.com/terraform-google-modules/terraform-google-cloud-storage/test/integration/multiple_buckets    6.654s
  1. module-swapper -registry-prefix=terraform-google-modules -restore를 실행하여 마지막으로 module-swapper를 실행했을 때의 예시 main.tf 파일에 대한 조정을 실행취소합니다.
[root@<CONTAINER_ID> workspace]# module-swapper -registry-prefix=terraform-google-modules -restore
2025/08/04 19:30:41 Module name set from remote to cloud-storage
2025/08/04 19:36:32 Modifications made to file /workspace/examples/multiple_buckets/main.tf
2025/08/04 19:36:32 --- Original
+++ Modified
@@ -21,8 +21,8 @@
 }
 
 module "cloud_storage" {
-  source = "../.."
-   version = "~> 10.0"
+  source  = "terraform-google-modules/cloud-storage/google"
+  version = "~> 10.0"
 
   project_id = var.project_id
 
  1. exit을 실행하여 테스트 컨테이너를 종료합니다.

9. 입력 및 출력에 대한 문서 생성

루트 모듈, 하위 모듈, 예시 모듈의 README에 있는 입력 및 출력 테이블은 각 모듈의 variablesoutputs에 따라 자동으로 생성됩니다. 모듈 인터페이스가 변경되면 이러한 테이블을 새로고침해야 합니다.

실행:

make generate_docs
# This will generate new Inputs and Outputs tables

10. CFT에서 린트 테스트 실행

린터는 소스 코드를 분석하여 프로그래밍 오류, 버그, 스타일 오류, 의심스러운 구조를 표시하는 도구입니다.

저장소의 많은 파일을 린트하거나 포맷하여 품질 표준을 유지할 수 있습니다. CFT의 품질을 보장하기 위해 린트 테스트를 사용합니다.

실행:

make docker_test_lint
# This will run all lint tests on your repo

11. GitHub에서 풀 요청 제출

이제 코드를 로컬로 변경하고 통합 테스트를 통해 테스트했으므로 이 코드를 마스터 저장소에 게시해야 합니다.

마스터 저장소에서 코드를 사용할 수 있도록 하려면 브랜치에 코드 변경사항을 커밋하고 마스터 저장소에 푸시해야 합니다. Codelab 시작 시 포크한 기본 저장소에 코드를 추가하려면 저장소에 코드를 커밋한 후 마스터 저장소에서 풀 요청 (PR)을 제기합니다.

PR을 제출하면 제안된 코드 변경사항을 검토하라는 알림이 저장소 관리자에게 전송됩니다. 또한 다른 사용자를 검토자로 추가하여 코드 변경사항에 대한 의견을 받을 수도 있습니다. PR이 Cloud Build를 트리거하여 저장소에서 테스트를 실행합니다.

코드 변경사항을 바탕으로 코드 검토자가 코드에 대한 의견을 제공하고 권장사항 및 문서에 따라 변경해야 하는 사항이 있으면 수정을 요청합니다. 관리자는 코드 변경사항을 검토하고 코드가 저장소를 준수하는지 확인하며, 코드를 마스터 저장소에 병합하기 전에 변경사항을 적용하도록 다시 요청할 수 있습니다.

다음 단계에 따라 포크된 브랜치에 코드를 커밋하고 포크된 브랜치에 코드를 푸시합니다.

  1. 첫 번째 단계는 변경된 파일을 로컬 저장소에 추가하는 것입니다.
$ git add main.tf
$ git add README.md
$ git add variables.tf
$ git add examples/multiple-buckets/main.tf
$ git add test/integration/multiple_buckets/multiple_buckets_test.go
# The ‘git add' command adds the file in the local repository and 
# stages the file for commit. To unstage a file, use git reset HEAD YOUR-FILE
  1. 이제 파일이 스테이징되었으므로 변경사항을 커밋합니다.
$ git commit -m "First CFT commit"
# This will commit the staged changes and prepares them to be pushed 
# to a remote repository. To remove this commit and modify the file, 
# use 'git reset --soft HEAD~1' and commit and add the file again.
  1. 커밋된 변경사항을 로컬 저장소에서 GitHub로 푸시하여 가져오기 요청 (PR)을 만듭니다.
$ git push -u origin feature/silly_label
# Pushes the changes in your local repository up to the remote
# repository you specified as the origin

이제 코드 변경사항을 풀 요청할 준비가 되었습니다.

다음 단계에 따라 terraform-google-modules/terraform-google-cloud-storage 저장소에 PR을 만드세요.

  1. 웹브라우저에서 repo의 기본 페이지로 이동합니다.
  2. 포크에서 PR을 열라는 배너를 통해 제안이 표시됩니다. '비교 및 pull 요청'을 클릭합니다.

60e7ae0cbc11588e.png

  1. 코드 변경사항을 설명하는 pull 요청의 제목과 설명을 입력합니다. 간결하면서도 최대한 구체적으로 설명하세요.

f4302385e9e1776a.png

  1. 검토 준비가 완료된 pull 요청을 만들려면 'pull 요청 만들기'를 클릭합니다.
  2. PR로 인해 트리거된 Cloud Build 트리거가 실행됩니다.
  3. 문제가 발생하면 포크에서 풀 요청 열기에 관한 공식 GitHub 문서를 참고하세요.

포크된 브랜치에 첫 번째 코드 변경사항을 푸시하고 마스터 브랜치에 대해 첫 번째 CFT PR을 제출했습니다.

12. 축하합니다

축하합니다. CFT 모듈에 기능을 추가하고 검토를 위해 PR을 제출했습니다.

CFT 모듈에 기능을 추가하고, 예를 통해 로컬에서 테스트하고, GitHub에 코드를 커밋하기 전에 테스트를 실행했습니다. 마지막으로 검토를 위해 PR을 제출하고 CFT에 최종 병합했습니다.

이제 Cloud Foundation Toolkit을 시작하는 데 필요한 중요한 단계를 알게 되었습니다.