LayerX エンジニアブログ

LayerX の エンジニアブログです。

IAM Access AnalyzerのPolicy生成機能を使ってみた

CTO室の@ken5scal (鈴木)です。

2021/04/08にAWS IAM Access Analyzerの新機能として、CloudTrailのログをもとにIAM Roleのポリシーを生成するリリースが発表されました。

ところで、やはりというべきか、さすがというべきか、すでにクラスメソッドさんからブログがリリースされています。

dev.classmethod.jp

しかしながら、statementの単位でウンウン唸ったり、下手なポリシーをつけて撃ち抜いた足の数など数え切れない一介のIAMマンとしては、歓喜をもってこのリリースを迎えざるを得ません。その昂りは、ブログネタ被りの羞恥心など容易に吹き飛ばすほどのものです。というわけで、早速、今回のリリースについて書いていこうとおもいます。

IAM運用のつらみ

Identity is new perimeterといわれ、早10年弱。セキュリティの一番一丁目であるIAMを確実に運用するのは重要です。 最小権限の原則はその最たるものですが、果たして声を大にして、原則に沿った運用をしている!といえる組織はどれほどあるしょうか。 その原則は全くもって正論ですが、AWS Serviceの数 x Serviceに紐づくActionの数 x Effectの数 ✕ Conditionの数をすべて把握するには大きな労力を要し、Resourceを “*” にしない等にとどまってる方も多いのではないでしょうか。

最近はConftestなどの登場でテストが可能になってきてはいるものの、基本的にはAWSにデプロイしないと結果はわかりません。 特に、CodeDeployなど暗黙的に複数のサービスを利用したりしている場合もあり、一層、デプロイ前の設計・実装を難しくしています。

このような事情もある中で、公式自体がある意味、最小権限ではないManaged Policyの利用を推奨をしています。

https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html

そのため、多くの方はまずはManaged Policyの利用あるいはザックリしたIAM Policyを設定して、それからIAMのAccess AdviserやCloudTrailの集計といった実績から逆算する地道な努力をして、徐々に権限を絞っている方が多かったのではないかと思われます。

この労力をはらってくれるのが、今回リリースされた「IAM Access Analyzer - Policy Generation」です。

IAM Access Analyzer - Policy Generationの現在

次の画面は実際につかって表示された画面です。 f:id:layerx:20210408195108p:plain

もし、調査対象のRole/Userにアタッチされたサービスが、Policy with action-level informationに含まれていれば、実際に利用されたサービスとアクションの組み合わせまで表示してくれます。上記の例でいうと、KMSです。この場合、実際に使われていたActionはDecryptのみであったことがわかります。おかげで、Describe Key Actionを除外することができました。うーん、最高。AWS大好き。

しかし、まだまだリリースさればかりのサービスですので、ちょいちょいと制限があります。例えば、公式のドキュメントにもある通り、ポリシー生成に使われるCloudTrailのログのファイル数およびデータ量、並列実行数、一日最大実行数などです。また、現時点ではクロスアカウントのCloudTrailはできないとの記述もあります。詳しくはクオータに関するドキュメントを御覧ください。

IAM and STS quotas - AWS Identity and Access Management

f:id:layerx:20210408195424p:plainf:id:layerx:20210408195434p:plain ↑色々ためして、出力されたエラー

処理もそこまで早いわけではなく、90日間のタイムレンジを指定したポリシー生成には約20minほどかかりました。また、当然ですが、Iam:PassRoleのようなCloudTrailに記録されないものは自分たちでよしなに対応せねばなりません。同時に、ABACとの相性もあまりよくないのではないかな、という気がします。

というわけで、まだ実運用でバリバリ使うにはつらそうですが、とはいえ、APIがすでに用意されているなど、今後の改善に疑いの余地はありません。 処理パフォーマンスやキャパシティが広がった場合、IAM運用は大きく変わるでしょう。今まで DSLなどで静的に管理していたInline PolicyやIAM Policyを、より自動化・動的なやり方で管理せねばなりませんが、設計と運用を今から妄想するのが楽しみです。

一旦、今日はこの辺で。

リモートワーク下での新メンバー加入時にモブプロやってみたら素早くコードのナレッジ共有ができた話

こんにちは、LayerX インボイスのAI-OCRを開発しているTomoakiです。最近推しのセブンイレブンの商品はマーラーカオ(中華風蒸しパン)です。

さて、LayerXでは開発効率を上げるために日々様々な施策を行なっておりますが、今回はその中でもリモート下での新メンバー加入時に実施したモブプロが良かったので紹介したいと思います。 f:id:tomoaki25:20210408152410p:plain

TL; DR

  • 新加入のメンバーにコードの知識を素早く共有する必要があった。
  • リモートワーク下では綿密なコミュニケーションが取りにくかった。
  • モブプロを通じて書いた人しかわからない、コードに込められた意味・お気持ちを素早く共有できた。
  • 結果的に新メンバーのスムーズなオンボーディングに繋がった。
  • リモートでも従来のモブプロの効果は薄れることはなく、むしろ画面がしっかり見えてGoodだった。
  • 「同僚の開発環境の設定がそれぞれ見れる」「コミュニケーション不足解消」などリモートならではの効果も。
  • 毎日ではなく、コードのナレッジの共有ができていない時や新メンバーへの共有目的にショットで行うと良さそう。

通常の開発スタイルは前回紹介したので、ぜひご覧ください。

