開発グループ マネージャーが入社してから3年半でやってきたことのふりかえり


My Redmine

仕事ができるから仕事が集まってきて、忙しいのか。(多分違う)
仕事ができないからいつまでも仕事が終わず、忙しいのか。(疑わしい)
はたまた週4日しか働いてないから忙しいのか。(これな)
こんにちはサービス開発グループマネージャーの吉岡です。

2018年11月に入社以来、開発グループのマネージャーという肩書きはありつつも、主に AWS を中心としたクラウドサービスを利用して、実務をこなす機会が非常に多かったように思います。(プレイングマネージャーといいつつ開発ばかり)

今回は年度も変わったことですし、これまでどのような仕事をこなして来たか、そして今後どのようなことに取り組んでいくのか、書ける範囲で記事にしてみたいと思います。

今回書いてみる内容

  1. 社内システムのインフラ環境の改善
  2. My Redmine の東京リージョン構築(My Redmine Gen.2)
  3. 利用申し込みフォームと登録処理の自動化
  4. RedMica Bridge(Redmine REST API の WEB クライアント)
  5. 現在取り組んでいるプロジェクト(取り組む予定)

※ 自分がメインになって関わり、成果物のあるプロジェクトをピックアップしています。
※ 全て 1 人で作ったわけではなく、あくまで一番手を動かした成果物の紹介です。
※ 実はこのほかにも色々と仕事をしています。
※ それぞれの詳細仕様の説明は省かせていただきます。(外部公開している資料がある場合、そちらをご確認ください。)


全体図

さっそく、各プロジェクトの詳細を書いていきたいと思います。

1. 社内システムのインフラ環境の改善

経緯

入社後、Rails で作られた社内システムのサーバー(Linux)のサポート切れるからアップデートしてほしいとオーダーされて、詳細をつめるうちに一から環境を作り変えることに。 EC2 全部入り(アプリケーションサーバー、DB サーバー)だったのでとりあえず、当時流行りのコンテナで動かすことにしました。
(当時は「俺、インフラエンジニアじゃないけどなー」と思ったり思わなかったり)

アーキテクチャー図

業務システムのため、詳細は省きます。顧客情報などを管理するシステムだとお考えください。


再構築後の構成図

主な AWS の利用サービス

VPC, ALB, ECS(EC2), RDS, CodePipeline(CodeCommit, CodeBuild), CloudFormation, AWS WAF, KinesisFirehose, S3, Cloudwatch

主なタスク(作業の流れ)

  1. 社内業務システムのコンテナ化
  2. ECS を利用した本番環境の構築
  3. デプロイ用の Pipeline の作成
  4. CloudFormation を利用した IaC 化

感想

正直、そこまで AWS やコンテナに詳しかったわけではないですが、「サーバー(Linux)管理は嫌でござる」から始まり、EC2 は使いたくないという強い気持ちで ECS を選択しました!そして、コンテナのホストも Fargate というサーバーレスのコンテナ実行環境がで始めたこともあり、それを使いたいと思いましたが。。。

などの理由により泣く泣く、ホストタイプは EC2 を選択。それでも EC2 で環境作って管理するよりはマシだと思いました。その他、CloudFormation を利用したことで、インフラ環境のデプロイが簡単にでき、複数環境に構築してデプロイを検証できるようになったのは大きかったです。(学習コストは高めでしたが)

また、デプロイ方法を CodePipeline を利用することで Git の操作でデプロイできるようになったので、全体を通して随分と運用を効率化できたと思います。ちなみにですが、ECS は後に Fargate への移行も実施し、EC2 への依存度がまた一つ少なくなりました。(うちの若手エンジニアが頑張ってくれました。感謝!)

参考

EC2 から ECS へ移行を始めたお話

2. My Redmine の東京リージョン構築(My Redmine Gen.2)

経緯

My Redmine は海外リージョンで動いていたのですが(まだ残ってる)、東京リージョンでも動かせるようにしたいという話が持ち上がり、海外のリージョンの環境をそのまま東京リージョンでも構築するという話から始まりました(当然 EC2 を中心に構築されています)。

