一休.com Developers Blog

一休のエンジニア、デザイナー、ディレクターが情報を発信していきます

tsqllint & Appveyor & AWS CodeDeployで実現するDDL適用自動化

この記事は一休.comアドベントカレンダー2018の22日目です。

qiita.com


データベースに対するDDLの適用、みなさんはどのように運用していますか。
一休では長らく担当者が手動適用をしていました。が、開発者全員の依頼をまとめて、定期的にDDL適用を行うのはかなりの作業負荷です。 そこで、アプリケーションのソースコードと同じようにGitHubとCI/CDのパイプラインを構築して、適用したい開発者が自分で適用できる仕組みを構築しました。

この記事では、その概略を紹介したいと思います。
※当社はMicrosoft SQL Serverを使っているので、その前提の記事になります。

デプロイフロー

f:id:s-tokutake:20181221184621p:plain

  • CIにはAppveyorを、CDにはAWS CodeDeployを利用
    • CodeDeployは後述の通り、外部アクセス用のプロキシサーバも利用
  • GitHubにDDLを管理するリポジトリを作成
  • 開発者はこのリポジトリで新規に適用したいDDLのPull Requestを作成
  • PRをmasterブランチに適用するとAppveyor経由でCodeDeployが起動される。
  • CodeDeploy Agentが動いているddl-controllerマシンでDDLを実行し、SQL Server に適用
    • 適用履歴もSQL Serverのテーブルで管理して同じDDLが2重適用されないように制御
    • 適用結果(実行ログ)はAmazon S3にアップロード
    • Lambdaでログの中身をチェックして、適用結果をSlackに通知

工夫点、注意点

tsqllintでDDLの構文チェック

データベースの定義変更なので、注意深く実施する必要があります。また、実際に定義を適用してみたらエラーになった、となると手戻りが発生して面倒です。
そこで、linterを導入しようと考えました。調べてみるとSQL ServerのT-SQL (Transact-SQL)の構文がチェックできる tsqllintというツールがありました。 動作確認してみたところ、きちんと動作するし、lintのルールのカスタマイズもできるのでこれを採用しました。
そして、これを利用した簡単なNode.jsのスクリプトを書き、Appveyor上で動かして、構文チェックを実行するようにしました。チェックが通らなければ、Pull Requestをマージできないようにします。

※ちなみに、tsqllintはVS Codeの拡張もあるようです。SQL Serverの管理などでT-SQLに触れる機会が多い方には便利かもしれません。

linterでチェックできない点はレビューでチェック

ファイルグループの指定が正しいか、などlinterのチェックだけでは検出できない重要な点があります。 このような点についてはPull Requestのテンプレートにチェック項目を書き出し、Pull Requestの作成者とレビューワーの双方がチェックする、という運用ルールにしました。もちろん、レビューワーのApproveがなければ、Pull Requestはマージできません。 機械的なチェックではないので、多少の不安はありますが、今のところうまくいっています。

インターネットに出れないEC2インスタンスでCodeDeploy Agentを動かすにはプロキシが必要

これは、注意点なのですが、データベースが置かれているネットワークは、インターネットには接続できないようになっているのが一般的です。
一方でCodeDeploy Agentが正常に動作するためには、外向きHTTPSの通信ができることが必須です。
CodeDeploy Agentが外部のAPIを定期的にコールしてデプロイを実行する必要があるかどうか確認しているからです。
この場合、CodeDeploy Agentの構成ファイルに外向き通信をプロキシするためのプロキシサーバのURLを設定する必要があります。
当社では、外向きの通信ができるネットワークにApacheでプロキシサーバを立て、そのURLをCodeDeploy Agentの構成ファイルに設定しました。

Apacheの設定は以下の通りです。

Listen *:8088
<VirtualHost *:8088>
  ProxyRequests on
  AddDefaultCharset off
  AllowCONNECT 443
  <Proxy codedeploy-commands.ap-northeast-1.amazonaws.com>
      <LimitExcept CONNECT>
         Order deny,allow
         Deny from all
        # ↓ CodeDeploy Agent が動いているマシンのIP
         Allow from xx.xx.xx.xx 
      </LimitExcept>
  </Proxy>
</VirtualHost>

CodeDeploy側は、conf.ymlを次のように修正します。
Windowsの場合、 C:\ProgramData\Amazon\CodeDeploy\conf.yml にあります。

---
:log_dir: 'Amazon/CodeDeploy/log'
:root_dir: 'Amazon/CodeDeploy'
:verbose: true
:wait_between_runs: 1
:wait_after_error: 1
:bundle_name: 'artifact_bundle.tar'
:proxy_uri: http://xx.xx.xx.xx:8088 # ここにプロキシサーバのIPを記述

これで、CodeDeploy Agentを再起動すれば正常に動くようになります。

※ 環境によってはセキュリティグループなどネットワークレイヤの調整も必要です。

終わりに

長年、手動でやっていたものを自動化して、果たしてうまく運用が回るか、心配はありましたが、しっかりと運用に乗りました。
データベースをクラウドに移行したという前提条件とアプリケーションのCI/CDの構築経験の応用が実現のキーポイントだったと思います。

※データベースのクラウド移行については、当ブログに詳細な記事がありますので、ご覧ください。

user-first.ikyu.co.jp

user-first.ikyu.co.jp

この記事の筆者について

  • システム本部CTO室所属の 徳武 です。
  • サービスの技術基盤の開発運用、宿泊サービスの開発支援を行なっています。