tech.layerx.co.jp

解決したかった課題

4月ですし新しくチームにメンバーが増えた会社も多いとは思いますが、オンボーディング用の資料が整っていなかったり、活字だけのオンボード資料では十分伝えたい事が伝わらず頭を抱えている方も多いのではないでしょうか。 何かしたいけど、開発のスピードを落とすわけにはいかないので横で付きっきりになる訳にも行かないですし、コードリーディングを片っ端からやるのも時間がかかりすぎてしまったり、情報過多で消化できない可能性があります。

弊社でも一時的に一人で開発していたOCR機能を新年から三人でやることになったのですが、(筆者を含む)新加入のメンバーはOCRの事前知識がほとんどない状況で、コードの知識を素早く共有する必要がありました。 とはいえ、開発スピード落としたくない。また、リモートワークなのでちょっとしたコミュニケーションが取りにくいという状況でした。

そこでモブプロで知識を素早く共有できるのではないか?ということで試しにやってみることにしました。

先行事例・そもそもモブプロってなんだっけ・ペアプロと違う?

そもそもモブプロとは何でしょうか。Wikipediaによると

Mob programming (informally mobbing) (aka. ensemble programming) is a software development approach where the whole team works on the same thing, at the same time, in the same space, and at the same computer. This is similar to pair programming where two people sit at the same computer and collaborate on the same code at the same time. With mob programming, the collaboration is extended to everyone on the team, while still using a single computer for writing the code and inputting it into the code base

https://en.wikipedia.org/wiki/Mob_programming

とのこと。簡潔にいうと、一人がPCを操作し、全員で同じ画面を見ながら指示を出し合い一つのことを実装することですね。ペアプロとはペア(組・対 = 二人)で実施するかモブ(群衆)で実施するかという違いで、大きな相違はないみたいです。

f:id:tomoaki25:20210408152608p:plain

ざっとモブプロ関連の記事を調べましたが、主な実施目的としては、

  • 新規エンジニアメンバーへナレッジを共有するため
  • デザイナー、QA、PM/POなどエンジニア以外のメンバーと合意を取りながら進めるため
  • 若手の育成のため
  • 気分転換のため

などが散見されました。

ただ、一般的にペアプロやモブプロは物理的に同じ空間で行うのがほとんどでした。 今回はリモートワークという条件の下で、コードナレッジ共有を目的に実施するモブプロはいかがなものか検証してみました。

手順

1. タスクを決める

ここが一番大事なポイントです。ほんの一部しかコードをいじらないタスクだと、最終的に共有できるナレッジも限られてしまいます。とはいえ、あまりにも大きすぎるタスクだとタスクを完了させるのに時間がかかり過ぎてしまいます。コードを横断的にみる必要があり、かつ2~3時間以内には終わるタスクがちょうど良いかなと思います。

もし、コードを横断的にみる必要がそこまでない場合は適宜コードのリファクタリングも合わせてやると、コードもスッキリしますし、幅広い箇所のナレッジの共有もできるのでおすすめです。

今回は実装だけでなく、OCRの学習用のデータ作成などオペレーション周辺のタスクも実施しました。

2. 実装する人の順番を決める

今回は3人で行うので一人一回実装を行うことにします。最初に手を動かすのは新メンバーが良いかと思います。すでにコードを知っている人がいきなり書いてしまうと、慣れているため本当は説明が必要な箇所の説明をすっ飛ばしてしまったり、スピードが早く新メンバーがついて行けなくなってしまう恐れがあるからです。

3. 実装開始

zoomでエディタを画面共有し、開発を開始ます。モブプロのポイントを一つ挙げると、キーボードを持っている人はタイピングに専念して、自分で考えて勝手に実装しない、というのがあります。実装者は他のメンバーの指示を受けながら実装を進め、だいたい30分~1時間を目安に区切りがいい所で交代します。ちなみにずっと集中しっぱなしなので結構疲れます。

3. 交代(二人目)

次の実装者に交代します。前の実装者は一旦コードをコミット・プッシュするなどして引き継ぎます。

4. 交代(三人目)

同様にして次の実装者に交代します。今回は3人での作業なので最後マージするところまで担います。

検証結果・感想

良かったこと
  • コードの知識の共有ができた
  • 事前準備なしでできた
  • 他のエンジニアの技を盗む機会になった(ショートカットキーとか、実装する順番とか)
  • 初期メンバーにとって当たり前になってしまってた作業や課題に対して、新メンバーからより効率的な手法や課題の解決策の提案があった
    f:id:tomoaki25:20210408151308p:plain
    エンジニアAの感想
リモートならではの良かったこと
  • 画面が全員しっかり見える
  • 全員の開発環境が見れて面白い(オフラインだと通常一つのPCで行う)
  • 物理的に会えないがために不足していたチームのコミュニケーションを補完できた
  • 一人暮らしメンバー(筆者)としては久しぶりに数時間ぶっ通しで会話ができてメンタルが回復した
  • キーボード含め、開発環境は各々慣れているものを使える(オフラインだと他人の環境を利用する)
    f:id:tomoaki25:20210408151500p:plain
    エンジニアBの感想
デメリット
  • 三人分の時間を使う

結論

