1. 개요
이 실습에서는 코드형 인프라 도구인 Pulumi를 사용하여 Google Cloud 리소스를 프로비저닝하고 관리하는 방법을 알아봅니다.
학습할 내용
이 실습에서는 다음 작업을 진행하는 방법을 학습합니다.
- Pulumi 설치 및 구성하기
- Google Cloud에서 인프라를 모델링하는 YAML 프로그램 작성
- Pulumi를 사용한 Cloud 리소스 프로비저닝 및 관리
- pulumi convert를 사용하여 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
스택을 다시 배포하고 예를 선택합니다.
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. 축하합니다.
축하합니다. 실습을 완료했습니다.