Amazon RDS/Auroraをクローンするシステムを作った話

こんにちは、技術部SRグループの菅原です。

最近、Ninja650からNinja1000に乗り換えました。パワーがあるせいで3速発進・4速発進が平気でできてしまい、シフトワークがどんどん下手になっています。精進したいものです。

この記事では、Amazon RDS/Auroraをクローンするシステムを作った話を書きます。

Amazon RDS/Auroraをクローンするシステム

サービス開発を行っていると、調査や検証でプロダクション環境で使われているデータベースが必要になることがあります。開発環境やステージング環境にもデータベースは存在するのですが、プロダクション環境のデータでしか再現しないバグの調査や、プロダクション環境のデータ量でのスキーマ変更の負荷の検証など、開発環境やステージング環境のデータベースではできない作業も多いです。しかし、オペレーションミスや個人情報へのアクセスを考えると、プロダクション環境のデータベースで直接作業をすることは大きなリスクを伴います。

Amazon Auroraのクローン作成機能を使うと、プロダクション環境に影響を及ぼさないクローンを作成できるのですが、個人情報にアクセスできてしまう点は解決できません。また、クローンの作成や削除には強力なIAMの権限が必要なため、管理者がクローンを作成して利用者に渡すような手間が発生していました。

そこで、それらの問題を解決し、開発者が手軽にプロダクション環境のデータベースを触れるように、Amazon RDS/Auroraをクローンするシステムを作成しました。

クローン作成の手順は以下の通りです。

  1. SlackでRubotyに対して @ruboty rds clone db-cluster:my-cluster db.t3.small 4h というコマンドを送る
    • 普段からChatOpsでデプロイが行われていること、作成したクローンDBの情報を共有しやすいことなどからインターフェースとしてSlackを利用しました
  2. RubotyがBarbequeのジョブを起動する
  3. Barbequeのジョブがクローンを作成する
    • Auroraの場合はクローン作成機能、RDSの場合はスナップショットから復元
  4. クローンDBのマスターユーザーのパスワードを変更する
  5. クローンDBのデータをマスキングする
  6. セキュリティグループを変更して、社内ネットワークからクローンDBにアクセスできるようにする

f:id:winebarrel:20200819092303p:plain

f:id:winebarrel:20200819092422p:plain

データのマスキングには同僚の@mozamimyが作ったDumptruckという社内ツールを利用しており、以下のようなJsonnetの設定ファイルに従ってデータをマスキングします。

{
  database: 'db_name',
  except: ['secure_%'], // `secure_`プリフィックスのテーブルはクローンDBにコピーしない
  rules: [
    {
      table: 'users',
      transforms: [
        {
          column: 'tel',
          value: "lpad(id, 12, '0')", // SQLでデータをマスキング
          inline_sql: true,
        },
        {
          column: 'email',
          value: "concat(id, '@example.com')",
          inline_sql: true,
        },
      ],
    },
  ],
}

作成したクローンDBは、利用後に開発者が自分で削除するか、利用期限が切れるとバッチ処理が自動的にクローンDBを削除します。

f:id:winebarrel:20200819092447p:plain

開発者が自分でDBの削除やパラメータの変更を行えるようにするため、クラスタIDやインスタンスIDには rcc- というプレフィックスを付け、IAMの対象リソースをrcc-*とした権限を開発者に付与しています。

まとめ

Amazon RDS/Auroraのクローンが手軽にできるようになったことにより、プロダクション環境のデータの調査や、データベースのパフォーマンスの検証がはかどるようになりました。また、データのマスキングを設定ファイルで管理することにより、どのカラムに秘匿情報が入っているかもわかりやすくなったと思います。プロダクション環境のデータベースを使った作業は管理者やSREに作業が集中しがちなので、このような形でなるべく開発者に権限を委譲していきたいです。

/* */ @import "/css/theme/report/report.css"; /* */ /* */ body{ background-image: url('https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527163350.png'); background-repeat: repeat-x; background-color:transparent; background-attachment: scroll; background-position: left top;} /* */ body{ border-top: 3px solid orange; color: #3c3c3c; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; line-height: 1.8; font-size: 16px; } a { text-decoration: underline; color: #693e1c; } a:hover { color: #80400e; text-decoration: underline; } .entry-title a{ color: rgb(176, 108, 28); cursor: auto; display: inline; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; font-size: 30px; font-weight: bold; height: auto; line-height: 40.5px; text-decoration: underline solid rgb(176, 108, 28); width: auto; line-height: 1.35; } .date a { color: #9b8b6c; font-size: 14px; text-decoration: none; font-weight: normal; } .urllist-title-link { font-size: 14px; } /* Recent Entries */ .recent-entries a{ color: #693e1c; } .recent-entries a:visited { color: #4d2200; text-decoration: none; } .hatena-module-recent-entries li { padding-bottom: 8px; border-bottom-width: 0px; } /*Widget*/ .hatena-module-body li { list-style-type: circle; } .hatena-module-body a{ text-decoration: none; } .hatena-module-body a:hover{ text-decoration: underline; } /* Widget name */ .hatena-module-title, .hatena-module-title a{ color: #b06c1c; margin-top: 20px; margin-bottom: 7px; } /* work frame*/ #container { width: 970px; text-align: center; margin: 0 auto; background: transparent; padding: 0 30px; } #wrapper { float: left; overflow: hidden; width: 660px; } #box2 { width: 240px; float: right; font-size: 14px; word-wrap: break-word; } /*#blog-title-inner{*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-position: left 0px;*/ /*}*/ /*.header-image-only #blog-title-inner {*/ /*background-repeat: no-repeat;*/ /*position: relative;*/ /*height: 200px;*/ /*display: none;*/ /*}*/ /*#blog-title {*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-image: url('https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527172848.png');*/ /*background-repeat: no-repeat;*/ /*background-position: left 0px;*/ /*}*/