三人分の時間を一つのタスクに使うので流石に毎日やると開発速度落ちますが、ナレッジの共有が足りない時にショットで行うのが良いかなと思いました。 リモートであっても、従来のモブプロの効果は薄れることなく、むしろ画面がしっかり見えるので他のメンバーの開発環境の設定や実装の仕方を学び合うことができ、またリモートワークに伴う日頃のコミュニケーション解消にも繋がるなど、副産物も多く一石三鳥でした。 (ちなみに第二回も開催したのですが、すぐに終わってしまったので以降はしばらくやってないです。チームの練度が上がった証拠ですね!)

今回は実際に試して良かった開発手法を紹介しました。LayerXでは新しいことを試しながら日々開発の効率を高めています。少しでも興味がありましたら、一度お話を聞きに来てください。

herp.careers

プロセスがプロダクト。エンジニアがカスタマーサクセスをやる意義

はじめまして。LayerX インボイスに携わっているエンジニアの花村(@naomasabit)です。

本職はエンジニアなのですが、簿記資格を持っており、監査法人でエンジニアとして財務分析や暗号資産監査業務に携わった経験があるため会計知識もある程度持ち合わせています。

そのバックグラウンドもあり、開発の傍ら経理のユーザーと接するカスタマーサクセスにも携わっています。今回はエンジニアがカスタマーサクセスをやる意義について書いていきます。

カスタマーサクセスとは

カスタマーサクセスは継続的営業プロセスとも言われます。売り切り型のサービスと異なり、期間に応じて売上が上がるサブスクリプション型の購入形態だと解約されないように継続的にユーザーの満足度を高める必要があります。

f:id:naomasabit:20210408105219p:plain

こちらは社内の勉強会で利用したスライドですが、カスタマーサクセスの目的は大きく

  • 解約防止
  • 追加受注
  • 紹介案件作り
  • (プロダクトへの)フィードバックループ

の4つに分類されます。

特に解約はSaaSとしての売上に直結してしまうため、一番上の「解約防止」について重要度の高い目標に設定しています。

しかし、初期のスタートアップの少ない人員で、日に日に増えていく利用企業に対して満足度を常に見ていくことはなかなか難しいところです。今回はLayerX インボイスが工夫している一端をご紹介します。

テクノロジーでレバレッジをかける

f:id:naomasabit:20210407195803j:plain

カスタマーサクセスを効率的に行うためにAWSのQuickSightというツールを導入し、ユーザー各社の月間利用状況を把握しています。画像に出しているのは各社ごとの月間請求書処理枚数です。元々ヒアリングで聞いていた請求書枚数に対して実際に処理した割合の値を計算し、LayerX インボイスで処理した割合が少ない多いがわかるように色で表しています。

他にもいくつかの観点でユーザー各社の利用状況をモニタリングしており、あまり活用されていないユーザーについてはアプローチして業務活用の支援をさせていただいています。サービスではユーザーが満足していない場合、問い合わせがあるとは限らず、カスタマーサクセスは不満足の兆候を能動的に検知し、ユーザーがサービスを使いこなせるようにサポートする必要があります。

SaaSの運用ではヘルススコアと呼ばれるユーザーの活用状況を点数にする概念があります。LayerX インボイスでもユーザーの活用データを分析しながらこのヘルススコアの分析・設計を行っています。

このようにエンジニアがカスタマーサクセスに入ることで、ダッシュボード設計やデータの分析を利用してテクノロジーでチームを強化することができます。

爆速でフィードバックを受けて改善する

f:id:naomasabit:20210407174007p:plain

先ほど述べたカスタマーサクセスの目的の一つにフィードバックループを回す、というものがありました。エンジニアがカスタマーサクセスを行うことで直接フィードバックを受けることができます。

初期のプロダクトはスピードが命です。特に、不確実な環境の中で何を作るべきかを判断するためには、作る人間がユーザーの前に立つことが最速の道だと思います。ユーザーの声を聞いて足りない機能を洗い出し、そのまま実装して再度ユーザーの声を聞きにいくことで素早いフィードバックループが回せます。

SaaSの難しくも面白いところですが、多くのユーザーに利用してもらえるように機能を開発しつつ、特定のユーザーのためだけの仕様にならないように汎用化していくバランスが求められます。そのような仕様を定義していくためには複数のユーザーの要望を聞いて、なるべく多くのユーザーに満足してもらえるような仕様の落とし所を考える必要があります。

特に、ユーザーの業種や業態、規模によって業務の進め方も要望も異なるため、様々なユーザーの声を聞いて業務を知り、ユーザーの背景を深く理解することを開発の上で重視しています。

このようにエンジニアがカスタマーサクセスを行うことで素早いプロダクトのフィードバックを受けることができます。スタートアップの世界には「スケールしないことをしよう」という格言があります。初期プロダクトは徹底的にユーザーの声を聞いてスケールしないことをした結果、大きなスケール成長の種が得られるという話です。

久々に格言の出てくる文章を読み返したらエンジニア向けにとても良いことが書いてあったので、引用しておきます。

皮肉にも、技術者は昔から世話をすることを嫌うという伝統があります。しかし、その伝統は、時代遅れです。技術者がシステム全体を動かすのではなく、ただひたすら作ったものの狭い領域を預かるだけが仕事だった時代ではなくなっています

ポール・グレアムによる「スケールしないことをしよう」前編 | POSTD より

プロセスがプロダクト

ここまで、エンジニアがカスタマーサクセスに関わることのメリットについて

  • テクノロジーでチームにレバレッジをかけられること
  • フィードバックを爆速で受けて改善できること