(自分は)EC2 で動かしても絶対に幸せにはならないという強い信念で「どうせ作るなら、コンテナで作りましょうよ!」と提案。ということでプロジェクトスタート!!当然、言い出しっぺの法則で自分のタスクになったわけです。
やっぱり「俺、インフラエンジニアじゃないけどなー」と思ったとか思わなかったとか。

アーキテクチャー図

サービスについては以下のサイトを参考にしてください。
https://hosting.redmine.jp/


My Redmine Gen.2 構築後の構成図

主な AWS の利用サービス

Route53, VPC, ALB, ECS(Fargate), RDS Aurora, S3, CodePipeline(CodeCommit, CodeBuild), CloudFormation, AWS WAF, Kinesis, Cloudwatch
AWS SAM, StepFunctions, Lambda, SQS, SNS, SES, CloudWatch, Fargate, S3, EC2

主なタスク

  1. Redmine のコンテナ化
    1. S3 Plugin 作成(添付ファイルを S3 に保)
    2. マルチテナントの実装(Apache の設定調整)
  2. ECS(Fargate)を利用した本番環境の構築
  3. アプリケーションデプロイ用の Pipeline の作成
  4. サービス利用者の新規登録、停止、削除を自動実行するための処理システムの構築 (社内システムへの登録、Redmine のデプロイ、停止、データー削除処理などの自動化)

感想

1.Redmine のコンテナ化
2.ECS(Fargate)を利用した本番環境の構築

社内システムで一度 Rails をコンテナ化して本番環境で運用した経験もあったので、割と楽にできるだろうと思って取り組みましたが、以下の縛り(要望)はなかなか強力でした。

特に大きな問題は以下2つです。

1. どうやってローカルストレージ(コンテナの中)に保存される添付ファイルをコンテナ外で保存できようにするか?

EFS を検討したりしたのですが、検討していた当時は値段が高く、バックアップ機能がなかったり、何より Fargate と接続できない問題があり、断念。結局、添付ファイルを S3 に保存できるようにする Plugin を利用することでなんとか調整しました。

ちなみにですが、S3 Plugin は最初自分が既存のプラグインを改良して使用しましたが、途中で、社内の Redmine プロにお願いして、ほぼほぼ書き直していただきました。そして今も引き続きメンテナンスをしていただいております。感謝!

2. どうやって(どこで)マルチテナンシーを実装するか?

当初1顧客(1 Redmine)につき 1 Task(1 コンテナ)にしようと思っていましたが、コスト的に見合わず、コンテナ内に Apache + Passenger を動かすことで実現しました。(これまでの Virtual Host 機能を踏襲)
一度、アプリケーション側での実装も検討しましたが、影響範囲が広すぎで断念しました。

一点工夫した点としては、1つのソースコードで全てのサイトを管理したかったので、Apache で管理できる環境変数をうまく使って、S3 と RDS の接続先(エンドポイント)や S3 のプレフィックスをプロセスごとに切り替えて、マルチテナントを実現しました。

特に2に関しては、会心のアイデアだったと思うのと同時に、このためさまざまな問題も起きたかなと思ったりすることろもあります。(Redmine あたりの原価をあげればもっと良い構成もあったかなーと思ったり)


マルチテナントの説明図

3.アプリケーションデプロイ用の Pipeline の作成

デプロイ用の Pipeline に関してはかなり苦労しました。今回の仕様上、Redmine の数だけ DB が存在し、デプロイ時に全ての DB に Migration を実行する必要があります。その場合、どのように Migration を実行するか??はとても悩みました。(数が多いので、シーケンシャルに実行すると、とても時間がかかる)

当初は DB の数だけ Fargate(ビルド済みの Redmine) を動かして、そこでrake db:migrateを実行(並列実行)させる処理を Pipeline に組み込んでいました。これでうまく動きそうだったのですが、ある時急に Fargate の API コールでエラーが発生するように。。。よくよくドキュメントを調べてみると Fargate の API を同時にコールできる数に制限があるとのことでした。

時間をずらして Fargate を実行すると結局時間がかかるし、どうしたものかと色々と悩みましたが、2020年の年末ごろだったでしょうか。AWS Lambda コンテナイメージ に対応というニュースが流れてきました。これにより、すでにビルド済みの Redmine のイメージをベースに rake db:migrate を実行する処理を追加したイメージを作成し、あとはそれを AWS Lambda で実行することで対応ができました。(ほぼほぼ、Fargate を利用してた時に書いたコードで対応が出来ました。)

