ツナワタリマイライフ

日常ネタから技術ネタ、音楽ネタまで何でも書きます。

AWS RDS の Engine Version ごとの EOL 情報からアラート通知させる

これの続き。

blog.chaspy.me

解決したかった課題はこれ。

github.com

AWS RDS の Engine Version を Prometheus 形式で Export することで、今何のバージョンが何個あるかが可視化できるようになった。

あとは EOL 期限になったら、近づいたらアラート発砲できればいいんだが、どのように EOL 情報を取ってくればいいか、が課題だった。

残念ながら RDS の Recommendations は API が存在しない。し、Engine version outdated では過ぎたかどうかしかわからない。

docs.aws.amazon.com

どうする

こういう csv を持つ。

  • minimum_supported_version.csv
Engine,MinimumSupportedVersion,ValidDate
mysql,5.7.0,2021-02-05
postgres,9.6.0,2021-02-16
postgres,9.7.0,2022-01-18
aurora-postgresql,10.4,2022-01-31

逐一送られてくる AWS からのメールをみたら、この CSV を更新する。1年前から余裕をもって何度も送ってくるので、どうにかして気付けるだろう。

これ、何を意味しているかというと、例えば RDS MySQL の 5.6 系が 2021-02-05 で EOL となった。強制アップデートはまだ先だが、セキュリティパッチが当たらない日がこの日なので、この日に設定した。

aws.amazon.com

で、この日を過ぎると、5.6 が非推奨となるため、"Minimum Supported Version" はその1つ上、5.7.0 となる。

この情報をもとに、各 RDS の Engine, Engine Version を比較し、以下の4種類の string を eol_status tag につける。

  • 期限切れ: expired
  • 期限の1ヶ月以内: alert
  • 期限の1ヶ月以上3ヶ月以内: warning
  • 期限の3ヶ月以上: ok

これで、このタグを使って、expired, alert, warning の内容に応じてアラートをしかけることができる。

本当はこの csv の中身にあたる情報を API で取得したい。

学びとか感想とか

結構めんどくさかった。

Version 比較

github.com

が便利だった。

func compareEngineVersion(rdsInfo RDSInfo, minimumSupportedInfo MinimumSupportedInfo) (bool, error) {
    engineVersion, err := version.NewVersion(rdsInfo.EngineVersion)
    if err != nil {
        return false, fmt.Errorf("failed to declare engine version: %w", err)
    }

    minimumSupportedVersion, err := version.NewVersion(minimumSupportedInfo.MinimumSupportedVersion)
    if err != nil {
        return false, fmt.Errorf("failed to declare minimum supported version: %w", err)
    }

    return engineVersion.LessThan(minimumSupportedVersion), nil
}

LessThan 以外にもいろいろある。

pkg.go.dev

CSV の構造体への Parse

最初普通に1行ずつ読んであれしようと思ったけど面倒になったので少し探すと csvutil という便利そうなライブラリがあったので使った。

github.com

type MinimumSupportedInfo struct {
    Engine                  string
    MinimumSupportedVersion string
    ValidDate               string
}

func readEOLInfoCSV() ([]MinimumSupportedInfo, error) {
    var eolInfos []MinimumSupportedInfo

    csv, err := ioutil.ReadFile("minimum_supported_version.csv")
    if err != nil {
        return []MinimumSupportedInfo{}, fmt.Errorf("failed to read CSV file: %w", err)
    }

    if err := csvutil.Unmarshal(csv, &eolInfos); err != nil {
        return []MinimumSupportedInfo{}, fmt.Errorf("failed to unmarshal: %w", err)
    }

    return eolInfos, nil
}

Unmarshal で短くかけて良い。

github.com

Binary から見た読み込むファイルのパス

地味にハマった。こういう変更が必要だった。

github.com

csv, err := ioutil.ReadFile("minimum_supported_version.csv")

こういう風にファイルを指定していて、実行バイナリは /app/ 以下にあって、そこと同じ場所に csv をおいていた。

Dockerfile の最後らへん。

COPY minimum_supported_version.csv /app/minimum_supported_version.csv


ENTRYPOINT ["/app/aws-rds-engine-version-prometheus-exporter"]

この場合、ファイルパスは Dockerfile の Workfir からの相対パスになるので、no such file or directory となった。まぁそれはそうか。

/etc/ 以下に csv をおいて、読み取るようにした。

なるべく絶対パスで書く方がいいんだろうな。

結果

ちゃんととれた。

f:id:take_she12:20210207185609p:plain

空白の string が返っているのは、csv に engine 名がない場合。undefined なのは事実なのでそれでいいかと思いこうしている。

ちなみに中身は Aurora MySQL

expired なのは RDS MySQL で、近々メンテ予定しています。

これで こういう Datadog Alert が作れる。

f:id:take_she12:20210207191441p:plain

ちゃんとアラート発火した。めでたしめでたし。

f:id:take_she12:20210207223105p:plain

なんか metric value 変だな。。。

課題

Aurora MySQL のサポートがまだ。

ただ、そもそも EOL 情報がよくわからんというのと、Aurora MySQL の場合 engine_version が以下の2パターンあってキモい。

  • engine_version="5.7.12"
  • engine_version="5.7.mysql_aurora.2.07.2"

パースしたくないでござる。

ので現状サポートできてないです。

おわりに

コード書くの、まだ楽しいにはならないけど、量が質に転嫁する部分もあるだろうし、書いていればネタが浮かんでまたコードを書くというループが起きることを感じているので、今後もコード書きは継続的に続けてみる。

おしまい。