1. 概要
このラボでは、Infrastructure as Code ツールである Pulumi を使用して Google Cloud リソースをプロビジョニングして管理する方法について学習します。
学習内容
このラボでは、次の方法について学びます。
- Pulumi をインストールして構成する
- Google Cloud でインフラストラクチャをモデル化する YAML プログラムを作成する
- Pulumi を使用して Cloud リソースをプロビジョニングして管理する
- pulumi 変換を使用して、YAML プログラムを Python プログラムに変換します。
2. 設定と要件
セルフペース型の環境設定
- Google Cloud Console にログインして、プロジェクトを新規作成するか、既存のプロジェクトを再利用します。Gmail アカウントも Google Workspace アカウントもまだお持ちでない場合は、アカウントを作成してください。
- プロジェクト名は、このプロジェクトの参加者に表示される名称です。Google API では使用されない文字列です。この場所はいつでも更新できます。
- プロジェクト ID は、すべての Google Cloud プロジェクトにおいて一意でなければならず、不変です(設定後は変更できません)。Cloud コンソールでは一意の文字列が自動生成されます。通常はそれが何であるかは気にする必要はありません。ほとんどの Codelab では、プロジェクト ID を参照する必要があります(通常は
PROJECT_ID
として識別されます)。生成された ID が気に入らない場合は、別のランダムな ID を生成できます。または、ご自身で試して、利用可能かどうかを確認することもできます。このステップ以降は変更できず、プロジェクトを通して同じ ID になります。 - なお、3 つ目の値として、一部の API が使用するプロジェクト番号があります。これら 3 つの値について詳しくは、こちらのドキュメントをご覧ください。
- 次に、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. 完了
お疲れさまでした。ラボはこれで完了です。