を書きました。開発内容がプロダクトと考えられがちですが、B2BSaaSの提供において、カスタマーサクセス含めたプロセスがプロダクトだと感じてきています。

LayerX インボイスのユーザーが求めているものが支払業務の効率化である以上、便利なプロダクトに加えて、問い合わせに的確に返答する体制、フィードバックをいただいてからの改善速度、プロダクトの活用方法の案内など含めたプロセスそれ全てがプロダクトと考えた方がしっくりきます。

今回はカスタマーサクセスとエンジニアについてのトピックを記事にしました。LayerX インボイスチームではこの初期フェーズだからこそ役割に縛られずエンジニアが幅広く活躍できる環境が整っています。少しでも興味がありましたら、一度お話を聞きに来てください。

herp.careers

LayerX インボイスにおける請求書AI-OCRの概要

AI-OCRが動くイメージ図

こんにちは!LayerX エンジニアの高際と申します!

この記事ではLayerX インボイスを支える請求書AI-OCR (Optical Character Recognition; 画像からの文字認識) について、

  • 開発における品質の考え方
  • 開発の方針
  • 請求書AI-OCRを構成する処理群

といった構成でお伝えしていきたいと思います。これ以外のトピックや、さらに深掘りした話も本ブログにて引き続き投稿していきます。

開発における品質の考え方

LayerX インボイスでは請求書AI-OCRの品質が顧客満足度に直結すると認識しており、その品質向上に注力しています。そのため、具体的な構成のお話をする前に、品質について簡単に述べておこうと思います。

品質の要素としてはいろいろありますが、請求書AI-OCRとしては以下に注目しています。

  • 読み取り項目数
  • 精度
  • 応答速度
  • スケーラビリティ
  • 可用性
  • コスト

それぞれ簡単に説明します。 「読み取り項目数」は支払期日や支払金額、取引先の情報(会社名や口座情報)など、請求書記載の情報をどれだけ読み取れるかという指標です。

「精度」は言葉のままで、実際の値とOCRで読み取った値を比較してどれだけ正解できたかの割合です。とはいえプロダクション環境ではお客さまのビジネス上の理由で実際の請求書の値から変更されることも多く、精度のモニタリングは簡単ではありません。

「応答速度」は、請求書1枚がアップロードされてから画面に表示されるまでにかかる時間のことです。スケーラビリティとも関連しますが、並列で複数枚アップロードされても性能が劣化しないように開発を進めています。

「スケーラビリティ」は同時に何枚の請求書を処理できるか表しています。

「可用性」は請求書AI-OCRのサービスが壊れず正常に動くことを表します。

最後に「コスト」。これはほとんどインフラコストと等価です。コストが高くなるとサービス価格やプロダクト開発への投資に影響することになるため、重要な要素の一つとして注意しています。

このように一言で品質と言っても様々な要素がありますが、次節ではこれらの品質を維持し高めていくための開発方針を説明します。

開発の方針

LayerX インボイスの請求書AI-OCR開発では以下を基本方針としています。

  • SaaSやAWSマネージドサービスをフル活用
  • 様々な観点での精度モニタリングを実施
  • オペレーションを改善し続ける

これは、以前福島がnoteにてデジタルネイティブな会社の文化について執筆した内容に基づいています。

デジタルネイティブな会社文化ってなんだろうというのをまとめたもの。LayerXでも原理原則ここに従っていきます

ノンコアは巨人の肩に乗り、SaaSやAWSマネージドサービスをフル活用することで、コアである顧客の利益に直結するような改善に集中することができます。また、スケーラビリティや可用性、コスト最適化といった課題もAWSのベストプラクティスにのっとることで様々な恩恵を受けることができます。

また、LayerX インボイスでの会計ソフト対応やワークフロー機能等ではユーザストーリーに基づき優先順位を決めることができますが、請求書AI-OCRでは読み取り精度の改善が主なミッションになります。

読み取り精度という結果は様々な要因によってもたらされるものですが、その要因の分析が大雑把だと、開発者それぞれに属人化した知識や経験といった勘に頼った改善になってしまいます。様々な観点での精度モニタリングを実施し、どこがボトルネックかを可視化することで、勘ではなく事実に基づく正しいアクションを実行し、効率よく精度の改善をしていくことができます。

また、請求書AI-OCRの開発には、精度改善のための学習データ作成をはじめとした様々なオペレーションがあります。そういったオペレーションを改善し続けることで、品質改善のサイクルを高速化していきます。データ量やデータ自体の品質が物を言う世界なので、データを増やし、精度を改善するためのオペレーションを大切にしています。

チームによって方針は様々だと思いますが、わたしたちの場合はこのように開発生産性を高め、勘ではなく事実に基づき、同時にオペレーションも磨きながら日々品質向上に努めています。

それではいよいよ次節から請求書AI-OCRの仕組みについて解説していきます。

請求書AI-OCRを構成する処理群

LayerX インボイスの請求書AI-OCRは、以下の図のように複数の処理で構成されています。

請求書AI-OCRを構成する処理群

LayerX インボイスが請求書を受け取ると、まずはいくつかの前処理を行います。リサイズやノイズ除去、ファイル変換といった処理を行います。

前処理が一通り完了すると、いわゆる汎用のOCRが実行されます。これは例えば画像を入力すると、その中に含まれる「文字」と画像内における「位置情報」を返すといった処理です。以下のような画像をイメージしていただければわかりやすいと思います。

