開発中の機能
GitOpsモード(仮称)

GitOpsモード(仮称)

⚠️

この機能は現在開発中であり、まだ公開されていません。記載内容は今後変更される可能性があります。

GitOpsモードは、各環境のバージョンと有効・無効を、その環境に対応するブランチの設定ファイルだけで決めるプロジェクトの設定です。新しいコマンドbm applyで、設定ファイルの内容を環境ごとに反映します。

開発環境を経由してほかの環境へコピーするbm syncとは違い、bm applyは設定ファイルから指定した環境へ直接反映します。QA中の変更が開発環境に入っていても、本番環境には出ません。

反映したバージョンには、GitのコミットSHAなどの名前をつけられます。どの環境がどのバージョンを使っているかは、バージョン/有効化設定の画面で確認できます。切り戻しは、Gitでrevertしてbm applyで反映し直すだけです。

featureブランチを検証環境でQAし、終わったものから本番環境用のブランチへ直接マージする運用を想定しています。

プレビュー期間中は、プロジェクトをこのモードにする設定をベースマキナ側で行います。

解決したい課題

設定ファイルを読んでも、各環境の状態がわからない

Terraformのようなツールに慣れていると、設定ファイルに書いた内容がそのまま環境の状態になる、と考えるのが自然です。ブランチを見れば、そのブランチに対応する環境で何が動いているかがわかり、planで差分を確かめてからapplyで反映します。

今のコード管理はこの考え方になっていません。設定ファイルを直接反映できるのは開発環境だけで、検証環境や本番環境の状態は、bm syncを実行した時点の開発環境のバージョンをコピーしたものです。本番環境用のブランチがあっても、その設定ファイルは本番環境の状態を表しません。画面からの変更も受けつけるため、設定ファイルとずれることもあります。

以降の課題は、どれもこのずれから生じています。GitOpsモードでは、各環境の状態を、その環境に対応するブランチの設定ファイルと一致させます。bm apply --dryがplanに、bm applyがapplyにあたります。

QA中の変更が本番環境に出てしまう

mainを本番環境用のブランチとし、featureブランチごとにQAして、終わったものからmainへマージする運用を考えます。今のbm syncでは、設定ファイルを直接反映できるのは開発環境だけです。そのため、QAではfeatureブランチの設定ファイルを開発環境へ反映することになります。

問題は、mainにマージしたあとの本番環境への同期です。bm sync <本番環境のID>はmainの設定ファイルではなく、開発環境が今使っているバージョンを本番環境へコピーします。開発環境に別のfeatureのQA中の変更が入っていれば、まだmainにマージしていないその変更も本番環境に出ます。

developmentActionsで同期から外す手はありますが、この運用ではうまく使えません。同期から外れるのは、同期を実行するブランチ、つまりmainの設定ファイルでdevelopmentActionsに入っているアクションだけです。featureブランチのなかで指定しても、本番環境への同期には影響しません。QAを始める前に、対象のアクションをdevelopmentActionsへ移すだけのPRを先にmainへマージしておく必要があります。

同じアクションを2つのfeatureが並行して変えている場合は、この回避策も使えません。開発環境のバージョンは1つなので、両方の変更が入ったバージョンしかなく、先にQAが終わったほうだけを本番環境に出す手段がありません。

本番環境に出したあとで、戻したり直したりしにくい

リリースを切り戻すには、バージョン/有効化設定の画面で、アクションを1つずつ前のバージョンに戻します。Gitの内容は戻らないので、次の同期で同じ変更がまた出ないよう、別途revertも必要です。切り戻したいリリースのあとに別のPRをマージしていると、さらに手間が増えます。あとのPRの変更を残すには、そのPRが触ったアクションを見分けて、アクションごとに戻す先のバージョンを選ばなければなりません。

本番環境だけを急いで直す場合は、画面でアクションを直接編集します。編集したアクションはWeb管理に戻り、Gitの内容とずれます。同じ修正を設定ファイルにも入れておかないと、次の同期で修正が上書きされます。

