Medley Developer Blog

株式会社メドレーのエンジニア・デザイナーによるブログです

メドレーでセキュリティエンジニアとして働くということ

はじめまして。メドレーでセキュリティエンジニアをしている三浦です。

私はメドレーには今年(2021年)の2月に入社し、このブログを執筆している時点で入社4ヶ月目となります。現在、全社的なセキュリティを担当しています。

今回のブログは以下のような構成でお届けします。

目次

  1. 自己紹介と、本ブログのテーマについて
  2. 前職でのセキュリティエンジニアとしての仕事
  3. メドレーでのセキュリティエンジニアの仕事
  4. セキュリティエンジニアとしての活動内容や役割の違いと気づき、課題
  5. セキュリティエンジニア募集中!

自己紹介と、本ブログのテーマについて

私は前職でセキュリティ専業会社のセキュリティエンジニアとして脆弱性診断やペネトレーションテストのほか、セキュリティ研修の講師、ファイアウォールやWebアプリケーションファイアウォール(WAF)と呼ばれる機器の導入支援などに携わっていました。

このなかでも脆弱性診断の案件に多く関わっていたこともあり、最後には脆弱性診断のサービスオーナーとしてサービスに関わるすべてを取りまとめる立場でした。

今では事業会社のセキュリティエンジニアとして活動しているわけですが、このブログではセキュリティエンジニアとしての活動内容や役割にどのような変化があり、その変化により直面している自分自身の課題や苦労について書いていきます。

前職でのセキュリティエンジニアとしての仕事

先述のとおり前職では脆弱性診断に関わることが多かったため、ここでは脆弱性診断について取り上げます。

脆弱性診断はスポット案件として実施することがほとんどでしたので、案件の流れという観点で仕事内容を整理すると以下のようになります。

  1. 営業フォロー(同行やQ&Aなど)
  2. スケジュールや診断対象などについてお客様にヒアリング
    1. ここで診断用環境の準備をお願いすることが多い
  3. 診断対象の調査、クロール作業
  4. スケジュール感や制限事項についてお客様とすり合わせ
  5. 計画書を作成
  6. 社内で計画書レビュー、お客様へ送付
  7. 診断作業
    1. 自動診断ツールの調整
    2. 手動診断の実施
    3. 出力結果の精査、再現性の確認
    4. 速報があれば当日中に整理して送付
  8. 診断結果のエビデンス整理
  9. 報告書の下書き、リスク度合いの検討
  10. 社内で報告書レビュー
  11. お客様へ報告書を納品
  12. 報告会の実施

このなかで、特に診断担当者の技術的スキルが問われたのが「手動診断の実施」と「出力結果の精査、再現性の確認」で、全体のうち約4割ほど。残りはドキュメント作成、レビュー、ミーティング、業務改善といった定型業務が占めていました。

私は「この4割の部分に対して付加価値を提供したい」というエンジニアとしての気負いと、個人的な関心という2つの理由から、寝る時間を削っては脆弱性の悪用(Exploit)手法の習得と、知識的な補強としての資格取得に明け暮れる時期がありました。

結局、寝不足が続いたことが原因で肺炎を発症し、入院一歩前まで炎症マーカーが悪化するという自分自身の脆弱性が露呈することになったのですが。ちゃんと夜は寝ましょう。

話がすこし脱線しましたが、脆弱性診断やSI案件などは年度末にピークを迎えるものの年間を通じて五月雨で受注することも多く、一定の品質を維持しながらも納期を守るために目の前の案件で必死だったというのが今までの仕事のスタイルでした。

目の前の案件をひたすらこなし、組織に対して「報告書を提出して終わり」の関わり方に対して『これで社会の役に立っているのだろうか』という疑問が生まれたことが、メドレーに入社する転機になっています。

メドレーでのセキュリティエンジニアの仕事

さて、セキュリティサービスを提供する側で案件に追われていた私がメドレーでセキュリティエンジニアとして活動することになっているわけですが、具体的に今なにをしているのか?というと、大きくは以下の6つが挙げられます。

  • 自社サービスに対する脆弱性診断
  • 脅威情報や脆弱性情報の収集、周知
  • 全社的な業務プロセス上のリスク調査
  • 全社システムのBCP整備、保守
  • ISMS運用
  • セキュリティ相談

自社サービスに対する脆弱性診断というのは「脆弱性診断の内製化」で、脆弱性診断を外部の業者にお願いするのではなく自社内で実施して開発にフィードバックする形です。

内製による診断であっても、基本的な流れはすでにご紹介した流れで進めていますが、対象サービスをクロールしてから診断対象を確定させるまでの主要なポイントでは、操作手順に漏れがないかなどの観点で開発からのレビューを挟むようにしています。これは内製であるからこそ実現できているアプローチだと思います。

f:id:medley_inc:20210527151142p:plain
内製で実施している診断対象一覧の例

なお、ここまで脆弱性診断について書いてきましたが、これは現在の業務のほんの一部で、このほかにはISMSの運用(事務局)としての活動のほか、コーポレートITメンバーと共に事業継続計画(BCP)整備なども並行して進めなければなりません。とにかく関わる範囲が広く、そして、とても地道な活動です。

ですが、会社全体を俯瞰してセキュリティのことを意識して物事を考え続けられる立場というのはセキュリティ会社では経験できないことで、自社にとっての最適解は何か?を探求し続けることの新たな面白さを見いだすことができています。

セキュリティエンジニアとしての活動内容や役割の違いと気づき、課題

ここまでの内容でお気づきの方もいるかと思いますが、現在の業務はISMS運用を初めとしてリスクマネジメントの分野も多く、実務的なバックグラウンドのない業務も出てきています。

システム的なセキュリティに関しても「どうやって悪用できるか...好物のBOF*は無いのか..BOFはどこだ...」という攻撃観点の思考回路のみで判断するのではなく、「どのようなソリューションや仕組み、またはルールでリスク低減できるのか、そして、それをなるべく自動で運用できるようにはどうするか」という守る側にとっての実務的な課題を考えなければなりません。

* バッファオーバーフローのこと

このほかに、私が実際に感じているセキュリティエンジニアとしての気づきや考え方の変化を挙げていくと、以下のようなものがあります。

  • 攻撃手法の理解を踏まえ、(社内リソースを鑑みた)現実的に運用しうる対策の仕組みを提案できなければならないことを痛感した
  • 仕組み化やルール化するにも、エンジニアではない従業員の存在を考慮するようになった
  • 脆弱性単体の影響範囲や度合いではなく、システムの利用方法や情報の種類など、社内だからこそ持てる視点を持って評価するようになった
  • 「アップデートしたくてもできない」問題が生じないシステム設計が肝要であることを改めて認識した

これらの変化への対応については、すべてソリューションや自動化に対して私の知見がまだまだ不足しているため、これからは「攻撃者目線」の考え方に加えて「ソリューションと自動化」の知見を補完しながら、メドレーのセキュリティ向上に貢献し続けていきたいと考えています。

セキュリティエンジニア募集中!

最後となりますが、セキュリティエンジニアは関わる業務の幅広さに加え、絶対的な正解が存在しない問題にソリューションを提供することも多い仕事です。

メドレーでの内製による脆弱性診断や全社セキュリティに興味がある方はぜひジョインしてください。いつでもお待ちしています!

www.medley.jp

介護のほんねリニューアルの話

はじめまして。メドレーでデザイナーをしているおおのです。わたしはメドレーには昨年(2020年)の6月に入社し、現在老人ホーム・介護施設の検索サイト「介護のほんね」を担当しています。

介護のほんねは昨年リニューアルを行いました。今回は、そのリニューアルプロジェクトの中で自分が取り組んだこと(主にサイトトップのリニューアルについて)についてお話しようと思います。

目次

  1. 介護のほんねとは
  2. リニューアルの背景
  3. プロジェクトについて
  4. プロジェクトとの関わりについて
  5. サイトトップの制作
  6. プロジェクトを終えて

介護のほんねとは

