ちゃんと改善を回すためのDX Criteriaの活用

f:id:kotamat:20200429160545p:plain

DX Criteriaの第一弾がリリースされ、だいぶ時間が立ってから導入を検討することになったので、今更感は結構ありますが、ROXXなりの導入方法をもとに知見を共有することによって、今後導入される企業様並びにCTOの方々の何かしらの参考になればと思い、ブログを書くことにしました。

tl; dr

  • とりあえずやるよりは目的を持ってやったほうがいい
  • アセスメントは事業部ごとに行った
  • アセスメントめっちゃ多いので、2段階の絞り込みで対象範囲を絞った
  • 運用のためにシートをいじってみた
  • 一人でやるよりは、現場メンバーの声を反映したほうが解像度上がる

DX Criteriaとは

日本CTO協会が作成した、DXの基準となるものです。日本CTO協会はDXを2つの意味(Digital Transformation, Developer eXperience)で捉えており、DX Criteriaでは5つのテーマ、8つのカテゴリ、8つの項目で全320個のチェックにより数値化し、自己診断することができます。 詳しくは公式ページにて確認いただけます。 今回はこれをどのように現場で生かしていくのかを考え、改善サイクルに組み込んでいったROXX社の事例の紹介をさせていただきます。

DX Criteriaの導入背景と目的

今まではトップラインの向上を会社全体でも各事業部でも追ってきました。当然それは事業としての成長には不可欠ではありつつ、評価軸が事業成長に結びつくかどうかによりがちでもありました。 プロダクト開発においては、当然施策のリリース量も大事ではありつつ、それを追いすぎることによって将来の改善スピードの低下につながるような因子(いわゆる技術的負債など)がフォーカスに当たらなくなるというのが発生します。

「事業成長」と「事業部サイドからは見えないプロダクトに開発に必要な投資」のバランスを取るのは非常に大変であり、双方別々の責任者が立っていることが多い(求められるスキルが全く異なる)ため、優先順位をつけるためのコミュニケーションも非常に取りづらい状況になりがちです。

これを客観的評価軸に基づいて実施することによって、それが「ただのエゴ」ではなく「中長期を見据えた正しい意思決定」として認知されるようにする必要があり、それを行うために第三者機関が設定した評価軸を欲しておりました。

まさしくDXCriteriaはそれに該当するため、今回導入することにしたという背景があります。

当然導入するということは、何かしらの改善に活かすまでがゴールであります。すべての改善項目を同時に改善することは不可能であるため、改善効果の高いものからしっかりと改善に至るまでを評価軸ごとに目標設定し、実施していくことを導入時に決定しました。

Tips

正しく導入背景や目的を言語化し、「なんでこれやったんだっけ」みたいな状況にならないようにしたほうがいいと思います。

アセスメントやってみて

弊社には、2つのプロダクトがあり(agent bank, back check)、それぞれ技術スタックとしては同じなのですが、事業フェーズも組織構造も何もかもが違うため、それぞれでちゃんとアセスメントしないと薄まるなと初見で気づきました。

Tips

新規でやる方は、アセスメントの内容を確認の上、どの範囲でアセスメントをするのがいいのかを事前に確認したほうがいいかなと思います。

2段階の絞り込み

当然アセスメントはすべての項目に対してやったほうがいいわけですが、320項目もあり、一つ一つがかなり濃度の高い質問項目であるため、全部やるのは難しいケースもあると思います。

利用上の注意にもある通り、「すべての項目を満たせばいいというものではない」と認識しており、改善プロセスに回しアセスメントの内容を体感できて初めて活用の効果があるものかと思います。

ROXXではまず、開発組織全体として何が問題なのかというのを、5つのテーマから絞ることにしました。

事業と組織の状況を鑑み、改善されるイメージを最も持てた「システム」と「チーム」にフォーカスすることとしました。

次に、その項目に対してアセスメントをそれぞれの事業部の開発責任者主導でチェックをしていきました。

アセスメントをしていく中で、それぞれの評価項目に置いても重要視すべき項目と、現時点では重要視する必要がないものが浮き彫りになってきました。そのためシートを改修し、重要視すべき項目に対して、理想とされる評価を記入したものを別途用意しました。

f:id:kotamat:20200429155105p:plain

既存のアセスメントを「現実」、重要視すべき項目が記入されたものを「理想」とし、「現実」に記入されている項目のうち、「理想」に記入されているものと乖離があるものは黄色になるようにしました。

その結果が下記画像となります。 f:id:kotamat:20200429155121p:plain

f:id:kotamat:20200429155135p:plain

画像の通り、黄色になっているところをフォーカスし、改善していけば効果的に課題解決に向かうことがひと目で理解できるようになりました。

理想と現実を分割したシートはテンプレートとして下記URLで公開しております。もしお使いになる場合は、本家同様シートをコピーした上でお使いいただければと思います。

https://docs.google.com/spreadsheets/d/1NyEmOQ0wqnq_pNHtQlaDLbInGc6w6cCAViLF4sfwqx0/edit?usp=sharing

Tips

