「k3sとラズパイでフロントエンド開発に挑戦した話」を発表しました

今週は2つのイベントでLTをさせていただきました!ほぼ同じ内容で登壇したので、2日連続で参加された方には申し訳なかったのですが、少し内容を変える努力はしました。。。

rancherjp.connpass.com

cnjp.connpass.com

発表資料

 

ストーリー

フロントエンジニアでラズパイ持っててkubernetesに興味があったら、とりあえずラズパイ上にNuxt.js乗せたくなりますよね!?

ということで、今回はNuxt.jsをラズパイに入れたk3s上にデプロイすることに挑戦したときの話をしました!ポイントとしては下のとおり!

  • arm32v7/nodeの alpine だと npm install でコケる
  • なのでARMのイメージで alpine はあきらめる
  • docker create manifest でマルチアーキイメージを作れる(ARMとx86_64で同じイメージ名!)
  • Dockerfileの FROMARG を使うとイメージレイヤのキャッシュが効かない疑惑がある

ヘルプをもらえました!

node のイメージを素で使ってましたけど、 node-slim にしては? というアドバイスがいただけました!

f:id:kenev:20190608003541p:plain
879mb→310mb

半分以下には落とせました!けれど2桁までは落としたい気持ちがあります。。。

ARG 使うとキャッシュは効かない!? についてのアドバイスもいただけました!

上の公式ドキュメント読みましたけど、毎回同じ値にしてるのにキャッシュ効かないんですよねー。これは引き続き調査 or Dockerfileを分ければいいのかなと思ったり。

おまけ

こういうコメントがもらえてうれしいです!アプリ寄りな話を増やしたい気持ちはあるんですよね。

なかなか時間を作るのにも苦労していますが、今後もフロントエンドとコンテナをからめていきたいです!

カックさん(@kakakakakku)さんのメンタリングを卒業しました

3月から5月の3ヶ月間に渡るカックさん(@kakakakakku)のブログメンタリングを卒業しました!

ここに卒業記事を残し、今後についても書き残しておきたいと思います。

メンタリングをなぜ受けたのか

僕はアウトプットすること自体は好きで、ブログを書いたりイベントに登壇したりは不定期にしていました。自分でも認識していた問題はアウトプットの習慣化がまるでできていなかった点です。その点を改善すべく、メンタリングを受ける決意をしました。

アウトプットの習慣化がなぜできないのか

「なぜアウトプットの習慣化ができないのですか?」と聞かれたら多くの人が「忙しくて時間が無い」と答えるかと思います。

今、「うんうん」と頷いた方、ぜひぜひ下の記事を読んでいただきたいです。これだけでもマインドセットが変わると思います!

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

僕も「時間が無い」と思っていた中の一人ですが、「時間が無い」と定義していたのは自分です。誰かに強制的に自分の時間を奪われていたわけではありません(そういう人もいるかもしれませんが…)。時間の使い方をコントロールできていなかったのが大きな原因だと気づくことができました。

3ヶ月の実績

3ヶ月の実績は下のとおりです。

f:id:kenev:20190603205019p:plain
PV

項目 3月初 5月末
Twitter Follower 393 410
はてブ 0 12
読者数 0 31

メンタリングが始まって結構すぐにCloud Native Kansaiという大きめなイベントでLT登壇することができたので、PVがすごく上がっています。

そのときの記事がこちら。

kenfdev.hateblo.jp

けれど、この波に乗ることができずにいっきに低迷!そこからOPAネタを書いていきながら、最後は書評に挑戦して徐々にPVを上げていくことができたかなと思っています(まだまだですが)。

驚くような結果にはならなかったので反省していますが、今後も継続して精進していきます!

課題

卒業とともにカックさんに最後のフィードバックをもらいました。中でも特に僕が今後も改善していきたい点については「満足できるクオリティに達するまでの距離を遠くに置きがち」なところです。週1のアウトプットを出していくことはできるようになったのですが、1アウトプットするまでに要している時間が多すぎると感じています。

いつもどうしても

  • まとまりが悪い
  • ストーリー性が見えにくい
  • もっと違う観点を取り入れたほうがいいのでは
  • などなどetc.

と考えてしまって、書いては消して、書いては消してを続けてしまいます。「小さく考える力」が圧倒的に足りていないのを痛感しています。 カックさんにも薦められた「小さな習慣」を読み、「常にアジャイルに、小さく考えられるように」改善し続けたいと思っています!

小さな習慣

小さな習慣

メンター、カックさんについて

カックさんは本当にすごい方です。そのすごさは他のメンティの卒業エントリを見てもわかると思います。今後もエントリは増えていくと思うので、下のようにググったりTwitter検索した内容を確認すると勉強になります。

www.google.com

twitter.com

すごい点は数え切れないほどあるのですが、僕からも1点共有しておきたいです。

それは「やってみせる・やらせてみる・フィードバックする」のサイクルが本当にうまく回っていると感じた点です。

この記事を書いている最中にもカックさんからこんなツイートが流れています。