介護のほんねは、納得できる老人ホーム・介護施設探しができる検索サイトです。介護のほんねには、全国にある多くの施設が掲載されています。予算やエリアなどお好みの条件で施設を検索したり、気になった施設へ見学予約や資料請求などお問い合わせができます。また社内の入居相談員による施設に関する資料送付や条件にあった施設紹介、施設見学の日程調整などのサポートにも対応しています。

リニューアルの背景

介護のほんねは2014年にローンチされました。しかし、長い間の運用の中で古いデザインと新しいデザインが入り混じっている部分があったり、SEOの観点での強化が必要だったり、今後の成長に向けて手直しする部分が積もり始めていました。また、2019年に「医療につよい老人ホーム検索サイト」にコンセプトを変更しましたが、より多くの方にご利用いただくためにも、医療につよいというコンセプトからさらに一歩進み、様々な状況のお客様に向き合い、お客様が介護に対して前向きに、そして後悔のない選択ができるよう寄り添うことのできるサービスにしていきたいという思いから今回のリニューアルが始まりました。

プロジェクトについて

リニューアルプロジェクトは昨年5月頃から始まり、外部のデザイン制作会社と連携して進められました。制作会社の方には、デザイン業務の支援をお願いしつつ、週1〜2回の定例で進捗報告や業務内容の確認を行っていました。

プロジェクトとの関わりについて

自分が入社したのが昨年6月後半だったので、デザインや開発も部分的に進んでいる状況でした。介護領域の勉強や、担当サービス、競合調査、リニューアルプロジェクトや介護のほんねのこれまでの歩みについてなどのキャッチアップと並行してリニューアルのデザインのことも考えていました。

そこで次のようなことを意識して動きました。

プロジェクトに対して

  • 社内のメンバーといつでもコミュニケーションがとれることを活かし、外注先とも相談して自分自身も手を動かしながらデザインをブラッシュアップすること

社内に対して

  • サービスに対するメンバーの思いを確認しつつ、これまでのサービスの歩みを尊重して動くこと
  • 社内のデザイナーの先輩など頼れる人には頼ること

サイトトップの制作

プロジェクトにジョイン後、主にサービスの顔であるサイトトップについて、アイデア出しやデザインをしました。

サイトトップにどのようなコンテンツを掲載するのか、また、お客様が介護に対して前向きに、そして後悔のない選択ができるよう寄り添いたいというサービスの思いをどのように表現すればよいか考えていきました。

掲載するコンテンツに関しては、サイトトップを誰に向けて作るのかという部分を介護施設探しが初めての人に設定し、このサイトでは施設が探せることを伝えてサービスのコア機能を全面に出しつつ、介護のほんねでの施設探しの魅力ポイントや、介護や施設探しに関するコラムやQ&Aなどお役立ち情報も掲載するようにしました。

▼ リニューアル前のサイトトップ

f:id:medley_inc:20210401103421p:plain

また、当時のサイトトップは上に貼ったキャプチャの通りで、落ち着いた青を基調としたクリーンで誠実そうな印象がありました。これまで築き上げてきたプロダクトのイメージや印象は、リニューアル後も受け継いで残していきたいなと思いました。

それをふまえた上で、サイトトップの新しいキャッチコピーやキービジュアルをどういうものにするのかプロジェクトのメンバーとアイデアを出しながら考えました。しかし、「どのアイデアも間違ってないけどもっといいのがありそうだな」という気持ちが拭えず、なかなか決まりませんでした。

そこで、改めて原点に帰って情報を整理するために次のことに取り組みました。

  • ユーザーを知る
  • 介護のほんねが提供する価値を整理する
  • 信頼できる情報から納得できる介護サービスと出会えることをキャッチコピーに落とす
  • 介護のほんねの世界観を視覚的に伝えられるようなメインビジュアルの選定

ユーザーを知る

まずはじめに介護のほんねのユーザーデータを1件1件見ていきました。そこにはお客様の情報や施設を探している理由など様々な情報がまとまっています。それらのデータを見ていくと、おおよそ4つのパターンにわけられることがわかりました。

① 退院後の施設を探したい
転倒など何かしらの理由で入院している家族の退院期限が迫っており、退院後に在宅での介護ではなく施設にいれる必要があるケース

② 施設を移動しないといけなくなった
介護度があがったことで施設の受け入れ可能範囲から外れた場合や、施設の中でトラブルがあるなどの事情により施設を移る必要があるケース

③ 今後に備えて早めに動きたい
今すぐ介護施設に入れる必要があるわけではないものの、親が高齢でひとり暮らしをしていて不安なためまだ自分で動けるうちに施設にいれておきたいケース

④ 在宅介護では限界がきてしまった
自分自身も高齢になってきたため、仕事や家事に加えて介護の両立が難しくなってきた方が施設を探しているケース

このようなお客様のデータを見ていると、事情が事情だけになるべく急いで施設を探しているものの、離れても家族が幸せに暮らせるように慎重に施設を探したい、という思いが伝わってきました。

▼ ユーザーの大まかなパターン

f:id:medley_inc:20210401115623p:plain

f:id:medley_inc:20210401115632p:plain

f:id:medley_inc:20210401115641p:plain

f:id:medley_inc:20210401115649p:plain

介護のほんねが提供する価値を整理する

次に、ユーザーの方に対して介護のほんねができることはどういうことかを整理しました。

介護のほんねは「老人ホーム・介護施設の検索サイト」ということからもわかるように、施設を探すことができ、プロの入居相談員が施設探しから実際の入居までサポートするサービスです。また介護のほんねとしては、お客様が介護に対して前向きに、そして後悔のない施設探しができるよう寄り添いたいという思いがあります。そこで、介護のほんねの価値を機能的なものと情緒的なものにわけて整理してみました。

機能的価値=すぐに納得できる施設が見つかること
情緒的価値=家族のために、いろんな思いをもって施設探しをしているユーザーに寄り添うこと

ユーザーデータから見えてきた「事情が事情だけになるべく急いで施設を探しているものの離れても幸せに暮らせるように慎重に施設を探したい」、そのようなユーザーに介護のほんねは寄り添って、後悔することなく納得できる施設がすぐに見つかるようにサポートしていくことを伝えたいなと思いました。

納得できる介護サービスと出会えることをキャッチコピーに落とす

ユーザーやサービスの提供価値について整理をしたところで、新しいコンセプトをサイトトップのキャッチコピーにどう落とし込むのかを考えました。

そもそもサイトトップのキャッチコピーですので、前提として「サービス概要、コンセプトが端的に伝わること」は大事にしたいと思いました。サービス概要は、繰り返しになりますが老人ホーム・介護施設の検索サイトです。そして端的にサービス価値を伝えるためにも、先程述べたサービスの機能的価値である「すぐに納得できる施設がみつかること」をキャッチコピーに盛り込もうと考えました。

色々アイデアを出した結果、「老人ホームが見つかる」というサービスのコア機能に加え、介護のほんねならではの「すぐに」見つかるということや、後悔のない納得いく施設選びができるというエッセンスを入れて、最終的に「納得できる老人ホームがすぐ見つかる」というコピーになりました。

介護のほんねの世界観を視覚的に伝えられるようなメインビジュアルの選定

キャッチコピーはサービスの機能やできることをわかりやすく伝えるものにしたため、キービジュアルは先程述べたサービスの情緒的価値のエッセンスをいれたいと思いました。それを踏まえ、いろんな思いを持った相談者の方に寄り添い、ご家族が施設に入居されてから始まる新しい生活を前向きに捉えられるようなビジュアルにしようと思いました。

キービジュアルの選定にあたり、チーム内で意見を集めながら、色々アイデアが出ました。入居後のイメージやサービス概要が伝わりやすい老人ホームの屋内風景の写真、入居後の楽しい生活が期待できそうな施設のスタッフと入居者の笑顔の写真や、サービスの寄り添うスタンスを抽象的に伝える手を握り合うような写真など、たくさんの写真をあてはめて検討を繰り返しました。

▼ イメージ選定

