今天的主題是介紹 Pulumi 的 Backend 與遷移至其他 Backend 的方法。
Pulumi 的 Backend 就是儲存 Pulumi 狀態的地方。從第一篇文章開始,預設都是使用 Pulumi Cloud 做為 Pulumi 的 Backend。
做為 Pulumi 官方主要用來營利的 SaaS 服務,Pulumi Cloud 提供的功能不只管理 State。還有提供可視化、搜尋、洞見 (insight) 等功能。詳細的資訊可以參考 Pulumi Cloud 的產品頁面。
除了 Pulumi Cloud 以外,還支援了檔案系統、物件儲存空間 (AWS S3、Azure Blob Storage、Google Cloud Storage)、任何支援 S3 相容 API 的服務做為 Backend。
回顧Day 03 安裝 Pulumi的文章,安裝完 Pulumi 後,就會使用 pulumi login
指令登入 Pulumi Cloud。其實這也就是指定所有專案的預設 Backend 是使用 Pulumi Cloud。
如果要切換至其他物件儲存空間的話,可以先使用 pulumi logout
登出後,再設定其他 backend。
可以參考 pulumi login
說明中的指令,來設定不同的物件儲存空間做為 backend。
AWS S3:
$ pulumi login s3://my-pulumi-state-bucket
GCP GCS:
$ pulumi login gs://my-pulumi-state-bucket
Azure Blob:
$ pulumi login azblob://my-pulumi-state-bucket
如果要使用本地檔案系統做為 Backend 的話,也可以使用 pulumi login --local
指令。
透過 CLI 設定的 Backend 為所有專案的預設 Backend。如果希望可以在不同專案使用不同 Backend,而免去頻繁 logout
、login
的話,可以透過更改 Pulumi.yaml
這個 Pulumi 專案檔來達成。
在 Pulumi.yaml
中可以設定 backend:
name: aws-vpc-ts
runtime: nodejs
description: A minimal AWS TypeScript Pulumi program
backend:
url: file://./state
在 backend url 中,如果是 local file system 的話,可以用 ./ 代表專案的相對路徑。當然在這也可以使用絕對路徑。另外所設定的路徑必須是一個資料夾,且這個資料夾需要存在。Pulumi 會使用這個資料夾來管理整個專案中不同 Stack 的狀態。
如果使用 pulumi login --local
設定本地檔案系統為 Backend,預設的資料夾會放在使用者的家目錄中。
因此也可以在 Pulumi.yaml
中設定 url: file://~/
了解了 Pulumi 有不同的 Backend 後,接著介紹如何遷移 Backend。例如可以將 State 管理從 Pulumi Cloud 更改為本地檔案系統。
遷移前可能需要先確保 Secret Provider 不是 Pulumi Cloud,需要改為 passphrase,否則可能會在新的 backend 無法解密 secret。
以下範例為:更改 Secret Provider,並執行一次 pulumi up,讓 Pulumi Cloud 中的 state 中的資料改用 passphrase 加密。
$ pulumi stack change-secrets-provider passphrase
$ pulumi up
接著才是遷移 stack 中的 state 至新的 backend,在 Pulumi 中,遷移 Backend 必須每個 Stack 做一次。
步驟如下:
實際操作的方式如下:
透過指令 pulumi stack export
指令將目前 stack 的 state 匯出
$ pulumi stack export > stack-dev-state.json
Note: 雖然 pulumi 支援 export 時,匯出解密的 state,但在 local 的 secrets provider 沒辦法使用 Pulumi Cloud,所以會導致解密失敗。因此前面才會說要先更改 secret provider。
這步驟可以透過 pulumi logout
、pulumi login --local
或是設定 Pulumi.yaml
達成。
我在這邊就透過更改 Pulumi.yaml 來達成:
name: aws-vpc-ts
runtime: nodejs
description: A minimal AWS TypeScript Pulumi program
backend:
url: file://./state
[Day 18] Pulumi 的 State 管理的文章中有提到,Pulumi 資源 URN 的組成,其中 stack name 也是組成的一部分。因此遷移不同 backend 時,要注意 stack name 必須一樣才行。
在 Pulumi Cloud 中,我使用 dev
做為 stack name,因此必須在 local 也建立一個一樣的 stack name:
$ pulumi stack init dev
Enter your passphrase to unlock config/secrets
(set PULUMI_CONFIG_PASSPHRASE or PULUMI_CONFIG_PASSPHRASE_FILE to remember):
Enter your passphrase to unlock config/secrets
Current stack is dev:
Managed by ...
No updates yet; run `pulumi up`
Current stack resources (0):
No resources currently in this stack
Use `pulumi stack select` to change stack; `pulumi stack ls` lists known ones
$ pulumi stack import --file stack-dev-state.json
Enter your passphrase to unlock config/secrets
(set PULUMI_CONFIG_PASSPHRASE or PULUMI_CONFIG_PASSPHRASE_FILE to remember):
Enter your passphrase to unlock config/secrets
Import complete.
看到 Import complete 就代表所有 state 都已經匯入到本地檔案系統了!
Pulumi 會將狀態放到指定 backend 路徑中的 .pulumi 隱藏資料中中,如果在該資料夾中有看到資料,就代表 state 成功遷移了。
tree state/.pulumi
state/.pulumi
├── backups
│ └── aws-vpc-ts
│ └── dev
│ ├── dev.1696433004635544000.json
│ ├── dev.1696433004635544000.json.attrs
│ ├── dev.1696433265234289000.json
│ └── dev.1696433265234289000.json.attrs
├── history
│ └── aws-vpc-ts
│ └── dev
│ ├── dev-1696433004634850000.checkpoint.json
│ ├── dev-1696433004634850000.checkpoint.json.attrs
│ ├── dev-1696433004634850000.history.json
│ ├── dev-1696433004634850000.history.json.attrs
│ ├── dev-1696433265233596000.checkpoint.json
│ ├── dev-1696433265233596000.checkpoint.json.attrs
│ ├── dev-1696433265233596000.history.json
│ └── dev-1696433265233596000.history.json.attrs
├── locks
│ └── organization
│ └── aws-vpc-ts
│ └── dev
├── meta.yaml
├── meta.yaml.attrs
└── stacks
└── aws-vpc-ts
├── dev.json
├── dev.json.attrs
├── dev.json.bak
└── dev.json.bak.attrs
13 directories, 18 files
接著就繼續照著上面的步驟,依序遷移其他的 stack。
這邊有個狀況就是,Pulumi 的設計中,會希望所有的 stack 都使用同一個 backend。如果有什麼特殊需求,希望每個 Stack 都有自己的 backend,這在 Pulumi 預設的設定中是做不到的。但可以透過設定 PULUMI_BACKEND_URL 環境變數來快速的切換不同的 Backend。如果有這個需求或許可以試試看。