OCR結果のイメージ図

この処理で得た結果は「意味」を持たず、ただの文字列に過ぎません。LayerX インボイスで入力補助として利用するにはもう一つ処理が必要になります。それがわたしたちがラベル検出と呼んでいる処理です。ラベル検出を実行することで、読み取った「文字」に意味を与えることができます。

この他にもいくつかの後処理を行い、一連の処理が完了します。

最後まで処理が完了すると、以下の図のようにユーザーの画面に読み取った結果が表示されます。

読み取り結果

■ 処理を複数に分ける理由

このように、LayerX インボイスの請求書AI-OCRは複数の処理で構成されています。請求書を入力するとラベル検出まで一気通貫で処理する、いわゆるEnd-to−Endのモデルを作ることも可能ですし、いくつか論文も出ていますが、わたしたちは処理を分けることにしました。

処理を分けるメリットとしては

  • 柔軟に処理を組み替えやすい
  • 処理ごとに改善しやすい
  • エラー時にどこで何が起こってるか分析しやすい

といったものがあります。逆にデメリットとしては

  • デプロイするものが多くなる
  • 多数の処理をモニタリングする必要がある
  • 処理ごとに異なる技術を要求される
  • 処理間のオーバーヘッドで全体の応答速度が遅くなる
  • 壊れる箇所が増える
  • リトライしても冪等にする必要がある

といったものがあり、はじめに述べたようなといった品質の注力要素全てを高めていくには工夫が必要です。そういった工夫や実装の詳細については、本ブログにて定期的に発信していこうと思います。

また、請求書AI-OCR機能の配信だけでなく、学習フェーズでもたくさんの工夫をしているので、そのあたりも今後書いていけたらなと思っています。

まとめ

というわけで、この記事ではLayerX インボイス請求書AI-OCR開発における品質の考え方、開発方針、請求書AI-OCRを構成する処理群について紹介しました。

請求書AI-OCRというと、今までのLayerXとだいぶ違うものを作ってる感じがするかもしれません。しかし、コア・ノンコアの考え方や、データを集め勘ではなく事実に基づいてアクションするというところは、行動指針に「Fact Base」を掲げるLayerXらしさが出ているんじゃないかと感じています。

まだまだ作りたい新機能もたくさんあり、機能や精度の改善、オペレーション改善、インフラの改善などやりたいことが山積しています。採用もオープンになっていますので、少しでも興味ありましたら、一度話を聞きに来てください!

herp.careers

https://herp.careers/v1/layerx/71h6Nu8eSDYC

LayerX インボイスの技術スタック〜分野横断で開発するためのSchema Driven Development〜

DX事業部の @yyoshiki41 です。

今回は、今年1月にリリースしたLayerX インボイス のアプリケーション開発についてです。 インフラ構成については、昨日のLayerX インボイスのインフラアーキテクチャで紹介されています。

tech.layerx.co.jp

LayerX インボイスというプロダクトの特徴

LayerX インボイス は、主に経理業務を行う方を対象ユーザーにした SaaS プロダクトです。 サービス内で以下の業務を行うことがメインになっています。

  1. 請求書の受領
  2. 請求書から仕訳を行う
  3. オンラインバンキングに取り込むためのデータを出力する
  4. 会計ソフトに仕訳データを連携する

また上記の他にも

  • マスタデータ(例えば、仕訳データの入力に使う取引先や部門、税区分など)の管理や会計ソフトへの連携
  • 源泉税の支払管理
  • 請求書の社内での確認

などを行う機能が実装されています。 エンジニアの普段の業務としては、馴染みのないものがほとんどですね、、

前置きが長くなりましたが、経理業務や会計からは少し離れ、本題のアプリケーション開発の話に移っていきます。

横断的な開発チーム

チームの特徴としてはフロントエンド開発だけを行うメンバーはおらず、

  • バックエンドエンジニアがフロントエンド開発を行う
  • UIデザイナーもフロントエンド開発を行う

という体制で開発をしています。

担当の領域を明確化するのではなく、機能単位で実装者をアサインして進めており、 プロダクトが立ち上げ期においては(必要な機能数が多いこともあり)非常にワークしていると思います。 プロジェクト初期に、サービス立ち上げを行った経験値を持つエンジニアが揃っていたこともうまくハマった点でもあります。

Frontend <=> Backend に限らず、Backend <=> Ops などをきれいに線引くことは難しく、 両者を行き来できるとコミュニケーションコストや機能提供スピードの面でもメリットを享受出来ると考えています。

フロントエンド開発

現在は、PCブラウザでのみサービス提供をしており、 Nuxt + TypeScript で、SPA という見慣れた構成かと思います。 Cloudfront + S3 での静的配信を行う形を取っています。

バックエンド開発

バックエンドは、Go がメインで使われています。 使っているライブラリなどは下記です。

  • フレームワーク:go-swagger
  • ORM:gorm(v1)
  • Logger: zerolog
  • DB Migration: dbmate
  • Model Generator from DB Schema: xo(fork したものを使っています)
  • Job Worker: Machinery

選択の理由としては、以下のような理由が挙げられます。

  1. まず薄く入れれるもの
  2. PR / Fork してメンテして運用出来るもの
  3. 静的型付けでコーディング出来るもの
  4. Goプログラムと外部とのデータ I/O の変換(marshalling/unmarshalling)部分を自動化出来る(e.g. HTTP API での json, DB)

