通过 YAML 在 Google Cloud 上使用 Pulumi

1. 概览

本实验将教您如何使用 Pulumi,这是一种基础架构即代码工具,用于预配和管理 Google Cloud 资源。

学习内容

在本实验中,您将学习如何完成以下操作:

  • 安装并配置 Pulumi
  • 编写 YAML 程序,在 Google Cloud 上为您的基础架构建模
  • 使用 Pulumi 预配和管理 Cloud 资源
  • 使用 pulumi transform 程序将 YAML 程序转换为 Python 程序

2. 设置和要求

自定进度的环境设置

  1. 登录 Google Cloud 控制台,然后创建一个新项目或重复使用现有项目。如果您还没有 Gmail 或 Google Workspace 账号,则必须创建一个

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • 项目名称是此项目参与者的显示名称。它是 Google API 尚未使用的字符串。您可以随时对其进行更新。
  • 项目 ID 在所有 Google Cloud 项目中是唯一的,并且是不可变的(一经设置便无法更改)。Cloud 控制台会自动生成一个唯一字符串;通常您不在乎这是什么在大多数 Codelab 中,您都需要引用项目 ID(它通常标识为 PROJECT_ID)。如果您不喜欢生成的 ID,可以再随机生成一个 ID。或者,您也可以尝试自己的项目 ID,看看是否可用。完成此步骤后便无法更改该 ID,并且该 ID 在项目期间会一直保留。
  • 此外,还有第三个值,即某些 API 使用的项目编号,供您参考。如需详细了解所有这三个值,请参阅文档
  1. 接下来,您需要在 Cloud 控制台中启用结算功能,以便使用 Cloud 资源/API。运行此 Codelab 应该不会产生太多的费用(如果有费用的话)。如需关停资源,以免产生超出本教程范围的结算费用,您可以删除自己创建的资源或删除整个项目。Google Cloud 的新用户符合参与 $300 USD 免费试用计划的条件。

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

  1. 存储桶
  2. IAM 绑定
  3. 一个包含字符串“Hello World!”的文本对象
  4. 一些输出
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

检查堆栈配置,您应该会看到键 gcp:project,其中包含您的项目 ID 作为值

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

更新 Pulumi.yaml 项目文件以指向 Python 程序。请注意,运行时和主条目已更改

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. 恭喜!

恭喜,您已完成本实验!