これで課題は解決!
…かと思いきや、AWS Lambda を立ち上げて一気にデプロイしたら今度は RDS がパンク寸前。。。(CPU とか接続数とか)
仕方がないので、デプロイ用の Pipeline で Migration を実行しているステージを分割して、実行のタイミングをずらすことでなんとか RDS の負荷を分散に成功。こうしてどうにか Pipeline のいい感じで使えるようになりました。


Pipeline 簡略図

4.サービス利用者の新規登録、停止、削除を自動実行するための処理システムの構築

こちらの処理は当時 AWS の SA(ソリューションアーキテクト)の方に薦められて StepFunctions というサービスを利用して実装することにしました。(新しいサービスと言いつつも AWS Lambda の塊です)
StepFunctions という当時リリースされたばかりのサービスで、情報が少なかったり、実際に AWS 上で動かさないと挙動が掴めなかったりで、開発のペースが上がるまでは結構苦労した印象があるのですが、ある程度慣れてくると非常に使いやすくて良いサービスだなと今でも思います。

一番苦労した点としては、AWS Lambda から Postgresql を操作するために、psql コマンドのバイナリデータを AWS Lambda に仕込んだのはちょっと調べたり挙動の確認に時間を使いました。(最終的に AWS の技術サポートに問い合わせてなんとか解決)
デプロイ後、最初の一回目が期待通りに動作するかドキドキしたものでした。

…思い入れが深いかったり、一番時間をかけているというのもあり、思いのほか感想が長くなりました。こうして振り返ってみても、胃が痛くなってきそうです(思い悩むと胃にくるタイプ)。実はこちらのリリース後、My Redmine の利用が増加して来たので、あのタイミングで各種処理を自動化できたのはとても幸せだったのではないかと改めて感じる今日この頃。(しかし、この後、とんでもない出来事が!)

参考

3. 利用申し込みフォームと登録処理の自動化

経緯

時はちょうど、コロナの第一波が起こりはじめた頃、My Redmine Gen.2 の新規登録(無料お試し)などは一部手作業で登録したり、お客様への登録情報(アカウント情報)は郵送したりしていました。また、お客様によっては申し込んだらすぐ使われたい方もおられる訳で、その場合、サポート窓口で登録情報のやり取りをしてました。

側から見てても大変だなーと思ったので、登録用のフォームメール(React)を作って自動登録と通知ができれば楽になるのではと思い、提案したところからプロジェクトは始まりました。
「俺、アプリケーションエンジニアですから!」とテンション爆上がりだったとか。

サービス(アプリケーション)概要

以下のサイトの申し込みフォーム
https://hosting.redmine.jp/order/trial/


システムのフロー

主な AWS の利用サービス

AWS Amplify, S3, API Gateway, AppSync, DynamoDB, SES, Lambda, SQS

主なタスク

  1. React を利用した入力ホームを作成
  2. 入力データーの送信、社内システムへの登録などのバックエンドの処理を作成(主に node.js)
    1. メール認証機能
    2. 各種バリデーション
    3. メール送信 API
    4. 社内システムへの新規登録用の API

感想

最初は入力した情報をそのまま送信して、ハイお終い!くらいに考えて取り組みはじめましたが、作りはじめてみると、色々と要望(考えないといけないこと)が出て来ました。

メールが使えるか確認(認証)してほしい。サブドメインが使えるのもか(使用済みでないか)も確認してほしい…などなど(自動化するにあたって当たり前の要望、というか大前提となるべき仕様)。自分の考えの浅さを反省。。。(あくまで既存の入力フォームの仕様をベースに考えていたため、かなり甘い見積もりでした)
今回のシステムは社内の業務フローへの影響も大きかったため、別の部署の人たちも巻き込んで色々と調整しながら進めたプロジェクトで大変勉強にもなりました。

そして、1番の苦労したのは AWS Amplify を選択したことだったかもしれません。便利そうということで思い切って使ってみましたが、色々と苦労が絶えず。。特に amplify/cli のアップデートのタイミングで頻繁にアプリケーションが壊れたので、とても苦労しました(env と branch 切り替えたのも原因かも)。ちなみに、現在進行形で色々と苦労が絶えません!