以降では4番目の観点であり、チームとしての開発方針である Schema Driven を支えるものをメインに紹介していきます。

横断的な開発と Schema Driven Development

先程も述べたとおり、開発者はフロントエンドとバックエンドの双方を開発するため、 クライアントサイドエンジニアにAPIサーバーのI/Fを共有してモックを作って実装開始してもらうなどのコミュニケーションは行ってはいません。 それでも Schema Driven で開発するメリットとして享受したかったものに以下があります。

  • スキーマを先に宣言として書き、それがドキュメンテーションになる
  • レビュー工程を設計段階で行える
  • レビュー後、スキーマを「真」とした生成が行われた状態(強制された状態)で実装を始めることができる

また、HTTP API だけでなく DBレイヤでも取り入れている Schema Driven の開発プロセスをご紹介します。

■ go-swagger: HTTP API Schema 編

  1. Swagger 2.0 で定義を書く
  2. レビュー
  3. go-swagger でコードジェネレート (Swagger定義から、API Router, Req/Res Structs を生成)
  4. 作成された scaffold から、内部実装を書き進める

Swagger 2.0 (OpenAPI 2.0) しか使えない点はデメリットですが、それ以外に困る箇所は今の所ありません。 複数APIサーバーをモノレポで管理しており、Swagger 定義は以下のようなディレクトリで管理しています。

swagger
├── api                # サービスAPI
│   ├── gen.yaml       # 生成後の swagger定義 yaml
│   ├── meta.yaml      # swagger meta データ
│   └── paths          # URLパス毎にファイルを分割
│       └── users.yaml # /users の定義
├── api-admin          # 管理画面API
├── api-internal       # 内部サービス通信用API
└── definitions        # 全APIでの共通 model 定義
    └── users.yaml

API毎にディレクトリがあり、 definitions でモデル定義を共通化させて管理させています。 meta.yaml + paths/ + definitions/ から、swagger/api/gen.yaml を生成して、それを go-swagger にくわせてコード生成しています。

■ xo: DB Schema 編

  1. migration ファイルをSQLで書く
  2. レビュー
  3. ローカル上でマイグレーション適応
  4. xo コマンドでコードジェネレート (DB Schema から Go Structs を生成)

xo の使い方は 本家のREADME に譲りますが、Go Structs や enum、テーブルのPK/UK/FKからのクエリ関数生成、また生成テンプレート(Go の "text/template" 形式)をカスタマイズして任意のコードを生成することも可能です。

現状は主にモデル生成部分で使っており、CI上でテストを走らせ、DBスキーマがコードに反映されていないことを検知できるようにしています。

手を入れている点としては、アプリケーションから変更を加えないカラム(e.g. created_at, updated_at, MySQL の Generated Columns)を無視する設定を入れていたり、テンプレート部分を変更してテーブルやカラム名の const 化を行ったりしています。 DB アクセスする関数では gorm を使用していますが、生クエリではなく生成された Struct を使って書くケースが大半です。

おわりに

プロジェクト初期から Schema Driven を取り入れていたため、開発フローのベース部分での手戻りやカオス化などは避けられたと考えています。 とは言えまだまだスピードも開発機能も必要とするプロダクトなので、今後も変化をしていくことにはなります。

採用もオープンになっていますので、少しでも興味ありましたら、一度話を聞きに来てください!

herp.careers

LayerX インボイスでは、Schema を先に書いて開発を始めるスタイルを導入しました。 使用するプログラミング言語の実装から開始する(コードからスキーマを生成する)アプローチも、言語の特性とツール選択からは可能かと思います。 GraphQLで schema-first vs code-first が話にあがることもあり、 今後も開発スタイルをプロジェクトにあった形で始める点は動向には注目していきたい次第です

LayerX インボイスのインフラアーキテクチャ

こんにちは、LayerXでインフラを担当している高江です。

今回は、弊社の請求書AIクラウドサービス「LayerX インボイス」のインフラについて、 現在のアーキテクチャ構成と、設計時に考慮したポイントをご紹介いたします。

サービス自体については事業責任者の @mosa_siru がご紹介しておりますので、こちらのエントリをご覧ください。

tech.layerx.co.jp

アーキテクチャ構成

まずはみんな大好き構成図から。
LayerX インボイスのインフラはAWS上に構築されており、その構成はざっくりこのようになっています。

f:id:shnjtk:20210402190022p:plain
LayerX インボイス インフラ構成図

大きく分けると、

  • LayerX インボイス(本体機能)
  • ユーザー情報管理・認証基盤
  • 共通データ基盤

という3つの部分から構成されています。

LayerX インボイス(本体機能)

ここがLayerX インボイスの本体となる部分で、請求書を受け取ってOCRで内容を読み取り自動で仕訳を切ったり、各種会計サービスと連携するといった処理を行います。

こちらについては、

  • フロントエンド : NuxtによるSPA
  • バックエンド : GoによるAPIサーバ
  • データストア : AuroraやDynamoDBなどのデータベース

という、いわゆる3-tierアーキテクチャです。

これに加えて、LayerX インボイスにはメールで送付された請求書を取り込むという機能があり、これはSendGridと連携することで実現しています。
メール受信機能はインボイスの本体機能とは切り離し、独立して稼働させています。
これは、本体機能をメンテナンスしている間や、万が一APIサーバに障害が発生した場合であってもメールは受信できるようにするためです。

