おそらくはそれさえも平凡な日々

GitHubのprivate repositoryを含んだ場合のGo Modules管理

tl;dr

本題

Goに限った話ではありませんが、プロジェクトで使っているprivate repositoryからまた別のprivate repositoryを参照している場合、CI/CDなどの外部環境からどのようにそれらにアクセスさせるか困ることがあります。

例えば、git submoduleを使っている場合や、Goの場合ですとGo Modulesで指定しているパッケージがprivate repositoryである場合などがあるでしょう。

なぜ困るのかと言うと、GitHubの場合、CI/CD環境からprivate repositoryのリソースにアクセスさせる場合、repositoryにRead-only deploy keyを設定して使う方法が個人にも依存せず、アクセス権限を絞る上でも望ましく、一般的に利用されますが、このDeploy Keyを複数のrepositoryで共有することができないという仕様上の制約があるため、複数のprivate repositoryをcloneしようとすると途端に困ってしまうからです。

どうするか

Deploy Keyが使えない以上、個人ユーザーのSSH Keyか、API tokenを利用するしかありません。しかし、個人のものを使ってしまうと、個人に依存してしまいますし、自分の全てのprivate repositoryにアクセス可能になってしまいます。これでは困る。

ここでも、前回の記事でも取り上げた、"machine account"を活用します。

そういった用途に関して、GitHubのDeveloper Guideにも"Machine users"という項でドンピシャで説明されています。ここでは、accountではなくusersになっています。

ref. https://developer.github.com/v3/guides/managing-deploy-keys/#machine-users

Machine userを作成し、最小限必要なrepositoryのみにREAD権限を与えることで権限を絞ることができます。そのアカウントを複数人で管理すれば個人に依存することもありません。

Goの場合

GoのModulesの場合、対象のpackage repositoryをhttpsスキームのURLで取得しようとするため、取得時にそれを insteadOf で書き換えてやるのが基本戦略になります。

SSHを利用する場合

% git config --global url."ssh://git@github.com/<myorg>/".insteadOf "https://github.com/<myorg>/"

personal access tokenを使う場合

% git config --global url."https://${user}:${token}@github.com/<myorg>/".insteadOf "https://github.com/<myorg>/"

SSHかaccess tokenか

CI/CD上で利用する時、tokenの設定をする方法だと、うっかり画面の実行ログ上でtokenが見えてしまうリスクがあるかも知れません。またSSHを使う方法のほうが、GitHub固有の設定にもならないため、SSH KeyをCI/CD環境上に安全に設定する方法があるのであれば、そちらのほうが良さそうです。

Go公式の以下のissueでも特定のソースホスティングサービス用の設定を持たせられるようにできないか議論されていますが、やはり、sshでinsteadOfを使う方法が現状の対応案として紹介されています。Russ Cox氏もコメントしていますね。

https://github.com/golang/go/issues/26134

CircleCIだとSSH方式がより簡単

CiecleCIは標準でprivate repositoryにDeploy Keyを自動登録することで、repositoryのリソースアクセスを実現しています。

これでは冒頭に述べたように、単一private repositoryのリソースしか取得できないため、CircleCIにはそれを回避するために"User Key"を簡単に設定する機能が備えられています。公式ドキュメントの "Controlling Access Via a Machine User" という項にそれが書かれています。

ref. https://circleci.com/docs/2.0/gh-bb-integration/#controlling-access-via-a-machine-user

これはCircleCIがOAuth経由でGitHubユーザーにSSH Keyを自動的に登録する方法で、CircleCIはそのSSH Keyを使って、repositoryのリソースにアクセスするようになります。

これは少し怖いので、やはり、個人ではなくMachine userでやるべきでしょう。 一度、SSH Keyが登録されたあとは、その認可は念の為revokeしておいた方が良いでしょう。GitHubの個人設定のApplications -> Authorized OAuth Apps からrevokeできます。 revokeするとSSHキーも根こそぎ消えるみたいで駄目でした。セキュリティ的には正しい挙動…。

Go Modulesの依存取得

ここまでくればあとは簡単です。checkoutディレクティブを使えば、repositoryを取得できますが、この時、前項のSSH Keyを自動的に使い、insteadOfの設定も以下のように暗黙的にやってくれています。

% git config --global url."ssh://git@github.com".insteadOf "https://github.com"

あとは、private repositoryはmachine userの権限の範囲で取得できますし、Go Modulesの依存取得もinsteadOfの設定がされているため、go mod download とかでうまいことやってくれます。

まとめ

ということで、GitHubのMachine userとCircleCIのSSHのUser Keyを利用すれば、複数のprivate repositoryの取得が容易になり、privateなGoパッケージの取得も同様に簡単になります。