バックエンドとフロントのベースは自分が作って、そこから見た目のデザイン含めて外部委託のエンジニアさんと一緒に作業を進めました。本当にプログラムを書くのは楽しい!(React 楽しい!)と思えたプロジェクトでした。

4. RedMica Bridge(Redmine REST API の WEB クライアント)

※ 3 から 4 のプロジェクトまで一年以上時間が経過しています。

経緯

あまりにも YAML とか Dockerfile とか書く機会が多くて、とにかくコードを書きたい一心で始めたプロジェクト!もはや Ruby じゃなくても良いから YAML(or JSON)以外の何か。。そう!もっと表現力豊かな何かを書きたくて始めたプロジェクト!!!

というのは半分冗談で大袈裟に書いていますが、たまにはコード書きたくなったのは本当です。ということで、Redmine の REST API を利用したフロントエンド(React)のアプリケーションを開発を始めました。

社内で説明するときには以下のような、目的・意義(言い訳)を掲げました。

実は入社時に新しいサービス作ったりもしてほしいというオーダーもいただいていたので、まぁ、Redmine に絡めたサービスなら全社で取り組みやすいでしょと思い提案しました。

サービス(アプリケーション)概要

RedMica Bridge
https://redmica-bridge.farend.jp/


RedMica Bridge 構成図