2段階の絞り込みにより、記入の負担を最小限にした上で今何を重要視すべきかの洗い出しをしやすくなりました。
DXCriteriaの導入目的を達成するために必要であればシートをカスタマイズするとよさそうです。

メンバーを巻き込んだ優先度付け

絞り込みを行いましたが、それでも対象項目は多いままです。このままでは何から改善を行えばいいかはわからないままです。

そこで、「改善項目」というシートに、対象項目を洗い出し、優先度付を行っていくことにしました。

まずは、当該評価を行った事業部ごとの開発責任者に「なぜその評価を行ったかの理由」と「本人が思う優先順位」をつけてもらうようにしました。

ただ、それだけではDXの当事者である「各開発者」の視点が抜けてしまいます。そのため、各メンバーと1on1を行い、上記評価理由をどう思うかと、その本人が思う優先順位を聞き、メンバーと開発責任者間にどのような現状認識の乖離があるかを把握することとしました。

その結果をもとに、総合的にチームのボトルネックを改善するためにどの項目を優先すべきかを並び替え、優先度の高いものに対してはどのような改善施策をいつまでに行っていくのかを決定しました。

f:id:kotamat:20200429155156p:plain f:id:kotamat:20200429155212p:plain

Tips

評価者一人で優先順位をつけると、現場との認識の乖離によって納得度の低い改善項目となりうるため、メンバーを巻き込んで優先度をつけました。

まとめ

まだこちらの改善プロセスは回し始めたばかりなので、これがどれだけ効果を発揮するのかは今後の改善次第ではありますが、改善プロセスを回し始めてすぐメンバーからは改善が体感できたという声が上がってきたので、改善項目の選定プロセスは一定の効果をもたらしたと感じられております。

「SSRと規約だけ」の勘違いを解く、 Nuxt.js をプロジェクトで採用すべき理由

back check 事業部に業務委託でコミットしているフロントエンドエンジニアの potato4d です。

ROXX では、 v1.0 が出る前から、プロダクト、コーポレートサイト、ランディングページ、メディアなど、多くのシーンにて、 Nuxt.js が採用されています。

Nuxt.js は多くの人に愛される一方で、最近は Vue 3.0 の話もあり、多少評価が落ち着いてきた印象があります。

この記事では、十分に普及した今だからこそ、 Nuxt.js の本当の優位性と、どういったときに使うべきか。あるいは使うべきでないかを再度言語化できればと思います。

SSRとルールだけ」という勘違い

まずは Nuxt.js の採用についてです。多くの場合、「Vue か Nuxt か」という問いには、いかが判断基準として使われます。

  • SSR 今必要かどうか
  • Nuxt.js の組み込みのルールをチームに適用したいかどうか

これは確かに Nuxt.js を採用する一つの理由ではありますが、実際にはこれだけではありません。

Nuxt.js は、 Vue.js の延長ではなく、 Vue.js の機能をよりよいアプローチで提供しているフレームワークとして、機能面でいくつかの大きな価値があります。

これから順を追って紹介していきますが、それらの判断軸について考えた上で、全てが不要な場合に限り Nuxt.js を利用しない選択肢が出てくるのではないかと思います。

Vue.js プロジェクトにおける Nuxt.js 選定の基準

SSR が今必要なのかどうか、Nuxt.js のいわゆる「規約」について採用したいかどうかは既に知られていると思うので、それ以外について言及します。

プロジェクトが将来的に SSR エンジンを利用する可能性があるか

まずは言及される「SSRするかどうか」。です。

SSRをするときにのみ Nuxt.js をすべき」という言説について、一部は正しいですが、一部は誤りがあります。

例えば「個人個人のデータを扱うアプリみたいな Web サービスだから必要ない」といった場合などです。ここで伝えたいのは、 SSR の是非を考えるさい、多くの場合は「開発開始時点の要件」で考えられがちということです。

しかし、実際は後から必要になることも多くあります。

例えば

  • 「サービスのトップにおいて、初回の応答速度を可能な限り高めたい」
  • 「求人の URL を貼ると API のデータを基に OGP とページタイトルがプレビューされてほしい」
  • 「個人のワークスペースを持つメモアプリだけど URL での限定共有がほしい」

などが上げられます。こういったシチュエーションにおいて、開発開始時点での要件だけをみると、 SSR は不要には見えるのではないでしょうか。しかし、実際にはこういったケースは頻発します。

このようなシチュエーションにおいて、あとから SSR をするのは非常にコストの高い作業となります。

簡単なものでいうと、暗黙的に window オブジェクトに依存したコードがある。ライフサイクルフックの選定をサボって全てが mounted になっている。というのは既存プロジェクトの SSR 対応を担当したことがあるかたは経験したことがあるはずです。

現代では、SSRを要求されるシチュエーションは非常に多くなっているため、Universal なコードであることを前提とした上で、本番環境を SSR するかどうかという判断軸を持つことが重要です。

一方で、「そのユーザーのログインコンテキストに依存して外部に絶対に何もでないアプリケーション」みたいなものがあれば、それは SPA 前提で問題ありません。

