🕌

Amazon EKSの最新バージョンを管理するリポジトリを作った

2023/03/07に公開

何番煎じかは知りませんがAmazon EKSの最新バージョンを管理するリポジトリを作ってみました。

https://github.com/k-kinzal/eks-release-detecter

モチベーション

モチベーションとしてはEKSの最新バージョンを取得する方法がなく各種仕組みに組み込みにくいことです。

例えば最近では自動で最新のバージョンを検知し、バージョンを変更してPullRequestを作成する機能があったりします。(e.g. Renovate
しかし、EKSではこういったものを組み込む方法がなく、人間がEKSの更新を検知し、コードを変更して、適用するというフローを行わなければなりません。
はっきり言ってしまえばインテリジェンス溢れる人間のやることではない訳ですね。

それなら各種仕組みに組み込みやすい形でバージョンを管理できるようにしよう!と思ってやったのがこちらのリポジトリになります。

使い方

一番簡単なのはcurlを使うことだと思います。

$ curl https://raw.githubusercontent.com/k-kinzal/eks-release-detecter/main/latest
1.25
$ curl https://raw.githubusercontent.com/k-kinzal/eks-release-detecter/main/versions
1.25
1.24
1.23
1.22

他にはGitHubのTagReleasesにも対応しているので、そちらに対応しているツールがあればそちらをご利用ください。

中身の解説

中身はシンプルで下記のコードでKubernetesのバージョンを管理しているページをスクレイピングしています。

package main

import (
	"fmt"
	"log"
	"net/http"
	"regexp"

	"github.com/PuerkitoBio/goquery"
)

const URL = "https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html"

func main() {
	res, err := http.Get(URL)
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()
	if res.StatusCode != 200 {
		log.Fatalf("status code error: %d %s", res.StatusCode, res.Status)
	}

	doc, err := goquery.NewDocumentFromReader(res.Body)
	if err != nil {
		log.Fatal(err)
	}
	re := regexp.MustCompile(`^\d+\.\d+$`)
	doc.Find("ul").Each(func(i int, s *goquery.Selection) {
		if i != 0 {
			return
		}
		s.Find("p").Each(func(_ int, s *goquery.Selection) {
			version := s.Text()
			if !re.MatchString(version) {
				log.Fatalf("version is not semver compliant: `%s`", version)
			}

			fmt.Printf("%s\n", version)
		})
	})
}

これをGitHub ActionsのSchedule実行で定期的に実行しています。

go mod download
go run main.go > versions
cat versions | head -n 1 > latest

これで差分があればコミットし、Tagを作成し、Releasesを作るというだけですね。
基本はGItHub Actionでの自動更新ですが、何か上手く動作してなかったら適当にPRください。もし僕が死んだら適当にフォークしてください。

今後の方針

とりあえず準備ができたので、これを使って新しいEKSバージョンが発表されたら自動で新しいバージョンに対応したEKSのPRを作って、マージしたら自動で新しいEKSクラスタが作られるようにするっぞー!!!!
どう組み込みかは決めていないので、実際に組み込んだらUse casesに方法を追加していこうかなとは思います。

最終的には自動でPRを生成して、自動でマージして、自動でEKSクラスタを作って、自動でアプリケーションを移行して、AWSさんがドキュメントを更新したらNoOpsでEKSのバージョンアップを終わらせるんだ・・・(夢)。

余談

https://stackoverflow.com/questions/68049761/aws-eks-get-available-kubernetes-versions

aws eks describe-addon-versions | jq -r ".addons[] | .addonVersions[] | .compatibilities[] | .clusterVersion" | sort | uniq

どうやらこれでもバージョンを取得できるみたいですね!
こんな方法があったとは・・・!!!

Discussion