主なタスク

  1. バックエンド開発(Redmine REST API をプロキシーさせる処理
  2. React によるフロントエンド開発

主な AWS の利用サービス

AWS Amplify, Cognito, S3, API Gateway, AppSync, DynamoDB, SES, Lambda

感想

実は入社当初、ドキュメント管理のサービスを作ろうと思い、ささっとプロトタイプを作りましたが、うまくサービスインさせることはできず。。その時の失敗の経験を踏まえて、以下のようなことを心がけて、始めました。

1. 実績(プロトタイプ)を作ってから話を始める

自分はよくやるパターンで、必ず動くものを提示してからプロジェクトを提案します。(ある程度の技術検証を終えた状態)

今回も下記のように Redmine のアドベントカレンダーに REST API 関連のことを記事で書いてからプロジェクトスタートしました。
Rebuild the Redmine front end with REST API.

2. 1人で始めない。できれば専任の人が欲しい。

1人で始めると、途中で他の作業が忙しくなるとそこで開発が止まります。できれば専任で開発できる人が必要です。(当たり前のこと)

今回は運良く仲の良いエンジニアさんに週一日こちらの開発をしていただけることになったので、非常にラッキーでした(外部委託)。初期のベースの部分は自分が作成したのですが、そこから先の改良は、ほぼお任せ中。大変ありがたいことです!感謝!!(思惑通り)
やはり、必ず複数人で始めないとダメだなと強く感じました。

3. 開発グループだけでなく、他の部署の人も巻き込む

こちらも事前に別グループのマネージャーさんと相談をしてこういうことするから手伝って欲しいと事前に打診。快く引き受けていただいたのですが、マネージャーさんと一緒にやろうよと話を持ちかけたつもりが、なぜか別の人がプロジェクトにジョイン!(「なぜ??」と思ったとか思わなかったとか)

現在はプロジェクト全体の管理や広報活動を手伝ってもらってて、イイ感じです!感謝!!(マネージャーさんグッジョブ!)

4. とにかく走り出す(何かしらの形でリリースする)

正式版をリリースしようと思うと色々と社内調整が必要なため、現実的ではないと判断。ベータ版ということでとりあえずリリース。(世の中に永遠のベータ版という言葉がありまして…)

ということで、一応ベータ版としてリリースしていますが、現在進行形で開発を進めています。そして最近、弊社期待の若手エースが手伝ってくれることに今後も開発はどんどん Amplify(増幅)していくハズ??(チームで仕事するって楽しいですね。みなさんに感謝!)

やはりコードを書くのは楽しくて、なるべくこちらの開発に時間を使いたいなと思いつつ、AWS(インフラ)関連の運用保守・改善作業の方が優先度が高く、なかなか思うようには時間が使えない現状です。

今後、こちらのプロジェクトに関われるエンジニアをちょっとづづ増えて、みんなでコード書いて遊べればと思っています。

5. 現在取り組んでいるプロジェクト(取り組む予定)

番外編として、その他、現在取り組んでるお仕事も一部紹介したいと思います。

運用業務(上記作成した成果物のメンテナンス作業)

日々の何かしらアラートが上がると状況確認と原因の調査など取り組んでいます。(ほとんどは特に気にする必要のないものが多いです。)場合によっては復旧作業をしたりアラームの閾値を変更したり、追加でアラームやバッチ処理を作成したりしています。

OpenSearch を利用したログの可視化

まだ使うかどうかの技術的(マネー的)な調査段階ですが、My Redmine Gen.2 で溜め込んだログを ETL -> DWH -> BI ツール みたいなことをゴニョゴニョしております。(また違う領域にキター

各種 API

最近の大きなところでは、社内システムと Redmine を連携させるための API のアーキテクチャを考えたり、レビューしたり、動作検証したり、本番環境へデプロイしたり、デプロイ用の Pipeline の構築したりなどなど。

その他(今後取り組むこと

まとめ

以上、今回は自分がこれまでやってきたお仕事内容の紹介でした。入社して3年半弱経過しましたが、こうして改めてみると結構色々なことをやってきたなぁーと思います。改めて思うことは自分のように個々のスキルにそこまで深さがなくても、なんとなく作れて、無難に運用ができてしまうあたり、AWS ってやっぱりすごいなーと感じます。(ここでいうスキルはプログラミングスキルだったり、インフラエンジニアとしてのスキル)

まだまだ改善が必要な箇所、こうすればもっと良くなるなどのアイディアはあるので、引き続きアイディアを実現していけたらと考えています。色々なことにチャレンジできる環境を与えてもらって、会社はもちろん、周りの皆様には本当に感謝です!

ここらで一区切り!これからも新しいことに挑戦していきたいと思います!!

こちらの記事もオススメです!
AWS上でクラウドネイティブで再構築した「My Redmine Gen.2」リリース!
My Redmine Gen.2をリリース!クラウドへの対応を進めより良いサービスになりました。
無料版 Google Chrome OS の動向(2022年3月時点)
無料版 Google Chrome OS CloudReadyとChrome OS Flex(Preview版)を使ってみました。
Redmine 5.0で古いプラグインを動作させる方法(Zeitwerk対応)
Redmine 5.0ではZeitwerkが採用され、プラグインがZeitwerkに対応していないとRedmine 5.0は起動しません。
The Redmine Award 大賞をいただいたのでこれまでのRedmine活動を振り返る
これまでのRedmineに関する情報発信や開発への協力を評価いただきました。
シンプルなUIでRedmineのチケットを作成・更新できる「RedMica Bridge」ベータ版をリリース
シンプルなUIで簡単にチケットに入力できる「RedMica Bridge」は、複数のRedmineを横断してチケットを管理できるサービスです。
ファーエンドテクノロジーからのお知らせ(2024/04/17更新)
入門Redmine 第6版 出版記念セミナー「Redmine 8年分の新機能ふりかえり」【2024/4/18開催】
入門Redmine 第6版(2024年3月23日発売)に掲載された新機能に関する内容を執筆者・監修者が紹介します。
My Redmine 初回ご契約で「入門Redmine 第6版」プレゼントのお知らせ
Redmineのクラウドサービス「My Redmine」を初めてご契約いただいたお客様にRedmine解説書「入門Redmine 第6版」を進呈いたします。
2024年度ブランドパートナーに島根県在住のモデル ユイさんを継続起用
ユイさん(モデルスタジオミューズ所属)をファーエンドテクノロジーの2024年度ブランドパートナーとして継続して起用します。
My Redmine スタンダードプランおよびAdminサポートデスクプランの料金改定のお知らせ【2024年4月ご利用分より】
2024年4月ご利用分より、My Redmine スタンダードプラン(民間企業・個人向け及び官公庁向け)とAdminサポートデスクプランの料金を改定いたします。
Redmineの最新情報をメールでお知らせする「Redmine News」配信中
新バージョンやセキュリティ修正のリリース情報、そのほか最新情報を迅速にお届け