例えば社内向けの管理画面は、ログイン画面などのごく一部を除き、ログインが不要なエンドポイントは現実的に存在し得ないため、SSR は不要といえます。

なお、nuxt generate についても、こちらは内部的に SSR を行っておりますので、「最終的には静的サイトなので SPA モードで問題ない」というわけではないことをご留意ください。

Node.js サーバーの運用が可能かどうか

また余談として、Node.js サーバーが立ち上がるということもしっかりと認識しておくべきです。

これは SSR する場合に付随してくるほか、Nuxt.js の serverMiddleware や Node.js からの Nuxt.js 利用が発生する場合に考慮すべき事項です。

SSR というとサーバーが必要でランニングコストがかかるという部分はフロントエンドエンジニアの多くの共通認識になっています。しかし、運用という観点は忘れられがちではないでしょうか?

Nuxt.js を利用していると、SSR は勿論、その他でも Node.js 上で動かすことがそれなりに発生します。ただコンピューティングリソースを利用するというだけでなく、例えば以下のような問題にも対処が必要であるという認識を持った上で、自分たちが Node.js サーバーを運用できるかを考える必要があります。

  • Node.js ランタイムの追従 (常に LTS に追従できるか?1,2年サイクルでメジャーバージョンをあげられるか)
  • セキュリティ問題への対処 (脆弱性のあるパッケージがより無視できない問題となる)
  • メモリリーク・サーバースケーリングへの対処

これらを意識するのが難しい場合、Nuxt.js を採用する場合であっても SSR については忘れることを推奨します。

Context / Inject によってコードをクリーンに保ちたいか

あまり話に挙がりづらいですが、 Nuxt.js が独自のプラグイン構造を持っていること、そしてそれが強力であることも認識する必要があります。

Nuxt.js には、 Plugin という概念が存在します。これは、これまで Vue.js プロジェクトにおいて、自分たちで作っていた Vue.use を吸収するレイヤーによく似ています。例えば Bootstrap Vue や Element UI を import して Vue.use していたような層がここにあたります。

しかし、 Nuxt.js の Plugin の価値はそれだけにとどまりません。Nuxt.js の Plugin は、 Vue.js の Provider / Inject をうまく隠蔽し、 Context として活用できるという大きな優位性があります。

聞き慣れないワードも多いかもしれませんが、身近な例としては、 Axios Module が this.$axiosapp.$axios で呼び出せるあの機能です。

Axios Module の抽象化粒度が良いかどうかは諸説ありますが、「コンポーネントやストアから特定の外部依存を切り出せる」ということには、大きな価値があります。

具体的には、コンポーネントのテストを書く場合のシチュエーションなどにおいて、以下のように記述できるという利点があります。

import TheUserEditForm from '~/src/components/TheUserEditForm.vu'
import { shallowMount } from 'vue-test-utils'

const $axios = {
  async get() {
    return {
      data: {
        foo: 'bar'
      }
    }
  }
}

describe('~/src/components/TheUserEditForm.vue', () => {

  test('Submit form', () => {
    const wrapper = shallowMount(TheUserEditForm, {
      mocks: {
        $axios
      }
    })
    // Code
  })
})

多くの場合こういった記述が全く不要というわけではないので、Nuxt.js を利用したほうがシンプルに取り回せます。

反対に、こういった優位性が不要なシンプルな Web サイトの場合、同様に静的サイト出力が可能な Gridsome などが選択肢に上がってくる可能性もあります。

ここも判断軸として加えると良いでしょう。

選定にあたってあまり重要ではないこと

Routes の自動生成と layout

Nuxt.js の大きな特徴として、ファイルシステムと密接に紐付いた Routes が挙げられます。

これは、非常に便利な機能ではありますが、 Nuxt.js のみが唯一もつというわけではありません。Nuxt.js スタイルの Routes について、 Vue CLI v3.x or higher が利用可能なvue-auto-routing というパッケージにて代替が可能となっています。

これは日本人の Vue.js コアチームメンバーの ktsn によって開発されており、今もアップデートが続いています。

この機能自体は便利ですが、意思決定に関わるようなものではありません。

Vuex 連携

これも非常に便利な機能ですが、 Single Source of Truth への評価が落ち着いてきた現代においては、大きなポイントとはならないのではないでしょうか。

実際に ROXX では、新規でのコードにおいては Vuex を利用しないケースも多くなっていきています。

このあたりは現場にあわせて効果が変わる部分であるため、あまり大きな要因とは言えません。

おわりに

Vue 3.0 が既にインストール可能となり、 TypeScript との親和性や Composition API による新記法などに期待と注目が集まっています。

その大きな変化をうけて、 Nuxt.js がどうなっていくか、単純な Vue.js プロジェクトで十分となるかは非常に気になるトピックではあります。

しかし、Nuxt.js には、目先の生産性やSSRだけではなく、高品質なプロジェクトの基盤を持っていること、そして、より高品質な基盤を自分たちで作り上げていくための土壌が存在しているという大きな価値があります。

この記事が現場における Nuxt.js の妥当性について再度考えるきっかけとなれば幸いです。

agent bankの開発で使われているKubernetes, EKS

agent bank開発部の森です。

