Terraformからeksctlを操る!terraform-provider-eksctlを使ってみた

2021.02.28

eksctlとは

k8sクラスターをeks上に作成するのをサポートしてくれるCLIツールです。コマンド一発で、クラスターだけでなくクラスター作成に必要なVPCやIAMロールなどの周辺リソースもまるっと作成してくれます。

詳しくは以下のエントリをどうぞ。

terraform-provider-eksctlとは

で、そんな便利なeksctlをさらにTerraformでラップしたものがこのterraform-provider-eksctlです。私は現在参画中のプロジェクトにて、クラスター外のリソース(ALBなど)をTerraformでプロビジョニングしています。ですので、クラスター作成部分もTerraform化できるのは何かと都合が良いのではないかと思い、触ってみたいと思いました。

providerのインストール

Terraform version 0.13以降であれば、以下のようなコードを書いてterraform initするだけでOKです。簡単ですね。

terraform {
  required_version = "= 0.14.7"

  required_providers {
    eksctl = {
      source  = "mumoshu/eksctl"
      version = "0.15.1"
    }
  }
}

provider "eksctl" {}

クラスター作成

eksctlでクラスターを作成する際、 eksctl create clusterというコマンドを使うのですが、細かい設定の方法は大きく分けて2つの方法があります。一つが以下のようにコマンドのオプションを使う方法です。

$ eksctl create cluster \
--name test \
--version 1.18 \
--region ap-northeast-1 \
--nodegroup-name linux-nodes \
--nodes 3 \
--nodes-min 1 \
--nodes-max 4 \
--with-oidc \
--managed

もう一つが、YAML形式で設定を書き、--config-fileもしくは-fオプションでそのファイルを読み込む方法です。

$ eksctl create cluster --config-file=hoge.yaml

terraform-provider-eksctlは、後者のYAML形式と同様の方法でクラスター作成が可能です。

eksctlのGitHubリポジトリにはサンプルのYAML設定ファイルが色々置いてあります。これらのファイルのapiVersionkindmetadataをコメントアウトすればこの設定がそのまま使えます。

例えば、01-simple-cluster.yamlという設定ファイルがあります。中身はこんな感じです。

01-simple-cluster.yaml

# A simple example of ClusterConfig object:
---
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: cluster-1
  region: eu-north-1

nodeGroups:
  - name: ng-1
    instanceType: m5.large
    desiredCapacity: 1

cloudWatch:
    clusterLogging:
        # enable specific types of cluster control plane logs
        enableTypes: ["audit", "authenticator", "controllerManager"]
        # all supported types: "api", "audit", "authenticator", "controllerManager", "scheduler"
        # supported special values: "*" and "all"

apiVersionkindmetadataをコメントアウトします。

01-simple-cluster-for-terraform-provider-eksctl.yaml

# A simple example of ClusterConfig object:
---
# apiVersion: eksctl.io/v1alpha5
# kind: ClusterConfig

# metadata:
#   name: cluster-1
#   region: eu-north-1

nodeGroups:
  - name: ng-1
    instanceType: m5.large
    desiredCapacity: 1

cloudWatch:
    clusterLogging:
        # enable specific types of cluster control plane logs
        enableTypes: ["audit", "authenticator", "controllerManager"]
        # all supported types: "api", "audit", "authenticator", "controllerManager", "scheduler"
        # supported special values: "*" and "all"

そして、以下のようなリソースを定義します。

resource "eksctl_cluster" "primary" {
  eksctl_version = "0.38.0"
  name           = "primary1"
  region         = "ap-northeast-1"
  spec           = file("./01-simple-cluster-for-terraform-provider-eksctl.yaml")
}

この状態でterraform applyするとEKSクラスターを作成可能です。

YAMLファイルのスキーマは以下で一覧できます。

eksctlの事前インストールは不要

前述のeksctl_clusterリソース内でeksctl_versionという引数でeksctlのバージョンを指定しました。こうやってeksctl_versionを指定した場合は、事前にTerraform実行環境にeksctlをインストールしておく必要はありません。この場合、providerが所定のバージョンのeksctlをTerraformルートモジュール以下の.shoal/Barrel/eksctl/以下にダウンロードしてきて、それをリソースのプロビジョニング時に使用します。

$ tree -la
.
├── .shoal
│   ├── Barrel
│   │   └── eksctl
│   │       ├── 0.38.0
│   │       │   └── eksctl
│   │       └── INSTALL_RECEIPT.json
│   (略)
(略)

確認

~/.kube/configにコンテキストが自動で追記され、かつ現在のコンテキストに設定されます。ですのでそのままkubectlコマンドが使えます。

$ kubectl config current-context
1614484588452781000@primary1.ap-northeast-1.eksctl.io
$ kubectl get all --all-namespaces
NAMESPACE     NAME                          READY   STATUS    RESTARTS   AGE
kube-system   pod/aws-node-z7rp2            1/1     Running   0          21m
kube-system   pod/coredns-79769ff86-5qxwj   1/1     Running   0          55m
kube-system   pod/coredns-79769ff86-trv4d   1/1     Running   0          55m
kube-system   pod/kube-proxy-6t6dl          1/1     Running   0          21m

NAMESPACE     NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)         AGE
default       service/kubernetes   ClusterIP   10.100.0.1    <none>        443/TCP         55m
kube-system   service/kube-dns     ClusterIP   10.100.0.10   <none>        53/UDP,53/TCP   55m

NAMESPACE     NAME                        DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
kube-system   daemonset.apps/aws-node     1         1         1       1            1           <none>          55m
kube-system   daemonset.apps/kube-proxy   1         1         1       1            1           <none>          55m

NAMESPACE     NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
kube-system   deployment.apps/coredns   2/2     2            2           55m

NAMESPACE     NAME                                DESIRED   CURRENT   READY   AGE
kube-system   replicaset.apps/coredns-79769ff86   2         2         2       55m