f:id:medley_inc:20210401103430p:plain

  • 車椅子が写りこんでいると、自立度が高い状態で施設を探している方(※介護の必要がない元気な方向けの施設もあり、元気なうちから施設に入られる方もいらっしゃいます)にとって自分が使っていいサービスではないのかとマイナスなイメージにならないか?
  • 施設スタッフと入居者が笑顔で写っている人が写ったモデル風の綺麗な写真だと素材感が出すぎて嘘っぽくならないか?
  • 手を包みこむなどモチーフが抽象的すぎるとかえって何も伝わらないのではないか?

写真を選ぶ中でチーム内でも相談しながら、小さな違和感をひとつずつつぶしていきました。そして、最終的に下のようなキービジュアルになりました。

▼ リニューアル前とリニューアル後

f:id:medley_inc:20210401115327p:plain

f:id:medley_inc:20210401115319p:plain

これからの新しい生活がポジティブなものに捉えられるような、スタッフと笑顔で生活する入居者が写っており、背景に程よく雑多感が残る素材感を抑えた写真を選びました。写真に写っているのは入居者と入居者に寄り添うスタッフですが、介護のほんねも同じように、施設探しをしている方に寄り添う姿勢がこの写真から間接的に伝われば嬉しいなと思っています。

プロジェクトを終えて

プロジェクトは一段落しましたが、スタートラインにたったところなので、まだまだ追加したい機能や磨き込みたい部分も山積みだなと感じています。

今回、自分のデザインに納得感をだすためにサービスや介護の知識、チームのメンバーが考えていることへの理解を深めながら並行してリニューアルのデザインを手掛けたことは、とてもやりがいのあるものでした。

また、リニューアルをきっかけに改めてサービスの価値や目指したい世界を整理できたのはとても良かったです。これからも介護のほんねの目指したい姿を見据えながら、より多くの方につかってもらえるようなサービスにしていきたいと思っています。

www.medley.jp

開発チームと一体となったQA

みなさんこんにちは、メドレーの QAエンジニア かみむら です。 入社して間もなく1年になります。 CLINICS開発チームのQA活動を行っています。

私自身の経歴としては、テスト・品質関連業務に足を突っ込んでから早20年になろうとしています。 2020年はメドレーのQAエンジニアが一気に0名→2名になりました。 先日 Magic Pod導入の記事 を公開した米山とはかつての同僚でもあります。 現在は別々の部署に所属していますが、お互い得意分野を発揮しつつ時折情報交換や相談ごとなどをしているような関係性です。 自分とは違うタイプの同職種がいると、何かと捗ります(その辺りはまた別の機会に…)。

CLINICS開発チームでは、エンジニア・デザイナー・QAエンジニアがワンチームで開発を進めています。 これまで私が経験してきた現場では、QAは開発チームの外側にいる(ステークホルダーとして)ことが多く、新鮮な気持ちでいます。

この記事では私の入社以降取り組んできたQA活動の概要についてお話ししたいと思います。

「CLINICSのQA」とは?

さて、何しろこれまで「QAエンジニア」という職種のひとが存在しなかった開発チームのため、まずは「CLINICSに必要なQAってなんだろう?」というところから考えはじめました。 もちろん、数々のプロダクトを大きな障害なくリリース・運用してきているので、それなりにQA/テストの技術力はあるはずです。

入社前にも、何度も

  • なぜ(他の手段ではなく)QAエンジニアの採用が必要なのか?
  • QAエンジニアにどんな役割を期待しているのか?

といった点を開発チームの上長と話し合いました。

なぜ(他の手段ではなく)QAエンジニアの採用が必要なのか?

私は第三者検証会社に所属していた期間が長いこともあり、品質についての悩みがある開発チームにテスト支援だったりコンサルティング的役割で関わることが多かったので、「てっとり早く他社に相談するのではなく、採用したいのはなぜだろう?」という疑問が単純にありました。

現場の思いとして、以下の点が挙げられていました。

  • プロダクト開発エンジニアがリリース時のリグレッションテスト(シナリオテスト)をメンテ・実施しているが、CLINICS(電子カルテ)の複雑さに追いついていくのが難しくなってきた
  • ここに対して専門性をもって取り組むことで、複雑なドメイン知識を扱うプロダクトを安定して開発リリースできる仕組みを作りたい

QAエンジニアにどんな役割を期待しているのか?

描いている組織体制像としては以下のようなお話でした。

  • QAエンジニアにテストフェーズだけ縦割り的に関わってもらうのではなく、プロダクト開発チームとしてひとつになって、有るべき開発プロセスを一緒につくり上げていきたい
  • 開発エンジニアがテストに関してしっかりと理解をしていくことで、そもそも品質の高いプロダクトをつくることができる、といった世界を目指したい

これら課題に対してチャレンジ的に「やってみたい」と強く思ったのと、私はこれまでにいろいろな現場の開発体制の中でテストエンジニア/QAエンジニアとして活動してきていましたが、「プロダクト開発チームとしてひとつになって」というところがすごく「それ良いな!」と思ったのを覚えています。 専門職に任せるのではなく、「一緒に理想の世界をつくりあげたい」という気持ちがとても見える良い組織だと思いました。

「QAエンジニア」「テストエンジニア」「SET/SWET」

ここで少し職種名に関する補足説明をしますと、「QAエンジニア」という呼称は比較的新しい概念なんじゃないかと思います。

一般的には「テストエンジニア」と言い、文字通り「テスト業務に特化したエンジニア」を指していました。その後『テストから見えてくる グーグルのソフトウェア開発 』(2013年日本語版発行)から「SET/SWET(Software Engineer in Test)」が日本でも認知され、国内の導入事例が出てきたことで一気に広まった印象です。

私の解釈では、「QAエンジニア」と呼称する場合、「テストエンジニア」や「SET/SWET」の素養も含みつつテスト以外にも「品質向上のための活動全般を積極的に担う役割」という意味合いが濃くなるんじゃないかと捉えています。

CLINICSのありたい「QA」の姿

上長と話し合った結果、以下のような活動をメインに据えていきましょうということになりました。

  1. (現状行っている)テストの改善
  2. プロセス改善
  3. 知識の底上げ

それぞれのトピックについて、現在CLINICSのQA活動としてどのように取り組んでいるかを1つずつ詳しく説明していきます。

「テストの改善」

現状CLINICSの開発サイクルは週1回のリリースとしています。 毎回リリース用にコードフリーズした環境に対してリグレッションテストを開発チーム全員で手作業(マニュアルテスト)により行っています。 日々の機能追加や改修の際に手をいれてはいますが、リグレッションテストのシナリオもツギハギ感がみえるようになってきました。 そして増えてきたシナリオによってどこがどう品質担保されているのか見通しが悪くなっている点が大きな悩みでした。

そこでまず、「現状のシナリオテストを分析し、全体的に再設計する」という計画をたて、現在は開発チームの中でもカルテに造詣の深い一部メンバーで定期的にMTG(レビュー会)を行いながらテスト設計の方針を組み立てています。 設計図ではマインドマップツールやマトリクスを作成して方向性や粒度をすり合わせしています。

私自身も、今までの業務でこれだけじっくり丁寧にテスト設計をしてきたことがないため、厳しくもたいへんやりがいのあるタスクとなっています。

「プロセス改善」

こちらはテストそのものではなく、開発チームのルーチンワークや体制に関わる改善です。

種まき的にスモールチームで新しいふりかえり手法を試してみたり、開発定例会で共有している障害情報とテスト実施中に見つかったバグの情報を一元化して残す仕組みを導入したりなど行いました。 特に「ふりかえり」については常に改善を意識できるプロセスで、上手なふりかえりをすればするほど開発品質が向上すると考えられているため、勉強会の後にフィードバックコメントをもらう仕組みをつくったりなどちょっとした隙間にも「ふりかえり」を小さく回せるように腐心しています。

それとまだ着手できていませんが、記録した障害・バグ情報も近いうちに分析・分類していって今後の開発に役立てたいと考えています。 バグ分析は時間がかかるのでなかなかサクッとはいきませんが、長期的視点では有用な財産になります。

