使用 Pulumi 自建状态后端:存储、身份、锁与恢复责任

作者:Pulumi 文档团队。本文依据 Using a DIY Backend 全文翻译整理,核对日期为 2026-10-05。上游文档会持续更新,CLI 版本门槛以各节说明为准。本稿仅静态核对配置与命令,未登录后端,也未执行基础设施变更。

DIY(Do It Yourself)后端把 Pulumi 状态保存在本地文件系统或自行管理的远端存储中。它提供默认启用的基础文件锁和历史记录,但团队仍需自行安排备份、共享、访问控制及协作恢复。Pulumi Cloud 则由服务处理这些运维工作,并通过事务 API 提供比普通对象存储协议更强的保障。选择自建后端,意味着同时接下状态数据的运维责任。

Pulumi CLI 通过云厂商身份访问自建状态存储;.pulumi 中分别保存后端元数据、活动状态、操作锁和历史,备份及访问控制由团队管理。
未完纪原创示意图,展示状态目录与责任边界,非 Pulumi 界面截图。

先认识 .pulumi 里的四类数据

pulumi login <backend-url> 选择后端。对象存储和文件系统端点分别使用 s3://、azblob://、gs://、file://。检查点保存在端点下相对的 .pulumi 目录。例如 S3 桶为 my-pulumi-state-bucket,则检查点位于 s3://my-pulumi-state-bucket/.pulumi。

路径 用途
meta.yaml 后端自身的元数据,不是某个 stack 的资源状态。
stacks/ 各 stack 的当前活动状态,例如 dev.json;项目作用域下则可能是 proj/dev.json。
locks/ 操作进行中的锁,例如 dev/$lock.json 或 proj/dev/$lock.json,其中 $lock 是唯一标识符。
history/ stack 历史,例如 dev/dev-$timestamp.history.json,项目作用域版本在前面加项目目录;时间戳记录历史文件创建时间。

锁的存在不等于已经完成异地备份,也不代替团队访问隔离。不要因为遇到锁或元数据报错就直接删文件。状态文件可能包含敏感基础设施信息,读写、删除和备份恢复权限应当按最小范围分配。

本地文件系统

使用本地后端的最短命令是:

pulumi login --local

这等价于 pulumi login file://~,状态 JSON 默认保存在 ~/.pulumi。若要保存到 /app/data/.pulumi/,端点应给它的上一级目录:

pulumi login file:///app/data

file://./einstein 这样的相对路径以当前工作目录为基准。因此在 CI 或不同终端中运行时,先确认工作目录;同样的文本未必指向同一个实际后端。登录成功的信息只说明后端选择完成,不能当作状态备份或恢复验证。

AWS S3:端点、身份与最小权限

pulumi login 's3://<bucket-name>'
pulumi login 's3://<bucket-name>?region=us-east-1&awssdk=v2&profile=<profile-name>'

第二种查询参数写法自 CLI v3.33.1 起可用,按官方示例同时带上 awssdk=v2、区域和 profile。整个 URL 必须加引号,避免 shell 把 & 当作操作符。桶名之后也可带多级前缀,如 s3://my-bucket/app/project1,便于在同一桶里划分项目。

凭据配置遵循 AWS SDK 的会话与身份机制,参见 AWS Session 文档。后端访问与程序里部署 AWS 资源使用的 provider 配置是两个需要分别核对的层面。

官方给出的 S3 后端权限覆盖 stack 创建、预览、更新、刷新、销毁与移除等完整生命周期,只需要以下四种 S3 动作:列举桶、读取对象、写入对象、删除对象。删除权限也用于释放锁,不能因为“只是存状态”就完全省略它。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PulumiStateBackendList",
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::<bucket-name>"
    },
    {
      "Sid": "PulumiStateBackendObjects",
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
      "Resource": "arn:aws:s3:::<bucket-name>/*"
    }
  ]
}

