はじめに
こんにちは。IT基盤部第三グループの田村です。社内システムのインフラを担当しています。
本記事では、社内標準Wikiツールである Confluence (コンフルエンス)を、サーバー版から Atlassian Cloud へ移行した際に工夫したことや苦労したことについてご紹介します。
Confluenceとは
Confluenceとは、アトラシアンが開発・販売している企業向けのWikiツールであり、コラボレーションツールでもあります。DeNAでは、2011年から社内標準Wikiツールとして使用しています。
なぜAtlassian Cloudへ移行することになったのか
2020年10月、アトラシアンから「サーバー版新規ライセンスの販売終了」および「サーバー版サポート終了」が発表されました。( 参考資料 )
2021年2月2日:新規ライセンスの販売終了、サーバー製品機能の開発終了、サーバー製品価格の改定
2024年2月15日:サポート終了
DeNAではサーバー版を利用しており、2024年2月までにクラウド版とデータセンター版(オンプレミス)のどちらかに移行せざるを得ない状況になりました。アトラシアン社としてはクラウド版を推奨とのことでした。
クラウド版とデータセンター版の比較
サーバー版のアクティブユーザー数:3,100、契約ライセンス数:10,000
項目 | クラウド版(Premium) | データセンター版 |
---|---|---|
契約ライセンス数 | 3,100 | 4,000 |
ライセンス費用 | 2,260万円/年 | 2,000万円/年 |
切り替え方法 | 既存スペース(約2,100)を移行 | ライセンス入替えのみ |
日々のメンテナンス | メンテナンス不要 | 自社で行う必要がある |
バージョン | 最新版 | LTS(安定版) |
※ユーザー数、ライセンス数は検討した当時の数
比較すると、インフラ担当としてはデータセンター版のほうが気軽に移行出来て良さそうに見えますが、新機能が充実しているクラウド版はユーザーにとっては魅力的です。 課題管理ツールである JIRA (ジラ)も同様に移行を検討していて、現状のサーバー版ではAdmin権限がないとプロジェクトのカスタム項目やワークフローの設定変更等ができないため、ユーザーがカスタマイズしたい場合はIT戦略部に都度依頼する必要がありました。JIRAクラウド版では「チーム管理対象プロジェクト」を選択すると、ユーザー側でプロジェクトのカスタマイズが可能となるため、JIRAはクラウド版へ移行することになり、JIRAとConfluenceを管理する上で、両方とも同じプラットフォームにあった方が管理しやすいので、Confluenceもクラウド版へ移行することになりました。
移行検証
移行先がクラウド版に決まったので、移行検証を進めていきます。
まずは移行ツールを検証することから始める
数年前に、分社化対応でConfluenceの一部のスペースをAtlassian Cloudへ移行する作業を行なったことがあるのですが、 数個程度のスペース移行でも上手くいかず、とても不安定な移行ツール(Confluence Cloud Migration Assistant)でした。 移行ツールも日々進化してるとはいえ、全スペース(約2,100個)移行というのは、とても過酷な作業になることは容易に想像出来ます。正直完遂出来る気がしませんが、まずはツールの動きや使い方を確認しました。
実際にいくつかのスペースをsandbox環境に移行すると、いろいろな不具合が発生したため、その時どのような対応を行なったかをご紹介します。
・メールアドレスチェック
問題点
上記エラーのほとんどは、メールアドレスなしのアカウントで、Atlassian Cloudではメールアドレスが必須項目なので入ってないとエラーになります。 基本的に従業員のアカウントにはメールアドレスが入っており、メールアドレスが入ってないアカウントはシステムアカウントになります。
解決した方法
移行前にAtlassian Cloudで必要なアカウントを作成しておけば、無視して問題ありません。
・添付ファイルチェック
問題点
何らかの原因で、サーバー上の添付ファイルが破損しているか存在しないのですが、復元は不可能です。
解決した方法
下記オプションでエラーチェックを無視するようにしました。
- dark featureにアクセスします。
https://<confluence-url>/admin/darkfeatures.action - 下記フラグを追加します。
migration-assistant.disable.missing-space-attachments
参考資料: dark feature
・Confluence Cloud Migration Assistantのバージョンチェック
問題点
デフォルトの設定では、最新のConfluence Cloud Migration Assistantでないと移行することが出来ません。しかし、最新版にしたことによって移行時に不具合があり失敗するケースがあります。
解決した方法
特定のバージョンで移行したい場合は、バージョンチェックを外すことが出来ます。
- dark featureにアクセスします。
https://<confluence-url>/admin/darkfeatures.action - 下記フラグを追加します。
migration-assistant.disable.app-outdated-check
DeNAの環境において、どのバージョンが一番適しているかを見つけるため、新しい順に6個程度のバージョンで移行検証を行いました。
バージョン | 検証結果 |
---|---|
3.3.2以降 | ユーザー・グループチェックに時間がかかるようになった |
3.3.1 | 添付ファイルとスペースデータを分けて移行出来るようになった |
3.2.9 | ユーザー・グループチェックは最短で、移行の成功確率もかなり高い |
このことから、添付ファイルのみを移行する場合は最新版で実施し、スペースデータは ver3.2.9で行うとスムーズに移行できることがわかりました。
注意事項:2023年1月31日以降、Confluence Cloud Migration Assistant 3.3.6以前のバージョンは使用出来なくなります。
参考資料:
Confluence Cloud Migration Assistant Version history
移行時間の測定
移行スケジュールを作成するにあたり、各スペースを移行するのにどれくらい時間がかかるかを測定します。
スペースによって、ページ数や添付ファイル数、添付ファイルサイズが異なります。
移行ツールの処理の流れは、Cloudへ添付ファイルアップロード → スペースのエクスポート → Cloudへデータアップロード → Cloudへインポート の順に行われます。
サンプリングとして100スペースほどを選んでSandbox環境へ移行して、それぞれの処理にどれくらいかかったかを測定してみましたが、並列処理の部分があったり、クラウド側の負荷具合が影響して規則性を見つけることが出来ませんでした。 次に着目したのは、移行ツールの設定画面に表示される、スペースごとの移行推定時間です。この時間と実際の移行時間がどれくらい違うか比較してみたところ、移行推定時間と比べておよそ2割減の時間で移行出来ることが確認できました。
添付ファイルは、本番移行前にクラウドへ転送しておくことが可能です。それにより本番移行の時間を短縮することが出来ます。 全ての添付ファイルの転送は13日かかりました。
これで、全体の移行時間が見えてきました。
移行準備
移行中、ページの編集が不可になることの業務影響を最小限にする必要があります。まずは要件の洗い出しを行いしました。
- 個人スペースは、ユーザとの紐付けなどの問題があり、また業務関連も少ないので、最初に移行を完了すること。
- 長期間にわたって移行作業が続くので、1日あたりの移行作業時間は9時間になるようにスケジューリングする。
- 直近で更新しているスペースは夜間に行うこと。
- 直近で更新されていないものは、日中帯に行っても問題ない。
- 添付ファイルを事前にアップロードしておくことで、本番移行時は差分チェックと不足してる添付ファイルのアップロードのみを行い、移行時間を短縮することができる。
移行スケジュール
これらを踏まえて、移行する順番は下記のようにしました。
時期 | 対象 | 期間 |
---|---|---|
移行開始日の3週間前 | 添付ファイルのみ | 13日間 |
移行開始日の1週間前 | 添付ファイルのみ(差分更新) | 3日間 |
移行初日(土曜) | 個人スペース全て | 2日間 |
平日20時から | 直近3ヶ月以内に更新があったスペース | 4週間 |
最後の2日間 | 3ヶ月以上更新がなかったスペース | 2日間 |
移行スケジュールの案内
各スペースの移行スケジュールについて、事前にユーザーへ告知しましたが、1ヶ月間に渡って移行作業を進めるため、忘れてしまう可能性があります。 移行日を忘れないようにするための施策と、移行が完了したことを知らせる施策を紹介します。
・移行スケジュールのダッシュボード
Confluenceのヘッダー部分に「移行スケジュールはこちら」というリンクを追加して、リンク先へ飛ぶと今日の移行予定のスペース名が表示されたり、現在のステータス(移行前、移行中、移行完了)が表示されるダッシュボードを作成しました。
・移行後サーバー版ページ
スペースの共通ヘッダーに、「このスペースはAtlassian Cloudへ移行しました。」の文言とクラウドのURLを表示し、移行が完了してることを分かりやすく伝えました。
スペースヘッダーの一括変更は、DB updateのクエリとキャッシュクリアで可能です。
クエリ (MySQL)
update BANDANA set BANDANAVALUE=REPLACE(BANDANAVALUE, "<header>", "<header>h2. ■■■ お知らせ ■■■\\\\このスペースはAtlassi
an Cloudへ移行しました。\\\\ [https://<sub-domain>.atlassian.net/wiki/spaces/SPACEKEY/overview] 
Cloud版の同じページに飛ぶには、ページ上部の「Cloud版のページはこちら / Click here for the Cloud version」をクリックして
ください。
----
")
where BANDANACONTEXT='SPACEKEY' and BANDANAKEY='com.atlassian.core.CustomPageSettings';
※SPACEKEY名とCloudのサブドメイン部分の修正が必要。
キャッシュクリア
DBをupdateしただけでは反映されないため、管理画面の「キャッシュ管理」を開き、Settings (Persistence)をフラッシュすると画面に反映されます。
移行作業はつつがなく終わりました
移行したデータ
項目 | 値 |
---|---|
スペース数 | 2140 (内 personal space 1269、site space 871) |
ページ数 | 51万4000ページ |
添付ファイル数 | 215万個 |
添付ファイルサイズ | 1.22TB |
以上の通り準備を整えて粛々と作業を進め、無事全てのスペース(約2,100個)を計画通り移行しました。
URLをリダイレクトする
移行はできたわけですが、さまざまなリソースには以前のConfluenceのページURLのリンクが大量に書かれています。これらのリンクをクリックすると移行前のサーバーに行ってしまいます。この問題は検証作業を進めている時から気づいていて、移行作業と並行して解決策を準備していました。
スペースキーとタイトルを使って新旧のマッピングテーブルを作る
サーバー版のページIDとクラウド版のページIDのマッピングテーブルを用意すればリダイレクトさせることができます。しかし、移行しないことには移行先のクラウド版のページIDが決まりません。またページIDという番号だけでは新しい移行先のIDを特定することはできません。ふとドキュメントを作成してる時に、ページをコピーした際、スペース内で同じタイトル名は作成出来ないことに気づきました。「もしかして今開いてるページのタイトル名とスペースキーが取得できれば、APIでその2つ値を元にCloud版のページURLが取得できるのではないか」と思いつきました。これが結果としてうまくいきました。 そのアーキテクチャとスクリプトは下図の通りです。 実際に使ったスクリプトコードの一部も紹介します。
①カスタムHTML HEADで、今開いているページのタイトル名(page-title)とスペースキー(space-key)を取得し、バックグラウンドで動いているアプリに渡します。
②アプリは2つの引数を元にAPIをコールします。使用するAPIは
GET /wiki/rest/api/content
です。
③URLを取得します。
④URLをJavaScriptに返します。
⑤クラウドのURLへリダイレクトします。
スクリプト
カスタムHTML HEAD部分
<script type="text/javascript" >
async function createDynamicURL(){
var title = AJS.Meta.get("page-title");
var space_key = AJS.Meta.get("space-key");
var url = 'https://<sub-domain>.atlassian.net/wiki';
var request_url = 'https://'+location.hostname+'/cloudapi/rest/api';
if (title === undefined || space_key === undefined ) {
window.open('https://<sub-domain>.atlassian.net/wiki/home','_self');
} else {
var reqdata = JSON.stringify({
title: title,
spacekey: space_key
});
var result_data;
await AJS.$.ajax({
type: 'post',
url: request_url,
dataType: 'json',
contentType: 'application/json',
data: reqdata,
headers: {
"Accept": "application/json",
}
}).done(function(data) {
console.log(data)
result_data = data;
}).fail(function() {
alert('エラーが発生しました');
}).always(function() {
console.log('complete');
});
console.log(result_data)
if (result_data.count == 0) {
alert('Cloud版にページがありません!別のスペースに移動されたか、タイトル名が変わった可能性があります。');
}
url = url + result_data.url
window.open(url,'_self');
}
}
</script>
カスタムHTML BODYの部分
<a href="javascript:createDynamicURL();">Cloud版のページはこちら / Click here for the Cloud version</a>
GO言語で作成したURL取得スクリプト(一部)
// Post Data
r.POST("/cloudapi/rest/api", func(c *gin.Context) {
reqdata := BodyResp{}
if errA := c.ShouldBind(&reqdata); errA != nil {
c.String(http.StatusNotFound, `the body should be Json`)
}
// =================================
api, err := goconfluence.NewAPI("https://<sub-domain>.atlassian.net/wiki/rest/api", "admin-user", "admin-token")
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"Error": "Request failed"})
}
query := goconfluence.SearchQuery{
CQL: "space='" + reqdata.SpaceKey + "'+and+title='" + reqdata.Title + "'",
}
result, err := api.Search(query)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"Error": err.Error()})
}
if len(result.Results) == 0 {
c.JSON(http.StatusOK, gin.H{"count": len(result.Results)})
} else {
c.JSON(http.StatusOK, gin.H{"count": len(result.Results), "title": result.Results[0].Title, "url": result.Results[0].URL})
}
})
※ <sub-domain>
の部分は修正が必要です。
移行後の問題点
移行後にいくつかユーザーから問い合わせや要望が寄せられました。そのいくつかを紹介します。
ページ表示が遅い
移行後ページの表示が遅くなったというクレームを多くの方から戴きました。アトラシアン社も重大な課題と認識していて、アプリケーションレベルやホスティング環境レベルでの改善プロジェクトを複数立ち上げて取り組みを進めている状況とのことです。
スペース単位のCSSが利用できない
スペース単位のCSSが使用出来きなくなったので、ページが見にくくなったというクレームも多く戴きました。こちらについてはテーマの購入を検討しています。
おわりに
およそ1年にわたって、クラウド移行プロジェクトを進める中で、多くの課題に直面し、1つ1つ解決して無事完遂することが出来ました。
これからAtlassian Cloudへ移行予定の企業様に参考になれば幸いです。
最後まで読んでいただき、ありがとうございます!
この記事をシェアしていただける方はこちらからお願いします。