今後追加予定の機能では、この課題に対してbm rollbackとbm hotfixを構想していました。GitOpsモードはこれに代わるもので、どちらもGitの操作とbm applyだけで済むようにします。

本番環境で動いている内容とコミットを結びつけられない

バージョンの名前は作成日時です。本番環境で動いているのがどのコミットの内容かを知るには、同期した時刻をCIのログなどで調べ、そのときのコミットを人が探します。

開発環境での変更がほかの環境に伝わる

バージョンの指定が「常に最新」の環境は、開発環境に新しいバージョンができた時点で動作が変わります。bm syncを実行していなくても変わるので、防ぐには--pin-versionでバージョンを固定しておく必要があります。

今のbm syncとの違い

このモードでは、環境ごとのバージョンをbm applyでしか変えません。やりたいことごとの違いは次のとおりです。

やりたいこと今(bm sync)GitOpsモード
feature を検証環境で QA し、終わったものから本番環境へ出す本番環境へのコピーに QA 中の変更が含まれる。防ぐには、QA の前に対象をdevelopmentActionsへ移す PR が必要本番環境用のブランチを本番環境にbm applyするだけ。マージしていない変更は出ない
同じアクションを触る feature を並行して QA し、先に終わったほうだけを出す開発環境のバージョンに両方の変更が入っているので、片方だけを出せないマージした feature の内容だけが出る
main、stg、prdと一直線に昇格させる--fromと--pin-versionをつけて環境間でコピーし、動作確認前のアクションはdevelopmentActionsで除外する各ブランチをその環境にbm applyする。developmentActionsはそのまま使える
リリースを切り戻す画面のバージョン/有効化設定でアクションを1つずつ戻す。Git は戻らないrevert してbm applyする
あとに別の PR をマージしたリリースを切り戻すアクションごとに戻す先のバージョンを人が選ぶrevert した PR の変更だけが戻り、あとの PR の変更は残る
本番環境だけで緊急修正する画面でアクションを直接直す。そのアクションは Web 管理になり、Git の内容とずれる本番環境用のブランチに修正をマージしてbm applyする
本番環境でどのコミットの内容が動いているかを確かめるバージョンの名前は作成日時なので、コミットとの対応は CI のログなどから人が追うバージョンの名前がコミット SHA なので、画面でそのままわかる
開発環境で変更を試しているあいだ、ほかの環境を動かさない「常に最新」の環境は、開発環境に新しいバージョンができた時点で動作が変わる。防ぐには--pin-versionが必要ほかの環境は、その環境にbm applyしたときしか変わらない
本番環境からアクションを外す--with-disableをつけて同期するか、画面の有効化設定で無効にする設定ファイルから消してbm applyする

モードをONにしたプロジェクトでは、コード管理のアクション・ビューを画面から編集・削除したり、環境ごとのバージョンや有効・無効を切り替えたりできなくなります。bm syncも使えません。Web管理のアクション・ビューは、モードがONでも今までどおり画面で作成・編集できます。モードがOFFのプロジェクトは何も変わりません。

仕様

環境への反映

bm apply <環境ID>は、設定ファイルの内容を指定した環境に反映します。どの環境でも同じコマンドで反映し、反映元の環境はありません。

アクションとビューごとに、設定ファイルの内容と、反映先の環境が今使っているバージョンの内容を比べます。同じなら何もしません。違えば新しいバージョンを作り、その環境をそのバージョンに固定します。ほかの環境のバージョンは動きません。開発環境に反映したときも同じです。

# 反映する差分を確認する(何も変更しない)
bm apply <環境ID> --dry
 
# 設定ファイルの内容を環境に反映する
bm apply <環境ID>
 
# バージョンの名前を指定して反映する
bm apply <環境ID> --ref <名前>

反映先の環境にまだ存在しないアクションは反映できず、エラーになります。新しいアクションは、先に開発環境へ反映して作ります。