新機能の開発や不具合修正中、他の人にちょっとみてもらいたい時に プレビュー環境 とよばれる環境を構築してURLを共有してみてもらうことが多々あります。

最近 agent bank のプレビュー環境を Amazon EKS に置き換えましたのでどのように構築したのか、構築してみての感想を記します。

back check でもプレビュー環境を構築しています。あえて異なるアプローチをとったのでback checkでのプレビュー環境の構築についてはこちらの記事もご参照ください。 techblog.roxx.co.jp

概要

概要を列記すると以下のとおりです。

構成

  • KubernetesAPIコンテナ、フロントエンドコンテナを起動、管理している
  • Kubernetesの環境構築には Skaffold , Helm を利用している
    • ローカル環境のAPIコンテナ、データベースコンテナもKubernetesで構築している
      • ローカル環境ではAPIのみコンテナ起動、フロントエンドは yarn dev で起動
    • プレビュー環境はEKS (Amazon Elastic Kubernetes Service) 上で利用している

プレビュー環境へのデプロイ

  • GitHub ActionsでPull Request作成時や任意のタイミングで開発者がアクセスする環境にデプロイしてコンテナを作成する
    • Pull Request をクローズしたら自動で環境は削除される

インフラ構成図

インフラ構成図です。大きいサイズの画像はこちら

f:id:jiska_roxx:20200319192954p:plain
インフラ構成図

クラスター内部詳細はこちらです。大きいサイズの画像はこちら

f:id:jiska_roxx:20200319192943p:plain:w800
クラスタ

クラスター内部でnginx controllerが起動しており、其々ネームスペースごとに起動するコンテナへ紐づいています。 また、メールの表示確認などに使用している MailHog やシステムの統計のために Grafana が起動しています。

クラスター内部のログはCloudwatch Logsへ出力するようにしています。

MySQLやElasticacheなどはクラスターには含めていません。

Before Kubernetes

今回構築したKubernetesで動作している環境の前はどうだったのか、その課題はなんだったのか、それぞれ記載しておきます。

旧開発環境はEC2インスタンスで起動しており、nginxで複数サブドメインを定義して動かすようにしていました。 環境を追加したい場合は EC2インスタンスsshしてサブディレクトリ作成して.envファイルを手動で編集する という面倒なもので、社内esaに手順はまとめてあるものの準備に時間がかかっていました。

デプロイはSlackの専用チャンネルでhubot経由でデプロイしていましたが、 朝になるとhubotプロセスが死んでる ので毎朝再起動かけていました。

解決したかった課題

この状況から解決したかったことは以下のとおりです。

  • 環境を簡単に増やせること
    • PRごととか、欲をいえばコミット単位で環境作りたい
  • かんたんにデプロイできること
    • Slackの専用チャンネルでhubot経由でデプロイできるのは便利なのでこの体験は失いたくない
  • メンテナンスコスト下げたい
    • 俗人化のもと
  • デプロイは高速化したい
    • デプロイに数分かかっていた

Why Kubernetes

この状況でなぜKubernetesを選択したかですが、正直なところback checkと同じくECSで環境構築した方が楽でしたが、今後EKSやKubernetesまわりの運用を開発チームが正しく行えるのか評価、またback checkとあえて別のアプローチを検証した方が社内知見も増えるだろうという目的でした。

次にkubernetesクラスターの構築手順を記します。

Slaffold, Helmを利用した環境構築

kubernetesクラスターの構築には Skaffold , Helm を組み合わせて利用しています。

skaffold.dev

helm.sh

それぞれ公式ホームページから引用すると、SkaffoldはKubernetesのアプリケーション構築、プッシュ、デプロイのワークフローを処理し、CI / CDパイプラインを作成するためのビルディングブロックを提供するツール、HelmはKubernetes用のパッケージマネージャーです。

Skaffold & Helm導入して良かったこと、大変だったこと

Skaffold用とHelm用にYamlを記述し、skaffold run を実行するとDockerイメージのビルド、ECRへのプッシュ、EKSへpodsを作成…といった一連の作業をコマンド1つで行えるようになりました。

また、ローカル環境も skaffold dev で起動させ、APIコンテナを動作させつつソースコードの編集時に自動反映させるような仕組みを実現できています。

Helmについてはパッケージ管理に用いるChartsが拡張性が高く、agent bank用のAPIコンテナ、フロントエンドコンテナの作成もHelm Chartsで定義しています。 またMySQLコンテナなどよく使いそうなものが公開されており便利でした。

大変だったこととしてHelm Chartsに go templates を多用することになり、{{ include "xxxx" . | indent 4 }} などindent合ってたっけ?みたいな数えることが多々あり以下のようなぱっと見読むのが大変なYamlが出来上がりました…。

