freee社内のアクセシビリティのいい話 2020年8月号

どうも、20新卒の全盲のコード書き、野澤です。社内では cat と呼ばれています。猫好きなのでこの名前です。もう猫になりたいぐらい猫好きです。

私が正社員として入社してから4か月が経過しました。そのなかで、freee社内でアクセシビリティのいい話がたくさんありましたので、そのうちのいくつかを共有したいと思います。「アクセシビリティ」という言葉を聞いたことがない方や、アクセシビリティについてもっと知りたいという方は、以下のエントリーもぜひご覧ください。

jobs.freee.co.jp developers.freee.co.jp developers.freee.co.jp

全盲なのにコードは書けるのか?

はい。このような疑問を抱く方も、当然いらっしゃるのではないでしょうか? 全盲ということは、まったく目が見えないということです。画面が見えないわけなので、コードも見えないし、terminalの出力も見えません。では、どうやっているのかというと…。

  • PCに「スクリーンリーダー」をインストールして、コードやターミナル出力、ウェブサイトの内容、入力する文字など、あらゆるものを読み上げさせて聞く
  • 「点字ディスプレイ」という機械をPCに接続して、集中して読みたい部分を点字で読む

なんということでしょう!こういう支援技術を使うと、画面をまったく見なくてもRailsのAPIサーバを実装できたり、CSS以外のReactコンポーネントをがんがん作れたり、社内共通のReactコンポーネントライブラリ( Vibes ) でいい感じのUIをさくっと書けたり、AWSでインフラを作ってコンテナデプロイができたり、よくわからないエラーが出て時間を溶かすことができたりするのです。

新卒4か月で取り組んだこと

以下に、私が4か月で取り組んできた業務内容を挙げます。

4月から5月は、新卒研修で新規ウェブアプリの開発に携わり、API設計、フロントエンドロジック、インフラ構築とデプロイを担当しました。 6月からは、freeeサービスにおける認証認可基盤を開発/保守するチームに配属となりました。最初の1か月は、freee アカウント管理の機能改善や保守作業を行っていました。7月からは、現在開発中の新しいマイクロサービスのgRPC実装に力を入れており、書いたことも読んだこともなかったgoとドラマティックな戦いを繰り広げています。freeeにおけるマイクロサービス化の歩みについて興味がある方は、以下の記事も合わせてご参照ください。

developers.freee.co.jp

じつは困ったこともあった

支援技術のおかげでfreeeでの仕事ができている私ですが、画面を見ることができないというのは事実であり、そのハンディキャップが完全になくなったわけではありません。

業務で利用するサービスのアクセシビリティが確保されておらず、スクリーンリーダーへの対応が不十分だったこともありました。事前知識の獲得や要件定義の把握に利用する資料が視覚的レイアウトや色に依存しており、それだけでは理解できなかったということもありました。

工夫しながらどんどん改善

何かの目的を達成しようとするとき、多くの場合、そのための方法は1つではありません。いくつかある方法のうち、目が見えなくてもできるものを探し、必要な環境を1つずつ整えていけばよいのです。このとき、一緒に仕事をするメンバーとの協力は欠かせないものです。場合によっては、今までのやり方から、多かれ少なかれ変化が発生することも十分にあり得るからです。幸いなことに、配属先のメンバーは変化に対して柔軟で、私が最大のパフォーマンスを発揮できるよう、いろいろなことを一緒に考えてくれています。そのうちのいくつかをご紹介したくて、この記事を書いています。

研修でどうしても難しかったところを臨機応変に対応してもらえた

研修資料に画像がたくさんあったときには、専用のチャット部屋を作って質問できるようにしてもらえました。 研修に利用する予定のサイトを開いたらスクリーンリーダーが暴走してどうしようもなかったときは、そのサイトを使わずにローカルでやればいいということにしてもらえました。 研修のスライドには、インフラ構成図なども多くあったのですが、かなりの部分に代替えテキストを付けてもらえていたので、理解にこまることはありませんでした。

新卒の同期たちが、結構自然にアクセシビリティと発言する

新卒研修でばんばんコーディングをしているときも、アクセシビリティ関係を結構気にしてもらえていたし、アクセシビリティを直すPRを投げるとすぐ見てくれたし、とてもよかったです。そのおかげで、うちのアプリはVibesを使わなかったけどかなりアクセシブルになりました!

配属先で運用方針を工夫してもらえた

私が来る前は、JamboardというGoogleのホワイトボードみたいなサービスを利用していたり、JIRAのスプリントボードにフラグを付けて、それを共有しながらやったりしていたようです。けれども、Jamboardは文字情報だけでなく配置も重要になり、現状、その読み上げには対応していないので私は利用できません。 JIRAは一応使えることには使えるのですが、いくつか並んでいるタスクの中からフラグが付いているものを探したりする作業は、画面全体が見えていないとどうしても時間がかかり、追いつくことが困難です。

驚くべきことに、これについて、私が実際に参加する前から検討していただけていました。しかも、お互いの利便性を損なわず、変更が容易で、柔軟な形で。「Jamboardなんですが、やめましょう!!!」という一声でJamboardが消え去ったときには、正直ビビりました。