カックさん自身、かなり多忙なはずなのですが、毎週必ずアウトプットをしています。メンターであるカックさんがやってみせてから、メンティにもやらせてみる。そして、やらせてみた後は必ずフィードバックがもらえます。フィードバックは「よかった」「悪かった」なんてシンプルなフィードバックじゃなくて、かなり濃厚で、親身なフィードバックがいただけます。すごいのは、それらのフィードバックや他の通常な会話も合わせて、メンティの僕が精神的に負荷を感じることが無い点です。「がんばろう」という気持ちに素直になりますし、「しんどい」ときにはどう乗り越えていくことができるか相談に乗ってくれます。メンターの鏡です!自分自身で最高のメンターによるメンタリングを経験することができたので、僕もこうなれるように、この点についても日々精進していきたいです。

今後について

このメンタリングを通して毎週最低1記事を書くということが習慣化できたので、自分は成長したと感じています。メンタリング中に初挑戦した書評ともちょうどフィットするのですが、メンタリングを受けたことで、セルフマネジメントのレベルが上がって、ブログを書くことの習慣化が可能になったのかなと思います。

今後3ヶ月の目標としては

としたいです。

習慣化したのを継続すること(当たり前ですが!)、質の高い記事が書けるようになること。そして、英語のアウトプットも増やしていけたらと思います!(世界は広い!)

またちょっと長い目な記事になってしまいましたが、以上で卒業報告とさせていただきます!

カックさん(@kakakakakku)、本当にありがとうございました!!!

Unit Test好きにはたまらない!Conftestで設定ファイルのテストをしてみた

KubeConでOpen Policy Agent関連の発表を追っていたところ、面白そうなプレゼンを発見しました!

Unit Testing Your Kubernetes Configuration with Open Policy Agent

僕はUnit Test大好き人間なのでUnit Testと聞くだけで興奮するのですが、それにさらにOpen Policy Agentが関わっているときたら放っておけません!

もしOpen Policy Agentについて初めて聞いたという方は以下の記事でも紹介しているので興味があればぜひ!

kenfdev.hateblo.jp

Conftest

ConftestはYAMLあるいはJSONで定義された設定ファイルに対してテストを書けるというツールです。

面白いのは、テストに使うのがOpen Policy AgentのRegoというポリシー用の言語だという点です。上に紹介した記事にも書いていますが、さらに気になる人は公式サイトでもRegoについて詳しく書かれているのでぜひ読んでみてください。

www.openpolicyagent.org

インストール

Macにインストール。僕はbrewを使いましたが、様々な方法でインストールできますので、READMEをチェックしましょう!

brew tap instrumenta/instrumenta
brew install conftest

インストールはこれで完了です!

テストを書く

ではテストを書いてみましょう!KubernetesYAMLがテストできるってところがハイライトされがちですけどYAML, JSONならなんでもOKです!

ということでせっかくなのでチュートリアルには無いCircleCIのYAMLを対象にしました!

テストを書くにあたって重要なのはRegoという言語を使うということです。

Regoはポリシーに特化した言語で、ちょっとトリッキーなところもありますが、宣言的で読みやすい言語だと思います。

例えばCircleCIの以下のようなconfigがあったとします。

version: 2.0
jobs:
  build:
    docker:
      - image: circleci/buildpack-deps
    steps:
      - checkout
  test:
    docker:
      - image: kenfdev/golang:1.12
    steps:
      - checkout
workflows:
  version: 2
  build_and_test:
    jobs:
      - build
      - test

これを.circleci/config.ymlに置きます。

conftest を導入すると何ができるかというと、このYAMLの記述内容に対してポリシーを書くことができます。

具体的にはこんなポリシーを割り当てることができます

  • version: 2.1 以上しか使っちゃいけない
  • CircleCI純正のイメージしか使っちゃいけない
  • コンテナのイメージにlatestを使っちゃいけない

などなどです。

実際にこのポリシーを適用したテストを順番に書いてみます。

conftestはデフォルトでpolicyディレクトリ配下の.regoファイルを見てくれる様なので、circleci.regoというファイルを作ります。

touch policy/circleci.rego

この中にルールを書いていきます。

packageを指定

Regoのpackageはデフォルトでmainが使われます。これは--namespaceオプションで変更可能とのこと。

なので、packagemainにしましょう。

package main

version: 2.1 以上しか使っちゃいけない

「CircleCIのOrbs機能を使いたいから、Versionを必ず2.1以上にしたい」というポリシーがあるかもしれません。その場合に書けるポリシーは以下のとおり。

deny[msg] {
 input.version < 2.1
 msg = "Use version 2.1 or higher"
}

denyになる条件を探すので、「どうなっているとルール違反か?」というマインドが必要です。inputというのはRegoで特別な変数で、conftestの場合ここにテスト対象のYAMLあるいはJSONが入っています。なのでinput.versionversionにアクセスできます。

conftestを実行してみます!

$ conftest test config.yml
config.yml
   Use version 2.1 or higher

2.0config.ymlに指定しているので怒られてますね!

CircleCI純正のイメージしか使っちゃいけない

こんなユースケースがあるかどうかはさておき、使うコンテナのimageにポリシーを設けたい場合の例になります。