# 抜粋
metadata:
  name: {{ template "agent-bank-base.api.fullname" . }}
  labels:
    app: agent-bank-api
{{ include "agent-bank-base.labels" . | indent 4 }}
spec:
  selector:
    matchLabels:
      app: agent-bank-api
      release: {{ .Release.Name }}
  template:
    metadata:
      labels:
        app: agent-bank-api
{{ include "agent-bank-base.labels" . | indent 8 }}
    spec:
      terminationGracePeriodSeconds: {{ .Values.api.terminationGracePeriodSeconds }}
      containers:
        - name: api
          image: {{ .Values.api.imageName }}
          imagePullPolicy: {{ .Values.api.imagePullPolicy }}
          args:
            - php-fpm
          command:
            - sh
            - -c
          env:
{{- range $key, $value := .Values.api.env }}
            - name: "{{ $key }}"
              value: "{{ $value }}"
{{- end }}

プレビュー環境へのデプロイ

プレビュー環境へのデプロイはGitHub Actionsで行っています。上述の skaffold run が起動するようにしています。

  1. Pull Request作成
  2. コメントに /preview 入力
  3. でCIフローが動き出す
  4. skaffold runが起動してコンテナのビルド、デプロイ開始
  5. デプロイ完了、Pull Requestに起動したコンテナのURLがコメントされる

解決したかった課題は解決したのか

課題と結果を振り返ります。

課題 結果 振り返り
環境を簡単に増やせること よい
かんたんにデプロイできること とてもよい
メンテナンスコスト下げたい Hubotの運用をやめられたけどEKSの運用は大変だったのでトータルではあまりコスト下がってない
デプロイは高速化したい × デプロイから環境立ち上げまでの時間は数分かかっている

今後改善していきたいこと

  • コンテナの自動起動数に制限がある
    • インスタンスのスペック次第だが同時に割り当てられるIP数に制限がある
  • コンテナの起動に数分かかる
    • イメージのビルドに時間がかかっているので高速化が必要
  • 各コンテナで共通のデータベースを参照している
    • agent bankのseederが貧弱なのでいい感じのデータが作成できていないため
      • seederをいい感じにしていく

EKS使ってみての感想

たとえば EKSのコンソールではコンテナ内部の情報を確認することができず、クラスター内部にどんなpodsが起動しているのかとかが確認できません。 確認するためにはたとえばOctantなど別ツールを使う必要があり、せっかくAWS使っているのにAWSだけで全て完結するでもないのがつらいです。

github.com

また、クラスターはデプロイごとに破棄、再作成したいけどロードバランサーは再利用したい…みたいな運用が難しいです。

なぜつらいのか調べていたところ、Amazon EKS Advent Calendar 2019 最終日のtoriさんの記事みてふに落ちました。

toris.io

長いですが引用します。

Kubernetes というプラットフォームの哲学に沿ってシステムを構築すれば、素晴らしく一貫性のある自動化とその体験が手に入ります. しかし、Kubernetes というプラットフォーム自体の運用容易性を高める目的で Kubernetes クラスタ自体を短命なものにしようとすると、そのクラスタから作成された長寿命なクラスタ外リソース(ALB や RDS)のライフサイクルとの整合性が取れず、奇妙な運用をやることになってしまう.

そのような悩ましい現実を直視した結果、ALB や RDS は AWSAPI で、コンテナで動かすものは KubernetesAPI で、というような、一貫性に欠ける構築・運用方法を選ぶことが往々にしてあります. あるいは Kubernetes クラスタを短命かつ継続的に再作成することは諦め、長寿命なクラスタとしての運用を選択することで、AWS リソース作成と管理まで含めて Kubernetes の一貫性ある体験の中で完結させることにプライオリティを置く方もいます. しかしその選択の結果、数多くのアプリケーションが同居しながら動く大規模クラスタに育ってしまい、ちょっとしたクラスタ障害がそこで動く多くのアプリケーションに影響を与えるようなことになってしまうのは想像に難くありません.

このような状況と前提条件の中で、どういう決断をするのか. 何が自分たちと自分たちのシステムにとってベストなのかをどうやって判断するのか. これが EKS(Kubernetes) が ECS と比較して『難しい』と言われる正体、その理由の1つだと僕は理解しています.

AWSの恩恵を受けつつもKubernetesの運用を楽したい、という欲張りすると難しいなあという感想でした。

まとめ

  • Kubernetesは便利だった
  • Skaffold, Helmの組み合わせはかなり便利だった
  • 引き続き開発環境よくするのやっていきたい
  • EKSの運用には勘所つかむのが大変

ともあれ今後もagent bankの開発がんばっていくための足場固めができつつあるので新機能の開発や既存機能のブラッシュアップもより加速することができると思います。

back checkのプレビュー環境

これは3/18に開催された、ROXX社内LT大会の資料です。

概要

今回は下記の内容を紹介します

  • back checkのリポジトリの状況
  • プレビュー環境に求められる要件
  • 参考にしたOSS
  • 実際の昨日のアウトプット
  • 具体的な実装

back checkのリポジトリの状況

backcheckには下記の4つのリポジトリが存在しています

  • LP
    • LPのフロントエンドが実装されている
    • Nuxt.js製
  • admin
    • 管理画面のフロントエンドが実装されている
    • Nuxt.js製
  • front
    • ユーザが使う画面が実装されている
    • Nuxt.js製
  • API
    • back checkが使うすべてのAPIが実装されてる
    • Laravel製