また「開発プロセス」「業務フロー」自体の現状の悩みごとを現場の声として私が直接探るためと、開発チーム内で「共通の目標」を認識するためのブレストをリード陣と行いました。 進め方は「SaPID 」という改善手法を参考にしています。

SaPIDとは、”Systems analysis/Systems approach based Process Improvement methoD”の略語で、当事者自らが(最終的には仲間と共に)解決すべき問題点を特定し、現実的に解決、改善、そして革新を実現しながら段階的・継続的に自律運営へのゴールを目指す手法です。

誰かにやらせる、やらされるのではなく、当事者自らの意思、チーム・組織の意思で自律的に運営を進めることを志向するのが特徴です。

f:id:medley_inc:20210305203657p:plain

コロナ禍の中、日によってリモートで参加のメンバーがいたりなどふせんをつかったワークにも工夫が必要でしたが、最終的には「共通の目標」として

  • 自分と身の周りに役に立つ状況をつくる
  • 世間に認知されるプロダクトをつくる

というような定義をつくることができました。

「知識の底上げ」

CLINICSはこれまで中途採用メンバーが多かったため、OJT中心で体系的な教育はまだまだ整備をしている段階です。 新卒入社も増えてきている昨今ではメンバー全体で知識レベルが合わないことによる弊害が出てきており、目線を合わせていくことが喫緊の課題でした。

普段の業務の中で断片的な情報を得ることはできてもなかなか体系的な知識を効率的に身につけることは難しいので(専門書は分厚くてハードルが高い)、上長からのたっての願いでもあり、QAに従事している者にとっては割と初歩的なテスト技法から教えることにしました。 私のようにずっとQA活動をしてきた者にとっては当たり前の技法でも、開発エンジニアにとっては意外と知る機会がなかったりするものです。 覚えておくとテストの段階だけではなく設計品質もあげることができるので、定着するように日々取り組んでいます。

まずは教科書的な内容をCLINICSチームのConfluenceに書いて、講義形式でCLINICS開発チームのメンバーに説明し、実践編として宿題を出して答え合わせと解説を行う、という流れで行っています。 学習者としては話を聞いているだけでは覚えにくく、実際に手を動かしたり、日々の業務で本当に困った経験をすると学びたい欲に火がつくと思っているので、実践を大切にしています。 演習問題は以下のような書籍を参考にして作問しています。ありがとうございます、著者の方々。

ソフトウェアテスト技法ドリル―テスト設計の考え方と実際
はじめて学ぶソフトウェアのテスト技法
ソフトウェアテスト技法練習帳 ~知識を経験に変える40問~

一度教わっただけではなかなか覚えるのも難しいので、大事なテスト技法(境界値分析とか…)は折に触れて何度も何度も口にするようにしています。

(再)「CLINICSのQA」とは?

冒頭で引用した Magic Pod導入の記事 では、「テストの自動化は(リリース後即座に修正できない)アプリから着手していく」方針としました。 現在は、CLINICSのWebページ側のテスト自動化も推進しています。

テスト自動化の目的は現場によっていろいろと思いがあるものです。なぜ「テスト自動化をやるのか?」については、機械にリグレッションテストを任せて手が空いた分、より高度な(経験則が必要な)探索的テストができるようになるから、と考えています。

最初の問いに戻ります。
「CLINICSのQA」とは何か?

品質向上する仕組みが自然にできている自律した組織で、私は開発チームメンバーと「おもしろいテスト」「楽しいテスト」をしていきたい、と思っています。 それによって顧客が出会う可能性のある不具合が減り、「そもそも品質の高いプロダクトをつくることができるという世界」に近づけるのではないかな、と考えています。

「おもしろいテスト」「楽しいテスト」とは発見であり、学習であり、フィードバックのサイクルによって生まれます。 そのためにも前述の「プロセス改善」と「知識の底上げ」は両輪で進めていく必要があります。

品質向上のための手段は、テストの他にも実に多岐に渡ります。 長年やってきた私もまだ全貌を掴み切れていない「QAのエンジニアリング」ってこんなに奥深く楽しい! ということが開発チームメンバーの共通認識になるとうれしいです。

f:id:medley_inc:20210305203713p:plain

最後までお読みいただきありがとうございました。

www.medley.jp

HTTPコンテンツ圧縮でパフォーマンス改善

事業本部 プロダクト開発室のエンジニアの中畑です。

オンライン診療・服薬指導・クラウド診療支援システム「CLINICS」の開発・基盤周りを担当しております。

今回は、HTTPのコンテンツ圧縮について調査・対応する機会があったので、本ブログにて紹介したいと思います。

HTTPコンテンツの圧縮とは

HTTPコンテンツの圧縮とは、HTTPの通信においてWebサーバー側が返すデータを、なんらかの形式で圧縮してクライアントに返すことです。圧縮されたレスポンスをクライアント側は解凍して利用します。

HTTPコンテンツの圧縮によって得られるメリット・デメリットは以下の通りです。

⤴メリット

  • 通信の帯域使用量を減らせる
  • それによって通信にかかる時間を削減し、ページ表示速度を向上できる

⤵デメリット

  • 圧縮・解凍コストがかかる
    • ただし、圧縮・解凍コストはほとんどの場合は小さいため、メリットを下回る
  • 大容量ファイルやもともと圧縮されているファイル(画像や動画、PDFファイルなど)を圧縮するのは、圧縮してもサイズがそれほど小さくならないため非効率である
    • サイズがあまり削減できない割に、圧縮・解凍にCPUリソースを使い、数百MBを超えるファイルになるとそれぞれ数秒かかることもある

HTTPコンテンツを圧縮するためには

HTTPコンテンツを圧縮するためには、クライアントが解凍可能な圧縮形式を指定する必要があります。解凍可能な圧縮形式を指定するには、リクエストヘッダにAccept-Encodingヘッダを指定します。

最近のブラウザでは、HTTPリクエスト時に自動的にAccept-Encodingヘッダを自動的に付加してアクセスしているので、ブラウザ経由の場合は特に明示的に指定する必要はありません。Chrome, Safari, Edgeなど、ほとんどのメジャーなブラウザではAccept-Encoding: gzip, deflate, brが指定されています(※2021-01-23時点)。

圧縮形式(gzip, deflate, br)

圧縮形式はいくつかありますが、ブラウザを利用する場合は以下のいずれかが選択肢になります。

  • gzip: LZ77と32ビットCRを用いた圧縮形式
  • deflate: zlib構造体とdeflate圧縮アルゴリズムを用いた圧縮形式
  • br: Brotliアルゴリズムを用いた圧縮形式。gzipに近いが大容量の言語辞書を用いて、頻出するパターンの単語を圧縮して効率化。そのため文章的なテキストではgzipよりも圧縮率が高いと言われる

Brotliは比較的新しい形式で、ほとんどのサーバー、ブラウザで対応しています。

サーバーでのHTTPコンテンツの圧縮方法(gzip)

サーバーはクライアントのAccept-Encodingリクエストヘッダを受け取り、その中から1つを選択して圧縮処理を行い、Content-Encodingレスポンスヘッダを付加してクライアントに結果を知らせます。

f:id:medley_inc:20210129123916p:plain

CLINICSが利用しているそれぞれのアプリケーション・ミドルウェアに絞って、どのようにHTTPコンテンツ圧縮を実現しているか解説したいと思います。いくつか圧縮形式はありますが、ここではgzip形式での圧縮方法について解説します。

NGINX

NGINXのngx_http_gzip_moduleを利用することでgzip圧縮することができます。

nginx.confのgzipディレクティブをonにすることで圧縮が有効になります。ただし、タイプを指定しないとContent-Type: text/htmlのときにしか圧縮されません。他のタイプでも圧縮したいときはgzip_typesディレクティブも合わせて指定する必要があります。gzip_types*を指定することで、すべてのコンテンツを圧縮することもできます。