CircleCIでgit-pr-releaseする

git-pr-releaseそのものの説明に関してはninjinkunの以下のエントリを参照ください。

git-pr-releaseのすすめ

さて、現職に入社したら、git-pr-releaseが使われていたのですが、リリース担当者が手元で実行するフローになっていました。しかし、git-pr-releaseの本場であり発祥の地でもある、はてな社では、git-pr-releaseはCIに作らせるものであったので、それに倣って、こちらも現職で利用しているCircleCIに作らせるようにしてみた。

手順

  1. .git-pr-releaseをrepositoryに配置する
  2. GIT_PR_RELEASE_TOKEN をCircleCIに登録する
  3. .circleci/config.yml にjobを設定する

おまけ

1. .git-pr-releaseをrepositoryに配置する

すでにgit-pr-releaseをお使いの場合は、既に配置されているかも知れませんが、repository rootに以下のような.git-pr-releaseファイルを配置してコミットもしておく。

[pr-release "branch"]
    production = master
    staging = develop
[pr-release]
    labels = pr-release

pr-release.labels でラベルの設定もできるのでこれも後でリリース履歴のリストアップするときなどに便利です。設定を~/.gitconfig.git/configに登録しておく手もありますが、ちゃんとrepositoryに置いておくとプロジェクト共通の設定になるので何にせよ良いです。

2. GIT_PR_RELEASE_TOKEN をCircleCIに登録する

GitHub上でpersonal access tokenを発行する。その際、scopeの選択のときにrepoにチェックを入れておく。

そこで作られたtokenをCircleCIのプロジェクトの環境変数設定で GIT_PR_RELEASE_TOKEN という名前で登録しておく。

ここで個人のpersonal access tokenを使うのが嫌な場合は、後述のmachine accountを活用すると良い。

3. .circleci/config.yml にjobを設定する

CircleCIの設定に例えば以下のようにjobを設定する。ここでは"pr-release"という名前で、jobを設定している。たった3ステップの簡単なjobである。

version: 2.1
jobs:
  build:
    ...(略)...
  pr-release:
    docker:
      - image: circleci/ruby
    steps:
      - checkout
      - run: gem install -N git-pr-release
      - run: git-pr-release --no-fetch
workflows:
  version: 2.1
  works:
    jobs:
      - build
      - pr-release:
          filters:
            branches:
              only: develop

workflowのfilters設定で、developでしか動かないように設定しているのもポイントで、これで、developが進んだときだけgit-pr-releaseが再実行されることになる。そして、git-pr-releaseは再実行してもいい感じに既存のpull requestをアップデートしてくれるのです。

ということでこれだけで、developにfeatureブランチをマージしていけばCircleCIが自動的にpr-releaseを生やしてくれるようになりました。開発者の手元にgit-pr-releaseをインストールする必要もなくなりました。めでたしめでたし。

おまけ: machine accountとTriage権限の話

個人のtokenを使うの怖いし、退職リスク等もあるので、アクセスできるrepositoryや権限を絞ったユーザーを自動化のためにオーガニゼーションに一つ作るとよいでしょう。

これは、GitHubの利用規約に、machine accountという名前で定義されています。自動化のためのアカウントを1フリーユーザー辺り1つ作ってもよく、これを複数人でメンテしても良いとされています。

A machine account is an Account set up by an individual human who accepts the Terms on behalf of the Account, provides a valid email address, and is responsible for its actions. A machine account is used exclusively for performing automated tasks. Multiple users may direct the actions of a machine account, but the owner of the Account is ultimately responsible for the machine's actions. You may maintain no more than one free machine account in addition to your free User Account.

Triage(トリアージ)権限

machine accountには必要以上の権限を与えるべきではなく、一般的にはrepositoryのRead権限のみを与えることになるでしょう。

しかし今回の、git-pr-releaseを実行させる場合、pull requestを作成しそれにラベルを付与します。しかし、ラベルの付与はRead権限のみではできません。

ここで、最近ベータで追加されたTriage権限が有用です。これはRead権限に加えて、issueやpull requestの操作が可能になっているものです。

ref. https://help.github.com/en/articles/repository-permission-levels-for-an-organization

とう言うことで、今回の場合、machineアカウントに対象repositoryへのTriage権限を付与すれば万事解決です。

ニッチな権限でありますが、このようにうまく嵌るところが見つかると面白いですね。

ちなみに、machine accountは複数のprivate repositoryにアクセスが必要なCI/CDを構築する際にも効果を発揮するのでその辺りはまた今度。

「コンテナ物語」は破壊的イノベーションと人間たちの物語だった

これは、ITエンジニアが真っ先に想起するアプリケーションコンテナではなくて「物理コンテナ」の物語です。以前、コンテナに関するイベントに登壇させていただいた際に読んでいたのですが、やっとこさエントリを書きます。