必ずimagecircleci/から始まっているかどうかをチェックしてみます!

deny[msg] {
  docker_images := input.jobs[_].docker[_].image
  not startswith(docker_images, "circleci/")
  msg = "Only use official CircleCI images"
}

Regoのちょっとトリッキーな書き方をさっそく取り入れてみました。

docker_images := input.jobs[_].docker[_].image

これを言語化すると「jobsの中に含まれる複数のキー(build, test)の中にあるdockerという配列の中のimageキーの値」になります。

こうやって書くことでOPAがよしなに順番に拾ってくれます。そして、それらがcircleci/で始まってなかったらアウトにします。

not startswith(docker_images, "circleci/")

ここで使っているstartswithはRegoに予め組み込まれているビルトイン関数です。OPAのドキュメントにも載っているので、どういうものがあるかチェックしておくといざとなったら使えて便利です!

www.openpolicyagent.org

circleci/で始まっていないもの」を探すので、先頭にnotをつけている点もお忘れなく!

実行してみます!

$ conftest test config.yml
config.yml
   Only use official CircleCI images
   Use version 2.1 or higher

kenfdev/golang:1.12 を使っているので怒られていますね!

コンテナのイメージにlatestを使っちゃいけない

またまたimageに関連するポリシーです。安定したCIを回すためにimageに必ずタグを指定するというポリシーが必要になるかもしれません。latestを使っていたらルール違反にしましょう。

deny[msg] {
  docker_images := input.jobs[_].docker[_].image
  tag_is_latest(split(docker_images, ":"))
  msg = "Do not use `latest` container image tags"
}

# helpers
tag_is_latest(images) {
  count(images) < 2
}

tag_is_latest([_, tag]) {
  tag == "latest"
}

docker_imagesはさっきと同じですが、2行目がまたちょっとトリッキーです。latestを検知する方法は以下の2つの観点にしています。

  • :で分割した場合に要素が2個より小さい
  • :で分割して末端側(tag側)の値がlatestになっている

いずれかにヒットしたらルール違反にします!ここでポイントなのは、「いずれか」ということ。つまりOR条件になります。Regoのルール内の行は全てANDになり、同じルール名のルール(この場合tag_is_latest)を並べるとORになるという特性があります。これはIncremental Definitionsと言って公式ドキュメントでも説明があるので要チェックです。

www.openpolicyagent.org

また、僕が以前書いた記事にもANDとOR、そしてルール内から別のルールを呼び出すことについて触れていますので興味があればぜひ参考にしてみてください!

kenfdev.hateblo.jp

上のやり方ではtag_is_latestというルールを別途2つ作って、それぞれの判定条件を書きました。

:で分割した場合に要素が2個より小さい
tag_is_latest(images) {
  count(images) < 2
}

imagesにはsplit(docker_images, ":")で分割された値が入ってきます。今回の例であれば下のようになります。

["circleci/buildpack-deps"] # 要素数は1つ
["kenfdev/golang", "1.12"] # 要素数は2つ

タグが無い場合のデフォルトがlatestになるので、分割された要素の数が2より小さいかどうかをチェックします。

:で分割して末端側(tag側)の値がlatestになっている
tag_is_latest([_, tag]) {
  tag == "latest"
}

また新たな記法が引数の場所([_, tag])に登場しました。これは、いい感じに配列の値を分割代入させる書き方です。

例えば下のように書くとイメージしやすいと思います。

[name, tag] = ["circleci/buildpack-deps", "latest"]

nameにはcircleci/buildpack-depsが対応し、tagにはlatestが対応して代入されるようなイメージです。でも、nameには今回は特に興味がないので、上の例では[_, tag]と書いています。そして、ルール内ではtag == "latest"というように評価することで、taglatestかどうかチェックすることができます。

それでは、テストを実行してみましょう!

$ conftest test config.yml
config.yml
   Only use official CircleCI images
   Do not use `latest` container image tags
   Use version 2.1 or higher

image: circleci/buildpack-depsがタグを指定していないので、ちゃんと怒られていますね!ちなみにimage: circleci/buildpack-deps:latestとしてもちゃんと怒られます。

conftestでテストができました!念の為ポリシーの全体像も載せておきます。

# .circleci/policy/circleci.rego
package main

deny[msg] {
 input.version < 2.1
 msg = "Use version 2.1 or higher"
}

deny[msg] {
  docker_images := input.jobs[_].docker[_].image
  not startswith(docker_images, "circleci/")
  msg = "Only use official CircleCI images"
}

deny[msg] {
  docker_images := input.jobs[_].docker[_].image
  tag_is_latest(split(docker_images, ":"))
  msg = "Do not use `latest` container image tags"
}

# helpers
tag_is_latest(images) {
  count(images) < 2
}

tag_is_latest([_, tag]) {
  tag == "latest"
}

config.ymlの修正

怒られっぱなしなのもちょっと悲しいので、config.ymlを直しましょう!

全てのポリシーを満たすために下のように修正しました。

