S3バックアッププラグインを横展開して分かったこと
はじめに
WordPress向けに Ozeki Database Backup for S3 を作成した後、同じ考え方をMoodleにも展開してみることにしました。
最初は、
WordPress版で作ったS3バックアップ処理をMoodle向けに移植すればよいのではないか
くらいに考えていました。
しかし、実際に進めてみると、それほど単純ではありませんでした。
確かに共通する部分はあります。
Database backup
↓
compression
↓
S3 upload
↓
verification
AWS SDKを使い、長期Access Keyをアプリケーション内部へ保存せず、IAM RoleなどのCredential Provider Chainを使うという考え方も共通です。
ところがMoodleでは、バックアップ対象そのものの意味がWordPressとはかなり違いました。
今回は、
同じ「S3へバックアップする」という目的でも、対象アプリケーションによって設計はどこまで変わるのか
という観点で整理します。
1. WordPress版では、まずDBバックアップに絞った
WordPress版では、最初の公開機能をかなり限定しました。
対象はMySQL / MariaDBのデータベースです。
WordPress database
↓
mysqldump / mariadb-dump
↓
PHP fallback
↓
gzip
↓
Amazon S3
手動バックアップ、WP-Cronによる自動バックアップ、WP-CLI、retentionなどを追加しましたが、基本的な対象はDBです。
これは意図的でした。
WordPressでは、
DB
uploads
plugins
themes
wp-config.php
など、完全な復旧には複数の資産が必要です。
それでも最初は、
まずDBを安全に外部へ退避できること
に絞りました。
機能を小さくして、認証、dump、S3 upload、retention、公開品質まで一通り完成させることを優先しました。
2. Moodleでは「DBだけ」では話が終わらない
Moodle版を考え始めると、すぐに違いが見えてきました。
Moodleにはコースバックアップがあります。
Moodle自身が、
course
↓
.mbz
というバックアップarchiveを生成できます。
つまり、WordPress版のように「自分で全部バックアップ形式を設計する」のではなく、
Moodle自身がすでに持っているバックアップ機能をどう活用するか
という話になります。
そこでMoodle版では、
Moodle automated course backup
↓
.mbz archive
↓
Secure S3 Storage
↓
Amazon S3
という構成を取りました。
ここで最初の大きな違いが出ました。
WordPress版では、
自分のpluginがdatabase backupを生成する
のが中心でした。
Moodle版では、
Moodle自身が生成した完成済みbackup artifactを安全にS3へ移す
という役割も重要になります。
3. Moodleにはmoodledataがある
さらにMoodleには moodledata があります。
ここには単純な画像ファイルだけではなく、Moodleが管理する各種コンテンツが保存されています。
特に filedir では、コンテンツはcontent-addressed storageとして管理されています。
つまり、
photo.jpg
document.pdf
assignment.docx
のような元のファイル名だけを見てコピーすればよい、という構造ではありません。
Moodle側のDBとfile storageには関係があります。
そのため、
DB dumpだけ取れば復旧できる
とも、
filedirだけコピーすれば復旧できる
とも言えません。
ここで、バックアップを単一ファイルではなく、
recovery set
として考える必要が出てきました。
例えば概念的には、
Recovery Set
├── Database artifact
├── Course backup
├── Content inventory
└── Referenced filedir objects
というまとまりです。
WordPress版にはなかった考え方です。
4. 「ファイルを全部コピーする」だけでは効率が悪い
Moodleの filedir はcontent-addressedです。
同じ内容のファイルであれば、複数の場所から参照されていても、storage上では同じobjectとして扱われることがあります。
これは効率の良い仕組みです。
一方でバックアップ側から見ると、
moodledata/filedirを全部S3へコピー
だけでは、毎回大量のデータを転送することになります。
そこでMoodle版では、
どのcontent objectがそのrecovery setから参照されているのか
を考える方向へ進みました。
つまり、
Database / course state
↓
content inventory
↓
必要なfiledir object
↓
S3
という考え方です。
これは単なるdirectory backupより少し複雑ですが、Moodleのstorage modelに合っています。
5. WordPress版の「Retention」もそのまま持っていかなかった
WordPress版では、バックアップ世代数を指定して古いdatabase backupを削除するRetention機能があります。
例えば、
最新30世代を保持
のような方式です。
Moodle版でも最初は同じ仕組みを使えばよいように見えます。
しかし、recovery setと共有content objectを考え始めると、単純ではありません。
例えば、
Recovery Set A
└── content X
Recovery Set B
└── content X
の両方が同じcontent objectを参照していたとします。
Recovery Set Aが古くなったからといって、
content Xを削除
してしまうと、Recovery Set Bまで壊れる可能性があります。
そこでMoodle版では、少なくとも現在の段階では、
pluginが確認済みremote objectを積極的に削除する
より、
S3 Versioning / Lifecycleを使ってretentionを管理する
方向を選んでいます。
同じ「S3バックアップ」でも、WordPress版とMoodle版でretention戦略が変わったわけです。
6. スケジューリングもMoodle流に合わせる
WordPress版では自動実行にWP-Cronを使っています。
WP-Cron
↓
database backup
↓
S3
MoodleにはMoodle CronとScheduled tasksがあります。
そのためMoodle版では、
Moodle Cron
↓
Scheduled task
↓
backup transfer
という仕組みに合わせます。
重要なのは、
自分で独自schedulerを作らない
ことです。
Moodleには、
- Scheduled tasks
- Adhoc tasks
- Cron
- administration UI
といった仕組みがあります。
アプリケーションが持っている標準機構を使った方が、管理者にとって自然です。
WordPress版でもMoodle版でも、
外部cronを自作する
のではなく、
そのplatformが持っているschedulerへ統合する
という方針は共通しています。
7. 「AWS認証をアプリケーションに保存しない」は共通だった
一方、WordPress版からそのまま持っていけた設計思想もあります。
それがAWS認証です。
WordPress版では、
WordPress
↓
AWS SDK
↓
Default Credential Provider Chain
↓
IAM Role
↓
S3
という構成にしました。
Moodle版でも同じです。
Moodle
↓
AWS SDK
↓
Default Credential Provider Chain
↓
IAM Role / task role / web identity etc.
↓
S3
Moodleの管理画面にも、
Access Key ID
Secret Access Key
を入力する欄は設けていません。
つまり、
アプリケーション内部に長期AWS credentialを保存しない
というsecurity boundaryはそのまま維持しました。
ここはWordPressとMoodleで共通化できる部分でした。
8. しかし「共通化できるから共通ライブラリにする」とはしなかった
WordPress版とMoodle版には、共通する処理がかなりあります。
例えば、
AWS SDK client
S3 upload
checksum
verification
database backup
artifact metadata
です。
最初から共通ライブラリを作ることもできます。
しかし、今回はまだそうしていません。
理由は、
本当に共通しているものが何なのか、2つの実装を通して確認したかった
からです。
最初に抽象化すると、
WordPressで必要だったもの
↓
共通機能だと思う
↓
Moodleでは実は違った
ということが起こります。
実際、Retentionのように、WordPressでは自然でもMoodleではそのまま持っていけないものがありました。
そのため、
まず2つを実際に作る
その後に本当に共通する部分だけを見る
という順番にしています。
これは、思った以上に重要でした。
9. Moodle版ではrestoreまで含めて考える必要が強くなった
WordPress版でも当然、バックアップはrestoreできなければ意味がありません。
ただ、Moodle版ではrecovery setを扱うため、
backupできた
だけでは不十分です。
例えば、
Database
Course archive
Content
がそろっていても、それらの関係が崩れていれば復旧できません。
そこでMoodle版では、CI上で、
backup artifact生成
↓
S3互換storageへ転送
↓
download
↓
別databaseへrestore
↓
内容確認
というrestore gateを強く意識しています。
つまり、
upload成功
ではなく、
復旧可能性を確認する
ところまでrelease条件へ近づけています。
ここも、Moodle版を作る中で強くなった考え方です。
10. WordPress版よりMoodle版の方が先へ進んだ部分もある
少し面白いことに、後から作り始めたMoodle版の方が、一部ではWordPress版より先へ進みました。
現在Moodle版では、
Database
Course backup (.mbz)
Content
を扱う方向へ進んでいます。
一方WordPress版は、現在まだdatabase backupが中心です。
つまり、
WordPress
→ 最初にsecurity / release / publishingを固めた
Moodle
→ その経験を使ってbackup architectureを広げた
という関係になりました。
今後は逆に、
Moodle版で得たcontent backupの知見をWordPress版へ戻す
ことも考えています。
例えばWordPressのuploads/media backupです。
一方向の移植ではなく、
WordPress
↓
Moodle
↓
WordPressへ知見を戻す
という循環になりつつあります。
11. 同じ機能を作るより、同じ原則を持っていく
今回一番大きく感じたのは、
「WordPress版をMoodle版へ移植する」
という考え方より、
WordPress版で得た設計原則をMoodleへ持っていく
という考え方の方が正確だったことです。
共通した原則は、
長期AWS credentialをアプリケーションに保存しない
S3 upload後にverificationする
backupはrestore可能性まで考える
platform標準schedulerを使う
localとremoteの責務を明確にする
release artifactをCIで検証する
などです。
一方、実装はplatformごとに変わります。
WordPress
WP-Cron
WP-CLI
uploads
plugin lifecycle
Moodle
Scheduled tasks
Moodle Cron
course backup
moodledata/filedir
backup/restore APIs
つまり、
原則は再利用する
実装は無理に再利用しない
という形です。
12. S3を「バックアップ先」から「実ストレージ」へ使う話はさらに別
Moodle版を作っていると、
そもそもcontentをS3上で直接運用すればよいのではないか
という話も出てきます。
WordPressでも同様に、
uploads
↓
S3
というoffloadがあります。
さらに静的HTMLを生成して、
WordPress
↓
static HTML
↓
S3
↓
CloudFront
と公開する構成も考えられます。
しかし、これはbackupとは別の段階です。
Backup
→ primary storageはlocal
→ S3は復旧用
Primary S3 storage
→ S3が日常運用のstorage
では責務が大きく違います。
そのためMoodle版でも、S3をprimary content storageとして使う機能は将来フェーズとして明確に分離しています。
まずは、
バックアップと復旧を確実にする
ことを優先しています。
13. 横展開してみることで、最初の設計も見直せる
WordPress版だけを作っていたときには、
database backup
retention
S3
が自然なモデルに見えていました。
Moodleへ展開すると、
course archive
database
content-addressed storage
recovery set
S3 lifecycle
という別の世界が出てきました。
その結果、
WordPress版も将来DBだけではなくmediaやcontentをどう扱うべきか
という次の課題が見えるようになりました。
これは横展開の大きなメリットだと思います。
別platformへ持っていくと、
最初の実装で暗黙に前提としていたもの
が見えるからです。
まとめ
WordPress向けに作ったS3バックアッププラグインをMoodleへ展開するとき、最初はコードの移植を考えていました。
しかし実際には、
WordPress
↓
そのまま移植
↓
Moodle
ではありませんでした。
むしろ、
WordPressで得た設計原則
↓
Moodleの仕組みに合わせて再設計
↓
Moodleで新しい知見
↓
WordPressへ戻す
という流れになりました。
同じ、
S3へ安全にバックアップする
という目的でも、WordPressとMoodleでは、
- バックアップ対象
- scheduler
- file storage
- retention
- recovery
- lifecycle
が違います。
そのため、
同じコードを再利用することより、同じ設計原則を再利用すること
の方が重要でした。
WordPress版:
Moodle版:
WordPress版はWordPress.orgでも公開しています。
Moodle版についてもPlugin Directoryへの公開申請を行っています。
今後は、Moodle版で進めているcontent protectionの考え方をWordPress側のmedia backupへ戻すことも考えています。
一つのpluginを別platformへ展開したことで、単純な横展開ではなく、両方の設計を見直す循環が始まったように感じています。