gzip: on;
gzip_types: text/css application/javascript application/json

また、CloudFrontなどProxyを経由してのアクセスの場合はデフォルトでは行われません。Proxy経由のアクセスかどうかは、リクエストヘッダにViaヘッダがあるかどうかで判定します。

CloudFront経由でのアクセスの場合はVia: 1.1 xxxxx.cloudfront.net (CloudFront)のようにViaヘッダが付加されているため、NGINXにてProxy経由であると判定します。Proxy経由であっても何かしらの条件で圧縮したい場合はgzip_proxiedディレクティブを指定する必要があります。

ref. https://nginx.org/en/docs/http/ngx_http_gzip_module.html

CloudFront

CloudFrontのBehaviorの設定にて設定します。Compress Objects Automaticallyを有効化することで、gzip圧縮が有効になります。

f:id:medley_inc:20210129124017p:plain

上記を有効化すると、CloudFrontでは以下の条件で圧縮が行われます。

  • ファイルサイズが 1,000(≒1KB) 〜 10,000,000(≒10MB) バイトの間
    • よって、オリジンからファイルサイズを判定するためのContent-Lengthヘッダが付与されていない場合は、サイズ判別できないため圧縮されない
  • 特定のContent-Typeのコンテンツを圧縮する
    • テキスト系のコンテンツは圧縮するが、画像や動画、PDFなど、もともと圧縮されているものは対象外。詳しくはこちら
  • オリジン側(NGINXやRailsなど)から圧縮して返される場合は、再度圧縮は行わない
    • Content-Encodingヘッダの有無で判定している

ref. https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html

Rails

RailsはデフォルトではHTTPコンテンツの圧縮は行いません。Railsでコンテンツ圧縮を行いたい場合は、RailsのRack MiddlewareのRack::Deflaterを導入するのが簡単です。しかしながら、Rack::DeflaterはすべてのContent-Typeのコンテンツでも圧縮するので、画像や動画・PDFなど圧縮するべきでないコンテンツまで圧縮してしまいます。NGINXやCloudFrontなど、Rails外の他のサービスやミドルウェアに任せるのが良いと思います。

CLINICSでのHTTPコンテンツ圧縮のシーケンス

前章で解説したアプリケーション・ミドルウェアは、CLINICSでは以下のように連携しています。

f:id:medley_inc:20210129132442p:plain

AWS上にRailsアプリケーションをデプロイしており、通常のアクセスはロードバランサーからNGINXを経由してRailsにアクセスし、静的ファイルなどキャッシュコンテンツはCloudFront経由でアクセスしています。

CLINICSでは用途に合わせた圧縮を行っています。3つのケースを紹介します。

1. NGINX経由でRailsにアクセスした時

f:id:medley_inc:20210129124126p:plain

APIアクセスなどは上記シーケンスでアクセスしています。ほとんどがtext/htmlapplication/json形式のコンテンツとなり、NGINXにてgzip圧縮処理を行っています。Railsはアプリケーションの処理のみを行い、圧縮は行わないようにしています。

2. CloudFront経由でS3にアクセスした時

f:id:medley_inc:20210129124148p:plain

画像ファイルやPDF、静的なjs、cssファイルなどはサービスのデプロイ時にS3にアップロードしています。クライアントはCloudFront経由でアクセスし、S3から取得して、CloudFrontでgzipに圧縮処理を行っています。また、一定期間CloudFront上にキャッシュされるので、効率よく圧縮コンテンツを返します。

3. CloudFront→NGINX→Rails経由でS3にアクセスした時

f:id:medley_inc:20210129124210p:plain

静的ファイルの中でもシグネチャをチェックしているものは、このフローでアクセスしています。NGINXでも圧縮設定をONにしていますが、Viaヘッダがあるため、NGINXでは圧縮しないようになっています。

まとめ

HTTPコンテンツの圧縮を適切に行うことで、サービス全体のパフォーマンス向上が見込めます。更にCloudFrontを活用することで、アプリケーションやミドルウェアでの圧縮処理をなくし、更なるパフォーマンス向上が見込めます。

今回はHTTPコンテンツのgzip圧縮についてのみ触れましたが、Brotli圧縮についてもNGINX、CloudFrontともに可能なため、今後取り入れていきたいと考えています。もしHTTPコンテンツの圧縮設定を特に気にしたことがない方は一度確認してみてはいかがでしょうか?

最後に

メドレーでは、医療分野の社会課題をITにて解決するために日々邁進しています。医療という分野においては、機微な情報を扱ったり診療を止めないようにするために、パフォーマンス・セキュリティ共に高いサービスレベルが求められます。興味を持った方がいらっしゃいましたら、まずは気軽に面談できればと思いますので、是非ご応募ください!

最後までお読みいただきありがとうございました。

www.medley.jp

UIテストの自動化にMagic Podを導入した話

こんにちは。インキュベーション本部のQAエンジニアの米山です。主にCLINICSアプリのQAを担当しています。メドレーには2020年8月に入社しました。

今回は入社してまず行ったことの一つ、リグレッションテストの自動化と、そのために導入したMagic Podというツールについて、経緯や導入してみた結果をご紹介したいと思います。

CLINICSとは

私の所属するチームで開発しているCLINICSというプロダクトはアプリでオンライン診療や、クリニック・病院から処方箋を発行してもらうことができ、オンライン上で診察からお薬の受け取りまで完結できるサービスです。 プラットフォームはiOSAndroidのネイティブアプリ、それから同様のサービスをWebブラウザからも利用することが出来ます。

QA/リリース周りの状況

CLINICSの開発組織にQAエンジニアがジョインしたのは昨年(2020年)ですが、サービス自体は2016年にローンチされています。

本組織ではリリース前に行うリグレッションテストについては、開発メンバを中心にチーム全体で行う文化があります。 アプリのリリースは隔週で行っており、その都度開発メンバ自身によってテストが行われていましたが、自動化されたUIテストは存在していませんでした。

メドレーではQAエンジニアがジョインして間もないため、やりたいこと・やるべきことは多岐にわたる中でまず何から着手するべきか検討しました。

QAプロセスの策定・改善から、新機能をリリースまで推進するためのQA活動もあり、並行して幾つか動いている中でテスト自動化をどのタイミングで、どうやってスタートするか悩みました。

バリューから考える

f:id:medley_inc:20210115142126p:plain

メドレーのバリューはこの三つです。これらのバリュー視点で考えてみました。

「凡事徹底」として、リリース前のリグレッションテストをしっかり行うことは当然のこととして考えられます。

「中央突破」の視点ではどうかと考えると、やはりテストプロセスにおいて、特にリリース毎に繰り返し作業となるリグレッションテストを自動化することは王道であり、ベストプラクティスの一つだと考えられます。 そのため自動化は優先度高く進めるべきではあります。

残る一つ「未来志向」については、例えば1~2年後やその先を考えて、リグレッションテストが自動化されているべきか否かで言うとやはりYesです。

また、別の観点として、現在はわずか2人のQAエンジニアに対して、複数のプロダクトが存在している状況で、QAエンジニアがアサインされていないプロダクトも多くあります。

私自身も昨年10月からアプリ・基盤チームに異動したこともあり、今後についてもまた体制が変わっていくことは十分に考えられました。

そんな状況下では、仮にUIテストを自動化した環境を用意できたとして、その後に担当者が不在になった場合も考慮しておく必要があります(自動テストにおいて、担当が不在になったことでメンテされなくなり形骸化するケースはよくある話です)。

そのため、仮に実装者が不在となった後でも誰かに引き継ぎやすく、またエンジニア以外でも運用できる環境が望ましいと考えました。そういった観点でツールとしては基本ノーコードでもメンテできるMagic Podは有力な候補となりました。

これらをまとめると、以下のような結論に至りました。

  • テストの自動化は推進した方が良い
  • ただし、他のメンバでもメンテしやすい環境を選定する

ただしQAとしてやるべき事が沢山ある中で、テスト自動化だけに専念できる状況ではありません。 そのためなるべく他タスクと並行して小コストで進められる事も重要な要素でした。