version: 2.1 # 2.1に変更
jobs:
  build:
    docker:
      - image: circleci/buildpack-deps:jessie # latest使うのやめた
    steps:
      - checkout
  test:
    docker:
      - image: circleci/golang:1.12 # circleciのイメージに変更した
    steps:
      - checkout
workflows:
  version: 2
  build_and_test:
    jobs:
      - build
      - test

それではテスト実行です!

$ conftest test config.yml
config.yml

ちょっとわかりづらいんですけど、何も怒られなくなりましたね!

いい感じにconftestで設定ファイルに対してテストが書けることがわかりました。Regoへの慣れは必要ですが、今後Open Policy Agentも様々な場所で使われていくことになりそうなので、Regoは学んでおいて損は無いんじゃないかなと思っています。

今回のコードは以下のリポジトリに置いてます。

github.com

まとめ

  • YAML, JSONの設定ファイルに対してテストが書けるconftestを試した
  • conftestは宣言的にOpen Policy AgentのRegoを使ってテストを書ける
  • どこがルール違反になっているか、場所も教えてくれるとさらにうれしい
  • 全部ポリシーをパスしてたらもうちょっとうれしい出力がほしい(笑)
  • 今後に期待したい!!!

参考

Conftestを使ったテストの例 github.com

Open Policy Agentのチュートリアル www.openpolicyagent.org

セルフマネジメントについて考える / 『管理ゼロで成果はあがる〜「見直す・なくす・やめる」で組織を変えよう』を読んで②

管理ゼロで成果はあがる〜「見直す・なくす・やめる」で組織を変えよう」という本を読み終えました!

この本の中でも特に「生産的に働く」ことについては以下の記事で書評を書いたので、興味がある方はぜひ!

kenfdev.hateblo.jp

この記事では、第2部で紹介されている「セルフマネジメントのレベル」と「師匠が背中を見せる」ことについて注目した書評を書きます。

目次

  • はじめに
  • 第1部 生産的に働く ~楽に成果をあげるために“見直す”
    • やり方を見直す ~「ふりかえり」で抜本的に生産性を改善する
    • 生産性を見直す ~「時間対効果」の高い仕事をする
    • タスクを見直す ~「タスクばらし」で小口化する
    • やる気を見直す ~無理に上げない、なくさない状況をつくる
    • 信頼関係を見直す ~「心理的安全性」を生み出す環境
    • 会議を見直す ~口を動かすだけでなく、いっしょに手を動かす
    • 雑談を見直す ~ホウレンソウから「ザッソウ」へ
    • 社内業務を見直す ~人手に頼らない「業務ハック」で改善を続ける
    • 価値を見直す ~受託脳よりも提案脳で考える
  • 第2部 自律的に働く ~人を支配しているものを“なくす”
    • 管理をなくす ~セルフマネジメントで働くチームをつくる
    • 階層をなくす ~「ホラクラシー」組織を実現する仕組み
    • 評価をなくす ~個人の成長と会社の貢献の「すりあわせ」をする
    • 数字をなくす ~組織のビジョンよりも自分のためならがんばれる
    • 組織の壁をなくす ~信頼しあえる企業文化の育て方
    • 急募をなくす ~仕事があっても、いい人がいなければ採用しない
    • 教育をなくす ~自分の頭で考える社員の育て方
    • 制度をなくす ~本質ありきで考える「そもそも思考」
    • 通勤をなくす ~働く場所に縛られない「リモートチーム」
  • 第3部 独創的に働く ~常識や慣習に従うことを“やめる”
    • 既存のビジネスモデルに従うのをやめる ~納品のない受託開発
    • 顧客を説得する営業をやめる ~対等な関係を作るマーケティング
    • 新規事業の指示命令をやめる ~部活から生まれるイノベーション
    • 規模を追求することをやめる ~組織の大きさもコントロールしない
    • 会社らしくすることをやめる ~文化をつないでいくコミュニティ
  • おわりに

セルフマネジメントの3つのレベル

本書では「管理をなくす」にあたって、セルフマネジメントについて紹介されています。「仕事」、「組織」、「自分」という3つの観点で、それぞれレベルを3つに分けて定義しています。

観点 Lv1 Lv2 Lv3
仕事 タスクを管理する リソースを管理する 価値を生み出す
組織 周囲に伝える 周囲と協調する 周囲を活かす
自分 休憩をとる 安定して働く 将来を考える

何ができていると、どこのレベルにいるかというのが述べられています。「自分はそれぞれの観点でどこのレベルにいるのか?」というのを確認できて面白いですし、何ができればレベルが上がるのかというのも参考にすることができます。

「休憩をとる」ということ

セルフマネジメントのレベルの中でも注目したいのは「自分」の観点の中のLv1に入っている「休憩をとる」ことです。

休憩が習慣化していない人にとっては「いつ休憩をとるのか?」というのが難しいと感じそうですが、僕はポモドーロ・テクニックがここにフィットすると感じました。

何度か僕のブログで紹介していますが、ポモドーロ・テクニックについては僕のブログメンターでもあるカックさん( @kakakakakku )の以下の記事がおすすめです!