JIRAについては、議題に上がるチケットの番号を言ってもらうようにするだけで、1個ずつ読み上げさせて探す手間が0になり、問題なく話についていけるようになりました。これこそ、専門的に言うところの「障害の社会モデル」ですね。

Vibes プロトコルで話をするとフロントが普通にできちゃう

さすがに自分で見た目を確認して…とはいきませんが、どちらにしろ社内のコードは必ずレビューとセットなので、そこは問題になりません。Vibesという社内で開発しているUIコンポーネント集があるので、最初にフロントを実装するときに、「ここらへんにVibesのNoteコンポーネントを置いて、ボタンはこのpropsを渡せば今回やりたいスタイルにできるから、そんな感じでやっといてー」という感じでちょっと打ち合わせをすれば、それだけで問題ないのです。中身の表示を変える、条件分岐させるといったことは、Reactをどうやって書くかというだけの話なので、そこは私が考えればいいのです。

ちなみに、Vibesを使わなかった新卒研修では、私が強い気持ちでコンポーネントを書いて、あとはスタイルなどを誰かがあててくれて、気が付いたら組み込まれている…という感じにしていました。それでもなんとかなったようですが、私が画面のデザインデータを見られなくて妄想力を溢れさせて実装したところがちょっと違ったりしたみたいです!やっぱりVibesは社内プロダクトの開発には欠かせない存在です!

デプロイタスクで、E2Eが成功しているのかどうかわからなかったのを直してもらえた

ステージングデプロイのあと、E2Eテストが走るようになっているのですが、これが成功したかどうかは、色の違いで表示されていました。これは当然私にはわからないし、それがE2Eの成功/失敗を表している通知であることさえ、教えてもらうまでまったく知りませんでした。

この問題に定期デプロイしているときに気づいたのですが、3日後にはQAチームの方が直してくださり、 success か failure と表示されるようになりました。これで、なんの問題もないですね!

社内には点字があるし、点字付きで郵便物が送られてくる

先日、社内全体で行われる大規模イベントがありました。そこで使用する道具がいくつかあり、郵送されてくることになっていました。受け取ってみると、その箱には点字が付いていて、中身にまでしっかり点字の説明が入っていました。実は、中に複数の箱が入っていて、順番に開けないといけなかったのですが、点字の説明のおかげで、バッチリ正しい順番で開けられました!

「7月3日開封案内まで開封厳禁」と書かれた大きな箱と、中に入っていた空ける時間の指定された箱
社内イベントで使われた「フリスピBOX」と、中身の箱
(詳しくは社員500名 全員オンライン!8時間の大規模イベントを気合とハックでやりきった話を参照)

freeeは、我々点字ユーザーのために、点字をシールに印字できる機械を購入して使ってくれています。今は出社することがないのですが、オフィスのドリンクサーバーには、ボタンを押したらなんの飲み物が出てくるのか、すべて点字で書いてあるのです。

ドリンクサーバーの写真。上からジンジャエール、ペプシネックス、オレンジジュースのボタンがあり、左側に点字ラベルがある
オフィスのドリンクサーバー。よく見るとボタンの左側に点字ラベルが貼られている

なんか困ったらとりあえずSlackのtimesチャンネルでつぶやくと優しい人が教えてくれる

業務のことでも、業務外のことでも、です! 皆さんがtimesを見て反応してくれるおかげで、私は生きることができます。これは本気です。

4か月でこんなにあった

今や、普段の業務において、視力障害が妨げになることはほぼありません。それどころか、日常生活においてちょっと困ったとき、会社の仲間に助けてもらえることすらあります。これは、多くのfreeersの協力によって実現されていることで、毎日感謝しています。私も、freeersやfreeeカスタマーにマジ価値を与え続けられるよう、日々精進していきたいと思います!

サマーインターン生がアクセシビリティの改善に取り組んだお話

はじめに

こんにちは。
freeeサマーインターン2020に参加させていただきました ganariyaと申します。
2022新卒予定の修士1年で、群知能と呼ばれる生物の群れの行動をシミュレーションして最適化を行う研究をしています。
普段は競技プログラミングを趣味で行っています。

さて、そんなganariyaは、freeeのプロダクトの一つであるプロジェクト管理フリーチームで、2週間のインターンに参加させていただきました。
具体的な業務内容は、プロジェクト管理フリーのアクセシビリティの改善です。

ganariyaにとってアクセシビリティとは初めての概念です。
最近重要視されているアクセシビリティとは一体何でしょうか。


アクセシビリティ (Accessibility)

アクセシビリティの定義はいくつか公式な定義があります。 そのうち、freeeアクセシビリティー・ガイドラインを一般公開しましたを引用すると

誰でも、ほぼ同じコストで、ほぼ同じようにサービスや情報を利用できる

ような状態をアクセシビリティが高い状態といえます。

2020年現在、あらゆる人がインターネットやスマートフォン、IoTにクラウドなどを利用しています。
そのため、国籍、年齢、性別、障害の有無、マシン環境など、誰でもストレスなく平等にサービスを利用できることが求められます。