プレビュー環境に求められる要件

上記の様に、それぞれが別のリポジトリで実装されているため、下記のケースを想定したレビュー環境が必要となりました

  • LP, admin, front, APIそれぞれどれかだけの変更だけが反映されているもの
  • 複数のリポジトリにまたがった修正が反映されているもの

また、それ以外にプレビュー環境として、下記の要件を満たす必要がありました

  • プレビュー環境同士は完全に独立していること
    • 新規機能も多いためDBスキーマの変更にも耐えられるよう、DBも独立していること
  • githubのChatOpsでできること
  • Auth0と連携ができること
    • 環境作成時に、callbackURLなどが自動的に反映されること
    • https化されていること
  • PRがクローズされたら、自動で環境が削除されること
  • k8sとかの知識は不要で、AWS上で動くこと
  • リソースの上限とかはあんまり気にしたくない

参考にしたOSS

色々と探していたら、下記のOSS(というかプレゼン用に作ったと思われるなにか)が見つかった

https://github.com/clareliguori/clare-bot

clare-botというボットに対して、 preview this とメンションするだけで、プレビュー環境を作ってくれるというもの。使用している技術スタックも

Built with GitHub APIs, AWS Fargate, AWS CodeBuild, Amazon ECR, and AWS CloudFormation

とのことで、実装も簡単そうだったのでこれを使うことにした。

一方これだけでは最初の要件(マルチリポでよしなに使える)が適応できないため、ソースコードをいじる必要があった

実際の機能の使い方

  1. GitHub上でプルリクエストを作成します。
  2. プルリクエスト上で「@roxx-bot preview this」とコメントします。
  3. roxx-botさんがちょこちょことコメントを残していきます。(最長で30秒ほどかかります)
  4. しばらく経つとそのプルリクエスト(=base branch)のコードが反映された環境が立ち上がり、URLが表示されます。
  5. backcheckの環境は1リポジトリでは完結しないので、もう一方の環境を立ち上げます。

    つまり、apiのプルリクエストであればfrontを、frontのプルリクエストであればapiのプレビュー環境を立ち上げます。

    1. @roxx-bot preview front」または「@roxx-bot preview front」とコメントします。
  6. しばらく経つとそのプルリクエスト(=base branch)のコードが反映された環境が立ち上がり、URLが表示されます。

  7. URLのリンクを踏むとプレビュー環境を見ることができます。

preview XXX のあとに、githubのPRのURLを貼り付けることによって、そのPRで立ち上がっているURLを、環境変数に適応できるため、複数PRにまたがる施策でも問題なくアプリケーションが動くようになります。

具体的な実装

立ち上げ時

bot

  1. 10秒ごとに自分宛てのメンションが来ているかの監視
  2. メンションが来ていたら、コメントの中身を解析し、環境立ち上げの関数を実行
    1. preview xxx のxxxの部分から、どのリポジトリの環境を立ち上げるか判断
    2. xxx以降に指定されたPRのURLをよしなに解析し、そのリポジトリで必要となる環境変数を書き換え
  3. 環境用のユニークIDを発行(これが環境立ち上げ時のURLのサブドメインにもなる)
  4. Auth0にcallback URLなどを追加
  5. 対象リポジトリにあるbuildspec.ymlをもとにCodeBuildを開始
  6. CodeBuildからCloudFormation用のymlが出力されるので、それをもとに対象環境を立ち上げ
  7. 立ち上げ後、成功したらGitHubのコメントにURL付きで通知

リポジトリ

  1. bot側から渡ってくる各種環境変数を変換し、必要に応じてdocker buildするときに使う
  2. gitのコミットハッシュをdocker tagとしコミット→ECRにpush
  3. 生成したイメージのタグ等を用い、CDKを実行(以下CDKの実装内容)
  4. 環境変数の中で、ECSの実行時に使うものだけを抽出し、環境変数
  5. APIの場合はapimysqlを立ち上げ、フロント系の場合はnuxt generateしたものをnginxで静的ファイルとして参照する

cleanup時(bot側のみ)

  1. Githubのステータスがcloseになったことを検知
  2. Auth0のcallback URLなどを削除
  3. CloudFormationのスタックを削除
  4. 削除が完了し次第GitHubのコメントに通知

課題は解決したのか

課題 結果 コメント
他の環境に依存しない環境を立ち上げられたか AWSのフルマネージドな環境なので、無意識に無限に増やせる
Auth0との連携はできたか botをTypeScriptで書いてるので柔軟性が高くそれほど困らずに作れた
複数リポジトリのPRにまたがる環境を作れたか 一応作れたが、こういうのを作るためにモノレポ化はしたほうがいいなと改めて認識
デプロイの速度 docker cacheとか色々挟んだが、どうしても時間はかかってしまう。何故かECSのタスクをアップデートするときに、過去のタスクが削除されるまでの時間が長く、トータルの時間が長くなってしまっている
DBの独立性 backcheckはシーダーがいい感じに整っているので、特に問題なく環境構築はできた