kakakakakku.hatenablog.com

ポモドーロ・テクニックを使って「25分間は超絶に集中し、その後は5分間休憩をとる」というサイクルを繰り返していくと休憩も1つのタスクのように感じられるようになり、自然と習慣化もしていきます。

だれかが管理しないと休めないようでは、マネジメントする側の負担は大きいままです。

と、本書でも述べられています。休憩を自らとれるかとれないかは、自分だけの問題ではないということに気づく必要があります。休憩の習慣化は小さく見えてセルフマネジメントにおいては大きな一歩だと感じました。

師匠が背中を見せる

本書には「教育をなくす」という章があり、「教育する」のではなく「仕事の中で育てる」方法について紹介しています。

これには以下3つのポイントが述べられています。

  • やってみせる
  • やらせてみる
  • フィードバックする

本書では育てる側を「師匠」、育てられる側を「弟子」と呼んでいて、1点目の「やってみせる」というのは「師匠が弟子に背中を見せる」ということです。ポイントとなるのは、いかにして師匠は弟子に自分の技術を盗ませるかです。そのためにまずは「やってみせる」ことが大事だと述べられています。個人的にふりかえってみても、物理的に離れていた新人に仕事をやってみてもらったときよりも、隣に座って一緒に仕事をしていた新人の方が圧倒的に成長のスピードが早かったのが記憶に残っています。これは、自然と自分の仕事を「やってみせる」ことができていたのではないかと思います。

気になった点としては、最初から物理的に離れている者同士(リモート)の場合、「やってみせる」にはどうしたら良いかということです。フルリモートをしている身としては今後の課題として追求していきたいです。

まとめ

  • 『管理ゼロで成果はあがる〜「見直す・なくす・やめる」で組織を変えよう』を読んだ
  • セルフマネジメントに悩んでいるor興味がある人にオススメできる
  • セルフマネジメントできる人を増やしたい人にもオススメできる
  • フルリモートにおける師弟関係について追求していきたい

生産的に働くことについて考える / 『管理ゼロで成果はあがる〜「見直す・なくす・やめる」で組織を変えよう』を読んで①

ふとFacebookのタイムラインから流れてきた「管理ゼロで成果はあがる〜「見直す・なくす・やめる」で組織を変えよう」という本。今まで技術書ばかり読んできていて組織や人に関する本には手をつけていなかったのですが、最近は積極的に読むようにしています。この本を読みながら改めて気付かされる点が非常に多かったため、自分のためにも書評を書きます!

目次

以下が目次となっていて、この記事では太文字の「第1部 生産的に働く ~楽に成果をあげるために“見直す”」に注目します。

  • はじめに
  • 第1部 生産的に働く ~楽に成果をあげるために“見直す”
    • やり方を見直す ~「ふりかえり」で抜本的に生産性を改善する
    • 生産性を見直す ~「時間対効果」の高い仕事をする
    • タスクを見直す ~「タスクばらし」で小口化する
    • やる気を見直す ~無理に上げない、なくさない状況をつくる
    • 信頼関係を見直す ~「心理的安全性」を生み出す環境
    • 会議を見直す ~口を動かすだけでなく、いっしょに手を動かす
    • 雑談を見直す ~ホウレンソウから「ザッソウ」へ
    • 社内業務を見直す ~人手に頼らない「業務ハック」で改善を続ける
    • 価値を見直す ~受託脳よりも提案脳で考える
  • 第2部 自律的に働く ~人を支配しているものを“なくす”
    • 管理をなくす ~セルフマネジメントで働くチームをつくる
    • 階層をなくす ~「ホラクラシー」組織を実現する仕組み
    • 評価をなくす ~個人の成長と会社の貢献の「すりあわせ」をする
    • 数字をなくす ~組織のビジョンよりも自分のためならがんばれる
    • 組織の壁をなくす ~信頼しあえる企業文化の育て方
    • 急募をなくす ~仕事があっても、いい人がいなければ採用しない
    • 教育をなくす ~自分の頭で考える社員の育て方
    • 制度をなくす ~本質ありきで考える「そもそも思考」
    • 通勤をなくす ~働く場所に縛られない「リモートチーム」
  • 第3部 独創的に働く ~常識や慣習に従うことを“やめる”
    • 既存のビジネスモデルに従うのをやめる ~納品のない受託開発
    • 顧客を説得する営業をやめる ~対等な関係を作るマーケティング
    • 新規事業の指示命令をやめる ~部活から生まれるイノベーション
    • 規模を追求することをやめる ~組織の大きさもコントロールしない
    • 会社らしくすることをやめる ~文化をつないでいくコミュニティ
  • おわりに

「精神論」でふりかえりをしてはいけない

「やり方を見直す」方法として「ふりかえり」の大切さが述べられています。

ふりかえりの4つのポイント

  1. KPT(Keep・Problem・Try)でふりかえりをする
  2. とにかく全員で出し切ることを優先する
  3. 精神論ではなく、具体的なアクションに落とし込む
  4. 週に一度、1時間のふりかえりから始める

