AWS CodeBuildからDBマイグレーションを実行する方法を調査
やりたいこと
CodeBuildを使って、RDSへのDBマイグレーションを実行したい。
さらにCode Pipelineと合わせて使うことで、自動デプロイ時にDBマイグレーションを自動的に実行できるようになる。
知りたいこと
- 必要なIAMポリシーは何か
- CodeBuildで実行するコマンドや操作
前提
- ECSとRDSを利用している
- DB:PostgreSQL
- 言語:TypeScript
- ORマッパー:Sequelize
必要なIAMポリシーは何か
IAMポリシーは特別必要なものは不要だと思われる。
CodeBuildで実行するコマンドや操作
CodeBuildをVPC内で実行するようにして、ネットワーク周りを正しく設定すればできそう。
参考にしたURL集
まずはCodeBuildのビルドプロジェクトを作成する。
CodeBuildからRDSに接続するためにはVPCの設定が必要だが、一旦後回しにする。
ソースは「GitHub」を選択し、自分の公開リポジトリを指定。
無料枠で実施する場合、インスタンスタイプをgeneral1.small
にする必要がある。
以下の用に設定した。
- オペレーティングシステム:
Amazon Linux 2
- ランタイム:
Standard
- 環境イメージ:
aws/codebuild/amazonlinux2-x86_64-standard:3.0
- 環境タイプ:
Linux
- コンピューティング:
3 GB メモリ、2 vCPU
(general1.small
)
使用するランタイムによって、サポートしているイメージが異なる。
- buildspec.ymlの作成
CodeBuildのプロジェクトのランタイムや実行コマンドを定義する
-
npm init
でpackage.jsonの生成 -
sequelize
をインストール
DBはPostgreSQLなので、関連パッケージも合わせてインストールする。
$ npm install --save sequelize
$ npm install --save pg pg-hstore # Postgres
4. GitHubにプッシュした後、AWSコンソールから「ビルドを開始」を押して、ビルドを開始する
先にRDSを作っておく。(時間がかかるので)
- データベースエンジン:PostgreSQL 12.5
- インスタンスタイプ:
db.t2.micro
- ストレージタイプ: 汎用
- ストレージ: 20GiB
マイグレーションコードの用意をした後、buildspeck.yml
にDBマイグレーションのコマンドを追加した
どのフェーズに追加するべきかは迷ったが、ビルドの後だと思ったので、post_build
フェーズにした。
phases:
post_build:
commands:
- echo This phease is post_build at `date`
- echo exec DB migration
- npm run db:migrate
CodeBuild用のネットワーク環境の整備
- サブネットを作成
- CodeBuildを配置するPrivateサブネット
- NATゲートウェイを配置するPublicサブネット
- Privateサブネット用のルートテーブルの作成
-
0.0.0.0/0
のターゲットには作成するNATゲートウェイを指定
-
- NATゲートウェイを作成
- Elastic IPでIPアドレスを割り当て
- セキュリティグループの作成
- CodeBuildのセキュリティグループ
- RDSのセキュリティグループのインバウンドルールにCodeBuildのセキュリティグループからのアクセスを許可する設定を追加
CodeBuildの環境変数にDATABAS_URL
を追加
CodeBuildからRDSへの接続はできたが、RDS内部にデータベースを作成していなかった。
以下のエラー
Sequelize CLI [Node: 12.19.1, CLI: 6.2.0, ORM: 6.6.2]
Loaded configuration file "config/config.json".
Using environment "development".
ERROR: database "db-migration-test" does not exist
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! code-build-db-migraiton@1.0.0 db:migrate: `sequelize db:migrate`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the code-build-db-migraiton@1.0.0 db:migrate script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /root/.npm/_logs/2021-03-28T13_48_01_711Z-debug.log
RDS内部にデータベースを作成して、もう一度トライしたらできるのではないか。
マイグレーションコードの用意
-
sequelize-cli
をインストール
$ npm install -D sequelize-cli
- Sequelizeのプロジェクトを初期化
$ npx sequelize init
configファイルなどが生成される
{
"development": {
"use_env_variable": "DATABASE_URL"
}
}
- マイグレーション用のファイルを生成
$ npx sequelize migration:generate --name create-schema
自動的に生成されたjsファイルを編集。今回はスキーマを作成するのみ。
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
queryInterface.createSchema('test_schema');
},
down: async (queryInterface, Sequelize) => {
queryInterface.dropSchema('test_schema');
}
};
- NPMスクリプトにコマンドを定義(任意)
{
(略)
"scripts": {
"db:migrate": "sequelize db:migrate",
}
(略)
}
- ローカル環境で実行して動作確認する
Dockerでマイグレーション実行用コンテナ(node実行環境)とDBコンテナを作成して確認した。
$ npm run db:migrate
つまづいた部分
Dockerの扱いに慣れていない
ローカル環境でDockerイメージの作成、コンテナを立ち上げることに時間がかかってしまった。
最初からdocker-composeを使ってやれば少しは早かったかもしれない。
CodeBuildからGitHubにアクセスできなくなった。
CodeBuildに割り当てるセキュリティグループのアウトバウンドルールを削除してしまったため。
CodeBuildをVPC内で実行するためのネットワーク設定に時間がかかった
- サブネットの作成
- パブリックサブネットとプライベートサブネットの違いはインターネットゲートウェイへのルーティングが設定されているかどうかの違い
- NATゲートウェイの作成
- NATゲートウェイはプライベートサブネットからインターネットにアクセスするために必要。
- NATゲートウェイ自体はパブリックサブネットに配置し、Elastic IPを割り当てる。
- ブライベートサブネットのルートテーブルにNATゲートウェイを設定する
CodeBuildからRDSへの接続でタイムアウトが発生した
CodeBuildのセキュリティグループのアウトバウンドルールでpsqlが許可されていなかった。
後片付け
コスト削減のため、検証の終わりには作成したインスタンスを削除する。
- そのままにしておくとお金がかかるもの
- ✅ RDS
- ✅ NATゲートウェイ
- ✅ Elastic IP
- そのままでもお金はかからないが作成したもの
- ✅ 各セキュリティグループ/サブネット/ルートテーブル
- ✅ CodeBuild(ビルド時間にお金がかかるので)