継続は力なり

タイトル通り定期的な更新を心掛けるブログです。

Bytebase の Terraform provider を試してみる

タダです.

Bytebase の設定は手動で設定していたのですが, Terraform のサポートされています.全ての設定をサポートされているわけでないですが,試した備忘録としてまとめていきます.

サポートされているリソースについて

Bytebase Terraform provider では次のリソースがサポートされています.

bytebase.cc

ローカル環境のプロジェクトを追加する

ローカルで Docker を立ち上げて新規のプロジェクトリソースを追加します.なお,最初は Sample project というのがあるだけです.

Docker を立ち上げた後 Terraform 用のサービスロールを追加し,ワークスペースDBA権限を持たせておきます.その後,Terraform 実行のためのサービスキーをコピーしておきます.

Docker の立ち上げコマンド

docker run --rm --init \
  --name bytebase \
  --publish 8080:8080 --pull always \
  --volume ~/.bytebase/data:/var/opt/bytebase \
  bytebase/bytebase:2.16.0

追加したサービスアカウント

Terraform provider を設定

以下のように provider 定義をしておきます.なお,必要なパラメータが①サービスアカウントのメールアドレス,②サービスアカウントのアクセスキー,③Bytebase の設定した外部 URLになります.

terraform {
  required_providers {
    bytebase = {
      source  = "bytebase/bytebase"
      version = "0.0.9"
    }
  }
}
provider "bytebase" {
  service_account = var.service_account
  service_key     = var.service_key
  url             = var.url
}

resource "bytebase_project" "first_my_project" {
  resource_id   = "first-my-project"
  title         = "Firest My project"
  key           = "FMP"
  workflow      = "UI"
  schema_change = "DDL"
}

プロジェクト初期化して, terraform apply で適用してみます.期待通りに First My project を追加できました.

❯ terraform init     

~中略~
Terraform has been successfully initialized!
~中略~