自動化されたUIテストは全くない事や、他のテストの密度も鑑みると、なるべく早い段階で一定の自動テスト環境は用意したいという想いもありました。

これらの状況も踏まえ、ツールを選定・トライアルしてみた結果、Magic Podを導入することに決めました。

Magic Podの紹介

Magic Podについて、サービス自体の詳細は割愛しますが、端的にいうとクラウド環境かつGUIからUIテストの実装及び実行を行うことができるツールです。

GUIで自動テストが実装できるツールだと、Autifyなども有名です。 Autifyはブラウザ向けのツールですが、実装方法はMagic Podとは少し異なり、操作をレコーディングしてテストシナリオが自動で生成される形が基本です。

一方、Magic Podは以下のようにアプリの画面をまずキャプチャで取り込み、そこからテストで使いたい項目を選択し、シナリオにドラッグアンドドロップしていくことでテストシナリオを生成することができます。

f:id:medley_inc:20210115141554p:plain

ログインなど、複数のテストで使う部分は共通化しておきます。

テスト対象がiOSアプリであろうと、Androidアプリやブラウザであろうと基本的に同じI/Fからテストの生成・メンテが出来ることは大きな強みの一つです。

また、テストで使用するフィールドの要素を選択可能なことも、状態変化に強いテストとする上での強みとなります。

例えば「調剤薬局名でさがす」というテキストフィールドに対して、そのテキストを使うのか、IDなのか、テキストフィールドなのかxpathなのかといった所です。

そのため、

  • テキストが頻繁に変わるような場所(例えば日付など)ではテキストを使わない
  • アプリ内部でリファクタリングなどが動いている場合であれば逆にIDは変わる可能性が高いため、テキストで指定する

UIテストを作り込む上では当然のことではありますが、上記のような工夫によりテストの成功率を上げることができます。

導入してみて

トライアル中は探りながらの部分はあったものの、慣れると実装工数は非常に短期間で実装でき、トータルでもiOSで2~3週間(オンボーディング含む)、AndroidのUIテストについては実質2~3日で基本的なテストシナリオの自動化を行う事ができました。

その後、運用しながら落ちやすいテストの改修を行ったり、運用が安定してからはCIにも連携しています。

UIテストの運用においては定期的に実行することは非常に重要なことですが、Magic Podの場合、BitriseではUI上から設定でき、Circle CIに対してもドキュメントを参照しながら比較的容易に設定できます。

実際、昨年1クォーター運用してみて、幾つかのクラッシュをリリース前に検知してくれました。

また、私自身、過去にはXCTestにおけるUITest(Testing Your Apps in Xcode)やAppiumを使ってUIテストを運用していたため、以下ではそれら他ツールとの比較も含めて紹介してみたいと思います。

実装コスト

実装コストにも初期構築と、その後のメンテコストで分かれますが、他のツールと比較して、大きく異なるのは初期構築コストだと思います。

Magic Podについては環境構築コストは非常に低コストで行うことができます(基本的な部分は1日あれば十分だと思います)。 またテストのレポーティングやキャプチャ機能なども標準で付いていますので、この辺りも自前で頑張る必要はありません。

次にメンテコストですが、例えばXCUITestではまずビルドを行い、debugして各ボタンなどの要素のIDなどを確認し、それらを用いてコーディングしていました。 Magic Podでは一度アプリをアップロードして、スキャンすることで画面の要素を一括で取得でき、その中から操作したい要素を選択することができます。

そのためこちらもコストはだいぶ下がります。ただ、この部分については他のツールや言語でも慣れればそう時間はかからないのでもしかしたら大差ないかもしれません。

あえて言うとdebugでIDを確認する手間が楽になる、実装したテストを試して実行するのが容易(ビルド待ちの時間がない)といった辺りでしょうか。

運用コスト

UIテストといえばFlakyなテスト(落ちたり落ちなかったりするテスト)に悩まされることは多いですが、運用してみると最初の内はそういったこともありましたが、現状ではほぼ起きていません。

これはMagic Podに限った話ではありませんが、

  • クラウド上で実行されることで環境要因で落ちることは稀
  • 落ちた時には自動でリトライされる
  • ビルドもCI上で実行している
  • 実行はメンバが活動していない時間帯に行っている

といった辺りが要因かと思います。

またMagic Podのようなツールを使っている場合に助かる部分としては、Xcodeなど、UIテストに必要なツールのアップデートに対するメンテが不要ということも挙げられます。

逆に少し辛い所

ここまでMagic Podの良い部分を多く書きましたが、逆にこのようなGUIでのテストツールを使うことで少しやり辛い点も紹介しておきたいと思います。

1. テストコードのレビュー

テストコード(ケース)はMagic Pod上で管理されているため、PRレビューなどのプロセスを行うことができません。 そのため、ケースの修正に対して、反映させる前にレビューしてもらいたい場合は、テストケースをコピーしてから編集するなど少し工夫が必要になるかと思います。

現状では困ることはありませんが、複数人で同一のプロジェクトに対して運用したい場合は少し煩雑になりそうです。

2. テストコードの管理

自動テストにおいて、テスト結果に影響が出る仕様変更が入るような場合、仕様変更に対するテストコードの修正は開発と並行して用意しておき、プロダクトへの変更がマージされるタイミングで同時にテストコードの修正もマージしたいケースがあります。

Magic PodではGitHub上でテストコードを管理していないため、このようなケースへの対応を自動で行うことが難しく、予めテストケースを分けて用意しておき、実装がマージされた後に手動で置き換えるか、マージされた後に影響のあるテストケースを修正するといった手動でのプロセスが必要になります。

現時点で気になったのは上記の2点ですが、これらも今後改善されていく可能性は大いにありますし、プロセスの中での工夫次第で対処も可能かと思います。

その他

基本的にUIテストを自動化する上で気をつけるべきことやアンチパターンはどんなツールを使っても同じです。 他のツールでは難しいことが、このツールでは実現出来るということも稀で、時にはプロダクト側で手を入れる必要もあります。 どんなツールであれ、何かしら工夫すれば達成出来ることが多いため、違いが出るのは実装や運用、オンボーディング等のコスト部分が最も大きいのではないかと感じています。

周囲のサポート

テスト自動化を行う場合(だけではないですが)、周囲の理解を得ることは大事な部分ですが、チームメンバは皆前向きで興味を持ってくれて進めやすい環境でした。

特にCI連携の部分ではiOS/Androidの開発の方にもサポートしていただき大変助かりました。

そしてMagic Podについては、数年前から運用している株式会社ノハナの武田さんにも事前に話を伺ったり、オンボーディング中は質問させていただいたりしました(ありがとうございました!)。

またMagic Podの伊藤様には導入時からトラブルシューティングに多大なサポートをいただいています。

Circle CIに入れ込む際には、ちょっと詰まった点があり伊藤様とメールでやり取りしていたのですが、その日のうちにドキュメントがアップされたり、 とある環境下で不明なエラーが出ていて相談した際には、ストアからCLINICSアプリをダウンロードして試していただいたり、とにかくいつも迅速かつご丁寧な対応が印象的でした。

まだQAチームもないような少人数の状況では、こういったトラブルに対して相談でき、共に解決法を探れる方がいるという意味でも非常に心強いです。

今後について

アプリのUIテストについて、改善していきたいことはまだまだ沢山あるのですが、現状でも基本的なテストは用意できているため、じっくり腰を据えて改善していきたいと考えています。

また現在はブラウザのテスト自動化を進めています。メドレーのCLINICS以外のプロダクトの多くはWebブラウザをプラットフォームとしているため、Webについてはプロダクトを跨いだ活動も行っていければと考えています。

長くなりましたが、最後までお読みいただきありがとうございました。

www.medley.jp

ChatOpsな稟議ワークフローシステムを開発しました

はじめに

こんにちは。コーポレートエンジニアの溝口です。
メドレーでは、今年7月に稟議ワークフローシステムを導入しました。
詳細は「システム概要」の章でご紹介しますが、システムの全体像としては以下のようになっております。

