Terraformと言えば様々なベンダー・コミュニティが提供するProviderを利用することで各種インフラを簡単に操作することが出来るが、Tanzu Mission Control(以下TMC)の操作用にTanzu Mission Control Providerが用意されている。
これを試してみる。
何が出来るか
どこまでTerraformで出来るかを書いているドキュメントが見つけられていないが、Resourceの一覧を見るとTerraform経由でTMCの操作のほとんどが出来るようである。
Known Issueを見るとvSphere8でClassBaseでのクラスタ構築には失敗するようであるが、中の人に聞いたら「直ってる」とのことなのでクラスタ構築も出来そうだ。
前提条件
今回の検証をするにあたり、以下は既に用意しているものとする。
- Terraformコマンド
- TKGクラスタがあり、TMCのAgentを導入済み
- VMware Cloud ServicesからAPIトークンを取得済み
- APIトークンの権限はTMC上でAdmin相当
なお、TMCのProviderの前提として、K8sクラスタはTKGのみとなっている点に注意。
APIトークンの取得方法が分からない人はこちらを参照するとよい。
触ってみる
TMCのAutomation center
からTerraform
のタブをクリックするとサンプルが表示されるので、それに従って進める。
最初にProviderの定義を作成する。なお、TMCのAutomation centerで確認できるサンプルでは1.0.3を使っていたが、'23/12/22時点では最新版が1.4.0だったので、バージョンを最新のものに変更している。
cat << EOF > ./provider.tf
terraform {
required_providers {
tanzu-mission-control = {
source = "vmware/tanzu-mission-control"
version = "1.4.0"
}
}
}
provider "tanzu-mission-control" {
endpoint = var.endpoint
vmw_cloud_api_token = var.vmw_cloud_api_token
}
EOF
次に変数の定義を作成し、TMCのエンドポイントとAPIトークンを設定する。
cat << EOF > ./variables.tf
variable "endpoint" {
description = "The Tanzu Mission Control service endpoint hostname"
type = string
default = "xxxx.tmc.cloud.vmware.com"
}
variable "vmw_cloud_api_token" {
description = "The VMware Cloud Services API Token"
type = string
default = "325y0....jC"
}
EOF
この段階でterraform init
は通るようになる。
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Reusing previous version of vmware/tanzu-mission-control from the dependency lock file
- Using previously-installed vmware/tanzu-mission-control v1.4.0
Terraform has been successfully initialized!
:(省略)
サンプルにあるように、ClusterGroupを作ってみる。
ただし、サンプルには以下の問題があるため訂正して作成する。
- シングルクォートで括っているが、シングルクォートはTerraform的に使用不可
-
name
にアンダースコアを使っているが、アンダースコアはTMC的に使用不可
cat << EOF > ./create_cluster_group.tf
resource "tanzu-mission-control_cluster_group" "create_cluster_group" {
name = "imurata-test-cluster-group"
meta {
description = "test_cluster_group_description"
labels = {
"env" : "test",
"using" : "terraform"
}
}
}
EOF
念のためドライランを実施。
terraform plan
特にエラーが出なければ、applyする。
terraform apply
削除も実施してみる。terraform destroy
で削除する。
terraform destroy
Harborをデプロイする
Package InstallResourceを見ると、Tanzu Packageもデプロイ出来そうなので、試しにHarborをデプロイしてみる。
Harborに必要なものと言えば、cert-manager, contourなので、これらも合わせてデプロイする。
が、結論からいうと上手く行かない。
試したコードはこちら。(Contour部分で躓いたため、Harborまでは書いていない)
create-contour.tf
variable "cluster_name" {}
variable "provisioner_name" {}
variable "management_cluster_name" {}
locals {
install-list = {
"cert-manager" = {
name = "cert-manager"
package_metadata_name = "cert-manager.tanzu.vmware.com"
constraints = "1.12.2+vmware.1-tkg.1"
inline_values = { "" : "" }
}
"contour" = {
name = "contour"
package_metadata_name = "contour.tanzu.vmware.com"
constraints = "1.25.2+vmware.1-tkg.1"
inline_values = jsonencode({
{
"certificates": {
"duration": "8760h",
"renewBefore": "360h"
},
"contour": {
"configFileContents": {},
"logLevel": "info",
"pspNames": "vmware-system-restricted",
"replicas": 2,
"useProxyProtocol": false
},
"envoy": {
"hostNetwork": false,
"hostPorts": {
"enable": true,
"http": 80,
"https": 443
},
"logLevel": "info",
"service": {
"annotations": {},
"disableWait": false,
"externalTrafficPolicy": "Cluster",
"type": "LoadBalancer"
},
"terminationGracePeriodSeconds": 300
},
"infrastructure_provider": "vsphere",
"namespace": "tanzu-system-ingress"
}
})
}
}
}
resource "tanzu-mission-control_package_install" "create_package_install" {
for_each = local.install-list
name = each.value.name
namespace = "my-packages"
scope {
cluster {
name = "${var.cluster_name}"
provisioner_name = "${var.provisioner_name}"
management_cluster_name = "${var.management_cluster_name}"
}
}
spec {
package_ref {
package_metadata_name = each.value.package_metadata_name
version_selection {
constraints = each.value.constraints
}
}
inline_values = each.value.inline_values
}
}
同じリソースでcert-manager, contourを作成するため、for_eachで回す形で各種パラメータを設定している。
また、package_metadata_name
やconstraints
はkind: PackageInstall
が中で持っているものと同じ値を指定する。
inline_values
は取り敢えずJSONで渡してみたが上手く行かず、仕様を確認したところ、StringのMapとなっているようで、{"<文字列>": "<文字列>"}
のみ受け付けている模様。
これが問題で、ContourやHarborのvalues.yamlの中身はStringで渡せるようなものではなく、無理やり文字列にしても以下のように逆にPackageInstall
側で怒られる。
inline-values:
|
1 | {"certificates":"{duration:8760h, renewBefore:360h}"}
|
= found: string
= expected: map (by schema.yaml:179)
ということで、現時点ではvalues.yamlが不要なものだったり、値がシンプルなものにしか利用できない。
Feature Requestは発行したので、そのうち実装されることを期待したい。
まとめ
TerraformのTMC Providerを使って、TMCやTKGをTerraformで管理する手がかりを得ることが出来た。
ただ、まだ機能としては未熟な部分もあり、ドキュメントも最低限の部分のみ整備されている感じなので、利用する場合はしっかり検証してから利用するようにした方が良さそうだ。