コネヒト開発者ブログ

コネヒト開発者ブログ

ecschedule用のYAMLファイル専用リポジトリを解体して、各アプリケーションのリポジトリへ移管した話

プラットフォームグループでインフラエンジニアをしている @laughk です。 今回は、当社の ECS Scheduled Task の管理リポジトリを解体し、各アプリケーションのリポジトリへ移管した話を紹介します。

背景

コネヒトでは、ECS Scheduled Task の管理を一元管理するリポジトリがありました。このリポジトリでは ecschedule というツールを使って EventBridge のルールを YAML で管理、あわせて ECS のタスク定義もJSONで管理し、GitHub Actions 経由で EventBridge ルールの適用を ecschedule apply で行うというものでした。ecschedule については、以下の記事で導入の話を書いています。

github.com

tech.connehito.com

このリポジトリでは、3つのプロダクトの EventBridge のルールが一元管理されていました。

これは導入当初は各プロダクトのデプロイツールで ecs-deploy を使っていた関係で ECS サービスやタスク定義などのリソースをコード管理するという習慣自体が無かったことに由来します。ECS 関連のリソースの管理される場所も定まっておらず、ecschedule で必要とされる定期実行バッチの EventBridge のルールを管理する YAML ファイルを含め適切な管理場所も無かったため、独立したリポジトリを用意した経緯があります。

なお、定期実行バッチで利用する ECS タスク定義の JSON も同様の状況でしたが、後述するように ecspresso の導入によって Web アプリケーションのデプロイとまとめて管理されるようになりました。

なぜ一元管理しているリポジトリを解体したのか

ecschedule で管理していたリポジトリを解体した理由は、主に以下の2点です。

  • ECS 関連のデプロイ・リソースの管理状況が変わった
  • ecschedule の運用が安定し、プロダクトのリポジトリから独立している状況が煩わしくなった

結果として、 ecschedule で管理していたリポジトリを解体し、各プロダクトのリポジトリに ecschedule 用の YAML ファイルの管理と CI/CD などの自動化された仕組みを移管しました。

ECS関連のデプロイ・リソースの管理状況が変わった

ecs-deploy から ecspresso に移行したことで、タスク定義やデプロイ周りのコード化、デプロイの CI/CD 化が進みました。 特にそれまで Web アプリケーション用の ECS タスク定義と定期実行バッチ用の ECS タスク定義が別々に管理されていたのが、ecspresso によってデプロイも含めて共通化されたことが大きいです。

ecspresso 導入後に Web アプリケーションと定期実行バッチ用の ECS タスク定義更新の共通化については、以下のスライドにまとめているので興味のある方はご覧ください。

www.docswell.com

結果、定期実行バッチの EventBridge のルールだけが別のリポジトリに分かれている状況がかえって手間になりました。

ecschedule の運用の安定し、プロダクトのリポジトリから独立している状況が煩わしくなった

ecschedule 導入当初はツールに扱いなれていないメンバーも多く、ちょっとした記載方法のミスや設定漏れが発生するケースもあり、インフラエンジニアが中央集権的に管理する意義はありました。

しかし、問題が発生するごとにチェックスクリプトを用意して CI/CD でチェックする対応を繰り返していくうちにトラブルが発生するケースはなくなり、結果としてインフラエンジニアが介入する必要はほとんどなくなりました。

むしろ定期実行バッチの追加・変更・削除については関連する機能を実装した開発メンバー・チームのほうが状況を適切に把握しているケースがほとんどのため、インフラエンジニアが管理しているリポジトリに対して別で Pull Request を出す運用がそもそも実態に見合っていないものになっている状況でした。

解体から移管の概要

ecschedule 用の YAML ファイルを一元管理していたリポジトリの解体と各アプリケーションのリポジトリへの移管の概要は下図のイメージです。リポジトリのディレクトリごとに分かれていたものを、対応するアプリケーションのリポジトリに移管しました。

解体から移管の際に意識・工夫したこと

リポジトリの解体から設定ファイルの移管の際に意識・工夫したことは以下の通りです。

  • git log は git filter-repo を使って git log を保持した状態で移管
  • コードだけ移管するのではなく CI/CD による自動化もセット。人やチームに移管するのではなく、ツール・仕組みに移管する
  • デプロイで扱う CLI ツールは aqua で管理

git log は git filter-repo を使って保持した状態で移管

ecschedule 向けの設定ファイルを単純に移管することは簡単です。 しかし、それなりの時間運用していたものであるため、過去の経緯はできる限り追跡可能にしておきたいです。

そこで git filter-repo を使って、過去のコミット履歴を保持したままリポジトリを移管しました。 1 git 本体には含まれていないため、追加で brew や scoop でインストールする必要があります。 2

github.com

cluster1/prd-event-rules.yamlcluster1/dev-event-rules.yaml というファイルを batches というリポジトリからリポジトリ service1 の scheduled_batch_rules/ 配下に git log を保った状態で移動する例を示します。