この本について

この本には、コンテナが「20世紀最大の発明」と言われるくらい、如何に革新的であったか、どのように普及していったかが書かれている。これは是非ITエンジニアに読んで欲しい。今のアプリケーションコンテナとの類似点が非常に多いからだ。原題は「The Box」であるが、日本語訳の「コンテナ物語」は僕らにとってはナイス訳だと言わざるを得ない。

コンテナが発明され、世界の船やトラック、鉄道のコンテナ運送が共通化される中で、どのような変化が起こったかについて、具体的には以下のようなことが書かれている。

マルコム・マクリーンというビジョナリー

まず、この本は裸一貫で運送会社を立ち上げたマルコム・マクリーンというビジョナリーがコンテナ輸送を提唱し、その行動力を持って普及させたことについて書かれている。

早く新事業に乗り出したくてうずうずしているマルコム・マクリーンは、なんとかアイデアを実現する方法をみつけるよう部下をせかす。

冲仲士という専門職能団

当時の技術職である沖仲士(港湾労働者)の描写も面白い。当時の沖仲士が会社へのエンゲージメントよりも横のつながりが強かったことは、2000年代のWebエンジニアを彷彿とさせる。

港湾労働の特殊性から、波止場には独特の文化が生まれた。一つの会社のために働く仲仕はまずいないから、彼らの忠誠心は仲間とともにあり、会社に義理立てする者はいなかった。自分の仕事ぶりを知っているのも、気にかけているのも、仲間だけだと男たちは考えていた。労働は苛酷で危険である。そのつらさは他人にはわからない。だから、労働者同士の団結は強かった。

大都市の他の産業と比べ、港湾荷役業では労働者階級特有のコミュニティが発達した

そんな彼らが、コンテナという破壊的イノベーションに対してどのような抵抗を示し、どのように受け入れていったかといったこともこの本には書かれている。

コンテナという「システム」

コンテナは単なる箱ではなくてシステムとなって本領を発揮した。

輸送コストの圧縮に必要なのは単に金属製の箱ではなく、貨物を扱う新しいシステムなのだ

単なる箱だけではなく、港や船、クレーン、制御ソフト、それらがあってこそ、コンテナの本領が発揮される。そこには標準化の物語があり、その中でどのような思惑の交錯があったのか、アメリカとヨーロッパでの思惑の違いについてもこの本には書かれている。

このあたりはKubernetes周りのエコシステムの発展を思い描きながら読んだ。ここでちょっと面白かったのは「コンテナ化して盗難が減った」という話。「隔離性」の重要性が物理コンテナでも在ったのだ。

隆盛と衰退

船会社はコンテナに移行するための巨額の費用を負担して青息吐息になり、ほんの一握りしか生き残れなかった

コンテナリゼーションは世界の港のパワーバランスを一変させた。コンテナ対応が早かった港が一気に成長することとなり、逆にニューヨーク港など隆盛を誇った港が衰退した。

例えば、湾の奥の港はコンテナ以前は工場の近くまで物資を運ぶために大いにメリットがあったが、コンテナ時代になると、無理して湾の奥まで行かなくても、手前の付けやすい港に停泊して、ハイウェイでコンテナを運んでしまえば良くなった。わざわざ湾の奥の港を使う必要がなくなったし、コンテナ化により、船が巨大化し、喫水の関係上、浅い港には停泊できなくなったというのもあった。

パラダイムシフトで情勢が一変したことが書かれていて、インパクトが強い。

アジャイルの萌芽

このような可能性が最初に注目されたのは、一九八〇年代初めのことだった。日本のトヨタ自動車が開発したジャストインタイム方式である

この本はアジャイルについては書かれていないが「コンテナの未来」という章でトヨタについて書かれている。

コンテナにより、輸送コストが下がり、リードタイムも短くなった。これにより、部品などの中間財の在庫を抱えずに、リアルタイムに不足を補うようになっていた。これにより、世界の物流の半分以上を中間財が占めるようになった。

これが「ジャストインタイム」方式である。コンテナによりリードタイムのボトルネックが解消されたからこそ、ジャストインタイムが生まれ、トヨタが躍進したのである。

八七年には、フォーチュン五〇〇にランクされる米企業の五分の二がジャストインタイムを採り入れている。そして採り入れた企業の大多数が、これまでとは全然ちがう輸送方式に切り替えなければだめだと気づいた