誰にとっても使いやすいこと、同じような操作ができることが、今のITサービスに必要なのです。

アクセシビリティガイドライン

Webにおけるアクセシビリティは、W3Cが作成したガイドラインである「Web Content Accessibility Guidelines (WCAG) 2.1」にて定義されています。

以上のWCAGは英語版であり、日本のウェブアクセシビリティ基盤委員会が翻訳したガイドラインは「Web Content Accessibility Guidelines (WCAG) 2.1」にて読むことができます。

しかし、WCAGのガイドラインは特定の用途に絞らないために抽象的に書かれており、分かりにくい部分があります。
そのため、freeeではWebサービスにおけるfreeeアクセシビリティガイドラインを公開しており、このガイドラインに準拠するようにプロダクトを作成しています。

このfreeeガイドラインでは

  • フォーム
  • 画像
  • ログイン・セッション

といった具体的なWeb要素に分けてアクセシビリティの説明をしています。
また、実際のプロダクト作成時の注意点やチェックリストも記載しています。

アクセシビリティの例

アクセシビリティは概念的であり理解が難しいです。

そこで、アクセシビリティの具体的な例を2つ見てみましょう。

例1 alt属性を設定する

例えば、以下の画像を見てください。
これはfreee developers blogのアイコンです。

しかし、この画像にはalt属性が設定されていません。

このalt属性は、画像の代替テキストを設定するための属性です。
画像がなにかの手違いで表示されないとき、ブラウザが代わりにaltで設定された文字を表示してくれます。これによって、画像が読み込めない場合でも、なにが表示されるはずだったのか利用者は理解することができます。
また、目が見えにくい方はスクリーンリーダーを用いてWebページの情報を音声として聞きます。このとき、もし画像にalt属性が設定されていない場合、そこに画像があることは分かりますが何を表す画像かを伝えることができません

そのため、画像にalt属性を設定することは、アクセシビリティを向上させる最初のステップと言えます。
以下のようにaltを設定すると良いでしょう。 これによって、どのような画像であるかをより多くの方に伝えることができます。

freee developers blogのアイコン

<img src="https://cdn-ak.f.st-hatena.com/images/fotolife/g/ganariya/20200827/20200827114321.png" alt="freee developers blogのアイコン">

該当するfreeeガイドラインはfreeeガイドライン 画像の説明の提供です。

例2 Webらしい表記にする

以下3つのリンクをクリックしてみてください。

  1. freee公式サイト
  2. google
  3. https://www.yahoo.co.jp/

このうち、本当にクリックできるのは1つ目と3つ目のリンクのみです。
2つ目は「青文字で書かれたテキスト」であり、リンクではありません。リンクと誤解されやすいような青色や紫色のテキストは避けるべきです。
また3つ目のリンクも、リンクを直書きするよりアンカータグでリンクを指定したほうが、音声を分かりやすく読み上げてくれます。

また、実装の都合上意外とやってしまうのが以下の例です。

<div onclick="サイトを開くjavascript" class="div-link">
   Yahoo公式サイト
</div>

上記のような実装は可能な限り避けるべきです。 なぜならば、ブラウザは以上のようなdivタグをリンクであるとは認識してくれません。ただのonlickハンドラが設定された良く分からないdiv要素がそこにある、としか認識されないのです。

もしどうしても使用しないといけないのであればrole="link"属性を付与します。 ただし、できる限り最初から用意されているaタグやbuttonタグなど、行いたい操作に適したHTMLタグを利用すべきです。

該当するfreeeガイドラインはfreeeガイドライン リンクの説明です。

このように、Webページとして当たり前の表記・実装を行うこともアクセシビリティを向上させる重要な改善です。


アクセシビリティ改善内容

それでは、アクセシビリティの観点から実際にganariyaが改善を行った内容を特に3つ取り上げて説明します。

1つ目 テキストで情報を伝える

プロジェクト管理フリーでは、プロジェクトに関わった方々の工数を記録することができます。
このとき、下記の画像のようなカレンダーに工数を設定します。

修正前のカレンダー。今日の日付に相当するセルだけ、背景色を水色にしている

このとき、「今日の日付に相当するセルであること」を色の違いでのみ表現しているため、色覚異常の方や目の見えない方が今日のセルを判別し辛い状態になっていました。

そこで、今日の日付であれば、テキストで「今日」と表すように修正しました。

修正後のカレンダー。今日の日付のところだけ、日付の数字をテキストで『今日』、にしている

この修正によって、今日のセルの識別が色の違いのみに依存しないようになりました。

該当するfreeeガイドラインは以下のリンクです。

2つ目 エラーメッセージを読み上げる

プロジェクト管理フリーには、多くのフォームがあります。
これらのフォームの送信時に入力内容の間違いがあった場合は、エラーメッセージを表示して利用者に内容を修正してもらう必要があります。

例えば、以下の画像のようなエラーメッセージを利用者に提示します。 標準労働時間を24時間以内で入力してほしいですが、利用者はとても大きな数字を入力してしまいました。 そのため、「1分以上24時間以内の数字を入力してください。」とエラーメッセージを出しています。

