Kong GatewayのSaaS版であるKonnectに対応したTerraform ProviderがひっそりとGitHubに公開されている。
'24/6/13現在まだベータ版でありTerraformのページではドキュメントも公開されていない状態だが、使おうと思えば使える状態なので試しに使ってみる。
※'24/10/8追記:'24/9/12に1.0がリリースされました。ドキュメントも今は揃ってます。
ここでは以下をTerraformでやってみる
- ControlPlaneの構築
- ServiceとRouteの作成
- レート制限の設定
なお、DataPlaneに関してはKonnect APIの管轄外なのでKonnectのProviderからデプロイせず、別で行う必要がある(Cloud Gatewayの場合はデプロイ可能)。
別のProviderを使ってTerraform化は出来そうだがここでは対象外とした。
あと今回使うtfファイル・ディレクトリの配置に関しては適当なので、好みに合わせて適宜修正して欲しい。
terraform-provider-konnectとは
Kong KonnectのためのTerraform Providerで、以下のようなものの自動構築が可能となっている(らしい)。
- Control Planeの構築
- Cloud Gatewayの構築
- Kong Gatewayの基本コンポーネント(Service、Route、Upstream、Consumer等)の設定
- 一部のPluginの設定(AI関連や認証、レート制限、キャッシュ等範囲は広い)
- その他もろもろ(Dev Portal、API Product、Organization、etc)
Konnectを自動構築する場合、これまではdeck
で行うことが一般的だったが新しい選択肢が増えたといえる。
なお、deck
と比較するとこんな感じじゃないかと思われる。
deck | Terraform | |
---|---|---|
基本機能のカバー範囲 | Keyなどは含まれない | Keyなど含んでやや広い |
ControlPlane/DataPlaneのデプロイ | 出来ない | 出来る(DPはCloudGatewayのみ) |
Plugin | 完全サポート | 特定のもののみ |
サポートプラットフォーム | Kong Gateway/Konnect | Konnect+その他色々なプラットフォーム |
実装の容易さ | 慣れれば簡単 | ドキュメントなく難 |
移植(Konnect↔KongGateway)の容易さ | コード修正不要 | 別でコードが必要 |
CI/CDとの相性 | バッチリ | バッチリ |
Terraform Providerだとドキュメントがないのとサポートプラグインが限られるのが非常に痛いが、ここが改善されるとdeck
を置き換えても良さそう。
前提
以下が用意されているものとする。
- Konnectのアカウントがある
- Konnect上にOrganizationを作成済み
Konnectは無料枠でも問題ない。メールアドレスさえあれば利用できる。
構築・設定
KonnectのTerraform Providerを使って構築・設定を行っていく。
最終的には以下のファイルを作成する。
.
├── main.tf
├── modules
│ ├── control-planes
│ │ ├── main.tf
│ │ ├── output.tf
│ │ └── provider.tf
│ └── gateway-configs
│ ├── httpbin-ratelimit.tf
│ ├── httpbin-rt.tf
│ ├── httpbin-svc.tf
│ ├── main.tf
│ ├── provider.tf
│ └── variables.tf
├── provider.tf
└── variables.tf
なお、上記のファイルは以下に置いたので、実際に試したい人で作成するのが面倒であればそちらから入手して欲しい。
konnect-provider-sample
Terraform CLIの導入
この辺を参考に自PCにCLIをインストールする。
ここではMacの手順で進める。
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
基本となるファイルの作成
KonnectへのAPIの発行はKonnectのPAT(Personal Access Token)を使う。
持っていない人はKonnectのPersonal Access Tokenのページに飛んで、Generate Token
でTokenを生成する。
次にトークンを環境変数に設定する。
TF_VAR_
がついた環境変数はterraform
コマンド実行時に変数として扱えるので、以下のような感じでトークンを設定する。
export TF_VAR_konnect_token=kpat_Qbzexxxxx
変数を定義するvariables.yaml
を作成する
variable "konnect_token" {
description = "Konnect PAT"
type = string
sensitive = true
}
Terraform Providerを定義する。
terraform {
required_providers {
konnect = {
source = "kong/konnect"
}
}
}
provider "konnect" {
personal_access_token = var.konnect_token
server_url = "https://us.api.konghq.com"
}
一旦ここでterraform init
を実行してProviderが使えるか確認する。
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Finding latest version of kong/konnect...
- Installing kong/konnect v0.2.5...
:(省略)
Terraform has been successfully initialized!
:(省略)
上記のように出力されればOK。
ControlPlaneの構築
Control Planeのtfファイルの格納用ディレクトリを作成する。
mkdir -p modules/control-planes
またこちらの下にもprovider.tfを配置する。
terraform {
required_providers {
konnect = {
source = "kong/konnect"
}
}
}
ControlPlaneはkonnect_gateway_control_plane
で定義できる。
サンプルを参考に以下のように作成した。
resource "konnect_gateway_control_plane" "tfdemo" {
name = "Control Plane by Terraform"
description = "Created by Terraform"
cluster_type = "CLUSTER_TYPE_HYBRID"
auth_type = "pinned_client_certs"
}
少し補足する。
cluster_type
はControlPlaneをデプロイする時のタイプを指定するもので、以下の4️つから選択できる。
-
CLUSTER_TYPE_CONTROL_PLANE
:Cloud Gateway用? -
CLUSTER_TYPE_CONTROL_PLANE_GROUP
:Control Plane Groupを選択したのと同じ -
CLUSTER_TYPE_HYBRID
:Kong Gateway( Self-Managed Gateway)を選択したのと同じ -
CLUSTER_TYPE_K8S_INGRESS_CONTROLLER
:Kong Ingress Controllerを選択したのと同じ
auth_type
はControlPlaneとDataPlaneの通信方法を設定する箇所で、以下の2つから選択できる。
-
pinned_client_certs
:Pinned mode(鍵認証)で動作 -
pki_client_certs
:PKI mode(証明書による認証)で動作
Control Planeモジュールを読み込むためのmain.tf
を作成する
module "control-planes" {
source = "./modules/control-planes"
}
モジュールを読み込ませる。
terraform init
設定を適用する。
terraform apply
問題なければ以下のようなメッセージが表示される。
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Konnectにアクセスすると、以下のように設定した内容でControl Planeが作成されていることが分かる。
ServiceとRouteの作成
次にServiceとRouteを設定する。
Service・Route側でControl Planeを参照できるよう、outputでControlPlaneを出力する。
output "cp" {
value = konnect_gateway_control_plane.tfdemo
}
Service・Route作成に使うtfファイルの格納用ディレクトリを作成する。
mkdir -p modules/gateway-configs
またこちらの下にもprovider.tfを配置する。
terraform {
required_providers {
konnect = {
source = "kong/konnect"
}
}
}
ControlPlaneを参照するための変数を用意する。
variable "control_plane" {
type = any
}
次にServiceを作成する。Serviceはここではhttpbinを利用する。
作成するファイルは以下となる。
resource "konnect_gateway_service" "httpbin" {
name = "HTTPBin"
protocol = "https"
host = "httpbin.org"
port = 443
path = "/"
control_plane_id = var.control_plane.id
}
control_plane_id
はどのControlPlaneと紐づけるかを指定するためにControlPlaneのIDを指定する。
ControlPlaneのリソースがvar.control_plane
に格納されるように後ほど設定する。
なお、おそらくIDのベタ書きでも行けるとは思う。
次にRouteを作成する。
resource "konnect_gateway_route" "httpbin" {
name = "httpbin"
paths = ["/httpbin"]
strip_path = true
control_plane_id = var.control_plane.id
service = {
id = konnect_gateway_service.httpbin.id
}
}
Serviceと同じ要領でcontrol_plane_id
はControlPlane作成時に設定される変数の情報を使って引っ張る。
service.id
については同一モジュール内からリソース(konnect_gateway_service.httpbin
)を直接参照してRouteを紐づける。
また、モジュールにはmain.tf
が必要なので空ファイルを作成する。
touch modules/gateway-configs/main.tf
最後にroot直下のmain.tfに以下を追記する。
module "gateway-configs" {
source = "./modules/gateway-configs"
control_plane = module.control-planes.cp
}
gateway-configsの中のvariables.tf
で定義したcontrol_plane
はここで設定した。
動かしてみる。
terraform apply
以下のような出力が得られるはずだ。
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Konnect側でもService、Routeが作成されたことが確認できる。
ここで動作確認用にDataPlaneもデプロイしてhttpbinにアクセスできるかを確認する。
DataPlaneのデプロイ方法についてはTerraformを使っていないため割愛する。
ここではMac上にDockerでデプロイした。
Data Planeが提供するProxy経由でアクセスしてみる。
$ curl -i localhost:8000/httpbin/ip
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 47
Connection: keep-alive
Date: Thu, 13 Jun 2024 07:24:01 GMT
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
X-Kong-Upstream-Latency: 731
X-Kong-Proxy-Latency: 1
Via: kong/3.7.0.0-enterprise-edition
X-Kong-Request-Id: 0c066f075523c4032279af617e1cb80c
{
"origin": "192.168.127.1, xxx.xxx.xxx.xxx"
}
無事httpbinにアクセスできることが確認できた。
レート制限の設定
最後にRate Limit Pluginを使ってレート制限を設定する。
Rate Limit Pluginはリソースkonnect_gateway_plugin_rate_limiting
で用意されているので以下のようにtfファイルを作成する。
resource "konnect_gateway_plugin_rate_limiting" "httpbin_rate_limiting_plugin" {
enabled = true
config = {
minute = 5
policy = "local"
}
protocols = ["http", "https"]
control_plane_id = var.control_plane.id
route = {
id = konnect_gateway_route.httpbin.id
}
}
1分間のアクセス可能な上限を5回とした。
ServiceやRouteと書き方は変わらないので、ここでは書き方については補足説明は特にしない。
ファイル作成後、適用する。
terraform apply
動作確認する。6回アクセスしてみる。
for((i=0;i<6;i++)); do curl -I localhost:8000/httpbin/ip | grep "HTTP\|Limit"; sleep 1 ; done
6回目で以下が表示されて上限に達したことが分かる。
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit-Minute: 5
X-RateLimit-Remaining-Minute: 0
RateLimit-Remaining: 0
RateLimit-Limit: 5
RateLimit-Reset: 8
Pluginの適用も問題なさそうだ。
所感
Konnectの自動構築はdeck
でも出来るが、他の環境も含めてまとめて一元管理・まとめて構築したい場合はTerraformが使えるのは嬉しい。
まだドキュメントがなくて使うにはかなりキツイが、今後の発展を見守りたい。