「トヨタ生産方式」は僕らアジャイル開発者にとっては必読の一冊である。口酸っぱく「作り過ぎの無駄」について書かれている。そうしないようにジャストインタイム方式が生まれ、それを生み出したものがリアルコンテナなのである。それがまたアジャイルの種になり、クラウドそしてアプリケーションコンテナに至り、インフラ調達のリードタイムを解消する革新的イノベーションにつながっていることは胸熱だと言わざるを得ない。

このエントリでだいぶ書いてしまったが、それでもこの「コンテナ物語」の面白さを損なうものではないので、ぜひ読んで欲しい。

Kibelaクライアントのkibelasyncを作った

https://github.com/Songmu/kibelasync

Natureでは、Kibelaをナレッジベースとして利用していますが、文章は書き慣れたエディタで書きたいという気持ちがあり、クライアントを作った。GraphQLの勉強にもなると思ったというのもある。

名前やコンセプトはblogsyncのオマージュです。手元にMarkdownをごそっと落としてきて、編集して更新するものです。

Install

% brew install Songmu/tap/homebrew
# or
% go get github.com/Songmu/kibelasync/cmd/kibelasync

https://github.com/Songmu/kibelasync/releases からバイナリ取得も可能です

Setup

KIBELA_TOKENKIBELA_TEAM環境変数を適宜設定してください。

Usage

記事を取得する

デフォルトでは ./notes 以下にごそっとMarkdownを取得します。これは KIBELA_DIR 環境変数や、-dir オプションで変更可能です。

また、取得時にMarkdownファイルのmtimeがその記事の最終更新日時にセットされます。

# 全件一括取得(ローカルファイルのほうが新しい場合は更新されない)
% kibelasync pull
# 全件一括取得(問答無用で全てのファイルを上書き・高速)
% kibelasync pull -full
# limit指定(更新日時が新しいものから指定件数取得)
% kibelasync pull -limit 10
# folder指定
% kibelasync pull -folder=議事録

記事を更新する

落としてきたMarkdownを編集後、そのファイルを引数に指定して、push サブコマンドを叩きます。

% kibelasync push notes/333.md

記事を作成する

サブコマンドpublishに標準入力、もしくはMarkdownファイルを引数に指定することで新規記事を作成できます。

% kibelasync publish --title=こんにちは /path/to/draft.md
% kibelasync publish --title=kibelasync
さてかきはじめるか…
^D
% echo "# こんにちは\nさようなら" | kibelasync publish

この時、何らかの形でのタイトル指定が必須です。Markdownの冒頭にMarkdownのh1要素がある場合、それがタイトルだとみなされます。

# 共同編集を有効にする
% kibelasync publish -co-edit /path/to/draft.md
# 記事投稿後、当該記事のMarkdownをサーバーから取得して保存する
% kibelasync publish -save /path/to/draft.md

-save オプションを利用した場合、元のMarkdownファイルは削除されます。

ということで

だいぶ便利だと思うのでご利用ください。開発にあたってはAPIの挙動に関してKibelaにいくつかフィードバックを送らせてもらい、爆速で対応してもらいました。ありがとうございました。

開発言語はGoですが、実装的に面白い点として、APIリミットに引っかからないように、http.Client.Transport をカスタムして過剰なリクエストを送らないように工夫しています。このあたりは、先日のOpen Go Friday in Fukuokaでお話させてもらいましたが、別記事にまとめるかも知れません。興味がある方は、client/ratelimit.go辺りの実装を見てみてください。

Go Conference'19 Summer in Fukuokaで登壇してきた

https://junkyard.song.mu/slides/gocon2019-fukuoka/#0

色々あってお声がけ頂き、登壇させてもらえることになったので、福岡に行ってきました。出張扱いで、出張費用も所属のNature Japan株式会社に出してもらいました。

話した内容は、Go Conference 2019 Springで20分で話した内容を、単なる再演にならないように内容を膨らませて40分で話した感じです。割と好評のようで良かったです。資料は口頭で説明した部分も多いので、トピックに分けて改めてブログ記事にしたいと思っています。

イベント全体を通して

スタッフの皆さまが少人数ながら的確に動いていて、何もストレスなく快適にイベントを過ごすことができました。すごく楽しかった。ビールや生ハム、スピーカーディナーも楽しませてもらいました。スポンサーの各社に感謝。

会場のFukuoka Growth Nextも小学校をリノベしたスタートアップ支援施設ということで、趣があって良かった。高島市長がいらっしゃったのはびっくりしました。市長のスピーチすごかった…。

交流とか

@k1LoW さんと初めてお話できたのが良かった。ツールを量産していることになんとなく一方的に共感を持っていて、実際、彼の発表でお話されていた「技芸のコードによるボトムアップ」という言葉には共感を感じることができた。

@pyama86さんには毎回福岡行くたびに勝手にお世話になっています。ありがとうございます。