ListBucket 是桶级动作,Resource 必须是桶 ARN;另三种动作则作用于对象 ARN。若后端位于 app/project1 前缀下,可以把对象 Resource 缩小到 arn:aws:s3:::<bucket-name>/app/project1/*。上面的完整桶对象范围来自原文,不能把它称作共享桶中每个团队的最终最小边界。

同样四种动作也可写进桶策略,但需要增加适当的 Principal。MinIO、Ceph 等兼容 S3 服务需要等价的读、写、列举、删除权限。这里的“四种”限定为该后端的 S3 API 动作;如果存储另外启用 KMS、跨账户策略或网络访问限制,仍需满足相应额外条件,不能把这段策略当作所有部署的完整授权。

S3 兼容端点:不要直接复制明文连接示例

官方还介绍 MinIO、Ceph 和 SeaweedFS 等 S3 兼容服务,可用 endpoint、disableSSL、s3ForcePathStyle 查询参数控制连接。原文的本地 MinIO 示例显式设置 disableSSL=true,会停用 TLS,不能直接挪到远程或生产网络。

下面是本文的安全修订示例:采用已配置有效 TLS 证书的端点,移除关闭 TLS 的参数。端口和证书必须以实际服务配置为准;这是配置思路,尚未连接验证。

pulumi login 's3://<bucket-name>?endpoint=minio.example.com:443&s3ForcePathStyle=true'

如服务确实要求明文连接,应明确限制为隔离测试网络,而不是通过关闭校验来掩盖证书或主机名错误。不要把后端凭据写进文档、聊天记录或版本库。

Azure Blob Storage

pulumi login 'azblob://<container-path>'

AZURE_STORAGE_ACCOUNT 指定存储账户。身份验证可以使用 AZURE_STORAGE_KEY(账户访问密钥)或 AZURE_STORAGE_SAS_TOKEN(SAS 令牌)。两者都没有提供时,后端使用 Azure SDK for Go 的 DefaultAzureCredential,按该 SDK 的凭据链尝试托管身份、工作负载身份联合、服务主体凭据和 Azure CLI 等方式。

这个后端使用的是 Azure SDK for Go 的认证机制,不是 Pulumi Azure provider 的认证机制。因此 ARM_TENANT_ID、ARM_CLIENT_ID、ARM_USE_OIDC 不能替代它需要的变量;服务主体方式应使用 AZURE_TENANT_ID、AZURE_CLIENT_ID、AZURE_CLIENT_SECRET。

自 CLI v3.41.1 起,在完成 az login 后,也可把存储账户写进端点:

pulumi login 'azblob://<container-path>?storage_account=account_name'

身份应具有 Storage Blob Data Contributor 或等价的 blob 读、写、删除权限。环境变量是输入机制,不自动保证秘密安全;在 CI 中应由受控秘密存储或工作负载身份注入,避免输出到日志。

Google Cloud Storage 与 PostgreSQL

GCS 后端使用 gs:// 端点:

pulumi login 'gs://<my-pulumi-state-bucket>'

认证按 Application Default Credentials 配置。

当前官方页也列出了 PostgreSQL 后端,连接地址形如 postgres://<username>:<password>@<hostname>:<port>/<database>。这是格式说明,不应把真实密码直接填到 shell 命令中:它可能进入历史、日志或进程参数。官方也明确建议使用环境变量或其他安全凭据管理方式;具体可用参数以该页指向的 PostgreSQL 后端 README 为准。本文不编造一个未经该实现确认的免密码连接命令。

项目作用域与不可逆升级

CLI v3.61.0 之前,DIY 后端的 stack 位于全局命名空间,同一后端中不同项目不能各自拥有同名的 dev、prod 或 staging。v3.61.0 及以后,新建或空的 DIY 后端默认按项目划分 stack,行为与 Pulumi Cloud 一致。

已有后端仍保留旧的全局命名方式。官方提供 pulumi state upgrade 将后端中的所有 stack 升级为项目作用域,但这是单向操作:升级后的 stack 不能再由旧版 CLI 访问,也不能降回原格式。升级前应保存后端备份,并统一团队及 CI 的 CLI 版本;不要把它放进每次启动都执行的脚本。本文没有执行这项升级。

看到 meta.yaml 报错时,先检查连接条件

执行 pulumi login、pulumi config 等需要读取状态的命令时,可能遇到读取 .pulumi/meta.yaml 失败,并伴随 AccessDenied、HTTP 403,或 MissingRegion。meta.yaml 是 CLI 访问 DIY 后端时首先读取的文件,所以这种错误通常意味着已到达存储服务,但认证、授权或配置有问题,不意味着文件本身丢失或损坏。

  1. 检查凭据是否过期或无效,例如 AWS SSO、STS AssumeRole 或短期 Azure 凭据;刷新后重试。
  2. 检查当前身份是否有后端需要的权限。能完成身份认证,不等于能读写状态、创建锁和删除锁。
  3. 检查 S3 区域。可在带引号的后端 URL 中提供 region=us-east-1,或设置 AWS_REGION。
  4. 检查后端 SDK 所需环境变量,不要误用资源 provider 的同名近似配置。
  5. 必要时启用 CLI 详细日志诊断,但分享日志前应移除秘密、临时令牌及敏感基础设施信息。

来源与编辑说明

来源:Pulumi 官方文档:Using a DIY Backend,作者为 Pulumi 文档团队。上游 docs 仓库采用 Apache License 2.0;© 2026 Pulumi Corp. 完整许可证附于本文末尾。本文是经过中文翻译、重组及安全注释的修改版本,主要差异是移除 MinIO 示例中的关闭 TLS 参数、避免可复制的含密码命令,并解释共享桶权限和升级边界。中文翻译及编辑标注:未完纪,2026-10-05。

本次只完成静态审查,没有执行登录、权限测试、状态升级、资源预览或部署;没有发现额外问题不代表没有漏洞。后端的实际恢复能力仍须通过团队自己的备份与恢复演练确认。

原文的两类完整报错示例如下,便于对照日志;它们不是本文连接后端的结果。

error: read ".pulumi\\meta.yaml": blob (key ".pulumi/meta.yaml") (code=Unknown): AccessDenied: Access Denied
        status code: 403
error: read ".pulumi\\meta.yaml": blob (key ".pulumi/meta.yaml") (code=Unknown): MissingRegion: could not find region configuration

版权与许可全文

以下保留本页涉及的来源材料或示例代码的版权、许可条件与免责声明;各自适用范围依原声明。中文翻译及编辑标注:未完纪,2026-10-05。

LICENSE-UPSTREAM.txt

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容