バージョンの名前

--refで、反映で作るバージョンの名前を指定します。省略すると、実行中のコミットのSHAが名前になります。CIでは環境変数GITHUB_SHA、CI_COMMIT_SHAの順に読み、どちらもなければgit rev-parse HEADの結果を使います。ローカルで--refを指定せずに実行したとき、未コミットの変更があるとエラーになります。

同じアクションに同じ名前のバージョンがすでにあり、内容も同じなら、新しく作らずにそのバージョンへ固定します。同じコミットを検証環境と本番環境に順に出すと、両方の環境が同じバージョンを使います。CIを再実行してもバージョンは増えません。同じ名前で内容が違うときはエラーになります。

有効と無効

反映する設定ファイルにあるアクション・ビューは有効になり、コード管理のもののうち設定ファイルにないものは無効になります。bm sync --with-disableを常につけたときと同じ扱いで、無効にしたものは削除されず、設定ファイルに戻してbm applyすると再び有効になります。

developmentActionsとdevelopmentViewsは、開発環境に反映するときはactions・viewsと同じに扱い、ほかの環境に反映するときはないものとして扱います。

画面でできること

モードがONのプロジェクトでは、コード管理のアクション・ビューの編集、削除、環境ごとのバージョンや有効・無効の切り替えを画面からできません。バージョン/有効化設定の画面は、各環境が使っているバージョンの名前と有効・無効を表示するだけになります。

Web管理のアクション・ビューは、モードがONでも今までどおり画面で作成・編集でき、環境ごとのバージョンや有効・無効も切り替えられます。Web管理のものを設定ファイルに書いてbm applyすると、bm syncと同じくコード管理に移ります。

全環境で共有する設定

アクションの設定には、バージョンに保存されるものと、保存されないものがあります。バージョンに保存されるのは、名前、パラメーター、データソースと処理の内容です。識別子、説明、ジョブ実行を優先的に表示する設定、権限設定、レビュー設定はバージョンに含まれず、アクションごとに1つの値を全環境で共有しています。レビュー設定の環境ごとの承認後の自動実行は環境ごとに値を持ちますが、これもバージョンには含まれず、設定ファイルから書き込むと全環境ぶんがまとめて置き換わります。

そのため、共有する設定はバージョンの切り替えで段階的に出せません。どの環境への反映で書き込んでも、その時点で本番環境を含むすべての環境の値が変わります。検証環境で実行権限の変更を試すと、本番環境の実行権限も同時に変わります。

今のbm syncでは、開発環境への反映でこれらを書き込み、ほかの環境への同期ではコピーしません。開発環境用のブランチにマージした時点で、本番環境の権限やレビュー設定も変わります。

GitOpsモードのbm applyは、--with-shared(仮称)をつけたときだけ共有する設定を書き込みます。つけたときは、設定ファイルの内容と今の値を比べ、差分を表示してから書き込みます。つけないときは、開発環境への反映でも書き込まず、比較も差分の表示もしません。

# 共有する設定も含めて反映する
bm apply <環境ID> --with-shared

--with-sharedをつけるのは、1つのブランチの反映だけにします。複数のブランチの反映でつけると、ブランチごとに設定ファイルの内容が違う場合、反映のたびに値が行き来します。本番環境用のブランチの反映につければ、共有する設定の変更はリリースと同時に出ます。開発環境用のブランチの反映につければ、今のbm syncと同じ動きになります。

コード取得設定を使うビュー

コード取得設定を使うビューは、バージョンを持たないためbm applyの対象外で、扱いは今までと変わりません。

モードの切り替え

モードのONとOFFは、開発設定のコード管理の欄で切り替えます。OFFに戻すと、画面からの編集や環境ごとのバージョンの切り替えを再びできます。各環境は、反映したバージョンに固定されたまま残ります。

運用パターン