修正前の標準労働時間設定画面。エラーメッセージの内容がブラウザに伝えられていない。

このとき、目の見える方はエラーメッセージが表示されたということに気づくことができます。
しかし、目が見え辛い方はこのエラーメッセージに気付くことができず、ページが遷移しない原因を自分で調べなければなりません。

そのため、aria-liveが設定できるように、エラーメッセージを出すクラスを修正しました。
aria-live属性は、設定されたHTML要素のコンテンツに変更があったときに、その変更内容をスクリーンリーダーで読み上げるように設定するための属性です。

<div class="message" aria-live="polite" id="error-message">
</div>

上記のようにaria-liveを設定することで、idがerror-messageのdivタグにエラーメッセージが追加されたタイミングで、そのメッセージをスクリーンリーダーが読み上げてくれます。

これによって、より多くの方がエラーメッセージを理解し、フォームが修正しやすくなりました。

該当するfreeeガイドラインは以下のリンクです。

3つ目 リンクを含む完了メッセージを自動で消さない

作業完了を示す通知メッセージ。工数を一括登録しました、というメッセージが通知される。

プロジェクト管理フリーでは、工数を一括登録した際に作業が完了した旨のメッセージが通知します。この通知メッセージには、行った一括登録を取り消すボタンが設定されており、ボタンを押すことによって先程の操作を取り消すことができます。

しかし、これまでの通知メッセージは表示されてから5秒経過すると自動で消える仕組みになっていたため、利用者が意思決定に伴う操作をうまくできない問題が発生していました。 そこで、ボタン操作が含まれるような通知メッセージは、自動的に消えないように振る舞いを変更しました。

ただし、通知メッセージにおける問題をまだすべて解決できていません。
例えば、通知メッセージが出てきたことに目が見えない方が気付きにくくなってしまっています。
この問題を解決するためには、通知メッセージが出てきたら読み上げを行うaria-live属性を付与する修正が考えられます。また、通知メッセージが出てきたときにマウスのフォーカスを直接移動させる修正も考えられます。

これらの問題に対する解決法に唯一の正解があるわけではありません。
通知メッセージがすべて読み上げられてしまうと、不必要な情報量が多くなってしまい作業の邪魔になる可能性もあります。 ページによっては、行っている作業を継続したいためマウスが移動すること自体が嫌となる場合も考えられます。

誰にでも使いやすいプロダクトになるよう、状況に合わせて最善の対策を練ることが大切であると感じました。


インターンを通じて学んだこと

インターンの2週間は本当にあっという間で、ganariyaにとって新しい経験の連続でした。
得られた知識・変わった概念は本当にたくさんです。

プロダクト開発

ganariyaは大学3年生始めのころに競技プログラミングに出会い、それ以来ほぼすべての時間を競技プログラミングに費やしてきました。競技プログラミングが楽しくて楽しくて仕方がなかったのです。
大学1, 2年生のころはUnityやSiv3Dでゲーム開発をしたり、Webの勉強をしていましたが、気持ちを一気に塗り替えたのが競技プログラミングでした。

そのため、競プロのChrome拡張機能をVueで作成したり、Electronで変な個人アプリを作ったりはしていましたが、大規模なWebアプリをチームで作るということ自体がはじめてでした。

所属させていただいたチームのコード・開発を見てganariyaは椅子から転げ落ちました。

ソースコードはとても考えられて設計されています。
テストは自動化されており、毎日新しい機能が追加されています。
アジャイル開発でチームが回っており、開発コードのみではなくチームのプロセス自体が改善されています。

このようなチームとしてのWebアプリ開発のプロセスを少しでも学べた経験がとてもありがたい、と感じています。
というのも、競技プログラミングは数理・アルゴリズム的な問題を素早く考察してバグなく実装することが求められます。
そのため、大規模なソースコードはほぼなく(データ構造やアルゴリズムのライブラリを作成することはありますが)、どちらかといえばアルゴリズムを多く理解し数理的に応用する、ということを主としています。
競技プログラミングを頑張ることによって、フロントエンド、バックエンドの知識などが直接身につくことは基本的にはありません。(基礎力、スポーツなどで言えば筋トレに競技プログラミングは相当します。)

これから大学に出て社会に貢献していくには、どこかで考え方を競技プログラミング中心から変えていく必要があり、その貴重な機会をいただけたと考えています。

アクセシビリティ

アクセシビリティは、特に今回学んだ貴重な経験ならびに新しい知識です。

というのも、ganariyaが行った改善内容を、freeeアクセシビリティー・ガイドラインを一般公開しましたの著者である中根さんに実際に使っていただき、多くのレビューをいただきました。
このうち、いただいたレビューの中で特に印象に残っている2つをご紹介します。

