TerraformでGitHubのチーム管理を自動化して事故った話


はじめまして。
ICTトラブルシューティングコンテストの実行委員をやっている黒崎 (@kuro_m88) です。
学生時代に第3回の運営をやり、社会人になってからは運営学生のサポートをしています。

ICTトラブルシューティングコンテスト(以下ICTSC)とは、学生による、学生のためのインフラ技術コンテストです。
来月の2016年8月27日 にNTT西日本杯 第6回 ICTトラブルシューティングコンテストが大阪で開催されます。
トラコンに関する過去のツチノコエントリーは以下をご参照ください。

ツチノコブログICTSCエントリ集

TerraformでGitHubのチーム管理を自動化してみた

ICTSCでは出題に利用するコードや出題する問題案の管理をGitHubを利用して行っています。
https://github.com/ictsc

ICTSCに携わる学生や社会人は基本的にこのGitHub Organizationに入っているのですが、回によって運営に携わる学生も違います。
第4回だけ運営だった人もいれば、第4回, 第5回は運営だったけど、第6回は競技者として参加するといったケースもあります。

ICTSCのGitHub Organizationに入っている人は今回で50人くらいになるので、誰が第何回の運営だったかぱっと把握するのが難しくなってきました。

一番簡単なのはその回の運営に関係ない人をOrganizationからはずすことなのですが、せっかく運営に関わってくれたのにはずすのも寂しいなと思い、ユーザ管理をある程度自動化できないかなと思い立った訳です。(課金体系が変わったら運用方法を考えないといけませんが…)

Terraform GitHub Provider

その頃会社でTerraformを使い始めたので、GitHubも同じような感じで管理できないかなー?と調べてみると…!

なんと、Terraform GitHub Providerがあるではないですか…!🎉
https://www.terraform.io/docs/providers/github/index.html

これを使えばGitHubのOrganizationの

  • メンバー管理
  • チーム管理
  • チームのメンバー管理
  • リポジトリの権限管理

ができるようです。やりたい操作が全部用意されていました!!

ドキュメントを読みながら、こんな感じのものを作ってみました。
https://github.com/ictsc/ictsc-github-member

簡単に説明しますと、まずICTSCのGitHub Organizationのメンバーをここで定義します。
ictsc-github-member/members.tf

次に、チームを作ります。例えば第6回の運営参加メンバーはICTSC6というチームに所属させます。
また、そのチームが読み書きできるリポジトリも定義しています。
ictsc-github-member/team-ictsc6.tf

過去の運営チーム(ICTSC5等)のチームはプライベートリポジトリを見られないようにしています。
ictsc-github-member/team-ictsc5.tf

最後にこれらの操作をCircle CIで自動化できるようにします。
こんな感じの設定ファイルを書きました。
ictsc-github-member/circle.yml

運用方法

ICTSCのチームメンバに追加して欲しい人はプルリクエストを投げます。
https://github.com/ictsc/ictsc-github-member/pull/40

(ちなみに、彼は第5回の運営委員で、第6回は運営ではなく競技者として参加するのでこのプルリクエストは拒否します)

このリポジトリはpublicですが、マージする権限があるのは実行委員(社会人サポートチーム)の人だけなので、レビューののち production ブランチにマージするとCircleCI上でterraform applyが走り記述したとおりの権限がメンバーに与えられます👍

いい感じですね!👏

事故は突然に

github_membership.membership_for_kurochanという名前が冗長に感じたのでmembership_for_を取り払ってgithub_membership.kurochanのような書き方に統一したくなったので統一しました。

terraform planで変更内容を確認して、terraform applyしてみました。以下がその時のログです。

$ ~/terraform/terraform apply --var-file=conf/github.tfvars
github_membership.membership_for_kurochan: Refreshing state... (ID: ictsc:kurochan)
github_membership.membership_for_kurochan: Destroying...
github_membership.netmarkjp: Creating...
role: "" → "admin"
username: "" → "netmarkjp"
github_membership.kurochan: Creating...
role: "" → "admin"
username: "" → "kurochan"
github_membership.membership_for_kyontan: Destruction complete
github_membership.membership_for_kurochan: Destruction complete
github_membership.netmarkjp: Creation complete
github_membership.kurochan: Creation complete

コマンドの実行も成功し、当時管理者権限を持っていた僕ともう一名のアカウント設定の名前が、変更されています。
うんうん、ちゃんとうまく行ったようです。

ひととおり仕組みを作ったので学生に自慢しようと思った矢先、GitHubから一通の不穏なメールが…😨

!?!?

誰かに僕のアカウントの管理者権限が外されたようです。

せっかくterraformで管理しているのでもう一度terraform applyしてみましょう。

2 error(s) occurred:

* github_membership.netmarkjp: PUT https://api.github.com/orgs/ictsc/memberships/netmarkjp: 403 You must be an admin to add or update an organization membership. []
* github_membership.kurochan: PUT https://api.github.com/orgs/ictsc/memberships/kurochan: 403 You must be an admin to add or update an organization membership. []

Terraform does not automatically rollback in the face of errors.

403 You must be an admin to add or update an organization membership.

🔥🔥なんかやばそう!!🔥🔥

とりあえずもう一人の管理者権限を持っている方に僕を管理者に戻すようにお願いしました。

えっ、もうこれはどうしようもないのでは…😇

そしてだれもいなくなった…

管理者権限のあるユーザ全員(自分含め)から権限を剥奪してしまったようです。
誰一人管理者がいない状態なので、復旧のしようがありません。
学生にドヤ顔するつもりがなんと説明すればいいのか分からない状態になりました…。こんなことってあるのか…😱

困ったときの神頼み

どうしようもなくなったので神様(サポート)に連絡するしかありません。
自分の英語力で通じるのか自信なかったですがとりあえず連絡…

すると

よかった…回復してもらえそうです。

どうしてこうなったのか

最初のログを見ると一見成功したように見えます。
ただ、2度目実行した時には権限がなくなっていてエラーになっていたので、APIコールした瞬間はすくなくとも権限を持っていたようです。

ここからは僕の想像なので本当にこうなっていたのか分かりませんが、例えばGitHub側が

こんな感じの権限の更新の処理が非同期に行われる仕組みになっていたとしたらTerraformのように高速でAPIを叩くアプリケーションを実行した場合、今回ような事故が起きそうです。。

対策

Terraformを実行する用のユーザを作成しました。
このユーザに管理者権限をもたせ、このユーザのアカウントに関してはTerraformの管理外としました。
これで自分で自分の権限を剥奪するような事故は起きないはずです。

教訓

terraform planはあくまでも実行計画を表示するだけであって、実際に適用したら成功するかどうかは別の話で保証されないということを身を持って経験しました…。
実行される内容が問題ないかしっかり確認してから適用しましょう。。(以後気をつけます)

さいごに

ICTトラブルシューティングコンテストではこのような実際の経験を元にしたトラブルの問題を運営学生がたくさん作っています!
次回コンテストも面白い(つらい?)トラブルが出題されると思いますのでご期待ください!!

«

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Optionally add an image (JPEG only)