@budougumi0617さんと話が盛り上がった。普段、東京でも交流がありますが、地方のカンファレンスで話すとなんか盛り上がったりして、そういう合宿的な非日常感は地方開催ならではというところ。

あとは、前夜に、メルカリさんの福岡オフィスにお邪魔してOpen Go Friday #5に参加させてもらったのですが、そこで期せずして@dragon3さんに二年ぶり(YAPC::Fukuoka以来!)にお会いできたのが嬉しかった。

その他福岡の皆様と色々交流させてもらいました。なんだかんだで福岡には年に一回くらい行っていて、今後も行きそうなのでまた機会でもよろしくお願いします。

bashでdotenvファイルを環境変数に読み出す

.env みたいな環境変数設定ファイルを読み込んでから指定プログラムをexecするみたいなラッパーが欲しくなる事あると思います。

Goだとgithub.com/joho/godotenvとかあるけど、Goでやるほどでもないよねーという感じだったので、bashで書くなどした。

#!/bin/bash
set -e
if [[ "$#" = "0" ]]; then
    echo "usage: env-wrap.sh cmd [args...]" >&2
    exit 1
fi

# declare -x を引数無しで呼び出して、現状の環境変数をexportableな形式で書き出す
orig_env="$(declare -x)"

envfile=.env

# allexportは`KEY=VALUE`をシェル変数じゃなくて、環境変数としてexportする危険なオプション
set -o allexport
source $envfile
set +o allexport

# 元の環境変数を優先するために書き戻す
eval "$orig_env"

exec "$@"

declare -xset -o allexport とかがポイントです。

bashやzshでしか動かないので、それ以外の環境で動かさないようにお気をつけください。

bashで配列の各要素を適切にクオートする

シェルスクリプトでラッパーを書くときに、exec "$@" とかよくやると思います。$@は特殊な変数で、クオートすることによって、配列の「各要素」が適切にクオートされて関数などに渡される。正確に言うとクオートされるわけではないのですが、要素に空白が含まれていてもばらばらにならないということです。

この振る舞いを普通の配列で実現するにはどうすればいいのか。これは、"$array[@]" のように添字に@を指定してやれば良い。これは配列が存在するbash限定の話です。

Shell Parameter Expansion に色々書いてあって学びがあるので読むとよいです。

certbotを使ってサイトをhttps化した

6月5日から変わっています。wwwも付いたり付かなかったりだったのを付いてない方に統一しました。

アーカイブ 見ると、徐々にはてブが移行されているっぽくて面白い。

令和にもなったし、301を返していれば、はてブも統合されるようになったので、流石に充電期間中httpsにするかーと思っていた。

今どきのオシャレな方法で実現しようかとも思ったが、結局時間が取れなかったので、今のVPSのNginxからRijiで生成した静的ファイルを配信する方式を維持したまま、certbotでぱぱっとやってしまった。非常に簡単だった。同様の事例はたくさんあるが、メモがてらログを残しておく。

環境構築

リポジトリをcloneするだけ。

% git clone https://github.com/certbot/certbot.git
% cd certbot
% ./certbot-auto ...

以降、certbot-auto というコマンドを使って各種操作をおこなうことになりますが、こいつを叩くと、追加依存のインストールや、自動更新、sudoでの実行など諸々よしなにやってくれる。ツールの特性上、自動更新がちゃんとされるのは安心。ただ、いろいろ頑張っているからか、起動はかなり遅く、もっさりしている。致し方ないか。

証明書の発行

以下のようなコマンド実行するだけ。今回はNginxが既に実稼働しているサーバーなので、そのwebrootを指定している。

./certbot-auto certonly --webroot \
  --webroot-path /home/Songmu/htdocs \
  --domain songmu.jp \
  --email y.songmu@gmail.com \
  --agree-tos -n

/etc/letsencrypt 配下に証明書や諸々が書き込まれる。

サーバー設定

/etc/letsencrypt/live/ドメイン 以下に証明書が配置されるので、Nginxであれば以下のように書いてやれば良い。