1つ目は、「画面における読み上げと表示内容をできるだけ一致させる」ことです。表示内容と読み上げが異なると、誤った操作が発生する、もしくはそもそも画面の変化に気付くことができない可能性があります。また、aria-labelを用いて表示内容と異なる読み上げを行うと、将来的にソースコードが修正された場合にaria-labelのみを直し忘れてズレが発生してしまう可能性があります。これらを防ぐためにも、表示内容や操作の一貫性を保つことが原則であることを学びました。統一されたインターフェイスは、プログラム的にも機能的にも、そしてアクセシビリティ的にも大事なのだなと分かりました。

2つ目は、「操作の状況やページの状態によって取るべきプラクティスが異なる」ことです。例えばaria-live属性によって、ユーザはメッセージの検知ができます。しかし、この読み上げられるメッセージが長かったり頻度が多かったりすると、使い慣れたユーザは多すぎて逆に操作の邪魔になってしまいます。必ずこれで最適解である、というものではなく、Webアプリの状況やページ量、操作内容によって取るべき方法が変わってきます。ユーザを第一に考えを凝らして、プラクティスを作り出すのが大切なのだと分かりました。

これまでの個人開発やバイトの開発では、画像にalt属性を付与すること、色のコントラスト、タグの区別などのアクセシビリティを気にせず、機能を重視して開発を行っていました。
そのため、ganariyaが書いてきたコードにおそらくアクセシビリティが低いコードがたくさん埋まっています。
それらを早く修正したい、多くの人にとってもっと使いやすいアプリにしたい、そのような感情が今回のインターンならびにレビューを通して芽生えました。
この感情を大切にして、アクセシビリティを意識したキレイなコードを生んでいきたいです。


最後に

ganariyaは現在修士1年です。
来年には就職活動を行い、再来年には社会に出ます。
これまで支えられていた側から社会になんとかして貢献していく側になります。

多くの競プロerにとって、いつまでも競技プログラミング一本ではなく、もう一個競プロが生きるような柱が必要です。
それが人によっては、フロントエンドであったり、バックエンドであったり、インフラのパフォーマンスチューニングであったり、はたまた起業だったりします。

今回のサマーインターンを通じて、この思考のプロセスの転換の機会をいただくことができました。
ganariyaにとってのもう一本の柱、競プロが生きる軸を見つけていこうと思います。

競プロがチョットデキル、アクセシビリティなどもチョットデキル、そんなエンジニアを目指して、まずは自分のこれまでのソースコードのアクセシビリティの改善から始めていきます。

サマーインターン生のganariyaでした。
ここまでご覧いただき本当にありがとうございました。
初心者なりにですがアクセシビリティのことをお伝えできていれば、とてもうれしく思います。

freeeアクセシビリティー・ガイドラインVer. 202008.0を公開しました

こんにちは、freeeのアクセシビリティーおじさん、中根です。 以前CAO(Chief Accessibility Ojisan)を名乗ろうと思って名刺にも入れようとしたんですが、「説明コストが高すぎる」という冷静かつ的確な一言で断念したことがあります。

さて、今回もfreeeアクセシビリティー・ガイドラインの更新情報をお届けします。

中心は「チェック内容」の見直し

8月21日に公開したVer. 202008.0の更新内容の中心は、各ガイドラインに対応できているかどうかを確認するための「チェック内容」に関する見直しです。 前回のリリースまでの作業で、ガイドライン本文の内容が基本的に固まり、追加しようと思っていた参考情報も概ね追加できたことから、各ガイドラインについてのチェックを効率的に進めるための方法を検討した結果が、今回のリリースです。

以下、少し詳しく紹介します。

チェック内容の整理

まず、すべてのチェック内容について、それぞれどのガイドラインと対応しているのかという情報と併せてリストを作りました。

このリストを眺めると、同じチェック内容が複数のガイドラインに対応しているような場合がいくつか目に付きます。 そのため、実際にチェックを実施してみると、複数のガイドラインについてまとめてチェックできる場合が少なからずあることに気づきました。 (正確には、分かっていたことではあるのですが、予想以上に非効率的だなと感じました。)

そこで、なるべく効率的にチェック作業を進められるように、作業内容が似通っているチェックを1つにまとめることにしました。 その結果、元々は1つのチェック内容には1つのガイドラインが対応しているという状態のリストだったものが、1つのチェック内容に複数のガイドラインが対応している状態のリストになりました。

例えば、これまでコントラストに関するチェックは、テキスト、画像内のテキスト、画像化されたテキストなど複数の対象に関して別の項目が存在している状態でしたが、今回の変更ではこれを1つの項目にまとめています。

チェック対象の見直し

次に、各チェック内容について、開発のどの段階で行うものかという視点で見直し、結果として「チェック対象」を変更しました。

これまでは、機能、ビジュアル、挙動、マークアップという4つのチェック対象を示していましたが、今回の変更では以下の3種類に変更しています。

  • デザイン:主に仕様を決める時点や設計段階で確認すべき項目
  • コード:マークアップやコーディングを確認しなければ判断が難しく、主に実装時に確認すべき項目
  • プロダクト:実際に操作してみたときの挙動で判断でき、主に実装後に確認する項目

