こんにちは。エンジニアのjunです。
園探し・見学予約メディアのホイシルで掲載しているコンテンツに関するデータ編集のオペレーションを、SaaSであるベースマキナを用いて構築したので紹介します。
ベースマキナについて
ベースマキナは、SQLやAPI呼び出しの登録だけで社内向け管理画面を自動生成するローコードサービスです。
システムのデータ更新・削除の業務に関して、エンジニアが本来の開発業務以外で時間を費やしていたオペレーション用の画面作成工数を削減できるようになり、権限管理や承認フローが提供されていることで、非エンジニアも画面から顧客データを安全に操作できるようになるというサービスです。
主な特徴として、ベースマキナのサーバと自社管理のデータベースをセキュアに接続する方法を提供しているところです。
下記のドキュメントにあるように、bridgeというアプリケーションをデータベースへの接続が可能なところにデプロイしたうえでベースマキナの指定するIPからのアクセスを許可するように設定すると、ベースマキナのサーバから自社管理のデータベースへクエリを発行することができるようになります。
なお、SaaSから自社のデータベースへ接続ができるメリットは、セキュリティ上のリスクでもあるため、それを防ぐための権限設計や簡易な承認フローが設けられる点も良いところかなと私は思っています。
抱えていた課題
ホイシルは、保活および保育士求人のメディアとして多数の保育施設に関する情報を掲載していますが、より良いサービス提供のためには掲載されている内容の更新が重要となります。
そういった背景から社内向けに情報編集用のWeb画面を提供しているのですが、すべての情報を細かく更新することはできていない状態でした。
一方で、社内向け機能は重要ではあるものの、開発チームの限られた時間でプロダクトを成長させていくために開発アイテムとしての優先度は下がりがちで、困ったら手動でのDBオペレーションで回避するのが定番となっていました。
そのような状況において、業務フローを効率化するためにSlackでのサポートから開発へのDBオペレーション依頼ワークフローやテンプレート作成などを整備していましたが、プロダクト規模が大きくなるとそれでも業務負担が大きくなり、ミスの温床でもありました。

幸いなことにDBオペレーションのクエリ自体はある程度定型化できること、過去の作業実績などはストックしていたことから、 ベースマキナがこういった状況を改善してくれるだろうという仮説を立てて導入をしていきました。
導入に向けてやったこと
bridgeの設定
自社システムとベースマキナをセキュアに接続するためには、まずベースマキナのbridgeアプリケーション(以降bridgeとだけ記します)の自社システム内への設置を行う必要があります。
ホイシルではこのような構成でbridgeを動作させています。

とはいえやることはシンプルで、bridgeのコンテナをデータベースへアクセス可能な環境へ設置し、ベースマキナのシステムからのhttpリクエストを受け付けられるようにすることだけです。
つまり通常のWebアプリケーションのデプロイと全く同じと言っても良いはずです。唯一異なるのはベースマキナのシステムからのみアクセスを許可するような制御が必要な点です。
ベースマキナとbridgeの間の通信はインターネット経由であり、認証が少なくとも現状はかけられないためにIP制限のような仕組みはセキュリティの観点から必須と思われます。
※ パブリックサブネット内にロードバランサを設置する以外でより簡易な方法があれば知りたいです
また、ホイシルではECSのコンテナのデプロイにecspressoを利用しており、サービス定義やタスク定義はjsonnetで書いています。
以下に実際のタスク定義から抜粋したものを掲載します。
ECSでbridgeを動かす場合は大抵こういうものになると思うので参考になるはずです。
なお、コンテナヘルスチェックの設定はbridgeのコンテナイメージ内にwgetコマンドが入っていることを確認できたため使っていますが、ベースマキナ公式のドキュメントで明言されている方法ではないので注意が必要です。
その前提に立たない場合、ECSタスク内にbridgeヘルスチェック用のサイドカーコンテナを立てるなどで対応することになりますが、割り切ってこのような設定にしました。
そして、ロードバランサ経由でアクセスをする場合にはターゲットグループのヘルスチェックがあるのでコンテナ自体のヘルスチェックを行わないこともできますが、デプロイを正しく制御するためにもコンテナのヘルスチェックはある方が良いと考えており、このようにしています。
local must_env = std.native('must_env'); { "containerDefinitions": [ { "name": "basemachina-bridge", "image": "public.ecr.aws/basemachina/bridge:latest", "essential": true, "environment": [ { "name": "PORT", "value": "8080" }, { "name": "TENANT_ID", "value": "{{ must_env `BASEMACHINA_TENANT_ID` }}" } ], "portMappings": [ { "containerPort": 8080, "hostPort": 8080, "protocol": "tcp" } ], "healthCheck": { "command": [ "CMD-SHELL", "wget -q -O - http://localhost:8080/ok || exit 1" ], "interval": 30, "timeout": 5, "retries": 3, "startPeriod": 10 }, "logConfiguration": { "logDriver": "awslogs" }, "ulimits": [ { "hardLimit": 65535, "name": "nofile", "softLimit": 65535 } ] } ], "cpu": "{{ must_env `ECS_CPU_ALL` }}", "memory": "{{ must_env `ECS_MEMORY_ALL` }}", "runtimePlatform": { "operatingSystemFamily": "LINUX", "cpuArchitecture": "ARM64" } }
業務フローとベースマキナの設定
業務フローは以下のようになりました。
サポートの方が必要な情報をベースマキナ上で入力してデータの更新をかけられるようになったため、
slackのワークフローに入力・実行する時間が短縮され、さらにエンジニア抜きで業務ができるようになりました。