f:id:medley_inc:20201225155753p:plain

ワークフローシステムと聞かれたら、どんなシステムを思い浮かべますか?
申請者がシステムで申請すると、予め定められた承認者へ承認依頼がメールで通知され、申請内容の確認及び承認のためにシステムへログインする、という流れがよくあるワークフローシステムではないかなと思います。

我々はコーポレート部門として「徹底的に合理性を追求した組織基盤や、仕掛けづくりを行っていく」ことを目指しています。故に、メドレーの稟議ワークフローシステムにおいても便利合理的なシステムを目指して開発を行いました。今回ChatOpsの概念を取り入れることで、一般的なワークフローシステムよりも洗練されたシステムを構築できたかなと思います。
本稿ではシステム概要及び、裏側の仕組みをご紹介していきます。
最後までお付き合いいただければ幸いです。

ChatOpsとは

ChatOpsとは「チャットサービス(Chat)をベースとして、システム運用(Ops)を行う」という意味です。ざっくり書くと「システムからChatへメッセージを飛ばし、次のアクションが同じChat画面で開始できる」というものとなります。(下記フローはあくまで一例です)

f:id:medley_inc:20201225155817p:plain

ChatOpsには以下のメリットがあると考えています。

  1. 常に立ち上げているツールという共通インターフェースである

  2. インタラクティブなコミュニケーションにつながり、スピーディである

  3. 共有しやすく、記録に残しやすい

本稿では、詳しく説明はしませんが、興味がある方は事例等を解説しているサイトもあるので、是非探してみてください。

なぜChatOpsなのか

稟議申請においては
承認者「これ値引きしてもらって××円になったはずだけど、金額間違ってない?」
申請者「すいません、変更し忘れました。差戻しお願いします」
などのコミュニケーションが度々発生します。
通常のシステムであれば、確認事項がある際はシステム内のコミュニケーション機能を使う、もしくは、ChatにURLや稟議番号を転記して確認のためのコミュニケーションを取ることが想定されます。

メドレー内の業務コミュニケーションはSlack上で殆ど完結しています。
Slackではない他の場所で会話が発生すると情報が分散しますし、SlackにURLを転記するといった行為や、別システムへのログインなども非効率です。
そこで、共通インターフェースのChatを中心にシステム構築する=ChatOpsを採用し、稟議ワークフローを構築してみようと考えました。結果、稟議ワークフローシステムの情報をSlackへ連携し、稟議におけるコミュニケーションはSlackに集約、承認行為もSlack上で可能、というシステムを構築することができました。

システム概要

申請

申請者はTeamSpirit上で稟議内容を記入し、稟議申請を行います。 TeamSpiritとは、勤怠管理や工数管理、経費精算などを管理できるクラウドサービスです。Salesforceをプラットフォームとして採用しており、アイデア次第でいろいろなカスタマイズが可能です。

f:id:medley_inc:20201225155854p:plain

Slackから申請できるようにするのがChatOpsのあるべき姿かもしれませんが、過去の申請からコピーしたい、申請種別ごとに入力する項目が異なる等の要件を考慮し、TeamSpiritから申請するように設計しました。申請の導線については、今後もよりよい仕組みに磨き上げていきたいと考えています。

承認

申請者が「稟議申請」ボタンを押下すると、Slackの稟議チャンネルに申請内容及び添付ファイルが自動投稿されます。
承認者は申請内容に問題がなければ、投稿に配置されているボタンを利用して承認・差戻しが行えます。

f:id:medley_inc:20201225155917p:plain

承認者は稟議ワークフローシステムへアクセスすることなく、Slackで承認行為が完結できます。稟議内容において確認事項がある場合にはSlackの投稿スレッドで申請者と質疑応答のやり取りができ、承認・差戻しの判断に必要なコミュニケーションが行えます。

後続のアクション

承認後には、
・申請者に承認or差戻し結果をSlackのDM(ダイレクトメッセージ)で通知する


・後続の担当者へSlackで通知する
・(法務押印などの)承認後タスクを作成し担当者に通知する
等、後続のアクションへつながっていく仕組みも用意しました。

システムの裏側

入力インターフェース

入力画面は、TeamSpiritで標準提供されている稟議オブジェクトを利用しました。入力項目は標準で用意されているコンポーネントを利用し、メドレー独自で定義しています。承認プロセスを定義すれば、Slackを使わずにTeamSpiritのみでも運用は可能です。

Slack通知

Salesforceの標準機能とApex を用いたScript処理を使ってSlack通知をしています。

Apexとは、Salesforce内で利用するビジネスロジック用のオブジェクト指向プログラミング言語(ほぼJava)のことです。

Slack通知までの大きな流れは以下です。
1. 稟議申請ボタンを押したタイミングでステータス項目を「未申請」から「申請中」へ変更
2. プロセスビルダーにてステータス項目が「申請中」になったことを検知してApexをコール
3. Apex内で申請情報や承認者情報の取得
4. Slack APIをコールし、Slackへ投稿

1~4のプロセスを詳しく見ていきます。

1. 稟議申請ボタンを押したタイミングでステータス項目を「未申請」から「申請中」へ変更

申請者が「稟議申請」ボタンを押したタイミングで承認プロセスを走らせます。
申請時のアクションとして、 ステータス「申請中」とします。ステータスが変わる毎に処理を走らせているので、ステータス定義は一つ肝になります。

2. プロセスビルダーにてステータス項目が「申請中」になったことを検知してApexをコール

プロセスビルダーを利用することで「稟議レコードを作成または編集したとき」に何らかの処理を実施することが可能です。今回は、ステータスが「申請中」になった場合にApexをコールする、という処理にしています。

3. Apex内で申請情報や承認者情報の取得

通知に必要な情報を揃えるため、Apexの処理では稟議オブジェクトの申請情報と合わせて次の承認者情報も取得しています。

String ownerId = p.OwnerId;
//申請者のユーザ名を取得
String applicant = [SELECT Username FROM User WHERE Id = : ownerId].Username;
//承認プロセスのレコード取得
String processInstanceId = [SELECT Id FROM ProcessInstance WHERE TargetObjectId = : p.Id ORDER BY CreatedDate DESC limit 1].Id;
//承認者のIDを取得
String approveId = [SELECT OriginalActorId FROM ProcessInstanceWorkitem WHERE ProcessInstanceId = : processInstanceId].OriginalActorId;

4. Slack APIをコールし、Slackへ投稿

Apexが取得した情報をもとに、Slackに投稿します。
稟議内容を記載し、申請者・承認者に対してメンションされるようにユーザ名も記載します。
また、今回は承認者用にインタラクティブボタンを配置する必要があったので、Block Kitを利用し、ボタン付きメッセージを作成しました。

{
  "text": "hoge",
  "blocks": [
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "fuga"
      }
    },
    ...
    {
      "type": "actions",
      "elements": [
        {
          "type": "button",
          "text": {
            "type": "plain_text",
            "text": "承認"
          },
          "value": "Approve",
          "style": "primary"
        },
        {
          "type": "button",
          "text": {
            "type": "plain_text",
            "text": "差戻し"
          },
          "value": "Reject",
          "style": "danger"
        }
      ]
    }
  ]
}

TeamSpirit(Salesforce)→Slackへの投稿は開発において苦労したポイントの一つです。

Slackからのアクション

Slackの投稿に埋め込んでいるボタンがクリックされた際は、Lambdaを経由してTeamSpirit(Salesforce)のRestAPIをコールし、承認処理を実行しています。
また承認後は、ボタンを「承認」スタンプに置き換えています。

開発を終えて

稟議ワークフローシステムを導入するにあたり、ChatOpsの概念を取り入れSlackに連携する業務システムを構築しました。
承認者からは「Slackで承認やコメントができ、社外からでもすぐに対応できるので便利」「Salesforce-Slack連携は他にも活用できるので是非やっていこう」などのコメントをいただきました。また、承認後にもスレッドにて、「振込お願いします」「物品届きました」等のやりとりも行っており、情報がSlackに集約されていく狙い通りの運用になったかと思っています。