これはあくまでもfreee社内での開発の状況に即して考えているものなので、開発体制によってはより細かい分類が必要だったり、逆にこのような分類が不要だったりすることもあると思います。 freeeの開発体制においては、対象が「デザイン」のチェックは設計段階でUX担当者が実施し、「コード」のチェックは実装時にエンジニアが実施し、「プロダクト」のチェックは実装物のテスト段階で品質保証の担当者が実施することを想定しています。

このような前提に基づいて各チェック内容の対象を見直した結果、チェック対象を増やすことになったものが複数あります。 そして、チェック対象や開発工程に応じて、より適切な表現に修正した項目もあります。

例えば、画像の説明の提供: 画像に関する過不足のない説明をテキストで提供する。

というガイドラインについて、これまでのチェック内容は以下のようになっていました:

  • マークアップ: 画像に関する簡潔で過不足ない説明が alt 属性や aria-label 属性で付加されている。かつ
  • マークアップ: 短いテキストでは充分に説明できない場合には、 aria-describedby 属性を使うなどして、詳細な説明が提供されている。

今回の変更で、このガイドラインのチェック内容は以下のようになりました:

  • デザイン
    • 画像に関する簡潔で過不足ない説明(alt属性値)が、設計資料で明示されている。かつ
    • 短いテキストでは充分に説明できない場合には、詳細な説明のテキストが設計資料で明示されている。
  • コード
    • 画像に関する簡潔で過不足ない説明が alt 属性や aria-label 属性で付加されている。かつ
    • 詳細な説明が必要な場合には、その説明が当該の画像の直前または直後に表示されている、または aria-describedby 属性で関連付けられている。
  • プロダクト
    • 画像の説明が適切に読み上げられる。

これまでは実装時に適切にマークアップされていることを確認すれば良いというような書きぶりになっていたのに対して、変更後は設計時、実装時、動作確認時にそれぞれ確認するような形になっています。 上の例の場合、もし動作確認時にスクリーン・リーダーで画像の内容が読み上げられなければ、実装時に適切なマークアップがされていない可能性、さらには設計時に適切な説明が考えられていない可能性があるということになります。

チェック内容をまとめた新たな章を追加

以上のような見直しや整理を、手元ではGoogleスプレッドシート上で行いました。 (そして今後の改善も) スプレッドシート上でまとめることで、作業もしやすいですし、実際にチェックを行う場合にもチェック・リストとして活用しやすいという利点があります。

いずれこのスプレッドシートを一般公開する方向でも考えてはいるのですが、まずはこの内容をガイドラインの1章としてまとめることにしました。 そうして追加されたのが、アクセシビリティー・チェック・リストです。 ぜひ一度見てみてください。

ちなみに、今後のメンテナンスを効率的にするために、このスプレッドシートの内容を取得してJSONに変換するGoogle Apps Script、そのJSONを処理してSphinxのソースとして使えるようにするPythonスクリプトを作りました。 これらのスクリプトで作ったファイルが、ソース・リポジトリーの source/checks/inc 以下にあるファイル群です。 (なおスクリプトはプログラミング・センスのなさにあふれたものなので公開しません……。)

引き続きご意見などお待ちしています

今回の変更についても、それ以外の部分についても、ご意見やお気付きの点など、GitHubリポジトリーのIssuesやPull Requestsでお知らせください。

既存サービスの1つをEKSに移行しました

こんにちは。関西支社の hatajoe です。

先月からSREチームへ異動しました。
関西支社としては1人目のSREで、今後関西でSRE組織を拡大するためにも良いロールモデルになれるよう頑張りたいと思います。困っちゃうな〜。

今回は、自分がしばらく携わっていた既存サービスのEKS移行についての思い出話を書きたいと思います。

最近の freee インフラ事情

移行話をする前に、最近の freee のインフラ事情をざっくりですが前置きます。

freee の展開するサービスは AWS を利用して提供しています。
各AWSリソースはほとんど全てが terraform によって構成されており、全て1つのレポジトリに集約する形で管理されています。
EKSについては別管理となっており、eksctl, kubectl, helm, helmfile などをラップした内製システムが存在します。こちらも社内の全EKSクラスタ設定が1つのレポジトリに集約されています。アプリケーションのデプロイなどもこちらのレポジトリを通じて行われます。
EKS環境のモニタリングや監視については Datadog を採用してお り、設定は terraform によって構成され、他と同様に1つのレポジトリで全て管理されています。

freee のEKS環境をとりまくインフラは、これら3つのレポジトリに対して(正確には terraform module として切り出されたレポジトリもある)プルリクエストを作ることで構成を変更する、Gitopsを意識した運用となっています。

freee の GitOps については SRE の renjikari が CNDK 2019 で紹介させて頂いた資料があるのでこちらをご覧頂ければと思います。

Kuberneteの運用を支えるGitOps

移行の背景

今回移行を行ったサービスは Railsアプリケーションを EC2インスタンスに直接デプロイする形の割とトラディショナルな構成の上で提供しているものでした。

移行の背景としては次のようなものが挙げられます:

  • k8s+コンテナ運用による社内CI/CD基盤の標準化が進められる
  • アプリケーションエンジニアに対してインフラ構成変更についての権限を移譲しやすくなる

