1. 개요
이 실습에서는 코드형 인프라 도구인 Pulumi를 사용하여 Google Cloud 리소스를 프로비저닝하고 관리하는 방법을 알아봅니다.
학습할 내용
이 실습에서는 다음 작업을 진행하는 방법을 학습합니다.
- Pulumi 설치 및 구성
- Google Cloud에서 인프라를 모델링하는 YAML 프로그램 작성
- Pulumi를 사용한 Cloud 리소스 프로비저닝 및 관리
- pulumiconvert를 사용하여 YAML 프로그램을 Python 프로그램으로 변환합니다.
2. 설정 및 요구사항
자습형 환경 설정
- Google Cloud Console에 로그인하여 새 프로젝트를 만들거나 기존 프로젝트를 재사용합니다. 아직 Gmail이나 Google Workspace 계정이 없는 경우 계정을 만들어야 합니다.



- 프로젝트 이름은 이 프로젝트 참가자의 표시 이름입니다. 이는 Google API에서 사용하지 않는 문자열이며 언제든지 업데이트할 수 있습니다.
- 프로젝트 ID는 모든 Google Cloud 프로젝트에서 고유하며, 변경할 수 없습니다(설정된 후에는 변경할 수 없음). Cloud 콘솔이 고유한 문자열을 자동으로 생성합니다. 보통은 그게 뭔지 상관하지 않습니다. 대부분의 Codelab에서는 프로젝트 ID (일반적으로
PROJECT_ID로 식별됨)를 참조해야 합니다. 생성된 ID가 마음에 들지 않으면 무작위로 다른 ID를 생성할 수 있습니다. 또는 직접 시도해 보고 사용 가능한지 확인할 수도 있습니다. 이 단계 이후에는 변경할 수 없으며 프로젝트 기간 동안 유지됩니다. - 참고로 세 번째 값은 일부 API에서 사용하는 프로젝트 번호입니다. 이 세 가지 값에 대한 자세한 내용은 문서를 참고하세요.
- 다음으로 Cloud 리소스/API를 사용하려면 Cloud 콘솔에서 결제를 사용 설정해야 합니다. 이 Codelab 실행에는 많은 비용이 들지 않습니다. 이 튜토리얼이 끝난 후에 요금이 청구되지 않도록 리소스를 종료하려면 만든 리소스를 삭제하거나 전체 프로젝트를 삭제하면 됩니다. Google Cloud 새 사용자에게는 미화 $300 상당의 무료 체험판 프로그램에 참여할 수 있는 자격이 부여됩니다.
3. 인프라 설정
Pulumi 설치 및 구성
Cloud Shell에서 다음 명령어를 실행하여 Pulumi를 설치합니다.
curl -fsSL https://get.pulumi.com | sh
경로에 Pulumi를 추가하고 Pulumi의 도움말 메시지를 확인하세요
export PATH=${PATH}:~/.pulumi/bin
# view the help message to verify pulumi runs
pulumi -h
다음 명령어를 실행하여 프로젝트 ID를 설정하고 액세스를 승인합니다. 사용자는 이 명령어를 사용하여
export PROJECT_ID=$(gcloud config get-value project)
gcloud auth application-default login
Cloud Shell에서 GCS 버킷을 만들어 백엔드로 사용
gsutil mb gs://pulumi-${PROJECT_ID}
pulumi login gs://pulumi-${PROJECT_ID}
새 프로젝트 만들기
Cloud Shell에서 프로젝트 루트 디렉터리 만들기
mkdir pulumi-lab && cd pulumi-lab
프로젝트 파일 정의(Pulumi의 진입점)
cat <<EOT > Pulumi.yaml
name: pulumi-lab
description: Try Pulumi
runtime: yaml
main: yaml-repo/
EOT
YAML 리소스 정의
yaml 형식으로 클라우드 리소스 정의를 저장할 디렉터리 만들기
mkdir yaml-repo
다음 리소스 정의로 yaml-repo/Pulumi.yaml 파일을 만듭니다.
- 버킷
- IAM 바인딩
- 문자열 'Hello World!'가 있는 텍스트 객체
- 몇 가지 출력은
resources:
# Create a GCP resource (Storage Bucket)
my-bucket:
type: gcp:storage:Bucket
properties:
location: US
website:
mainPageSuffix: index.html
uniformBucketLevelAccess: true
my-bucket-binding:
type: gcp:storage:BucketIAMBinding
properties:
bucket: ${my-bucket.name}
role: "roles/storage.objectViewer"
members: ["allUsers"]
index-object:
type: gcp:storage:BucketObject
properties:
bucket: ${my-bucket}
source:
fn::stringAsset: Hello World!
outputs:
bucketName: ${my-bucket.url}
리소스 배포
스택 초기화 및 구성
export PULUMI_CONFIG_PASSPHRASE=pulumi-lab
pulumi stack init dev
pulumi config set gcp:project $PROJECT_ID
스택 구성을 확인하면 프로젝트 ID가 값으로 포함된 gcp:project 키가 표시됩니다.
pulumi config
이 시점에서 디렉터리 구조는 다음과 같아야 합니다.
├── Pulumi.dev.yaml
├── Pulumi.yaml
└── yaml-repo
└── Pulumi.yaml
스택 배포
pulumi up
이 명령어는 프로그램을 평가하고 수행할 리소스 업데이트를 결정합니다. 먼저, 명령어를 실행할 때 변경되는 사항을 간략히 설명하는 미리보기가 표시됩니다.
(출력)
Previewing update (dev):
Downloading plugin gcp v6.44.0: 45.69 MiB / 45.69 MiB [=============] 100.00% 1s
Type Name Plan
+ pulumi:pulumi:Stack pulumi-lab-dev create
+ ├─ gcp:storage:Bucket my-bucket create
+ ├─ gcp:storage:BucketObject index-object create
+ └─ gcp:storage:BucketIAMBinding my-bucket-binding create
Outputs:
bucketName: output<string>
Resources:
+ 4 to create
Do you want to perform this update? [Use arrows to move, type to filter]
yes
> no
details
예를 선택하면 리소스가 프로비저닝됩니다. 다음과 같이 출력됩니다.
Do you want to perform this update? yes
Updating (dev):
Type Name Status
+ pulumi:pulumi:Stack pulumi-lab-dev created (3s)
+ ├─ gcp:storage:Bucket my-bucket created (1s)
+ ├─ gcp:storage:BucketObject index-object created (0.78s)
+ └─ gcp:storage:BucketIAMBinding my-bucket-binding created (5s)
Outputs:
bucketName: "gs://my-bucket-874aa08"
Resources:
+ 4 created
Duration: 11s
다음 명령어를 실행하면 정의된 출력이 출력됩니다.
pulumi stack output
다음 명령어를 실행하여 변경사항을 확인합니다.
gsutil ls $(pulumi stack output bucketName)
다음과 같이 출력됩니다.
(출력)
gs://my-bucket-11a9046/index-object-77a5d80
4. YAML을 Python으로 변환
위의 예시를 Pulumi Python 프로그램으로 변환해 보겠습니다.
pulumi convert --language python --out ./py-repo
py-repo에서 생성된 코드 검사
cat py-repo/__main__.py
(출력)
import pulumi
import pulumi_gcp as gcp
my_bucket = gcp.storage.Bucket("my-bucket",
location="US",
website=gcp.storage.BucketWebsiteArgs(
main_page_suffix="index.html",
),
uniform_bucket_level_access=True)
my_bucket_binding = gcp.storage.BucketIAMBinding("my-bucket-binding",
bucket=my_bucket.name,
role="roles/storage.objectViewer",
members=["allUsers"])
index_object = gcp.storage.BucketObject("index-object",
bucket=my_bucket.id,
source=pulumi.StringAsset("Hello World!"))
pulumi.export("bucketName", my_bucket.url)
.......
Python 가상 환경 활성화
source py-repo/bin/activate
Python 프로그램을 가리키도록 Pulumi.yaml 프로젝트 파일을 업데이트합니다. 런타임과 기본 항목이 변경된 것을 알 수 있습니다.
cat <<EOT > Pulumi.yaml
name: pulumi-lab
description: Try Pulumi
runtime: python
main: py-repo/
EOT
스택을 재배포하고 yes를 선택합니다.
pulumi up
변경사항이 없으며 출력은 다음과 같이 표시됩니다.
(출력)
Previewing update (dev):
Type Name Plan
pulumi:pulumi:Stack pulumi-lab-dev
Resources:
4 unchanged
Do you want to perform this update? yes
Updating (dev):
Type Name Status
pulumi:pulumi:Stack pulumi-lab-dev
Outputs:
bucketName: "gs://my-bucket-c2b49ad"
Resources:
4 unchanged
Duration: 6s
5. 리소스 삭제
만든 리소스를 삭제합니다.
pulumi destroy
확인 내용은 다음과 같이 표시됩니다.
Previewing update (dev):
Type Name Plan
pulumi:pulumi:Stack pulumi-lab-dev
Resources:
4 unchanged
Do you want to perform this update? [Use arrows to move, type to filter]
yes
> no
details
Do you want to perform this destroy? yes
Destroying (dev):
Type Name Status
- pulumi:pulumi:Stack pulumi-lab-dev deleted
- ├─ gcp:storage:BucketIAMBinding my-bucket-binding deleted (5s)
- ├─ gcp:storage:BucketObject index-object deleted (1s)
- └─ gcp:storage:Bucket my-bucket deleted (0.73s)
Outputs:
- bucketName: "gs://my-bucket-874aa08"
Resources:
- 4 deleted
Duration: 10s
6. 축하합니다.
축하합니다. 실습을 완료하셨습니다.