iT邦幫忙

2023 iThome 鐵人賽

DAY 11
0

為何需要 Stack Config?

在 Pulumi 中,可以透過 Stack 部署同一個 Project 多次,但總不能每個 Stack 都用同樣的 VPC CIDR。所以必須有個方式可以設定不同 Stack 的參數。在 Pulumi 中,可以透過 Stack Config 達成這個目的。Pulumi 的做法是將設定檔放在 Stack config 中,並在程式內存取這些設定。

回頭來看 Pulumi.dev.yaml 檔案,在一開始建立 Project 的時候有設定的 aws region 就會被當作一個 config 放在 Stack config 檔案中。

config:
  aws:region: ap-east-1

Pulumi 的 config 格式長這樣:<namespace>:<name>namespace 預設為 project 的名稱 (Pulumi.yaml 內的 name),也可以自定其他名稱。

讀取 config

首先,先來修改 Pulumi.dev.yaml 檔案,在裡面加上 VPC CIDR。

config:
  aws:region: ap-east-1
  cidr: '10.120.0.0/16'

這邊的 cidr 前方沒有給定 namespace,預設就會被放在 <project name> 這個 namespace 中。

接著在 index.ts 中,使用 pulumi.Config 類別來讀取 config。

const config = new pulumi.Config();

Config 中提供了很多方式可以讀取 Stack config 中的方法。

  • get
  • getBoolean
  • getNumber
  • getObject

get 方法取得的 config 為 string,其他 method 則會將 config 轉換為相對應的型別。如果轉換失敗則會丟出錯誤。

get 相關的讀取方法皆不保證該 config 存在,所以有可能讀取到空值,需要特別處理。

通常會使用 get 讀取選用的 config,如果使用者沒有設定就會給予預設值。

例如:

const vpcCidr: string = config.get('cidr') || '172.16.0.0/16';

假設想要確保該 config 有設定,使用者必須要在 Stack 檔案中指定的話,可以使用 require 相關的方法。

  • require
  • requireBoolean
  • requireNumber
  • requireObject

這些 require 相關的方法與 get 方法相對應,唯一的差別就在可以確保讀到資料。

const vpcCidr: string = config.require('cidr');

如果 config 未被設定,執行 pulumi up 時,會得到以下錯誤:

Missing required configuration variable 'aws-vpc-ts:cidr'
    	please set a value using the command `pulumi config set aws-vpc-ts:cidr <value>`

讀取其他 namespace 的 config

要讀取其他 namespace 的資料,可以在 Config 的建構子中傳入 namespace 的名字。如果沒有傳任何的 namespace 預設就會使用 project name。

以下範例為讀取 aws:region 設定的內容:

const awsConfig = new pulumi.Config('aws')
const region = awsConfig.get('region')

使用 CLI 操作 config

設定 config

除了直接更改 config 以外,也可以透過 CLI 設定 config。

設定的指令為:

pulumi config set <key> [value]

例如前面的範例中,設定 cidr 就可以透過 pulumi config set cidr 10.120.0.0/16 設定 config。

設定完後,可以在 Pulumi.dev.yaml 檔案中看到 cidr 的設定。

config:
  aws-vpc-ts:cidr: 10.120.0.0/16
  aws:region: ap-east-1

由於 Pulumi Stack Config 是使用 YAML 儲存,因此 config 也可以是 Sequence 或是 Map (對應到 TypeScript 就是 Array 與 Object)。如果要設定 Sequence 或是 Map 就得透過 pulumi config set --path <config path> [value] 指令來設定了。

以下範例為設定 publicSubnetCidrs 序列中的資料:

$ pulumi config set --path "publicSubnetCidrs[0]" 10.120.0.0/24
$ pulumi config set --path "publicSubnetCidrs[1]" 10.120.1.0/24

Pulumi.dev.yaml 中的呈現方式:

config:
  aws-vpc-ts:publicSubnetCidrs:
    - 10.120.1.0/24
    - 10.120.1.0/24

使用 CLI 設定 Sequence 或是 Map 相對比較麻煩,建議直接修改 stack 檔案。

取得 config

Pulumi CLI 除了可以設定 Stack config 以外,也能讀取 config。

透過 pulumi config 指令即可列出所有的 config 資料。

$ pulumi config
KEY         VALUE
aws:region  ap-east-1
cidr        10.120.0.0/16

如果要讀取特定的 config,可以透過 pulumi config get <name> 取得特定的 config。

$ pulumi config get cidr
10.120.0.0/16

讀取 config 的時候,也能指定 namespace。

$ pulumi config get aws:region
ap-east-1

範例

最後提供一個比較複雜的範例,這個範例是透過 config 建立一個 VPC 與兩個 Subnet。

$ pulumi config set vpcCidr 172.30.0.0/16
$ pulumi config set --path "subnet[0].az" ap-east-1a
$ pulumi config set --path "subnet[0].cidr" 172.30.0.0/24
$ pulumi config set --path "subnet[1].az" ap-east-1b
$ pulumi config set --path "subnet[1].cidr" 172.30.1.0/24

執行完上述指令後,stack 檔案中會出現 vpcCidr 與 sbunet 的相關設定。

config:
  aws-vpc-ts:subnet:
    - az: ap-east-1a
      cidr: 172.30.0.0/24
    - az: ap-east-1b
      cidr: 172.30.1.0/24
  aws-vpc-ts:vpcCidr: 172.30.0.0/16
  aws:region: ap-east-1

接著就可以使用程式碼來讀取相關的設定了,這邊將 subnet 有關的設定定義一個 Interface,並使用 requireObject 讀取這些設定。

interface SubnetArgs {
  az: string
  cidr: string
}

const config = new pulumi.Config();
const vpcCidr = config.require("vpcCidr")
const subnet = config.requireObject<SubnetArgs[]>("subnet");

讀取完 config 後,就可以來建立資源了:

// 建立 VPC
const vpc = new aws.ec2.Vpc("my-vpc", {
  cidrBlock: vpcCidr,
});


const mySubnet: aws.ec2.Subnet[] = [];
// 建立 subnet
for (let subnet of subnets) {
  mySubnet.push(
    new aws.ec2.Subnet(`my-subnet-${subnet.az}`, {
      vpcId: vpc.id,
      cidrBlock: subnet.cidr,
      availabilityZone: subnet.az,
    })
  );
}

以上的範例會建立 1 個 VPC,2 個 subnet。如果要建立更多的 subnet,可以直接修改 stack config 中 subnet 的數量,這樣就可以讓程式可以更彈性的新增資源。

Reference


上一篇
[Day 10] Stack Output
下一篇
[Day 12] Pulumi 的 Secret 管理
系列文
30 天學習 Pulumi:用各種程式語言控制雲端資源30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言