TerraformのEKS Published Moduleでクラスターを作成した際にコンテキストファイルに接続情報を「追記」する

2021.04.26

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Terraform EKS Published Module

Terraform Registryにある以下Published Moduleを使うと比較的簡単にEKSクラスターが作成できます。

ざっくりとは例えばこんなコードでクラスターが作れます。

module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "15.1.0"

  cluster_name    = var.cluster_name
  cluster_version = var.k8s_version
  subnets         = var.subnet_ids
  vpc_id          = var.vpc_id

  worker_groups = [{
    root_volume_type = "gp2"
  }]
}

コンテキストファイルを自動作成したい → 失敗パターン

とても便利です。さて、このモジュールにはwrite_kubeconfigという引数があります。これをtrueにすると、このクラスターに接続するコンテキストファイルも併せて出力してくれます。(デフォルト値がtrueです。)

ファイル出力先ディレクトリは別の引数config_output_pathで指定できます。こちらのデフォルト値は"./"なので、Terraformを実行しているディレクトリにファイルが作成されます。ファイル名はkubeconfig_(クラスター名)になります。

ですが、どうせならデフォルトのkubeconfigパスである~/.kube/configに作成してくれたほうが便利ですよね。 なので、引数設定してそうしてみます。

 module "eks" {
   source  = "terraform-aws-modules/eks/aws"
   version = "15.1.0"
 
   cluster_name    = var.cluster_name
   cluster_version = var.k8s_version
   subnets         = var.subnet_ids
   vpc_id          = var.vpc_id
 
   worker_groups = [{
     root_volume_type = "gp2"
   }]

+  write_kubeconfig   = true # デフォルトtrueだけど明示化しておく
+  config_output_path = pathexpand("~/.kube/config")
 }

これで確かに~/.kube/configにコンテキストファイルが作成されます。なのですが…すでにその位置にファイルがあった場合、追記ではなく上書きしてしまいます。 それで良い場合もあるでしょうが、他のクラスターにもアクセスしたいケースだと困ります。

コンテキストファイルを自動作成したい → 成功パターン

どうやら2021年4月26日現在このモジュールにコンテキストファイルを追記してくれるオプションは備わっていないようです。仕方がないので以下の方法で対応しましょう。

 module "eks" {
   source  = "terraform-aws-modules/eks/aws"
   version = "15.1.0"
 
   cluster_name    = var.cluster_name
   cluster_version = var.k8s_version
   subnets         = var.subnet_ids
   vpc_id          = var.vpc_id
 
   worker_groups = [{
     root_volume_type = "gp2"
   }]

+  write_kubeconfig   = false
-  write_kubeconfig   = true 
-  config_output_path = pathexpand("~/.kube/config")
 }
+
+resource "null_resource" "update_kubeconfig" {
+  triggers = {
+    cluster_name = module.main.cluster_id
+  }
+  provisioner "local-exec" {
+    command = "aws eks update-kubeconfig --name ${module.main.cluster_id}"
+  }
+}

事前にTerraform実行環境にAWS CLIをインストールしておく必要があります。 Null Providerのnull_resourceというリソースで、Terraform内でAWS CLIのaws eks update-kubeconfigコマンドを実行します。このコマンドはコンテキストファイルを上書きでなく追記してくれます。

triggersは、この値に変更があるときのみコマンドを実行する、という設定です。この設定を入れることで基本的に初回のapply実行時以外はこの処理が走らないようにしています。クラスター名が変わる=エンドポイントが変わるのでクラスター名(=クラスターID)を値に設定しています。(ですがクラスター名を変えると他の箇所でエラーが出るので、適切にコンテキストファイルを作り直すことができてないです…ここのうまい対処法をご存知のかた教えて下さい)

参考情報

蛇足

EKS Published Moduleにはkubeconfig_nameという引数もあります。最初これがコンテキストファイル名、config_output_pathがそのファイルが置かれるディレクトリを指定するものかと思ったのですが、誤解でした。kubeconfig_nameは、コンテキストファイル内に書かれるコンテキストの名前を指定するものでした。ですので、config_output_pathにはディレクトリに加えてファイル名まで指定することができます。

併せて読みたい