Pulumi:用通用编程语言管理基础设施
Pulumi 基础设施即代码:用你熟悉的语言管理云资源
Pulumi 简介
什么是 Pulumi?
Pulumi 是一个现代基础设施即代码(IaC)平台,它允许你使用真正的通用编程语言(TypeScript、Python、Go、C#、Java 等)来定义、部署和管理云基础设施。与依赖领域特定语言(DSL)的工具不同,Pulumi 让你能够使用条件、循环、函数和现有的包管理器来构建动态、可复用的基础设施代码。你不再受限于声明式配置的边界,而是完全融入了软件工程的生态。
为什么选择 Pulumi?
- 真正的编程语言:使用你已掌握的技能(如 TypeScript 或 Python),享受 IDE 的自动补全、重构、测试和包管理。
- 跨云与多云:统一的方式管理 AWS、Azure、Google Cloud、Kubernetes、Cloudflare 甚至本地资源,一份代码可覆盖多个提供商。
- 代码复用与抽象:将常见架构模式封装成函数、类或组件,通过包管理器(npm, PyPI)分享给团队。
- 强类型与错误检查:在部署前就捕获大量配置错误,减少运行时故障。
- 可编程的流程控制:自然地利用
for循环、if语句动态创建资源,无需学习额外的模板语法。 - 状态管理自动化:自动管理资源状态,支持本地文件或云对象存储(如 S3、Azure Blob),便于团队协作。
核心概念:项目、堆栈和资源
- 项目:一个包含 Pulumi 程序的目录,定义了云资源集合。通常包含源代码、依赖项和
Pulumi.yaml配置文件。 - 堆栈:一个项目的独立实例,代表不同的环境(如
dev、staging、prod)。每个堆栈有自己的状态和配置,允许你安全地隔离变更。 - 资源:云基础设施的基本构建块,比如虚拟机、存储桶、数据库或 Kubernetes Pod。在代码中,资源是 Pulumi 提供商模块中的类对象,通过设定属性来定义期望状态。
环境准备
安装 Pulumi CLI
Pulumi 命令行工具是管理基础设施的入口,可通过以下方式安装:
- macOS:
brew install pulumi/tap/pulumi - Windows:下载安装器或使用
choco install pulumi - Linux:
curl -fsSL https://get.pulumi.com | sh
安装完成后,运行 pulumi version 验证成功。
配置目标云平台(以 AWS 为例)
- 确保已安装 AWS CLI,并配置好凭据(
aws configure),或设有环境变量AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY。 - 设置 Pulumi 默认区域(可选):
pulumi config set aws:region us-east-1 - Pulumi 会使用云平台的默认认证链,兼容角色、配置文件等方式。
类似的,若要使用 Azure 或 GCP,需完成相应 CLI 的认证步骤。
选择开发语言与编辑器
虽然 Pulumi 支持多种语言,本教程以 TypeScript 为例。你需要:
- Node.js(LTS 版本)
- npm、yarn 或 pnpm
- 代码编辑器推荐 VS Code,搭配 Pulumi 扩展以获得更好的智能提示。
编写第一个 Pulumi 程序
创建项目
在终端中创建工作目录并初始化新项目:
mkdir pulumi-demo && cd pulumi-demo
pulumi new aws-typescript
交互命令会要求输入项目名称、堆栈名称以及云区域。这会在当前目录生成一系列文件,包括 index.ts(主程序)、Pulumi.yaml 和 Pulumi.dev.yaml。
理解程序结构
打开 index.ts,典型内容如下:
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
// 创建一个 AWS S3 存储桶
const bucket = new aws.s3.Bucket("my-bucket", {
acl: "private",
});
// 导出一个输出
export const bucketName = bucket.id;
import引入 Pulumi 核心库和云提供商资源模块。new aws.s3.Bucket(...)声明了一个 S3 存储桶资源,第一个参数是资源的逻辑名称(仅在 Pulumi 中标识),第二个参数是配置属性对象。export用于将资源的某些属性输出到终端,或供其他堆栈引用。
定义资源(AWS S3 存储桶)
我们来创建一个更完整的存储桶示例,并尝试利用代码循环生成两个桶:
import * as aws from "@pulumi/aws";
// 动态创建多个存储桶
const environments = ["dev", "staging"];
const buckets = environments.map(env => {
return new aws.s3.Bucket(`my-app-${env}-bucket`, {
acl: "private",
tags: {
Environment: env,
ManagedBy: "Pulumi",
},
});
});
export const bucketNames = buckets.map(b => b.id);
使用 map 这种常规编程方式轻松实现重复资源,无需学习新的模板语言。
预览变更(pulumi preview)
在项目目录下运行:
pulumi preview
Pulumi 会分析代码与当前状态,展示将要创建、更新或删除的资源明细。这是部署前的安全检查,确保变更符合预期。
部署基础设施(pulumi up)
确认预览无误后,执行:
pulumi up
Pulumi 再次显示计划摘要,并要求你确认(除非使用 --yes 参数)。确认后,Pulumi 开始与 AWS API 通信,在云端创建真正的基础设施。部署结束时会显示输出变量(如存储桶名称)。
检查部署结果
可以通过 AWS 控制台或 CLI 验证资源是否已创建。也可通过 Pulumi 命令查看:
pulumi stack output
更新与删除
更新资源属性
直接修改代码,例如将存储桶的 acl 从 "private" 改为 "public-read",然后重新执行 pulumi up。Pulumi 会计算最小增量,仅更新需要变化的属性,无需重建整个资源。
销毁基础设施(pulumi destroy)
当不再需要这些资源时,运行:
pulumi destroy
该命令会删除当前堆栈中管理的所有资源,同样提供预览和确认步骤。销毁后,资源及其关联数据(如存储桶中的内容)将永久移除。
状态管理与团队协作
Pulumi 状态后端
默认情况下,Pulumi 状态存储在本地文件系统,不适用于多人协作。推荐使用 Pulumi Cloud(免费层级可用)或自托管后端(如 S3)。要启用云后端:
pulumi login https://api.pulumi.com
登录后,状态会被自动加密并安全保存,支持状态锁定和审计。
使用堆栈隔离环境
通过创建多个堆栈来管理开发、测试和生产环境:
pulumi stack init staging
切换堆栈:pulumi stack select staging,每个堆栈拥有独立的配置文件和状态。可以定义不同区域的配置、实例大小等,通过 pulumi config set 存储差异化设置。
进阶特性概览
组件与抽象
Pulumi 允许你创建自定义组件资源,将多个云资源组合成一个可复用的架构单元。例如,一个“Web 服务”组件可能包含 EC2 实例、安全组和负载均衡器。定义类后,其他团队成员只需 new MyWebService(...) 即可实例化。
动态提供商与跨语言集成
如果官方提供商未覆盖某些 API,你可以编写动态提供商来扩展 Pulumi。此外,多语言支持(TypeScript、Python 等)意味着微服务团队可以各自用擅长的语言管理各自的基础设施,并共享输出值。
总结
Pulumi 将基础设施管理带入了真正软件工程的时代。你不再需要用局限的 DSL 描述静态配置,而是可以用通用语言书写可测试、可抽象的代码,直接统治云资源。从第一个 S3 存储桶到复杂的企业级多云架构,Pulumi 都提供了统一且高效的 IaC 体验。下一步,建议探索官方文档的更多提供者资源、实践自动化 CI/CD 集成以及学习编写自定义组件。