いずれにしても、サービスに対する可用性・保守性性の向上、アプリケーション開発の速度を損なわないインフラ環境というものを目的とし、それらを実現していくための1つの施策としてのEKS移行という位置づけとなります。

k8s+コンテナ運用による社内CI/CD基盤の標準化が進められる

現在、freee には EKS環境でサービスを提供しているものとそうでないものが混在しており、これらを両方運用していく上で各種オペレーションが複雑化しているという課題があります。その結果、自分のように新しくチームに参加したメンバーがそれらをキャッチアップすることに時間が掛かってしまったり、インフラ構成に対する各種ツールセットのメンテナンスコストがかさむといったことが見えてきました。

社内のサービスがEKS環境へ移行が進むにつれて、k8s+コンテナに対するインターフェースを中心とした社内CI/CD基盤の標準化が進められてきました。
これらは k8s+コンテナインターフェースの特徴を活かし、サービスごとに微妙に異なるデリバリープロセスや、インフラ管理におけるツールセットの分散などを吸収できるような設計となっています。
今後はこちらの共通基盤に投資し、あわせて各サービスのEKS移行を進めることでインフラ管理に対する保守性の向上や、CI/CD基盤開発による全体最適が掛かりやすい状態を見込んでいます。

SREで現在開発を進めている社内CI/CD基盤の1つに、GitHub Actions を使用したコンテナイメージビルドパイプラインがあります。
こちらについては SRE の manabusakai, tmnakagawa が Kubernetes Meetup Tokyo #32 で紹介させて頂いた資料がありますのでこちらをご覧ください。

アプリケーションエンジニアに対してインフラ構成変更についての権限を移譲しやすくなる

EKS移行前のサービスでは、インフラ構成の変更や環境変数の設定などは権限の都合上SREが依頼ベースで作業する必要がありました。
様々なチームから依頼が発生するするため作業完了までのリードタイムが多く発生してしまうなど、アプリケーション開発のボトルネックとなりやすいワークフローの1つとなっています。
EKSへ移行を済ませることで、kubernetes の特徴を活かし、これまでSREで作業を行っていた環境変数の設定や、pod のリソースキャパシティ調整、HPAによるスケーリング調整などをクラスタの namespace ごとにアプリケーションエンジニアへ権限移譲しやすくなります。
kubernetes リソースは yaml ファイルとして宣言的に管理されており、構成変更もCIによって行われるため比較的安全にオペレーション出来るのと、例として挙げた類の変更については学習コストもほぼ発生せずオペレーションが可能になります。 権限移譲が行われることで、アプリチームとしてはオンデマンドな対応が可能となり、SREチームとしては他の作業に集中できるなどのメリットを見込んでいます。

移行の手順

ここからは実際に移行する際に気をつけたことや、実施したことを時系列で紹介します。 移行の流れは以下のようになります。

  • 検証用環境の作成と移行
  • ステージング環境の作成
  • ステージング環境での性能試験
  • ステージング環境での移行リハ
  • 本番環境移行

本番環境の移行は、Route53 record と Target group のリクエスト重み付けを利用して徐々に新環境へ移行する手段を選択しました。移行はメンテ中などサービスがダウンしてるタイミングで行うことも出来ましたが、通常時のリクエストを新環境で少しずつ受け何か問題が起きたら即切り戻せっるメリットがあることからダウンタイム無しで移行する戦略を取りました。

Route53からリクエストを旧環境と新環境に移していく
旧環境と新環境のイメージ図

検証用環境の作成と移行

まずは移行に際して必要な事項を洗い出すため、検証用の社内プライベートなクラスターを作成しサービスが起動するまでを目指しました。
freee では本番環境、本番環境と同じコードがデプロイされているステージング環境の他にインテグレーション環境と呼ばれるリリース前の機能に対するQAを実施する環境がいくつかあります。こちらの1つをEKS環境へ移行する作業です。
何をもって正常に移行できたと判断するかは難しいポイントです。移行対象のサービスは様々な社内サービスに対して依存しており、それらの疎通確認や、定期バッチ、非同期ワーカーの処遇を考えなければいけません。
これらの課題に対して、トライアンドエラーによるインクリメンタルなクラスタ作成作業と、QAチームと協力し正常な状態定義の作成を並行して行いました。

freee では期のクォーターの30%ほどを使って品質改善を行う取り組みを一部のチームで実施しており、今回の移行はその枠にて行われました。
その中で有志が集まった即席チームという体裁で、全員が EKS や kubernetes に精通したメンバーというわけではありませんでした。
また、社内に既存サービスのEKS移行の事例が無かったことから、どうしても作業は手探りとなりました。1つ問題を解決しては次の問題にあたるといった泥臭い作業が続きます。その過程でメンバーそれぞれにたまっていく知見や、同じ志をもって取り組んだムーブメント感など今思えば懐かしい。freee にはこういったチャレンジをスモールに始める事のできる文化やチャンスがあって、個人的には良いエンジニア文化の1つだと思っています。

このフェーズで大切だったのは正常な状態の定義で、これは本番移行時までずっと使われる重要なドキュメントだったように思います。