❯ terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # bytebase_project.first_my_project will be created
  + resource "bytebase_project" "first_my_project" {
      + id            = (known after apply)
      + key           = "FMP"
      + resource_id   = "first-my-project"
      + schema_change = "DDL"
      + tenant_mode   = "TENANT_MODE_DISABLED"
      + title         = "Firest My project"
      + visibility    = "VISIBILITY_PUBLIC"
      + workflow      = "UI"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

bytebase_project.first_my_project: Creating...
bytebase_project.first_my_project: Creation complete after 0s [id=projects/first-my-project]
╷
│ Warning: Project not exists
│ 
│   with bytebase_project.first_my_project,
│   on project.tf line 1, in resource "bytebase_project" "first_my_project":
│    1: resource "bytebase_project" "first_my_project" {
│ 
│ Project projects/first-my-project not exists, try to exec the create operation
╵

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

terraform apply 実行後のプロジェクト一覧

まとめ

Bytebase の Terraform provider を使ってみたので使い方をまとめました.

Bytebase のメタデータストアを RDS の PostgreSQL を指定する

タダです.

以前の記事で ECS で Bytebase を展開する記事を書きました.書いた後に気付いたのですが,ECS タスクを落としてしまうとユーザー情報やデータベースの接続情報など Bytebase のデータが無くなっていてデータベースの指定ができてなかったしそりゃそうかと思って専用のデータベースを使う過程を備忘録にまとめます.

sadayoshi-tada.hatenablog.com

専用のデータベースの設定

冒頭の通りデフォルトでは --data ディレクトリで指定した場所にデータが保存されるので別途専用のデータベースを指定するオプションがあります.ビルドするときに --pg を指定するか環境変数PG_URL を指定すれば良いです.ドキュメントに記載がありますが, postgresql://bytebase:z*3kd2@example.com:5432/metapostgresql://bytebase:z*3kd2@example.com:5432/meta?sslrootcert=root.pem のフォーマットでデータベースの接続情報を渡してあげる必要があります.

www.bytebase.com

専用データベースで RDS の PostgreSQL を指定する

そして本題です.専用データベースに RDS PostgreSQL を指定します.起動時の論理データベースで meta というデータベースを用意する必要があるため初回の起動時に指定して作成しました.その他のパラメーターは以下のように指定しました.

  • データベースエンジンバージョン: 16.1-R2
  • インスタンスクラス: db.t3.small
  • ストレージタイプ: gp3
  • ストレージ容量: 20GB
  • パラメーターグループ: デフォルトのパラメーターグループ

docs.aws.amazon.com

Bytebase の接続ユーザーを作成する

Bytebase 接続ユーザーとして bytebase というユーザーを作り,ドキュメント記載の以下の権限を付与しています.これで準備万端です.

  • SELECT
  • INSERT
  • UPDATE
  • DELETE
  • TRUNCATE
  • REFERENCES
  • TRIGGER
  • CREATE
  • CONNECT
  • TEMPORARY
  • EXECUTE
  • USAGE
  • ALTER DATABASE meta OWNER TO bytebase
  • ALTER SCHEMA public OWNER TO bytebase

専用データベースのオプションを指定してビルドする

この記事ではビルドの指定オプションとして --pg で指定した場合はコンテナイメージを作り,ECS で起動すれば接続できました.

※変更前
CMD ["--port", "8080", "--data", "/var/opt/bytebase"]

※変更後
CMD ["--port", "8080", "--pg", <接続情報>]

まとめ

Bytebase のメタデータストアとして RDS PostgreSQL を指定してメタデータを保存できるようにしてみました.

デッドロックの発生時に通知できるように CloudWatch Logs サブスクリプションフィルターを作る

タダです.

以前,デッドロックの発生時にエラーログを CloudWatch Logs に出力するパラメーターを紹介しました.デッドロック発生時に Datadog Logs に流したいと思って CloudWatch Logs サブスクリプションフィルターと Datadog のモニターを設定したので備忘録として設定内容を書きます.

sadayoshi-tada.hatenablog.com

設定したサブスクリプションフィルター

結論ですが, "*** (1) TRANSACTION:"で設定したところフィルタリングができています.Terraform での設定例で書くと,以下のようになります.この設定で CloudWatch Logs → Kinesis Data Strems → Lambda 等を使って Datadog Logs にログを転送することができました.

resource "aws_cloudwatch_log_subscription_filter" "deadlock_subsctiption_filter" {
  name            = [サブスクリプションフィルター名]
  role_arn        = [Kinesis Streams に流すための IAM ロール ARN]
  log_group_name  = [エラーログが出力されている CloudWatch Logs のグループ名]
  destination_arn = [Kinesis Streams の ARN]
  distribution    = "ByLogStream"
  filter_pattern  = "\"*** (1) TRANSACTION:\""
}

関連ドキュメント

docs.datadoghq.com

docs.datadoghq.com

デッドロックの発生時に通知する Datadog のモニター設定

デッドロックの詳細情報が Datadog Logs に流れてきたら後はその内容を通知していきます.こちらも Terraform で設定したので設定例を書きます.

resource "datadog_monitor" "deadlock_notify_monitor" {
  name  = [モニター名]
  type  = "log alert"
  query = "logs(\"service:rds @aws.awslogs.logGroup:\\\"/aws/rds/cluster/[Aurora クラスター名]/error\\\"\").index(\"*\").rollup(\"count\").last(\"5m\") >= 1"
  message = [アラートメッセージ]
  monitor_thresholds {
    critical = 1
  }
  enable_logs_sample  = true
}

まとめ

デッドロックの発生時に Datadog Logs にログを転送するための CloudWatch Logs サブスクリプションフィルターの設定と転送されたログからモニターを作ったので,その設定をまとめました.

データベース CI/CD ツールの Bytebase を ECS Fargate でホストしてみる 🐳

タダです.

データベースの CI/CD の方法を検討する際に Bytebase を試すことがありました.Bytebase はセルフホストするかクラウド版を利用するかの二択があるのですが,セルフホストとして ECS Fargate で起動して RDS に SQL 実行を検証してみました.この記事では Bytebase を ECS Fargate で起動するために行って設定をまとめていきます.

Bytebase とは

Bytebaseは,データベース開発ライフサイクルを管理する開発者とDBAのためのデータベース CI/CD ツールです.Bytebase では MySQL,PostgreSQL,MongoDB,Snowflake,TiDB,ClickHouse,Spanner 等をサポートしてます.GitHub,GitLab,Terraformと統合して GitOps も可能にします。

www.bytebase.com

platformengineering.org

ECS Fargate で起動するためにやったこと

ECS Fargate で Bytebase をホストしていきますが,このケースでは ALB をパブリックサブネットに配置し,ECS はプライベートサブネットに配置する構成を作る想定で記載してきます.

コンテナイメージを ECR に格納

まず,Bytebase のコンテナイメージを ECR に格納していきます.Bytebase のリポジトリ に用途ごとに Dockerfile が用意されていますので,こちらの Dockerfile をビルドしました.ビルドコマンドはこのスクリプトを参照しました.

$ docker build -f ./scripts/Dockerfile \    
--build-arg VERSION="${VERSION}" \   
--build-arg GO_VERSION="$(go version)" \
--build-arg GIT_COMMIT="$(git rev-parse HEAD)" \
--build-arg BUILD_TIME="$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
--build-arg BUILD_USER="$(id -u -n)" \
--platform linux/amd64 \
-t bytebase-test .

ECS タスク定義の作成

ECR にコンテナイメージを格納したらタスク定義を作っていきます.コンテナのスペックは CPU 1コアとメモリが 2GB が要件になっているので,これを踏まえた設定を行います.ECS タスクを起動するに設定を行った部分のみ抜粋したのが以下の定義になります.

{
    "containerDefinitions": [
        {
            "name": "[コンテナ名]",
            "image": "[ECR イメージ URI]:latest",
            "portMappings": [
                {
                    "name": "8080",
                    "containerPort": 8080,
                    "hostPort": 8080,
                    "protocol": "tcp",
                    "appProtocol": "http"
                }
            ],
            "essential": true,
            "mountPoints": [
                {
                    "sourceVolume": "data",
                    "containerPath": "/var/opt/bytebase",
                    "readOnly": false
                }
            ],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "[ロググループ名]",
                    "awslogs-region": "ap-northeast-1",
                    "awslogs-stream-prefix": "[ログストリームプレフィックス]"
                }
            }
        }
    ],
    "family": "hoge",
    "taskRoleArn": "[ECS タスクロール ARN]",
    "executionRoleArn": "[ECS タスク実行ロール ARN]",
    "networkMode": "awsvpc",
    "volumes": [
        {
            "name": "data",
            "host": {}
        }
    ],
    "cpu": "1024",
    "memory": "2048"
}