server {
    listen 443 ssl;
    ssl_certificate     /etc/letsencrypt/live/songmu.jp/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/songmu.jp/privkey.pem;
    server_name  songmu.jp;

証明書の更新

これも非常に簡単で、以下のコマンドを実行すれば良い。

./certbot-auto renew --post-hook 'sudo service nginx reload'

特にドメインの指定などが必要ないのは、/etc/letsencrypt/renewal 以下に /etc/letsencrypt/renewal/songmu.jp.conf のような設定ファイルが書き込まれているため。

ドメイン期限が1ヶ月以内に迫っているときだけ更新をしてくれる親切仕様になっている。また、--post-hook は証明書が更新された時のみ実行される便利フック設定。ここではNginxのリロードを指定している。 certbot-auto renew && sudo service nginx reload などとしてしまうと証明書が更新されてなくても毎回リロードかかってしまうので、ちょっと困る。

上記のコマンドは、実行しても証明書を発行したばかりの時はスキップされるので、更新動作を確認したい場合は、--force-renewalを指定して動作確認をしてみると良いでしょう。ただ、--force-renewal はLet's Encryptのサーバーへの負荷の観点もあり、普段は使わないほうが良いオプションです。

更新の自動化

cronを適当に仕込んでおけばよいが、certbot-autoもNginxのリロードもsudoが必要で、cronでsudoを使えるようにするのは大変。つまり、sudoersのrequirettyのユーザー設定と、パスワード無しでsudoができるコマンドを指定するなどが必要。

めんどい上にセキュリティを緩めることにもなるので、それは避けて普通にrootのcronで動かすようにしてしまった。

# /etc/cron.d/certbot-renew
37 18 * * 5 root /usr/bin/mkr wrap -n certbot-renew -- /home/Songmu/certbot/certbot-auto renew --post-hook '/sbin/service nginx reload'

ちゃんと動くか少し不安なので、mkr wrap を使ってMackerel監視するようにした。便利。

これも、Let's Encrypt側のサーバー負荷の観点から、実行時間を散らすためにランダムスリープなどを入れることが望ましいとされています。実際Debianでパッケージインストールした場合は、 perl -e 'sleep int(rand(3600))' && certbot -q renew というようなcron設定がなされるようです。Perlが使われていてウケる。

それをやっても良いのですが、日次じゃなくて、週次(5なので毎週金曜日)で動かすようにしたので、まあそれでいいでしょう、ということで。

Nature Remo作ってる会社のCTOになったのでみんな買ってくれよな!

6月1日付けでNature Japan株式会社の取締役CTOに就任しました。最初の営業日の6/3(月)からいきなり台湾出張に行ってきました。良いスタートアップ感。ついでに本日6月5日に39歳になりました。新たなチャレンジにワクワクしています。

大塚(@maaash)さん、村瀬(@typester)さんに続く3代目のCTOとなります。2人はカヤック時代の同僚でもありますが、カヤックのラボチームのダブルエースだった彼らの後任としてCTOをやるのは恐れ多いのですが、僕は組織づくりなど含めて僕なりに組織に貢献していきます。

当社はおかげさまでスマートリモコンのNature Remoが好調で、現在はNature Remo Eというスマートエネルギーハブの開発を進めているところです。今後は電力なども見据えて事業を展開していく計画で面白いフェーズにあります。

まだ、社員全員でも10人に満たない小さな会社ですが、これからより成長させて、エンジニアも採用していきたいので、興味のある人は是非連絡ください。オフィスは今は恵比寿です。近くにお立ち寄りの際は、ぜひ遊びに来てください。

こちらからもお声がけなどさせていただくこともあると思いますがよろしくおねがいします。

技術スタック

こんな感じです。インフラからクライアント、組み込みまでまだまだエンジニアに来て欲しい状況です。Cでファームウェアを書くとか僕も全然やったことありませんが、そういう新しいチャレンジをしてみたいという人も歓迎です。

React Nativeに関しては@typesterと@soh335がでている以下のインタビュー記事があります。

React NativeでiOS/Androidアプリを丸っと開発! Nature Remo開発で分かった長所と短所

転職理由とか

以下は個人的な話。

typesterに請われたこと

転職を決めたのは、尊敬しているtypesterさんに熱烈に請われたというのが一番大きな理由です。typesterとはカヤック時代の同僚であり、360度評価で彼に書いてもらった評価文言は今でも大事に保存しています。

rebuild.fmを聞いている方はご存知かも知れませんが、typesterがアメリカに移住するため、その後任のCTOが必要な状況であり、そこで彼に「Songmuが一番良い」と白羽の矢を立てていただきました。

今年の年末年始休暇の際にtypesterから話をもらい、CEOの塩出とも話をさせてもらって、かなり迷ったのですが新しい道に進むことにしました。

「僕が断ったら誰に声かけるつもりだったんですか?」と後で聞いたら、ビッグネームがいろいろ出てきて、それより評価していただいていたのは光栄でした。僕はtypesterの技術を含めた審美眼は信用していて(多くの人が注目する前からNode.jsやRedisやGoやRustを良いと言っていた…!)、その彼が僕にそういう評価を下してくれていたのは非常に嬉しかった。

冒頭でも書きましたが、maaashさん、typesterさんの次のCTOをできるのは非常に光栄なことです。彼らはカヤック時代、僕のソフトウェアシステムアーキテクトの師匠とも言える存在でした。僕がモノリシックなWebアプリケーションの作り方しか知らなかった頃に、彼らが必要に応じて独自デーモンをいくつも作ってシステムを組み上げていく姿には衝撃を受けました。

まあその後の運用が大変になったりもするのですが、そこも含めて彼らが携わったシステムを現職で引き継げることは楽しみに思っています。

IoTハードウェアを作るということ

元々Nature Remo自体は便利に使ってはいたのですが、技術領域として、ハードウェアやIotにはそれほど興味はありませんでした。電子工作とかをするわけでもないので。だからこそ、逆に、こういう未知の領域でチャレンジできるチャンスが舞い込んできたのは面白いと考えました。

情熱があって何かを始める人なんて少なくて、普通は何気なく始めたことに無意識のうちにのめり込んで、そこから情熱が生まれる

岡本太郎のこの言葉が好きで、なんでも前向きに、主体的に取り組んでみたら面白くなるものです。Mackerelも最初は正直そこまで興味があるわけではなかったのだけど、やってみたらめちゃくちゃのめり込んだ。現職でもそういう体験をしたいと思っています。

今も、ECHONET LiteWi-SUNといった全然知らなかったプロトコルや規格の話が出てきて大喜びしています。

ハードウェアを含めた生産を如何にアジャイル的にやるかみたいなところにも興味があり、トライしていきます。

強力なプロダクトオーナー

前職では長らく僕自身がプロダクトオーナーをしていて、それはそれで面白かったのですが、個人的には強烈な個性を持つプロダクトオーナーと一緒にやるのも結構好きというのもあります。

CEOの塩出は個性的なビジョンを持っている人で、まだ若く、頭の回転も速いので、一緒にやっていくのはかなり面白そうだと思っています。

リスクテイク

誘われたとき、正直、生活水準の維持が頭をよぎりました。

はてなで働く中で、子供が2人でき、マンションも購入し、生きていく上で考慮すべき事項が増えました。そして、はてなのエンジニアの中でトップクラスに給与をもらっていましたし、フリーランチもあるので働くには恵まれた状況でした。

だから逆にその環境を捨てるのには躊躇してしまう状況でもありました。今回の話を受け、そういう自分に気づき、身軽さを失っていることに危機感を覚えました。まだギリギリリスクテイクできるだろうということで、妻とも相談し、新しいチャレンジをすることを決めたということもあります。

よく考えてみると、こんなチャンスはなかなかなく、これまでエンジニアとして実績を積み上げてきてよかったとも感じています。

個人的には、ベンチャーの多くのことが決まっていないカオス感が好きです。とはいえこの規模の人数のどベンチャーともなると初めてなので、その中で自分が経営者としてどう振る舞えるか、成長できるかというところには自分のことながら関心を持っています。

ということで、皆様Natureをよろしくお願いいたします。

認定スクラムマスターになりました

https://www.scrumalliance.org/community/profile/mmatsuki2

アトラクタ社の認定スクラムマスター研修を受け、テストも合格し、晴れて認定スクラムマスターとなりました。だからなんだというわけでもないですが、スクラムに関する交流や雑談などしたいとかあれば、ご相談ください。

受けたのは以下の研修で、Gabrielle Benefieldさんと原田騎郎さんが講師でした。

比較的長年アジャイルやスクラムに関わってきたので、良い知識の再整理の機会になりました。ありがとうございました。

私とスクラム

意外かもしれませんが、僕はそれなりにアジャイルやスクラムを経験してきました。とはいえ、今の開発者が押さえておくべき技術分野の一つなので、人並みくらいかもしれません。Mackerelチームでのスクラムを取り入れており、2年弱スクラムマスターを、3年弱プロダクトオーナーを経験してきました。アンチパターンであるPO, SM兼務の経験もしました。

僕とスクラムの出会いは、2012年の頭です。当時のカヤックのソーシャルゲームチームに、あの@ryuzeeさんがコンサルで入っており、そこでいろいろ教わりました。そこでアハ体験があり、その後はアジャイルやスクラムに興味を持ち積極的に考え方なども取り入れるようになったのです。

変化に強くなりましょう、自律的なチームでありましょう、っていうところが特にスクラムの好きなところ。

その後、ryuzeeさんとは継続的に交流させてもらっていますが、その中で彼ほどのスクラムコーチはなかなかいないという実感も強くなりました。一番最初に一番良い人にスクラムを教わったので運が良かった。

研修を受けた訳

それなりにスクラムを自己流で経験してきたので、改めて知識の再確認と振り返りや、トレンドやアップデートのキャッチアップなどのためというのが主。

また、長年プロダクトオーナーをやってきましたが、次の会社ではPOは別にいて、開発体制の整備なども含めてやることになりそうなので、スクラムマスターの研修が良いかなとも思ったというところ。

5月は実質無職だったので、学生の夏休みみたいに何も成果を出せないで浪費してしまうことも懸念されたので、そこは自腹を切って研修を受けて、認定スクラムマスターになるという成果くらいは出すか、という思いもありました。

あと、daiksyさんが最近研修を受けて良かったと言っていたのも後押しになりました。

研修について

参加40人の中で、5年以上スクラム経験ある人が僕含めて3人くらい。Web系よりは、スクラムを最近聞いたとか取り入れたとか、比較的堅めの業界の人も多くて、スクラムの広まりを感じた。いろいろな業界な人が入る分議論が盛り上がって面白かった。

講義の進め方もユニークで、それほど資料は使わず、GabrielleさんがiPadに図や絵を書いて、それをプロジェクターで映しながら講義し、それにワークショップやQ&Aを挟むスタイルで、groove感があって良かった。daiskyさんから聞いていた彼が受けた研修の様子とは結構違いそうだったので講師によってスタイルの違いがあるのだなーと思った。

研修で面白かったところ。

outputよりoutcome

これは再三言われていた。機能をリリースした数ではなく、リリースした機能がどういう効果をもたらしたかが大事、ということ。ベロシティを追い求めすぎると、output過多になってしまい作り過ぎの無駄を背負い込むことにもなるので注意。ベロシティは将来を予測するためのもので、過去をトラッキングするものでもないし、スコアとして追い求めるものでもない。

プロダクトオーナーを複数人が務めるのは有り有りや無しや

これはスクラム専門家の間でも議論がある。基本的には一つのスクラムチームで一人がいいのではないか。ちなみに、顧客がプロダクトオーナーをやるのは無理だと考えたほうが良い。顧客はステークホルダーである。

スクラムマスターはチームにスクラムのプラクティスを遂行させる

思っていたよりも役割としてそれをしっかりやることがスクラムのフレームワークでは求められてるのだなぁということを感じた。ただ、スクラムマスターが権威的になってもいけないというのも同時に言われていて難しいですね、ってなった。「考えさせることが大事」とも。

最近はDoneは「完了」じゃなくて「完成」と訳すようになった

「完了」だと何にせよ終わっていれば良いというニュアンスになってしまうため「完成」の方が適訳。プロダクトバックログがちゃんと出荷可能状態で「完成」しているか。

最適なプロダクトバックログの見本を見せるのは難しい

チームによる。「スクラムチームが経験を積むと、バックログは雑になってくることも」という話もあって、わかるーと思いつつもそれを言い訳にするのは良くないなとも思った。

スプリントゼロについて

スプリントを回し始める前の準備期間を便宜上スプリントゼロと呼ぶ人がいる。これはスクラム公式の用語ではないことに注意。これも流派はあるが、講師の原田さんとしてはインクリメントがないのにそれをスプリントと呼称するのは違和感があるのでスプリントゼロという言葉は使わない方が良いという立場。

ただ、スプリントを回し始める前に準備をしっかりやったほうがその後が速いのが確かで、2スプリント期間を超えない範囲で準備期間を設けるのはアリ。

余談だが、デザインスプリントも混同されやすい言葉だが、これもスクラムのスプリントとは関係ないプロトタイピング手法なので注意。

使われてない機能は削る。そのために計測する。ドキュメントも同様

なかなかできないけどそうだよな、という感じ。面白かったのはドキュメントの閲覧数を見ると良いという話で、確かに見られていないドキュメントは消すなり、再確認するなりしたほうが良さそう

ハードウェア開発とスクラム

短いスプリント期間が切りづらく、リードタイムが長いものに対してどうするのか、という話。これもいろいろ実例があるけど、テストハーネスとシミュレーターを作り込んでそこでイテレーションを回すのが大事、という話だった。おっしゃる通りだけど、大変そうだな、とも思った。

医療の世界とスクラム

多くの事例が出てたけど、医療や製薬みたいなクリティカルな世界でも欧米ではかなりスクラム化が進んでいるようで驚いた。「多くの実験や検証が必要なのだから、スクラム的にやらないと無理だ」などとも言われていて、確かにおっしゃる通りだけど、なにか怖さを感じてしまう。これは僕のマインドチェンジが足りてないんだろうなー。

このあたりのマインドの話は他の参加者とも温度差を感じるところはあった。「納品したら別のチームが運用を引き継ぐ」「開発とインフラは別」みたいな前提からなかなか抜けられない人もいるようにも。

このあたりのスクラムに対する理解度により、それをどこまでの領域で適用できるかというところにも関わってくるのだろうと感じた。「チームでフルスタックになる」という言葉も講義で度々出てきて、そのとおりだと思った。