CLIオペレーションとしては、おおよそ次の流れになります。一度移行元で scheduled_batch_rules/*.yaml だけの構成を作った後で、移行先リポジトリに強制的にマージするイメージです。

## ローカルにクローンしている batches リポジトリに移動
$ cd /path/to/batches

## 移行したいファイル以外、すべてをgit log含めて削除する
$ git filter-repo --path cluster1/dev-events-rules.yaml --path cluster1/prd-events-rules.yaml --force

## cluster1/ を scheduled_batch_rules/ に git log を保ちつつリネーム
$ git filter-repo --path-rename cluster1:scheduled_batch_rules --force

## 移行先のクローンしてあるリポジトリに移動
$ cd /path/to/cluster1

## 移行元のリポジトリをリモートに追加
$ git remote add batches /path/to/batches

## 移行元のリポジトリのリモートブランチを取得
$ git fetch batches

## 移行元のリポジトリのブランチを移行先のリポジトリにマージ
$ git merge batches/main --allow-unrelated-histories

注意点

  • /path/to は適宜自分の環境のものに読み替えてください
  • git fileter-repo は一度実行すると rebase などでも元に戻すことはできなくなるため、移行元となるリポジトリは移行用に別途クローンしておくことをおすすめします。
  • 移行元を移行先で取り込む際の git merge--allow-unrelated-histories オプションがないとエラーとなりマージできません。

コードだけ移管するのではなく CI/CD による自動化もセット

単純に設定ファイルの管理を別リポジトリに移すだけではこれまで利用してきた CI/CD による自動化された仕組みも失われてしまいます。 そうなると当然ながら CI/CD も含めて移管することになりますが、これまでの定期実行バッチの EventBridge のルールを管理するためだけのリポジトリからアプリケーションの開発が行われているリポジトリへの移管となるため、既存の CI/CD の影響を加味しつつ行いました。

移管した仕組みは次の通りです

  1. Pull Request 作成時に行うジョブ
    • ecschedule diff (差分チェック)
    • ecschedule 用の YAML の最低限のチェックツールの実行
  2. main ブランチマージの際に行うジョブ/tag push ( GitHub Release 作成)の際に行うジョブ 3
    • ecschedule apply (dev 環境への適用)
    • ecschedule apply (prd 環境への適用)

コネヒトでは全社的に GitHub Flow が採用されているためこのような流れになっています。

ecschedule の適用については既に ecspresso によるデプロイ(ECSサービス更新とバッチ用のECSタスク定義更新)が同様の流れで行われるようにしていたため、基本的にはデプロイが成功した後にジョブが走るようにしています。

それぞれについてもう少し詳しく説明していきます。

Pull Request 作成時に行うジョブ

まずは ecschedule diff によるYAMLと実際の EventBrige の EventBridge のルールの差分チェックを行うシンプルなジョブです。 GitHub Actions の YAML は次の通りです。

name: diff-check
on:
  push:
    paths:
      - "scheduled_batch_rules/*"
      - ".github/workflows/scheduled-batch-yaml-check.yaml"

permissions:
  id-token: write
  contents: read

jobs:
  diff-check:
    strategy:
      matrix:
        target:
          # diff check の対象となるファイルパスを指定
          - scheduled_batch_rules/dev-events-rules.yaml
          - scheduled_batch_rules/prd-events-rules.yaml
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: setup aqua
        uses: aquaproj/aqua-installer@v3.0.1
        with:
          aqua_version: v2.36.0

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: arn:aws:iam::123456789012:role/assume-role-for-ecs
          aws-region: ap-northeast-1
          role-session-name: GitHubActions-${{ github.run_id }}

      - name: check diff
        run: |
          ecschedule diff -conf ${{ matrix.target }} -all

工夫しているポイントとしては次のものがあります

  • トリガーの push.paths に ecschedule で利用する設定ファイルとGitHub Actions の YAML ファイルを指定し、定期実行バッチを変更しない場合は CI/CD ジョブが走らないようにする
  • matrix を使って dev 環境と prd 環境の差分チェックを並列して行う

次は、ecschedule 用の YAML の最低限のチェックツールの実行を行うジョブです。

check_rules_yaml.sh という独自に用意したシェルスクリプトを使って、YAML の構文チェックを行っています。内容は本エントリの趣旨から外れてしまうため詳細は割愛しますが、 EventBridge のルール名の重複チェックと overrides.*.command に余分なスペースが入っていいかのチェックを行います。

name: scheduled batch yaml check
on:
  push:
    paths:
      - "scheduled_batch_rules/*"
      - ".github/workflows/scheduled-batch-yaml-check.yaml"

jobs:
  scheduled_batch_yaml_check:
    strategy:
      matrix:
        target:
          # syntax check の対象となるファイルパスを指定
          - scheduled_batch_rules/dev-events-rules.yaml
          - scheduled_batch_rules/prd-events-rules.yaml

    runs-on: ubuntu-latest
    steps:
      - name: Check out code
        uses: actions/checkout@v4
        with:
          path: service1

      - name: Check out platform-toolbox
        uses: actions/checkout@v4
        with:
          repository: Connehito/platform-toolbox
          token: ${{ secrets.MACHINE_USER_GITHUB_ACCESS_TOKEN }}
          sparse-checkout: ecs_scheduled_task
          path: platform-toolbox

      - name: Run Syntax Check
        run:
          /bin/bash platform-toolbox/ecs_scheduled_task/check_rules_yaml.sh service1/${{ matrix.target }}

工夫しているポイントは次のとおりです。

  • 独自のチェックスクリプトはインフラツール管理用のリポジトリに移管し、CI/CD 上でマルチリポジトリクローンで対応
  • ecschedule diff 同様に matrix を使って dev 環境と prd 環境の構文チェックを並列して行う

特に、前者のチェックスクリプト check_rules_yaml.sh の扱いは複数のリポジトリで共有して利用できてかつ多重管理になることを避けたかった背景があります。

独自に作成したスクリプトなので最悪コピペで ecschedule の設定ファイル同様に移管することもできますが、それでは管理が散り散りになり今後の更新・修正が煩雑になります。当初は Draft Releaseデプロイフローを作成してみました - コネヒト開発者ブログ でも紹介されているカスタムアクションを作って共有化することも検討しましたが、その場合シェルスクリプトでチェックアウトしたリポジトリのファイル内容を読み込むのに難があったため、今回は actions/checkoutrepository オプションを使って別リポジトリのクローンを行うことで対処しました。4

Connehito/platform-toolbox というリポジトリは、元々コネヒトの主にインフラエンジニアが業務で利用する共通のスクリプトやツールを置いているプライベートリポジトリです。今回の check_rules_yaml.sh の置き場所としても適切であったため、このリポジトリに移管しました。

今回のシェルスクリプト check_rules_yaml.sh はコネヒト独自のものであるものの、CI/CD 上で利用するちょっとしたスクリプトがある場合でも同様に共通化することができます。

mainブランチマージ/tag push時に行う適用のジョブ

ecschedule apply が伴うジョブは次の通りです。

# ---- (中略) ----

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:

        # --- ( ecspresso によるデプロイジョブ ) ---

  scheduled_batch_rules:
    runs-on: ubuntu-latest
    needs: [ deploy ]
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: setup aqua # aqua で管理しているパッケージのインストール
        uses: aquaproj/aqua-installer@v3.0.1
        with:
          aqua_version: v2.36.0

      # 以下、定期実行バッチルールの適用
      # dev環境向けのバッチルールが変更された場合のみに、適用する
      - uses: dorny/paths-filter@v3
        id: scheduled-batch-rules-changes
        with:
          filters: |
            src:
              - 'scheduled_batch_rules/dev-events-rules.yaml'

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ vars.AWS_ROLE_ARN }}
          aws-region: ap-northeast-1

      - name: ecschedule apply to dev
        if: steps.scheduled-batch-rules-changes.outputs.src == 'true'
        run: |
          ecschedule apply -conf scheduled_batch_rules/dev-events-rules.yaml -all

ecschedule apply については ecspresso によるデプロイが成功した後にシンプルに ecschedule の適用ジョブが実行されるように追加しています。この時、 main ブランチマージの時のみ dorny/paths-filter で定期実行バッチ用の EventBridge のルールファイルを指定し、定期実行バッチを変更しない場合は極力 CI/CD ジョブが走らないようにしています。

本当は tag push の際も同様にしたいところですが paths-filter の仕様上 main ブランチマージ直後に作成された tag の場合、正しく差分を検知できません。そのため、本番環境への適用のジョブでは paths-filter を使わず、冪等であることを加味して常に ecschedule apply するようにしています。

デプロイで扱うCLIツールは aqua で管理

ecschedule の設定ファイルの移管は CI/CD の自動化も含めて行いましたが、 ecschedule そのもののも aqua を使って管理するようにしました。

github.com

aqua は Go 製の宣言型 CLI パッケージマネージャで、リポジトリトップに aqua.yaml というファイルを置くことで、リポジトリ内で利用するCLIツールとそれらのバージョン管理ができます。 aqua を導入した背景としては、主に次の課題を解決するためです。

  1. 各個人で ecschedule, ecspresso などを brew, scoop, mise などの管理に任せていると、いざローカルで利用する必要がある際にバージョンが合わずに想定外の動作をするケースがある
  2. ローカルで利用する CLI ツールのバージョンと GitHub Actions で利用する CLI ツールのバージョンをそろえたい
  3. CLI ツールの継続的なバージョンアップ

これらの課題は一度 CI/CD でワークフローが出来上がってしまえば、その後あまり意識されることが無くなってしまうものであります。 しかし、長期的な視点で考えるといずれも放置されるような状況になると「ある日突然 CI/CD が動かなくなる」という事態にもなりかねません。 そのため、ecschedule 導入のタイミングで同時に仕組みでつぶしておきたい課題でありました。

aqua を導入することで、リポジトリ内で利用する CLI ツールのバージョン管理を一元化し、 GitHub Actions での利用も含めてバージョンを一元管理できるようになりました。また、 renovate にも対応しているため、継続的なアップデートも人の手によるものではなく仕組みで行えるようにできます。

バッチ専用リポジトリを解体してどうなっているか

リポジトリの解体から移管が完了してからしばらく経ちますが、当初の目論見通りの改善ができたように感じています。

具体的には、バッチ追加の Pull Request がアプリケーション実装と EventBridge のルール追加・変更を一つのリポジトリで一気通貫して行えるようになり、インフラエンジニアによる形骸化した Pull Request レビューも必要なくなりました。

一見些細な事ではありますが、開発者が普段コミットしているリポジトリで完結するようになったことで、複数のリポジトリに合わせる余計な環境構築の必要はなくなり、別々に Pull Request を出してそれぞれのデプロイのタイミングを伺う必要も無くなりました。より必要な開発に集中できる環境を用意することに寄与できたように思えます。

ecschedule のような「直接アプリケーションには関わらない、けれどもシステムの運用上アプリケーションの開発者が直接触れたほうがよいインフラリソース管理」において、コネヒトでは今回のようなアプリケーションリポジトリに統合するという形に落ち着きました。もしも同様にアプリケーションと距離の近いインフラリソースの管理に課題を感じているケースの参考になれば幸いです。


  1. git log を保持したまま別のリポジトリにファイルを移す方法として git filter-branch を使う事例もあります。しかし git filter-branch は git 2.46.1 時点で公式でも非推奨となっており、git filter-repo を使うことが推奨されています。参考: Git - git-filter-branch Documentation
  2. https://github.com/newren/git-filter-repo/blob/main/INSTALL.md#installation-via-package-manager
  3. コネヒトでは一般的なステージング環境を dev 、本番環境を prd と呼んでいます。
  4. actions/checkout: Action for checking out a repo - Checkout multiple repos (private): https://github.com/actions/checkout?tab=readme-ov-file#checkout-multiple-repos-private

PyCon JP 2024で登壇してきました!

みなさんこんにちは。MLエンジニアのたかぱい(@takapy0210)です。

先日開催されたPyCon JP 2024 のDay1で、「低コストで実現する社内文書RAG機能を搭載したAIチャットボット開発」というタイトルで登壇してきました。

本日はその発表資料と当日の様子をお届けしようと思います。

PyCon JPとは

Pythonや、Pythonを使ったソフトウェアについて情報交換、交流をするためのカンファレンスです。 今回は久しぶりにオンサイトのみの開催でした。

  • 概要:日本最大級のPythonユーザーカンファレンス
  • 日時:2024年09月27日(金)~ 2024年09月29日(日)
  • 会場:TOC有明コンベンションホール

トーク内容

Slackを活用したAIチャットボットの構築と、そのチャットボットに社内文書に基づいた回答を生成させる機能(RAG)を低コストで実装した方法についてお話しました。
RAGの精度向上などの話は控えめに、0→1でRAGを実装し肌感を掴みたい方向けの内容になっています。

前半では、Slack Appで実現するシンプルなAIチャットボットの開発方法について説明し、後半では、AIチャットボットに社内文書に基づいた回答を生成させる仕組み(RAG)の紹介や、RAGを実現する上でのポイントや低コストで実現するTipsについて紹介しました。

登壇の様子

カンファレンスの感想

今回は2021年・2022年に引き続き、3回目の登壇でした。
2021年・2022年ともにオンライン/オフラインのハイブリット開催であり、完全オフラインでのPyCon参加は初めてだったのですが、思った以上に多くの人が来場されており、コミュニティの熱量の高さがうかがえました。

また、タイムテーブルを見ても分かる通りさまざまなトピックのトークがあり、かつ英語でのトークも多く、Pythonが幅広い用途・地域で用いられているんだなと、改めて実感しました。

参加者の地域

また、今回は参加者一人一人にNFCタグ付きの名札も配られており、参加者同士がコミュニケーションをしやすい工夫も感じられました。

最後に

PyCon JP 2024運営スタッフの皆様、当日コメントや質問をしてくださった皆様、Speakerの皆様、ありがとうございました & お疲れ様でした!

コネヒトのデータや機械学習周りの仕事についてもう少し知りたいな、と言う方がいましたら、以下のページにまとめているので、良ければ見てみてください!
カジュアル面談もお気軽にお声掛けいただければと思います!

tech.connehito.com

コネヒトはiOSDC Japan 2024に協賛いたします!

こんにちは、iOS/Androidアプリエンジニアの@katsutomuです!

本日は、iOSアプリ開発者の祭典iOSDC Japan 2024に協賛するお知らせです。

コネヒトはiOSDC Japan 2024に協賛いたします!

iOSDC Japan 2024に、シルバースポンサーとして協賛いたします。

iosdc.jp

スポンサーするにあたって、コネヒトは「人の生活になくてはならないものをつくる」というミッションを掲げているので、技術コミュニティについても同様に、サポートして一緒に盛り上げていくことができたら、と思っております。

イベント概要

  • 開催 2024年8月22日(木)~ 8月24日(土)
  • 場所 早稲田大学理工学部 西早稲田キャンパス + ニコニコ生放送
  • 対象 iOS関連技術およびすべてのソフトウェア技術者
  • タイムテーブル https://fortee.jp/iosdc-japan-2024/timetable
  • 主催 iOSDC Japan 2024 実行委員会 (実行委員長 長谷川智希)
  • 共催 早稲田大学 理工学術院
  • 後援 早稲田大学グローバル科学知融合研究所

iOSDCトークンはこちら!

#mamari-swiftui

これはiOSDCチャレンジで使うトークンです!

今年もオンラインだけではなく、オフラインでも開催される予定です。 技術者同士のつながりや知識の共有が広がることにワクワクしています。皆さん、楽しみましょう!

3年ぶりのTech Visionアップデートに込めた想い

こんにちは。CTOの永井(shnagai)です。

今日は、約3年ぶりにアップデートしたConnehito Tech Visionについて、主に戦略面のアップデート内容とそこに込めた想いを交えつつ書いていきます。

tech-vision.connehito.com

Connehito Tech Visionとは

Connehito Tech Visionは「Beyond a Tech Company」というビジョンを掲げた、コネヒトにおけるテクノロジーへの「態度」を表明した羅針盤です。

コネヒトのエンジニア組織及び技術領域において、何を大事に何に投資していくかといった未来の構想や方向性をまとめたものになります。

Tech Visionのスコープ

環境変化に適応するために2つのフェーズに分けることでスコープを明確にしています。

今回Phase2に突入したため、Phase1の成果を振り返りつつ、新たな戦略を追加しました。

Phase1

  • 2021年〜2023年

Phase2

  • 2023年〜2025年

戦略のアップデート

ここからはアップデートを行ったそれぞれの戦略について、具体の内容とその背景について説明していきます。

Phase2においては、元々5つあった戦略のうち2つを完了と位置づけ、「Run with Tech」という新しい戦略を含めた4つの戦略を制定しました。

各内容のアップデートにおいて、現場のエンジニア主導で、これまでの振り返りとPhase2で目指すべき方向性を踏まえて議論を行いました。

Phase2の戦略

スーパーモブ

内容 - クロスファンクショナルチームを組成し、開発基盤の強化や開発体験の向上を図る

目的 - 人が増えても入れ替わっても開発の質と速度が落ちないようにするため

Phase1において、通常タスクの中でPHPのバージョンアップをする仕組みが整ったり、本番データの開発環境への同期を行ったりと、普段のプロダクト開発チームの枠を飛び越えたエンジニアの交流と技術面での成長の促進に繋がる取り組みが活性化しました。

Phase2においてもこの取り組みを継続していくことで、エンジニアの成長を促進し、組織としての技術力向上を目指しています。

Run with Tech【New】

内容 - 世の中のテクノロジーの成長と共にコネヒトも成長し、新たな価値を生み出しステークホルダーを喜ばせる

目的 - 新しいテクノロジーを導入し、ユーザー体験の革新、競争力の強化、業務効率の向上、生産性と提供価値の最大化を図り、「DevとBiz」の垣根を越えて次世代の働き方を体現するため

2023年から、生成AIをはじめとしたテクノロジーの活用を推進する「Run with Tech」というプロジェクトがスタートしました。短期的には、テクノロジーを活用した業務効率の向上を目指しており、すでに100時間以上の業務時間削減の成果も出てきています。

実行プロセスの中でBizメンバーの可能性を広げることと、余白を生み出した先に新たな価値創造をしステークホルダーを喜ばせることをゴールに目指します。

Failable System

内容 - 失敗が出来る(失敗しても問題ない、失敗が評価される)システムと組織をつくる

目的 - 大きな成果が期待できるチャレンジを後押しするため

不確実性の高い現代の市場環境において、失敗を恐れずにチャレンジを続けることが違いを生み出す上で重要だと考えています。

この戦略を掲げることで、失敗がしやすいシステムや仕組みの構築に投資するという意思表示としています。 加えて、評価制度においてもチャレンジをしっかりと評価することで、エンジニアが積極的にチャレンジを続けて競争力の源泉になりうる環境を作り出していきます。

1to1 AI

内容 - 一人一人に最適化された情報をデータや機械学習を用いて提供する

目的 - 単一の情報をブロードキャストするのではなく、それぞれの家族に寄り添った情報を提供すること、および大量の非構造化データを活用するため

Phase1において、プロダクトへのレコメンドの複数導入や検索システムの内製化にトライしてきました。

マス向けの情報提供では届けられない価値をユーザーに提供するために、特定の技術には固執せずにこれからも様々な可能性を探りながら、トライを続けていきたいと思っており、ママリというメインプロダクトにおいては一番の投資分野として位置づけています。

Phase1で完了した戦略

3人に1人

内容 - 社内のエンジニア比率を33%以上にする

目的 - 会社としてやりたい事業を全て実現するため - 技術の力で、プロダクトだけに留まらず社内の課題も解決するため

Phase1制定時はエンジニア数が少なく、各所でエンジニアの不足を感じていたため、エンジニアの比率を上げる取り組みを行いました。

結果として、優秀なエンジニアを多く採用することができ、Run with Techに代表されるようなプロダクト開発に閉じない新たな取り組みを行えるようになったので、この戦略自体はPhase1で完了と位置づけしました。

Let's Go

内容 - バックエンドのシステムにGoを積極的に導入する

目的 - Go言語の採用により、技術的な選択肢を増やすため

Phase1制定時は、ほぼすべてのプロダクトでPHPを採用していましたが、技術的な選択肢を増やすためにGo言語の採用を進めました。

結果として、検索APIやメインシステムへのGo言語の一部導入を通じ、Go言語を書けるエンジニアが増え、コネヒトの技術スタックの選択肢の1つになったので、この戦略自体はPhase1で完了と位置づけしました。

これから

Phase1の振り返りを通じて、各戦略確実に制定時よりも前に進んでおり、Tech Visionという羅針盤を掲げる効果性を感じることができたと考えています。

ここで紹介した戦略はエンジニア中心に取り組むものが多いですが、このTech Visionは全社員が一丸となって取り組むものと位置づけており、アップデートのプロセスにおいても、経営メンバー全員が読み込みやFBを行って今回のアップデートに至りました。

このTech Visionを持続的にアップデートして、実行していくことがコネヒトの技術への投資スタンスを示すものだと考えており、全社一丸で実行力をもってビジョンの達成に向かっていきたいと思っています。

hrmos.co

ママリで使用している Aurora MySQL のアップグレード(v2 から v3)を行った EOL 対応プロジェクトの進め方を振り返る

こんにちは。コネヒトでは Aurora EOL 対応芸人となっているささしゅう(@sasashuuu)です。本日は、コネヒトを代表するサービス「ママリ」のデータベースを Aurora MySQL v2 から v3 へアップグレードした際のプロジェクトの全容をお伝えしたいと思います。

はじめに

まず、ママリというサービスと Aurora の構成について触れておきます。 ママリは、子育て Q&A アプリおよび情報サイトを通じてママ向けのサービスを提供しています。詳細や各種サービスの利用については、弊社ホームページをご覧ください。

connehito.com

現在のママリの主要な AP サーバーとデータベースの構成は以下の通りです(※具体的なサーバーの台数については図では省略)。

AP サーバー構成

用途 利用サービス サーバー台数
Q&A アプリ用 AP サーバー(Native アプリ API 向け) ECS Fargate 4 ~ 30タスク
(サービスは1つ)
Q&A アプリ用 AP サーバー(Web アプリ向け) ECS Fargate 2 ~ 4タスク
(サービスは1つ)
情報サイト用 AP サーバー(Web アプリ向け) ECS Fargate 4 ~ 20タスク
(サービスは1つ)

データベース構成

用途 利用サービス サーバー台数
ママリ共用 RDB Aurora MySQL v3 2インスタンス
(リーダー・ライターそれぞれ db.r6g.4xlarge)

※Aurora に関してはレプリカの Auto Scaling により必要時にスケールイン/アウトの設定あり。

※アップグレード前は db.r4.4xlarge が 3 台の構成(アップグレードの機会に見直しを実施)。

プロジェクトの進め方の全体像

プロジェクトの進め方は以下のフローで行いました。本記事では1つ1つのトピックの詳細な解説は省略しますが、どういったフローでアップグレードに向けた作業をおこなっていたのかをざっくりとイメージしていただけると幸いです。

プロジェクトの構成

プロジェクトのメンバーは基本的にインフラエンジニア1名とアプリケーションエンジニア(サーバーサイド)1名の体制で臨みました。作業が増えるフェーズではエンジニアを増員し(最大5名程度)、手分けして作業を行いました。主に CI・Dev 環境でのテストや動作確認、不具合修正対応のフェーズで特に人手が必要でした。アサインと業務分担については、インフラエンジニアとアプリケーションエンジニアの作業領域を分けつつ、必要に応じて互いに協力し合いました。下記は先ほどのフローに担当領域を示した図です。青色がインフラエンジニア、赤色がアプリケーションエンジニア、共に重なっている箇所は両方が担当しました。

良かった点

EOL 対応を進める上で特に良かった点をピックアップしていきます。

MySQL Shell アップグレードチェッカユーティリティの活用

MySQL Shell の アップグレードチェッカユーティリティ という機能があります。これは MySQL5.7 から 8.0 へのアップグレードに伴う互換性に関するエラーや問題を検知してくれるツールです。Aurora というマネージドサービスを使用している都合上一部正常にチェックできない項目もありますが、基本的な互換性はありますので十分に活用できる印象です。以下は今回アップグレード対象だった Aurora v2(MySQL5.7) へ実行した結果の例を一部記載したものです(※一部マスク処理あり)。

接続

mysqlsh -u xxx -h xxx -P xxx -p --ssl-ca=xxx

アップグレードチェッカーの実行

 MySQL  xxx:xxx ssl  JS > util.checkForServerUpgrade()
The MySQL server at xxx:xxx, version 5.7.12-log - MySQL Community
Server (GPL), will now be checked for compatibility issues for upgrade to MySQL
8.0.32...

中略

1) Usage of db objects with names conflicting with new reserved keywords
  Warning: The following objects have names that conflict with new reserved
    keywords. Ensure queries sent by your applications use `quotes` when
    referring to them or they will result in errors.
  More information:
    https://dev.mysql.com/doc/refman/en/keywords.html

  xxx.xxx.rank - Column name
  xxx.xxx.rank - Column name
  xxx.xxx.rank - Column name

4) Usage of utf8mb3 charset
  Warning: The following objects use the utf8mb3 character set. It is
    recommended to convert them to use utf8mb4 instead, for improved Unicode
    support.
  More information:
    https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8mb3.html

  xxx - schema's default character set: utf8
  xxx.xxx.xxx - column's default character set: utf8
  xxx.xxx.xxx - column's default character set: utf8
  xxx.xxx.xxx - column's default character set: utf8

以下略

上記の例では、MySQL8.0 で予約キーワードとなる rank カラムを使用している箇所や、MySQL8.0 で非推奨となる utf8mb3 を使用している箇所などが検知されました。

CI の活用

ママリの開発では GitHub Actions による CI/CD を構築しています。このワークフロー上では PHPUnit による自動テストが実行され、アプリケーションのデプロイ前に問題があればワークフローで異常を検知できます。Dev や Prd 環境のアップグレード前に、このワークフロー上で使用している MySQL のイメージを MySQL5.7 から 8.0 へ変更しテストすることによって、アップグレードにおける不具合を効率よく検知することができました。以下はワークフローの設定ファイルの例です(※一部マスク処理あり)。

name: Pull request
on:
  pull_request
env:
  AWS_ROLE_ARN: xxx
permissions:
  id-token: write
  contents: read
jobs:
  php:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:8.0 # 5.7から変更

中略

      - name: Run phpunit
        env:
          xxx: xxx
          xxx: xxx
          xxx: xxx
          xxx: xxx
        run: vendor/composer/bin/phpunit -d memory_limit=512M

以下略

CLI ベースでの手順構築

Aurora のアップグレード方法には様々な手法がありますが、弊社では AWS CLI を使用したオペレーションを採用しました。CLI ベースだと移植性が高く、順序立てた手順の構築がしやすいというメリットが大きいと感じたためです。個人的な見解になりますが、各アップグレード方法の内容について比較したものは以下となります。

アップグレード方法の比較

メリット デメリット
コンソール GUI による直感的な操作が可能 移植性が低い(リソースのリンクやキャプチャを手順に埋め込んでいる場合、他のデータベースのアップグレード作業でも使いまわしづらい)
AWS CLI ・移植性が高い(他のデータベースのアップグレード作業でもパラメータを変えて使いまわしやすい)
・IaC に比べ順序立てた手順が作りやすい
コマンド実行時のコピペミス等によるリスクがある
IaC ・(コードの)バージョン管理やレビューのしやすさがある
・fix したコードを使用するためオペミス等のリスクが減る
順序立てた手順を実行する観点で扱いが難しい(例として段階的なバージョンアップグレードが必要であったり、アップグレードとインスタンスクラスの変更を同時に行えない問題がある)

CLI を用いたアップグレードについて実際の使用例を一部ご紹介します。弊社の場合、Notion であらかじめ手順書を作成し、作業時にコマンドをコピーアンドペーストで実行していくという方法を取っていました。

RDS Blue/Green Deployments の利用

今回のアップグレードでは Amazon RDS Blue/Green Deployments を利用しました。Green 環境の構築および Blue 環境とのレプリケーションからスイッチオーバーによる切り替えを提供してくれる機能です。以下の手順でアップグレードを行いました。

  1. Green 環境の作成
  2. Green 環境のアップグレード
  3. Green 環境への DDL 実行
  4. スイッチオーバー

良かった点は、事前に必要な作業を Green 環境で済ませておくことによって、サービスの計画停止の時間を短縮できることでした。特に今回はエンジンのアップグレードに加え、アップグレードに伴う DDL の実行(※後述)も必要であったこともあり、計画停止の前段階でネックとなる作業を終わらせることができました。ただし、Green 環境への DDL 実行は基本的に推奨されていない(サポートの方へ確認済み)ことから、実施する場合はリスクを承知の上で行う必要があります。

チームや専門領域を跨いだエンジニア間の定期的なコミュニケーション

1〜2週間に1回程度、インフラエンジニア・アプリケーションエンジニアが同期を取り連携していました。互いの進捗や状況を共有することで、発生している問題や課題が把握できたので、プロジェクト全体で見た際の人的リソース調整などが上手く行えていたように感じます。また、インフラエンジニアのみでは把握しづらい開発組織全体への影響を考慮した舵取りをよりしやすくなったのも良いポイントだったと思います。

プロジェクト内で共通のカンバンを使用する

所属チームや取り扱うサービスにより issue やタスクカード等の置き場所が異なる弊社ですが、基本的に EOL 対応のプロジェクトでは共通のものを使用するようにしました。 プロジェクト全体の状況が一元的に管理しやすくなるのでオススメです。

弊社の場合、Notion のデータベース等を活用していました。 下記は実際に使用していたものの一例です。

タスク管理
発生した問題等の管理

反省点・課題

続いて EOL 対応を進める上での反省点や課題をピックアップしていきます。

通常のアプリケーション開発業務との並行運用

Dev 環境アップグレードから Prd 環境アップグレードまでにバージョンの乖離期間があり、その期間に通常のアプリケーション開発に支障をきたすことがありました。Prd 環境がまだ MySQL5.7 であるもCIの環境を 8.0 に変えたことにより、CI をパスしたとしても Prd 環境での動作の担保ができない状態になっていました。Prd リリース前にシステムの異変を検知するという CI の目的を踏まえると、Prd 環境と同じ 5.7 で CI が通れば Prd リリースして良いことになります。ただタイミング悪く乖離期間にリリースが重なってしまったものがありました。5.7 ではなく 8.0 を使用した CI でテストを通した結果、テストが落ちてしまうということがありました。これに関しては旧バージョンと新バージョンの CI を構築し、どちらでもテストおよびリリースが可能な状態にする対策を取りました。また、次回以降の EOL 対応では対象データベースに関わる開発チームから1名以上をアサインしてもらい、EOL 対応と通常のアプリケーション開発業務をよりうまく調整しながら進めていけるようにする対策を考えました。

計画停止作業の影響範囲の認知負荷

今回のアップグレード作業では、夜間に計画停止を行いました。影響範囲が広く、認知負荷も高い状態でした。影響のあるサービスにはメンテナンス画面を出したり、監視システムを無効にしたりする対応が必要で、ステークホルダーに対して利用停止を告知・依頼する手配も必要でした。この点においては今後認知負荷を軽減していけるように情報を集約していく必要があると感じました。

バイナリログレプリケーションを使用していた場合の Amazon RDS Blue/Green Deployments の利用

ママリのデータベースは to C 向けのサービスでの利用がメインですが、分析用に RDS for MySQL へのバイナリログレプリケーションも行っていました。

Amazon RDS Blue/Green Deployments では仕様上バイナリログが引き継がれないという問題がありました。下記のように Blue/Green 環境のスイッチオーバー後は、Blue 環境で使用していたバイナリログは引き継がれないため、スイッチオーバー後はそのままレプリケーションの再開が行えないというものです。

スイッチオーバー前の状態

スイッチオーバー後の状態

そのため以下の手順でオペレーションを行う必要がありました。

  1. スイッチオーバー前に Blue 環境で目印となるクエリを実行
  2. Blue 環境と分析 DB のレプリケーションを停止
  3. Blue/Green 環境のスイッチオーバー
  4. Green 環境にて目印のクエリが含まれたログファイルを dump
  5. 目印のクエリのファイル名・ポジションをもとに Green 環境と分析 DB のレプリケーションを再開

このように、RDS for MySQL とのバイナリログレプリケーションを構築している場合、特殊なオペレーションが発生するため注意が必要です。

想定外のスロークエリの発生

SELECT COUNT(*) のクエリが遅くなる事例はいくつかあるため事前にチューニングを行っていましたが、Prd アップグレード後に別種のスロークエリが発生しました。以下のような構文のクエリでした(※一部マスク処理あり)。

SELECT
    `xxx`. `xxx`,
    `xxx`. `xxx`,
    `xxx`. `xxx`,
    ...中略
FROM
    `xxx`.`xxx` AS `xxx`
        LEFT JOIN
    `xxx`.`xxx` AS `xxx` ON (`xxx`.`xxx` = `xxx`.`xxx`)
WHERE
    `xxx`.`xxx` >= xxx
        AND (NOT (`xxx`.`xxx` = xxx)
        AND NOT (`xxx`.`xxx` = (xxx)))
        AND `xxx`.`xxx` = xxx
        AND `xxx`.`xxx` = 'xxx'
        AND `xxx`.`is_hoge` = '0'
ORDER BY `xxx`.`xxx` DESC
LIMIT xxx;

is_hoge(仮名) という boolean のカラムを使用していましたが、比較演算子を等価から不等価に変更することでパフォーマンスが向上しました。

修正前

`xxx`.`is_hoge` = '0'

修正後

`xxx`.`is_hoge` != '1'

変更前のクエリは実行計画で Using temporary, Using filesort が発生していたのですが、比較演算子の変更によりこれらは解消されました。 なぜこのスロークエリが発生したのか、また等価比較の変更でなぜ Using temporary, Using filesort が解消され、パフォーマンスが向上したのかは不明です。 とはいえ事前検証をもう少し入念にしておけば Prd 環境のアップグレード後に慌てる必要はなかったため反省点でした。

非推奨文字セット・照合順序変更の DDL の対応コスト

MySQL8.0 から utf8mb3 が非推奨になります。デフォルトの文字セットが utf8mb4 になり、照合順序が utf8mb4_0900_as_ci となる仕様変更もあります。utf8mb3 を使用している箇所があったため、アップグレードに伴いデフォルトの文字セットおよび照合順序を変更する DDL を実行しました。DDL の実行には数時間(おおよそ3時間程度)かかりましたが、事前に Green 環境で実施したため、運用中のデータベースや計画停止作業に影響はありませんでした。ただし、事前対応の準備コスト(DDL 実行時間を見積もった上で逆算し、 Green 環境の構築と DDL 実行を行う等)があるため、場合によっては他の方法を検討する必要がありそうです。

おわりに

色々と大変なことはありましたが、Aurora MySQL v2 の EOL 対応を無事に終えることができました。個人的には弊社の場合だと v1 から v2 へのアップグレードよりもネックとなるポイントが多く、難易度が高かったように感じました。今回はコネヒトにおける事例を紹介しましたが、これから v2 EOL 対応を控える方々の参考になれば幸いです。頑張ってください!それではさようなら!

生成AIなどのテクノロジーの力でビジネス成長を目指す『Run with Tech』の活動紹介

こんにちは。CTO室プラットフォームグループに所属している @yosshiです。

今回、私が参加している「Run with Tech(以下、ランテク)」というチームの活動内容についてご紹介させていただきます。

目次

ランテクについて

コネヒトでは、Tech Visionの中でBeyond a Tech Companyというビジョンを掲げています。

ランテクは、このビジョンを実現するために2023年12月に設立されたチームで、生成AIをはじめとするテクノロジーの力を活用し既存の課題解決や新たなビジネス創出を目指した活動をしています。

具体的には、生成AIをはじめとしたテクノロジーの活用により社員の時間の余白を作ること、またテクノロジーに関する基礎知識の向上・スキルアップを図ることを目指しています。

現在はCTO・エンジニアなど5名のメンバーを中心に運営しています。

なぜやるのか?

こういった社内のテクノロジー活用を推進する場合、業務改善・BPRの側面が強くなりがちなのですが、目標としてはもう少し視点を前に、既存の改善だけではなく「新たなビジネス創出と成長、ステークホルダーへの価値提供」という部分を目指しています。

生成AIの誕生により、今後BizとDevの境界は今後どんどん曖昧になっていくと思うので、コネヒトではBiz/Devの垣根を超えて、それぞれの立場から必要なテクノロジーを活用する「アフターテックカンパニー*1」を目指していきたいと考えており、ランテクの活動はその状態を実現するために非常に重要な取り組みだと捉えています。

活動事例

ランテクでは2023年12月の活動スタートから、小さいながらも少しずつ成果が出てきたので、その中の活動内容・実績についていくつかご紹介したいと思います。

事例一覧

事例①:全社向け生成AI教育
事例②:生成AI利用時のプロンプト事例の共有
事例③:経営層向けの生成AI活用課題
事例④:記事タイトル生成時の生成AI活用(削減時間:10.5時間/月)
事例⑤:インスタグラム 記事情報取得の効率化(削減時間:3.75時間/月)

事例①:全社向け生成AI教育

まず、生成AIを身近なものに感じてもらうため、コネヒト全社員向けに生成AIに関する基礎教育を行いました。

生成AIとは何か?の基本的な説明から、実際に生成AI(ChatGPT)に触れてもらうところまでを一つのコンテンツとして提供しました。

スライドの一部抜粋

アンケート結果

また、教育終了後にアンケートも実施しました。

このアンケートはランテクの活動が始まってから定期的に実施しており、教育以降で生成AIに関する期待感が高まったこと・実際に利用する人が増えたことを実感しました。

<業務において生成AIを使う頻度は?>

<生成AIを利用することにより業務価値を上げられるという自信はありますか?>

※2023/12〜24/3の社内アンケートの実績。回答数:12月51名、1月46名、3月48名、

事例②:生成AI利用時のプロンプト事例の共有

生成AIの基礎教育だけではなく、プロンプトエンジニアリングのノウハウを共有しています。

これによって、実際に生成AIを使う際に、少しずつより精度の高い回答を得られるようになってきているように感じます。

共有したプロンプトの例


※ 2024年3月時点で有効とされているものを紹介しています。

事例③:経営層向けの生成AI活用課題

経営メンバーに対して生成AIに関する課題を出して、実際に取り組んでもらいました。

社内全体で取り組むにあたって、ボトムアップももちろん必要ですが、経営メンバーが生成AIを武器として使いこなし、その様子を見せてもらうのも大事だと思います。

具体的には、事業部を統括する立場や経営の立場から考える課題など、以下のような課題に取り組んでもらいました。

主な課題はこちら

技術課題①:マイGPTsを作ってみよう

技術課題②:管掌領域における生成AI活用案だし

戦略課題①:生成AI時代における会社の「事業」を考える

戦略課題②:生成AI時代における会社の「組織」を考える

また、取り組んでもらった課題については、後日全社員に向けて共有してもらいました。

共有会の様子はこちら

課題に取り組んでみて 経営メンバーの感想

発表会に出席した社員の感想

また経営メンバーの発表会を受けて社員から多くの感想が寄せられたので一部ご紹介します!

  • 生成AIはもちろん、経営がどう組織を考えているのか?をキャッチできるとても良い会だったなと思いました!ランテクの皆さん、経営の皆さん運営・準備ありがとうございました〜!
  • きれいに議論されたアウトプットではなく、個々がさまざまな粒度で考えた話を聞けたので生成AIに対してさらにワクワク感が高まりました!あとはちょうどどんなビジネスマンになりたいのか・・を最近もんもんと考えているのでヒントになりそうなありがたい会でした!
  • 生成AI活用による生産性や効率アップなど価値メリットに視線が集まる一方で、それが一般化した未来を考えたとき、家族をテーマに扱うコネヒトが社会に対してどのようなサービスを届けるべきか、あるいはどのような組織であるべきかを、あらためて思考したいなと思いました。

また、早速 取締役 Captainの@itoshoさんがこの課題で取り組んだ内容をブログに書いてくれました。

興味ある方はこちらもぜひご覧ください!

tech.connehito.com

事例④:記事タイトル生成時の生成AI活用

弊社のWEBサービスであるママリでは、記事編集時にタイトリングをする必要があります。

その際、メンバーによっては適切なタイトリングに悩むケースがありました。

そこで、編集経験や知見に関わらず、誰でも良いタイトリングができるように生成AIを活用することにしました。

生成AIの利用にあたり、ツールは弊社内で作成しているSlack上で動作する自作の生成AI Botで対応しています。

弊社のSlack Botについて詳しく知りたい方は、こちらの記事をご覧ください。

tech.connehito.com

tech.connehito.com

質問文

回答

プロンプトの工夫点として、過去に実際に反応の良かった記事タイトルを参考例としてChatGPTに与えているのですが、それによって生成AIが考えてくれるタイトル候補が、普段ママリがつけているものに近いものになったように感じます。

事例⑤:インスタグラム 記事情報の取得

これまでの流れでは、生成AIの事例が多くなってしまいましたが、ランテクでは生成AIに絞らず、状況に応じて別の技術も使用しています。

例えばこちらは、GAS(Google Apps Script)とインスタグラムのグラフAPIを利用して、Bizメンバーの業務を改善した事例となります。

弊社ではSNS運用やSNS投稿の記事化に力を入れているので、さまざまなアカウント情報を取得する機会があります。

これまではアカウントごとに直接インスタグラムの画面を見ていましたが、インスタグラムのグラフAPIとGASを利用することにより、特定ユーザーの投稿情報を自動取得してスプレッドシート上に転記する、という仕組みを作りました。

<取得した記事情報>

最後に

これまでに記載した通り、ランテクでは様々なテクノロジー活用に関する取り組みを実施しています。

コネヒトでは、新入社員が活躍しやすい環境を整えるため、3ヶ月間のオンボーディング期間を設けていますが、最近その教育プログラムの一環として、生成AIに関するトレーニングを追加しました。

Biz/Devに関わらず、社員全員がコネヒトに所属することで当たり前のように生成AIやテクノロジーを活用することができる状況を作り出し、最終的には全社員でビジネスの成長・ステークホルダーへの価値の提供を目指していきたいと思っています。

※このブログはChatGPTに壁打ちをしながら執筆しました。また、OGP画像もCanvaの生成AI機能を利用して作成しています。

*1:コネヒトのTech Visionの中で掲げている目標。テクノロジーを中心に据えつつもBizやDev、開発やセールスといったラベルを曖昧にしたテックカンパニーのことを指している

ユーザーとの距離を近くするために、ユーザーインタビュー実施のプロセスを自動化し、リードタイムを減らした話

こんにちは。今年の 4 月からプロダクトマネージャーになった@TOCです。 私は 3 月まではエンジニアとしてプロダクトマネージャーと一緒にユーザーとの距離を近くするための取り組みをいくつか行っていました。 本記事ではその取り組みの一つとして週一ユーザーインタビューの実現のために行ったインタビュー実施までのプロセス改善についてご紹介します。

(現在はプロダクトマネージャーですが、この記事ではエンジニアとしての帽子を被って記載します)

はじめに

プロダクト開発において、ユーザーの声を直接聞くことはとても大事な機会です。開発チームが直接ユーザーと対話する機会を増やすことは、リアルなフィードバックを得る上で非常に効果的だと思います。

コネヒトでは以前から定期的にユーザーインタビューを行っていましたが、実施の頻度としては 2~3 ヶ月に 1 回行うような状態でした。この頻度では、ユーザーのニーズの変化に迅速に対応することは難しく、また新たなアイデアを試す機会も限られてしまうように感じていました。

そこで私たちは、直近のゴールとして「週に 1 回はユーザーと話せる状態を実現する」ことを目指しました。この目標を達成する上で、どこがハードルになっているのかを プロダクトマネージャー(以下 PM) と話してみると下記のような課題感がありました。

  1. インタビュー企画から実施までの流れが属人化しており、1 人の PM しかできない
  2. 日程調整など実施プロセスを手動で行っており、実施までの運用コストがかかる

ユーザーとの距離を近くしたい、そのためにユーザーと頻度高く会話できる状態を作りたいのに、リードタイムが長いが故に実現できていない状態となっていました。この状態を解決するために、プロセスを効率化する必要がありました。

まずは業務フローを洗い出し、体験する

プロセス改善をするためには、まずその実態を知るのが手っ取り早いと思っています。なので、実際のフローを自分で行ってみて「どこに課題感があるのか」、「改善できるポイントはどこにあるのか」を特定するところから始めました。

実際に行ってみると、かなり手間のかかる作業であることがわかりました。 その中でも特に改善できそうなポイントが下記でした。

  • メールを候補者ひとりひとりに手動送信している。
  • メールの送信文をコピペして手動で書き換えている。
  • インタビュー予定が入ったことが PM しかわからない。入ったことを PM が Slack で周知する。

また、当時利用していた日程調整サービスもサービス終了のタイミングを迎えたところでした。 以上を踏まえて以下の改善を行うことにしました。

  1. 日程調整を自動化し、ミスが極力起きない運用にする
  2. より使いやすい日程調整ツールを選択する
  3. インタビュー予約が入った時に全体に周知し、見える化する

以下でどのような改善を行ったかを説明します。

プロセスの改善を行う

プロセス改善のために行った取り組みを 3 つ紹介します。

1. GAS を使ってメール送付を自動化

まず、 1 人ずつ手動で送っていたメール送付を、Google App Script(以下 GAS) を利用して一括送信できるようにしました。 GAS を使ったメール送信の方法は世の中にたくさん情報が出ているので詳細は省きますが、スプレッドシート上にメールアドレス、名前、担当者名を記入し、メール送信ボタンを押すと各項目の値が挿入されたメールが一括送信されるものを作成しました。

ほとんど他サイトを参考にして、ざっと作ったものになりますがコード内容を記載しておきます。

これによりメール送信の工数削減だけでなく、コピペをする際のミス防止にも繋がります。 もちろんこれで 100%ミスを防げるかというとそうではないですが、必ずテスト送信を行ってから本送信を行う、慣れてない人がやる時はモブ作業で画面を映しながら行うなど、極力ミスが起こりにくいオペレーションを行っています。

2. 日程調整は専用ツールに任せる

元々日程調整ツールは利用していましたが、利用サービスの終了に伴い、日程調整ツールも見直しを行うことにしました。日程調整ツールも様々なツールが世にありますが、最終的には TimeRex というサービスを選択し、現在も利用しています。

かなり具体的な方法にはなりますが、どういった形で TimeRex を利用しているのかの大枠をご紹介いたします。

  1. ユーザーインタビュー用のカレンダーアカウントを作成する
  2. TimeRex のアカウントを作成し、連携カレンダーを 1.で作成したカレンダーにする
  3. TimeRex でインタビュー用のカレンダーを作成する
  4. 日程調整用の URL から日程調整を行う。ユーザーインタビュー用のカレンダーに予定が入れば OK

もし、上記を行う場合、TimeRex のカレンダー設定は状況に合わせて変えていただければと思います。 一つちょっとした工夫点でいうと、弊社では固定のユーザーインタビュー時間を決めて設定をしています。例えば、火曜 10:00~11:00、水曜 17:00~18:00 など決めて、インタビュアーを担当する社員の予定はブロックしておきます。TimeRex でも日程候補の日時は細かく時間単位で設定できるので、固定のブロック時間に合わせて予約できる時間を設定しています。この固定枠を決めておく方法はタイミーさんの事例を参考にさせていただきました。

speakerdeck.com

上記によって、1 週間の中で固定のユーザーインタビューの時間を確保して、インタビューが入れば対応できる状態を作りました。

3. 日程が決まったら Slack に自動で通知をし、同席者を決める

最後にインタビュー予定が入ったら通知が来るようにすれば、インタビューのアサインなどもスムーズに行えそうです。 これは TimeRex が Zapier 連携できるので、その機能を利用しました。 設定は至ってシンプルで、TimeRex でイベント作成されたら Slack 通知する、というワークフローを組んでいます。

Zapier のワークフロー

イベントが作成された場合は下記のような通知がされます。

イベント作成通知

また、キャンセルをした際にも通知できます。

キャンセルの通知

このように通知をすることでインタビュー予定にすぐ気づけるようになります。 また、この投稿を利用することでインタビュー同席者の募集や立候補もしやすくなりました。

インタビュー同席者の募集

Zapier 連携を利用することで簡単に自動化できますので、もしよければ試してみてください。

どう変わったか

3 つの取り組みを改めてまとめると下記のようになりました。

改善のまとめ

どの取り組みも比較的ライトに実現ができました。これにより募集からユーザーインタビューまでのリードタイムが削減されました。 例えばメールを送る作業は、 1 人に対して確認も含め 3 分ほど使っていたのが、人数が増えても全員に対して 5 分ほどでメールを送れるようになりました。 何より、作業が簡略化されたことにより、他の PM への展開もしやすくなったので、今後ユーザーインタビュー文化を広げる足がかりになったかと思います。

歩み寄ることの大切さ

この取り組みは同じチームの PM と会話しながら実現をしました。もともと結構面倒な作業をしていたのは感じていたのですが、実際に自分がやってみると「これは面倒だね。こうしてみたらどう?」という提案をすることができました。

エンジニアは面倒なことを効率化することに関して、ある程度の知識があるし、効率化が好きな人は結構多いんじゃないかな、と思ってます(自分もそう)。 そんな自分が他の職種の人の作業を見たり、話したりすると「言ってくれれば、この作業もっと簡単にできたのに」と思うことが結構あったりします。 「時間取っちゃって申し訳ないから」という話を聞くこともあるのですが、「面倒なことに時間使う方がもったいないから全然声かけてくれて大丈夫!」という気持ちになります。

でもこれはエンジニアからも歩み寄ることも大事なんだろうな、と。

僕もやりがちですが、改善したいことを聞くと「そもそも何でこれをやるの?」「これってどういう意味があるの?」って聞いちゃいがちです(言い回しはもっと柔らかくしますが)。言われた方は「え、なんか困らせてるかな」という印象を受けるかもしれないですが、僕としては「もっとよくできないか、もっといい解決策はないか」を考えて聞いてることが多いです。でもそれは言わないとなかなか伝わらないことでもあるので、僕(エンジニア)から伝えていくことが大事なのだと思っています。

「困ったな、この作業面倒だな」と感じてる人は

  • 具体の解決方法はなくていい。「〇〇したい」レベルでいいので、声をかけてみよう。
    • 「さてさて、改善しちゃおうかな」と腕まくりしてくれる人がきっといる。

「困ったな、この作業面倒だな」と感じてる人を見た人は

  • 一緒に体験してみる。
  • 「こうしたら解決できるよ〜」を作っちゃって、動くもので見せちゃう。

こういったことをすると、「困ったときに解決できるかも」という雰囲気を作るきっかけになるかもしれません。