また、時間のかかる処理は非同期処理とし、APIサーバとworkerタスクとのメッセージングにはSQSを介しています。
そのほか、定期バッチ処理のためにRundeck(ジョブスケジューラ)をEC2上に立てて運用しています。

ユーザー情報管理・認証基盤

ユーザー情報の管理やログイン時の認証機能を担当する部分です。
部署や担当者、役職といった組織情報の管理も行います。
インボイス本体に比べると軽量で、構成もシンプルです。
一部の機能はプライベートAPIとして実装されており、インボイス本体からプライベートネットワーク内の通信として呼び出されるため、internal ALBを配置しています。

共通データ基盤

ユーザーの情報や請求書情報、仕訳情報などのデータを管理する部分です。
データベースにはAuroraやDynamoDBなど複数のサービスを併用しています。
また、全文検索エンジンとしてElasticsearch Serviceも利用しています。

設計時の考慮事項

LayerX インボイスのインフラ構成を検討するにあたり、開発初期の頃から意識しているのは以下の点です。

  • ノンコア運用で頑張らない
  • 横展開できる
  • 出来る限りシンプルに

ノンコア運用で頑張らない

「適切に楽をする」とも言えるかと思いますが、これはスケーリングやバックアップなど、運用上必要ではあるがコアではない部分についてはマネージドサービスを活用して自分たちのコストはかけずにやろう、ということです。
こういったことはクラウドベンダーが提供してくれるサービスに任せ、開発リソースは本質的なコア部分に最大限投資できることを重視しています。

これは、LayerX CEOの福島がこちらのnoteで書いていた「コアとノンコアを意識。ノンコアにはSaaSを」という内容に通づるものがあります。

comemo.nikkei.com

横展開できる

今後LayerX インボイスと連携する新たなサービスを開発する際に、LayerX インボイスで蓄積した開発資産を活用することで、短期間で必要なインフラを構築し、サービスを提供できるようにするということです。
高い再利用性、汎用性を意識する、とも言えます。
少人数のチームで多数のサービスを高速に展開するために重要な要素であると考えています。

出来る限りシンプルに

構成が複雑化すると全体の把握が困難になり、例えば構成上の重要な部分に関する知識が一部のメンバーにしか理解されておらず、運用が属人化して担当者がSPOFになったり、設定ミスによる障害を引き起こす原因になったりします。
そのため、構成要素を少なくしたり、循環参照が発生しないように通信経路を一方向にするなど、設計段階から常に構成をシンプルに保つことを意識しています。

おわりに

以上、LayerX インボイスのインフラ紹介でした。

構成をご覧いただくと、特に奇をてらった部分はなく、比較的オーソドックスなものになっているのが分かると思います。
しかし、この構成に至るまでには数々の試行錯誤があり、その都度技術的な調査や選択を繰り返してきました。
その結果、なぜこのような構成にしたのかという判断のクオリティは、開発当初に比べて明確に上がっています。

今後も機能追加やサービスラインナップの拡充などによりインフラの規模はますます大きくなっていくと思われますが、設計の根底にある意識やアプローチは変わらないので、これまで積み重ねてきた経験を基に、開発スピードを落とさない運用を目指していきたいと思います。

おまけ

今年のAWS Summit Online 2021で、今回触れなかったCI/CDパイプラインやセキュリティ、ガバナンスといった点も含めて @mosa_siru と一緒にたっぷりとご紹介いたします。
5/12(2日目)の17時からとなりますので、こちらもぜひご覧ください!

aws.amazon.com

LayerX インボイスの紹介と開発風景

こんにちは!LayerXの @mosa_siru (榎本) と申します。

LayerXでは、LayerX インボイスという経理の方向けのDXプロダクトを開発しています。いわゆるSaaSです。こちらの事業責任者をやっております。

https://www.layerx.jp/invoice

今回のエントリでは

  • LayerX インボイスの簡単な紹介
  • 数ヶ月で爆速リリースするまでのプロセス
  • インセプションデッキとチーム話
  • スクラムのスタイルと開発チームのMTG

について書きます。最後まで読んでいただけたら嬉しいです!

LayerX インボイスって?

会社には、「1. 請求書を受け取り」「2. その内容をみて会計上の仕訳を行い」「3. 適切に支払う」という請求書処理プロセスがあります。これらの業務フローは各社バラバラですが、手入力でExcel、会計システム、オンラインバンキング上で何度も同じ内容を入力していたり(その分ミスも増え、チェックも多く必要です!)、各種マスタが点在していて転記作業が必要だったりと、その煩雑さから月初の残業とストレスの元になっていました。

LayerX インボイスでは、請求書を効率的に回収し、OCRや学習データを用いて請求情報と仕訳をデータ化し、加工することなく会計システムとの連携・支払データを出力する一連のプロセスを一気通貫で行うことができます。なんだか便利そうですね!

実際に多くの会社さんに導入され、「作業時間が減った」「ストレスが格段に減った」「月次の締めが早くなった」などの声をいただいております。

f:id:mosa_siru:20210402145806p:plain

LayerX インボイスは2020年の秋頃にプロダクトの方向性が決まり、翌年1月にリリースするという極めて速いスケジュール感で開発されました。現在も毎週のように新機能や、新しい会計ソフトへの対応がリリースされております。どのように開発しているのか、その風景を紹介できたらと思います。

インセプションデッキ

