「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:私はリーダーだったのできかなかったのですが、他のスタッフは普通にトークをききにいけます

CDKとterraformの使い分け

こんにちは、 kotamat です。

少し前から、CDKを用いた環境整備を行いました。今までterraformで構築してきたので、それとの差分をメモ代わりに書こうと思います。

TL; DR

使い分けとしては下記のようになるかなと思っています

  • CDK
    • ベストプラクティスを簡単に構築したい場合。
    • ビルドプロセスなど、動的にインフラ構成を構築したい場合
  • terraform
    • サービスの基盤となるインフラを構築したい場合
    • 同等の環境を、異なるVPCなどで構築したい場合

CDK

とは

AWS クラウド開発キット (AWS CDK) は、使い慣れたプログラミング言語を使用してクラウドアプリケーションリソースをモデル化およびプロビジョニングするためのオープンソースのソフトウェア開発フレームワークです。

https://aws.amazon.com/jp/cdk/

簡単に言うと、TypeScript、PythonJava、および .NET でCluodFormation(AWS専用のIaCサービス)用のパターンファイルを生成してくれるものとなります。 いつも使い慣れた言語を使うことができるため、サーバーサイドのエンジニアが手軽にインフラの構築を実現できるものとなります。

使用感

今回はTypeScriptを用いたのですが、型推論がしっかり効いていたため、どのリソースにどのようなパラメータが設定可能なのかを、コードをみるだけである程度推測することが可能で、流れるようにコードを書くことができました。

const app = new cdk.App()
new ApiStack(app, 'Api', {
  env: {
    account: 'account',
    region: 'ap-northest-1'
  }
})
app.synth()

class ApiStack extends cdk.Stack {
  constructor(parent: cdk.App, name: string, props: cdk.StackProps) {
    super(parent, name, props)

    const vpc = Vpc.fromVpcAttributes(
      this,
      'Vpc',
      {
        vpcId: 'vpc-8932jkdw',
        availabilityZones: ['ap-northeast-1a', 'ap-northeast-1c'],
        publicSubnetIds: ['subnet-8302sba', 'subnet-32890231'],
        privateSubnetIds: ['subnet-9042389fdjosa', 'subnet-re032109jifds']
      })

    const cluster = Cluster.fromClusterAttributes(this, 'Cluster', {
      clusterName: 'api-cluster-name',
      vpc,
      securityGroups: []
    })
  }
}

このように、<リソース名>.from<設定するアトリビュート>()とすると、現在のリソースから情報を取得し、その取得した結果を別のリソース作成時に使い回すといったことができます。

実行時は下記のようにTypeScriptをJS化した上で通常のJavaScriptを実行するだけなので、環境変数の注入など、動的に指定することが可能です。

cdk synth --app 'node index.js' > ../template.yml

いいところ

上記で紹介したとおり、環境変数などを用いて動的にパラメータを注入できるわけですが、それが生きるポイントとしては、 何かをビルドしたときにインフラを用意する というユースケースが考えられます。

CDKを使っているということは必然的にAWSを用いているということになるわけですが、例えばあるリポジトリでCodeBuildで環境を整備しようとしたときにbuildspec.ymlを配置すると思うのですが、そちらに下記のように指定することによって、dockerイメージを作成したあとにそのイメージを使って環境を作るといったことが可能になります。

phases:
  install:
    commands:
      - npm install -g npm@6.12.0 aws-cdk@1.14.0

  build:
    commands:
    # ... docker build
      - npm ci
      - npm run build
      - cdk synth --app 'node index.js' > template.yml
artifacts:
  files:
    - template.yml

こちらのartifactsを使ってCloudFormationを立ち上げるといった具合です。 この際、例えばCodeBuildに対して特定の条件を分岐させるような環境変数を提供し、それをコード化することによって必要な環境をよしなに作ることができます。

const vpc = Vpc.fromVpcAttributes(
  this,
  'Vpc',
  {
    vpcId: 'vpc-8932jkdw',
    availabilityZones: ['ap-northeast-1a', 'ap-northeast-1c'],
    publicSubnetIds: ['subnet-8302sba', 'subnet-32890231'],
    privateSubnetIds: ['subnet-9042389fdjosa', 'subnet-re032109jifds']
  })
if(process.env.SOME_CONDITION){
  Cluster.fromClusterAttributes() //...ECSを立ち上げる
} else {
  Repository.fromRepositoryName() //... ECRからなにか取る
}

相性のいい環境

上記のようによしなに分岐ができるため、例えば特定の環境のみを再現したい場合の プレビュー環境 や、単純に日頃使い慣れている言語で、サクッと環境を作りたい サーバーサイドのエンジニア などがこの昨日を使うといいかもしれません。

相性が良くない環境

CDKは、 @aws-cdk/aws-ecs-patternsApplicationLoadBalancedFargateService など、便利な関数を呼び出す形で組み立てていきます。 型である程度中を推論できるものの、ハードコーディングされているオプションなどがあり、細かいチューニングには向かないかなと思いました。

Terraform

Use Infrastructure as Code to provision and manage any cloud, infrastructure, or service

https://www.terraform.io/

Terraformのサイトから引用したのですが、文字通り、AWS以外のクラウドインフラにおいて使えるIaCのツールとなります。

使用感

下記のように、独自のDSLを用いて記述していきます。 HashiCorpプラグインなどを使うことによって、設定できるパラメータが何があるかと言うのをある程度推論してくれます。

resource "aws_alb" "default" {
  name = local.alb_name

  security_groups = [
    aws_security_group.alb.id,
  ]

  subnets = data.aws_subnet_ids.main.ids
}

resource "aws_alb_listener" "http" {
  default_action {
    target_group_arn = aws_alb_target_group.default.arn
    type             = "forward"
  }

  protocol          = "HTTP"
  load_balancer_arn = aws_alb.default.arn
  port              = 80
}

実行は基本的にサイト上にあるバイナリファイルをダウンロードしてきて、それを実行していく形になります。

terraform plan # 仮実行
terraform apply # 本実行

実行後はstateというストレージに環境全体の情報が格納され、次回以降の実行時はこのstateと実際のインフラ環境、コードの状況を比較し、差分のみを実行するといったことを行ってくれます。

いいところ

一つ一つしっかり記述していくため、細かいチューニングができるのが特徴です。 また、バイナリの方でフォーマットのコマンドも用意されているため、基本だれが書いても同じようなコードになります。

また、importという機能があり、Webコンソールなどですでに構築されている環境の状態をstateに持ってくる機能があるため、試しにWebコンソールで環境を作ったあと、importでコード化するということができます。

相性のいい環境

基本的に運用し続ける環境で効果を発揮すると思われます。理由としては、

  • 差分適応による効率的な環境設定ができる点
  • import機能による、コード化の簡易性
  • インフラ構築に特化した、宣言型の実装

というところで、メンテナンスに適しているためです。 また、workspaceを用いることによって、本番環境と同等の環境を手軽に別の環境で作成することができるため、本番適応前の最終確認などが手軽に行えるといった点も評価できるポイントです

相性の悪い環境

すべてのパラメータを宣言的に書くという仕様上、あまり動的に変わるようなインフラ環境には向かないと思われます。 動的に変更したい場合はCDKを検討しましょう

まとめ

CDKとTerraformを比較してきました。それぞれ一長一短あると思いますが、よしなに使い分けていけるといいかなと思っております。

元記事

kotamat.com