PulumiとはIaCツールである。
競合としてTerraformとかCDK Terraformがある。PulumiはSDKを持つ好きなプログラミング言語で好きなプロバイダのリソースを記述できる面白いアーキテクチャになっていて、例えばKubernetesやCloudflare、AWSなどのリソースを、ScalaとかNodeとかTypeScriptで記述できる。
PulumiでScalaを利用するためのSDKがBesomであり、これはVirtusLabによって開発されている。
BesomはKubernetesなどのプロバイダのインターフェイスもScalaにポートしてくれているので、Scalaを利用してKubernetes環境を立ち上げたり、設定したりできる。
例えば筆者が自宅で動かしているDockerイメージビューワのBesomコードは以下のリポジトリに置いてある:
シークレットの情報がプッシュされているが、これらはPulumiによって暗号化された値なのでexposeしてもかまわない。
Besomの話はいったんここまで。
Pulumiはリソース名に自動的にランダムなIDを割り振る(ことがある)
いきなりだが本題に入る。PulumiでKubernatesのNamespaceを切るには以下のように記述する。
import besom.* import besom.api.kubernetes.core.v1.Namespace import besom.api.kubernetes.core.v1.NamespaceArgs @main def main = Pulumi.run { val ns = Namespace( "foobar", NamespaceArgs(), ) Stack.exports( namespace = ns, ) }
これでpulumi up
を実行するとNamespaceが作成されるのだが、指定した名前通りにリソースを作ってくれない。foobar-0ab1f45e
みたいに、指定した名前-ランダムな英数
という名前でリソースが切られてしまう。これはリソースの衝突とかダウンタイムの発生を防ぐためにPulumiがお節介を焼いてくれているためだ。
ここで、我々が最初のパラメータに渡す名前は論理名と呼ばれ、実際に作られるリソースの名前は物理名と呼ばれる。
しかし、サービスディスカバリをするとなるとこれが問題となる。ServiceはService名.Namespace名.svc.cluster.local
といったDNS名で到達できるからだ。毎回NamespaceやServiceの名前が代わったら到達できないし、その都度関連するリソースを作り直していたら日が暮れてしまう。
このへんの都合はPulumiのドキュメントにちょっと書いてある。
pulumi.com/autonamed: Indicates that the Pulumi Kubernetes provider decided to autoname the resource (instead of using an explicitly provided metadata.name).
ちなみに既存のリソースはimportできる。
リソース名を固定する
リソース名を固定するには、明示的にArgsとして名前を渡す。
@main def main = Pulumi.run { val ns = Namespace( "foobar", // ここは論理名 NamespaceArgs(metadata = ObjectMetaArgs(name = "foobar")), // 物理名も渡す ) }
大抵のリソースにはname
のような引数があるので、これを指定するというわけ。
こうすると物理名を固定してリソースを作成できる。