今後の課題

  • ECSのタスクアップデート処理を見直して高速化
  • SSMを用いてAPIのコンテナ内に入れるようにする
    • プレビュー環境上でDBをいじりたかったりするので
  • 不要なコンテナは非稼働時には停止しておきたい
    • せっかくfargate使ってるのに、常に立ち上がっててコストがかかってる
  • botのコードのリファクタリング
    • 継ぎ足しになってるので不要なところとかは削除したい
    • 適度にモジュール化したい。現状は手続き型の典型的な処理の流れみたいになってる

PHPerKaigi 2020 に参加して、LTしてきました

こんにちは、今年の2月から、backcheck開発チームにジョインしました 秋葉です。
2020/02/09〜2020/02/11 に3日間に渡り開催された、PHPerkaigi 2020 に参加してきました。
今回自分は、スタッフとして色々やりつつ、ルーキーズLTの登壇者としてLTもしてきました。

phperkaigi.jp

これは参加者に全員配られたPHPerトレカ
f:id:akki_megane:20200215192447j:plain

ルーキーズLTしたよ

2/10 Day1 に
「明日からフロントもよろしく!」と言われたときに備える Atomic Design でのフロントエンド設計
というタイトルでルーキーズLTに登壇してきました
(プロポーザルを出すときに、Atom Design で出しているの前日に気づいてとても焦りました、Atomic Design が正しいです)
資料はこれ
speakerdeck.com

2019年に学んだことの一つとして、Atomic Design を使ったフロントエンドの設計があり、そのアウトプットという意味で登壇しました。 5分のLTということもあり、Atomic Design については触りの部分しか話せませんでしたが、興味を持ってくれる方がいればありがたいです。

反省

登壇時に緊張して、画面ばかりを見てしまいました。。。
理由としては登壇直前に、自己紹介のページを PHPerトレカに差し替え、
自己紹介を「ぼくの効果は 対戦相手のカードを1枚捨てることです! なのでみなさん手札を捨ててください」という自己紹介が ややうけ という結果に終わり(自分は大爆笑になると思っていました (泣))
登壇前は緊張していなかったのに、100人規模をややうけを見て緊張が一気に上がり、それ以降まともにお客さんの顔が見れませんでした。。。
終わった後に何人かに「いつもより緊張してたね」的なことを言われてしまい、若干凹みました。
緊張したとはいえ、カンファレンスでの登壇はいい経験になりました。
聞いてくださった皆様ありがとうございました。

アンカンファレンスでもLTしたよ

友人がトラックCで、ゲリラ的にLTしていたので自分も飛びこんで、LTを2回してきました。

  • 入門無限LT
  • AWS re:Invent 2019 俺的 注目技術

最初にやった、「入門無限LT」で、「会場にいるみんなにぜひこの場でLTやってほしいと」
けしかけたら、何人かの人が実際にLTに参加してくれてとても嬉しかです。

スタッフとして

スタッフのことについては、同僚の前田さんがいい感じにまとめてくれいますのでそちらもどうぞ。
https://techblog.roxx.co.jp/entry/2020/02/13/113611

事前準備

去年のPHPerkaigi2019年に引き続きスタッフとして参加しました!
今年はコアスタッフとして事前準備から参加していましたが、事前にやることや各種フローが整備されていて、
初めてのコアスタッフでしたがスムーズに割当られた仕事をすることができ、さすがカンファレンスジャンキーの集まりだと感動しました。

当日

自分は当日ルームBの担当をしながら、トークを聞いたり、参加者の方と交流したり、例年通りとても楽しく過ごせました。
大きな問題もなく無事に3日間やりきって、疲れましたがとても楽しかったです。
来年もスタッフやりたいなーと自然と思えました。

まとめ

カンファレンスで初登壇さらに初めてのコアスタッフで、資料作りや、事前準備等、個人的に慣れない作業で少し大変でしたが、
当日は最高に楽しく、登壇も楽しかったし、スタッフ業も楽しかったです。 
去年に引き続き、今年のPHPerkaigiは最高のカンファレンスでした!

ルーキーズLT × 1
アンカンファレンスLT × 2
懇親会LT × 1
計 4 回LTをしたので今回のPHPerkaigi一番LTをしたのは僕です!

GitHub CLIとhubを使い比べての感想

agent bank開発部の森です。 最近GitHubのPull Requestをローカルでcheckoutする案内に GitHub CLI Beta という項目が追加されましたね。

f:id:jiska_roxx:20200214124120p:plain
GitHub CLIの項目が追加されている

初めてみたときは hub がリネームでもしたのかな?と思っていたんですが実際はhubとは別のツールでした。 GitHub CLIとhubとを使い比べてみての感想をまとめます。

hubとの違い

GitHubCLIツールといえば hub が数年ほど前からあります。なぜhubがあるのになぜ別のツールを作ったのか? https://github.com/cli/cli#comparison-with-hub に違いが記載されているので引用します。

For many years, hub was the unofficial GitHub CLI tool. gh is a new project for us to explore what an official GitHub CLI tool can look like with a fundamentally different design. While both tools bring GitHub to the terminal, hub behaves as a proxy to git and gh is a standalone tool.