関連情報

www.bytebase.com

ALB ターゲットグループを作成する

ECS タスクを登録するターゲットグループを追加します.ターゲットグループではヘルスチェックのポートとヘルスチェックパスを以下で定義した以外はデフォルトで設定しています.

  • ポート: 8080
  • ヘルスチェックパス: /healthz

セキュリティグループを追加する

ECS サービスのセキュリティグループとして ALB からの TCP 8080 番ポートのインバウンド通信を許可し,アウトバウンドで RDS に接続するためのポートを解放しておきます.

Bytebase のECS サービスを追加する

最後に ECS サービスを追加します.作成したタスク定義と ALB ターゲットグループ,セキュリティグループを設定すれば完了です.ここまででの設定が完了していれば,ECS タスクが起動して Bytebase にアクセスできるようになります.

正常に起動できていればログイン画面が表示されます

まとめ

データベースの CI/CD ツールの Bytebase を ECS Fargate でホストする際に行った作業をまとめました.

RDS Blue/Green Deployment を使って Aurora MySQL 5.7 → 8.0 に移行を試した

タダです.

Aurora MySQL 5.7 のサポート期限が今年の10月末に迫っているため,データベースエンジンのバージョンアップを進めています.そんな中で RDS Blue/Green Deployment を使って開発環境のバージョンアップを行ったのですが,その時に感じた良さをまとめてみます.

RDS Blue/Green Deployment の概要

RDS Blue/Green Deployment は最小限のダウンタイムでデータベース環境の更新や移行を実現するための機能です.Blue/Green で2つの完全に独立したデータベース環境を用意して Blue が移行元の環境で Green が移行先の環境なのですが,Blue → Green にはデータがレプリケーションされているためタイミング合わせて切り替えを行います.

docs.aws.amazon.com

RDS Blue/Green Deployment の良さ

データベースエンジンバージョンアップがボタン1つでできてしまう手軽さ

データベースエンジンバージョンアップは以前だとむちゃくちゃ大変なイメージが有りましたが,RDS Blue/Green Deployment はそのイメージを払拭してくれました.というのもボタン1つで今回の Aurora MySQL 8の環境ができあがり,環境切り替えまでのデータレプリケーションも張り続けてくれ,切り替えもボタン一発で切り替えられました.事前準備や検証は一定ありましたが,実際の移行はむちゃくちゃ簡単でした.

関連記事

aws.amazon.com

docs.aws.amazon.com

環境移行後の Aurroa エンドポイントは引き継がれる

次の良さは Aurora のエンドポイントは Blue 環境から Green 環境に引き継がれます.当然といえば当然なのかもしれませんが,エンドポイントが引き継がれるおかげでアプリケーションの環境変数DNS で登録してるレコードに影響を与えません.これは運用上ありがたい機能でした.

Terraform の後追いを行う必要がほぼない

Aurora エンドポイントが引き継がれる点と関連しますが,Terraform で Aurora を管理してると移行後にどれくらい差分が出るのかが気になっていました.実際,データベースエンジンのバージョン以外はほぼ移行後の差分はでませんでした.差分として出たのは1つ目が Aurora AutoScaling の設定がなくなっていたことです.Green 環境にはその設定が引き継がれてないため,新規追加のリソースとして差分がでました.もう1つは DB クラスターパラメーターグループとパラメーターグループでした.これは family のパラメータを変数でデータベースエンジンのバージョンを渡していたからだったんですが,5.7と8のパラメーターグループを別々で作って family の値を固定値にすれば差分はでないため,Terraform の影響もほぼなくてありがたかったです.

関連記事

registry.terraform.io

registry.terraform.io

まとめ

RDS Blue/Green Deployment を Aurora MySQL のバージョンアップを行った時に感じた良さをまとめました.