ベースマキナ上に設定したデータ取得とデータ更新の2つのアクションの間は 結果表示のカスタマイズ 機能およびlinkToAction関数を利用しています。
これは「あるアクションの結果を入力として別のアクションを開く」という、プログラミングの用語でいうと関数をチェーンさせるようなもので、アクションを利用した業務フロー構築のキモになっています。
たとえばあるデータの特定のフィールドのみを更新したい場合などにおいて、一般的な編集フォームのように既存の設定値をフォームの初期値としたいはずです。linkToAction関数の引数にリンク先アクションの入力値を設定することができるようになっています。
これを適切に設定したうえで、データ取得用のアクションを実行してリンクを開くとデータ更新用アクションの入力値がすべて入った状態になり、更新したいところを手作業で入力し直してアクション実行するとDB上のデータが変わるのです。

メンバーへの共有、協力依頼
ここまで主にシステム面の解説をしましたが、こういったプロジェクトにおいて重要なのはシステムそのものよりも導入と運用です。
ホイシルの問い合わせ対応に関するベースマキナの導入に際しては、以下のような順序で行いました。
- サポートの方々や開発のメンバと課題認識のすり合わせを場を設け、ベースマキナで解消するプランを共有する
- 開発環境を用いてデータ更新で多く発生する業務のデモ操作を実装
- 全員でその操作をベースマキナを用いて触ってみて価値を体感する
- 改善後の業務フローをすり合わせて本番導入
ツールの導入などは初期の認知負荷があがるため価値を感じることができるだろうか?と心配していましたが、 サポートの方々も同じ課題を感じており業務負担が減るイメージを共有できたことで協力体制を築く事ができました。

導入してどうだったか
新しい業務フローとなり、エンジニアとしては問い合わせ対応業務に充てる時間が減りプロダクト開発に集中することができるため恩恵が非常に大きいです。
他方、サポートとしてはslackのワークフローとベースマキナに入力する時間の単純比較だけでは業務負担は減っていないように見えるかもしれません。
しかしながら、データ更新までにかかるリードタイムが削減され、社内でのコミュニケーションや社内用Web画面の要求整理等のコストを考えると顧客体験も上がり、サービス運営コストが下がっていると言えるはずです。
なお、いくつかのやむを得ないものを除き、元々のSlackワークフロー自体は残っているのですが、
少しずつベースマキナに移行することで着実に減ってきています。
理想的にはSlackのワークフローがなくなってすべて移行されると嬉しいのですが、
量が多い定型的な作業を減らすということが何よりも重要なことだと感じています。
そして、ベースマキナはtoB向けあるある機能であるcsv一括操作を提供しており、
エンジニアが手動で大量のデータを操作をするときにも利用することがあります。
これもまた便利だなと感じてます。
さいごに
ベースマキナを知ったきっかけ
私がベースマキナのことを知ったのはあるエンジニアの勉強会がきっかけでした。
とてもためになる発表をされている方がおり、Xでフォローさせていただいていたところベースマキナにご転職されたのを観測したところで、ベースマキナのサービスサイトを見て今回のような社内向けのオペレーション構築に良さそうだなという想像をしていました。
また一人のエンジニアとして「道具を作るための道具」に対してワクワクするものがあり、まさにそういうサービスであるところは好印象を抱いていました。ちょっとしたファンですね。
そんな折に、たまたまホイシルの担当になり前述の課題を感じて、真っ先にベースマキナを使えば解決できそうだなというイメージが湧いたので導入の段取りを進めていきました。
エンジニアコミュニティに出ていくことには、自分自身のスキルアップはもちろんのこと、他社、他業種のサービスを知る機会にもなるのだなということを強く感じます。
謝辞
まずは、こういったサービスの導入に関して前向きになってくださった社内のサポートやエンジニアの皆さんに感謝を述べたいです。
子ども施設のお客様に対して省力化を提案する者として、自分たち自身の業務の省力化に対しても積極的なのはコドモンの素晴らしい文化だなと感じるいい機会でした。
そしてベースマキナの方々もサポート対応が手厚く、slackで問い合わせるとエンジニアの方が丁寧に素早く回答してくださることが多いです。
導入時やアクションの作成などにおいて助けられることが多くて嬉しいと同時に、いちエンジニアとしても、開発をしながらも顧客と直接向き合っていることに関して敬意を払いたいです。