CIでbm applyを実行する構成の例は、GitHub Actions用のbm-actionの対応を含めて、公開時に改めて掲載します。ここではbm applyのコマンドで流れを示します。

feature ブランチを検証環境で QA してから本番環境に出す

mainを本番環境用のブランチとする運用です。featureブランチを検証環境に反映してQAし、終わったものからmainにマージして本番環境に反映します。

並行してQAしている別のfeatureは、mainにマージされるまで本番環境に出ません。bm applyはmainの設定ファイルだけを見るので、本番環境には先にマージした分だけが出ます。

本番環境への反映には--with-sharedをつけます。featureブランチで変えた実行権限やレビュー設定は、mainへのマージ後、本番環境への反映ですべての環境の値が変わります。検証環境への反映では書き込まないので、これらの変更は検証環境で事前に試せません。

新しいアクションを追加するfeatureブランチは、先に開発環境へ反映してアクションを作ってから、検証環境へ反映します。検証環境や本番環境には、まだ存在しないアクションを反映できないためです。

環境ごとにブランチを持って昇格させる

main、stg、prdの3つのブランチで運用する場合は、ブランチへのマージのたびに、そのブランチを対応する環境へbm applyします。mainは開発環境、stgは検証環境、prdは本番環境です。bm syncのように--fromで同期元の環境を指定したり、--pin-versionでバージョンを固定したりする必要はありません。--with-sharedはprdの反映にだけつけます。

同じコミットから反映したバージョンは、検証環境と本番環境で共有されます。developmentActionsは、bm syncのときと同じように使えます。ブランチの構成は実践的な開発フローも参照してください。

検証環境と本番環境で同じバージョンを使う

stgブランチを検証環境、mainブランチを本番環境に反映し、検証環境で確かめた内容をmainに昇格させる運用です。本番環境で、検証環境と同じバージョンをそのまま使いたい場合があります。

2つの環境がバージョンを共有するのは、同じ名前で内容も同じバージョンを反映したときです。名前を省略するとコミットSHAになるので、stgとmainが同じコミットを指していれば共有されます。ただし、GitHubのプルリクエストでstgをmainにマージすると、マージコミット、squash、rebaseのどれでも新しいコミットができ、SHAが変わります。内容は同じでも、本番環境には別の名前のバージョンができ、検証環境で確かめたものと同じかどうかを画面で見分けにくくなります。

同じバージョンを使うには、次のどちらかの方法をとります。

  • mainをstgと同じコミットまで進める: stgにない変更がmainへ入っていなければ、git push origin stg:mainのようにfast-forwardでmainを進めます。新しいコミットができないので、SHAが同じになります
  • --refで名前をそろえる: リリースごとにv1.2.0のような名前を決め、検証環境と本番環境の両方に--ref v1.2.0をつけて反映します
# stg ブランチを検証環境に反映する
bm apply <検証環境のID> --ref v1.2.0
 
# main ブランチを本番環境に反映する
bm apply <本番環境のID> --ref v1.2.0 --with-shared

--refで名前をそろえた場合、本番環境に反映する内容が検証環境で確かめた内容と違うと、同じ名前で内容が違うのでエラーになります。検証環境で確かめていない変更を本番環境へ出さずに済みます。

リリースを切り戻す

問題のあるリリースをrevertしたコミットを、本番環境用のブランチでbm applyします。戻した内容で新しいバージョンができ、その環境に固定されます。revertしたPRのあとにマージした別のPRの変更は残ります。戻すリリースに共有する設定の変更が含まれていれば、--with-sharedをつけて反映すると、その設定も戻ります。

本番環境だけの緊急修正

本番環境用のブランチに修正をマージして、bm applyで本番環境に反映します。特別なコマンドは要りません。どの環境も、対応するブランチの内容とずれません。

本番環境でどのコミットが動いているかを確かめる

バージョン/有効化設定の画面で、本番環境が使っているバージョンの名前を見ます。名前はコミットSHAなので、Gitの履歴とそのまま対応します。