特に3番目は多くの人が陥る問題だと思います。何か問題(Problem)があって、それを改善するための試み(Try)を考えた場合、どうしても「次はこうならないように気をつける」と精神論を言ってしまいがちです。

そういった精神論ではなく、以下のように具体的なアクションに落とし込むことが大事だと述べられています。

Problem「2日連続で寝坊してしまった」
↓
【NG】Try「早起きするように気をつける」
【OK】Try「目覚まし時計を買う」

僕もついつい「がんばる」や「気をつける」と言ってしまいがちですが、常にこの点は意識していきたいです。

100%の品質と完成度は目指さない

80%の完成度には2割の時間でよくて、残り20%を高めるためには8割の時間がかかる

というパレートの法則の引用を用いて、完璧を目指してはいけないという点が紹介されています。

ja.wikipedia.org

完璧を目指そうとすると考え込むことが多くなり、ひたすら時間だけが過ぎていくことが多くなります。また、そもそも完璧の定義自体が自分で決めたものなので、完璧かどうかなんてわかりません。

80%であってもリリースをしてみて、「もっとこうしてほしい」点や「これは必要ない」点について早い段階で見つけて改善していくことが大事だと述べられています。

最後にFacebook創業者のマーク・ザッカーバーグの引用も紹介されています。

Done is better than perfect.

この考え方は最近読んだ「エンジニアの心を整える技術」でも紹介されていて、非常に大事だと感じています。

booth.pm

作業じゃなくて仕事をまかせる

本書では「仕事」と「作業」は違うものだと述べられています。

  • 作業
    • 事前に定められた手続きに従っておこなう活動
    • 手を動かすことに価値がある
    • わかりやすい結果や指標がある
    • 進め方に創意工夫の余地がない
  • 仕事
    • だれかに価値を届けるための活動
    • 「価値とは何か」をそもそも考えなければいけない
    • わかりやすい結果や指標がない
    • 進め方に創意工夫の余地がある

作業の進め方に「創意工夫の余地がない」かどうかは議論の余地がありそうですが、僕自身も作業を依頼していることが今まで多かったかなと感じます。

作業には事前に定められた手続きが必要になるので、依頼する側の負担が大きいです。さらに、「依頼」をされると、された側は自分の仕事として考えるのが難しいと本書では述べられています。

仕事には「わかりやすい結果や指標がない」かわりに「進め方に創意工夫の余地がある」ことで、仕事をする側は 主体性をもって取り組む ことができます。

主体性をもつ→自律的に成長する→モチベーションが上がる→生産性も上がる

というような好循環が生まれる。上の表現だけでは単純に見えますが実際には「仕事の全体像や目的の伝え方」、「コミュニケーションの方法」、「フィードバック」について気をつけるべき点があり、本書では別途詳しく紹介されています。

社会人になって2、3年もすれば後輩ができたり、チームメンバーの入れ替えなどがあってコラボレーションを主体的に行っていく必要性が増していきます。そのときには作業ではなく、仕事をまかせることが大事なんだと改めて考えさせられました。

「ホウ・レン・ソウ」から「ザッ・ソウ」

本書ではホウ(報告)・レン(連絡)・ソウ(相談)の大切さについて述べられつつも、より大事なのはザッ(雑談)・ソウ(相談)だと述べられています。「雑談が大事」なのは既に知っている人も多いと思いますが、問題はどうやったら雑談を増やせるか?という点です。雑談は「よし、雑談をしよう!」と言ってなかなかできるものでは無いですし、信頼関係など前提条件が揃っている必要があります。

そこで本書では「雑談をうまくするポイント」が3つ紹介されています。

  1. 雑談と仕事の場所をツールで分けない
  2. 社内で起きている雑談の様子を見える化する
  3. 定期的に雑談する機会をつくる

雑談と仕事の場所をツールで分けない

この点についてはハッとさせられました。確かに、例えばSlackのチャンネルに「#雑談」というチャンネルがあったとしたら、そのチャンネルに投稿するということは「よし、今から雑談するぞ!」という気持ちが先に発生する人が多いと思います。もちろん人によってこれは変わるのでしょうけど、雑談をする前に「雑談 or NOT 雑談?」というオーバーヘッドが生まれるのがあまり良くないというのには納得させれました。流れるように自然に雑談ができる環境がベストですよね。

社内で起きている雑談の様子を見える化する

この点については前提として社内全体の高い信頼関係が必要だとは感じます。それが無い状態ではどうしても前節にも述べられているように、発言の前に「こんな内容(雑談)を投稿していいだろうか?」というマインドが発生してしまうからです。

また、もう一つ注意する点については、(これは雑談に限った話ではないですが)公開される情報が多くなるということはSlackのようなツールの場合にそれだけ「通知」も多くなります。これによって気になることが多くなり、生産性が落ちてしまう可能性も含まれていると思います。

f:id:kenev:20190520060707p:plain
気になる通知

そこで僕が追加で紹介したいのはポモドーロ・テクニックです。

「25分間はとにかく決めたタスクに集中し、5分間休憩を挟む」ということを1セットとして繰り返すテクニックのことです。この25分間の間、通知が来たとしても無視します。無視するというのは、Slackであれば「離席中」にして通知が来ないようにするレベルです。