ステージング環境の作成

インテグレーション環境の次はステージング環境に挑みました。
本番環境と同じコードがデプロイされている環境、ステージング。とはいえ、そのインフラ構成も完全に同じというわけではありませんでした。
チームとしては、ステージング環境の移行は本番環境のリハーサルであると捉え、まずは想定される本番環境移行手順となるべく変わらないようステージング環境を本番環境の構成に合わせる作業を行いました。元々合っていて然るべきという意見もあるかもしれませんね。それはそうという感情もありつつ、長い歴史の中で今こうして freee というプロダクトを世に提供出来ていることに比べれば些細な問題で、今どうするか、これからどうしていくかということを真剣に考えることの出来た良いプロジェクトでありました。

それはさておき、このあたりで議論したのが pod や node に対する水平スケーリング戦略でした。
既存環境においては Auto Scaling Group(ASG)によるスケーリング戦略を取っていましたが、EKS環境においては Cluster Autoscaler(CA) と Horizontal Pod Autoscaler(HPA)を採用しました。HPA によってスケールした pod がリソース的に node に乗り切らなくなると CA によって node がスケールするという具合です。おそらく EKS環境においては一般的な戦略かと思われます。

HPA は pod の使用するリソース(CPU、メモリ)以外にもカスタムメトリクスによるスケーリングが可能です。
こちらを利用することでより理想的なスケーリングルールを定義出来るというチャレンジで、我々は Datadog のメトリクスを HPA のカスタムメトリクスとして利用する手法を採用しました。例えば、HTTPリクエスト数による web pod のスケールや、非同期ジョブのキュー数による worker pod のスケールが設定可能です。

これらの調査と検証を進めたフェーズで、具体的に本番環境移行に対する現実感も増してきた時期という気がします。

ステージング環境での性能試験

本番環境の移行を見据えて、これまで準備してきたスケーリング設定やモニタリングアラート、現在のピークタイム負荷に対するリソースキャパシティプランニングを見据えた性能試験を実施しました。
スケーリング設定やモニタリングアラートの試験は特に問題なく行うことができましたが、リソースキャパシティを測る部分においては十分に実施できなかったことを認めます。本番環境と同等のリクエスト数を試験的に流すことは可能でも、ありとあらゆるリクエストタイプを本番同等に実行可能なシナリオを定義することは非常に難しく、1つのAPIエンドポイントをベースにリクエスト数を変えながら検証を行いました。
本番環境の移行は旧環境から新環境へリクエストの重みを数%ずつ増やしながらダウンタイム無しで移行する戦略を想定していたので、最悪EKS側の負荷が問題になった場合においては即EKS側へのリクエストを0%に戻すことで対処できるという算段で進めました。試験は gatling というツールを使用して行いました。

リソースキャパシティについてはそこそこに、pod や node が想定通りにスケールアウトするか、ログは収集出来ているか、モニタリング・アラートは機能するかという点はしっかり検証を行いました。

ステージング環境での移行リハ

本番環境での移行手順を確立するため、ステージング環境にて移行リハーサルを複数回行いました。
本番環境とステージング環境のネットワーク構成を比較し、移行手順を1つずつステージング環境で実施しながら本番環境でも適用できるかを確認していくという地道な作業となりました。このタイミングで本番環境の移行手順、問題が発生した場合の切り戻し手順とエスカレーション先などを全て定義し、関連する他サービスのチームにも具体的なスケジュールを共有しながらついにここまで来たかという緊張感漂う瞬間でありました。

本番環境移行

コロナの影響で全員がリモートの中移行作業が開始されました。
旧環境から新環境へ数%ずつリクエストの重みを変更し、アラートに注意しながら少しずつ移行を進めました。
ここまで来るとやることはシンプルで、作成した移行手順書を元にチームメンバをオペレーターと状態監視に分けて移行を完了しました。

以降作業をやっていたリモート会議のスクリーンショット。満面の笑み。
移行後の様子

今後の話

ひとまず移行は完了しましたが、その過程全てが想定通りうまくいったわけではありませんでした。
現在も、CA や HPA 周りのスケール調整、監視アラートしきい値の調整、その他にもまだ課題は残っていますが、有志が集まったプロジェクトから始まりここまでやり遂げることができ、組織的にも個人的にも得られた知見は多くあったのかなと思っています。

今後は、kubernetes を中心とした社内 CI/CD 基盤開発をより加速しつつ、組織として kubernetes 運用の段階的なレベルアップ、そしてまだ残っているEKSベースでない既存サービスの移行など山盛りの課題に向かって日々取り組んで行きます。

こういったまだまだ freee の DevOps の理想形を追い求めることの出来る環境や、移行についてのより詳しい話など興味を持って頂いた方がいらっしゃれば、是非軽い気持ちでご連絡ください。私も色々なチームの事例を是非聞いてみたいので情報交換出来ると嬉しいです!

We are hiring!

freee では複数のポジションで一緒に働く仲間を募集しています。「興味あるよ」という方は是非こちらのページもご覧ください。

jobs.freee.co.jp