スクラム開発の最初にチームの共通認識を揃えるインセプションデッキにて、チームで「やること」「やらないこと」を決めました。その中で「やること」のトップは 「スピード!スピード!スピード!」

動くものをいち早く作りデリバリーし、そのフィードバックを最速で反映する、そのサイクルを常に意識して開発しております。初期は1-2日で作ったプロトタイプ(または開発しないで紙芝居)をお客様に当てて反応をみる、なども繰り返していました。

ニュアンスを伝えるのが難しいですが、逆に「やらないこと」として「ちゃんとしすぎない」というのも取り入れております。エンジニアとして「ちゃんとしすぎる」のは際限がないため、事業の成功に寄与するように良いラインを模索し続けようという意図です。(ちゃんとしてます!)

エンジニアの文化

LayerXでは「Trustful Team」という行動指針があり、一言でいうと「背中を預け合う」形で開発しております。DXチームではフロント、サーバー、インフラとフルスタックに扱えるメンバーが、機能単位で一気通貫で開発しており、それが速さの源となっています。チームでわいわいしながらも、それぞれがプロ意識をもって開発するスタイルです。

f:id:mosa_siru:20210401211608p:plain
チームが組成されて早速成果が出た瞬間。Trustful Team!

ドメインに対するキャッチアップも貪欲で、SaaS経験者も経理業務経験者も乏しい中で、各位が勉強して突き進んでおります。このキャッチアップ力は、全社に共通する、LayerXの行動指針 「Be Animal」 たる所以かと思っております!

f:id:mosa_siru:20210329235432p:plain
slackのPublic channelの割合
slackでも透明性は健在です。強い個人が、意思決定に足る情報が浸透した上で有機的に動く。それこそが速度をうむ源泉です。

スクラムのスタイルとMTG

チームの開発スタイルを言葉でお伝えするのは難しいので、会議体を例にとって説明しようと思います。

MTGは開発時間確保と頭の切り替えのために、月曜日と金曜日に集中させるなど工夫をしています。

DDD - デモ駆動開発 (Demo Driven Development)

LayerXでは週次の全社定例で、各事業部が簡単な「デモ」をする文化があります。動くモノが正義だよね、という考えのもと、毎週プロダクトのアップデートが共有されます。動くモノを毎週見せるサイクルは程良い緊張感を生み、そして皆を鼓舞します。

チーム内でも、週の終わりにプロダクトの詳細なデモを行い、セールス含めた共通認識を作ります。 こちらのデモは「景気(進捗)が良い人」から行います。毎回の景気の良さにビビります。

タスク管理とSprint計画

ユーザーストーリーやタスクはAirtable(時々miro)で一元的に管理しています。(一時期ぐちゃぐちゃでしたが、なんとか持ち直しました。)全ての新機能に優先度が振られ、誰がみても何をすべきかわかるようになっています。数百以上のタスクが管理されています。やりたいことが無限にあります!!

Sprintは2週間単位で、その計画では優先度が高いものからピックしていきますが、あらゆる優先度を横並びに比較するのは難しいため、最近では「新機能」「機能強化」「bug」「品質」「改善(細)」「システム系」にタスクを分類しています。新機能はロードマップに従い、機能強化は優先度順に行います。

いかにお客様からの要望を一元管理し、最速で開発サイクルに回せるかが運営の妙になっています!

エンジニア朝会 ・全体夕会

エンジニアはdailyでstand up MTGをしており、簡単に昨日やったこと・今日やることを報告します。リリースの計画やQAの共有、簡単な相談も行います。

全体では夕方に集まり、セールス含めたチーム一体の全体共有や相談を行います。難しい仕様についてはここで共有します。 良いことがあったときは、ドラを鳴らします!!

夕会の風景。オフィスにいながらも、zoomで画面共有しています。便利!

気になり会

不定期で、エンジニアが「なんか気になるよね」「なんかもやもやする」ことを話す場を設けています。障害について、品質、コードの書き方、様々なトピックが話され、ネクストアクションに繋げていきます。

振り返り

月1で全体でしっかり振り返りを行います。KPT(Keep, Problem, Try)を行い、次のアクションにつなげます。

前月のProblemがKeepになっていることが多く、チームの強さを感じます!

リモートでの工夫

緊急事態宣言下はリモートがメインでした。そのときの工夫点としては、いつでも同期的コミュニケーションができるよう、Zoomで全員「つなぎっぱなし」をしておりました。

slackで「ちょっと今通話良い?」のコミュニケーションは心理的ハードルが高いので、zoomを常に立ち上げて、簡単に話しかけられるスタイルです。気軽な同期的コミュニケーションは、爆速開発には欠かせません。

全員が同じ部屋にいると大変なので、ブレイクアウトルームを使い、話し込むときは別の部屋にうつったり、作業集中したい人もうつるなどしていました。

リモートしているチームにはとてもおすすめです。ネックは電源消費がすごいこと。。

※4月現在は、出社を基本としています。企業文化を醸成し、組織力やチームワークを向上していくことを考えたときに、そういった結論になりました。一方オンラインの方が生産性が高いものは、積極的にオンラインで行っています。

まとめ

以上がDXチームのリアルな開発風景となります!ひとつひとつがかなり模索された上で今の形になっており、爆速開発を支えています。

今回は開発スタイルの話になりましたが、このブログではどしどし開発にあたっての知見を公開していきます!お楽しみに〜!!!