Chatサービスを利用している会社では、今回ご紹介したChatOpsは業務効率化するにあたり、有効な手法になるのではないでしょうか。もちろん、すべてChatに連携すればよいというものでもなく、しっかり設計や運用検討を行う必要があります。
今後はChatOpsに限らず業務効率化につながるものはどんどんやっていきたいと考えています。

さいごに

メドレーのコーポレート部門では「徹底的に合理性を追求した組織基盤や、仕掛けづくりを行っていく」ことを目指して、業務効率改善のための開発を推進しています。面白そう!と感じた方、メドレーでどんどん改善してみたい!と思っていただけた方は、ぜひ弊社採用ページからご応募お願いします!

www.medley.jp

最後まで読んでいただきありがとうございました。

CloudFront のエラー監視精度を上げた話

はじめに

はじめまして、メドレー新卒入社2年目の森川です。

インフラ経験がまだ4ヶ月ほどの未熟者ですが、AWS認定資格クラウドプラクティショナー の試験に合格することができました。上位の資格取得に向けて今後も勉強していきます。

先日私が担当させていただいた CloudFront のアラート改善について、問題の原因と対応方法を本記事で書かせていただきます。

よろしければお付き合いください。

背景と問題

弊社が運営しているプロダクトの一つ ジョブメドレー ではインフラ環境に AWS を利用しています。

監視には CloudWatch や Datadog などを使用しています。サービスの異常を検知するための設定のひとつに、CloudFront のエラーレスポンス増加を検知するためのアラート通知があります。

CloudFront が返すレスポンスのうち、特定の時間範囲の中で4xx, 5xx系のエラーを返した割合が閾値を超過したことを検知して、CloudWatch アラームから Lambda を通して Slack に通知を行っています。

ところが、ある頃を境に CloudFront での4xx系エラーレスポンスの発生割合が増加し、アラートの通知頻度が想定以上に高くなってしまいました。

f:id:medley_inc:20201221172048p:plain

原因

調査を行ったところ、刷新した社内システムにて以下2つの原因でアラートが発生していることが分かりました。

f:id:medley_inc:20201221172100p:plain

原因1. 社外サービスからのアクセスでアラートが発生

CloudFront のログを確認したところ、社外サービス(Slack, Google スプレッドシートなど)からのアクセスに対してステータスコード 403 を返しているレスポンスログが数多く記録されていました。

これらのサービスに弊社の社内管理システムの URL がポストされると、プレビューを表示するためのリクエストが送信されますが、この時のリクエストが社外からのアクセスとして WAF で制限されていました。

f:id:medley_inc:20201221172124p:plain

インフラ刷新前から現在まで稼働している CloudFront のログも確認したところ、こちらでも同様のエラーレスポンスが発生していることが分かりました。しかし、エラー割合増加のアラートが頻発することは現在でもほとんどありません。

以前はジョブメドレーが持つシステム全体へのアクセスをひとつの CloudFront で処理していたため、アラート通知の割合として計算する際の母数が大きく、社外からのアクセスによるエラーが発生していても、その割合が閾値を超過することが少なかったからだと考えられます。

インフラ構成を刷新したことをきっかけに、これまで目立っていなかった社外からのアクセスという問題が表面化してきたのです。

原因2. 利用者が少ない時間にエラーレートが高くなりアラートが発生

CloudWatch アラームでは、一定期間内でのレスポンスのうち、4xx, 5xx系のエラーごとにその割合が閾値を超過したことを検知してアラートを発生させる設定としていました。

しかし、深夜など利用者が少ない時間に一度でもエラーが発生すると、その割合が跳ね上がってしまうことでアラート発生頻度が増加し、誤検知と言える状態になっていました。

以下の画像では、4xx系エラーの割合が夜間に100%となっている箇所が確認できます。(表示時間は UTC です)

f:id:medley_inc:20201221172140p:plain

対応方法

2つの原因に対し、それぞれ対応を行いました。

対応1. 特定の社外サービスからのアクセスをエラー検知の対象外とする

各サービスの設定により、プレビュー表示によるアクセスを停止させる選択肢が考えられます。しかし、該当するサービスすべてに設定を行うのは難しく、管理も複雑になりそうです。

そこで、特定の社外サービスからのアクセスを エラー検知の対象外とする 方針で対応を行いました。

ログのすべてを CloudWatch アラームの評価対象としていたために、誤検知と言えるアラートが発生しているのが現状です。したがって、評価させたいログだけに絞り CloudWatch で評価させることができれば解決が図れます。今回であれば、特定のユーザーエージェントや IP アドレスなどを除外して CloudWatch に渡すという処理が求められます。

その実現のため、今回新たに作成したのが Lambda の関数です。

f:id:medley_inc:20201221172156p:plain

S3 に CloudFront のログが保存されたことをトリガーに Lambda を起動させるように設定しました。

ログごとに記録されているリクエスト元のユーザーエージェントや IP アドレスなどを確認し、除外対象かどうかを判定します。

そうして選別を通過したログを今度はステータスコードの5つのクラス(1xx, 2xx, 3xx, 4xx, 5xx系)ごとに振り分けます。

ただし、CloudFront ではステータスコード000 が入ることがあります。

f:id:medley_inc:20201221172213p:plain https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html

ステータスコード 000 はアラートで検知したところで対応できることが特にないため、検知対象から除外する方針としました。

(S3 のログを直接確認すると 000 なのですが、Athena でログを確認すると 0 で表示されるため、少しハマりました)

こういった意図しない値がステータスコードに含まれていた場合などを検知できるようにするため、5つのクラス以外の値が含まれていた場合に UNKNOWN_STATUS_CODE なクラスとして分類するようにしました。

必要なものに絞ったログを6つのステータスパターンに分け、それぞれの件数を CloudWatch メトリクスへ PUT させます。

f:id:medley_inc:20201221172229p:plain

ここまでが Lambda の仕事となります。

各ステータスのログの件数を CloudWatch メトリクスで確認できるようになったので、レスポンス全体における4xx, 5xx系エラーの割合が算出できます。これを元に閾値を設定し、以前のようなアラートを作成することができました。

対応2. CloudWatch アラームの検知ルールを調整する

利用者が少ない時間にエラーレートが高くなりアラートが発生する件については、 CloudWatch アラームの検知ルールを調整 することによって対応しました。

一定期間でのエラー数に閾値を定め、超過した際にアラートを通知するように変更しました。つまり、割合ではなく絶対数で判断させるようにしています。

以下の画像の緑色のグラフが新たな検知ルールで参照するものとなります。橙色で示しているのが4xx系エラーの割合ですが、これが100%となっている箇所においても新たな検知ルールには反応していないことが分かります。

f:id:medley_inc:20201221172242p:plain

対応を終えて

Lambda を用いた集計処理の作成と、アラートの検知ルールの調整を行うことで、CloudFront のエラー監視精度を向上させることができました。

以前は頻繁にアラートがあがっていましたが、対応後はすっかり落ち着きを見せています。

システムの安定稼働を実現するためにも、適切にアラートを検知できるように今後も改善を図っていきたいと思います。

今回の課題に対する解決手段としてはシンプルな対応であったかとは思いますが、私には実りの多い紆余曲折な経験となりました。

AWS の基本的なサービスの連携を学ぶことができたことに加え、新たに作成する AWS のサービスの課金額の試算や、実行計画を定めてからの実装など事前準備を意識して取り組むことができました。恵まれた環境の中、日々学ばせていただいております。

さいごに

メドレーでは「医療ヘルスケアの未来をつくる」というミッションを掲げ、各プロダクトの開発・運営が進められています。

エンジニア・デザイナーをはじめ多くのポジションで新たなメンバーを募集しています。ご興味をお持ちいただけた方は、ぜひお気軽にお話しさせていただければと思います!

ここまでお付き合いいただき、ありがとうございました。

www.medley.jp