この記事では詳しくは述べませんが、以下の記事がとてもよくまとまっているのでポモドーロ・テクニックに馴染みの無い人はぜひ読むことをお薦めします!

kakakakakku.hatenablog.com

話が少し逸れましたが、「雑談の見える化」は見ようと思えば誰でも見えるような状態にしておくことが一つのポイントなのかなと僕は解釈しています。これもSlackの例えになりますが、可能な限りチャンネルはすべてPublicにしておくことがその手法の一つかと考えています。「他のチームの様子はどんな感じだろ?」となったときに「チラッ」と覗けたり、チャンネルにJoinできたりする環境が大事だと思います。

この点についてはSlackのJulia Graceさんによる「Building Engineering Teams Under Pressure(英語)」という公演でも述べられていて、合わせて視聴することをお薦めします。

www.youtube.com

まとめ

「管理ゼロで成果はあがる〜「見直す・なくす・やめる」で組織を変えよう」の「第1部 生産的に働く ~楽に成果をあげるために“見直す”」を読みました!個人的には「ふりかえり」することと「雑談」することが2つの大きなポイントだと感じました。「生産的に働くこと」については常に意識しつつ今後も仕事に取り組んでいきたいと思います!

また、セルフマネジメントについては、以下の記事で書きました!

kenfdev.hateblo.jp

おまけ

生産的に働くこととDeveloper Happinessも強く関連していると思います。この点については以前書いた下の記事で「Developer HappinessとEmployee Retention」というトピックでも紹介していますので興味があればぜひ読んでみてください!

kenfdev.hateblo.jp

Algolia Searchの速さに鳥肌が立った話

algolia.connpass.com

「Algolia Community Party in 京都 - 2019年5月10日」に参加し、LTしてきました!

発表資料

ストーリー

業務でAlgoliaのスパイクをうつ機会があったので、そのときに経験した 圧倒的な爆速っぷり について完全なる自己満でそのときの気持ちを伝えました!

SPA(Single Page Application)の入門チュートリアルで「検索バーでフィルタリング」する簡単なアプリを作った記憶は無いでしょうか?

下のCodePenのような簡単なフィルタリングアプリです。

f:id:kenev:20190514230100p:plain
https://codepen.io/tiana-p/full/XGJgPo

ここで検索バーに文字を入力すると、リアルタイムにフィルタリングが適用されます。 とても速いのですが、Amazon楽天市場価格.comで使うような「大量のデータから検索」する機能で同じようなUXを実現しようとすると かなり難しい です。

なぜなら、上のフィルタリングアプリは 最初から ブラウザがインメモリに持っている情報に対してフィルタリングしているのに対して、「大量のデータから検索」する場合には外部のAPIにリクエストして、さらにそのAPIが外部のデータベース内のデータを取得しにいったりするからです。これをどうにか高速化するにはインデックスを頑張ったり、キャッシュを頑張ったりと、涙ぐましい努力が必要になります。そしてその努力をしたとしても、上のフィルタリングアプリのようなスピードを実現するのはかなり難しいと思います。

なので、大量のデータから検索するときに、 ちょっと時間がかかる っていうのは「ある程度は仕方ないかな」と妥協することが多いはずです。

ただし! 外部にデータがあったとしても爆速で検索できてしまうのがAlgoliaなんです!

下のデモサイトで体験ができるのでぜひ体感してみてください。

community.algolia.com

今まで様々な技術スパイクをうってきましたが、隣の同僚にまで「これ、やばいっすよ」って感動を伝えたのはAlgoliaが初めてです。

13万件のサンプルデータを入れてみて、多少パフォーマンスが変わるかと思いきや検索には 3ms しかかかりませんでした!(ただし、ネットワークの時間を含めると20~40ms)

イベントレポート

下のイベントレポートが両者とも非常にわかりやすくまとまっています!

Algoliaの @shinodogg さんのイベントレポート

shinodogg.com

@silver_birder さん のイベントレポート

silverbirder180.hatenablog.com

まとめ

まだAlgoliaのさわりの部分しか使えていないので

  • Query Rules(「cheap camera」って検索したら「cheap」が「< 10,000」に変換できて、10,000円以内のカメラに絞れたりする)
  • Personalization(検索で行った行動などから、ユーザー毎にサジェストをパーソナライズできたりする)
  • Internationalization(多言語に対する検索インデックスの管理方法)
  • Multi-tenancy(マルチテナントなデータの管理方法)

あたりのトピックを今後は深掘りしていきたいです!

幸運な巡り合わせのおかげで突如3日前に参加&LTが決まったイベントでしたが、Algoliaの中のEiji Shinohara( @shinodogg )さんやフランスからかけつけて下さったMichaël Sokol( @_ms123 )さんともお話できて本当によかったです!

「誰」が「何」をできるかをOPAのレスポンスで返す

OPA(Open Policy Agent)で「○○をやっていいですか?」に対して「Allow/Deny」の返答がくるパターンについていくつか記事にしました。