...そもそもhubがunofficialだったなんて知らなかった…公式プロジェクトとするべくhubとは異なる設計でつくられたそうです。とりあえず試しに使ってみましょう。

GitHub CLI

https://github.com/cli/cli#installation-and-upgrading に記載されている手順に沿ってインストールしてください。インストールすると gh コマンドが実行できるようになります。

❯ gh --help
Work seamlessly with GitHub from the command line.

GitHub CLI is in early stages of development, and we'd love to hear your
feedback at <https://forms.gle/umxd3h31c7aMQFKG7>

Usage:
  gh [command]

Available Commands:
  help        Help about any command
  issue       Create and view issues
  pr          Create, view, and checkout pull requests

Flags:
      --help              Show help for command
  -R, --repo OWNER/REPO   Select another repository using the OWNER/REPO format
      --version           Show gh version

Use "gh [command] --help" for more information about a command.

GitHub CLIでできること

今のところできることはissueとprの閲覧、作成です。 hubよりもできることはだいぶ少ないですが、issueやprをCUIで作る時に案内が丁寧だったりブラウザでプレビューできたりするのがhubよりもいいところです。 issue, prのリストはあまりhubと見た目変わらないですね。

f:id:jiska_roxx:20200214124531p:plain
gh issue list
f:id:jiska_roxx:20200214124525p:plain
gh pr list

気に入ったのはissueを作成する時にブラウザでプレビュー画面を表示してくれるところです。まちがって誤字入りissueやpr作ってしまうのが恥ずかしいので一度チェックできるのは嬉しい(チェックが漏れないとは言っていない)。

❯ gh issue create
Creating issue in jiska/example
? Title example
? Body <Received>
? What's next? Preview in browser
Opening github.com/jiska/example/issues/new/ in your browser.

公式ブログのアナウンス https://github.blog/2020-02-12-supercharge-your-command-line-experience-github-cli-is-now-in-beta/ に詳しい例が記載されていますのでそちらも参照ください。

今後期待したいこと

いまのところBetaだからなのか、僕がhubで重宝している機能、たとえば hub browse , hub ci-status , hub compare に相当する機能がGitHub CLIにはありません、今後の拡張を期待したいしcontributeがんばって追加してみようかな…

PHPerKaigi2020に参加して得た知見

こんにちは。bacckcheck事業部の前田です。
この記事は個人ブログの転載です。

phperkaigi.jp

PHPerKaigi2020に参加してきました。 一般参加ではなくスタッフとして参加したのでトークはきいてなく*1、スタッフとしての「PHPerKaigiの裏側!!」みたいなのも書かないので、あまりブログに書く内容がないのです・・・

そんな中で得た知見を少しでも紹介します。

朝のコンポタが最高

朝にモスバーガーで飲むコーンポタージュスープが最高です。 コンポタのためにスタッフ業をしているといっても過言ではないかもしれません。(過言です)
最高なので毎日行きました。

1日目

2日目

3日目

PHPerも踊れる

前夜祭にPHPrePartyというのがあり、なんとびっくり、DJイベントをやったのです。 普段のエンジニアの様子からはまったく想像つかないのですが、みんな踊れるんです・・・!!

ほしさきさんが動画をTwitterにあげていて、とても場の雰囲気が伝わってきます。

みんな場があればこんなにはしゃげるんだなーと再認識しました!

みんなコミュニケーションをとりたい

PHPerKaigiに参加して毎年思うことですが、みんなやっぱりコミュニケーションを取りたいんだな!!ということです。

当然に僕もコミュ障なわけですが、コミュニケーション下手ながらも、誰かと話したり、自分の知らない考え方をきいたりするのはとても楽しいのです。

そういうタイプは僕だけなのかな?と思ってたのですが、どうやらみんな同じ気持ちのようだとわかりました。

PHPerKaigiにはコミュニケーションスペースというものがあって、色々な人と話せる仕組みがあったりします。

f:id:chiroruxx:20200212213553j:plain

ここが本当にずっと賑やかで(トークやってるときもずっと!)、みんな楽しそうでした。

また、IRTもやっていて、ここもずっと満員でにぎわっていました。

f:id:chiroruxx:20200212213846j:plain

これは言ったら怒られるのかもしれないのですが、トークは後からでも情報を追えるんですよね。スピーカーのみなさんは優しいのでスライドをWebにあげてくれるし、最近のカンファレンスは後で動画を上げてくれるところも多いですよね。

でもこうやって誰かと話したり意見交換したりすることは、実はイベントに来ないとできないことなんです。

なのでみんな、色んな人といっぱい話すためにカンファレンスに行こう!PHPerKaigiに行けばいっぱい話せるよ!もちろんコミュ障でも!

と言っていきたいと思いました。

余談

今回はトレカが受付時に配られていて、PHPrePartyから本格的に交換していきました。
80人くらいの人と交換できて、わりと満足です。

ちなみに僕のカードはこれ。 f:id:chiroruxx:20200212215034j:plain

対戦相手はカードを1枚捨てる

うーん、自分の性格がでてるなぁ。

*1:私はリーダーだったのできかなかったのですが、他のスタッフは普通にトークをききにいけます