上一篇文章介紹了如何參考其他 Pulumi 的 Stack 中的狀態,今天來介紹一個比較進階的技巧——參考其他 IaC 工具的狀態。主要先介紹如何參考 Terraform 的 State,後面會再說明其他的 IaC 工具。
要參考 Terraform 的 State,就必須先安裝 @pulumi/terraform
,這個專案是專門讓 Pulumi 可以參考 Terraform State 用的。
Note: 如果是使用 Python 的話,則是安裝
pulumi-terraform
昨天介紹 Pulumi 參考其他 Stack 的 Output 有提到,所有專案的 Backend 都必須要使用相同的 Backend。那在參考 Terraform 的時候有沒有這個限制呢?
答案是沒有!
pulumi terraform 模組非常的彈性,可以支援多種 State 儲存的地方,如下列表
詳細的列表,與每個 Backend 的使用方式,可參考專案中的 Config 定義:https://github.com/pulumi/pulumi-terraform/tree/master/sdk/nodejs/state
參考 Terraform State 的方式與參考其他 Pulumi 資源的方式很像,都是建立一個 Resource 來代表要參考的對象。
例如以下程式碼,即是使用 local state 的方式參考另一個資料夾中的 tfstate 檔案。
const terraformStack = new terraform.state.RemoteStateReference("terraform-state", {
backendType: "local",
path: path.join(__dirname, "../terraform-vpc/terraform.tfstate"),
});
Terraform 的 RemoteStateReference 只有提供 getOutput
方法供我們取得 State 的資料,回傳的型別為 pulumi.Output
。這可能是比較可惜的地方,沒有提供類似 getOutputValue 的方法。
取得 Terraform State 的 Output 範例:
const vpcId = terraformStack.getOutput('vpcId');
這邊要注意,RemoteStateReference 是參考 Terraform state 的 output,因此必須確定 terraform 中有把想要被參考的值使用 output 輸出。
output "vpc_id" {
value = aws_vpc.project_vpc.id
}
下一個範例,來看如何參考 Terraform Cloud 的 state。這邊使用了 config 與 secret 的方式,將 terraform cloud 的 token 儲存在 secret 中,而其他的值則是使用 config 的方式設定。
可以看到每個不同的 backendType 對應到的參數數量、類型皆不相同,因此使用時還請參考原始碼。抑或是多利用 IDE 的自動補完功能。
const config = new pulumi.Config();
const terraformStack = new terraform.state.RemoteStateReference("terraform-state", {
backendType: "remote",
token: config.requireSecretObject('tfeToken'),
organization: config.require('terraformOrg'),
workspaces: {
name: config.require('terraformWorkspace')
},
});
接著我們順便來看看如何參考 AWS CloudFormation 的 Output。只要可以參考 AWS CloudFormation,那麼也可以用同樣的方式參考 AWS CDK 的 Output (畢竟 AWS CDK 會產生 CloudFormation)。
參考 CloudFormation 的 Output 與查詢 AWS 中的可用區的作法很像,都是呼叫一個 getXXX 的函式,且這個函式回傳的資料通常為 Promise<XXXResult>
。而這個資料中通長都是原始型別 (Primitive data type),沒有經過 Pulumi 的包裝。
使用範例如下:
// 使用 getStack 取得 Stack 的資料
const cloudformationStack = await aws.cloudformation.getStack({
name: "infra_stack",
});
// Stack 中有 outputs 屬性,他是個 Key-Value 的 Object (或者可以說是 Map),可以透過 output 的名稱取得值
const vpcId: string = cloudformationStack.outputs['vpcId'];
當然也是可以參考 Azure 的 ARM Template 的,需要使用到 azure.core.TemplateDeployment.get
的方法,第一個參數為 Resource name (pulumi 識別用),id 則為 Azure 上的 ID。
這個方法與 AWS 的 getXXX 不同,Azure Provider 的做法是類似 Pulumi import 的方式,將已有的資源狀態 import 進來。因此 outputs 的型別與 Terraform RemoteStateReference 一樣是 Output。
const template = azure.core.TemplateDeployment.get('azure_stack', config.require('templateId'));
const vpcId: Output<string> = template.outputs['vpcId'];
參考其他 IaC 工具的 State / Output 是非常實用的功能,當專案中,希望逐步導入 Pulumi 做為 IaC 工具時,就不需要將其他既有的專案重寫。而是只要使用 reference 的方式就可以參考其他 IaC 專案所建立的資源。