今回は、 「誰」が「何」をしていいか をOPAからのレスポンスで知る方法について検証したので共有します。

どういった場面でこれを知りたくなるかと言うと、

例えばSPA(Single Page Application)で、 ログイン中のユーザー が「何」をして良いか知りたいときが考えられます。

この情報があることによって、

  • 新規作成ボタンを表示する
  • 編集ボタンを表示する
  • 削除ボタンを表示する
  • 特定のメニューを表示する

などの判断をSPA側で行うことができるようになります。

今回の記事で作成するPolicyもOPAのSlackでやりとりがされていた内容をちょっとカスタマイズさせてもらったものになります。

ドキュメントには登場しないようなユースケースがコアメンバーによってPlaygroundでシェアされていたりするので、OPAに興味がある方はぜひSlackに参加することをおすすめします!

slack.openpolicyagent.org

権限の定義

今回の例では以下のような状況があると仮定します。

  • article というリソースがある
  • alicearticleread できるし write もできる権限がある
  • bobarticleread する権限しかもっていない

これをOPAのRegoで表現すると次のようになります。

package foo.bar

permission["alice"] = [
    { "resources": ["article"], "actions": ["read", "write"] }
]
permission["bob"] = [
    { "resources": ["article"], "actions": ["read"]}
]

実際はこの permission をハードコードすることは無く、データベースなりどこかに保持されているところからOPAに読みこませることになりますが、Playground上で表現するために直でデータを書いておきます。

指定したユーザーの権限を取得

では、データが用意されたのでここから aliceの権限を取得 したいとなったらどうすれば良いか。 欲しいのは以下の情報です。

[
    { "resources": ["article"], "actions": ["read", "write"] }
]

OPAでは「Allow/Deny」な答えを返すことが多いのですが、オブジェクトを返すこともできます。 これがドキュメントにも書かれている「Generating Objects」をする方法です。

www.openpolicyagent.org

OPAへのリクエストの input{ "user": "alice" } とした場合に、 alice の権限が返ってくるようにするには次のようなルールを定義します。

user_permission = perm {
    perm := permission[input.user]
}

ここでポイントとなる点は user_permission = perm の、 = perm の部分です。 普通のルールの場合は key だけ指定して value 側を指定することはありません。

value 側を指定(ここで言う perm )し、その値をルールの中身で用意することでレスポンスとして返すことができます。

実際に試してみましょう!下図はPlayground実行している様子です。

PlaygroundにはちょっとしたTipsがあって、図のように、選択した部分のルールのみを実行してOutputを確認することができます。

f:id:kenev:20190506222034p:plain

下記リンクからPlaygroundが実行できるので、ぜひ試してみてください!

play.openpolicyagent.org

Inputを

{
  "user": "alice"
}

としたことで、 user_permission のみを実行した結果が

[
  {
    "actions": [
      "read",
      "write"
    ],
    "resources": [
      "article"
    ]
  }
]

となり、 alice の権限がレスポンスとしてオブジェクトで返ってきているのがわかります。

また、 bob であれば以下のように、 article に対して read しか許可されていないのがわかります。

[
  {
    "actions": [
      "read"
    ],
    "resources": [
      "article"
    ]
  }
]

このように、「Allow/Deny」のレスポンス以外にも、オブジェクトでレスポンスを返すことができるということもわかりました!

そして、例えばこのレスポンスを使ってUI側では

  • write があるから新規作成、編集、削除ボタンを表示する

という処理が書けて、ログインしているユーザーの権限に応じて画面の見た目を変えることができます。

やっていいかどうかの判断

「誰」が「何」をしていいか を確認する方法についてはこれでOKですが、実際に「やっていいかどうか」の判断も必要になります。

具体的には以下の質問への答えが必要になります。

  • alicearticlewrite できますか?
  • bobarticlewrite できますか?

この質問をするときのInputはきっとこんなJSONになると思います。

{
  "user": "alice",
  "action": "write",
  "resource": "article"
}

そしてこの質問に対して、「Allow/Deny」の答えを出すためのRuleはRegoで以下のように表現することができます。

default allow = false
allow {
    permission[input.user][i].resources[_] == input.resource
    permission[input.user][i].actions[_] == input.action
}
  • permission["alice"] の中のデータを順番にチェック
  • i番目の情報の resourcesarticle が含まれるかチェック
  • i番目の情報の actionswrite が含まれるかチェック

結果として、 alice{ "resources": ["article"], "actions": ["read", "write"] } という permission を持っているので、すべて true となるので、結果も true です!

逆に bob の情報を下のように渡してみるとどうなるでしょう?

{
  "user": "bob",
  "action": "write",
  "resource": "article"
}

bob には { "resources": ["article"], "actions": ["read"]} という permission しか定義されていないので、 write できるかという質問に対しては false になります。

よって、このリクエストの結果は false になります。

まとめ

  • OPAは「Allow/Deny」以外にもオブジェクトをレスポンスとして返すことができる
  • 「誰」が「何」をできるか、を返すことでUIでその情報を使うことができる(ボタンの表示・非表示など)