Development Division/Platform Team/Sys-Infra Unit では、開発者がスムーズに開発作業をできるように様々なことに取り組んでいます。
今回はそのうちの1つを紹介します。
背景
Repro の Slack には、開発オペレーション用のチャンネルがあります。このチャンネルには@deploy-bot
が存在しています。前回の改善1で@deploy-bot
は使いやすくなったのですが、Development Division 全体ではあまり活用されていませんでした。
新規アプリケーションのデプロイ準備時に Sys-Infra Unit への作業依頼が多かったため、原因を探ってみたところ、使い始めるのが意外と大変だということがわかりました。
課題
@deploy-bot
でデプロイするために必要な従来の作業は、詳細に書くと以下の通りです。
- デプロイ用の IAM Role を追加する
- リポジトリごとにデプロイスクリプト2を用意する
- Capistrano3 の設定を確認する
- GitHub の対象リポジトリにデプロイキー(公開鍵)を登録する
- Rundeck の KeyStorage にデプロイキー(秘密鍵)を登録する
- LDAP4 で管理しているユーザー5にデプロイキー(公開鍵)を登録する
- deploy-bot の設定ファイルに設定を追加してデプロイする6
デプロイ用の IAM Role を追加するためには Terraform と AWS の知識が必要です。また、デプロイキーの登録作業は、特別な権限が必要です。 ほとんどの作業は Pull Request ベースでできるようになっています。
Sys-infra Unit のメンバーは全ての作業をできる権限を持っていますが、開発者は全ての権限を持っているわけではありません。
まとめると以下の3つの問題があるとわかりました。
- 仕組みが意外と複雑でよくわからない
- Terraform わからない
- 誰がどの作業をできるかわからない
改善内容
仕組みが意外と複雑でよくわからない
全体像を把握するためのシーケンス図を用意しました7。
%%{init: {'theme':'dark'}}%% sequenceDiagram participant Slack participant deploybot as deploy-bot participant Rundeck participant deployjob as Deploy Job participant AWS participant GitHub participant dockerbuild as build-server Slack->>deploybot: deploy rails dev_staging branch deploybot->>Rundeck: invoke deploy job Rundeck->>deployjob: invoke deploy job Rundeck-->>Slack: start deploying message deployjob->>GitHub: git clone (installation access token) deployjob->>deployjob: exec config/deploy.sh deployjob->>AWS: AssumeRole AWS-->>deployjob: temporary security token deployjob->>deployjob: cap ${stage} deploy deployjob->>dockerbuild: cap ${stage} docker:push dockerbuild->>GitHub: git clone (token) dockerbuild-->>AWS: docker push to ECR deployjob->>AWS: Update ECS task definition deployjob->>AWS: Update ECS service deployjob->>AWS: Update Lambda deployjob->>AWS: Update StateMachine deployjob-->>Slack: result status
そこそこ複雑ですが、この図を見ながらコードを読むとあまり迷わずに処理を理解できます。
なお Repro ではデプロイまわりのツールとして以下を利用しています。
- https://github.com/reproio/ecs_deploy
- Capistrano で ECS Task 定義と ECS Service を更新する
- https://github.com/reproio/capistrano-dockerbuild
- Capistrano でビルド用のサーバーに接続して docker build & push を実行する
- https://github.com/okkez/aws-assume-role-rs
Terraform わからない
デプロイに必要な権限を整理して Terraform のモジュールを理解しやすいように書き換えました。
- 以前、作成したモジュールを ABAC ベースで書き直しました
- 一部のアプリケーションでしか利用していない権限についてコードコメントで補足した
- 権限を確認しやすいよう AWS のサービスごとにファイルを分けた
- ABAC を利用できるアクションをすぐ確認できるようにコードコメントにドキュメントへのリンクを記載した
- 一部 ABAC を利用できないアクションもあるが、それは RBAC で記述した
- 利用方法のドキュメントもわかりやすく書き直した
まだ、既存の利用箇所を全て置き換えることはできていませんが、新規作成するものについては新しいモジュールを利用するようになっています。
誰がどの作業をできるかわからない
作業内容を見直し、特別な権限がなくても開発者であれば誰でも新しくデプロイするアプリケーションを追加できるようにしました。
特別な権限が必要な作業は以下の3つでした。
- GitHub の対象リポジトリにデプロイキー(公開鍵)を登録する
- Repro だと GitHub の管理者権限を持つ人に依頼する
- 管理者権限を持つ人は複数存在するが、忙しい人が多い
- Organization メンバーの権限は Terraform で管理しているので、誰でも簡単に確認できる
- Rundeck の KeyStorage にデプロイキー(秘密鍵)を登録する
- Rundeck の admin 権限を持つ人に依頼する
- Rundeck の権限は Terraform で管理しているので、誰でも簡単に確認できる
- 毎回、手順書を確認しながら作業していた
- LDAP のデプロイ実行用ユーザーにデプロイキー(公開鍵)を登録する
@deploy-bot
でデプロイしたいアプリケーションが増えるたびに、開発者各自がこれらの権限を持つ人に作業依頼をしなければなりませんでした。開発者の待ちも発生するし、作業者のコンテキストスイッチによるストレスや作業手順の確認などの手間がかかっていました。
全てデプロイキーの登録に関する作業なので、デプロイキーを廃止して GitHub App Installation Access Tokenを利用することにしました。さらっと書いていますが @deploy-bot
のコードを書き換えたり、Rundeck の deploy job のコードを書き換えたり等、そこそこの作業量がありました。
これで@deploy-bot
を使用してデプロイできるようにするための作業はPRを3つ作るだけになりました。
- デプロイ用の IAM Role を追加する
- リポジトリごとに定められた形式の config/deploy.sh を用意する
- Capistrano の設定を確認する(2のリポジトリと同じ)
- deploy-bot の設定ファイルに設定を追加してデプロイする
この手順では、チーム内のレビューで作業を完結できるので他チームや強い権限を持つ人への作業依頼が不要になり、開発者の待ち時間が削減できました。
まとめ
今回の改善により、デプロイプロセスを簡素化し、開発者がよりスムーズに作業を進められるようになりました。
@deploy-bot
利用方法のドキュメントを改善した- Terraform のモジュールを利用・理解しやすく改善した
- 特別な権限が必要なデプロイキーの登録作業を廃止した
- 開発者の待ち時間や作業の手間が削減できた
- チーム内で作業が完結するように手順を整理できた
以上の改善によって、開発者が他チームのサポートを待つことなく自立してデプロイ作業を進められるようになり @deploy-bot
の利用が活発になりました。
- サービス毎に作られていたデプロイ用のSlackBotなどを統合し、利用しやすくしました - Repro Tech Blog↩
- 決まったパスに実際のデプロイに利用するコマンドを書いたシェルスクリプトを用意する。↩
- Reproで主に利用しているRuby製のデプロイツール https://capistranorb.com/↩
- Reproでは EC2 インスタンスにログインするためのユーザーや SSH の公開鍵を LDAP で管理しています。↩
-
ChatOps を用いて
git clone && docker build
を専用サーバー上で実行するためのユーザーも LDAP で管理しています。↩ -
deploy-bot 自身のデプロイも
@deploy-bot
へ依頼できるようになっています。↩ - 元は PlantUML でしたが ChatGPT に mermaid 記法へ変換してもらったものを簡略化しています。↩