Terraform ControllerのBranch Plannerを試す

本記事では、TerraformリソースをGitOpsで管理できるTerraform Controllerで、Branch Plannerという機能を試してみます。

# Terraform Controllerとは
Terraform Controller (以降tf-controller) とはGitOpsでTerraformリソースを管理するためのFluxのコントローラーです。

tf-controllerの機能の詳細は下記をご覧ください。

https://weaveworks.github.io/tf-controller/

現時点でサポートしているMatrixは下記となります。
|Version|Terraform|Source Controller|Flux v2|
|-|-|-|-|
|v0.15|v1.3.9|v1.0.x|v2.0.x|
|v0.14|v1.3.9|v0.31.0|v0.41.x|
|v0.13|v1.3.1|v0.31.0|v0.36.x|
|v0.12|v1.1.9|v0.26.1|v0.32.x|

# 本題
tf-controllerのBranch Plannerとは、PR作成時にTerraformのPlan結果をコメントで通知してくれる機能です。
現時点ではこの機能はrcバージョンになります。

https://weaveworks.github.io/tf-controller/branch_planner/

今回は下記のクイックスタートを参考にさくっと試します。
- https://docs.gitops.weave.works/docs/terraform/get-started/
- https://weaveworks.github.io/tf-controller/branch_planner/branch-planner-getting-started/

環境情報
```
kubernetes: v1.27.1
flux: v2.1.1
helm-controller: v0.36.1
kustomize-controller: v1.1.0
notification-controller: v1.1.0
source-controller: v1.1.1
tf-controller: v0.16.0-rc.3 
```

## 手順
kindでクラスタを作成します。
```bash
kind create cluster --name tf-controller
```
fluxをインストールします。
```bash
brew install fluxcd/tap/flux
```
sync用のリポジトリを作成します。
```bash
export GITHUB_USER=<your github username>
export GITHUB_TOKEN=<your github personal access token>

gh repo create $GITHUB_USER/gitops-tf-controller
git clone git@github.com:$GITHUB_USER/gitops-tf-controller.git
```
fluxを導入します。
```bash
cd gitops-tf-controller

flux bootstrap github \
  --owner=$GITHUB_USER \
  --repository=gitops-tf-controller \
  --branch=main \
   --path=./cluster/my-cluster \
   --personal \
   --token-auth
```
tf-controllerのマニフェストをcurlで取得します。
```bash
git pull
mkdir -p ./cluster/my-cluster/infra/
curl -s https://raw.githubusercontent.com/weaveworks/tf-controller/main/docs/release.yaml > ./cluster/my-cluster/infra/tf-controller.yaml
```
ここでBranch Plannerを有効にするためにtf-controller.yamlに下記を追加します。（HelmReleaseのspec.values配下）
```yaml
    branchPlanner:
      enabled: true
```

kustomization.yamlを作成してリポジトリにpushします。
```yaml: kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - tf-controller.yaml
```
これで変更を検知してtf-controllerがdeployされます。

次にBranch Planner用のSecretを作成します。
```bash
kubectl create secret generic branch-planner-token \
    --namespace=flux-system \
    --from-literal="token=${GITHUB_TOKEN}"
```

デモ用のSync設定とTerraformオブジェクトを追加します。
```bash
export GITHUB_USER=<your user>
export GITHUB_REPO=<your repo>

cat <<EOF | kubectl apply -f -
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
  name: branch-planner-demo
  namespace: flux-system
spec:
  interval: 30s
  secretRef:
    name: flux-system
  url: https://github.com/${GITHUB_USER}/${GITHUB_REPO}
  ref:
    branch: main
---
apiVersion: infra.contrib.fluxcd.io/v1alpha2
kind: Terraform
metadata:
  name: branch-planner-demo
  namespace: flux-system
spec:
  approvePlan: auto
  path: ./
  interval: 1m
  sourceRef:
    kind: GitRepository
    name: branch-planner-demo
    namespace: flux-system
EOF
```

ブランチを作成して、リポジトリ直下にデモ用のTerraformリソースを準備します。

```terraform: main.tf
terraform {
  required_version = ">= 1.3.9"
}

variable "subject" {
   type = string
   default = "World"
   description = "Subject to hello"
}

output "hello_world" {
  value = "Hello TF Controller v0.16.0-rc.2, ${var.subject}!"
}
```

https://github.com/tf-controller/branch-planner-demo/blob/main/main.tf

リポジトリにpushしてPRを作成します。
しばらくすると、下記のようにplan内容がコメントされました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2509379/f4f0ac48-d18c-de2f-14f8-2df9401de223.png)


`!replan`とコメントすると再度Plan結果を通知してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2509379/08ed5ae1-4215-6967-37af-b65300b99a6a.png)

# まとめ
TerraformリソースをGitOpsで管理できる、 Terraform ControllerでBranch Plannerという機能を試してみました。
Plan内容をPR上で自動通知してくれる便利な機能なので早く正式リリースされることを期待しています。