【2019年6月版】Terraform+Spinnakerがよくね!? → もはや沼。

# GKE + Spinnaker のデプロイを Terraform で行ってみた。2か月ぶりに。

以前のこちらの記事「[【2019年4月版】Terraform+Spinnakerがよくね!? → 闇が深い。](https://qiita.com/koinori/items/3e1988de28473e328251)」で作成した Terraform のスクリプトを2か月ぶりに実行してみたのですが・・・**Terraformがバージョンアップ**してたり**GKEのバージョンアップ？**などあったりして、**まったく動かなくなって**おりました。

特に、[Spinnaker本家サイトの構築手順](https://www.spinnaker.io/setup/quickstart/halyard-gke/)が現時点では**構築できない**手順になっておりましたので要注意です。

## 対象環境
- OS : Ubuntu 18.04 LTS
- Terraform : 0.12.2 !!
- *Terraform : 0.12.2 !!*
- **Terraform : 0.12.2 !!**
- GCP Provider : 2.8
- Kubernetes Provider : 1.6.1

Terraform が 0.11 から 0.12 に上がりました。0.x 系での破壊的更新はアリですけど！アリですけど！

・・・以下に修正箇所を上げます。

## Terrform 0.11 から 0.12 へのマイグレーション

こちらの本家ページ「[Upgrading to Terraform v0.12](https://www.terraform.io/upgrade-guides/0-12.html)」にもありますが、以下のコマンドで設定ファイルをコンバートしてくれます。

```console
$ terraform 0.12checklist

$ terraform 0.12upgrade
```

変数や式の書き方がだいぶわかりやすくなりましたね。というか、基本的に `${...}` は書かなくてもOKになりましたね。

## Google Kubernetes クラスタ から Kubernetes Provider への接続情報

以下のようになります。

```terraform
data "google_client_config" "default" {}

provider "kubernetes" {
  host = google_container_cluster.gke.endpoint
  cluster_ca_certificate = base64decode(
    google_container_cluster.gke.master_auth[0].cluster_ca_certificate,
  )
  token   = data.google_client_config.default.access_token
  version = "~> 1.6.2"
}
```

前回の`master_auth`を使った認証は**全滅**でした。全く接続できなくなっておりました。
`google_client_config.default.access_token` の**トークンでしか、アクセスできません**でした。

## Connection リソースの host 指定が必須

Remote-exec Provider や File Provider で大活躍の Connection リソースですが、`host` の指定が必須になりました。~~そこ、自動でやってくれるから便利だったのにさ・・・~~

作成した vm インスタンスにsshでコマンド投げる場合は以下のようになります。

```terraform
resource "google_compute_instance" "instance-1" {
    name         = "small-instance-1"
    machine_type = "g1-small"
    zone         = "us-cental1-a"
...
  provisioner "remote-exec" {
    inline = [
      "KUBECTL_LATEST=$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)",
      "curl -LO https://storage.googleapis.com/kubernetes-release/release/$KUBECTL_LATEST/bin/linux/amd64/kubectl",
      "chmod +x kubectl",
      "sudo mv kubectl /usr/local/bin/kubectl",
      ....
    ]
    connection {
      host        = self.network_interface.0.access_config.0.nat_ip
      type        = "ssh"
      user        = var.gcp_account_name
      private_key = file("path/to/rsa/private")
      timeout     = "5m"
    }
}
```

このように、GCE のインスタンスに接続する場合は `self.network_interface.0.access_config.0.nat_ip` を接続先とします。

ちなみに、この値は上記の `terraform 0.12upgrade` では補完してくれませんので自分でその都度、確認する必要あります。

## kubenetes_secret.data がブロックからマップに変更

以前は以下のような書き方をしていた`kubenetes_secret.data`プロパティですが・・・

```terraform
resource "kubernetes_secret" "example" {
  metadata {
    name = "basic-auth"
  }

  data {
    username = "admin"
    password = "P4ssw0rd"
  }

  type = "kubernetes.io/basic-auth"
}
```

**マップ** になって以下のように `=` を挟むようになってます。

```
  data = {
    username = "admin"
    password = "P4ssw0rd"
  }
```
[本家のリファレンス](https://www.terraform.io/docs/providers/kubernetes/r/secret.html)を見ても0.11までの書き方だし、エラーメッセージもよくわからないので、かなりハマりました。

他にもブロックからマップになったプロパティ、あるんじゃないだろうか・・・

## Spinnaker のインストール手順がダメ

### その1

上記にも上げました [Spinnaker 公式サイト](https://www.spinnaker.io/setup/quickstart/halyard-gke/#part-2-gather-needed-credentials)の以下の手順で・・・

```console
$ GKE_CLUSTER_NAME={YOUR_GKE_CLUSTER_NAME}
$ GKE_CLUSTER_ZONE={YOUR_GKE_CLUSTER_ZONE}

$ gcloud config set container/use_client_certificate true

$ gcloud container clusters get-credentials $GKE_CLUSTER_NAME \
    --zone=$GKE_CLUSTER_ZONE
```
`gcloud config set container/use_client_certificate true` は**やっちゃダメです**。

以下のように `set container/use_client_certificate true` を抜いた、

```
$ GKE_CLUSTER_NAME={YOUR_GKE_CLUSTER_NAME}
$ GKE_CLUSTER_ZONE={YOUR_GKE_CLUSTER_ZONE}

$ gcloud container clusters get-credentials $GKE_CLUSTER_NAME \
    --zone=$GKE_CLUSTER_ZONE
```
が正解です。

ちなみに、`gcloud config set container/use_client_certificate true` を実施すると・・・

```
$ gcloud config set container/use_client_certificate true

$ gcloud container clusters get-credentials $GKE_CLUSTER_NAME \
    --zone=$GKE_CLUSTER_ZONE
Fetching cluster endpoint and auth data.
ERROR: (gcloud.container.clusters.get-credentials) get-credentials requires edit permission on プロジェクト名
```
と素っ気ない返事が返ってきます。たとえオーナー権限を持つサービスアカウントを使ったとしてもこのエラーメッセージは揺るぎません。

### その2

もはや些細なことですが`hal deploy apply` はエラーとなり、以下で動きます。

```
$ sudo hal deploy apply
```
はい、`sudo`が必要です。。。

以上！