不能直接 go run main.go,因为pulumi go程序是被cli驱动的插件式程序,需通过pulumi up启动runtime、加载模块并接管执行流程;go run仅编译运行,无法提供program context或触发iac流程。

可以直接用 Go 写 Pulumi 程序,但必须注意:Pulumi 的 Go SDK 不是纯本地库,它依赖 pulumi-cli 运行时和远程 state backend,不能像普通 Go 包一样直接 go run 启动。
为什么不能直接 go run main.go?
Pulumi 的 Go 程序不是独立可执行的二进制,而是一个“被 pulumi CLI 驱动的插件式程序”。它通过 gRPC 与 pulumi-cli 通信,由 CLI 负责资源规划、状态比对、provider 调用和 state 同步。你写的 main.go 只是提供期望状态的“输入描述”,真正的执行引擎在 CLI 进程里。
- 直接
go run main.go会报错:panic: no program context available或failed to initialize provider -
pulumi up才是唯一合法入口,它会启动 runtime、加载你的 Go 模块、调用main()并接管后续流程 - Go SDK 的版本必须与当前
pulumiCLI 版本严格匹配(例如 CLI v3.122.0 要求github.com/pulumi/pulumi/sdk/v3对应 commit),否则常见rpc error: code = Unimplemented desc = ...
初始化一个 Pulumi Go 项目要做什么?
别跳过 pulumi new,它不只是建目录,还负责生成正确的 go.mod、Pulumi.yaml 和 runtime hook。
- 运行
pulumi new go --name my-infra --stack prod,它会自动:- 创建
go.mod并 requiregithub.com/pulumi/pulumi/sdk/v3和对应云 provider(如github.com/pulumi/pulumi-digitalocean/sdk/v4) - 生成
Pulumi.yaml,其中runtime: {name: go}是关键,告诉 CLI 用 Go 插件加载器 - 写好基础
main.go框架,含pulumi.Run入口和ctx.Export示例
- 创建
- 手动新建项目容易漏掉
runtime声明或版本约束,导致pulumi preview直接失败 - 若已有 Go module,不要直接
go mod init后就pulumi login—— 必须先用pulumi new初始化,再把原有代码迁入main.go
如何在微服务项目里共用一套配置结构?
微服务的 config.yaml 和 Pulumi 的 stack 配置可以复用字段,但加载方式完全不同:Viper 解析文件,Pulumi 用 pulumi.Config 读取 stack 配置。
- 不要试图在
main.go里调用viper.Unmarshal—— Pulumi 运行时没有 Viper 上下文,且 config 文件路径不可靠 - 统一配置项应通过
pulumi.Config获取,例如:cfg := pulumi.NewConfig("myapp"); region := cfg.Require("region") - Stack 配置通过
pulumi config set --secret dbPassword 'xxx'注入,敏感值自动加密;非敏感值如nodeSize可明文存于Pulumi.prod.yaml - 若微服务和 infra 共享同一套环境变量(如
ENV=prod),建议用相同前缀命名 stack(myapp-prod)并用 CI 自动pulumi stack select
CI/CD 中触发 pulumi up 容易忽略什么?
Cloud Build 或 GitHub Actions 里跑 pulumi up --yes 很快,但失败常因权限或 state 锁导致,而非代码逻辑错误。
-
pulumi login必须指向托管 backend(如pulumi.com或自建 S3),不能用--local—— 否则多并发构建会覆盖彼此 state - 务必在 job 开头加
pulumi stack select myapp-prod,避免默认使用devstack 导致误操作 - 添加
--expect-no-changes到 staging 环境的 CI 步骤,防止意外变更;生产环境用--diff+ 人工确认 - Provider 认证凭据(如
DIGITALOCEAN_TOKEN)必须作为 secret 注入,不能硬编码或写进.env—— Pulumi CLI 不读取 .env 文件
最常被跳过的环节是 stack 名称与微服务部署环境的绑定关系:infra 的 prod stack 必须对应服务的 prod deployment namespace,否则 Export 出来的 kubeconfig 或 endpoint 会被下游服务误用。这个映射不在代码里,而在 CI pipeline 的参数传递链中,一环断就全错。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











