<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
        <title><![CDATA[the world as code]]></title>
        <description><![CDATA[the world as code]]></description>
        <link>https://chroju.dev</link>
        <generator>RSS for Node</generator>
        <lastBuildDate>Fri, 17 Apr 2026 01:38:51 GMT</lastBuildDate>
        <atom:link href="https://chroju.dev/feed.xml" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Workflowyにすばやくメモを書き入れるためのアプリをPWAで作った]]></title>
            <description><![CDATA[<p>https://github.com/chroju/jotflowy</p>
<p><a href="https://workflowy.com/">Workflowy</a> というアウトライナー（階層型メモアプリ）を長らく愛用しているものの、メモを書き入れるときのスピードと柔軟性に欠けるなあ、という気持ちが常々あり、非公式APIを利用した <a href="https://github.com/cjlm/send-to-workflowy">send-to-workflowy</a> を使ったりしていたのだが、昨年（2025年）から <a href="https://beta.workflowy.com/api-reference/">公式でもAPIが登場した</a> ので、Jotflowyという自分のためだけのアプリを作ってみた。</p>
<p>実装としては <a href="https://hono.dev/">Hono</a> とCloudflare Workersを使っている。Worker側では、ほぼWorkflowy APIとの中継部分だけを担当しており、データの保存などは特に行っておらず、ほぼフロント側に寄せている。APIキーは初回セットアップの際にWorker側で暗号化を施し、その後はCookieを通じて暗号化されたキーをやり取りするようにしている。こういった仕組みなので、誰にでもオープンな形で使ってもらうことは想定しておらず、使いたい場合にはセルフホストを推奨としている。変な使い方をしなければ、Cloudflareの無料枠範囲内で動かせるようになっている。</p>
<h2>機能について</h2>
<p><img src="/images/2026-02-15/jotflowy_settings.png" alt=""></p>
<p>基本的にはsend-to-workflowyを始めとしたこの手のツールでよくあるような、メモを送信すると、ある階層（Node）の配下に新たなNodeを作成する、という挙動をするが、もろもろ自分好みの機能を詰め込んでいる。</p>
<h3>送信先のNodeはインタラクティブに選択できる</h3>
<p><img src="/images/2026-02-15/jotflowy_destination_select.png" alt=""></p>
<p>APIでメモを送る（Nodeを作る）ときには、どのNodeの配下に送るか、送信先NodeのIDが必要になるのだが、このアプリではNodeの一覧をUI上で表示して、どこを送信先として指定するかインタラクティブに選べるようにした。類似のツールだと、ソースコードを覗いたりしてIDを自ら調べて持ってこなければならないものが多く、それはちょっと面倒だったのと、せっかく <code>List Nodes</code> APIがあるので使うことにした。</p>
<p>送信先Nodeは複数の場所をJotflowy上に保存しておいて、メモを送信するときにどのNodeへ送信するか都度選べるようにもしている。</p>
<h3>デイリーノートの自動作成</h3>
<p>送信先Nodeを保存する際、デイリーノートとして扱うかどうかを選べるようにしている。この機能をonにすると、当該Node配下にその日の日付のNodeを作り（すでに存在する場合はそれを使う）、その下にメモを送信するようになる。</p>
<pre><code class="language-bash">送信先Node
 └ New node # &#x3C;-- 普通はここに送られるが

送信先Node
 └ 2026-02-15
    └ New node # &#x3C;-- デイリーノート機能をonにすると、ここに送られる
</code></pre>
<p>なお、Workflowyには <a href="https://workflowy.com/learn/calendar/">Calendar</a> という、デイリーノート機能がすでに備わっており、アプリで「Today」ボタンを押すと指定したNode配下に自動でその日の日付が作られるようになっている。一応、これと連動を取るように実装していて、Calendarとして使っているNodeを送信先として指定すると、アプリ側で作る日付Nodeとバッティングせず共存ができるようになっている。ただし、Calendar配下に日付Nodeを直接作成するよう設定されている場合に限る（Calendarでは年月日の階層を作ることも可能だが、階層がある場合には非対応）、Jotflowyから新しい日付Nodeを作成した際は、Calendarに取り込むにあたってWorkflowy上で一手間必要（<a href="https://workflowy.com/learn/calendar/#migrate-your-existing-calendar">Calendar - Workflowy support</a>）、といった制約はある。</p>
<h3>PWAとWeb Share Target APIへの対応</h3>
<p>PWAとしてインストールし、スタンドアローンなアプリとして使える。</p>
<p>PWA化した大きな理由に <a href="https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Manifest/Reference/share_target">Web Share Target API</a> に対応させたかった点がある。これに対応することで、いわゆる他のアプリから「共有」する操作の対象になることができる。ブラウザでウェブページを読んでいるときに、そのページについてメモしたい、といった場面が結構多いので、これは個人的にmustだった。</p>
<p><img src="/images/2026-02-15/jotflowy_web_share_target.jpg" alt=""></p>
<h3>送信したメモの「履歴」が見られる</h3>
<p>「履歴」が見られる……と書いたが正確には履歴ではなくて、送信先として選んでいるNodeに対して <code>List Nodes</code> APIを実行して、直下にあるNodeの一覧を取得、表示できるようになっている。その時点でのWorkflowy上の最新状態を取得するから、送信後に別途削除、変更したNodeは見られないわけで、正確には「履歴」ではない。</p>
<p><img src="/images/2026-02-15/jotflowy_history.png" alt=""></p>
<p>デイリーノート機能を有効にしている送信先の場合は、日付ごとに区切った形でメモが表示されるようにもなっている。深く考えずに作ったが、このUIがわりとTwitterのような感じがあって見やすくて良いな、と思ったりしている。</p>
<h3>その他の機能</h3>
<p>他にも細々とした機能を備えている。</p>
<ul>
<li>URLを送信した際はtitleの自動取得が行われ、リンク形式で記述される</li>
<li>template機能を使って特定文字列を常に付与できる
<ul>
<li>例えば現在時刻を埋め込むようなtemplateを設定して、「起床」と送るとWorkflowyには「07:02 - 起床」と書き込まれる、みたいな感じ</li>
</ul>
</li>
<li>空行を間に挟んだメモを送ると、空行以降はWorkflowyのNoteとして扱われる</li>
</ul>
<p>コーディングにはClaude Codeをかなり活用しており、こういう自分のための開発をやりやすくなったなぁ、と実感する良い機会だった。実は昨年の夏ぐらいに一度何日かかけて作ったことがあったのだが、当時はなかなか思い通りにいかない部分があり、頓挫していた。やり直したい気持ちはずっとあったので、軽い気持ちでOpus 4.6を使ってゼロから作り直したところ、粗削りではあるものの、1日でそれなりに動くものが出来てちょっと驚いている。AIの進歩もあると思うし、最初の構築を通じて要件が固められたのもあると思う。</p>
<h2>余談：Workflowyと自分がメモに求めること</h2>
<p>ここからはWorkflowyとメモというものに関して、自分がどういった考え方をしていてこのアプリを作るに至ったかを書く、完全なる蛇足。</p>
<p>send-to-workflowyのほかにも <a href="https://www.nap.jp/michi/ios/MemoFlowy/memoflowy-ja.html">MemoFlowy</a> など、「Workflowyに手早くメモを送る」という需要は自分だけが持っていたものではなく、従来から結構広く存在していると認識しているのだが、だいたい以下の2点が理由だと思っている。</p>
<ul>
<li>Workflowyのモバイルアプリは起動に数秒かかる</li>
<li>起動した後で、メモしたいNodeへ移動するのにもちょっと手間がある</li>
</ul>
<p>近年このあたりは解消しつつあって、起動時間については1秒以下に収まるようになってきた。また「手早くメモを送る」という用途に対しても、そのための <a href="https://blog.workflowy.com/update-2026-02/">Quick Add</a> という機能がAndroid版に搭載された（iOS版は把握していないが、おそらく未リリース）。</p>
<p>そういった状況ではあるのだが、今回のアプリに搭載したような細かなカスタマイズをやりたかったのと、メモをしたためるときには、ある程度の没入感を持てるUIが欲しいのもあり、自分で独自に作るに至った。</p>
<p>メモを書くことと読むことを切り離したいという欲求が自分にはある。Workflowyの画面で過去に書いたメモがたくさん並んでいるところに、追記するように新たなメモを書くよりも、まっさらな画面で没入して書いて投げ込みたいという気持ちが強い。書くときに、まったく関係ない別の言葉が並んでいるとどうにも気が削がれてしまうところがある。なので集中して何かを書きたいときは、ポメラで新しいファイルを作ったり、macOSでは <a href="https://stone-type.jp/">stone</a> という、集中して書くことに特化したアプリを立ち上げることが多い。これはもう完全に自分の性分だと思う。ただ、一度書いたあとのメモを過去のメモと組み合わせながら考えを進めるのは好きなので、Workflowyというアプリ自体は性に合っている。思いついたときに付箋を1枚剥がしてメモを書いておいて、あとで書いた付箋を集めて全部机の上に並べてこね繰り回すような、そういう感覚に近いものを求めているのだと思う。</p>
<p>そういった個人の、言うなればどうでもいいようなこだわりをスッと形にできるのは非常に体験がいい。AIによるCodingが全盛となっていくタイミングで、Workflowyが十数年来初めてAPIの公開に踏み切った、というのもとても良いタイミングでありがたかった。</p>
]]></description>
            <link>https://chroju.dev/blog/jotflowy_workflowy_jotting_down_pwa_with_ai_coding</link>
            <guid isPermaLink="false">jotflowy_workflowy_jotting_down_pwa_with_ai_coding</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 14 Feb 2026 09:16:09 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[2026年年頭時点におけるSRE EMの立場からのAI雑感]]></title>
            <description><![CDATA[<p>昨年全然ブログを書かないまま終わってしまったが、AIに関する動向も目まぐるしいなかで、今時点の考えとかを都度書き留めておいたいいかなと思ったので、この年末年始という時期に一旦自分用の覚え書きがてら書いておく。</p>
<p>つらつらと思いつくまま書いているので長いし、何かの役に立つみたいな内容ではないです。あと、話の展開上チームやらマネジメントやらという言葉が出てきますが、ここは個人ブログなので、あくまで個人としての見解です。</p>
<h2>現時点でのAI利用状況</h2>
<ul>
<li>正直、エンジニアリング業よりマネージャー業の方が割合高いので、コーディングエージェントをバリバリ使えているとは言い難い
<ul>
<li>ただ、マネージャー業にコーディングエージェントを使ったりもしている</li>
<li>昨年からSREとして副業を始めてもおり、そちらでエンジニアリング機会も得たりはしている</li>
<li>エンジニアリングで意識的に使わないとマズいなという感覚がヒシヒシとある</li>
</ul>
</li>
<li>主に使っているのはClaude CodeとGemini</li>
<li>Claude Codeがメイン
<ul>
<li>法人契約のものと、副業等のために個人契約のProの2つを持っている</li>
<li>コーディング用途でもマネージャー業でもほぼこれを使っている</li>
<li>CLIでの利用がほとんどなのだが、Claude Code Webやin Excelなども興味はあるし活用できたらしていきたい
<ul>
<li>WebはDevinのように複数人で共有するような使い方やSlackとのIntegrationが充実してくると良いのだが……</li>
</ul>
</li>
</ul>
</li>
<li>Geminiがサブ
<ul>
<li>家族で使いたいこともあり、Google AI Proを契約して家族共有で使っている</li>
<li>単純にチャットでAIと話したいときはGeminiを使うことが多いが、特に大きな理由はない
<ul>
<li>Claudeと双方に同じ話題を投げることもあるが、どちらかと言えばGeminiのほうがちょっとお節介で求めてないことまでやろうとする印象はある</li>
</ul>
</li>
<li>あとはNotebookLMはだいぶ活用している</li>
<li>Gemini CLIはGoogle CloudのCloud Shellでだけ使っているけど、あれは超便利</li>
</ul>
</li>
<li>その他
<ul>
<li>ChatGPTはPay as you goで使っている
<ul>
<li>Readwise Reader（RSSリーダー）で記事の自動翻訳などをするのにAIのAPIキーを使いたいのだが、ChatGPTにしか対応していないので</li>
</ul>
</li>
<li>先月ぐらいからOpenCodeも触り始めているが、まだ全然
<ul>
<li>ツールとLLMのモデルが密結合しない方向性は歓迎したいので、そういったツールが出ては目配せしてはいる</li>
</ul>
</li>
<li>他、Cursor、Roo、Aider、Devinなど使ってきたがいずれも触らなくなってしまった</li>
</ul>
</li>
</ul>
<h2>SREのコーディング作業とAIによる効率化</h2>
<ul>
<li>いわゆるプログラミング言語を書くのに比べると、コーディングエージェントからSREが受けられる恩恵は限定的じゃない？みたいな気持ちが少しある
<ul>
<li>例えばTerraformに関して言えば
<ul>
<li>HCL（Terraform）はGitHub上のレポジトリ数がPythonやTypeScriptなどと比べて圧倒的に少なく、AIの学習はそれら言語よりは進んでいない</li>
<li>IaCのように宣言的な記述においては、アルゴリズムを書くときのような複雑性や課題内在性負荷は生じづらい</li>
<li>HCLの書き方、対象パブリッククラウドの知識、Terraform providerの知識、社内のドメイン知識と多方面に整合せねばならない上、テスト駆動なども発達していないので、手戻りは多くなる感覚がある</li>
<li>ここまでに書いた内容はKubernetes manifestなどでも同様に当てはまると思うが、いずれにせよ仮説でありちゃんと検証したわけではないし、そういった調査結果なども見つけられてはいない</li>
</ul>
</li>
</ul>
</li>
<li>一方では信頼性改善のためにアプリケーション側のコードを読み、当たりをつける、といった作業では抜群に役立つ
<ul>
<li>SREは職能やプロダクトを越境して行く役割が強いので、こういう恩恵は大きい</li>
<li>逆も然りで他職能の方がSREing的なことをするときにも役立つわけで、 <a href="https://martinfowler.com/articles/frictionless-foreword.html">Friction</a> を取り除くという方向性で考えていくと良さそうに思っている</li>
</ul>
</li>
<li>副次的な効果としては、AI向けのナレッジを整備するなかでチーム内で形式知化が進むよね、というのもある</li>
<li>結局のところ、よく言われる「ボトルネックが移動した」感覚であり、これまでとは時間と労力をかける対象が変わった、のが現状かなぁ、と思っている
<ul>
<li><a href="https://www.catchpoint.com/learn/sre-report-2025">The SRE Report 2025 | Highlighting Critical Reliability Trends</a> のように、AI活用が進んでもトイルは減っていないという調査結果も読んだけど、これはもう少し長期で調査結果が出てこないと判断が難しい</li>
</ul>
</li>
</ul>
<h2>マルチタスク前提の時代になってしまった</h2>
<ul>
<li>シングルタスクに集中して如何にフローに入るか？というのが個人の生産効率の上ではベストだったはずなのに、気付けばみんな <code>git worktree</code> で並列開発している</li>
<li>この方向性が正しいのかよくわからないけれど、今のところ「そりゃこうなるよな」という感覚ではある</li>
<li>マルチタスクを前提として
<ul>
<li>自分のタスクをもっと細切れに分解していかなければならない</li>
<li>あるタスクに集中するのではなく、一歩引いたところから複数のタスクを俯瞰するような形へ転換しなきゃな〜〜というマインドチェンジには結構苦労している</li>
<li>一方で「これで本当に幸せか？」ってのも考えたいんだけど、それは哲学とかの仕事かもしれない</li>
</ul>
</li>
</ul>
<h2>AIの活用と信頼性制御</h2>
<ul>
<li>AIを「使う」のではなく、自社内でAIが「使われている」場面に対してもSREの関心というのがあり</li>
<li>1つはプロダクトに組み込まれて使われる場面
<ul>
<li>AIが介在する機能は、そうではない機能に比べてレイテンシに対するユーザーの期待値が下がっているはずで、信頼性の考え方も変わってくる</li>
<li>ここの信頼性をどう捉えて扱って行くのかは結構難題ではと思っているけれど、まだ案外そういう話をそこまで見かけない気がしている</li>
</ul>
</li>
<li>もう1つは開発用途で使われる場面
<ul>
<li>こちらはどちらかと言えば信頼性というよりはセキュリティとコンプライアンスの関心だと思うし、すでにいろいろな方が書いているので割愛</li>
</ul>
</li>
</ul>
<h2>AIを前提として組織も職能も変化していく</h2>
<ul>
<li>先述したように、AIが職能やチーム間のFrictionを排除する方向へ促すのであれば、組織の構成や職種の考え方も変化するはずでは、というのが多分今一番の関心</li>
<li>例えばインシデント発生の際にトリアージを行うAI Agentを作るとして、そこにはSRE、セキュリティ、あるいは品質など様々な観点からナレッジを詰め込む必要がある
<ul>
<li>各職能チームが独自にEnablingをやるのではなく、互いに連携しながら業務フロー全体のFrictionをどう抑えて行くか？と考える必要が以前より増してきているのではないか</li>
</ul>
</li>
<li>チームトポロジーも考え方変わりません？って思っている
<ul>
<li>Enablingを直接人間に対して行うんじゃなくて、Agent Skillsを充実させたほうがいいよね、とか
<ul>
<li>完全にEnablingが不要になるという話ではなく、ストリームアラインドチームが機能するのに必ずしも「チームとして」能力を持つ必要がなくなってくるよね、という話</li>
</ul>
</li>
</ul>
</li>
<li>個々の開発者が自らの業務をAIに支援させる、というCopilot的な方向から、ある業務全体をAIが丸ごと担って複数人と協業するAgenticな方向へ変わって行くはず
<ul>
<li>そういう世界観になったとき、現在の職能や組織構成はそのまま通用するのか？</li>
<li>広くワークフローを見渡してドラスティックに手を入れて行く考え方が必要ではないか</li>
</ul>
</li>
<li>一方でこういった動きは専門職の消失を意味するわけではない、とも思う
<ul>
<li>パブリッククラウドが隆盛したときに「インフラエンジニアは死ぬ」と散々言われたが結局死ななかったように、隠蔽・抽象化された領域に対する専門性が、エンジニア組織から完全に不要となるわけではない</li>
<li>Agent Skillsが日常的な業務は代替してくれるとして、Skillsをメンテナンスする専門職は結局要る</li>
<li>騒がれているほどには「AIが職を奪う」とは考えていないのだけど、これは自分がマネジメントに軸足を移している故という可能性もある</li>
</ul>
</li>
</ul>
<h2>今年はどうしようか</h2>
<ul>
<li>LLMのことをもっと理解しないといけないなと思うので、今年はそのあたりをインプットのメインにしたい
<ul>
<li>せっかく通信制大学で基礎的な数学やAIの講義も受けたので、このあたりの知識が揮発しきらないうちに積み重ねを進めたい</li>
<li>トレンドとしてすぐ廃れるようなものとは思えないし、原理を知識として押さえたほうが長期的な利が大きそう</li>
</ul>
</li>
<li>AIを業務と組織の中心に置けるようにしていきたい
<ul>
<li>価値提供の高速化と安定のために必要な活動は変化してきている</li>
<li>AIでやれないか、AIをどう組み込むかを大前提として考えていかないとなかなか変化を起こせないなぁ、とこの1年を通して思っている</li>
<li>自分自身の業務に対してやれることもあるし、マネージャーとしてやれることもまだまだある</li>
</ul>
</li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/my_life_with_ai_2025</link>
            <guid isPermaLink="false">my_life_with_ai_2025</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 04 Jan 2026 14:19:23 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Notion Mailでメールをトリアージしている]]></title>
            <description><![CDATA[<p>最近、Notionが「 <a href="https://mail.notion.so/">Notion Mail</a> 」という、Gmail用のメールクライアント（Web appとiOS appがある）を出しているのだが、これがわりと良くて日常的に使っている。ざっくり言ってしまえば、Notionのデータベース機能の要領でメールを整理できるアプリと言う感覚に近く、表示するメールのフィルタ条件が異なる複数のViewを作ったり、メールに新たなプロパティをメタ情報として追加したりと言ったことができる。</p>
<p>効率的なメール処理を目指したクライアントアプリは他にもあるが、Notion MailのUI/UXは比較的独自性が強く感じる。そのわりに <a href="https://www.notion.com/ja/help/category/notion-mail">公式Help</a> を見ても個々の機能説明しかなく、どういった使い方をすると便利なのか、設計思想やワークフローが見えてこないので、何か良さそうな空気を覚えつつも、使いこなすまでに時間がかかるツールだと思っている。</p>
<p>Notion Mailの実践について書いた記事も他に見かけないので、自分なりの解を書いてみる。端的に言えば、Notion MailはInbox Zero（受信トレイのメールをトリアージして適宜分類し、受信トレイにメールがゼロの状態を保つ運用）を念頭に、以下のようなワークフローを想定したツールだと思う。</p>
<ul>
<li>AIを使って自動ラベル付与を行い、メールを効率的に分類、トリアージする</li>
<li>付与したラベルなどを使ってフィルタ条件を作成し、受信トレイには本当に見るべきメールだけを表示する（その他、必要に応じてViewを追加する）</li>
<li>日々の運用では受信トレイを中心にメールを処理し、Actionが必要なものはPriorityを付与して管理する</li>
</ul>
<h2>AIによる自動ラベル付与</h2>
<p>Notion Mailの売りのひとつがこれだと思うのだが、最初に断っておくと筆者は活用していない。いくつかのメールを選択してNotion AIに依頼すると、それらのメールと類似したメールを次から自動的に仕分けてラベル付与を行ってくれるという、いまどきのLLMになら確かに任せられそうな機能だ。</p>
<p>活用していない理由としては、AIによる分類は確実性が保証できないからだ。誤った分類が行われて、それによってメールの見逃しが発生する事態は避けたい。Gmailのオートフィルタは管理や編集が面倒なものではあるが、確実性を重視してオートフィルタによるラベル付与を採用している。また、Notionでできるのはあくまでラベル付与のみであり、Gmailのような「ラベル付与 and 既読にする」といった自動処理はできない。</p>
<p>逆に「ざっくり分類できればOK」「Gmailのオートフィルタ条件を書くのが嫌い」といった理由があれば、AI auto labelは使える機能だと思う。何度か実験はしてみたが、それなりに精度はありそうだった。</p>
<h2>本当に必要なメールだけを確認するようViewを分ける</h2>
<p>Notion MailとGmailで体験が大きく異なる点の1つが、このViewの機能だと思う。</p>
<p>Gmailでメールを表示する画面は、例えば「受信トレイ」であれば「アーカイブされていないメールを表示する」といった条件が決まっており、カスタマイズ性が高くない。 <a href="https://support.google.com/mail/answer/9694882?hl=ja">マルチ受信トレイ</a> を使えば、検索条件に基づいた追加受信トレイを作成できるが、作成できる受信トレイは5個までだったり、各受信トレイは並べて表示するしかできない、といった制約がある。</p>
<p>Notion Mailでは、任意の検索条件（From、To、添付ファイルの有無、ラベルの複数条件や除外条件、などなど）でメールを表示するViewを好きに追加できる。そして受信トレイもViewの1つであり、デフォルトではGmailと同様に未アーカイブのメールを表示するのだが、この条件を変更できる。</p>
<p><img src="/images/2025-09-16/notion_mail_inbox_filter.png" alt=""></p>
<p>Notion Mailのキーになるのはここだと考えている。受信トレイには、優先度高く処理が必要なメールだけを表示するよう設定し、そうではないメールはViewを分けて後で処理したできるようにすることで、効率化を図ることができる。先述のAIによる自動ラベル機能でも、ラベルを作るときに「このラベルは受信トレイに残すか？　それとも除外するか？」というモーダルが表示される。つまりはAIによってメールを受信トレイに残すか残さないか、最初のトリアージを任せるのがNotion Mailだと捉えている。</p>
<p>Gmailでもオートフィルタを使えば受信トレイのスキップが可能だが、スキップさせるということは「アーカイブする」ことと同義だった。Notion Mailではアーカイブしないままに受信トレイから除外できるようになるので、重要度の高い、すぐ読むべきものだけを受信トレイに残し、時間をおいて読んでもよいようなものは別のViewへと分けるといったことが可能になる。</p>
<p>筆者の場合、カレンダー関連のメールと、Gmailの「プロモーション」カテゴリに分類されるメール（＝企業からのメーリングリストや広告）は受信トレイから除外している。いずれも緊急性は高くないが、出欠確認、情報収集、不要ならUnsubscribeといった処理は必要になるので、別のViewから確認している。</p>
<h2>Priorityを活用してNext Actionを明確にする</h2>
<p>メールを仕分ける際には、Notion Mail独自のプロパティ（チェックボックスや任意のテキストなど）も付与できる。Gmailにはない機能をあまり多用したくはないのだが、「Priority」については実態がGmailラベルだと言うこともあり、これを活用して分類を行っている。</p>
<p>Priorityはデフォルトだと「To-do」「Important」「Waiting」と言った値が用意されており、優先度と言うよりはメールの状態を表すものに近い。こういった用途では、Gmailだとスターやマルチスターを使っていたところだが、Priorityでは文字が書けるので、「返信が必要」「アクションが必要（EOL通知のような）」など、直接的にNext Actionがわかりやすくなり、重宝している。ラベルの一形態に過ぎないと言えばそうなのだが、Priorityはインジケータのように目立つ形で表示されるので、視認性も高くなる。</p>
<p><img src="/images/2025-09-16/notion_mail_priority.png" alt=""></p>
<h3>Priorityの正体はラベルだが自動付与はできない</h3>
<p>Priorityの正体はGmailのラベルである。Priorityを付与したメールをGmail側で開くと、 <code>[Notion]/Priority-xxxx</code> というラベルが付いているのがわかる。</p>
<p><img src="/images/2025-09-16/notion_mail_priority_label.png" alt=""></p>
<p>ならばGmail側のオートフィルタを使って、自動的にPriority付与ができるのではないか、と考えるところだが、なぜかこれはできない。オートフィルタで付与したPriorityラベルは、Notion Mail側で認識してくれない。手動で付与した場合はNotion Mailにも反映されるので、このあたりの挙動はやや謎が残る。</p>
<p>まぁ自動識別するより、自身でPriorityを付与するほうが意識の上にものぼりやすいので、そこまで困っているほどでもない。</p>
<h3>StatusとPriority</h3>
<p>なお、Priorityと似たようなプロパティとしてStatusが存在する。両者の違いはほとんどないように思えるのだが、唯一「StatusはViewのグループ化に使えない」という点が異なる。</p>
<p>グループ化とは、あるViewの中でさらに何らかのプロパティを使ってメールをグルーピングして表示する機能である。筆者の場合はPriorityを付与したメールのみ表示したViewの中を、Priority別でグループに分けている。Statusはなぜかグルーピング条件として使えないので、採用を見送った。</p>
<p><img src="/images/2025-09-16/notion_mail_grouping.png" alt=""></p>
<h2>雑多な受信トレイをやめて、視界をクリアに保つ</h2>
<p>長々書いてしまったが、要は <strong>「ラベリングによるトリアージをAIで効率化した上で、トリアージレベルなどに応じてViewを適宜分離して、大量のメールが来ても視界をクリアに保つ」</strong> というのがNotion Mailなんだと思う。重要な取引先からのメールだけを集めたViewだとか、数多のクラウドサービスから来る通知メールだけのViewだとか、そういったものを気軽に作れるのがいい。</p>
<p>とはいえ、筆者の場合は人対人の連絡ではSlackが主ということもあり、メールの総量は多くない。ただ、それ故に油断して見逃すことも多かったので、よく来る管理職としての申請/承認系のメールや請求関連のものなどは専用のViewを作り、以前より見逃しは少なくなった。雑多なメールが押し込まれたGmailの受信トレイは、それだけで開く気が失せてしまうものでもあり、Viewを分けることで精神的な負荷も和らいだ気がしている。</p>
<p>最後に、そのほか細かなTipsを書いて終わりにする。まだ登場から1年も経っていないこともあり、今後の発展に期待している部分も大きい。</p>
<ul>
<li><code>⌘ + k</code> によるコマンドパレットからほとんどの操作（Viewの移動やメールに対する処理など）ができるので、ショートカットを覚えずともこれでなんとかなる。</li>
<li>ショートカットも多くはGmailと同様のものがあり、流用できる。</li>
<li>GUI上には動線がなく、 <code>⌘ + k</code> やショートカットのみ表示できる画面がいくつかある。例えば「すべてのメール」。</li>
<li>GmailにおけるStarは、Notion Mail上だとなぜか扱いが低く、ラベルの一種としてしか認識されない（☆マークとしては表示できない）。</li>
<li>不具合がいくらか見られる。
<ul>
<li>バルク処理に問題がある。Notion Mailで100通近いメールへの一括ラベル付与などを行っても、Gmailにうまく反映されない。</li>
<li>一部のメールで改行が無視される。条件は把握できていない。</li>
</ul>
</li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/notion_mail</link>
            <guid isPermaLink="false">notion_mail</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 15 Sep 2025 23:55:42 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Firefoxとtridactylを使い始めた]]></title>
            <description><![CDATA[<p>最近、メインのブラウザをVivaldiからFirefoxへと移した。メインブラウザを替えるのは <a href="https://chroju.dev/blog/vimperator_to_vivaldi">VimperatorからVivaldi + Vimiumへ乗り換える - chroju.dev</a> のとき以来で、実に8年ぶりにVivaldiから離れたことになる。Vivaldiはカスタマイズ性も高くて好きだったのだが、今年の春頃に「<a href="https://forum.vivaldi.net/topic/105671/%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97%E7%89%88-%E3%83%9A%E3%83%BC%E3%82%B8%E5%86%85%E6%A4%9C%E7%B4%A2%E3%82%92%E8%A1%8C%E3%81%86%E3%81%A8%E3%83%95%E3%83%AA%E3%83%BC%E3%82%BA%E3%81%99%E3%82%8B%E4%BA%8B%E3%81%8C%E3%81%82%E3%82%8B">ページ内検索を複数回繰り返すとフリーズする</a>」という不具合が数か月直らず、さすがに使うのが辛くなってしまった。</p>
<p>Firefoxは突然使い始めたわけではなく、サブブラウザとしてはずっと使っていた。 <a href="https://support.mozilla.org/ja/kb/containers">Multi-Account Contaienrs</a> という、「コンテナ」という単位でセッションの分離ができる機能があり、AWSコンソールを複数のアカウントに同時ログインして使うのに便利だったのだ。他のブラウザでもマルチプロファイルを活用して似たことが可能だが、Firefoxにおけるコンテナは単一プロファイル内での分離なので、ウィンドウを分ける必要もないし、ブックマークや機能拡張などはコンテナ間で共有できるので、より扱いやすい。使い勝手としては、タブグループごとにセッションが分かれている感覚に近い。また機能面の理由以外だと、Chromium一強の状況があまり好ましくない、Mozillaを応援したいという気持ちもあった。</p>
<p>Firefoxがそれでも「サブブラウザ」扱いだったのは、Vivaldiに比べていくつかの機能が欠落していたからだが、最近改めて見てみると垂直タブやマルチプロファイル（ローリングリリースのため、筆者のFirefoxにはまだ実装されてはいない）など、欲しかった機能にも対応していたので、メインに足ると考えた。</p>
<p>僕がブラウザ自体に求める機能はそれほど多くなく、垂直タブ、マルチプロファイル、あとは次点でピクチャ・イン・ピクチャがほしい。垂直タブはややマイナーめの機能とは自覚しており、Firefoxがネイティブの機能として実装してくれるとは正直考えていなかった。ニッチな需要しかないのかと思っていたが、考えてみればVivaldiやArc、Braveのような比較的新しいブラウザのほか、最近ではEdgeも採用しているので、徐々に市民権を得ている機能なのかもしれない。タブを多量に開く場合には、視認性の面で自分にとってはほぼマストになっている。</p>
<p>余談だが、Firefoxの垂直タブはピン留めすると少し既視感のある外観になる。さすがにこれは意識して寄せている気がするのだが、そこを意識するんだなぁというのはちょっと面白い。</p>
<p><img src="../images/2025-06-12/firefox_vertical_tabs.png" alt="Firefoxの垂直タブでピン留めをしている画像"></p>
<p>ネイティブな機能以外、つまり拡張機能としては「キーボードでブラウザを操作できる」ものを何より求めているが、Firefoxでは <a href="https://github.com/tridactyl/tridactyl">tridactyl</a> を使っている。何年か前にも触ったことはあるが、そのときより数段使いやすくなった印象がある。この分野の拡張では、かつてFirefoxの <a href="http://vimperator.org/">Vimperator</a> が代名詞に近い存在だったが、tridactylはかなり意識的にVimperatorの機能性を踏襲しており、使用感が似てきている。</p>
<p>この手の拡張は、何かの操作を行うコマンド（例えば引数に与えた数字n行分ページをスクロールする <code>scrollline</code> ）と、そのコマンドを実行するキーバインド（例えば <code>j</code> で <code>scrollline 5</code> ）で主に構成され、好きなキーで好きなコマンドを実行できるよう、カスタマイズすることが肝になる。tridactylではVimperatorと同様、ローカルファイルに設定を書いてそれを読み込めるので、dotfileとして管理ができる。</p>
<p>https://github.com/chroju/dotfiles/blob/main/dotfiles/HOME/.config/tridactyl/tridactylrc</p>
<p>組み込みのコマンドのみならず、任意のJavaScriptにもキーバインドできるので、他の拡張を入れずともtridactylだけで多くのことがまかなえたりする。URLとタイトルを任意の形式でコピーする、みたいな小さな機能実装もできるし、最近機能拡張からは使えなくなってしまった、Google翻訳によるページ全体翻訳も再現が可能だ。以下の設定をすれば <code>translate</code> コマンドで翻訳が実行されるようになる。</p>
<pre><code class="language-js">alias translate js let googleTranslateCallback = document.createElement('script'); googleTranslateCallback.innerHTML = "function googleTranslateElementInit(){ new google.translate.TranslateElement(); }"; document.body.insertBefore(googleTranslateCallback, document.body.firstChild); let googleTranslateScript = document.createElement('script'); googleTranslateScript.charset="UTF-8"; googleTranslateScript.src = "https://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit&#x26;tl=&#x26;sl=&#x26;hl="; document.body.insertBefore(googleTranslateScript, document.body.firstChild);
</code></pre>
<p>先述のコンテナ操作にもtridactylは対応しており、 <code>tabopen -c CONTAINER_NAME https://example.com</code> という形で、任意のコンテナ上でURLを開ける。特定のコンテナでよく開くURLがあるのなら、これにaliasやキーバインドを設定しておくと便利だ。</p>
<p>若干変わった機能としては、 <a href="https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/user_interface/Sidebars">サイドバー</a> にURLを読み込み、通常のタブと横に並べて表示する機能がある。これを普通に使おうとすると、サイドバーの開閉を切り替える <code>sidebartoggle</code> コマンドと、サイドバーに任意のURLを読み込む <code>sidebaropen</code> コマンドが分かれていてやや不便なのだが、これもキーバインドで解決できる。</p>
<pre><code class="language-js">bind --mode=browser &#x3C;C-g> jsua browser.sidebarAction.open(); tri.excmds.sidebaropen("https://gemini.google.com/")
</code></pre>
<p>このように設定すれば <code>Ctrl + g</code> でサイドバーにGeminiが開くようになる。また、現在タブで開いているURLを、サイドバーで開き直すというコマンドも別途実装しており、2つのページを見比べながら作業したいときによく使っている。Vivaldiだと、複数タブをタイルのように並べるタブタイリングという機能があってよく使っていたが、Firefoxにおいても、2ページ併存に限定されるとは言えだいたい似たようなことができている。</p>
<p><img src="../images/2025-06-12/firefox_sidebar.png" alt="FirefoxのサイドバーでGeminiを読み込んでいる画像"></p>
<p>動作も安定しているし、UIもシンプルなデザインで、使用上困ることはほとんどない。機能拡張はFirefox非対応のものもあり、Vivaldiからすべてを移してくることはできなかったが、最小限の拡張で使っていくのも悪くないと思っている。ネックとしては、稀にFirefox完全非対応で表示すらできないサービスがあることぐらいだろうか。</p>
]]></description>
            <link>https://chroju.dev/blog/tridactyl_firefox</link>
            <guid isPermaLink="false">tridactyl_firefox</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Thu, 12 Jun 2025 03:41:43 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[帝京理工学部の通信課程を働きながら6年で卒業した]]></title>
            <description><![CDATA[<p><img src="/images/2025-04-13/graduation.jpg" alt="学位記2つ目"></p>
<p>2つ目の学位記をゲットした。それぞれ学士（社会学）と学士（工学）なのだが、どちらもやたらとスコープが広くないか。</p>
<p>ということで、2019年春に入学した、帝京大学理工学部の通信課程をこの春に卒業した。2年次編入だったので、最短3年で卒業できるところ、働きながらとはいえ6年かかってしまった。</p>
<h2>単位修得状況</h2>
<p>| 評価 | 2年次 | 3年次 | 4年次 | 5年次 | 6年次 | 7年次 | 合計 |
| :--: | :---: | :---: | :---: | :---: | :---: | :---: | :--: |
|  S   |   8   |   2   |   4   |   2   |   6   |   6   |  28  |
|  A   |  12   |   8   |   6   |   8   |   8   |   0   |  42  |
|  B   |   4   |   4   |   6   |   4   |   2   |   0   |  20  |
|  C   |   0   |   4   |   0   |   0   |   0   |   0   |   4  |
| 合計 |  24   |  18   |  16   |  14   |  16   |   6   |  94  |</p>
<p>これ以外に、帝京以前に卒業していた大学の単位を32単位持ち込んでおり、合計126単位。卒業必要単位124を少しオーバーした。最終年は4単位だけ取ればよく、9月卒業も可能だったが、どうせ同じ授業料を払っているのだからと1年間在籍した。結局的に追加で修得した単位の数は多くなかったものの、単位は取らずとも資料を眺めたりした科目はいくつかあり、これはこれでよかったとは思う。</p>
<h2>働きながら大学に通う難しさ</h2>
<p>6年、という期間は結構かかってしまったなぁとは思うが、これ以上早められた気もしない。これぐらいが限界だったんじゃないだろうか。</p>
<p>帝京大学通信課程のシステムは以下の通りになる。</p>
<ul>
<li>単位の修得には、ごく一部科目を除いて「科目修得試験」合格が必要になる</li>
<li>「科目修得試験」を受験するには、レポート合格かウェブ学習システム（LMS）上での課題合格が必要になる</li>
<li>「科目修得試験」の受験機会は、年間にI〜IV期の4回がある</li>
<li>IとIII、IIとIV期の試験時間割は原則的に同じであり、1科目につき年2回の受験機会がある（不合格後に再受験も可能）</li>
</ul>
<p>つまり大学は4期制であり、1期あたりの学習期間はざっくり2〜3か月程度になることが多い。例えばI期は6月頭にレポート締め切り、7月頭に試験がある。4月頭から学習を始めるとして、レポート提出まで2か月程度しかなく、おまけに科目によってはレポートA、Bの2つ提出が必要かつ、Aの締め切りは6月頭ではなくさらに1か月ほど早く設定されていたりもする。1科目あたり全15回という授業回数を考慮しても、1期あたり2〜3科目進めるのが精々というところになる。</p>
<p>継続的な学習は習慣化してしまうのが一番で、自分の場合は毎朝1時間半か2時間ぐらいを学習に充てることにしていた。入学間もない頃は夜をあてていたが、仕事を終えてからでは集中力がもたず、2年目ぐらいから朝へ切り替えた。ちょうどリモートワークが一般化した頃だったので、起床→朝食→勉強から、ほぼシームレスに仕事へと移ることができ、朝の時間はだいぶ有効に活用できた。卒業後も、この時間は学習時間として継続している。</p>
<p>当然、習慣化したところで仕事由来のインプットが必要であればそちらを優先したりもするし、家庭やプライベートの都合で時間が取れなくなることもある。試験日は予備日があるわけではないので、別の予定に重なったり、体調不良で試験自体を受けられないこともあった。90単位近くを働きながら修得するという行程は非常に長くてプレッシャーでもあり、無理なのではないか、やめてもいいんじゃないかと考えたこともあったが、どうにか卒業まで辿り着けた。今はただただホッとしている。</p>
<h2>大学を選んだ目的と効果</h2>
<p>大学に入学した理由は、 <a href="https://chroju.dev/blog/become_parallel_worker_and_university_student">入学時に書いたエントリー</a> で、「車輪の再発明をしないための学びであり、車輪を適切に応用していくための学びをしたかった」と記している。文系出身なので計算機科学や数学の基礎を知らないことへの不安があったが、その点は一定解消できたとは思っている。</p>
<p>よく言われる話ではあるが、大学の知識というのはすぐ実践的に役立たつとは限らない。これは計算機科学に限った話でもない。だが、ふとしたときに理解を深めたり、異なる知識をつなぐきっかけになったりする。IPAの試験がIT系エンジニアの基礎として尊ばれているのと同じロジックだと思う。</p>
<p>とはいえ、いわゆる「コスパ」「タイパ」が良い勉強法ではまったくない。大学の学部というところは、卒業するのに一般教養の単位も必要になる（今回は「持ち込み」により新規修得はほぼしていないが）し、必ずしも興味ある分野だけを学べばいいものでもない。逆に言えば、こんな機会でもなければ電気通信法や電子回路を深く学ぶこともなかっただろうし、最終年では卒業に必要のない地理学や日本史（近現代）も学べて楽しかった。このように知見が広がるのは大学ならではだが、シンプルに計算機系の知識だけほしいとかであれば別の勉強法のほうがいいと思う。</p>
<h2>副次的に身についたこと</h2>
<p>短期間で多くの知識を覚える機会や、効率的かつ綺麗なアウトプットをする機会が増えたので、それまで使っていなかったさまざまなツールを駆使するきっかけにもなった。 <a href="https://chroju.dev/blog/adult_university_learner_first_year">社会人大学生1年目を終えて、大学生活と勉強法とその困難 - chroju.dev</a> で書いたiPad Pro、Anki、Scrapbox、LaTeX、 <a href="https://chroju.dev/blog/teikyo_university_learner_third_year">帝京大学通信課程での社会人大学生3年目を終えて - chroju.dev</a> に書いたテプラやGitHub Projectなどはいずれも卒業まで使い続けた。</p>
<p>他に追加で使ったものには、<a href="https://ja.wolframalpha.com/">Wolfram|Alpha</a> がある。数学を中心として、さまざまな問題を計算し、その過程を含めて表示してくれるサービスだが、大学の参考書には「過程」が載っていない場合も多く、重宝した。全機能をアンロックするには有償のProに登録する必要があるものの、学割でほぼ半額になる。</p>
<p>Generative AIについてはまさに在学中に出てきたのだが、あまり活用できないまま終えてしまった。レポートをまるごと生成するのは当然論外だが、NotebookLMや各種のDeepSearchなどは学習支援として相当に役立つはずだ。なお、帝京では「AI使用が全面禁止」といったことにはなっていなかったとは思うが、記憶が曖昧なので参考程度の情報としておいてほしい。</p>
<h2>今後の「進学」について</h2>
<p>今のところまったく考えていないが、修士にも興味はある。それが計算機関連になるのかはわからない。今働いている会社がMBA（経営学修士）の大学院を運営しており、自身もマネージャーを務めている関係から、そちら方面への興味もある。とはいえ一旦は休みたい気持ちが強いので、また気が向いたら考えようと思う。</p>
]]></description>
            <link>https://chroju.dev/blog/teikyo_university_graduation</link>
            <guid isPermaLink="false">teikyo_university_graduation</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 13 Apr 2025 08:43:38 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[2024年に解約した or 解約を検討したサブスク]]></title>
            <description><![CDATA[<p>サブスクリプション契約は放っておくとどんどん増えてきてしまう気がして、不要なものをまとめて解約していこうと決めて取り組んだ1年だった。価値のあるものにお金を払いたいという気持ちの一方、固定費というものには限界がある。</p>
<p>逆に、新しく契約したものはない。</p>
<h2>解約したもの</h2>
<h3>Amazon Prime (Student) / 年2,450円</h3>
<p>今は年2,950円に値上げをしたようだが、契約を開始したときは2,450円だった。いずれでも通常のPrimeと比べると破格。</p>
<p>Prime Studentは学生向けということで、最大でも4年間しか契約できない。通信制大学が5年目に入ったため自動的に終了となった。通常のPrimeへ移行してもよかったのだが、Prime Videoを始めとしたAmazonのサービスをそこまで使っているわけでもなかったので、いっそ解約することにした。</p>
<p>ネット通販のメインはヨドバシ.comに移し、ヨドバシで手に入らない場合のみAmazonを併用したりしているが、今のところ困ってはいない。というかヨドバシの配達が速すぎてびっくりする。</p>
<h3>O'Reilly Online Learning / 年$299</h3>
<p>こちらも年$299というのはBlack Fridayで安くなっている場合の価格で、本来は$499となかなかの金額になる。以前はAssociation for Computing Machinery (ACM)に年$99払って会員になれば、O'Reillyも特典で付いているというハックがあって、その頃から利用しており、一時その特典が終了してしまってからもBlack Fridayを活用して利用を続けていた。現在は一部内容が変わりつつACMの特典が復活している。</p>
<p>単純に、今年1年あまり活用できていないため、一旦やめてみることにした。このサービスに関しては、よく「年会費に見合うだけの冊数を読める気がしない」という理由で躊躇する人を見かける。個人的には1冊読み通すことにあまり重きは置いていなくて、原著、邦訳含めてオライリーを始めとした数千冊の技術書を串刺しで検索してつまみ読みできる点が一番のメリットだと思っている。当然ながらググるより情報の質は良いし、図書館などに行くより効率的にザッピングして、複数の文献を比較できる。ただ、今年はそれすらあまりやらなかったので、Black Fridayの際に悩みはしたが契約はしなかった。今はACMを活用すればBlack Fridayより安く契約もできるので、本当に必要だと思ったら復帰もしやすい。</p>
<p>最近は日本語書籍も発売翌月には読めるようになるし、生成AIが本を探してきてくれる機能なども付いたので、解約はしたけど非常におすすめ。</p>
<h3>IFTTT Pro+ / 年$149.99</h3>
<p>複数のSaaSを連携した自動化タスク（Appletと呼ぶ）を簡単に作れる、IFTTTの有料プラン。Free、Pro、Pro+の3段階があり、中間のProだと一部機能が使えなかったり、全部で20 Appletsしか作れないといった制約があるのだが、いろいろ用途を絞ることでPro+からProへと移行した。</p>
<p>Pro+は如何せん高い。従来からの有料プランはLegacy Proという形で安価に残っていたのだが、これが <a href="https://help.ifttt.com/hc/en-us/articles/16014462721435-Important-Update-to-the-Legacy-Pro-Plan">昨年Pro+に強制移行する形になってしまった</a>。Proであれば$34.99で、それなりに値頃感がある。</p>
<h3>週刊少年ジャンプ電子版 / 月980円</h3>
<p>「釘崎野薔薇の生死が明言されるまで購読する」という縛りで契約していたが、その条件を満たしたため解約。</p>
<h2>解約しようとしたができなかったもの</h2>
<h3>ATOK Passport / 月300円</h3>
<p>ATOKの変換精度は好きなのだが、設定まわりがあまり好きになれなくて、買い切り型や無償のIMEで代替できるのではないかと、いろいろ試したもののATOKに戻ってきた。</p>
<p>ATOKは変換性能の高さも然ることながら、入力ミスの自動修復が強い。入力をミスしたと気付いても、ATOKが直してくれるだろうからとDeleteをまったく押さずに突っ切るスタイルになっている自分に気付いた。ATOK特化型である。これはこれでよろしくない気もするが。</p>
<h3>Readwise / 月$7.99</h3>
<p><a href="https://chroju.dev/blog/readwise_reader_is_so_good">Readwise Readerで効率的にインプットする - chroju.dev</a> などでベタ褒めしてきたFeed Reader + Read Later系サービスなのだが、この円安の折に月$7.99はちょっと考えてしまう。</p>
<p>しかし、こちらも移行先が見つかっていない。一時期は無償で使えるOmnivoreを使っていたが、11月いっぱいで残念ながら <a href="https://blog.omnivore.app/p/details-on-omnivore-shutting-down">サービス終了</a> してしまった。メルマガとウェブページの双方をサクサク読めるサービスを探しているのだが、メルマガにも対応しているものがほとんどない。</p>
<h3>Tile Premium / 年3,600円</h3>
<p>忘れ物防止タグのTileは、実際にTileをどこかへ置き忘れてきた際に通知してくれる「スマートアラーム」などの一部機能を使うのにサブスク加入が必要となる。スマートアラームなぞマストな機能なわけで、実質的にはサブスク加入前提の製品だと思っている。</p>
<p>Ankerが発売しているEufyであれば、サブスク契約なしですべての機能が使えるので、一時こちらへ移ったのだが、明らかにTileより精度が悪いためTileへ戻った。Eufyの場合、電車の中など人混みにいると「落としていませんか？」と誤検知することが多く、逆に実際近くから離してみても、Tileより通知までのラグが大きい。ユーザーレビューなどを探ってもそこまで悪評はないようなので、何か僕の環境や設定に起因しているのかもしれない。</p>
]]></description>
            <link>https://chroju.dev/blog/cancel_subscriptions_2024</link>
            <guid isPermaLink="false">cancel_subscriptions_2024</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 28 Dec 2024 01:43:57 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[おひとりさまPleromaでFediverseに参加して1年が経った]]></title>
            <description><![CDATA[<p>https://chroju.dev/blog/twitter_to_pleroma</p>
<p>このエントリーで書いた <a href="https://pleroma.chroju.dev/users/chroju">Pleroma</a> を建て、Fediverseに参加してから1年が経ったので、いろいろ書いてみる。</p>
<h2>構成</h2>
<p>始めた当時はシステム構成に言及していなかったので、改めて書き残しておく。</p>
<p><img src="../images/2024-11-16/pleroma_diagram.png" alt="Pleroma構成図"></p>
<p>Pleromaは、Lightweight Kubernetesである <a href="https://k3s.io">K3s</a> 上でDockerコンテナとして動作させている。コンテナで動かす必然性はまったくなく、検証用で建てているK3s環境を常時活用していたいという、単にそれだけの理由でこの構成にしている。データの保存にはPostgreSQLが必要だが、これもコンテナで動作させて、EFSで永続化を行っている。</p>
<p>Pleromaは公式のDockerコンテナを提供していないため、サードパーティの https://github.com/angristan/docker-pleroma をforkして使っている。</p>
<p>インターネットとの通信には <a href="https://www.cloudflare.com/ja-jp/products/tunnel/">Cloudflare Tunnel</a> を利用している。いわばngrokのようなものであり、インバウンドの通信を開けなくても、Pleromaをインターネットへ公開できる。サーバの要塞化などの手間はなるべく減らしたい。</p>
<p>全体が載るEC2インスタンスは、t4g.smallのスポットインスタンスを利用している。お金の関係もあってだいぶ貧弱なサイズを使っているが、後述するようにフォロー／フォロワーが少ないこともあってか、そこそこ安定して稼働できている。図にある通りAuto Scalingを採用しているが、あくまで自動復旧のためであり、複数台構成を取っているわけではない。</p>
<h2>稼働状況</h2>
<p>定常的にメトリクスを記録してはいないが、 <code>cpu: 200m, memory: 250Mi</code> という <code>limits</code> 設定で今のところ安定して稼働している。ActivityPubの仕様上、Federationが増えれば負荷も大きくなるとは思うが、最低限の運用だとかなりリソースの消費は低い。Raspberry Piでも動作可能とうたっているだけはあると思う。</p>
<p>メトリクスの監視はしていないが死活監視だけは行っていて、 <a href="https://uptimerobot.com/">UptimeRobot</a> を利用している。無料プランだと5分ごとにHTTP通信を試みる簡易な監視ができるだけだが、不意に落ちている状況には気づける。また <a href="https://stats.uptimerobot.com/zwCT56wgqG/797405195">status page</a> が作れるのも気に入っている。</p>
<p><img src="../images/2024-11-16/uptimerobot.png" alt="UptimeRobot"></p>
<p>ちなみにstatus pageを見ると頻繁に落ちている期間があるが、当初は1AZ構成だったので、AZ内でのEC2キャパシティ不足で不安定になった時期があったりしていた。個人の環境ということもあり、安定性はあまり追求しない雑な運用をしているのが正直なところ。</p>
<h2>SNSとしては活用しづらい</h2>
<p><img src="../images/2024-11-16/pleroma_bio.png" alt="Pleromaのbio"></p>
<p>ステータス（投稿）が3桁にいくぐらいには投稿しているが、見ての通りフォロー／フォロワーはかなり少ない。</p>
<p>フォロー相手は、おひとりさまサーバを使っていると非常に見つけづらい。大勢参加しているサーバであれば、ローカルタイムラインやフェデレーションタイムラインに見知らぬ人の投稿が流れてくることもあるだろうが、ひとりでやっていると、他人を見つけるには他のサーバへと分け入っていく必要があり、手間がかかる。</p>
<p>知人からフォローしていきたいところではあるが、Fediverseでアカウントを持っている人はやはり少ないし、アカウントがあるとしてもそれを探す手段が限られる。仮に探し当てたとしても、すでに1年以上投稿がないということも多かった。Fediverseを常用している人は、体感やはり非常に少ない気がしている。</p>
<p>逆に、フォロワーがわずかとは言え増えたのが面白い。基本的には、偶然僕のPleromaへ流れ着くことはないはずである。それにも関わらず、他のSNSでまったく繋がりのない人からのフォローもあり、どこから探し当てたのか不思議に思ったりもしている。</p>
<p>今はもうある程度あきらめてというか、開き直って、静かなSNSとして利用している。</p>
<h2>クライアントソフト</h2>
<p>クライアントとしては、デスクトップではPleromaにフロントエンド（Pleroma FE）が同梱されているので、それをそのままブラウザから使っている。二要素認証もあるので安心感はある。</p>
<p>Androidでは <a href="https://tusky.app/">Tusky</a> を使っている。特にこだわりがあるわけではなく、なんとなく見つけて、使いやすかったので使い続けている、というぐらい。</p>
<p>投稿には <a href="https://buffer.com">Buffer</a> を使い、 <a href="https://x.com/chroju">X (Twitter)</a> や <a href="https://bsky.app/profile/chroju.dev">Bluesky</a> とクロスポストをすることも多い。あまり広く見られる必要がない独り言などは、Pleromaだけに投稿したりもする。</p>
<p>https://lifehacking.jp/2024/08/buffer-threads/</p>
<h2>自分のメインタイムラインとしての今後</h2>
<p>Pleroma、現状はあまりSocialな場にできていないものの、むしろそれでいいと考えて、自分のメインタイムラインとしての意識はこの1年間継続している。Socialな繋がりはX (Twitter)が場としてあり、PleromaはSocial性を追求せずに、好きに投稿を垂れ流す場所としている。と言っても、別に表へ出せないネガティブなことを書きたい、というわけではないが、最近自分のXは会社の採用活動にも活用していたり、公的な性質を帯びるようにもなってきたので、それに対する私的なタイムラインとして、どうでもいいようなことを書いてもOKな場所が別にあっていいな、というか。</p>
<p>このブログと同様、自分の庭という感覚に近いかもしれない。APIがあるのでIFTTTなどを通じたハックもしやすいし、Xと違って、ログインしていなくとも閲覧しやすいのもいい。購読する人はまずいないだろうが、RSSの形でも吐いてくれる。総じて使い勝手としては気に入っている。</p>
<p>今後もX、Bluesky、Pleromaの3軸を併用するのがしばらく続くと考えている。可能であればSocialな場はBlueskyに統一したいのだが、現状だとまだまだXの存在感が大きい。ただ昨今の情勢を鑑みると、Xの先行きに対する不安感は非常に強くなっている。</p>
<p>一方では、Fediverseが主流になる未来というのもまず来ないだろう。分散型のSNSは、分散しているが故にフレキシブルに利用できるメリットがあるが、分散しているが故に盛り上がりが見えづらくもある。局所的な人気と、自分のような個人ユースだけで続いていくんじゃないだろうか。</p>
<p>当然ながらOSSであるPleromaの先行きだってわからないわけだが、現状は活発に開発されており、まだまだしばらくは使っていきたい。</p>
]]></description>
            <link>https://chroju.dev/blog/pleroma_fediverse_one_year</link>
            <guid isPermaLink="false">pleroma_fediverse_one_year</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 16 Nov 2024 00:26:08 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Platform Engineering Kaigi 2024 #PEK2024 に参加した]]></title>
            <description><![CDATA[<p><a href="https://www.cnia.io/pek2024/">Platform Engineering Kaigi 2024</a> に行ってきた。</p>
<h2>イベント参加時点での筆者の状況</h2>
<p>Platform Enginneringを朧気に把握はしているが、腑に落ちるほど理解できてはおらず、それほど積極的に導入を図っているわけではない、というような状態。以前、 <a href="https://chroju.dev/blog/what_is_platform_engineering">Platform EngineeringとSREと「ちいとぽ」と - chroju.dev</a> を書いたときからあまり状況は変わっていない。ただ潮流として「来そうだな」とは感じていて、腑に落としたくて参加したと言ってもいいぐらい。</p>
<h2>Platform Engineeingは古くて新しい</h2>
<p>よく言われることだけれど、Platform Engineeringはまったく斬新な概念と言うわけではなく、従来から「共通基盤」と言われるような形で、似たプラクティスは実践されてきた。今日のセッションを聞いていても、Team Topologiesを元に実践を始めたという話もあれば、何年も前から取り組んできていたことが、今考えるとPlatform Engineeringに当てはまるのではないか、と考えて発表している、という話もあった。</p>
<p>キラキラした最新の概念、という受け取り方をしなくて良いと考えている。だから過度に遠ざける必要もないし、過度に盲信する必要もない。 <code>Class Platform Engineering implements DevOps</code> とも言うそうだが、SREとはまた異なるベクトルでのDevOpsの変形、あるいは実装、ぐらいに捉えていいのではないか。</p>
<h2>Platform Engineeringも小さく始める</h2>
<p>では何がPlatform Engineering（的）なのかという話だけど、ガートナーの定義はこうなっている。</p>
<blockquote>
<p>プラットフォーム・エンジニアリングは、インフラストラクチャ・オペレーションの自動化とセルフサービス機能により、開発者エクスペリエンスと生産性を向上させます。開発者エクスペリエンスを最適化し、プロダクト・チームによる顧客価値のデリバリを加速させることが期待できるため、大きく注目されています。</p>
</blockquote>
<p>ここでは「自動化」と「セルフサービス」に言及されているけれど、これは手段なので、個人的には一度外してみて良い気がしている。力点が置かれるのは「開発者エクスペリエンスと生産性を向上」「開発者エクスペリエンスを最適化」「デリバリを加速」あたりではないか。</p>
<p>最近見かけた以下の定義が一番腑に落ちている。</p>
<iframe class="speakerdeck-iframe" frameborder="0" src="https://speakerdeck.com/player/1347cb1c77e647aaa6a2f50678d6aa8b?slide=20" title="タクシーアプリ『GO』におけるプラットフォームエンジニアリングの実践" allowfullscreen="true" style="border: 0px; background: padding-box padding-box rgba(0, 0, 0, 0.1); margin: 0px; padding: 0px; border-radius: 6px; box-shadow: rgba(0, 0, 0, 0.2) 0px 5px 40px; width: 100%; height: auto; aspect-ratio: 560 / 315;" data-ratio="1.7777777777777777"></iframe>
<p>開発者がデリバリに集中するには、個別最適の必要性が薄い非機能的な部分を標準化し、低コストで扱えるようにすればいい、というのがPlatform Engineeringと捉えている。</p>
<p>よってセルフサービスや、システムの実体を伴った「プラットフォーム」は必要条件ではない。Team TopologiesでもWikiが最小のパターンという話があるし、今日の中だと <a href="https://www.cnia.io/pek2024/sessions/53c4528a-ffbf-4d83-8b92-68652f11a774/">マルチクラスタの認知負荷に立ち向かう！Ubieのプラットフォームエンジニアリング</a> で「Sentryやログ・ダッシュボードのリンク集を作るだけでも喜ばれる」という趣旨の話題があったのが印象的だった。Backstageのマネージドサービス「<a href="https://www.ap-com.co.jp/pressrelease/post-11079">PlaTT</a>」をまさに今日リリースしたエーピーコミュニケーションズの方と話していても、「最初からBackstageではなく、まずは小さく始めるので良いと思う」という話になったりした。</p>
<h2>Platform EngineeringとSRE</h2>
<p>立ち話のなかで「SREの人から見て、Platform Engineeringってどう捉えているか」と聞かれたりした。今日聞いたセッションのなかでも、セッションに対する質問のなかでも、このテーマは散見した。</p>
<iframe class="speakerdeck-iframe" frameborder="0" src="https://speakerdeck.com/player/4b71a1232bd44e168fdd29f37da93135" title="Platform Engineering と SRE の門 " allowfullscreen="true" style="border: 0px; background: padding-box padding-box rgba(0, 0, 0, 0.1); margin: 0px; padding: 0px; border-radius: 6px; box-shadow: rgba(0, 0, 0, 0.2) 0px 5px 40px; width: 100%; height: auto; aspect-ratio: 560 / 315;" data-ratio="1.7777777777777777"></iframe>
<p><a href="https://www.cnia.io/pek2024/sessions/31f1df6b-c98a-4bef-8c6b-fd0bf839bc7e/">Platform Engineering とSREの門</a> というこのセッションの中では、両者の目的の違いや、具体的な取り組み内容の違いなどを、様々な資料を用いて比較している。違いのみならず、共通点などを探して、組織体制をどう組むか、という点を論じた話もあった。</p>
<p>先の質問に自分がどう答えたかと言えば、 <strong>開発速度</strong> と信頼性のバランシングを行っている以上、Platform EngineeringとSREには重複した領域があるということと、特に国内ではインフラチームを改組してSREとした会社が多いため、既存のSREがPlatform Engineering的な性格を帯びている場合がよく見られるのではないか、ということだった。実際にどうかは知らないが、自分はこういった背景からPlatform Engineeringに触れることになった。</p>
<p>またSREは組織横断的な活動を求められることも多く、少ない人数でレバレッジを効かせる必要性に駆られる。となると、Platform Engineeringの考え方と近しく、そこから学べることは多いのではないか。</p>
<h2>どこまでがPlatformか</h2>
<p>もうひとつ気になったことがある。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">やっぱり<br>共通基板（共通で使えるサービス）とプラットフォームが色々と混ざってる話が色んなところで散見される気がする<br><br>あくまで、認証とか決済のマイクロサービスであって、プラットフォームと呼ぶと違う気がしてる<a href="https://twitter.com/hashtag/pek2024?src=hash&amp;ref_src=twsrc%5Etfw">#pek2024</a></p>&mdash; 沙南（5thVaxed:MMMFD） (@sokasanan) <a href="https://twitter.com/sokasanan/status/1810573783666954358?ref_src=twsrc%5Etfw">July 9, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>このポストの内容、今日セッションを聞きながら自分も考えていたことだった。Platformとはゼロからインフラやシステムを作る上での素地としてのものを指す（実体はBackstageだったりWikiだったり）と考えていたのだが、各プロダクトが共通して使う、例えば認証認可などの内部向けアプリケーション = このポストでいう「共通基盤」をPlatformとして扱っているセッションもあった。一方で、そういったシステムを取り扱うチームをStream Alignedとして整理しているセッションもあった。</p>
<p>結論としては、原義に照らすと認証認可等の共通システムはPlatformではないと思うものの、まぁどちらでもいいのではないかなぁ、という雑な考えに至っている。デリバリの加速、顧客へ価値を速く届けるというPlatform Engineeringの目的に照らせば、認証認可などは価値そのものではなく、これもまたPlatformとして整理して、開発者がシンプルに呼び出せるようにしよう、と考えていくのは意義がありそうと言える。</p>
<p>一方で、いやそれはマイクロサービスの一部だろう、という整理もわかる。そもそも先のガートナーの定義によれば、対象は「インフラストラクチャ・オペレーション」なので、共通化可能なものすべてがPlatformと言っているわけではない。認証基盤を作るのにもPlatformが必要になってくるわけで、認証基盤はあくまで社内へ価値提供するプロダクトとして、Stream Aligned Teamが扱うべきだ、という考え方もできそうだし、原義に忠実なのはこちらの整理だろう。</p>
<p>とはいえ、これは各社取り組みやすい整理でいいんじゃないだろうか。原理主義的になる必要はない、というよくある話に落ち着けたい。とはいえまだPlatform Engineeringがそこまで広まりきっていないなかで、すでに定義にブレが出てきているのは危うさも覚えるところではある。</p>
<h2>暗中模索を続けていく</h2>
<blockquote>
<p>サイトリライアビリティエンジニアリング（Site Reliability Engineering＝SRE）の分野で私が尊敬する人々は皆、この分野自体が今もなお進化、拡張、変革、新たな発見の真っ只中にあると考えています。ある意味では私たち全員がずっと、SREを探求し続けているのです。</p>
</blockquote>
<p>『<a href="https://www.oreilly.co.jp/books/9784873119618/">SREの探求</a>』冒頭のこの一節がとても好きなのだが、Platform Engineeringも同じだと感じる。</p>
<p>僕なりの解釈なので何か間違っていてどこかから怒られるかもしれないが、いずれも方法論ではなく、目的と考え方のセットであり、Howについてはある程度の自由度がある。ただ、Platform Engineeringの目的に同意する、その必要性を感じる人はどうやら多くいそうであり、僕もその一人であり、現在は各社なりの実践が無数に生まれている状況になりつつあり、それを一手に集めて話し合うような、こういったカンファレンスは非常に有意義だと感じた。 <a href="https://www.gartner.co.jp/ja/newsroom/press-releases/pr-20231204">昨年のガートナーによるハイプ・サイクル</a> だとすでにピークに達しつつあるが、となると国内だとまだ黎明期を脱したぐらいではないだろうか。これからもしばらく暗中模索が続きそうだし、是非また参加したい。</p>
<p>運営もとてもスムーズで楽しく過ごせました。カヌレとコーヒー、というおやつのチョイス、ゴミもあまり出ないしおなかにもわりと溜まってくれるし物珍しいしおいしいしで、とてもよかったです。</p>
<p><a href="https://gyazo.com/1d261d5ff3466e75f64e8dee43b7443e"><img src="https://i.gyazo.com/1d261d5ff3466e75f64e8dee43b7443e.jpg" alt="お台場カヌレとコーヒー"></a></p>
]]></description>
            <link>https://chroju.dev/blog/platform_engineering_kaigi_2024</link>
            <guid isPermaLink="false">platform_engineering_kaigi_2024</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 09 Jul 2024 12:27:16 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Pixel aシリーズからNothing Phone (2a)に乗り換えた]]></title>
            <description><![CDATA[<p><a href="https://gyazo.com/72a7e7552ba94e2bc6c556636c43c6d0"><img src="https://i.gyazo.com/72a7e7552ba94e2bc6c556636c43c6d0.jpg" alt="Nothing Phone (2a)とPixel6a"></a></p>
<p>なんかカッコいいなー、とNothing Phone (1)の頃から思ってはいて、それが(2a)で49,800円というリーズナブルな値段になり、時同じくしてPixelのaシリーズ最新の8aが72,600円まで上がってしまったので、これは乗り換えてもいいタイミングかなと。もともと乗り換えるつもりはなかったが、ご覧の通りPixel 6aをバッキバキに壊した故に買い替えを余儀なくされた。Nothing Phoneの良いところはビックカメラが正規代理店になっているところであり、壊したその足でビックカメラへ向かって、少し触ってすぐに購入した。</p>
<p>スマートフォンで処理の重いゲームをしたり、長時間動画を見たりということをしないので、求める性能はミドルレンジでよくて、Pixelのaシリーズは「ちょうどよかった」。3a以降、同じような理由でPixelを使っていた人は結構いたんじゃないかと。余計なアプリケーションが入っていないシンプルさも良かったし、カメラの性能なども気に入ってはいたのだが、円安の余波とはいえ7万円越えてくるとやっぱり「ミドルレンジか、これは？」となってしまう。</p>
<p>買う決め手を「価格」にしてしまったため、Nothing Phoneも今後円安反映がないとは言い切れず、そうしたらまた出戻りするかもしれないが、とりあえず今買う選択肢ならNothing Phone (2a)は十分に「あり」だなと。</p>
<p><a href="https://gyazo.com/69f17fa2d7a2031f18dd16c3ea18caa9"><img src="https://i.gyazo.com/69f17fa2d7a2031f18dd16c3ea18caa9.jpg" alt="背面の特徴的デザイン"></a></p>
<p>デザインがこの機種最大の特徴であり、カメラの配置と本体の材質ぐらいしか各社で差異がないんじゃないかとすら思えるなか、Nothing Phoneの遊び心は嫌いじゃない。</p>
<p><a href="https://gyazo.com/48693372636392f4de1a966a9681ba3f"><img src="https://i.gyazo.com/48693372636392f4de1a966a9681ba3f.jpg" alt="Glyph Interface"></a></p>
<p>背面にGlyph Interfaceと呼ばれる大きめのLEDが3つ入っているのだが、これは単なる飾りではなく、通知の種類で光り方を変えたり、タイマー使用時に残り時間を表現させたりできる。実用性が高いというよりは、これも「遊び心」の範疇だとは思うが、最低限の情報量で通知に気付ける、というのはデジタルデトックス的な効果も望めるかもしれない。実際、重要な通知が来ているときだけ、Glyphを光らせっぱなしにする、という機能があって、日中はスマホを極力使わないが家族からの連絡だけはすぐ気付きたい、といった用途でわりと便利に使っている。</p>
<p>ミドルレンジということで性能面の期待はしていなかったものの、不満らしい不満は特にない。6.7インチのディスプレイは大きすぎるという好みの問題や、背面に指紋が付きすぎるのが気にかかるぐらいか。スマホを10年以上使ってきたが、初めて背面にも保護フィルムを貼ったぐらいには指紋が目立つ。</p>
<p>Pixel 6aより良い点もあり、画面内指紋認証の精度はNothing Phoneのほうが遥かに高い。Pixel 6aでは成功率5割ぐらいという感覚で使っていたが、Nothing Phone (2a)ではほぼ百発百中で、ストレスがなくなった。</p>
<p>写真に関して細かいことは僕にはわからないが、6aと比べて大きく劣る、という気はしていない。2枚だけだが比較で撮ってみたので貼っておく。いずれも1枚目がNothing Phone (2a)、2枚目がPixel 6aであり、加工やパラメータ調整は何もしておらず、オートで撮ったそのままのものである。</p>
<p><a href="https://gyazo.com/c76af3f7e552f8b7c739ae432efe498e"><img src="https://i.gyazo.com/c76af3f7e552f8b7c739ae432efe498e.jpg" alt="Nothing Phone (2a) 撮影サンプル2"></a></p>
<p><a href="https://gyazo.com/ebfe601ca28237b672e84302d9d3d37a"><img src="https://i.gyazo.com/ebfe601ca28237b672e84302d9d3d37a.jpg" alt="Pixel 6a 撮影サンプル2"></a></p>
<p><a href="https://gyazo.com/bc70851014fa09c80abaa8b85dca085c"><img src="https://i.gyazo.com/bc70851014fa09c80abaa8b85dca085c.jpg" alt="Nothing Phone (2a) 撮影サンプル3"></a></p>
<p><a href="https://gyazo.com/a5508bbe9e4774b724aff489fe6d66de"><img src="https://i.gyazo.com/a5508bbe9e4774b724aff489fe6d66de.jpg" alt="Pixel 6a 撮影サンプル3"></a></p>
<p>組み込みのランチャーアプリも、ウィジェットなども含めてハードウェアに沿ったデザインになっていて良い。ウィジェットはほとんど使わない主義だったが、なんとなくデザインが良いので使ってみている。</p>
<p><a href="https://gyazo.com/b9702f2f4e67a185743a928678f1a3aa"><img src="https://i.gyazo.com/b9702f2f4e67a185743a928678f1a3aa.jpg" alt="Nothing Widgets"></a></p>
<p>このデザインを活かすなら裸で使いたいところだし、僕はスマートフォンにケースを付けたことがこれまでで一度もなかったのだが、Pixel 6aを派手に壊した反省から、今はSpigelのケースを付けている。ケースはこの機種の弱点と言えるかもしれない点の1つで、当たり前のように種類が少ない。ビックカメラであわせて買おうと思ったが、購入店舗では置いていなかった。</p>
<p>ちなみにデザインのこだわりはSIMピンや、付属のUSBケーブルにまで及ぶ。だいたい付属ケーブルなどはすぐ捨ててしまう（手元に山とあるので）のだが、これについては捨てられず携帯している。</p>
<p><a href="https://gyazo.com/7ef3365fee9b0fc981c8a8b4fa1785f5"><img src="https://i.gyazo.com/7ef3365fee9b0fc981c8a8b4fa1785f5.jpg" alt="付属品"></a></p>
<p>総じて、この価格でこの性能、というのは、巷の評判通りコストパフォーマンスがかなりいいと感じる。それだけに、この為替レートが継続した場合、次の(3a)が同じ価格で出ることはないかもしれないとも思う。次の買い替えのときには、またPixelとの間で悩んでいるかもしれない。スマホに変化や遊び心を求める、というのもここ数年なかったので、このタイミングでNothing Phoneを買えたのは幸運なタイミングだったようにも思う。</p>
]]></description>
            <link>https://chroju.dev/blog/nothing_phone_2a</link>
            <guid isPermaLink="false">nothing_phone_2a</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 23 Jun 2024 05:51:47 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『情報セキュリティの敗北史』を読んだ]]></title>
            <description><![CDATA[<p>https://www.hakuyo-sha.co.jp/science/security/</p>
<p>面白かった。タイトル通り歴史をつづった本であり、純粋な技術書というよりは読み物としての性格が強い。具体的なセキュリティインシデントも当然登場するが、その技術背景が詳しく掘り下げられるわけではない。「SQLインジェクション」「カーネル」など、専門家にとっては基本的な用語にも注釈がついているので、むしろ専門外の方でも広く読めるようにした文芸書に近いのかもしれない。ちょっと違う気はするが、『失敗の本質』情報セキュリティ版、みたいな趣だろうか。</p>
<p>歴史の範囲はENIACの誕生から2020年前後までであり、およそ現代における電子計算機の発展の歴史を概観する形になる。複数ユーザが1つのコンピュータを共有するタイムシェアリングシステムの確立、数多のコンピュータがネットワークで接続されたインターネットの誕生、急速にコンピュータが民間へ広まったドットコム・ブームと、コンピュータの扱い方を巡るパラダイムが変わるごとに、セキュリティの在り方も変わり、新たな問題が出現しては対策が積み重ねられてきたのだ、ということが語られる。まさに「敗北史」ではあるのだが、あまりネガティブな語り口ではなく、淡々と読める。今では当たり前になったセキュリティリスクが、歴史のどの段階で、どういった背景から生まれてきたのか、という観点で見る機会は、これまであまりなかった。</p>
<p>パラダイムの変化によってセキュリティの在り方が変わった、というのは技術的な要因のみならず、人間の心理的な要因も無視できない。例えば本書で「リスク補償理論」に触れられているが、これはある安全対策が導入された際、人は別のところで以前よりもリスクを冒すようになり、結果的に全体的なリスクの増減が相殺されてしまうという理論だ。これをセキュリティの文脈に当てはめると、ファイアウォールが導入されたことで安心感が生まれ、個々のクライアント側でユーザーのセキュリティ意識が低くなる、といった事象となる。6章では「ユーザブルセキュリティ、経済学、心理学」と銘打たれ、このような心理学や行動経済学の観点から見たセキュリティ問題に丸々1章が割かれているほか、7章「脆弱性の開示、報奨金、市場」や8章「データ漏洩、国家によるハッキング、認知的閉鎖」でも、人間のマクロな経済行動をベースとした話が展開される。インターネットの登場、スマートフォンの登場といった形でユーザーのコンピュータとの触れ方が変われば、当然ながらその心理にも変化が生まれ、情報セキュリティの問題も形を変えていく。さらには国家機関のサイバー戦争により、脆弱性は「武器」として扱われ、民間を巻き込んでより複雑な様相となっている。</p>
<p>単に「敗北史」を描いただけの諦念に満ちた本というわけではなく、最後の9章「情報セキュリティの厄介な本質」では全体を総括しつつ、今後の情報セキュリティの在り方に対して一石を投じて締めている。</p>
<blockquote>
<p>セキュリティを実現する ためには特定の条件が必要であるという主張には、反証可能性がない。また、特定のセキュリティ技術、製品、または方法を採ることがセキュリティに求められるというセキュリティ製品のベンダーや セキュリティ専門家のアドバイスにも、 反証可能性は存在しない。これは情報セキュリティ分野の中心で待ち構える、実存的な危機だ。人々が意識するかしないかにかかわらず、 その実際的な影響は、何十年にもわたって蓄積されてきた山のようなセキュリティアドバイスに現れている。どのアドバイスに効果があるかを判断する方法がないため、効果のないアドバイスを破棄することができず、すべて山の中に加えられてしまう。 (p.276)</p>
</blockquote>
<p>本書の帯には「愚者は経験に学び、賢者は歴史に学ぶ」という有名な格言が書かれているが、情報セキュリティはまさに歴史の集積であると、改めて気付かされる。本書によれば、バッファオーバーフローの概念が初めて公になったのは1972年のことだが、それから半世紀を経た現代においても、この問題が完全に撲滅されたというわけではない。一度現れた問題はその後もついてまわり、対策に対策を重ねて現代に至っている。</p>
<p>情報セキュリティ対策は終わりのあるものではないし、「敗北史」は今後も続いて行くのだろうが、そのなかで如何に最善を尽くすことができるかを知る上で、示唆に富んだ本だと思う。</p>
]]></description>
            <link>https://chroju.dev/blog/a_vulnerable_system</link>
            <guid isPermaLink="false">a_vulnerable_system</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 17 May 2024 14:44:56 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Corne Cherryを愛用した4年の後、Corne V4を購入した]]></title>
            <description><![CDATA[<p><a href="https://gyazo.com/7454c52f2a0f813050858ac44df5a855"><img src="https://i.gyazo.com/7454c52f2a0f813050858ac44df5a855.jpg" alt="Corne V4とCorne V3"></a></p>
<p>Corne Cherryを約4年前に手に入れて以来はずっとこれを使っていて、もう日常的に使うキーボードを買い替える必要はなかろう、ぐらいに溺愛しているのだが、そのCorneの新版V4が出たので購入した。何が変わったのか？という点は遊舎工房の商品ページを参照されたい。</p>
<p>https://shop.yushakobo.jp/products/8961</p>
<p>一番の違いとして <strong>「半田付けが不要になった」</strong> という点があり、キースイッチとキーキャップを買って植えて、あとはネジ留めさえすればすぐ使えるので、半田付けを敬遠していた方にも勧められそう。</p>
<h2>ケース付きで音が変わる</h2>
<p>もともと使っていたのはCorne V3に <a href="https://imkulio.com/">IMK Corne Case</a> というサードパーティのアルミ製ケースを合わせたものであり、この時点でもだいぶ完成度が高いと感じていた。</p>
<p><a href="https://gyazo.com/cc39bd19b7cdf20b3d8a276815ba3cb6"><img src="https://i.gyazo.com/cc39bd19b7cdf20b3d8a276815ba3cb6.jpg" alt="サンドイッチ構造とケース"></a></p>
<p>一方でCorne V4についても、自作キーボードで一般的なサンドイッチ構造（キースイッチを半田付けする基盤を、アクリルプレート2枚で挟み込むように構成したもの、写真左）とは異なり、ケースが搭載されている。IMK Corne Caseのような金属製ではなくプラスチック製ではあるが、非常に質感が良くて触ってて気持ちがいい。</p>
<p>金属製ケースだと少し甲高い音がしていたのだが、プラスチック製になって低めの静かな音に変わった。良い録音機材を持っていないので音を届けることはできないが、コトコトと良い音を立てていてすごく気に入っている。個人的にはもう少し静音性が欲しいので、遊舎工房の <a href="https://shop.yushakobo.jp/products/keyboard_foam?_pos=2&#x26;_sid=40c908672&#x26;_ss=r">フォームカットサービス</a> を使うつもりでいる。</p>
<p>なお、キースイッチは <a href="https://talpkeyboard.net/items/644369821c72b409e0ad9d2d">Kailh Deep Sea Silent Box Switch Islet</a> を使っている。今回のために新しく購入したが、静音性も然る事ながら、ブレが少なくてこれも非常に良い。</p>
<h2>追加された4つのキーをどう使うか</h2>
<p><a href="https://gyazo.com/ff54d737646f2deba2f011a818760d22"><img src="https://i.gyazo.com/ff54d737646f2deba2f011a818760d22.jpg" alt="ProMicroと追加キー"></a></p>
<p>V4ではProMicroが不要となったことで、空いたスペースにキーが左右2つずつ追加された。Corneのキー数は「ギリギリ足りる」という感覚でいたので、この変更はとても嬉しく感じていたのだが、結果から言うと現状あまり活用できていない。</p>
<p>そもそものCorneの配列が、改めて考えると完璧だったのだ、ということに気付いている。ホームポジションから1つ隣へ指を伸ばすだけですべてのキーに届くので、とても収まりが良いのだ。これに慣れると、今回追加されたキーはホームポジションから2つ隣というだけなのだが、それでも遠く感じる。文章を打つときにここまで指を伸ばすのが意外とつらい。</p>
<p>そのためタイピング時以外で活用できる、マクロなどを割り当てるのが良いかなと考えている。1つは画面ロックに設定してみているが、これはなかなかいい。他も使い道を模索したいところ。</p>
<p>また、これも意外だったのだが、打ち間違いが増えた。今使っているキーキャップが、ホームポジションのf, jキーに突起がないこともあり、意外とキーを見ながら打っていたらしく、「右から2番目のキーがf」という具合に視覚的に認識していたのが、キーが増えたことで目算が狂うようになったらしい。ただ、慣れの問題ではあり、徐々に打ち間違いは減っている。</p>
<h2>Vialでのキー設定</h2>
<p>近年はQMK Firmwareをコマンドラインでビルドする、という手段を用いず、GUIからキーマップを設定できるツールが増えた。</p>
<p>そのなかの1つに <a href="https://get.vial.today/">Vial</a> がある。これは設定変更のたびにファームウェアをフラッシュする必要がない（GUI上でキーマップを変更すると即時反映される）、<a href="https://docs.qmk.fm/#/feature_tap_dance">Tap Dance</a> などの若干特殊な機能もGUIから設定ができる、といった特徴があるのだが、利用するにはQMK Firmwareからforkされた、 <a href="https://github.com/vial-kb/vial-qmk">vial-qmk</a> というファームウェアを焼いておく必要がある。</p>
<p>Corne V4にデフォルトで焼かれているのはQMK Firmwareだが、ありがたいことに設計者であるfoostanさんのレポジトリ <a href="https://github.com/foostan/crkbd">foostan/crkbd</a> でVial向けのファームウェアが配布されているので、これを焼けばVialが使えるようになる。</p>
<p>Tap Danceは僕にとってCorneを使う上でのキラー機能に近い。右親指下のキーで、Single TapでIME OFF、Double TapでIME ON、Holdでレイヤー切り替えという設定をしている。トグルではない形でIMEを切り替えられるのは精神衛生にいい。従来、QMK Firmwareだとこのあたりを設定するのにちょっとしたコードを書かなければならなかったが、VialならGUIから設定できるのでだいぶ気軽になった。</p>
<p>Vialで1点だけ気になる点としては、Tap DanceでHoldがうまく認識されず、Single Tap扱いになることがたびたびあること。この点、調整可能なのかも怪しい気がしているが、もう少し粘ってみたい。</p>
<p>https://github.com/vial-kb/vial-gui/issues/108</p>
<h2>2度目のEND GAME</h2>
<p>自作キーボード界隈で、自分の究極の理想とするキーボードへたどり着くことをEND GAMEと言うが、2度目のEND GAMEかもしれない。</p>
<p>冒頭に書いた通り半田付け不要になったことで、リーチする層が広がり、分離型キーボードを買う上で市販のものに並ぶようなかなり有力な製品になったんじゃないかとすら思う。</p>
]]></description>
            <link>https://chroju.dev/blog/corne_v4</link>
            <guid isPermaLink="false">corne_v4</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 05 Apr 2024 14:40:51 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[帝京大学通信課程での社会人大学生5年目を終えて]]></title>
            <description><![CDATA[<h2>単位修得状況</h2>
<p>| 評価 | 2年次 | 3年次 | 4年次 | 5年次 | 6年次 |
| :--: | :---: | :---: | :---: | :---: | :---: |
|  S   |   8   |   2   |   4   |   2   |  6  |
|  A   |  12   |   8   |   6   |   8   |  8  |
|  B   |   4   |   4   |   6   |   4   |  2  |
|  C   |   0   |   4   |   0   |   0   |  0  |
| 合計 |  24   |  18   |  16   |  14   | 16  |</p>
<p>120単位修得し、ついに卒業まで残りは4単位となった。4単位ぐらいどうにかならなかったのか、とは思う。実のところ今年度の成績開示をするまで、残る必要単位はあと8単位だと勘違いしていた。どこでどうこの勘違いが起きたのかわからないが。。期中に「あと4単位で卒業可」と気付いていたらもう少し頑張ったかもしれないし、そうでもないかもしれない。いずれにせよ今年度はあんまり余裕がなかったので難しかった気もする。蓋を開けたら昨年度より修得単位数が多かったし、成績も良かったのでびっくりしている。</p>
<p>残り4単位のために1年分の学費を払う、というのはもったいない感があるので、単位登録は多めに行い、学びたい科目は卒業要件抜きにして学んでみようかと思う。あとは昨年度より試験がすべてオンラインになった関係から、2年間ぐらいキャンパスに足を踏み入れていないので、どこかで遊びに行っておきたい。まぁ理工学部のキャンパスは厳密には宇都宮なのですが、板橋でもいいかな。宇都宮も機会があれば行っておこうかな。餃子を食べがてら。</p>
<h2>受けて良かった科目</h2>
<h3>オペレーションズリサーチ</h3>
<p>ざっくり意思決定を支援するための科学的技法、という定義でいいんだろうか。線形計画法、待ち行列理論、動的計画法とかそのあたりを学んだ。計算機科学と軍事が切っても切り離せないが、オペレーションズリサーチもまた同様の関心から生まれている。</p>
<p>オペレーションズリサーチという分野については、『<a href="https://www.oreilly.co.jp/books/9784873119137/">サイトリライアビリティワークブック</a>』1章で言及があり、その関わりから楽しみにしていた。</p>
<blockquote>
<p>うまくいくとされていたベストプラクティスは、状況に大きく依存し、広く採用されているとはとても言えません。また、運用チームをうまく運営する方法についてはほとんど取り組まれていないという問題もあります。これらのトピックについての 詳細な分析は、一般に、第二次世界大戦中に連合軍におけるプロセスとアウトプットの改善に向けられた[オペレーションズ・リサーチ]（ http://bit.ly/2HeARLw ）に端を発すると考えられていますが、実際に私たちが考えていたのは何千 年にもわたって運用をうまく行う方法（ http://bit.ly/2HcEH7R ）についてでした。
（1章 SREとDevOpsの関係）</p>
</blockquote>
<h3>画像情報処理</h3>
<p>よくある画像フィルタが、数学的にどのようなメカニズムで掛けられているのか知ることができる科目。このあたりは全然予備知識がない一方、ImageMagickなどで触れる機会は多かっただけに、その内実がよくわかる気がして面白かった。GNU Octaveを使って実際に処理も書くので実感が湧きやすい。</p>
<h3>自動制御論</h3>
<p>いわゆる制御工学の分野。主にフィードバック制御を中心として学ぶ。多くは機械などの物理的なものが対象になるものの、あるシステムのアウトプットをフィードバックし、インプットを変化させてアウトプットの安定化を狙う、みたいな考え方は応用が利くものなので、知っておいて損はない分野だな、と。</p>
]]></description>
            <link>https://chroju.dev/blog/teikyo_university_learner_fifth_year</link>
            <guid isPermaLink="false">teikyo_university_learner_fifth_year</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 26 Mar 2024 00:32:27 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[MacBook Air (13-inch, M3, 2024) を買った話と、その初期設定]]></title>
            <description><![CDATA[<p><a href="https://gyazo.com/060a53f208064eb59987243f8b572339"><img src="https://i.gyazo.com/060a53f208064eb59987243f8b572339.jpg" alt="Image from Gyazo" width="1512"/></a></p>
<p>大学を卒業する前に（25年春卒業を想定）、MacBookを学割で買い替えておこうと思って待ち構えていたところ、先日M3のMacBook Airが出たので購入した。特にこの3月ごろの時期は、学割購入時にはApple Gift Cardも24,000円分もらえるのでさらにお得に。</p>
<h2>First Impression</h2>
<p>初めてApple Siliconを搭載した、MacBook Pro (13-inch, M1, 2020) からの買い替えなので3年ちょっとぶり。当時はまだTouch Barのあるモデルだった。いろいろ言われていたTouch Barだが、音量や明るさをスライダーで調整できる点などはわりと気に入っていたので、若干操作感の変化に戸惑いはある。</p>
<p>性能面の違いは然ることながら、10年ぶりぐらいにAirを買ったので、そのことによる変化が大きい。最近はAirでも24GBメモリを積めたり、十二分な性能になってきているので、あえてProを買う必要はないと判断した。Airであれば充電に必要な電力が30Wで済むので、 <a href="https://www.ankerjapan.com/products/a1634">Anker 511 PowerBank</a> のような、バッテリーと充電器を兼ねた機器でも充電が可能になった。充電器とバッテリーの双方を携帯しなくてよくなったのはなかなか便利。</p>
<p><a href="https://gyazo.com/52a2e29a6b4b864a394044d44bf58b35"><img src="https://i.gyazo.com/52a2e29a6b4b864a394044d44bf58b35.jpg" alt="Image from Gyazo" width="1512"/></a></p>
<p>明らかに薄さがわかる、Airの楔形ボディが好きだったので、それが失われたのは残念ではある。それでもProと比べれば明らかに薄いし軽くて取り回しはしやすくなった。バックパックに入れて背負ったときの感覚も、数百グラムの差分だが結構違う。向こう5年ぐらいはこれで戦えたらと思ってたりする。</p>
<h2>初期設定</h2>
<p>軽く初期設定まわりの話も書いておく。</p>
<p>僕は新しいPCを買ったら、以前のマシンの中身をそのまま移行するということはせず、ゼロから環境を作り直している。定期的に強制的なクリーンナップをするのは大事。初期設定については https://github.com/chroju/dotfiles にだいたい集約している。</p>
<h3>Homebrew</h3>
<p>Brewfileに以下のような形式でインストールするパッケージを書いておき、 <code>brew bundle</code> すると一気にインストールしてくれるので便利。継続的にメンテナンスとかはしていなくて、だいたいPCを買い替えたときに旧PCで <code>brew bundle dump</code> コマンドにより現在インストールしているものを出力し、不要なものを削除して新たなBrewfileとしている。</p>
<pre><code class="language-bash">brew "asdf"
brew "bitwarden-cli"
brew "fzf"
...
cask "anki"
cask "bitwarden"
...
</code></pre>
<h3><code>$HOME</code> 配下のファイル群</h3>
<p><code>~/.gitconfig</code> とか <code>~/.ssh/config</code> とか、 <code>$HOME</code> 配下に配置するファイル群。これについてはdotfilesのレポジトリに <code>HOME</code> というディレクトリを置いていて、例えば <code>HOME/hoge/fuga</code> のファイルのシンボリックリンクを <code>$HOME/hoge/fuga</code> に配置する、という形のシェルスクリプトを書いて対応している。今見ると2年ほど前に書いたなかなか頑張ったシェルスクリプトが出てきたけど、最近だともうちょいシュッとできるソリューションがありそうな気はする。</p>
<pre><code class="language-bash">#!/bin/bash

function make_symlinks() {
    for f in $(ls -A $1); do
        src="$1/$f"
        dst="$2/$f"
        if [ -f $src ]; then
            if [ -e "$dst" ] &#x26;&#x26; [ "$3" = '-f' ]; then
                echo "### WARN: overwrite $dst ###"
                ln -fs $PWD/$src "$dst"
            elif [ ! -e "$dst" ]; then
                echo "make symlink $dst => $src ..."
                ln -fs $PWD/$src "$dst"
            fi
        elif [ -d $src ]; then
            if [ ! -e "$dst" ]; then
                echo "make directory "$dst" ..."
                mkdir "$dst"
            fi
            make_symlinks $src $2/$f $3
        fi
    done
}

if [ "$1" = '-f' ]; then
  echo '!!! force mode'
fi

make_symlinks dotfiles/HOME $HOME $1
</code></pre>
<p>昔はAnsibleで頑張ったりしていた頃もあったが、もっと薄い仕組みでいいやという気分になり、シェルスクリプトに書き換えた経緯がある。</p>
<h3>各種システム設定とdefaults</h3>
<p>macOSの設定をターミナルから読み書きできる <code>defaults</code> というコマンドがある。 <a href="https://support.apple.com/ja-jp/guide/terminal/apda49a1bb2-577e-4721-8f25-ffc0836f6997/mac">Macの「ターミナル」でプロパティリストを編集する - Apple サポート (日本)</a> に記載されており、特に隠し機能というわけでもないのだが、どんなコマンドを打てばどういう設定になるのか、という情報は公式に公開されておらず、有志が確認した情報頼りの状況。</p>
<p>OSのアップデートに伴い、コマンドが変わることもあり得る。例えばメニューバーにバッテリーのパーセント表示をするコマンドは、Big Sur以降とその前までとで、以下のように違いがある。</p>
<pre><code class="language-diff">- defaults write com.apple.menuextra.battery ShowPercent YES
+ defaults write /Users/$_user/Library/Preferences/ByHost/com.apple.controlcenter.plist BatteryShowPercentage -bool true
</code></pre>
<p>Infrastructure as Codeチックなことができるので、できる範囲で使いたいところではあるのだが、上述の経緯があるのであんまり隅々までdefaultsで賄うことにはこだわっていない。知っているコマンドだけはスクリプトに列挙しておいて、効いたら儲け物、ぐらいで考えたほうがいいものと捉えている。</p>
<p>システム設定、その他ではだいたい以下のところをいじっている。</p>
<ul>
<li>キーボード
<ul>
<li>「キーボードショートカット」→「修飾キー」から、CapsLockをControlに変更する</li>
<li>「キーボードショートカット」→「ファンクションキー」→「F1、F2などのキーを標準のファンクションキーとして使用」を有効化</li>
<li>「キーボードショートカット」→「Spotlight」は使わないので、すべてのショートカットを無効化</li>
</ul>
</li>
<li>トラックパッド
<ul>
<li>「ナチュラルなスクロール」を無効化</li>
<li>「ページ間をスワイプ」を無効化</li>
<li>「通知センター（2本指で右端から左にスワイプ」を無効化</li>
</ul>
</li>
<li>Dock
<ul>
<li>「自動的に表示/非表示」を有効化</li>
<li>すべてのAppを削除して、使用中のAppだけが表示されるようにする
<ul>
<li>Appは <a href="https://www.raycast.com/">Raycast</a> から起動するので、Dockによく使うAppを置く必要がない</li>
</ul>
</li>
</ul>
</li>
<li>Mission Control
<ul>
<li>「最近の使用状況に基づいて操作スペースを自動的に並べ替える」を無効化</li>
<li>「ホットコーナー」をすべて無効化</li>
</ul>
</li>
<li>壁紙
<ul>
<li>黒いものにする
<ul>
<li>メニューバーの色が壁紙を透かすので、黒い壁紙にするとメニューバーも黒くなり、ノッチが目立たなくなる</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3>GPG key</h3>
<p>Git commitの署名などで使うGPG key。秘密鍵はYubikeyで管理しており、公開鍵はKeybaseに上げているので、公開鍵だけ引っ張ってきてあとはYubikeyを新たなPCに挿せば終わり。</p>
<h3>認証情報系</h3>
<p>Cloudflareとか各種クラウドサービスについては、新たに認証し直し、旧PCからCredentialを持ってきたりはしていない。APIキーが必要な場合はローテートする。</p>
<h2>開発環境はこれから</h2>
<p>とりあえず全般的な設定がこんな感じで終わってきたところで、個別に必要な開発環境などはまだこれから。なるべくローカル環境を汚さずにdevcontainerとか使うことを今度のマシンでは意識していきたい。このあたりは必要に合わせて徐々にやっていこうと思う。</p>
<p>あと、ターミナルは長年iTerm2を使ってきたが、今回 <a href="https://www.warp.dev/">warp</a> を試してみている。コマンドの自動補完に用いていた <a href="https://fig.io/">Fig</a> がちょうど開発終了を表明しており、後継のAmazon CodeWhispererに移っても良かったのだが、ちょっと趣向を変えてみようかなと。</p>
<p>https://www.warp.dev/</p>
<p>warpはターミナルアプリだが、補完機能も内包している。1回のコマンド実行とその出力が、UI上は「block」と呼ばれる区切られた範囲内で表示され、めちゃくちゃ長い出力とかでもblock内をiframeのような感覚でスクロールして見られるのがなかなかよかった。補完はFigほどではない感じがしているが、もう少しチューニングしつつ様子を見たい。</p>
<p>自分も若くなくなってはきたので、定期的に環境を入れ替える、ということは意識的にやっていかないといけない気がしてきている次第。</p>
]]></description>
            <link>https://chroju.dev/blog/macbook_air_2024</link>
            <guid isPermaLink="false">macbook_air_2024</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 23 Mar 2024 04:10:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[RaycastでTerraform Providerのドキュメントを読めるようにしている]]></title>
            <description><![CDATA[<p>最近の個人開発で、Terraform Providerのドキュメントを読むための <a href="https://raycast.com">Raycast</a> Extensionを作っている。Raycast ExtensionはReactでUIを書く形であり、ReactとTypeScriptの手習いとしてやってみている。なのでStoreで一般公開する気はないが、レポジトリから <code>clone</code> すれば誰でもインポートはできる。</p>
<p>https://github.com/chroju/raycast-extensions</p>
<p>処理としては以下のような感じ。</p>
<ol>
<li>ExtensionのPreferenceで、ユーザーが検索したいProviderを登録する（複数可）</li>
<li>Extensionを起動すると、登録されたProviderのGitHubレポジトリから、ドキュメントのmarkdownファイル一覧を取得し、その名前をUIへ表示する</li>
<li>ユーザーがmarkdownファイルを選択すると、そのファイルを読み込んで表示する</li>
</ol>
<p>Providerは任意のものを検索可能とし、ユーザーが好きなものを登録できるようにした。Raycastではrequiredな設定項目を作っておくと、Extensionの初回起動時に設定画面を表示してくれるのが便利。デフォルト値を登録しておいてもこの画面は開くので、どのように記載すればいいかデフォルト値を通じて例示が出来るのも良い。</p>
<p><a href="https://gyazo.com/6028443968e3303f623a28746d37b15e"><img src="https://i.gyazo.com/6028443968e3303f623a28746d37b15e.png" alt="Image from Gyazo"></a></p>
<p>任意のProviderに対応可能なのは、ドキュメントがProviderのレポジトリ内の決まった場所に保存されているから。<a href="https://developer.hashicorp.com/terraform/registry/providers/docs">Terraform Registry - Provider Documentation | Terraform | HashiCorp Developer</a> で、ドキュメントのディレクトリ構造が定められている。</p>
<p>ただ面倒なポイントとしては、ディレクトリ構造の規則が一度変更になっており、さらに従来の規則がまだ有効であること。</p>
<ul>
<li>現行の規則
<ul>
<li><code>docs/resources</code></li>
<li><code>docs/data-sources</code></li>
</ul>
</li>
<li>従来の規則
<ul>
<li><code>website/docs/r</code></li>
<li><code>website/docs/d</code></li>
</ul>
</li>
</ul>
<p>AWSやGoogleなどでもまだ従来の規則に則っており、双方に対応する必要がある。どちらの規則に従っているのかをあらかじめ知ることは不可能なので、現行のディレクトリ構造を探索してみて、フォルダがなければ従来のディレクトリ構造を探索するという形にしている。</p>
<p>最後の、ドキュメントを表示する部分はあまり難しくなくて、というのもRaycastにMarkdownを引き渡せば、いい感じに表示してくれる機能が最初から備わっている。Terraform ProviderのドキュメントもMarkdownで書かれており、Frontmatterだけ削除すればRaycastでそのまま表示できる。</p>
<p><a href="https://gyazo.com/3f10243797f2b34691b5abc04879495d"><img src="https://i.gyazo.com/3f10243797f2b34691b5abc04879495d.png" alt="Image from Gyazo"></a></p>
<p>体験としては結構良い感じではあるのだが、Raycastのウィンドウは閉じると初期状態に戻ってしまう点や、表示したMarkdownの全文検索するような機能がない点など、ドキュメントを読むには若干厳しいかなというところもある。うっかり画面を閉じるとまた最初から検索し直し……というのは辛いので、「最近読んだドキュメント」をキャッシュする機能は付けた。</p>
<p><img src="https://i.gyazo.com/cb77d069427881d3914472e14c5280dc.png" alt="alt text"></p>
<p>ブラウザでドキュメントを開くオプションも付けているので、全文検索しながらじっくり読みたい場合にはブラウザから開く形で対応している。</p>
<p>Raycast Extensionは初めて作ったものの、リッチなUIを簡単に作れるのでモチベーションを保ちやすい。並行してTypeScriptやReactの本を読んでいるので、それらの知識を反映させながらブラッシュアップしてく予定。</p>
]]></description>
            <link>https://chroju.dev/blog/raycast_terraform_provider_docs</link>
            <guid isPermaLink="false">raycast_terraform_provider_docs</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Thu, 15 Feb 2024 03:16:47 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[2023年を振り返る]]></title>
            <description><![CDATA[<p>年末と言うことで毎年やってますが振り返る。</p>
<h2>定量評価</h2>
<p><a href="https://gyazo.com/85c164ed8d58ab9e0a00c8b5525ebc3a"><img src="https://i.gyazo.com/85c164ed8d58ab9e0a00c8b5525ebc3a.png" alt="Image from Gyazo" width="1352"/></a></p>
<ul>
<li>ブログ : 13記事（昨年比 -6）</li>
<li>GitHub Contributions : 266 (-109)</li>
<li>書籍 : 34冊（-3）</li>
</ul>
<p>全部減ってますね。</p>
<p>ブログは書かなかったなぁ、という感覚が明確にある。インプットが技術からマネジメント寄りになり、なかなかそれを抽象化して自分の考えとして書く、というのができずにいる。技術的な記事はこうやってこうしたらこういう罠があって、こう課題をクリアしました、というのが言いやすいが、マネジメントやリーディングにおいて、そういった意識的な仮説検証のループが回せていない感じ。あとは実践が社内の話になってしまうので書きづらいのもあるし、一般化がしづらくも感じる。</p>
<p>GitHubはパブリックなContributionに限定した数字なので、まぁこんなものかなと。ただプライベートを含めた場合でも前年比-800ぐらいでかなり減っている。 <a href="https://onk.hatenablog.jp/entry/2023/08/31/235920">手を動かさないマネージャーを試している - id:onk のはてなブログ</a> という記事を読んでから、特に4Qは自分で手を動かす機会を意図的に減らすことを試していた。徐々に自チームだけではなくて、部門全体や部門をまたいだ検討をする機会が増えてきて、そういった広いレイヤーの話と、目の前で自分がこなすタスクとの間でコンテキストスイッチするのがかなりしんどく思えてきたのが一因。今の立場だと、手を動かすことからなるべく離れた方がいいと思っている。自分が本当にやるべきことにちゃんとフォーカスできる環境をつくる、というのは今後も大事にしたい。</p>
<p>本はもっと読みたいですね！と毎年言っている気がする。うーむ。言い訳ではないが、この読書冊数は <a href="https://booklog.jp/users/chroju">ブクログ</a> から取っており、つまりブクログに登録できない、ISBNのない本は換算されていない。同人誌などの類をよく読むようになるにつれ、これらもちゃんと「読書である」と換算したいな、と思ったりしている。</p>
<p>読んだ本でよかったのは『HIGH OUTPUT MANAGEMENT』、『97 Things Every SRE should know』、『作家の仕事部屋』、『組織戦略の考え方』、『アジャイルな見積りと計画づくり』あたり。</p>
<h2>今年のハイライト</h2>
<h3>認知行動療法</h3>
<p>https://chroju.dev/blog/how_to_be_a_stoic</p>
<p>今年最初に学んでいたのがこのあたりだった。負の感情に苛まれて落ち込むのをどうにかしたいとき、感情自体を制御はしづらいが、そのときどう考えたり行動したりしてその感情に至ったのかという「認知」と「行動」に着目してコントロールを目指す考え方。</p>
<p>聞きかじりで試しているので、なかなか実践が難しくも感じるが、こういった手法が存在すると知れたこと自体が財産だった。『ヒカルの碁』で伊角さんが感情のコントロールは「技術」であると気付くシーンがあるが、あれを20年越しぐらいに理解できた感じ。</p>
<h3>採用に対してオープンになる</h3>
<p>各種の人材系サービスで「転職活動はしていないが、話だけでも聞いてみたい」のステータスに変更し、実際に何社かとカジュアル面談する、ということをしていた。</p>
<p>きっかけは自分が採用活動をするなかでの気付き。採用においては、相手の転職意欲を問わずカジュアル面談などで認知を広め、「種を撒く」ことが大事になる。ならば求職側としても同じことでは？ということで、様々な会社との接点をつくることを意識し始めた。知っていたり、実際にお世話になっているあの会社やこの会社、あるいは全然知らない会社、とても良い機会を得られた。</p>
<p>ただ「とはいえ相手は業務なんだよなー」というのが、つい脳裏をちらついてしまい、自分の性格的に向いていないっぽい。今年後半においては、あんまりこの活動をしてはいないが、適度に続けてはいきたい。</p>
<h3>Fediverse (Pleroma)</h3>
<p>https://chroju.dev/blog/twitter_to_pleroma</p>
<p>Twitter大変動の1年であり、自分としてはFediverseに軸足を移しつつある。もうPleroma中心でいいかな、というぐらいに使い慣れてきた。サーバーも安定している。ただ、こういう年末年始とか技術系のカンファレンスに参加したときみたいに、大勢とたわむれたい場合はどうしてもTwitterになる。ブログへの流入もTwitterを無視できない。</p>
<h3>2年目の週報</h3>
<p>2022年から始めている週報は、NotionからWorkflowy、Pleromaと場を変えつつ、また何回か書かない時期を挟みつつ、とりあえず続いている。良い習慣になっている一方、体裁を整えればOK！みたいな、若干形式的になってきている感覚もあるので、内省の機会としてもっと活用できるようにしたい。先に書いたマネジメント面での仮説検証のループを回す軸にしたり、とか。</p>
<h3>体重が（多少）増加</h3>
<p><a href="https://gyazo.com/7aaab7212c0eeab055aed029c41af69e"><img src="https://i.gyazo.com/7aaab7212c0eeab055aed029c41af69e.jpg" alt="Image from Gyazo" width="1013"/></a></p>
<p>健康面では、低体重が一番の悩みだけど今年ようやく「意識的に体重を増やす」感覚が掴めた気がしている。増やすぞ！と思ってそのための施策を取るとちゃんと増えた。秋ぐらいはちょっとサボって減っているのだが、そんな簡単に減るのも勘弁してくれよ、という気持ちはある。</p>
<p>とりあえず標準体重の範囲内に載せるのが目標。</p>
<h2>振り返ってみて</h2>
<p>今年はプライベートに時間を取られることも多く、そこまで意識的な学びができていないというか、特に夏以降は自転車操業のような気分になっていた。もともと長期的に物事を考えるタイプではなく、キャリアも目の前の課題に対してアプローチを繰り返すことで積み重ねてきている感じなのだけど、それだけだと限界かもしれないとも感じている。もっと考える時間が要る。会社のことにせよ自分のことにせよ、広く遠くまで見渡して仮説立ててやってみて、調整をしながら前に進む必要がある。そのためには時間も取るべきで、大学を中心としてきた生活もそろそろ終息しつつあるので、時間の使い方を来年はガラッと変えてみたい。</p>
<p>技術的な動向だと、Platform Engineeringとか、先端で話題になっているテーマをあんまり楽しめていない自分がいる。Generative AIもそこまで活用できていないし、自分の生産性をこれは本当に飛躍的に変える可能性があるのか、と若干疑いつつ、単に自分が上手く使えていないだけなのだろうなと今は思ってはいる。先端をたしなむ必要性が必ずしもあるわけではないし、それならそれで今使っている技術の基礎と先端をしっかり押さえようかな、というターンが今なのかもしれない。ちなみに年末年始はReactを触っている。TypeScript (JS) に慣れたい。</p>
<p>一方でいろいろ変化が大きいですね、とも思う昨今。Generative AIもそうだし、OpenTofuとか。来年はChromeでの3rd Party Cookie廃止もあるし。振り回されないようにしつつ、押さえるべきは押さえつつ。</p>
]]></description>
            <link>https://chroju.dev/blog/retrospective_2023</link>
            <guid isPermaLink="false">retrospective_2023</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 31 Dec 2023 01:28:27 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[今年買ってよかったものと、今年のサブスク 2023]]></title>
            <description><![CDATA[<h2>SESAME Touch</h2>
<p><a href="https://gyazo.com/1c0d7ba9e85c032822a69ba6b065da0e"><img src="https://i.gyazo.com/1c0d7ba9e85c032822a69ba6b065da0e.jpg" alt="Image from Gyazo" width="2560"/></a></p>
<p>スマートロックのSESAMEから、新たに出たオプションパーツ。指紋認証とICカード認証による鍵の開閉が可能になる。写真は左から旧型のSESAME mini、SESAME 5、SESAME Touch。</p>
<p>もともとSESAME自体は数年単位で使っていた。開閉方法はスマホアプリから操作するか、スマホとSESAME本体がBluetoothで接続されれば解錠される「手ぶら解錠」の2択だったのだが、アプリを起動するのは面倒だし、手ぶら解錠のほうは精度がいまいちで、解錠されないときもあれば、扉に到着するよりかなり早く解錠されるときもあったりで、使っていなかった。</p>
<p>現在はICカード認証をメインとして、スマホのNFCタッチで開けているが、だいぶ楽になった。両手が塞がっていてもスマホを取り出してかざすぐらいならなんとかなる。指紋認証をメインにすればさらに楽だとは思うものの、精度が良くなくて使わないままになっている。おそらくは同じ指で複数回登録すれば精度が上がる気はしている（スマホの指紋認証のような丁寧な登録ではなく、1回タッチしたら登録完了、になるので、少しでも角度が違うと認識しないっぽい）。</p>
<h2>Bellroy Melbourne Backpack</h2>
<p><a href="https://gyazo.com/c17c9b543cbe15e176f1705f4f8db9ba"><img src="https://i.gyazo.com/c17c9b543cbe15e176f1705f4f8db9ba.jpg" alt="Image from Gyazo" width="1512"/></a></p>
<p>Bellroyは2021年1月にClassic Backpackを買ったのが最初。当時も <a href="https://chroju.dev/blog/best_buy_subscriptions_2021">買って良かった</a> に挙げていた。このClassicが、特にストラップの付け根あたりが裂けてボロボロになってきてしまったので、買い換えようと改めて様々なブランドを探ってはみたが、結局またBellroyになった。</p>
<p>Bellroyは背負い心地が良い。背面部分がClassicだと「ランバーサポート」と称されており、硬すぎず柔らかすぎずちょうどいい具合に背中とぴったり合ってくれる。PCリュックは如何に背中から離さずPCを配置できるかが、重さを感じないためのポイントであり、その点でこれ以上のものに出会えなかった。あとはストラップが下にいくほど細くなっていて、脇の下あたりで異物感を感じづらくなっているのも良い。「背負っている感覚」が非常に薄い。</p>
<p><a href="https://gyazo.com/2bd307307b32f70e0b26f94b05cd6874"><img src="https://i.gyazo.com/2bd307307b32f70e0b26f94b05cd6874.jpg" alt="Image from Gyazo" width="2688"/></a></p>
<p>背負いやすさでいえばClassicのほうが細かい点で上ではあるのだが、同じものを使うのもつまらなくて今回はMelbourneに。トップローダーがマグネット式になっていて開閉しやすい点、防水のサイドポケットがついて、スマホが取り出しやすくなった点など気に入っている。</p>
<p>Bellroyの難点は、国内で置いている店が少ないこと。今回探してみたところ、大きなLoftには置いていることが多かったが、扱っているラインナップは限られるようだった。Amazonで買うのが一番早い。ただ、Bellroyのバッグは色によって素材が違ったりもするので、触らずに買うのはわりと罠かも。僕は一度買っているので、写真から「この見た目だと、この素材かな……？」と推測して買う技を使っている。</p>
<h2>Pomera DM250</h2>
<p><a href="https://gyazo.com/9b1228d4b06dd709001775d5683dccf5"><img src="https://i.gyazo.com/9b1228d4b06dd709001775d5683dccf5.jpg" alt="Image from Gyazo" width="2688"/></a></p>
<p>買った経緯などは <a href="https://chroju.hatenablog.jp/entry/20230924/dm250_why_do_i_write_a_blog">DM250と、書き留めるということと、わかりあえなさと。 - the world was not enough</a> で書いている。何か書き物をするときはやっぱりポメラのほうがPCより集中できる気がする。</p>
<p>背面がめちゃくちゃ指紋つきやすいので、 <a href="https://shop.masking-tape.jp/products/list.php?category=144">リメイクシート</a> を貼ってウィリアム・モリスなポメラにしている。</p>
<h2>Anker 511 Power Bank (PowerCore Fusion 30W)</h2>
<p><a href="https://gyazo.com/54cbb24b4b994898fa8f5086ecd104a7"><img src="https://i.gyazo.com/54cbb24b4b994898fa8f5086ecd104a7.jpg" alt="Image from Gyazo" width="2688"/></a></p>
<p>USB充電器としても使えるモバイルバッテリーの最新型。充電器として使ったときに従来だと20Wも出ない感じだったのが、今回30Wになったので、Macbook Airさえも急速充電できるようになったはず。今はバッテリーと65Wの充電器を両方持ち歩いているが、MBAに買い換えてPower Bankだけ持ち歩く生活にしたいと思っている。</p>
<h2>無印良品 携帯用のびのびボディタオル</h2>
<p><a href="https://gyazo.com/bec788100b7eaf0b4b3b4fb165f709c3"><img src="https://i.gyazo.com/bec788100b7eaf0b4b3b4fb165f709c3.jpg" alt="Image from Gyazo" width="2688"/></a></p>
<p>ホテルや旅館で風呂に入るとき、ボディスポンジがアメニティで置いていないときってどうやって身体洗います？という問題。素手でも、備え付けの普通のハンドタオルとかでも泡立てるのが難しくて洗った気にならなくて、1泊とかならいいけど連泊しているとちょっと気になっていた。</p>
<p>ということでこれ。携帯用ということでEVA樹脂製のケースがついているし、試しに使ったところ、タオル本体も浴室に一晩吊しておけば乾いてくれた。泡立ちもよくてGood。</p>
<h2>無印良品 香りを楽しむ炭酸水 ライム&#x26;エルダーフラワー</h2>
<p><a href="https://gyazo.com/b9d1ef963a73a0c4bd7702da18a4dd7d"><img src="https://i.gyazo.com/b9d1ef963a73a0c4bd7702da18a4dd7d.jpg" alt="Image from Gyazo" width="1512"/></a></p>
<p>またも無印。今年のベスト炭酸水。エルダーフラワーソーダはスッキリしていて若干の甘味が感じられるバランスで好きなのだが、あまり売られているのを見ない。これは今のところ夏ぐらいから恒常的に売られていて入手しやすい。炭酸は弱めなので、リラックスしたいときに飲む感じ。</p>
<h2>Subscriptions</h2>
<pre><code class="language-diff">  * Gyazo Pro (¥4,680 / year)
  * MoneyForward プレミアム会員 (¥500 / month)
  * Nintendo Switch Online + 追加パック (¥4,900 / year)
- * Amazon Prime Student (¥2,450 / year)
- * Spotify Premium Student (¥480 / month)
+ * Spotify Permium Duo (¥1280 / month)
  * シネマシティ (¥1,000 / year)
  * Workflowy Pro ($49 / year)
  * dアニメストア (¥400 / month)
  * メールマガジン「読書日記／フヅクエラジオ」 (¥800 / month)
  * ATOK Passport (¥300 / month)
  * IFTTT Pro ($1.99 / month)
  * O’Reilly Online Learning ($299 / year)
- * Mailbrew ($59.88 / year)
- * Tile Premium (¥3,600 / year)
+ * Google One スタンダード (¥2,500 / year)
+ * Readwise ($7.99 / month)
+ * Raycast Pro ($96 / year)
</code></pre>
<p>解約周りだと、Amazon Prime Studentは学生向けということで最大4年間しか使えず、今年で4年を過ぎた。これを機にAmazonから少し距離を置いてもいいかなーと思って、通常のPrimeで再契約することはしていない。</p>
<p>Spotifyのほうはこれは自主的な解約で、家族2人で入るならPremium + StudentよりDuoのほうが安いと今更気付いたからです。。</p>
<p>Mailbrewは解約ではなく、無償提供に変わったという珍しいパターン。Twitter APIのゴタゴタがあった際、すぐに反応がなかったりなど継続性に不安はあるが、無償だし、ということで使ってはいる。</p>
<p><a href="https://thetileapp.jp/premium/">Tile Premium</a> は、スマートタグのTileで置き忘れアラートを有効化するのに必要だった契約。最近、サブスク契約が不要な <a href="https://www.ankerjapan.com/pages/eufy-smarttrack">Anker Eufy Security SmartTrack</a> に乗り換えた。「買ってよかった」に入れていないのは、置き忘れアラートが鳴るまでのスパンがTileよりちょっと遅かったり、まだ「良い」と言い切れない部分がある感じ。</p>
<p>新たに契約したものだと、Google Oneは写真の保存容量が無料枠だとまかなえなくなったため。Readwiseはすでに何度か書いている通り。</p>
<p>https://chroju.dev/blog/readwise_reader_is_so_good</p>
<p><a href="https://www.raycast.com/pro">Raycast Pro</a> はほぼAIだけを目当てで使っている。OpenAIのChatGPTは、ブラウザをわざわざ開くのが面倒で使う習慣ができなかったが、Raycastのランチャーから呼べるとわりと気軽に使う感覚が身についてきた。Raycast AIだとプロンプトを保存しておくことができるのもいい。プロンプトには「選択中の文字列」を渡すことなどもできるので、「今選択してる文字列を和訳せよ」とかもできる。</p>
<p><a href="https://gyazo.com/58a06afa2ddf19d1bd3784a9acd8816a"><img src="https://i.gyazo.com/58a06afa2ddf19d1bd3784a9acd8816a.png" alt="Image from Gyazo" width="742"/></a></p>
<p>これでOpenAIより安くGPT4も使えるから十分かな、と。Generative AIは何かしら使っていかないとマズそうだよな、という思いが強くて、もっと活用してはいきたいところ。</p>
<h3>サブスク契約に至る閾値</h3>
<p>単純に価格の多寡で決めてるわけでもないし、結構これは感覚だな、と今年は突きつけられた気がする。Raycast Proの年間$96は決して安くないが、Generative AIはマスト、という気持ちで契約した。一方で最近 <a href="https://kapeli.com/dash">Dash</a> が月間210円のサブスク型へ転換したが、こちらは不思議なことに渋っている自分がいる。</p>
<p>ひとつあるのは、月々の課金よりannually planがあるほうが財布の紐が緩みやすい。あんまり毎月の固定費というのを作りたくなくて、払うなら一気にポンのほうが個人的には好き。</p>
<p>そもそも「できる限り増やしたくない」というのも当然ある。本当に必要なものだけを契約したいし、ちゃんとプラスになるようなお金の使い方をしたい。まだもう少し減らしたい気持ちが正直なところ。定期的に固定で出るお金なんて、少ないに越したことはないのだ。</p>
]]></description>
            <link>https://chroju.dev/blog/best_buy_subscriptions_2023</link>
            <guid isPermaLink="false">best_buy_subscriptions_2023</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 29 Dec 2023 00:06:03 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Readwise Readerで効率的にインプットする]]></title>
            <description><![CDATA[<p>以前、 <a href="https://chroju.dev/blog/readwise_reader">RSSもPDFもYouTubeも、全部Readwise Readerで「読む」 - chroju.dev</a> というエントリを書いた。それから半年以上、ずっと <a href="https://read.readwise.io">Readwise Reader</a> を使っており、インプットが効率化されてきて改めて良いな〜とおもうので，どんな感じで使っているかをちょっと書いておく。先に書いておくが、ここで書く機能を使うには$7.99/月の契約が要る。</p>
<p>そもそもReadwise Readerって何？という点は先のエントリを……というところではあるのだが、ウェブページを中心として様々なものを「読む・読み返す」ためのサービスであり、以下のようなサイクルで読んでいくことになる。</p>
<ul>
<li><strong>収集</strong>: 読むかもしれない記事を自動収集する</li>
<li><strong>保存</strong>: 読みたい記事を保存しておく</li>
<li><strong>閲覧</strong>: 記事を読む、読んで記録をつける</li>
<li><strong>再読</strong>: 記事の抜粋などを読み返す</li>
</ul>
<h2>収集</h2>
<p><a href="https://gyazo.com/30c782099c7a675e2ff00d9a51f34077"><img src="https://i.gyazo.com/30c782099c7a675e2ff00d9a51f34077.png" alt="Image from Gyazo" width="239"/></a></p>
<p>Readwise Readerには、記事を集めておくところが2つある。UIの左上、「Feed」と、画像でFeedの上にあるアイコンが「Library」。「Feed」は自動的に記事を集める場所であり、「Library」は手動で記事を保存する場所にあたる。まずはFeedに記事を集め、そこから読みたいものをLibraryに送り込む。要するところ、FeedはRSSリーダーである。</p>
<h3>tips: 重要度の低いメールもFeedに入れる</h3>
<p>FeedとLibraryにはそれぞれ、メールアドレスが割り当てられており、それぞれメールを送って本文を保存させることができる。</p>
<p>個人的に、Gmail上では「必ず読むもの」だけを扱いたいと思っているので、「できたら読みたい」程度のメールはFeedに入れることにしている。メールマガジンなどを入れるのが主な使い道だが、他だと <a href="https://connpass.com/dashboard/">connpass</a> のイベント開催通知もFeedに飛ばしている。connpassは一度イベントに参加すると、その主催者のグループへ自動的に参加することになり、メール通知もデフォルト有効になっているのがちょっと面倒だったりするが、全部Feedに飛ばしてしまえばメールボックスはすっきりするし、必要なタイミングで読みやすくなった。</p>
<h3>tips: 高優先度のRSSはフィルタしておく</h3>
<p><a href="https://gyazo.com/2db874e807487db82dcd19eb8b4d9e18"><img src="https://i.gyazo.com/2db874e807487db82dcd19eb8b4d9e18.png" alt="Image from Gyazo" width="894"/></a></p>
<p>Readwise Readerは様々なフィルタを通したカスタムビューが作れる。登録したRSSフィードは、それぞれ任意のカスタムビューに送るよう設定することができるので、高優先度のRSSはフィルタできるようにしておくと良い。数日間Feedを消化できなったときは、高優先度のものだけ目を通して、あとは消している。</p>
<h2>保存</h2>
<p>Libraryに記事を保存する。Feedやメールから保存するだけではなくて、 <a href="https://getpocket.com/">Pocket</a> のようにブラウザの拡張機能からも保存できるし、PDF、ePubなどのファイルも保存できる。YouTubeの動画も保存できて、文字起こしもしてくれるので動画が苦手な人には便利、というのは前回も書いた。</p>
<h2>閲覧</h2>
<p>Libraryに保存したら、あとは順に時間のあるときに読んでいく。ちなみに、おそらく最近の変更なのだが、Libraryに保存するとGPT3.5による要約が自動的に付加されるようになった。</p>
<p>記事にはハイライトをしたり、コメントを入れたりすることができる。ハイライトは頻繁に入れておくと、次に書く「再読」の行程で役に立つ。コメントは面倒なのもあってあまり入れていない。コメント入れるほどなら、Scrapboxにメモを書いている。</p>
<h3>tips: PDFを翻訳する</h3>
<p><a href="https://gyazo.com/a194d8e445cb71896acc12bf29446f21"><img src="https://i.gyazo.com/a194d8e445cb71896acc12bf29446f21.png" alt="Image from Gyazo" width="1062"/></a></p>
<p>PDFはファイルそのままの体裁で読むこともできるが、文字列だけを抽出して表示する「Text View」にすることもできる。これの何が便利かと言えば、ブラウザ拡張のGoogle翻訳が使えるようになること。英語のPDFでもあっという間に全文翻訳できる。PDF翻訳にはDeepLを使ったりいろいろ試みてきたが、これが一番楽。</p>
<h3>tips: しばらく読んでいない記事をフィルタする</h3>
<p>先述の通りカスタムビューが作れるのだが、フィルタに使える検索条件がかなり豊富で、「最近読んでいない記事」をフィルタすることもできる。これを使って、しばらく読んでいない記事をフィルタして優先的に読んだり、一気に消したりしている。</p>
<p>具体的には以下のようなフィルタを使っている。Readwise Readerは各記事の「読んでいる位置」を記録しており、 <code>progress__lt:1</code> でフィルタとすると、まったく読み進めていない記事を抽出できる。これと <code>saved__before:"1 month ago"</code> のAND条件とすることで、1か月以上前に保存したがまったく読んでいない記事がフィルタされる。</p>
<pre><code class="language-bash">progress__lt:1 AND saved__before:"1 month ago" AND in:later
</code></pre>
<p>ちなみに、フィルタは様々な活用例が公式の <a href="https://readwise.notion.site/readwise/Reader-Filtering-Guide-d4b249df2eaa492283099ec2a3551640">Reader Filtering Guide</a> にまとめられている。</p>
<h3>tips: 要らない記事は消す</h3>
<p>Libraryの中の記事はステータス管理ができて、読み終わったら基本的にはアーカイブすることになる。</p>
<p>自分の場合、読んだものの再読の可能性が低そうな記事については、アーカイブではなく削除している。これはReadwise Readerの検索機能が、アーカイブを含めてLibrary内の全記事を対象としているため。検索のノイズを減らしている。</p>
<h3>tips: 読み上げ機能がある</h3>
<p>モバイルだと読み上げ機能がある。日本語もOK。僕は耳からのインプットが苦手なのであまり使っていないが、PodcastやAudibleが好きな人には便利かもしれない。</p>
<h2>再読</h2>
<p><a href="https://gyazo.com/e550c186a8719c55b9165761df7bf2cb"><img src="https://i.gyazo.com/e550c186a8719c55b9165761df7bf2cb.png" alt="Image from Gyazo" width="1366.48"/></a></p>
<p>Readwiseで最も肝になるのがこの機能だと思う。</p>
<p>そもそもReadwise Readerは <a href="https://readwise.io">Readwise</a> の付随サービスであり、Readerを使う際は自ずとReadwiseのアカウントを作ることになる。このReadwiseが何かと言えば、Kindle、Pocket、物理的な本などからハイライトを集めるツールであり、Readwise Readerのハイライトも自動的に収集してくれる。</p>
<p><a href="https://gyazo.com/78c560a3007ef552726397be651c5d4d"><img src="https://i.gyazo.com/78c560a3007ef552726397be651c5d4d.png" alt="Image from Gyazo" width="950.04"/></a></p>
<p>Readwiseが面白いのはDaily Reviewと言って、過去のハイライトから指定した数だけピックアップして再読する機能があること。Daily Reviewは1日1回指定した時間に作られ、メールで受け取ることもできる。</p>
<p>この機能は <a href="https://ja.wikipedia.org/wiki/%E5%BF%98%E5%8D%B4%E6%9B%B2%E7%B7%9A">忘却曲線</a> の理論に則っている。忘却曲線は簡単に言えば「覚えづらいものほど早く復習すると覚えやすくなる」ものであり、Daily Reviewにおいては、これに従って各ハイライトを早めにもう一度表示させるか、しばらく間を空けるかを選択していく。RSSは「読んだら読みっぱなし」になることも少なくないと思うが、この機能のおかげで頻繁に見返すことができるのが良い。</p>
<h3>tips: 物理的な本のハイライトも集める</h3>
<p>物理的な本についても、ページを写真に撮ってOCRでハイライトを取り込める。日本語でもOK。</p>
<p>本の場合はハイライト箇所が多かったりするので、1冊分を取り込むとDaily Reviewがしばらくその本のハイライトだらけになったりもする。そういうときにはDaily Reviewへの出現頻度を調整もできる。</p>
<p><a href="https://gyazo.com/124e6b1809f99704db17824b8e538a1c"><img src="https://i.gyazo.com/124e6b1809f99704db17824b8e538a1c.png" alt="Image from Gyazo" width="503.87999999999994"/></a></p>
<p>そのほか、自分が取り込んでいるのはO'Reilly LearningとGoogle Play Books。ただ、いずれも自動取り込みではなくて、手動でのエクスポート/インポートになる。Kindleがamazon.co.jp版には対応していないのが残念なところ。</p>
<h3>tips: 翻訳状態でハイライトすると、そのまま取り込まれる</h3>
<p>先ほど書いたようにGoogle翻訳で翻訳した状態でもハイライトができ、その場合は翻訳後の文字列がReadwiseに収集される。翻訳を解除すると該当のページからはハイライトの痕跡は消えるのだが、記録としてだけは残る。もしかしたらバグなのかも？とも思える挙動だが、見返すときは日本語のほうがやはり頭に入るので、結構積極的に翻訳してハイライトしている。</p>
<h3>tips: ハイライトをNotionに送る</h3>
<p>Readwiseに取り込んだハイライトを、自動的にNotionへ送り込む機能がある。あんまり有効活用はできていないが、Notionだと様々にビューを作れるのが利点だと思う。Obsidian、Logseqなどにも取り込み用のプラグインがあるらしい。</p>
<h2>Readwiseで全部読む</h2>
<p>以上、最近はこんな感じのサイクルでインプットをしている。特に「翻訳ができる」「ハイライトを復習できる」というあたりがキラー機能で、このサイクルに載せたいがために、PDFでもePubでもとにかく全部ツッコんで集約するようになった。ハイライトすれば後でまた読めるから、ざっくり読んで気になったところだけハイライトをしておいて、後で改めてじっくり読む、みたいな感覚にもなりつつある。</p>
<p>別にReadwiseからお金をもらっているわけでもなんでもないのだが、2回もエントリにするぐらいには気に入っているし、日本語圏でもっと流行って欲しくてかなり細かく書いてみた。おすすめ。</p>
]]></description>
            <link>https://chroju.dev/blog/readwise_reader_is_so_good</link>
            <guid isPermaLink="false">readwise_reader_is_so_good</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 22 Dec 2023 13:27:10 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Terraform Cloudで課金対象となるリソース合計数を、コマンドで取得する]]></title>
            <description><![CDATA[<p>宣伝記事です。</p>
<p>https://www.hashicorp.com/blog/terraform-cloud-updates-plans-with-an-enhanced-free-tier-and-more-flexibility</p>
<p>2023年5月より、Terraform Cloudで新しい料金体系が導入された。多くの人が使うであろう、Free tierと真ん中のStandard tierはリソース数に応じた課金（Freeはリソース数500までの制限）、という説明になっているが、パッと見では、何のリソースのことかよくわからない。</p>
<p>結論から言うと、Terraform Cloudに保存しているState上に記録されたリソース数の合計ということになる。要するに <code>terraform state list</code> で出てくるリソースの数ということになるのだが、 <code>null_resource</code> や <code>data</code> は含まないということで、ただそのまま数えればいいというわけではない。</p>
<p>https://dev.classmethod.jp/articles/tfc-pricing-resource/</p>
<p>こちらのClassmethodの記事にそのあたりは詳しく書いてあり、Terraform CloudのGUI上における数え方も記載されている。ただ残念なのは、まだ新料金体系で契約をしていない場合、課金対象となるOrganization全体のリソース数を直接見る手段がなく、各Workspaceのリソース数を1つずつ見て足し合わせるしかないということだ。Standard tierへ移行する前に、どの程度の料金になるのか見積もりたくても、そのための手段がないというのは、ちょっと不便だと思う。</p>
<p>というところで宣伝にはなるが、Terraform CloudのAPIを実行する <a href="https://github.com/chroju/tfcloud">tfcloud</a> というCLIツールを以前から作っている。これの <code>workspace view</code> コマンドを使えば、以下のようにリソース数を始めとした情報を取得できる。何もオプションを付けずに実行すれば、カレントディレクトリのTerraformの設定を見て、そのbackendとなっているWorkspaceの情報を取得する。</p>
<pre><code class="language-bash">$ tfcloud workspace view
Name:               test-a
Terraform Version:  1.6.2
VCS Repo:
Working Directory:
Execution mode:     local
Auto Apply:         false
Resource count:     1
Created at:         2023-05-05 00:16:03 (UTC)
Updated at:         2023-08-02 10:42:25 (UTC)
URL:                https://app.terraform.io/app/chroju/workspaces/test-a
</code></pre>
<p>すべてのWorkspaceの情報を一括で取得するなら <code>workspace list</code> コマンドを使えばいい。 <code>--format json</code> を付加すれば、全Workspaceの情報が単純に配列になった形の雑なJSON構造で落ちてくるので、こういう感じでjqを使えば一発でリソース数合計も取れる。</p>
<pre><code class="language-json">$ tfcloud workspace list chroju --format json | jq '[.[].resource_count] | add'
122
</code></pre>
<p>tfcloud、ローカルからTerraform Cloudの情報を取るのには結構便利で、自分用のツールとしてちまちまと使い続けている。最近 <a href="https://github.com/hashicorp/tfc-workflows-tooling">tfc-workflows-tooling</a> という、Terraform CloudのAPIを実行する公式のツールも出てきたので、tfcloudはお役御免になるかなと期待もしているが、こちらは <code>plan</code> や <code>discard</code> を実行する、本当にワークフロー周りのAPIしか実装しないようで、しばらくはtfcloudが必要そうだ。OpenTofuの顛末を見ていると、これも名前を変えたほうがいいのかな、とちょっと思っている。</p>
]]></description>
            <link>https://chroju.dev/blog/terraform_cloud_resources_count</link>
            <guid isPermaLink="false">terraform_cloud_resources_count</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 13 Nov 2023 10:04:51 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Twitter (X) からの避難先としてPleromaを建てた]]></title>
            <description><![CDATA[<p>最近X（旧Twitter）からの避難先として <a href="https://pleroma.chroju.dev/users/chroju">@chroju@pleroma.chroju.dev</a> を使い始めたので、そのあたりの背景などを書く。 <a href="https://pleroma.social/">Pleroma</a> はMastodonのようなFediverseを実現するソフトウェアの1つで、ActivityPubに対応している。</p>
<p>ちなみにX（旧Twitter）を緩やかに離れたいな、みたいな気持ちは別ブログのほうに以前したためた。わりとPleromaを使っていけそうなので、今後の投稿メインはゆるゆるとPleromaのほうに移していきたいと考えている。Mastodonやmisskeyをやっていたらフォローを是非。</p>
<p>https://chroju.hatenablog.jp/entry/20230709/without_twitter</p>
<p>Twitterから心が離れる理由を掻い摘まんで書くと。フォローしていない人のツイートを目にしやすくなったとか、TweetDeckが使えなくなった、といった「見る」側の問題がいろいろあった。一方で、自分は最近こんな記事を書いて、こんなことに興味がありますよ、というのを時系列で書いて「見られる」ためのツールとしては重宝していたのだが、それも最近の仕様変更で、ログインしていない人には時系列でユーザーページを見てもらうことも困難になり、自分の活動を示すパブリックなタイムラインとしても活用が難しくなった、というのが離れたい一番の原因。</p>
<h2>Alt-Twitterに何を求めるのか</h2>
<p>Twitterからの避難先はThreads、Mastodon、misskeyなど群雄割拠の様相を呈している。</p>
<p>避難先に求めることの第一はオープンであることだった。Twitterの仕様変更で、徐々に閉鎖的になっていくのが最もしんどかった。昨今の状況を鑑みると、特にActivityPubに対応していることを求めた。よってBlueskyやThreads（今後ActivityPub対応の予定があるとのことで、アカウントは取得したが）は候補にならなかった。</p>
<p>また、Twitterが運営者の一声でこうなってしまったことを考えると、第三者に運営を委ねるのではなくて、セルフホストするほうがいいのではないかと考えた。とはいえリソースを多く使うものは避けたいので、軽量な実装を調べた結果、行き着いたのが <a href="https://pleroma.social/">Pleroma</a> だった。もちろん実際に使ってみないことには軽量かどうかはわからないが、いくらか先駆者の話を読んでみると期待ができそうに思えた。</p>
<ul>
<li><a href="https://h3poteto.hatenablog.com/entry/2019/12/09/180020">Pleromaはいいぞ - PartyIX</a></li>
<li><a href="https://blog.3qe.us/entry/2023/04/09/220252#%E6%84%9F%E6%83%B3">軽量MastodonことPleromaインスタンスを立てたメモ - Lambdaカクテル</a></li>
</ul>
<h2>Wildebeestというロマン</h2>
<p>Pleromaを立ち上げる以前、 <a href="https://github.com/cloudflare/wildebeest">Wildebeest</a> も一時期セルフホストして使っていた。これはCloudflareが開発していたActivityPub対応のSNSで、大きな特徴としてCloudflare WorkersをはじめとしたCloudflareスタックだけでホスティング環境が整う点にあった。最低月額$5というかなりの少額で運用が可能だった上、構築に必要なTerraformやCloudflareのコマンド実行もGitHub Actionsで定義されており、レポジトリをforkしてAPIキーなどを設定し、Actionを実行するだけで環境が整う、という手軽さがあった。</p>
<p>たださすがにいろいろと厳しかったようで、使ってみると様々な部分で動作が不安定であり、最終的には2023年7月にメンテナンス停止が告知された。エッジサーバーで動くSNS、というのは2023年っぽい実装ではあって期待したかったのだが、ロマンとして終わってしまった。</p>
<h2>Pleromaのセルフホスト</h2>
<h3>インフラ</h3>
<p>ホスティング環境としては、Kubernetes検証用に建てていたK3sを使っている。</p>
<p>PleromaはDockerイメージが公式には提供されていないのだが、READMEでいくらかサードパーティでの実装が紹介されており、そのうちの1つである <a href="https://github.com/angristan/docker-pleroma">angristan/docker-pleroma</a> を使わせてもらっている。このレポジトリもイメージをビルドして公開するところまではしていないため、forkしてGitHub Actionでビルドすることにした。ほぼそのまま動いたが、設定ファイルである <code>config.exs</code> の「その他」に対するパーミッションが、最近のPleromaだと <code>0</code> になっている必要があり、その点だけ修正している（そういえばPRしても良さそうだ）。</p>
<pre><code class="language-diff">- COPY ./config.exs /etc/pleroma/config.exs
+ COPY --chown=pleroma --chmod=440 ./config.exs /etc/pleroma/config.exs
</code></pre>
<p>なお外部公開には <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/">Cloudflare Tunnel</a> を使っている。ngrokのようなものだが、Cloudflare DNSを使えば好きなドメインを当てることができ、最近の外部公開には全部これを活用している。K3sでcloudflaredをコンテナ起動させており、常時トンネルは開通した状態にあるので、あとはCloudflareのGUI側でどのドメインをどのポートにマッピングするかの設定だけで済む。</p>
<h3>データの永続化</h3>
<p>データの永続化については基本的にはRDBであり、PostgreSQLを使う。これについてもコンテナでまかなっている。一方でファイルシステムに書き込むものとして、 <a href="https://docs.pleroma.social/backend/configuration/static_dir/">Static Directory</a> と <code>uploads</code> がある。前者はフロントエンドで使う、例えばインスタンス全体の背景画像を設定できるのだが、そういったファイルが保存される。後者はユーザーが投稿した画像などの保存先だが、これはAmazon S3に変更することもできる。現状はそこまで画像を投稿するつもりもないのでローカルのままとした。いずれもPersistentVolumeを使い、フォルダパスは設定ファイル上で指定している。</p>
<pre><code class="language-elixir">config :pleroma, :instance,
  static_dir: "/var/lib/pleroma/static"

config :pleroma, Pleroma.Uploaders.Local,
  uploads: "/var/lib/pleroma/uploads"
</code></pre>
<h3>config.exs</h3>
<p>設定ファイルは <code>/etc/pleroma/config.exs</code> というものがあり、ここに基本的なものを書く。自分のインスタンスでは以下の設定をしており、K8s環境なのでConfigMapでマウントしている。</p>
<pre><code class="language-elixir"># Shoutboxという簡易的なchat機能を無効化
config :pleroma, :shout,
  enabled: false

# UIを通じたユーザー登録の無効化
config :pleroma, :instance,
  registrations_open: false,

# 画像アップロード時のオプション
# mogrify -stripによりEXIFを削除する
# ファイル名の難読化を行う
config :pleroma, Pleroma.Upload.Filter.Mogrify, args: ["strip"]
config :pleroma, Pleroma.Upload,
  filters: [Pleroma.Upload.Filter.Dedupe,Pleroma.Upload.Filter.AnonymizeFilename,Pleroma.Upload.Filter.Mogrify]
</code></pre>
<p>おひとりさま用なので、新規登録を受け付けないようにするのは重要なポイント。自分のユーザーを作るにはどうするのか、という話があるが、 <code>pleroma_ctl</code> というCLIが内包されており、 <code>pleroma_ctl user new hogefuga hogefuga@example.com --admin</code> で作成できる。このとき <code>--admin</code> を付与すると、後述する管理者ユーザーとして振る舞えるようになる。</p>
<p>その他、 <a href="https://docs.pleroma.social/backend/configuration/cheatsheet/#static_fe">Configuration Cheat Sheet - Pleroma Documentation</a> 全体をざっくり見て必要な設定を施せばよい。</p>
<h3>Admin FE</h3>
<p>管理者ユーザーとしてログインすると、右上にタコメーターのようなマークが表示され、ここから管理者設定を触れる。多くは <code>config.exs</code> で設定できる内容ではあるが、一部はおそらくここからしか設定できない、あるいはここで設定したほうが簡単な気がしている。</p>
<p>僕が設定しているのは <code>Settings > Others > Term of Service</code> ぐらい。ToSはどうも一度Admin FEで編集しないと、 Static DirectoryにHTMLが出力されないように見える。</p>
<h2>現状と感想</h2>
<h3>ホスティングの状況</h3>
<p>現状、スワップを有効化したt4g.small上でK3sを動作させており、そこには別のアプリケーションも載っているのだが、インスタンス全体でのCPU使用率は10％にも満たない値で推移しており、だいぶ安定している。まだフォロー/フォロワー数も投稿数も少ないというのはもちろんあるが、予想以上にリソースを食べる気配がなくて嬉しい。Gravitonのおかげというのもある。</p>
<h3>Static FEが好き</h3>
<p>機能的にも、一般的に想定されるものはいずれも問題なく動く。Pleroma独特のところだとStatic FEというものが好きだ。これは設定でデフォルト無効になっているのだが、有効化すると、インスタンスに登録されているユーザーやポスト（status）のパーマリンクを開いた際、JavaScriptを用いない静的なHTMLで表示してくれる。</p>
<p><a href="https://gyazo.com/c4f6db5efc77500de879af85b756198c"><img src="https://i.gyazo.com/c4f6db5efc77500de879af85b756198c.png" alt="Image from Gyazo"></a></p>
<p>PleromaのみならずMastodonでもmisskeyでもそうだが、ブラウザからアクセスすると、当然ながらSNSのアプリケーションとしてのUIが基本的には表示される。しかし、このPleromaはおひとりさま用で建てているがために、僕以外の人にとってはここにアプリケーションとしての価値はない。ならばSNS的な要素を削ぎ落とし、読むことに特化した静的なページとして表示すればよい、というのは良いアイデアだな、と感じた。冒頭に書いた通り、僕はこの手のSNSを「パブリックなタイムラインとしての自分の活動」を示すために使っているので、このStatic FEはまさにうってつけだった。</p>
<h3>TLをどう構築するか</h3>
<p>おひとり様インスタンスなので不特定な投稿が乱入してくることはない。おすすめや広告の形で、フォローしていない見知らぬ人がTLに跋扈するようになったTwitterに比べてだいぶ快適になった。</p>
<p>一方で、逆に投稿が少なすぎて今は苦慮している。Mastodon界隈で付きものの「誰をフォローすればよいのかわからない」問題がある。Twitterでフォローしている人のActivityPubアカウントを探す手段もないし、自分のインスタンスには誰もいないので検索で探しようもない。あまり多量のフォローをする気もないのだが、日常的な情報収集も兼ねてもう少し欲しいところではあり、どうしたものかと考えている。</p>
<p>みんなどうしているのか。思いつくのはmstdn.jpのような大手のインスタンスで検索してみることぐらいだが。</p>
<h3>Elixirわからない問題</h3>
<p>PleromaはElixirで実装されており、Dockerfileを読み解くにあたってmixコマンドぐらいは把握したが、コードは読めないし、今後学ぼうという気も現状あまりないのがどうなんだこれは、というのはある。その点だとRuby製のMastodonは敷居が低かったのかもしれない。あるいはPleromaを建てた後で知ったが、 <a href="https://github.com/superseriousbusiness/gotosocial">gotosocial</a> というGoのActivityPub実装もある。</p>
<p>セルフホストしているとはいえ、Pleromaは他者が開発しているOSSであり、結局のところ誰かに依存している点から抜け出せてはいない。そのことを考えても、ある程度自分でコードを読み書きできるようになっておくべきだろうとは感じている。</p>
<p>あるいは自分でActivityPubを実装するか。最近 <a href="https://blog.tyage.net/post/2023/2023-07-17-bridgy-fed/">このブログがFediverseに対応しました</a> や <a href="https://kayamatetsu.com/">kayamatetsu.com</a> のように、静的なブログのようなサイトでありながら、ActivityPubに対応する例もあり、これについても興味は惹かれる。少なくともどのようなプロトコルなのかはもう少し把握したい。</p>
<h3>X（旧Twitter）との兼ね合い</h3>
<p>Twitterをやめるということはないだろう、とは思っている。フォロー/フォロワーの関係性にしてもそうだし、Pleromaには現状人がいないので、災害時などに不特定多数の投稿から検索して状況を確認したい、という用途だと今後もTwitterの優位性は揺らがないんじゃないか。これ以上に人が集まるリアルタイムSNSが出てくる気はしないし、Twitterがそこまでユーザーを減らすこともなさそうではある。Threadsあたりか、どこかのmastodonインスタンスが超巨大になって、十分に代替可能になる、ということはあるかもしれないが。</p>
<p>ただ日常的な「SNS欲」を満たしたり、何かを自分がメインで投稿する場はPleromaにしていきたい、というつもり。</p>
]]></description>
            <link>https://chroju.dev/blog/twitter_to_pleroma</link>
            <guid isPermaLink="false">twitter_to_pleroma</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 23 Oct 2023 01:01:57 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Platform EngineeringとSREと「ちいとぽ」と]]></title>
            <description><![CDATA[<p>https://ascii.jp/elem/000/004/157/4157089/</p>
<p>先日こんな記事を読んだ。僕もPlatform Engineeringについては多少なり追ってはいるが、正直よくわかっていないというか、いまいち捉えどころがないと感じている。このエントリーは現時点における自分のPlatform Engineeringに対する認識の覚書であり、間違っている部分も多々あるかとは思う。</p>
<h2>原義</h2>
<p>Platform Engineeringについて調べていると、Gartnerの「<a href="https://www.gartner.co.jp/ja/newsroom/press-releases/pr-20220816">先進テクノロジのハイプ・サイクル : 2022年</a>」での登場が発端であるとする記事が多く見られる。そのGartnerにおける <a href="https://www.gartner.co.jp/ja/articles/what-is-platform-engineering">プラットフォーム・エンジニアリングとは何か？ | ガートナー</a> という記事から引いてみる。</p>
<blockquote>
<p>プラットフォーム・エンジニアリングは、インフラストラクチャ・オペレーションの自動化とセルフサービス機能により、開発者エクスペリエンスと生産性を向上させます。開発者エクスペリエンスを最適化し、プロダクト・チームによる顧客価値のデリバリを加速させることが期待できるため、大きく注目されています。</p>
</blockquote>
<p>ソフトウェアデリバリにおいて必要なインフラの構築を単に自動化するのではなく、開発者がセルフサービスで扱えるようにするというのがポイントだと捉えている。ここでは「インフラストラクチャ・オペレーション」と書かれているので、構築部分だけではなく、その後運用フェーズに入ってからのチューニングなども同様にセルフサービスとするのだろう。</p>
<p>ところで、僕が最初にPlatform Engineeringという単語を見かけたのは、Honeycombによる <a href="https://www.honeycomb.io/blog/future-ops-platform-engineering">The Future of Ops Is Platform Engineering | Honeycomb</a> という記事だった。先の2022年ハイプ・サイクルが発表された1か月後に書かれた記事だが、もともとHoneycomb内で実践していたプラクティスをPlatform Engineeringと名付けた、としており、Gartnerの発表との前後関係はわからない。</p>
<p>定義に大差はなく、「これは、サードパーティ プラットフォーム プロバイダーの運用スタックの評価と組み立てに特化しており、ソフトウェア エンジニアがセルフサービスでサービスを提供し、運用環境で独自のコードを所有できるようにします（Google翻訳）」「operations engineering minus the infrastructure」と書かれている。ただ、こちらのほうが、なぜこういったプラクティスが必要なのか丁寧に書かれており、納得感はある。曰く、開発者がコアとなる機能開発に集中できるようにするため、Platform Engineeringは、開発者がコードを実行するのに必要な作業をセルフサービスかつ、認知負荷の低い形で提供する。</p>
<h2>IDPの必要性</h2>
<p>昨今のインフラ、特にKubernetesを巡るエコシステムが相応に複雑化しているのは確かであり、これを開発者が直接的に取り扱うのではなく、ある程度抽象化して提供する、というのは理解できる。「operations engineering minus the infrastructure」はこれをよく表していると思う。</p>
<p>Platform Engineeringを追っているとよく言及されるのが、このプラクティスの実現にIDP（Internal Developer Platform）が必要である、ということだ。ツールとしては<a href="https://www.crossplane.io/">Crossplane</a>や<a href="https://backstage.io/">Backstage</a>が挙げられることが多く、統一的なインターフェースであらゆるインフラを払い出せるようなものが想定されている。最近Terraform Cloudでも、moduleの変数をGUIから入力して展開する<a href="https://www.hashicorp.com/blog/terraform-cloud-no-code-provisioning-is-now-ga-with-new-features">no-code provisioning</a>がGAになったが、文脈としては同じものだろう。</p>
<p>確かに「開発者へ認知負荷低くコード実行環境のプロビジョニングを提供する」となると、こういったツールに収束していくのは理解できる。気になるのは、先のGartnerの記事において「プラットフォーム構築の初期段階は、最も成熟度の高い社内開発者ポータル (IDP) から開始することがほとんどです」と書かれているように、半ばIDPの利用がPlatform Engineeringの実践上不可欠であるかのような印象を受けることだ。この手のプラクティスが、あるツールの利用を必要条件とするのは、あまり好ましくないように思うし、例えばマイクロサービスでバンバン環境を立ち上げるような組織でもなければ、IDPを維持管理するメリットは大きくないように思える。IDPを使わず、ドキュメンテーションやその他のツール群によるアプローチもあり得るのではないかと思うが、IDPを使わなければPlatform Engineeringを名乗るべきではないのだろうか。このあたりが掴めない。</p>
<h2>SREとの関係性</h2>
<p>SREとPlatform Engineeringは基本的には無関係というか、後者が前者の発展系や一類型といった類のものではないと認識している。SREは信頼性が第一に置かれ、どちらかといえばシステムの運用に比重が置かれる一方、Platform Engineeringはシステムの構築段階における工数やコストの削減に対する関心が大きい。基本的な目的はそれぞれ異なる。</p>
<p>ただ国内においては、事実上SREチームが横断的なインフラストラクチャチームを兼ねている場合も少なくない。以前書いた<a href="https://chroju.dev/blog/types_of_sre_teams">Embedded SREとは何か - SREの組織類型についての覚書</a>という記事で紹介した、Googleによる「SREチームの組織類型」の中にも、監視システムを含め共通的なインフラ整備を行う、Infrastructure SREという類型が存在する。</p>
<p>そういった役割を内包したSREチームが、インフラ構築における負荷を軽減するために、Platform Engineeringを取り込んでいく、あるいはその役割を分離していくという考え方はあり得るように思う。言ってしまえば、Platform EngineeringはEliminate toilの一環ではあり、SREと目的が交差する部分も大いに存在する。Platform Engineeringには、その構築した環境がReliableであるべきだ、という話が出てくるわけではないが、当然ながらそれは求められるわけだし、むしろ標準化を進めるのであればReliabilityやSecurityを組み込んだPlatformであることは自ずと必要になる。SREとPlatform Engineeringは同じロールではないが、協力関係にはあると見ている。</p>
<p>個人的には <code>class DevOps implements SRE</code> という言葉にあんまりしっくり来ていなかった（結果的にSREの活動はDevOpsの実装に近くはなるが、DevOpsという言葉が目指していた方向性と、SREの方向性は微妙に違う気がしている）のだが、 <code>implements Platform Engineering</code> であればしっくり来る感がある。</p>
<h2>Team Topologiesとの関係性</h2>
<p>"Platform" と言われると、<a href="https://teamtopologies.com/">Team Topologies</a>に登場する "Platform Team" をつい思い浮かべてしまう。Team Topologoies（＝ちいとぽ）は2年前に<a href="https://www.amazon.co.jp/dp/4820729632">日本語版</a>も出版されて話題になった、システム開発に有用な組織設計を解説した本だ。そのなかに登場する4つのチームタイプの1つが「プラットフォームチーム」であり、その役割は「横断的に内部サービスを提供し、ストリームアラインドチームが下位のレイヤーを意識する必要性を下げる」と定義される。ちなみにストリームアラインドチームとは、「他チームへ引き継ぎを行わずとも機能をリリースできる職能横断的なチーム」であり、要するところプロダクトの開発チームにあたる（のが望ましいとされる）。</p>
<p>Gartnerの記事にはTeam Topologiesへの言及はなく、Platform EngineeringがPlatform Teamの考え方にインスパイアされたものなのかはわからない。Team Topologiesにおける「プラットフォーム」の定義は、Evan Bottcherによる <a href="https://martinfowler.com/articles/talk-about-platforms.html">What I Talk About When I Talk About Platforms</a> に沿っていると書かれている。この記事ではセルフサービスでのプロビジョニングに言及されており、書かれている内容はほぼPlatform Engineeringだ。どちらかと言えば、先にPlatform Engineering的な考え方が存在しており、そこからTeam Topologiesがインスパイアされているように見える。</p>
<p>自分の場合はTeam Topologiesを先に読んでいて、SREの役割の一部がプラットフォームチームに転嫁可能だと考えていた。ただ、そこで実体としてのプラットフォームを伴うかは別だと思っていた。Team Topologiesにも「いちばんシンプルなプラットフォームは、下位のコンポーネントやサービスについて書いた単なるWikiページ上のリストだ」とある。一方でPlatform Engineeringには先述のようにIDPが必須かのような印象があり、こちらの指すプラットフォームは実体を伴う気がしている。そういった区分け方で正しいのかはまだわかっていない。</p>
<h2>感想</h2>
<p>自分の「しっくりこなさ」は、結局のところ何をしていればPlatform Engineeringと呼びうるのかがわからないという点にある。実体としてのIDPがあればよいのか。IDPがなくとも、Terraform Moduleなど何らかのツールやWikiによって、開発者のセルフサービスが実現してさえいればよいのか。最悪の話として、ウェブフォームに必要事項を埋めてPOSTすれば、その裏で誰かが人力で頑張っていたとしてもすぐに環境が払い出されたらそれでもプラットフォームと考えていいのか。そのあたりがわからないので、今のところ自分ではPlatform Engineeringという語を使うことは控えることにしている。</p>
<p>目的や考え方に関しては賛同するというか、中央集権的にインフラ管理を行っていれば自ずとここには行き着くだろう。開発者がすべての作業をセルフサービスできる、ストリームアラインドな在り方に近づくことは工数面でも認知負荷の面でも明らかな理想だ。その実現方法についてはIDPを使おうがなんだっていいじゃないか、と自分としては思う。インフラの新規プロビジョニングが年間に数えるほどしかないような組織で、IDPを抱えても仕方ないような気がしている。</p>
<p>いろいろと書いてきたが、繰り返しにはなるが考え方としては賛同するのだ。だからエッセンスとしては吸収していきたい。あるいはここで書いた考えに致命的な間違いがあって、本当のPlatform Engineeringはこうなんですよ！という話があって、それならば最高だ！という展開があるなら、それもまた望ましいと思っている。新しい考え方やプラクティスが生まれたときは、そういった議論があってこそだと思うので。</p>
]]></description>
            <link>https://chroju.dev/blog/what_is_platform_engineering</link>
            <guid isPermaLink="false">what_is_platform_engineering</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 15 Oct 2023 10:28:50 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[札幌で4日間ワーケーションした]]></title>
            <description><![CDATA[<p>コロナ禍真っ最中にもやってみたいなと思っていたワーケーション、「禍」が「落ち着いた」と言われる今になって機会がまわってきて、4日間札幌から仕事していた。</p>
<h2>働く場所としての札幌という街</h2>
<p>いろいろな意味で「札幌」を選んだのは正解だった。</p>
<p>端的に、この時期だと避暑地として最適。晴れていれば30度ぐらいにはなるので、「暑くない」というイメージをしていると肩透かしを食らうが、逆に太陽さえなければ涼しいのが良い。夜になると、半袖の上に1枚羽織らなければ肌寒く感じるほどで、特に今年の関東の猛暑を知った身だと快適としか言いようがなかった。湿度は数字の上だと、関東並にあるようだったが、あまり「蒸し暑い」と感じることはなかった。</p>
<p>非常にコンパクトなエリアに街の機能が集中しているのもいい。綺麗な碁盤の目状の街で、北は札幌駅から、南にある歓楽街のすすきのまでだいたい2kmぐらい、そのエリアに飲食店、企業、公共施設、公園などが集中している。今回は札幌駅とすすきのの真ん中あたりにあたる、大通駅の近くに泊まっていたが、徒歩で行ける範囲内に食事処、商業施設、様々なコーヒースタンド、公園、コワーキングスペース、 <a href="https://www.sapporo-community-plaza.jp/library.html">平日は21時まで開いている図書館</a> まであって何も困ることがなかった。</p>
<p><a href="https://gyazo.com/cb28e74e55ed879108af53788b6315a9"><img src="https://i.gyazo.com/cb28e74e55ed879108af53788b6315a9.jpg" alt="Image from Gyazo" width="1920"/></a></p>
<p>大通公園は最高だと思う。あんな大都会の中心に、あれほど広い緑地があるのは精神衛生にかなり良い。今の時期だと、仕事が終わったぐらいのタイミングがちょうど夕暮れどきで、コーヒーを買ってベンチで一息つくのがルーティーンになっていった。ちょうど自分の滞在期間にビアガーデンも始まってすごいことになっていた。</p>
<h2>旅先で働く環境をどう整えるか</h2>
<p>働く場所としてはほぼホテルを使い、少しだけコワーキングスペースを一時利用してみた。</p>
<p>泊まったホテルが昼間だとWi-Fiでも200Mbpsは出るところだったので、働く上では困らなかった。難があるとすれば椅子で、何の変哲もないホテルの椅子なので、何日か経つと腰以上にお尻が痛くなってつらくなった。頻繁に立ち上がったり、部屋から出て散歩したりするようになった。</p>
<p>尻の痛みに耐えかねて、というのもあってコワーキングスペースを一時利用した。都内でも使ったことはあるのだが、個人的にはそもそもあまり好んでいない。どうも不特定多数がいる場所で、それなりに秘匿性のある「仕事」という行為をすることが自分は向いていないらしい。また現状だと自分はマネージャー職なのでMTGが入ることも多く、MTGスペースの数が限られているコワーキングスペースでは働きにくさを感じる。</p>
<p>ただ設備が整っているのは確かであり、今回3日目に初めてコワーキングスペースでサブディスプレイを借りてみて、仕事の効率がガンガンに上がるのを感じた。椅子も仕事用のものがちゃんと備えられているので、座っていて身体が悲鳴を上げることもなかった。ワーケーションという長い期間の遠隔稼働においては、適宜コワーキングスペースを用いたほうがいいんだろうと思う。あるいはワーケーションではガチめな労働をするのはそもそも諦めるか。後者が正解のようにも思う。ディスプレイが小さくても出来る、MTGや思考、意思決定系のタスクに集中したほうがいいのかもしれない。</p>
<p>コワーキングスペースについては、今回いくつかの場所を使ったが、<a href="https://sih-d.jp/">SAPPORO incubation Hub DRIVE</a> が使いやすかった。丸一日使っても2200円でそれなりに手頃であり、壁を背にする席がいくつかあったり、ボックスタイプになっていたりする席がいくつかあるので、ショルダーハックもある程度防ぎやすい。</p>
<h2>1日の過ごし方</h2>
<p>現職はフレックス制の会社なので労働時間は自由に決められるが、普段の労働とリズムはほぼ変えなかった。</p>
<ul>
<li>7:30〜8:30 朝食、身支度</li>
<li>8:30〜10:00 個人的な勉強</li>
<li>10:00〜18:30頃 労働</li>
<li>18:30〜 大通公園あたりでコーヒー飲んだりしつつ、妻と合流次第夕食</li>
</ul>
<p>ちなみに妻は勤め先の札幌オフィスに一時的に席を借りていたので、日中は別々に働いていた。それもどうなんだ。お昼を一緒に食べた日もあったけれども。</p>
<p>「個人的な勉強」の時間は普段だと大学に費やしたりしているが、前述の「ガチめな労働をそもそも諦める」の一環でワーケーション中は諦めた。代わりに普段出来ていない思考系のタスクに費やした。これはそれなりに捗ったし、資料が足りなければ先述の図書館があったので、労働後に通ったりもしていた。</p>
<p>ここも結局「どこまでガチめに労働するか」だと思うが、今回はそれなりに普通に働こうと思っていたのでリズムを変えなかった。労働を少なめにしてリフレッシュを優先するなら、そういうのもありだと思う。今回は「私用のついで」のような滞在で、あんまり観光する時間もなかったので、リフレッシュしよう〜みたいなのがなくて、それはちょっと失敗だったかな、みたいな感覚もある。いろいろタスクをせねばならなくて、労働後にセコマで弁当買ってホテルで書類書いたりとかしていた。</p>
<h2>持っていってよかったもの</h2>
<h3>洗濯ネット</h3>
<p>働いたのは4日間だが、滞在日数は土日を合わせて1週間以上だったので、途中で洗濯をした。それにあたって洗濯ネットは持って行っていた。今回はコインランドリーではなく、部屋にドラム型洗濯乾燥機のあるホテルを借りたので、これも快適ポイントだった。部屋で仕事しながら洗濯できるのは時間の節約にもなる。</p>
<h3>Corne Chocolate</h3>
<p><a href="https://chroju.dev/blog/corne_chocolate_build_log">Corne Chocolate を組み立てる、40%キーボードに目覚める - chroju.dev/blog</a> からもう4年間愛用している携帯用キーボード。ロープロキーボードは持ち運びやすいのでおすすめ。</p>
<h3>MOFT</h3>
<p>https://www.moftjapan.com/collections/pc/products/moft-pc-stand?variant=42378051354881</p>
<p>超薄型のPCスタンド。そこまで高さが出せるわけではないが、これだけでもだいぶ働くのが楽になった。とにかく軽い、薄いというのがメリット。よくあるPCの裏側に貼り付けておくタイプだと、会社貸与のPCに使うには抵抗があるが、これは非粘着タイプもあるのがいい。</p>
<p>結果として、こういうスタイルで働いていた。</p>
<p><a href="https://gyazo.com/45ee9188c2abbe22db3594adb7ec2937"><img src="https://i.gyazo.com/45ee9188c2abbe22db3594adb7ec2937.jpg" alt="Image from Gyazo" width="2560"/></a></p>
<h2>よかった店</h2>
<h3>丸美珈琲店</h3>
<p>https://www.instagram.com/marumi_coffee/</p>
<p>札幌、総じてコーヒーのレベル高くない……？というのは今回の驚きポイント。なんか謂れがあるんだろうか、どうなんだろうか。探したらBRUTUSにそんな記事があった。</p>
<p>https://brutus.jp/sapporo_coffee1/?heading=1</p>
<p>なかでも今回良かったのが丸美珈琲店。ちょっと疲れているタイミングで入ったので、無意識にラテを頼んでしまい、「初めて来たのにラテにしたら豆の味がわからなさそう」と後悔しかけたのだが、牛乳に負けない豆の香りがあり、ラテってこんなに美味いものだったのか、と驚いた。</p>
<h3>一夜干しと海鮮丼 できたて屋</h3>
<p><a href="https://gyazo.com/dee07a0c55379e355b551c05b76620fd"><img src="https://i.gyazo.com/dee07a0c55379e355b551c05b76620fd.jpg" alt="Image from Gyazo" width="2560"/></a></p>
<p>東京にも展開している回転寿司 根室花まるが展開する定食屋。焼き魚やフライが中心。四ッ谷にも店舗があるらしい。焼きも揚げも、かなり肉厚な魚で食べ応えがあってよかった。</p>
<h3>ノースコンチネント</h3>
<p><a href="https://gyazo.com/0eec865b8d6fd443d207120cefae01d0"><img src="https://i.gyazo.com/0eec865b8d6fd443d207120cefae01d0.jpg" alt="Image from Gyazo" width="2560"/></a></p>
<p>食事の面だと、魚介もカレーも食べたけど、今回はここのハンバーグが一番美味かった。きっちり中まで焼かれた肉が弾力あって美味い。ソースがかなり濃いめで食欲をそそる。サラダもたっぷりで、もりもり肉を食べることへの罪悪感を消してくれる。おしゃれな見た目の店だが、これは白米に載せてわしわし食べることを推奨してるだろ？と言いたくなるような肉とソース。実際フォークとナイフは出てこなくて箸で食べるのがまたいい。おかげでかきこむようにガツガツ食べてしまう。とにかく美味しいので、滞在中2回行ってしまった。</p>
<h3>セイコーマート</h3>
<p><a href="https://gyazo.com/99b05b059542de84da122747244702ca"><img src="https://i.gyazo.com/99b05b059542de84da122747244702ca.jpg" alt="Image from Gyazo" width="1920"/></a></p>
<p>北海道のインフラ。せっかくなので、コンビニ寄るときはなるべくセコマを使った。パスタが120円ぐらいで買えるのは意味がわからないし、店内調理のホットシェフはだいたいどれ食べても美味い。「道産ポテトのフライ」が甘味の強い芋で美味しかった。</p>
<h2>総じて</h2>
<p>よかった。の、だけど、それは僕がもともと札幌という街が好きだったのもあるし、自分と関わりのない街で生活を営む、という行為が好きだったのもあり、ワーケーション自体がよかったのか、もろもろの要因が重なって「よかった」という感想になっているのかは自分でもわかっていない。そもそも自分は旅行が好きで、特に一人旅が好きで、それは自分とまったく関わりのない土地で、生活が営まれている、多くの人の人生が流れている、ということを実感できるのが好きであり、そのなかで一時的に場所をお借りして、自分も「生活」をする、ということは、旅行以上に楽しいものがあった。</p>
<p>ただ、あまりに普段通り「生活」しようとしすぎた、というのはある。ワーケーション、普段通りの生産性もパフォーマンスも出るはずないし、そもそも出すものでもないので、じゃあ何をするか？　ワーケーション中だからこそ出来ることは何か？というのを考えておくと尚良いのだろうな、と思う。</p>
<p><a href="https://gyazo.com/ee268a35b8b5c4980e099254ecad1559"><img src="https://i.gyazo.com/ee268a35b8b5c4980e099254ecad1559.jpg" alt="Image from Gyazo" width="2560"/></a></p>
<p>札幌に行くとだいたいエスタのLoft、ビッカメ、ユニクロあたりで忘れ物や足りないものの補充を毎回していたのだけど、それも今回で最後になるというのが寂しい限り。お世話になりました。ワーケーションは機会があればまたしてみたいが、札幌以上に居心地の良い街があるのかわからないので、また避暑で来年来てしまうかもしれない。</p>
]]></description>
            <link>https://chroju.dev/blog/workation_sapporo</link>
            <guid isPermaLink="false">workation_sapporo</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 23 Jul 2023 11:23:36 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[すべてのSREはエッセイを書こう]]></title>
            <description><![CDATA[<p>タイトルは「お前が書け」という話です。</p>
<p>https://learning.oreilly.com/library/view/97-things-every/9781492081487/</p>
<p>『<a href="https://learning.oreilly.com/library/view/97-things-every/9781492081487/">97 Things Every SRE Should Know</a>』を読んだ。言うまでもなく「97のこと」シリーズのSRE版にあたる。</p>
<p>Amazonでレビューを見ると、かなり漠然としていて哲学的だ、という理由で☆1つになっている投稿があった。他の「97のこと」シリーズを読んでいれば予想はできると思うが、この本もまた、確かにある種漠然としたエッセイ集であり、具体的な実践Tipsではない。自分としては、ことSREに関してはむしろ積極的にエッセイが読みたい。『SREの探求』に書かれている、この一節が象徴的だと思う。</p>
<blockquote>
<p>私の経験では、SREのような分野は、その分野の人々（すなわち現実の実務担当者）が互いに話し合うことで最も望ましく成長していきます。人々が集うことで、話し合い、議論し、笑い合い、自らの経験（成功と失敗）と未解決の問題を共有するようにするのです。会話が織りなす、賢く、親切で、多様性に富み、インクルーシブで、敬意に基づくコミュニティには、ある分野を他の何物にも代えがたい方法で進化させる効果があります。</p>
</blockquote>
<p>『97 Things ...』のなかでも、「93. SRE in Crisis」において近しいことが書かれている。現状のSREは『SRE book』を参考としているものの、この本もまたあくまでGoogleにおける実践、プラクティスであり、科学的に何か裏打ちされているわけではない。例えば、なぜトイルの比率は50％以下がよいのか。別の比率ではダメなのか。Googleのプラクティスをそのまま真似をする必要はないし、むしろあれほどの規模の組織で、あれだけ優秀なエンジニアを抱えたSREチームを真似できるわけがない。</p>
<p>だから、SREは探求が必要であり、各企業やチームの状況に合わせて、SREをどのように「インストール」したのかが重要になる。それは必ずしも客観的な根拠に基づいたものではないかもしれないし、仮説を立てて、実践検証して、また別の仮説を立てていく、常に発展途上なものでもある。そういった試行錯誤している実践や、そこから得られた教訓や、各々の「SRE観」をまとめていけば、自ずと「エッセイ」と呼ばれる、ある種漠然としたものにはなっていくだろう。それで全然いいので読みたい。SREはエッセイを書くべきだな、というのを、本書を読んで強く感じた。千差万別な実践をそれぞれに言語化していくことで、初めてGoogleに寄らない、SREというロールの抽象化ができる。Google1社による実践の手を離れ、多くの企業での具体的実践を通過することで、SREについてはさらに次の論理が生まれていくんじゃないか。日本だと主観的なエンジニアの記事に対して、「ポエム」という表現が半ば揶揄を交えつつ使われることがあるが、あれは詩ではないし、「エッセイ」と呼んだら抵抗なくなるんじゃないかと思うが、どうだろうか <a href="%E4%B8%8B%E8%AA%BF%E3%81%B9%E3%81%AE%E4%B8%8D%E8%B6%B3%E3%81%97%E3%81%9F%E3%80%81%E5%85%88%E5%85%A5%E8%A6%B3%E3%82%84%E3%83%90%E3%82%A4%E3%82%A2%E3%82%B9%E3%81%AE%E3%81%8B%E3%81%8B%E3%82%8A%E3%81%99%E3%81%8E%E3%81%9F%E8%A8%98%E4%BA%8B%E3%81%8C%E3%80%8C%E3%83%9D%E3%82%A8%E3%83%A0%E3%80%8D%E3%81%A8%E5%91%BC%E3%81%B0%E3%82%8C%E3%81%A6%E3%81%8A%E3%82%8A%E3%80%81%E3%81%9D%E3%82%8C%E3%81%AF%E3%80%8C%E3%82%A8%E3%83%83%E3%82%BB%E3%82%A4%E3%80%8D%E3%81%A8%E3%81%97%E3%81%A6%E3%81%AE%E5%93%81%E8%B3%AA%E3%81%AB%E3%82%82%E8%87%B3%E3%81%A3%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E5%A0%B4%E5%90%88%E3%81%8C%E3%81%82%E3%82%8B%E3%80%81%E3%81%A8%E3%81%84%E3%81%86%E8%83%8C%E6%99%AF%E3%81%AF%E7%90%86%E8%A7%A3%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%81%8C%E3%80%81%E5%8D%81%E6%8A%8A%E4%B8%80%E7%B5%A1%E3%81%92%E3%81%AB%E9%9D%9E%E5%AE%A2%E8%A6%B3%E7%9A%84%E3%81%AA%E8%A8%98%E4%BA%8B%E3%81%8C%E3%80%8C%E3%83%9D%E3%82%A8%E3%83%A0%E3%80%8D%E3%81%A8%E5%91%BC%E3%81%B0%E3%82%8C%E3%81%A6%E3%81%97%E3%81%BE%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%82%82%E6%80%9D%E3%81%86%E3%80%82">^1</a> 。</p>
<p>以下、印象に残った章をいくつかピックアップしておく。</p>
<h2>2. Do We Know Why We Really Want Reliability?</h2>
<p>信頼性というものがそう簡単に割り切れるものではないことがよくわかる一節。拡大する市場で勝負を仕掛けているのであれば、信頼性の欠落により失う顧客よりも獲得顧客のほうが多く見込め、機能開発に対するインセンティブが強く働く。このように、常に信頼性が至上命題ではないなかで、どう向き合うか。</p>
<h2>22. SRE, at Any Size, Is Cultural</h2>
<p>タイトルだけですべてを言い表しているし、とても同意する。 <a href="https://www.dynatrace.com/resources/ebooks/sre-report/">State of SRE Report 2022</a> でも、 "SRE is a cultural change" と書かれている。</p>
<h2>34. Storytelling Is a Superpower</h2>
<p>SREの行っていることは "mystical" に見えがちであり、他のチームに対するストーリーテリングをすること、そういったスキルも重要であると説かれている。技術一辺倒の技術職ではないよな、というのは自分も感じている。</p>
<h2>76. The SRE as a Diplomat</h2>
<p>いわゆるEmbedded SREのようなプラクティスについて書かれている。ここではDiplomat、すなわち外交官に例えられており、ロールとしては "forward-deployed SREs (fdSREs)" と呼び表されている。</p>
<h2>87. Important but Not Urgent: Roadmaps for SREs</h2>
<p>重要だが緊急ではない。アイゼンハワー・マトリックスにおいては、最も多くの時間をここに費やせとされているが、「緊急ではない」タスクは積まれがちであり、なかなか消化されていかないジレンマ。信頼性がひどく劣化していたりしない限りは、どのSREチームでも「重要だが緊急ではない」タスクばかりが溜まっていそうであり、それに着手できていないとすれば、トイルの比率を考え直したほうがいいのかもしれない。</p>
<h2>92. Risk and Rot in Sociotechnical Systems</h2>
<p>組織というのはリスクを過小評価して、信頼性への投資を怠りがちである。SREはこれを避けるように組織を仕向けていかねばならない。</p>
<h2>93. SRE in Crisis</h2>
<p>先に言及した通り。</p>
]]></description>
            <link>https://chroju.dev/blog/book_97_things_every_sre_should_know</link>
            <guid isPermaLink="false">book_97_things_every_sre_should_know</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Thu, 06 Jul 2023 10:20:28 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[RSSもPDFもYouTubeも、全部Readwise Readerで「読む」]]></title>
            <description><![CDATA[<p>https://read.readwise.io</p>
<p>情報収集のためのアプリとして最近Readwise Readerを使い始めたのだが、これが結構面白い。一言で表すと「RSS ReaderとRead it laterサービスが一体化したもの」なんだけど、独自性のある機能が非常に多くて、言うなればデジタル上における「読む」という体験がここに集約できるようになっている。</p>
<p>Readwise Readerではエントリーを溜め込む場所として <strong>「Feed」</strong> と <strong>「Library」</strong> の2つが用意されている。前者がRSS Readerの役割を果たすものであり、後者がRead it later的な場所となっている。FeedにはRSS以外にも、専用のメルアドを通してメルマガを送り込んだり、TwitterのPublic List経由でツイートを送り込んだりもできる。</p>
<p><a href="https://gyazo.com/2d31e079165cdfaa95bb32a9ed7ddfe0"><img src="https://i.gyazo.com/2d31e079165cdfaa95bb32a9ed7ddfe0.png" alt="Image from Gyazo"></a></p>
<p>特に面白いのがLibraryのほう。Feedから「あとで読みたい」ものを送れたり、Pocketのようにブラウザ拡張から今開いているURLを送れるのは基本。それ以外にファイルも登録して読むことができる。エンジニアをしているとホワイトペーパーなどのPDFを読む機会も少なくないが、なかなか未読管理まではできていなかったりする。これをRead it later的なワークフローで管理できるようになるのが便利だ。アップロードできるファイル形式には他にePub、CSVなどがある。ePubについては目次が設定されていれば、ちゃんとそれも読み込んで使えるようになる。</p>
<p><a href="https://gyazo.com/8c15846c4c28c2a5d116b2f872f986f5"><img src="https://i.gyazo.com/8c15846c4c28c2a5d116b2f872f986f5.png" alt="Image from Gyazo"></a></p>
<blockquote>
<p><a href="https://www.youtube.com/watch?v=6w7aV_zmDec">飯って同じ料理食う回のアニメ観ながら食べるよね？ - YouTube</a></p>
</blockquote>
<p>YouTubeのURLを登録した場合も面白くて、字幕をすべて取り込んでLibrary上で表示してくれる。日本語もイケる。なので、動画を「読むもの」に変換することができる。正直、動画によるインプットが苦手な質で、適当に飛ばし読みしながらザッピングできる文章のほうが好きなのだが、この機能によりある程度動画でもインプットが進むようになった。ちなみに、字幕上の任意の箇所をクリックすれば、その箇所から動画を再生してくれるという機能も付いている。</p>
<p>デジタル上で「読む」ものが集約できるというのはこのあたりであり、いろんなアプリを行き来しなくても、あらかたのものはここに突っ込んでおけばよくなった。</p>
<p>https://readwise.io</p>
<p>Readwise ReaderはReadwiseというサービスの派生サービスのようなものであり、親にあたるのはReadwiseだ。ではReadwiseはどのようなサービスかというと、PocketやKindleなどと連携させ、それらのハイライトを取り込んで集約できるというもの。取り込んだハイライトはReadwise上でタグを使って整理したり、反復学習の理論に則った間隔でリマインドメールを送らせたりして、記憶の定着を図ったりすることができる。Readwiseはこのような「読んだあと」にフォーカスしたサービスだったのが、「読む」フェーズまで取り込もうとしているのがReadwise Readerだと言える。</p>
<p>このような成り立ちもあり、Readwise Reader上でもあらゆる記事は当然ながらハイライトしたり、メモを書いたりすることができ、Readwise側へも自動的に取り込まれる。PDFでもePubでも、形式は問わない。YouTubeの字幕にもハイライトできる。</p>
<p><a href="https://gyazo.com/30ba64777bc9797a0f4b16e309d287f8"><img src="https://i.gyazo.com/30ba64777bc9797a0f4b16e309d287f8.jpg" alt="Image from Gyazo"></a></p>
<blockquote>
<p><a href="https://chroju.dev/blog/teikyo_university_learner_fourth_year">帝京大学通信課程での社会人大学生4年目を終えて - chroju.dev/blog</a></p>
</blockquote>
<p>さらに面白いのが、Readwise Readerのブラウザ拡張を使っている場合。拡張を入れた状態で、すでにReadwise Readerへ登録済みのページを表示すると、ブラウザで閲覧しながらそのままハイライトすることができる。ハイライト箇所はもちろん相互同期されるので、よくありがちな「過去に見たページをもう一回探し当てた」ときにも、以前読んだ箇所がすぐに見つけられる。</p>
<p><a href="https://gyazo.com/e4a4cb8a5c9b0368e2ad9a52d5db622d"><img src="https://i.gyazo.com/e4a4cb8a5c9b0368e2ad9a52d5db622d.png" alt="Image from Gyazo"></a></p>
<p>また、属性情報に基づくフィルタリング条件を保存しておいて、ビューを自由に作れるのも嬉しい。初期設定では「1週間以内に開いたハイライト」や、「あとで読むに保存して、1週間以内に開いて途中まで読んだもの（最後に読んだ位置を保存してくれている）」といったフィルタが作られている。PDFやYouTubeの動画だけフィルタする、なんていう基本的なものもある。</p>
<p>今のところ新たに作ったのは2つで、「日本語の記事でまだ読んでいないもの」と「1か月以上前に保存したが、1か月以上開いていないもの」。英語の記事はPCでGoogle翻訳にかけながら読むことが多いので、外出中にサクッと日本語の記事を読みたいときに前者を使っている。後者はありがちな「あとで読む記事読まない問題」の対処として使うつもりでいる。</p>
<p>Readwiseは生まれてから5年以上は経っているようだが、Readerは2022年12月にPublic Betaになったばかりのまだまだ新しいサービスであり、不満や不具合らしきものもいくつか見受けられる。全体的にCJK周りの処理が甘いような感じはあり、検索でうまく引っかからなかったり、変換確定のEnterで投稿自体が確定してしまうといったものも見られる。日本人ユーザーが増えてフィードバックが増えれば改善も速まる気がするので、日本での利用も増えて欲しいところ。</p>
<p>利用には月額課金が必要になる。最終的にはReadwiseに内包されるような形になるようで、現在もReadwiseの有料プランを契約すると、Readerも使えるという形式になっている。GAした後は料金は上がる見込みだそうだが、Public Betaから使っているユーザーは据え置きになる予定だそうだ [^1] 。現状、これだけの機能を月$7.99で使えるのはなかなか安いんじゃないかと思っている。なお、最初の30日間はお試しで料金がかからない。</p>
<p>TwitterのAPI有料化をきっかけに、従来情報収集に使っていたMailbrewが使えなくなってしまった [^2] のを受けてReadwise Readerを使い始めた。Tweetでの情報収集がだいぶ厳しくなってしまった今、情報収集においてはRSS Readerが復権するんじゃないかな、という感覚が強い。</p>
<p>[^1]: "Regardless, we don't intend to increase pricing on existing full subscribers at that time. This means that if you subscribe while Reader is in beta, you'll get lifetime access for $7.99/month (billed annually) as part of our current Readwise Full plan." <a href="https://blog.readwise.io/the-next-chapter-of-reader-public-beta/">The Next Chapter of Reader: Public Beta</a></p>
<p>[^2]: もともと開発が低調ではあったが、2023年4月28日現在、開発チームから音沙汰もない。Twitter OAuthでのログインもできなくなり、締め出されたと訴えているユーザーも出てきている。 <a href="https://mailbrew.canny.io/feature-requests/p/login-is-broke">Login is broke | Voters | Mailbrew</a></p>
]]></description>
            <link>https://chroju.dev/blog/readwise_reader</link>
            <guid isPermaLink="false">readwise_reader</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 28 Apr 2023 02:20:07 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[インシデント対応のプラクティスについての覚え書き]]></title>
            <description><![CDATA[<p>インシデント対応はシステム運用上避けることのできないものだが、改めて考え直してみると、そのフローについては経験知、暗黙知に頼ってしまっている部分が多いなということに先日気付いた。そこでインシデント対応とは何なのか、どういった原則論に則るべきなのかを客観的に考え直すために、一度主観を廃して、自分が触れてきたリソース上での記述を少し覚え書きとしてまとめてみようと思う。</p>
<h2>インシデント対応に関するリソース</h2>
<p>インシデント対応を専門として書かれたリソースは案外少ないかも知れない、というのはこの記事を書くにあたり、手元の資料を整理していて感じた。自分がこれまでに触れてきたものとしては、主に以下のものがある。</p>
<ul>
<li>ITIL</li>
<li>Mike Julian (松浦隼人 訳) . <a href="https://www.hanmoto.com/bd/isbn/9784873118642">入門 監視</a>. オライリー・ジャパン, 2019, 232p.</li>
<li><a href="https://ueokande.github.io/incident-response-docs-ja/">PagerDuty Incident Response Documentation</a> （※リンク先は有志による日本語訳）</li>
<li>John Allspaw, Jesse Robbins, (角 征典 訳) . <a href="https://www.hanmoto.com/bd/isbn/4873114934">ウェブオペレーション : サイト運用管理の実践テクニック</a>. オライリー・ジャパン : オーム社, 2011, 255p.</li>
<li>Betsy Beyer, Chris Jones, Jennifer Peto, Niall Murphy (Sky株式会社 玉川 竜司 訳) . <a href="https://www.hanmoto.com/bd/isbn/9784873117911">SRE サイトリライアビリティエンジニアリング</a>. オライリー・ジャパン, 2017, 592p.</li>
<li>Rob Schnepp, Ron Vidal, Chris Hawley. <a href="https://learning.oreilly.com/library/view/incident-management-for/9781491917619/">Incident Management for Operations</a>. "O'Reilly Media, Inc.", 2017, 173p.</li>
</ul>
<p>自分にとって、特に影響が大きいのはITILかもしれない。ITシステム運用について規格化されたものでは最も知名度があるし、もともと固めの運用に従事していた経験が長いこともあり、v3の頃にCertificateも取得している。</p>
<p>ITILは参考になる一方、厳密に則るとそれなりに運用コストもかかる、「お堅いもの」という印象が否めないのも確かだ。『入門 監視』の中でも、「ほとんどのチームにとっては、このような正式な方法はやりすぎ」として、ITILをそのまま使うのではなく、シンプル化して導入することを促している。僕もそれが現実的な落とし所だと思っている。ITILは残念ながらリソースがオープンなものではないので、そのエッセンスを取り込むなら『入門 監視』を参考にするのがいいかもしれない（余談だが、O'Reilly Online Learningの読み放題のなかで<a href="https://learning.oreilly.com/library/view/itil-foundation-itil/9780113316625/">ITIL Foundationの日本語訳</a>が読める。これだけで12000円するし、通常販売されているのは物理書籍だけのようなので、ここで電子版を読めるのはちょっとお得）。</p>
<p>PageDuty Incident Response Documentationは、PagerDutyが社内のインシデント対応ドキュメントを縮小して公開しているものにあたる。ITILを除けば、ここに挙げたものの中では最も具体的かつ実践的な内容にまとまっている印象を受ける。</p>
<p>『ウェブオペレーション』『サイトリライアビリティエンジニアリング (SRE book)』はいずれも一部、インシデント対応に言及した章がある。包括的に運用、DevOps、SREに関してまとめた本なので、記述量は他のリソースには劣る。</p>
<p>最後の『Incident Management for Operations (IMO)』だが、これは今回のエントリーを書くにあたって初めて目を通した。SRE bookとPagerDuty Documentationを改めて読んだところ、双方が参考にしているものとして、アメリカの災害対応を標準化したIncident Command Systemや、それに基づいて制定されたNational Incident Management System (NIMS)が挙げられていたのが目にとまった。そこでNIMSについて調べていたところ、『Incident Management for Operations』もまたNIMSを元にしたインシデント対応の方針をまとめたものとなっていたため、あわせて参考とした。少しページ数は少ないO'Reillyだが、丸1冊をインシデントレスポンスに割いているだけあって、記述は非常に詳しい。</p>
<p>以下では、これらのリソースを参照しつつ、最大公約数的にプラクティスをまとめていく。</p>
<h2>インシデントとは何か</h2>
<p>そもそもの「インシデント」という単語の定義は以下の通りとされている。表現は異なるが、ほぼ同じ意味に取れる。</p>
<ul>
<li>「サービスの計画外の中断、またはサービスの品質の低下」（ITIL）</li>
<li>「計画していないサービス停止やパフォーマンス劣化」（PagerDuty）</li>
</ul>
<p>逆に「何がインシデントではないか」だが、ITILにおいては「インシデント」と「問題」が分離されており、後者はインシデントを引き起こした潜在的な原因である。つまり、症状がインシデント、原因が問題と、別概念として捉えられている。これらの管理プロセスが分けられている意図としては、サービスの中断や劣化という「事象・症状」の復旧は第一に優先するべきであり、その根本的な原因の解決は優先順位的に劣後する、という点がある。SRE bookでも同様に、「止血」や回復を優先せよという記載がある。</p>
<p>また広義のインシデントを分解し、「重大インシデント」と「セキュリティインシデント」という枠を設ける場合がある。重大インシデントは、事業に重大なインパクトをもたらす（ITIL）ものであり、複数のチームの協力（PagerDuty）などが必要となり、セキュリティインシデントは攻撃の遮断といった、通常のインシデントとは別の対策が必要になるなど、いずれも「狭義のインシデント」とは別の管理フローを設けるべきとされる。</p>
<h2>オンコール</h2>
<p>「call」と言われると日本人としては電話を想像してしまうが、電話に限ることなく、インシデント発生の通知とその受信行為全般を「オンコール」と呼ぶ場合が多い（入門 監視、PagerDuty、SRE book）。</p>
<p>オンコール担当とは、その名の通り通知を最初に受ける担当者である。オンコール担当は通知を受けことするが、必ずしもそのままインシデントの解決まで担当する者を意味しない。多くのリソースでは、解決においては適切な担当者へエスカレーションすることが求められている。</p>
<blockquote>
<p>誰もが、全てを知っているわけではない。 チーム全体で手助けする。 確信がもてない問題をエスカレーションすることは、恥ずべきことではないし学びもある。 私たちのモットーは「エスカレーションをためらわない」（PagerDuty）</p>
</blockquote>
<blockquote>
<p>オンコール担当がひとりぼっちだということではありません。オンコール担当が知らないことや解決できないことに対しては、エスカレーションパスが必要なのは間違いありません。（入門 監視）</p>
</blockquote>
<h3>通知手段</h3>
<p>オンコールにどのような手段を用いるかについては、リソースにより少し記述が分かれる。受信箱がいっぱいになり、アラート疲れを引き起こしやすいとして『入門 監視』ではメールの使用を避けろとしているが、PagerDutyはメールを「最初の通知」として推奨している。</p>
<p>優先度により、通知先や通知手段は分けておくことが推奨される。即時アクションが必要であればSMS、電話などを利用し、そうではない低優先度のアラートでは人々を目覚めさせてはいけない（PagerDuty）。また高優先度のものについては、誰かが応答するまで繰り返し通知するという手法もある。</p>
<h3>ローテーション</h3>
<p>オンコールは基本的には忌避されるものであり、心身への負荷が高いため、担当のローテーションが推奨される。</p>
<ul>
<li>プライマリ、セカンダリなど常に複数人で待機する（PagerDuty、ウェブオペレーション）
<ul>
<li>『入門 監視』はオンコールシフト期間が長くなるとして、これを推奨していない。プライマリ担当者がオンコールを受ける責任があるとしている。</li>
</ul>
</li>
<li>対応で困った場合はためらわずエスカレーションしてサポートを請う（入門 監視、PagerDuty）
<ul>
<li>場合により、最初に通知を受け付ける担当と、詳細な対応をする担当を明確に分ける。いわゆるヘルプデスク、サービスデスクの考え方（ITIL、ウェブオペレーション）</li>
</ul>
</li>
<li>会社規模が大きければ、タイムゾーンにより時分割を行うFollow-the-Sunを導入する（入門 監視）</li>
<li>オンコール担当への補償として、担当直後の休暇や、金銭的な手当を検討する（入門 監視）</li>
<li>ソフトウェアエンジニアもローテーションに入れる（入門 監視）
<ul>
<li>運用担当への「丸投げ」を避ける意図。</li>
</ul>
</li>
</ul>
<h2>トリアージ</h2>
<p>インシデントの通知を受けたあとの最初のステップとして、事象の認識と、優先度や深刻度に応じた分類、トリアージを行う（ITIL、PagerDuty、入門 監視、ICS）。これはビジネス・インパクトの大きな事象を優先的に対応できるようにするため（ITIL）である。深刻なインシデントの場合には、社内外への広い伝達や、複数人での協力体制を敷くなどの相応の対応が必要であり、そういった対応の必要性を迅速に判断するためにトリアージを行う（PagerDuty）。</p>
<p>インシデントの具体的な分類方法については、PagerDutyのドキュメントに端的な例があって参考となる。IMOでもどのようにインシデントを抽象化して分類するか、細かい説明がされている。いずれにおいても判断材料とするべきは症状（影響範囲や停止時間など）とされており、よりインパクトの大きいインシデントでの迅速な対応を可能にすることが求められる。そのため精緻に分類することよりも、早期に分類を判断して行動を開始することを勧めている。</p>
<h2>役割分担</h2>
<p>先述の通り、インシデントはオンコール担当が必ずしも1人で担当するわけではなく、必要に応じてエスカレーションして複数人で対応する。この際、役割分担を行うことが推奨される。</p>
<blockquote>
<p>直感には反することですが、責任分担をはっきりと分けることによって、一人一人が自律的に動けるようになります。これは、同僚の動きを予想しなくてもすむようになるためです。（SRE book）</p>
</blockquote>
<p>主な役割としては以下のものがある。</p>
<ul>
<li><strong>インシデント指揮者（IC, Incident Commander）</strong>。全体の状況把握、指揮・監督、決断、委譲していないその他すべての役割（PagerDuty、入門 監視、SRE book、IMO）</li>
<li><strong>コミュニケーション調整役（Liaison）</strong>。顧客や社内のステークホルダーにインシデントの最新状況を通知する。窓口を限定することで、インシデント解決に取り組む者を集中させる目的もある（PagerDuty、入門 監視、SRE book、IMO）
<ul>
<li>PagerDutyでは、社内向けと社外向けで別の担当を置くことを勧めている。</li>
</ul>
</li>
<li><strong>記録係（Scribe）</strong>。発生した事象や、インシデント解決のために実行した作業を時系列で記録する（PagerDuty、入門 監視）。</li>
<li><strong>実行担当（SME, Subject Matter Expert）</strong>。実際にインシデントの解決を担当する。英語の名称通り、ドメインエキスパートを当てる。複数人で作業が重複したりしないよう、解決作業にあたるのはSMEに限定する（PagerDuty、入門監視、SRE book、IMO）。</li>
</ul>
<h3>通常時とインシデント時の役割は一致しない</h3>
<p>「指揮者」という性質上、ICをシニアメンバーや上長に割り当てたくなるが、その必要はなく、どの役割に誰を割り当ててもよい（PagerDuty、入門監視、IMO）。そのためにも、なるべく持ち回りでそれぞれの役割を担当したり、平時に障害訓練を実施したりして、すべての役割に慣れておく必要がある（PagerDuty、SRE book）。</p>
<h2>インシデントの解決</h2>
<p>解決においては、以下のようなプラクティスが推奨されている。</p>
<ul>
<li>リアルタイムに状況をまとめる。
<ul>
<li>タイムスタンプと関係者に関する情報を含める（ITIL）</li>
<li>複数人が並行で編集できるWikiなどを用いる（入門 監視）</li>
<li>Slackに状況を書き込んでいく（PagerDuty）</li>
</ul>
</li>
<li>迅速な情報共有のための通話と、記録のためのチャットの双方を用いる（PagerDuty）</li>
<li>ICはSMEの助言のもと、すばやく判断することが求められる（PagerDuty、IMO）
<ul>
<li>常に状況を観察し、定期的に深刻度の再評価、状況の連絡指示を行うレビュープロセスを設ける（PagerDuty、IMO）</li>
</ul>
</li>
<li>優先順位は「出血を止める」、サービスを回復する、根本原因の証拠を保存する、の順である（SRE book）
<ul>
<li>「出血を止める」という言い方が抽象的でわかりづらいが、『ウェブオペレーション』では、問題が起きているコンポーネントを切り離したりなどして隔離する「封じ込め」というプロセスが最優先とされており、これと同等のものと考えられる。</li>
</ul>
</li>
<li>パニックに陥らない、解決が困難なら追加支援を求める（PagerDuty、SRE book）</li>
</ul>
<h2>クローズ</h2>
<p>インシデントの解決、クローズについてはあまり言及が多くない。</p>
<ul>
<li>インシデントの解決 = インシデント発生前の状態へ復旧したかどうか、はICが判断する（PagerDuty、IMO）</li>
<li>ステークホルダーへ連絡する（PagerDuty、IMO）</li>
<li>根本的な解決ではなく、一時的な修正、復元である場合は、インシデント解決後に今後の対応を判断する（IMO）
<ul>
<li>またインシデントが長引く場合には、対応者を交代することがある。その際、ICは次の担当者へ適切に引き継ぎを行うことが求められる（SRE book、IMO）。</li>
</ul>
</li>
</ul>
<h2>ポストモーテムプロセス、事後レビュー</h2>
<p>インシデントの解決後、発生事象のフォローアップを行う（all）。このプロセスは、近年ではポストモーテムと呼ばれるドキュメントの作成プロセスとして扱われる（PagerDuty、入門 監視、SRE book）。単に事後レビュー（IMO）と呼んだり、ITILでは先述のとおり「問題管理」という、インシデント管理とは別プロセスとして扱われたりしている。</p>
<p>ポストモーテムプロセスは、発生した問題の理解を促すこと、根本原因を分析してインシデントの再発を防ぐこと、それらを通じて会社全体に学びの機会を提供することを目的としている。</p>
<h3>ポストモーテムの記載内容</h3>
<p>以下はPagerDutyとSRE bookによる。</p>
<ul>
<li>発生事象のサマリ</li>
<li>影響（時間、ユーザー数、SLA違反状況、発生したサポートリクエスト数など、具体的数値で書く）</li>
<li>解決した方策、行った対応</li>
<li>インシデントの根本原因</li>
<li>タイムライン</li>
<li>アクションアイテム（インシデント解決、根本原因修正のために行ったすべての対応チケットのリンク）</li>
</ul>
<h3>ポストモーテムレビュー</h3>
<p>ポストモーテムは単に記載するだけではなく、レビューを行う。</p>
<p>SRE bookにおいては、下書きの状態でシニアエンジニアが評価し、その後メーリングリストなどで広範な共有を勧めている。</p>
<p>PagerDutyや『入門 監視』においては、同期的なミーティングによるレビューを想定している。参加者は利害関係のあるすべての人（入門 監視）であり、インシデントに関わったエンジニアや対応者、サービスオーナー、影響のあったシステムのマネージャーらが含まれる。</p>
<p>早期に再発防止策を採る必要があるため、レビューをいつまでに行うかあらかじめルール化することも求められる。『ウェブオペレーション』では24時間以内、それが難しければ1週間以内としており、PagerDutyでは最も深刻なSEV-1では3営業日以内、SEV-2では5営業日以内としている。</p>
<p>レビュー観点は以下のような点である。</p>
<ul>
<li>インシデントの詳細や原因が十分に分析されているか？（SRE book、PagerDuty）</li>
<li>根本原因は十分掘り下げられているか？（SRE book、PagerDuty）</li>
<li>今後のアクションプランは適切か？（SRE book、PagerDuty、入門 監視、ウェブオペレーション）</li>
</ul>
<h3>ベストプラクティス</h3>
<ul>
<li>誰かを非難することや、ヒューマンエラーに帰結させることを避ける（all）</li>
<li>誰が読んでも理解しやすいよう、略語などは使わないか、使う場合は説明を付記する（PagerDuty、IMO）</li>
<li>事実を正確に記述し、仮定や不正確な表現を用いない（PagerDuty、ウェブオペレーション）</li>
<li>効果的なポストモーテムを書くことは賞賛されるべきである（SRE book）</li>
<li>過去の興味深いポストモーテムの読書会などを開き、積極的に学びを広める（SRE book）</li>
</ul>
<h2>Conclusion</h2>
<p>いずれも大きな方針としてはそれほどずれていない。オンコールの負荷に留意すること、インシデントの深刻度を適切に見極めること、役割分担を明確にすること、非難のないポストモーテムプロセスで再発を防ぐことなどはいずれのリソースでも言及のある事柄だった。一方で細かな部分では当然ながら差分があり、一部では真逆なことが書かれていたりもする。『入門 監視』がITILをシンプルな形で導入することを勧めていたように、絶対的な正解を求めずに、自分たちの状況に合わせて適切なフローを構築する必要性がある。</p>
<p>また、この分野で規格化されたものはITILぐらいであろうと思っていたが、<a href="https://www.fema.gov/emergency-managers/nims">NIMS</a>を参考としているものがアメリカでは少なくない、というのは新たな発見だった。機会があれば原典にも当たっておきたい。</p>
]]></description>
            <link>https://chroju.dev/blog/incident_response_practices</link>
            <guid isPermaLink="false">incident_response_practices</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 15 Apr 2023 10:37:18 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[帝京大学通信課程での社会人大学生4年目を終えて]]></title>
            <description><![CDATA[<p>帝京大学理工学部情報科学科通信課程の4年目（5年生）が終わったので今年も記録する。今年も卒業はできてません。過去の経緯は <a href="https://chroju.dev/blog/tags/university">tag: university</a> からどうぞ。</p>
<h2>単位修得状況</h2>
<p>| 評価 | 2年次 | 3年次 | 4年次 | 5年次 |
| :--: | :---: | :---: | :---: | :---: |
|  S   |   8   |   2   |   4   |   2   |
|  A   |  12   |   8   |   6   |   8   |
|  B   |   4   |   4   |   6   |   4   |
|  C   |   0   |   4   |   0   |   0   |
| 合計 |  24   |  18   |  16   |  14   |</p>
<p>順調（？）に年間の修得単位数は減ってきており、もう少し取っておきたかったのが正直なところ。ただ、今年は全4期のうち、最後のIV期は試験日程が合わずに受講しなかったため、例年の75%の期間でこれだけ取ったと思えば及第点か。</p>
<p>残り20単位で卒業できる。来年度でギリギリなんとかできたら嬉しいが、こう見ると若干厳しそうにも思えてくる。が、とりあえずは来年度での卒業を目標にしている。</p>
<h2>初めて通学機会がゼロに</h2>
<p>通信課程と言えど原則的に試験は対面実施なのだが、コロナ禍ではオンライン試験に切り替えられることが多く、2022年度はついに帝京大学への通学機会がゼロで終わる初めての年になった。正確には対面試験自体は実施されたのだが、系列の帝京平成大学中野キャンパスが会場となり、帝京大学へ行くことがなかった。なぜ会場が切り替わったのか、背景は説明されておらずわからない。ファミマでよく耳にする例の大学にまさか自分が行く機会があるとは思っていなかった。</p>
<p>とはいえ、22年度を通じてオンライン試験が主になったことについては良かったと思っている。もともと試験のオンライン実施については、緊急事態宣言もしくはまん延防止等重点措置が発令されていることが条件だと大学側から宣言されていたのだが、22年においては感染者数、死亡者数、病床使用率などが従来と同程度の水準になってもこれらの措置が取られることなく、客観的な条件としてはもはや意味を成していなかった。特に昨夏の第7波においては自分の周囲でも感染者がかなり増え、自身が濃厚接触者になって試験に向かえない事態になることをかなり恐れたのだが、結局のところ大学側は感染状況を踏まえて柔軟にオンライン化の判断をしてくれるようになった。思えば弊学は医学部を有し、板橋キャンパスにおいては大学病院が併設されてもいるので、感染症に敏感な部分もあったのかもしれないと想像する。</p>
<p>なお、23年度に関しては早々と全面オンライン試験化が発表されている（恒久的な話なのか、一旦1年間の話なのかはわからない）。このままいくと卒業まで二度と通学しなくなりそうで、さすがにそれは嫌だなぁという思いもあったりはしている。</p>
<h2>試験日程とプライベートの兼ね合い</h2>
<p>先述した通り、22年度は年度はじめの時点でIV期の試験日に予定が入ってしまっており、全体の4分の3の期間で単位修得を狙うしかなかった。こういった事態は4年目にして初めてだったが、社会人大学生をしていると当たり前のように生じる話ではあり、難しさを感じるところだった。例えば年末など、時期的に勉強時間を取るのが厳しい「期」というのはこれまでもあったが、試験日が空かないとなるともはやどうしようもなくなってしまう。</p>
<p>丸々1期分空いたのはメリットでもあって、例年年末年始休暇にレポートを頑張り、2月頭まで勉強していたのが、今年は12月頭までで大学から解放されたので、他のことにかなり時間を使えた。</p>
<p>とはいえ自分も若くはなくなってきており、仕事というよりはプライベートに比重を置くべき場面が増えてきてもいる。そういったことを鑑みても、早めに決着をつけたいな、と思う5年目を迎えている。</p>
<h2>受けて良かった科目</h2>
<p>今年は電気回路、電磁気学などの計算機関連以外の科目をかなり取っていたので、直接的に「よかった」と言えるのは以下2つぐらい。電気回路の知識などは、自作キーボードで電子工作に手を出しているので面白くはあったものの、正直1年後には忘れてそうな気がしている。</p>
<h3>情報セキュリティ</h3>
<p>共通鍵暗号、公開鍵暗号のような基本から始まり、ゼロ知識証明、Information Hiding、ISO/IEC 15408といった、自分がそれほど知見のない部分にまで絡む内容で純粋に勉強になった。各種暗号のアルゴリズムなどを実際に数学的知識を使って簡単に解いてみるような力も求められるので、結城浩先生の本などで「概念は知っている」という程度で済ませていた間隙を突かれた感じもあった。</p>
<h3>システム科学</h3>
<p>いまだに「システム科学ってなんですか？」と聞かれると答えづらくは感じるが、これも広範かつ興味をそそられる内容で楽しかった。UMLやPERTなどを用いたシステム計画技法、数理計画法などによるシステム最適化、システム信頼性、さらには複雑系の概念やゲーム理論まで取り扱った。</p>
<p>面白かったのはジョン・フォン・ノイマンがかなりフィーチャーされていたことで、彼の業績をまとめる課題があったので、いろいろと自主的に調べたりもしていた。この道にいればノイマンを知らないということはなかったが、ゲーム理論の確立にまで関わっていたことなど、把握できていないことも少なくなかった。システム、コンピュータというものの成り立ちを紐解くと、やはりノイマンを避けられないのだなと改めて思った。</p>
]]></description>
            <link>https://chroju.dev/blog/teikyo_university_learner_fourth_year</link>
            <guid isPermaLink="false">teikyo_university_learner_fourth_year</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 25 Mar 2023 10:41:44 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[クラウド時代の「構成図」には何を描くべきなのか]]></title>
            <description><![CDATA[<p>勢いに任せた与太話です。</p>
<p>https://blog.serverworks.co.jp/aws-services-to-be-omitted</p>
<p>この記事の言わんとするところはすごくよくわかる。AWSで構築したシステムの「構成図」は何度も描いてきたが、描いているうちに「どこまで描くべきかな」「ここは省略してもまぁいいか」などと独りごち、最終的にそれっぽいものが完成すれば、なんとなく背徳感を覚えつつも「これでいいか」としてしまったことは何度もある。</p>
<p>とはいえ構成要素を全部盛りにすればいいのかと言えば、そうも思わない。先の記事の最終形の構成図を見ると、それなりにAWSを知っている人でも一瞬ひるむんじゃないかと思う。この記事にしても、省略せず全部描け、という趣旨なわけではなくて、省略しちゃうものって実は結構ありますよね、というスタンスだ。</p>
<blockquote>
<p>今後 AWS 構成図を見るとき「書いてないけど実は裏に色々なサービスがいるんだったよな」と思い出していただけますと幸いです。</p>
</blockquote>
<p>要するところ、「構成図」とは何を描くものなのかの定義が現代においては曖昧になっている気がしている。</p>
<p>「現代においては」、と書いたが、僕の記憶を辿っていくと、昔はそんなことはなかったし、今でもオンプレであれば迷いなく「構成図」は描けると思う。僕にとって「構成図」という単語から連想されるのは物理構成図と論理構成図だ。この2つは定義がしっかりしており、確かIPAの試験でも出てきたはずだ。</p>
<p>一応書いておくと、物理構成図とは文字通り、システムを構成する物理的な機器の接続などを示した構成図だ。単にこのサーバとこのスイッチが繋がっているよ、という程度にとどまらず、24ポートスイッチのこのポートと、サーバの増設したほうのNIC（「NIC」って書いたの何年ぶりだろう）を繋いでますよ、というところまで図示したりする場合もある。そのために機器ベンダー各社がVisioなどで使える自社製品のイラストを配布していたりするぐらいだ。</p>
<p>論理構成図は論理的なネットワーク、主にはL3のIPネットワークに関して示す。物理的な結線だけを見ても、その上でどのようなIPネットワークが構成されているかはわからないので、ここでVLANが切られていて、サーバには3つNICがあるけどそれぞれ全部違うネットワークに脚が出てますよ、みたいなのを記す。</p>
<p>物理構成図はL1と2、論理構成図はL3を表すわけで、「何を描けばいいか」がハッキリしているし、その目的もわかりやすい。物理的な障害が起きていれば物理構成図を見ながら実際の結線を確認したりするし、機器の設定がおかしいようであれば、実機の状態と論理構成図を照らし合わせたりしていた。</p>
<p>オンプレの時代からクラウドの時代に移り、物理/論理という2種類の構成図は意味を成さなくなってしまった部分がある。論理構成図についてはまだ描きようがあるかもしれないが、真面目にAWSで論理構成図を描こうとすると、Lambda@EdgeはリージョナルエッジだけどCloudFront Functionsはエッジロケーションに描きわけるとか、ELBに紐つけたAWS WAFってVPC内にはないけどどこに描きましょうねとかいろいろ辛くなってくる。そもそも自分たちで構築したネットワークを把握する目的で論理構成図を描いていたわけで、AWS管理下で上手い具合にやっているところを構成図に落とし込みたいかというと、なんか目的感がズレている気にもなってくる。</p>
<p>ということで、クラウド時代にはクラウド時代としての「構成図」が要るんだとは思うが、物理/論理のように一般化されたクラウド向け構成図概念というものは僕の知る限りでは存在しない。各クラウドベンダーともアイコンは配布しているし、diagrams.netのようなサービスがあるぐらいで、みんな図を描いてはいるわけなのだが、物理/論理を描いていた頃に比べると何を描くのかがどうしてもふわふわしちゃうな、という落ち着かなさをずっと覚えている。</p>
<p>試しにググってみたが、AWS公式の <a href="https://aws.amazon.com/jp/builders-flash/202204/way-to-draw-architecture/?awsf.filter-name=*all">AWS のアーキテクチャ図を描きたい ! でもどうすれば良いの ? - 変化を求めるデベロッパーを応援するウェブマガジン | AWS</a> においても「アーキテクチャ図ではみなさんが「何を伝えたいか」によって図の描き方や図の粒度などの表現を自由に変えて良いと私は考えています ! 」と書かれていた。まぁそうだよね、という気はする。冒頭の記事を見ていて、どの段階の構成図がしっくりくるかは人によっても違うと思う。しっかり全部描いたほうがいいと言う人もいるだろうが、僕としてはルートテーブルやインスタンスプロファイルがそこにあるだろう、というのは経験から推測できるので、別に構成図に欲しいとは思わない。でもインフラにそれほど詳しくない人は欲しいと思うかもしれない。</p>
<p>だから「ここまで描きますよ」という合意の下で、みんなそれぞれの「構成図」を描いていくしかないのだろう。そして冒頭の記事の通り、「省略しているものがありますよ」という了解もまたとても重要だと思う。しかしまぁやっぱり、どこか落ち着かない。</p>
]]></description>
            <link>https://chroju.dev/blog/diagrams_with_cloud_systems</link>
            <guid isPermaLink="false">diagrams_with_cloud_systems</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 17 Feb 2023 13:27:32 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[docker/build-push-action v3.3.0で導入されたprovenanceオプションにまつわる問題]]></title>
            <description><![CDATA[<p><a href="https://github.com/docker/build-push-action/releases/tag/v3.3.0">docker/build-push-actionのv3.3.0</a> で、 <code>provenance</code> というオプションが入り、デフォルトで有効化された。このオプションについては、</p>
<blockquote>
<p>This may introduce issues with registry and runtime support (e.g. GCR and Lambda).</p>
</blockquote>
<p>という注意書きがされており、一部環境で問題が起きる可能性がある。GitHub Actionsでバージョンをマイナー、パッチバージョンまで指定せずに使っていた場合、自動的にこのバージョンが適用されるため、実際に問題になったという声もTwitterで散見され、自分も一部で引っかかった。</p>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr"><a href="https://twitter.com/github?ref_src=twsrc%5Etfw">@GitHub</a> Actions runner bumped <a href="https://twitter.com/Docker?ref_src=twsrc%5Etfw">@Docker</a> buildx today, which has default provenance on. It&#39;s a nice feature, but many registries do not support it including google container registry.<br><br>All builds broke, and had to disable provenance.<a href="https://t.co/wp0TsgAJi8">https://t.co/wp0TsgAJi8</a> <a href="https://t.co/eH0uv3fkZp">pic.twitter.com/eH0uv3fkZp</a></p>&mdash; Sigurd Fosseng (@fosseng) <a href="https://twitter.com/fosseng/status/1616227805125025792?ref_src=twsrc%5Etfw">January 20, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<h3>（2023-01-31 追記）</h3>
<p>その後v3.3.1で、 <code>provenance</code> オプションはデフォルト無効化に切り替えられ、改めてデフォルト有効化はv4.0.0でメジャーバージョンアップとして取り入れられた。</p>
<p>参考 : <a href="https://github.com/docker/build-push-action/pull/781">Disable provenance by default if not set by crazy-max · Pull Request #781 · docker/build-push-action</a></p>
<p>（追記ここまで）</p>
<h2>SLSA Provenanceとは何か</h2>
<p><code>provenance: true</code> を設定すると、Provenance attestationなるものが出力されるようになる、と書かれている。ドキュメントとしては <a href="https://docs.docker.com/build/attestations/slsa-provenance/">Provenance attestations | Docker Documentation</a> に記載があり、ここでは <a href="https://slsa.dev/provenance/v0.2#schema">SLSA Provenance schema, version 0.2</a> に従ったものが出力されるのだとされている。</p>
<p>SLSAは、Supply chain Levels for Software Artifactsの略である。ソフトウェアのサプライチェーン、つまり開発からビルドを経てデプロイされるまでの一連の過程において、外部の攻撃からその完全性を守るためのフレームワークがSLSAである。これはGoogleによって2021年に提唱されたものであり、背景などに関しては以下の記事が詳しい。例えばCI環境の汚染など、この分野での脅威は近年増加傾向にあるのだという。ちなみにSLSAの発音は「サルサ」だそうだ。</p>
<p>https://security.googleblog.com/2021/06/introducing-slsa-end-to-end-framework.html</p>
<p>SLSAには4つのレベルがあるが、このうち最も低いレベルであるSLSA 1で必要とされるのが、ソフトウェアのビルドプロセスに関するProvenance、すなわち来歴の情報をメタデータとしてアーティファクトに添付することだとされている。</p>
<h2>Buildkit 0.11でのProvenance attestation対応</h2>
<p>Dockerのビルドにおいては、2023年1月に <a href="https://github.com/docker/buildx/releases">buildx v0.10.0</a> でSLSA Provenanceへの対応が盛り込まれ、このbuildxを内包した <a href="https://github.com/moby/buildkit/releases/tag/v0.11.0">Buildkit v0.11.0</a> が同じ月にリリースされた。</p>
<p>https://www.docker.com/blog/highlights-buildkit-v0-11-release/</p>
<p>このバージョンでは <code>--provenance true</code> オプションを <code>docker buildx build</code> に付与することにより、Provenanceを生成してイメージに添付できる。冒頭のdocker/build-push-action v3.3.0における <code>provenance</code> オプション追加は、これを受けてのものである。</p>
<p>なお、手元のdockerでもこのオプションを試したかったのだが、macOS上でもUbuntu上でもエラーになってしまったので、残念ながらまだ試せていない。</p>
<h2>Attestation Storageの仕組みとレジストリ等の対応状況</h2>
<p>Provenance attestationのイメージへの添付においては、 <a href="https://github.com/moby/buildkit/blob/master/docs/attestations/attestation-storage.md">Attestation Storage</a> という仕組みが使われている。</p>
<p>DockerやOCIによるコンテナの仕様においては、image manifestと呼ばれるイメージのメタデータを格納する仕組みがある。さらに複数のmanifestの参照情報を保存する仕組みもあり、OCIでは <a href="https://github.com/opencontainers/image-spec/blob/main/image-index.md">image index</a> 、Dockerでは <a href="https://docs.docker.com/registry/spec/manifest-v2-2/#manifest-list">Manifest List (fat manifest)</a> と呼ばれている。例えばmulti-platform imageの場合、各platformごとにmanifestが生成されるので、これらがimage indexの中で取りまとめられる形になる。image indexについては、 <code>buildx imagetools inspect</code> コマンドで確認ができる。</p>
<pre><code class="language-bash">❯ docker buildx imagetools inspect docker/buildx-bin
Name:      docker.io/docker/buildx-bin:latest
MediaType: application/vnd.oci.image.index.v1+json
Digest:    sha256:08625f48a68bb050f54b1840b5cab728ff3f086fd00f1fb08389f4b1cb9db221

Manifests:
  Name:        docker.io/docker/buildx-bin:latest@sha256:aecb1ff186197954361752564c04e73a464f0132fa15ac31a36d70580d8eba82
  MediaType:   application/vnd.oci.image.manifest.v1+json
  Platform:    darwin/amd64

  Name:        docker.io/docker/buildx-bin:latest@sha256:3ac63f40838fb8c2170b2d96bb5fadbffb5854ad3868c117016bbe73dee9b0d7
  MediaType:   application/vnd.oci.image.manifest.v1+json
  Platform:    darwin/arm64

  Name:        docker.io/docker/buildx-bin:latest@sha256:caf1d5f0527f5a9e7ce7ac8bb0c2b065567e3cc2dee9d5c4ddf1589f4f59b959
  MediaType:   application/vnd.oci.image.manifest.v1+json
  Platform:    linux/amd64
</code></pre>
<p>Attestation Storageはこのmanifestを活用して保存されており、image indexにもその情報が記載される。</p>
<p>しかしながら、一部のコンテナレジストリなどは、Attestation Storageに対応できていない。より具体的にはmulti-platform imageに対応していない場合があるのだが、それはすなわちimage indexに対応していないことを意味しているようで、そのためAttestation Storageを使っているimageも起動できないようだ。GCPのCloud RunやAWS Lambdaが該当しており、issueが挙げられている。</p>
<p>https://github.com/docker/buildx/issues/1533</p>
<p>またAmazon ECRはmulti-platform imageに対応してはいるものの、image indexを適切に処理できていないのか、Storage部分のmanifestがイメージとして認識されてしまい、 <code>&#x3C;Untagged></code> という名前で表示されたり、イメージスキャンが走ったりしてしまうという問題が報告されている。</p>
<p>https://github.com/aws/containers-roadmap/issues/1596</p>
<p>https://github.com/docker/build-push-action/pull/746#issuecomment-1377806123</p>
<h2>暫定的な対処と今後</h2>
<p>上記のように不具合を起こす可能性があるため、自身が利用しているコンテナ環境の対応状況を見つつ、暫定的には <code>provenance: false</code> の指定が必要になってくる。コンテナ自体は正常に起動していても、ECRの例のようにレジストリが対応できていない場合もあるため、そちらもあわせて確認したほうが良さそうだ。</p>
<p>表層的には「面倒なものが追加されたな」という思いもあるが、SLSA自体の有効性は理解できる。ソフトウェアのサプライチェーンをめぐるセキュリティについては、アメリカの大統領令に盛り込まれたSBOM (Software Bill of Materials)の話題を聞くことも多くなってきているし、長期的にはより大きなトレンドになってくる可能性は小さくない。将来的には多くのコンテナレジストリや実行環境が対応し、特に気にせずデフォルトでProvenanceを生成するようになるのかもしれない。</p>
<p>~また今回の事例はdocker/build-push-actionの3.3.0における「破壊的な」変更がきっかけになったが、一部の環境で問題を引き起こしかねないことが事前に予見されていたのであれば、これはメジャーバージョンアップが妥当だったのではないか、という思いもある。Dockerとしては生成物が追加されるだけで後方互換性を壊すわけではないので、これはマイナーバージョンアップ相当であり、レジストリなどの対応状況については知らんよ、という言い分なのかもしれないし、それも理解できるところではあるのだが……。~ （先述した追記の通り、その後改めてこの変更はメジャーバージョンアップとして扱われることになった）</p>
<p>まぁGitHub Actionsを使う側としては <code>@v3</code> 指定で不意にアップデートされてしまった、というのはやはりよろしくないので、推奨されているcommit hashでのバージョン指定か、パッチバージョンまで固定するべきなのだろうな、とは思う。</p>
]]></description>
            <link>https://chroju.dev/blog/docker_buildx_slsa_provenance</link>
            <guid isPermaLink="false">docker_buildx_slsa_provenance</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 25 Jan 2023 03:50:17 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『迷いを断つためのストア哲学』と認知行動療法]]></title>
            <description><![CDATA[<p>https://honz.jp/articles/-/45269</p>
<p><a href="https://honeshabri.hatenablog.com/entry/bocchi.rocks">ぼっちを救うためのストア哲学 - 本しゃぶり</a> で紹介されていた、 『<a href="https://www.amazon.co.jp/dp/415209852X">迷いを断つためのストア哲学</a>』という本を読んだ。ストア哲学とは、古代ギリシャのゼノンに端を発する哲学であり、『迷いを〜』は後期ストア派にあたるエピクテトスの言葉をもとにした書籍だ。</p>
<p>ストア哲学というのはちょっとしたブームらしい。哲学と言うとどこか高尚なイメージもあるが、ストア哲学は生活のなかでの実践に重きを置いており、ビジネスの場でも応用が利くのだそうだ。僕も以前からいくらかの場所で名前を見かけたことはあった。昨年読んだ『<a href="https://chroju.dev/blog/become_an_effective_software_engineering_manager">エンジニアリングマネージャーのしごと</a>』の中でも「13.1.1 ストア派とあなた」という章があり、そのものズバリな言及がある。他、僕の読んだところだと『反脆弱性』のなかでも触れられていた。</p>
<blockquote>
<p>知的な生活とは、痛みを感じなくてすむように感情を位置づけることなのだ。そのためには、自分の財産を頭の中で帳消しにし、失う痛みを感じないようにすればいい。そうすれば、世界が変動しても悪影響を受けることはないのだ。（中略）ストア哲学とは感情をなくすことではなく、手なずけることだ。人間を植物に変えることではない。(ナシーム・ニコラス・タレブ(著/文) 望月衛(監修 | 翻訳)『反脆弱性 上』ダイヤモンド社, 2017, p.386)</p>
</blockquote>
<p>『迷いを〜』のなかではストア哲学の原則を欲求、行動、受容の3つと書いている。「ブーム」になっているストア哲学の側面は、このうち「受容」の原則が強いように思う。受容というのは、自分がコントロールできるものとできないものを見極め、コントロールできないものに関しては受容して、気にかけるのをやめよ、という話だ。『反脆弱性』からの引用部分はまさにそのことを示したものだし、その他にも様々な場所で似た話を見かける。例えば有名なもので「<a href="https://ja.wikipedia.org/wiki/%E3%83%8B%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E7%A5%88%E3%82%8A">ニーバーの祈り</a>」がある。</p>
<blockquote>
<p>神よ、変えることのできないものを静穏に受け入れる力を与えてください。変えるべきものを変える勇気を、そして、変えられないものと変えるべきものを区別する賢さを与えて下さい。</p>
</blockquote>
<p>あるいは7つの習慣における「関心の輪 影響の輪」も同様の話と言っていいと思う。ストア哲学の3つの原則のうちの1つに関してだけではあるものの、確かにビジネスの現場でよく引き合いに出されるメソッドとの関連性が強いことがよくわかる。</p>
<p>ストア哲学の実践という点においては、認知行動療法との繋がりもある。認知行動療法とは、心の問題をケアするにあたり、客観的に観察しやすい「認知」や「行動」を変えていくことによる効果を期待するものだそうだ。</p>
<p>この認知行動療法は、ストア哲学に源流を持つ、というような話があるらしい。僕は認知行動療法の成り立ちに詳しいわけではないので、実際にストア哲学を下地にして生まれてきたものなのか、後付け的に共通項が見出されているだけなのかまではわかっていない。ただ、読んではいないが『<a href="https://www.amazon.co.jp/dp/4772419063">認知行動療法の哲学ーストア派と哲学的治療の系譜</a>』という本も発刊されており、『迷いを〜』の中だけで言及されている話ではなく、ある程度一般的に認知されていることではあるようだ。</p>
<p>確かに、ストア哲学と認知行動療法には似ている点がある。ストア哲学において、怒りや不安などの負の感情へ対処する方法として、そういった負の感情を覚える「心像」を自分と同一視せず、切り離して受け容れよとされている。</p>
<blockquote>
<p>心像とは、出来事や人や誰かに言われたことに対する最初の反応である。それに対して、一歩下がって合理的な考えをめぐらせたり、軽率に感情的な反応をするのを避けたり、直面しているものがコントロールできるものか（そうであれば行動する）、できないものか（その場合は無関係のものとする）を自問したりする。</p>
</blockquote>
<p>認知行動療法もまた、負の感情そのものと対するのではなく、そういった感情を覚えたときに自分がどのように考えたのか、あるいは身体にどういった反応、行動が出たのかというところを言葉で書き下して観察し、一度自分から切り離して対処する、というフローを経る。ある場面に対してどういった思考や感情が沸き起こるか、というのは <a href="https://ja.wikipedia.org/wiki/%E8%87%AA%E5%8B%95%E6%80%9D%E8%80%83">自動思考</a> という言葉で表されるように、パターン化して癖になっているものらしい。Pull requestに何かコメントがついた通知が来ただけで、内容を見てもいないのに身構えてしまう、というように。この「認知の癖」を客観的に観察して気付き、変えていくことで負の方向への思考を断つのだそうだ。</p>
<p>なお、認知行動療法の1つ、比較的新しいものとして「マインドフルネス認知療法」というものがある。これは言葉通り、マインドフルネスの実践を通じて感情や認知から一歩離れる訓練をするものとのことで、このように辿ってくるとストア哲学とマインドフルネスにも関連性が見出せてくる。マインドフルネスの実践を単に「集中力を上げたい」などと単純化するのではなく、ストア哲学の様々な考え方に繋げていくと考え方も広がっていくかもしれない。</p>
<h2>Afterwords</h2>
<p>僕もネガティブに考えがちな質だったり、自己肯定感が常に低いといった課題意識があり、本書でかじったストア哲学の考え方や、そこから派生した認知行動療法、マインドフルネスは実践的に活かせそうだなと感じている。自己肯定感の低さをもたらしていることの1つに、他人からの評価をそのまま受け取れないという「癖」があるのは自分でもわかっており、なぜ他己評価を受け入れられないのかについては改めて考えてみたい。こういった作業は「脳のデバッグ」のようだなと思った。</p>
<p>具体的実践においては、認知行動療法がメソッドとして活用できそうだと考えている。自分の思考パターンなど、当然ながら自分自身で気付くのは難しいのだろうし、本来であれば専門家の助けを借りたほうがいいのだとは思うが、それほど深刻なメンタルの問題があるわけでもないので、『<a href="https://www.awarefy.app/">Awarefy</a>』というアプリを使って自分で学んでみることにした。</p>
<p>https://www.awarefy.app/</p>
<p>これはいくつかの質問に応える形で考えを書き下していけば、自分の認知や行動をスムーズに記録して振り返ることができる機能や、実際に療法のメソッドを1か月かけて学ぶプログラムなどが収録されたアプリだ。フル機能を使うには月額課金が必要になるが、感情や認知を切り離して考える習慣が付くまでは続けてみようと思う。</p>
<p>ストア哲学自体にも興味を持ったので、原典としてエピクテトスの言葉がまとめられた『人生談義』を買った。実践を進める傍らでこちらも読んでいきたい。</p>
<p>https://www.hanmoto.com/bd/isbn/4003360818</p>
]]></description>
            <link>https://chroju.dev/blog/how_to_be_a_stoic</link>
            <guid isPermaLink="false">how_to_be_a_stoic</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 08 Jan 2023 14:45:18 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[2022年を振り返る]]></title>
            <description><![CDATA[<h2>総括</h2>
<p>ライフステージが変わりました、というのと、チームのメンバーが増えたりなど、態勢が変わっていくなかでSREのチームをどう組織していくか、ということを考えて実践に落とし込もうとした、というのが大きい1年だった。</p>
<p>後者については <a href="https://chroju.dev/blog/types_of_sre_teams">Embedded SREとは何か - SREの組織類型についての覚書 - chroju.dev/blog</a> や <a href="https://note.com/globis_engineers/n/n004952a7dad8?magazine_key=m4b1ab51cfc1a">地道に積み上げるSRE　目的合意から進めたSREの探求と実践｜グロービス・デジタル・プラットフォーム｜note</a> といったエントリーにまとめてきた。他社でもSREの組織体系についてのエントリーをよく見かけるようになってきているし、どの会社でも関心領域が近いように感じている。今年1年はまだまだ模索という段階で、来年しっかり成果を残していきたい。チームリーダーという立場上、自分が思考する対象はやはり組織やチームが最も大きな位置を占める。</p>
<p>ライフステージについては、変わったことで生活上の優先順位が変わったり、これまでに無いタスクやイベントが入るようになってきて、この年末年始などは特にまさに、だったりというのはある。生活が変化することには慣れていくしかないし、それが苦には感じていない。ただやることはマジでいっぱいあるし、来年は引っ越しとかも考えたいし、マジでいろいろある。</p>
<h2>定量評価</h2>
<p><a href="https://gyazo.com/cb648bd2e9dbb8bfcc161f225b4b4131"><img src="https://i.gyazo.com/cb648bd2e9dbb8bfcc161f225b4b4131.png" alt="Image from Gyazo" width="1352"/></a></p>
<ul>
<li>ブログ : 19記事（昨年比 -6）</li>
<li>GitHub Contributions : 377 (-22)</li>
<li>書籍 : 37冊（-12）</li>
</ul>
<p>毎年この3つの指標を最近は見ている。GitHubの「芝」については <a href="https://github-contributions.vercel.app/">GitHub Contributions Chart Generator</a> というサービスを使わせてもらった。</p>
<p>どれも数字の上では下がっている。特にインプット、技術書をじっくり読むような経験が今年は少なくて、エッセイ的なものはいくつか読んでいたが、ガッツリ技術的なインプットができず、それがブログのエントリー数低下にも繋がっているように思う。</p>
<p>また後でも触れるが、週報を定期的に書くことにエネルギーを持って行かれて、アウトプットが減っているという負の側面も出てきてはいる。</p>
<p>GitHubはまぁこんなものかな、という具合。OSSに不具合を見つけたらPRするか、する暇やスキルがなければ取りあえずIssueを上げるというのを今年は継続的にやっていた、ぐらい。自分で何か作ったり、という機会はそれほど多くなかった。</p>
<h2>学んでよかったこと / やってよかったこと</h2>
<h3>Cloudflare</h3>
<p>リクエストの処理をよりエッジ側へと寄せていく考え方が主流になってくるなかで、今年はCloudflareをいろいろと触っていた。</p>
<ul>
<li><a href="https://chroju.dev/blog/k3s_cloudflare_zero_trust">K3s + Cloudflare Zero Trustな環境をuser dataでシュッと建てる - chroju.dev/blog</a></li>
</ul>
<p>CDNとDNSのみならず、Zero Trust、Workers、Workers KVなど、無料で触れる幅が広いことに驚いた。単純に触っていて技術的に楽しい、というのもあるし、最近は何かちょっとしたものをウェブ上にホストしたければ、まずはCloudflareで何か使えないかなと考えるようになっている。</p>
<p>業務用にシステムを組むときはどうしてもAWSの中だけで完結できたほうが見通しが良いと感じてしまうのだが、視界は広げておきたい。</p>
<h3>CUE</h3>
<ul>
<li><a href="https://chroju.dev/blog/cue_terraform">CUEでTerraformを書いてみる - chroju.dev/blog</a></li>
</ul>
<p>つい先日書いたが、CUEも触っておいてよかった。Policy as Codeの話が案外盛り上がってこないなと感じているが、シンプルな話として、IaCツールを覚えるのにプラスして別のPaCツールに精通する必要がある、という学習コストの問題はあるわけで、CUEはこのあたりの問題を上手いこと止揚していけそうな空気を感じている。</p>
<h3>週報</h3>
<p>https://log.chroju.dev で公開している週報を、年間を通じて続けることができた。あまりガチガチなルールでやらないのが続けるコツだとは思っていて、忙しい週などは1週空けてもOKとしており、何度か抜けはあるのだが、2週以上途絶えてしまうことはなく、完全に習慣化した。</p>
<p>Publicに書いてツイートもしているのは、習慣継続のプレッシャーとして使っているだけであって、読まれることはあんまり想定していなかったのだが、予想外にいろんなところで「読んでいる」という声をいただくことがあった。なかには真似して始めてくれている人もいて、純粋に嬉しく思っている。ただ、僕自身も他のエンジニアの方々がやっているのに影響を受けて始めたのだということは一応明言しておきたい。最初に始めたときの経緯は <a href="https://chroju.dev/blog/journal_with_notion">読んだ記事などを「週報」として notion にまとめ始めた - chroju.dev/blog</a> に書いている。</p>
<p>定期的にアウトプットすることを強制的に習慣化するのはそれだけで良いことだと思っているし、普段あまり接していない人がどんなことを学んだり考えたりしているのか知れるのも楽しい。</p>
<h3>Mailbrew</h3>
<ul>
<li><a href="https://chroju.dev/blog/mailbrew_nuzzel_alternative">Twitterの話題はMailbrewで収集する - chroju.dev/blog</a></li>
</ul>
<p>インプットの面ではMailbrewが便利で今も続いている。メルマガをGmailを開かず読めるようになったのが一番の良い点だし、あらゆるソースの情報を集約的に見られることで、インプット上の認知負荷がかなり楽になった。</p>
<h3>マインドフルネスと認知行動療法とストア哲学</h3>
<p>https://www.lifehacker.jp/article/226273book_to_read-666/</p>
<p>マインドフルネス自体は何年か前に聞きかじって、2か月ぐらい試したけどよくわからなくてやめたのだが、今年改めて調べていて認知行動療法やストア哲学との共通点を知り、再び興味を持った。 <a href="https://ja.wikipedia.org/wiki/%E3%83%9E%E3%82%A4%E3%83%B3%E3%83%89%E3%83%95%E3%83%AB%E3%83%8D%E3%82%B9%E8%AA%8D%E7%9F%A5%E7%99%82%E6%B3%95">マインドフルネス認知療法 - Wikipedia</a> というものがあるらしく、出来事に対して自動的に感情が反応してしまうサイクルを停めて、うつ病などの回復を図るものらしい。精神疾患の状態になくとも、自分の認知の「癖」を治すことには効果がある。例えば自分は自己肯定感が低く、何か褒められてもつい謙遜しがちだが、これは「自動的な反応」に近く、マインドフルネスを通じて自分の感情的反応を変えていくことができる、らしい。「脳のデバッグ」に近いものと捉えている。</p>
<p>まだきちんと調べ切れていないので、ここはもう少し調べてものにしていきたい。</p>
<h2>Afterwords</h2>
<ul>
<li>最後にこういうことを書くのもアレだが、「年」という単位を元に活動をしていない（四半期か年度のほうが大きい）ので、このタイミングでの振り返りってあんまり意味がないんだけど、年末ってこういうことしたくなるよね、というテンションなので今年も書いた。
<ul>
<li>GitHubの芝とかブクログとかは年単位でまとまるから、振り返りやすいのもあるし。</li>
<li>月単位でこの月は何をした、とかもっとしっかり書ければいいんだけど、大きい個人プロジェクトを持ってはいないし、仕事のことは書けないしでいまいち書くことないんだよなとも思う。</li>
</ul>
</li>
<li>チームリーダーになって以降、ソフトスキル重点になりすぎているのが悩みだったけど、それが自分の職務なのである程度割り切るようになってきた。
<ul>
<li>一方で新しい技術に手を出すことなどを意識していて、その結果がいくらか出せているのはよかった。</li>
<li>今年は新しいことを学ぶことを意識しすぎて散らかってたのもあるので、1個深くしっかり学ぶ、みたいなのも考えていきたい。</li>
</ul>
</li>
<li>週報は本当によいのだが、書くこと自体が目的かしがちで、振り返りサイクルが回せていない感覚も強くなってきたので、週報をまとめることを通じて振り返って次に繋げる、というのを来年は回したい。</li>
<li>もっと本を読みたいし、もっといろいろ書きたい。</li>
<li>なんかもうちょい書きたい気もするけど、紅白見ながら書いてて気もそぞろになってきたのでここらで閉じる。Vaundy知らなかったんだけど、いいですね。ではよいお年を。</li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/retrospective_2022</link>
            <guid isPermaLink="false">retrospective_2022</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 31 Dec 2022 12:34:42 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[今年買ってよかったものと、今年のサブスク 2022]]></title>
            <description><![CDATA[<h2>On</h2>
<p><a href="https://gyazo.com/17519db1b3b873e8ada7fab9d676613a"><img src="https://i.gyazo.com/17519db1b3b873e8ada7fab9d676613a.jpg" alt="Image from Gyazo" width="1000"/></a></p>
<p>スニーカーを選ぶときに「歩きやすさ」というパラメータをあまり意識していなかったのだが、 <a href="https://sauce3.hatenablog.com/entry/2021/12/29/084344">ニューバランスW880をよく歩くオタクにおすすめしたい 【買ってよかったもの2021】 - 二度漬け禁止</a> を読んで影響を受け、歩きやすい評判のあるスニーカーブランドを探した結果、 <a href="https://outlet.newbalance.jp/shop/g/gMW880GB4">New Balance MW880G B4</a> と <a href="https://www.on-running.com/ja-jp/products/cloud-5-waterproof">On Cloud5 Waterproof</a> を買い、結果Onに軍配が上がった。</p>
<p>空洞を複数繋ぎ合わせたCloudTecと呼ばれるソールがかなり特徴的だが、これが名前通り「雲の上を歩くような」履き心地を生んでいるらしい。実際、悪路でも舗装路でも衝撃をうまく吸収してくれているようで、歩いている感覚が常に一定に保たれている感覚がある。旅行や街歩きが好きなので、日に1〜2万歩程度歩くことはよくあるが、足裏が痛くなるということはほぼ無くなった。あまりに良かったので、追加で <a href="https://www.on-running.com/ja-jp/products/theroger-centre-court/mens/white-gum?queryID=288c55100004eb52c2d3d472f5cdcd55">THE ROGER Centre Court</a> も買った。こちらは外見が優先されているが、実はCloudTecが控えめに導入されていて、似た系統のテニスシューズよりはかなり歩きやすかった。</p>
<h2>BOOX NOVA Air</h2>
<p><a href="https://gyazo.com/4f836611881135b5f911d558388c87ce"><img src="https://i.gyazo.com/4f836611881135b5f911d558388c87ce.jpg" alt="Image from Gyazo" width="1000"/></a></p>
<p>E-ink Androidで、電子書籍端末専用で使っている。スタイラスペンも付属しているが、こちらは使っていない。</p>
<p>起動時間、画面描画の速さ、使えるアプリなど、いずれも実用的で電子書籍を読むときはほぼこれになっている。別売りの音量ボタン付きスリーブケースを取り付け、Kindleなどで「音量ボタンでページめくりを行う」設定をすると、物理ボタンでかなり速いページめくりを行えるようになる。ただ、そのためだけにケースを買って全体の重量を増やすのはイマイチなのは確かで、今だと物理ボタンが本体に搭載された <a href="https://sktgroup.co.jp/boox-leaf2/">BOOX Leaf 2</a> を買うほうがいいかもしれない。</p>
<h2>KAT Iron</h2>
<p><a href="https://gyazo.com/3c89a014d525a944289aee5d4447c664"><img src="https://i.gyazo.com/3c89a014d525a944289aee5d4447c664.jpg" alt="Image from Gyazo" width="1000"/></a></p>
<p>買ったのはだいぶ前なのだが、Group Buyに申し込んで今年届いたキーキャップ。名前通り「鉄」をコンセプトにした渋めのカラーリングも、フェニキア文字のレジェンドも、少し厚めの素材でできているため、コトコトと気持ちのよい音をさせてくれるところもすべてが良い。これで僕のキーボードは完璧になった。</p>
<h2>TOOL STAND DESK</h2>
<p><a href="https://gyazo.com/58bb07467096bd71068a30778279a8d4"><img src="https://i.gyazo.com/58bb07467096bd71068a30778279a8d4.jpg" alt="Image from Gyazo" width="1000"/></a></p>
<p>https://www.kingjim.co.jp/sp/spot/toolstand/</p>
<p>KING JIMが販売している、自立するバッグインバッグのような製品。机上にあまりモノを置きたくないし、かと言って袖机も買いたくないのだが、作業中にすぐ使うものは近くに置きたい、というニーズを上手く満たしてくれた。見た目に反して容量はあり、付箋、測量野帳、ペン、イヤホン、BOOX、机上の掃除用具、ScanSnap iX100、クリアファイル、さらに読みかけの本など色々突っ込んでいる。机上は綺麗だけどこの中はひどい有様になったりはする。</p>
<h2>エンジニアリングマネージャーのしごと</h2>
<p>https://www.oreilly.co.jp/books/9784873119946/</p>
<p>書籍についてはこれが一番よかったかなと思う。というか今年あんまり歯ごたえのある本は読めていないのを振り返ってみて反省した。書籍の感想は <a href="http://localhost:3000/blog/become_an_effective_software_engineering_manager">『エンジニアリングマネージャーのしごと』を読んだ - chroju.dev/blog</a> をご参考に。</p>
<h2>北海道富良野ホップ炭酸水 / ストロングスパークリングガラナ / 正気のサタン</h2>
<p><a href="https://gyazo.com/9bb9cf5ab6a1dcc03ce0972de496e9d3"><img src="https://i.gyazo.com/9bb9cf5ab6a1dcc03ce0972de496e9d3.jpg" alt="Image from Gyazo" width="1000"/></a></p>
<p>飲み物部門。</p>
<p>仕事中は炭酸水を常飲しており、炭酸の強さから基本的にはウィルキンソンを飲んでいるのだが、たまに変わったフレーバーがあれば手を出してもいて、今年飲んだ中では <a href="https://www.pokkasapporo-fb.jp/products/otherdrink/flavor/WJ69.html">北海道富良野ホップ炭酸水</a> と <a href="https://online.seicomart.co.jp/delivery/goods_list/goods_list_3.php?o_no=706900000001">ストロングスパークリングガラナ</a> が特によかった。フルーツテイストのフレーバーは炭酸水はどことなく甘みを錯覚するのだけど、この2つはホップとガラナということで、そういった錯覚もなくすっきり飲める。ただただリフレッシュしたいときには良い。後者は北海道メインのコンビニチェーン・セイコーマートのプライベートブランドなので、ネット通販で買っている。前者もあまり街中で見かけることはなく（見かけるのはJR東日本の駅自販機ぐらい）、同じく通販経由。</p>
<p><a href="https://gyazo.com/85f9fcfb168901b3f89e99d7dea91864"><img src="https://i.gyazo.com/85f9fcfb168901b3f89e99d7dea91864.jpg" alt="Image from Gyazo" width="1000"/></a></p>
<p><a href="https://yonasato.com/ec/product/satan">正気のサタン</a> は『よなよなエール』のヤッホーブルーイングが出したローアルビール。ヤッホーブルーイングのビールは好きなのだが、アルコール4%の『水曜日のネコ』ですらコンディションが完璧では無い日だと飲み干せずに頭痛と吐き気に襲われるレベルの下戸なので、自信を持って飲み干せるヤッホー製ドリンクが出たのは嬉しい。ローアルのIPA自体が現時点では珍しいし、香りも豊かで「妥協して飲む」のではなく積極的に飲みたくなる。ビールの味自体は好きで、酒は「万全に体調を整えて頑張れば飲める」という感じで飲んでいたが、これで潔く酒自体を諦められそうだなと思い始めている。</p>
<p>販路がまだ限定されていて、東京都内のセブンイレブンか通販でしか買えない。都内に足を運んだ際にセブンへ寄るのがルーチンになりつつある。</p>
<h2>さんしょうの種</h2>
<p><a href="https://gyazo.com/0e161b0ae22d679d0649980c66d35ed7"><img src="https://i.gyazo.com/0e161b0ae22d679d0649980c66d35ed7.jpg" alt="Image from Gyazo" width="1000"/></a></p>
<p>食べ物部門。</p>
<p>長野県へ旅行したときに、<a href="https://shop.yawataya.co.jp/item-detail/1156146">八幡屋磯五郎のさんしょうの種</a> を買ったのだがこれが手加減抜きに山椒を効かせていて最高に美味い。続けて10粒も食べると舌がビリビリしてくる。</p>
<h2>サブスク</h2>
<pre><code class="language-diff">  * Gyazo Pro (¥4,680 / year)
- * Day One (¥2,800 / year)
  * MoneyForward プレミアム会員 (¥500 / month)
  * Nintendo Switch Online + 追加パック (¥4,900 / year)
  * Amazon Prime Student (¥2,450 / year)
  * Spotify Premium Student (¥480 / month)
  * シネマシティ (¥1,000 / year)
- * Dynalist Pro ($7.99 / month)
+ * Workflowy Pro ($49 / year)
  * dアニメストア (¥400 / month)
  * メールマガジン「読書日記／フヅクエラジオ」 (¥800 / month)
  * ATOK Passport (¥300 / month)
  * IFTTT Pro ($1.99 / month)
- * Association for Computing Machinery ($99 / year)
+ * O’Reilly Online Learning ($299 / year)
- * Netflix (Standard) (¥1,490 / month)
+ * Mailbrew ($59.88 / year)
</code></pre>
<p>いくつか入れ替わったり追加されたりしている。Mailbrewについては <a href="https://chroju.dev/blog/mailbrew_nuzzel_alternative">Twitterの話題はMailbrewで収集する - chroju.dev/blog</a> で書いた。</p>
<p><a href="https://dayoneapp.com/">Day One</a> は以前からほのかにやめたい気持ちがあったが、最近一念発起してやめた。見た目のおしゃれな感じや、カレンダー形式で写真を眺めたり、x年前の今日の日記をピックアップしてくれたり、というのは好きだったが、お金を払わないとマルチデバイスで使えない、ウェブアプリはないなど、編集と閲覧の自由度が低く、俺の日記ぐらい俺の好きにさせろという気持ちが強くなった。現在は <a href="https://scrapbox.io">Scrapbox</a> で日記を書いている。気が向いたらエントリーにするかもしれない。</p>
<p>タスク管理などで使っているアウトライナーは <a href="https://dynalist.io">Dynalist</a> から <a href="https://workflowy.com">Workflowy</a> に変更した。以前はWorkflowyを使っていたので出戻りになる。Dynalist開発チームは最近流行りの <a href="https://obsidian.md/">Obsidian</a> の開発に手を取られているようで（参考 : <a href="https://talk.dynalist.io/t/no-monthly-blog-update-since-november-are-the-team-ok/7497/7">No monthly blog update since November. Are the team ok? - 🌟Features - Dynalist Forum</a>）、実際2021年9月以来、アップデートが停止してしまっている。この点を懸念してWorkflowyに移った。Dynalistのほうが機能は豊富なのだが、改めてWorkflowyを使うと、シンプルであるが故に考えることが少なく済む面もあり、今では気に入っている。</p>
<p>ACMはO'Reilly Online Learningを読める特典がなくなったので解約し、O'Reillyを直接契約することにした。なお定価は$499/yearなのだが、毎年9月頃に割引のキャンペーンがあるので、それを待って契約している。</p>
<p>Netflixは見たいものがなくなったために解約。これはもうフレキシブルに1か月単位で契約/解約するものだと思っている。</p>
<p>なお、しれっと昨年までなかったGyazo Proを追加した。これはもう何年か使っているのだが、ずっとリストに入れ忘れていた。Gyazo Proは写真やスクリーンショットで「後で使いそうなもの」をとにかく投げ込んでおけば、OCRやスクショ元のアプリ名で柔軟に検索できるので便利。またScrapboxと開発元が同じHelpfeel（旧NOTA）であり、Scrapboxは無料で使わせてもらっているので、せめてGyazoからお金を払わせてくれ、というような意味合いもある。</p>
]]></description>
            <link>https://chroju.dev/blog/best_buy_subscriptions_2022</link>
            <guid isPermaLink="false">best_buy_subscriptions_2022</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 27 Dec 2022 11:13:19 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[AWS Price List APIでAWSの料金体系をAPIから確認する]]></title>
            <description><![CDATA[<p>AWSサービスの各種価格設定を確認するときはHTMLを見ることが多いが、 <a href="https://docs.aws.amazon.com/ja_jp/awsaccountbilling/latest/aboutv2/price-changes.html">AWS Price List API</a> からも確認できる。AWS APIの1つではあるものの、これが他のAPIとは性質が異なり、ちょっと癖がある。</p>
<p>APIにはBulk APIとQuery APIの2種類がある。前者はあるサービスの価格情報などを文字通りまとめてダウンロードできるエンドポイントであり、APIとは言うが、実体としてはAmazon S3に保存されたJSONファイルになっている。そのため対象のサービスなどによってエンドポイント自体が異なってくる。ものによっては、例えばEC2だと4GB近い巨大ファイルが落ちてくるので扱いには注意が要る。</p>
<p><a href="https://gyazo.com/25e3c266352b066aedf1b2a098f28314"><img src="https://i.gyazo.com/25e3c266352b066aedf1b2a098f28314.png" alt="Image from Gyazo" width="794"/></a></p>
<p>Query APIはクエリをかけて、あるサービスの特定条件、例えばap-northeast-1のRDSのdb.t4g.microの料金のみを取得できる。こちらは各種SDKでも対応していて、AWS CLIの <code>pricing</code> サブコマンドからも叩くことが出来る。APIは3種類あり、 <a href="https://docs.aws.amazon.com/aws-cost-management/latest/APIReference/API_pricing_GetProducts.html">GetProducts</a> は料金情報の取得、<a href="https://docs.aws.amazon.com/aws-cost-management/latest/APIReference/API_pricing_DescribeServices.html">DescribeServices</a> はGetProductsでフィルタに使うことができる、あるサービスの属性情報の種類一覧を取得、  <a href="https://docs.aws.amazon.com/aws-cost-management/latest/APIReference/API_pricing_GetAttributeValues.html">GetAttributeValues</a> は属性情報に指定可能な値を一覧できる。</p>
<p>属性情報というのは例えばEC2であれば <code>instanceType</code> のような、価格情報の確定に関わるパラメータ。これが思った以上にたくさん指定しなくては十分に絞りきれない場合があったり、パラメータをどう指定するかわかりづらい部分がある。</p>
<p>Lambdaについて <code>describe-services</code> して属性情報を一覧すると以下のようになる。</p>
<pre><code class="language-bash">$ aws pricing describe-services --service-code AWSLambda --region ap-south-1
{
    "Services": [
        {
            "ServiceCode": "AWSLambda",
            "AttributeNames": [
                "productFamily",
                "termType",
                "usagetype",
                "locationType",
                "Restriction",
                "regionCode",
                "servicecode",
                "groupDescription",
                "location",
                "servicename",
                "group"
            ]
        }
    ],
    "FormatVersion": "aws_v1"
}
</code></pre>
<p>このうち <code>usageType</code> に指定可能な値を <code>get-attribute-values</code> で見てみる。</p>
<pre><code class="language-bash">$  aws pricing get-attribute-values --service-code AWSLambda --attribute-name usageType --region ap-south-1
{
    "AttributeValues": [
        {
            "Value": "AFS1-Lambda-GB-Second-ARM"
        },
        {
            "Value": "AFS1-Lambda-GB-Second"
        },
        {
            "Value": "AFS1-Lambda-Provisioned-Concurrency-ARM"
        },
        {
            "Value": "AFS1-Lambda-Provisioned-Concurrency"
        },
</code></pre>
<p>これらの値はAWSの料金明細などに記載があるが、それほど日頃見慣れているわけでもないし、AWSのドキュメントなどにも詳細な説明はない。AtributeNamesについては <a href="https://docs.aws.amazon.com/cur/latest/userguide/product-columns.html">Product details - AWS Cost and Usage Reports</a> に一覧されているが、その具体的な値、Valueが何を意味するかの記述はないので、手探りに考えていくしかない。</p>
<p>Lambdaは比較的とっつきやすくて、 <code>usageType</code> に <code>APN1-Request</code> （おそらくはap-notheast-1のリクエスト料金の意）を指定すると以下のように結果が1つに絞れる。若干妙な出力形式なのはJSONがstringで吐き出されているからで、こういった点でも癖がある。</p>
<pre><code class="language-bash">$ aws pricing get-products --service-code AWSLambda --region ap-south-1 --filters Type=TERM_MATCH,Field=usageType,Value=APN1-Request
{
    "PriceList": [
        "{\"product\":{\"productFamily\":\"Serverless\",\"attributes\":{\"regionCode\":\"ap-northeast-1\",\"servicecode\":\"AWSLambda\",\"groupDescription\":\"Invocation call for a Lambda function\",\"usagetype\":\"APN1-Request\",\"locationType\":\"AWS Region\",\"location\":\"Asia Pacific (Tokyo)\",\"servicename\":\"AWS Lambda\",\"operation\":\"\",\"group\":\"AWS-Lambda-Requests\"},\"sku\":\"3BE8DYKG4FYSZGDW\"},\"serviceCode\":\"AWSLambda\",\"terms\":{\"OnDemand\":{\"3BE8DYKG4FYSZGDW.JRTCKXETXF\":{\"priceDimensions\":{\"3BE8DYKG4FYSZGDW.JRTCKXETXF.6YS6EN2CT7\":{\"unit\":\"Request\",\"endRange\":\"Inf\",\"description\":\"AWS Lambda - Total Requests - Asia Pacific (Tokyo)\",\"appliesTo\":[],\"rateCode\":\"3BE8DYKG4FYSZGDW.JRTCKXETXF.6YS6EN2CT7\",\"beginRange\":\"0\",\"pricePerUnit\":{\"USD\":\"0.0000002000\"}}},\"sku\":\"3BE8DYKG4FYSZGDW\",\"effectiveDate\":\"2022-12-01T00:00:00Z\",\"offerTermCode\":\"JRTCKXETXF\",\"termAttributes\":{}}}},\"version\":\"20221214183021\",\"publicationDate\":\"2022-12-14T18:30:21Z\"}"
    ],
    "FormatVersion": "aws_v1"
}
</code></pre>
<p>自分が試すなかで厄介だったのはEC2で、それなりに多くの属性を指定しなければ一意の情報にまで絞り込むことができなかった。日頃あまり意識していなかったが、インスタンスタイプとリージョンや、Dedicated Hostなどのテナント属性だけでなく、ソフトがプリインストールされていたり、といった要素も関わってくる。最終的に1個に絞り込むには以下の属性が必要だった。</p>
<pre><code class="language-bash">$ aws pricing get-products --service-code AmazonEC2 --region ap-south-1 --filters '[{"Type":"TERM_MATCH","Field":"instanceType","Value":"t3.medium"},{"Type":"TERM_MATCH","Field":"location","Value":"US East (N. Virginia)"},{"Type":"TERM_MATCH","Field":"operatingSystem","Value":"Linux"},{"Type":"TERM_MATCH","Field":"tenancy","Value":"Shared"},{"Type":"TERM_MATCH","Field":"capacityStatus","Value":"Used"},{"Type":"TERM_MATCH","Field":"preInstalledSw","Value":"NA"}]'
</code></pre>
<p>なお、このAPIはTerraformにも対応しており、 <a href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/pricing_product">aws_pricing_product</a> で取得できる。このData sourceはかなりストイックで、取得結果が価格情報1つにまで絞り切れていないと <code>plan</code> の時点で失敗になる。</p>
<p>また先ほど見たとおり、結果はJSONがstringで落ちてくるので、そこから価格情報を取り出すには <code>jsonencode()</code> を噛ませる工夫が必要になる。いろいろとコツは要るが、使い方をマスターできればスポットインスタンスの価格設定にオンデマンドの価格を自動取得して設定する、ということもできるようになる。</p>
<pre><code class="language-hcl">data "aws_pricing_product" "ec2_instance" {
  # Price List APIはus-east-1とap-south-1しか対応していない
  provider     = aws.ap-south-1

  service_code = "AmazonEC2"
  filters {
    field = "instanceType"
    value = "t3.medium"
  }
  filters {
    field = "operatingSystem"
    value = "Linux"
  }
  filters {
    field = "preInstalledSw"
    value = "NA"
  }
  filters {
    field = "location"
    value = "Asia Pacific (Tokyo)"
  }
  filters {
    field = "tenancy"
    value = "Shared"
  }
  filters {
    field = "capacitystatus"
    value = "Used"
  }
}

resource "aws_spot_instance_request" "this" {
  spot_price = values(values(jsondecode(data.aws_pricing_product.ec2_instance.result).terms.OnDemand)[0].priceDimensions)[0].pricePerUnit.USD
}
</code></pre>
]]></description>
            <link>https://chroju.dev/blog/aws_price_list_api</link>
            <guid isPermaLink="false">aws_price_list_api</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 21 Dec 2022 00:23:35 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[CUEでTerraformを書いてみる]]></title>
            <description><![CDATA[<p>最近 <a href="https://github.com/cue-lang/cue">CUE</a> の話題を少しずつだがよく見かけるようになってきた。</p>
<ul>
<li><a href="https://engineering.mercari.com/blog/entry/20220127-kubernetes-configuration-management-with-cue/">CUE を使用した Kubernetes マニフェスト管理 | メルカリエンジニアリング</a></li>
<li><a href="https://engineers.ntt.com/entry/2022/08/08/082549">[DevOps プラットフォームの取り組み #4] CUE 言語の紹介 - NTT Communications Engineers' Blog</a></li>
<li><a href="https://gihyo.jp/article/2022/09/tsukinami-go-02">CUE によるスキーマやバリデーションのポータビリティ | gihyo.jp</a></li>
</ul>
<p>CUE とは何か、レポジトリの README から引用すると以下のように書かれている。</p>
<blockquote>
<p>CUE is an open source data constraint language which aims to simplify tasks involving defining and using data.
It is a superset of JSON, allowing users familiar with JSON to get started quickly.</p>
</blockquote>
<p>ポイントとしては JSON のスーパーセットであることと、データの定義や利用をシンプルにすることを目的としているという点だと理解している。昨今、Kubernetes の隆盛などにより、JSON やそれと互換性を持つ YAML を用いる機会が多くなったが、これら言語の機能だけではスキーマを定義したり、制約を書いたりすることは難しい。CUE はこれを解消する機能を持っているようである。</p>
<p>CUE が JSON のスーパーセットであるということは、JSON と互換性を持つ HCL のスーパーセットとしても使えるはずである。筆者はそもそも CUE に触ったこと自体がなかったので、今回は CUE で Terraform の定義をどのように書けばよいのか探りながら CUE に入門してみた。</p>
<h2>HCL と JSON の互換性</h2>
<p>https://developer.hashicorp.com/terraform/language/syntax/json</p>
<p>HCL と JSON には互換性があり、Terraform の定義も JSON で書くことが可能である。 <code>terraform</code> コマンドの対象として、カレントディレクトリの <code>*.tf</code> に加えて、 <code>*.tf.json</code> という postfix の JSON ファイルも読み取られる仕様となっている。</p>
<p>変換の手順としてはシンプルに key value をそのまま JSON として起こしていくだけだが、 <code>resource "aws_instance" "this" {}</code> のように複数の label が連続する箇所については、JSON Object がネストする形になる。例えば以下の HCL があるとする。</p>
<pre><code class="language-hcl">resource "aws_ebs_volume" "this" {
    availability_zone = "ap-northeast-1a"
    size              = 50
}

resource "aws_s3_bucket" "this" {
    bucket = "example"
}
</code></pre>
<p>これは以下の JSON に等しい。</p>
<pre><code class="language-json">"resource" : {
    "aws_ebs_volume" : {
        "this" : {
            "availability_zone" : "ap-northeast-1a",
            "size" : 50
        }
    },
    "aws_s3_bucket" : {
        "this" : {
            "bucket" : "example"
        }
    }
}
</code></pre>
<h2>CUE で Terraform の定義を書く</h2>
<p>早速ではあるが、上記の JSON を CUE に起こすと以下のようになる。</p>
<pre><code class="language-cue">resource: {
    aws_ebs_volume: {
        this: {
            availability_zone: "ap-northeast-1a"
            size: 50
        }
    }
    aws_s3_bucket: {
        this: {
            bucket: "example"
        }
    }
}
</code></pre>
<p>あるいは、 <a href="https://cuelang.org/docs/tutorials/tour/intro/fold/">フィールドが 1 つだけの場合はブラケットを省略できる</a> ので、以下も同義になる。</p>
<pre><code class="language-cue">resource: {
    aws_ebs_volume: this: {
        availability_zone: "ap-northeast-1a"
        size: 50
    }
    aws_s3_bucket: this: {
        bucket: "example"
    }
}
</code></pre>
<p>JSON への変換は <code>cue</code> コマンドを使って行う。コマンドのインストール方法は <a href="https://cuelang.org/docs/install/">ドキュメント</a> では <code>brew install cue-lang/tap/cue</code> となっているが、12 月の現時点では homebrew-core にも入っているようである。 <code>cue eval sample.cue</code> でバリデーション、 <code>cue export sample.cue</code> で JSON への変換が行える。</p>
<p>これだけだと key はクォーティングしなくて良くてちょっと楽ですねとか、それぐらいなものではあり、特に魅力を感じられる気はしてこない。</p>
<h2>スキーマ定義とバリデーション</h2>
<p>ここからが本領、CUE でスキーマを定義したり、値のバリデーションをかけたりするフェーズに入っていく。</p>
<p>CUE では「<a href="https://cuelang.org/docs/concepts/logic/#types-are-values">型は値である</a>」と言われる。これはあるフィールドを定義するものとして、型や制約と、具体的な値とが同じように評価されるということを意味する。数学的には <a href="https://cuelang.org/docs/concepts/logic/#the-value-lattice">Lattice</a>、日本語で「<a href="https://ja.wikipedia.org/wiki/%E6%9D%9F_(%E6%9D%9F%E8%AB%96)">束（そく）</a>」の概念を取り入れている。</p>
<pre><code class="language-cue">resource: aws_ebs_volume: this: {
    availability_zone: string
    size: &#x3C;100
}

resource: aws_ebs_volume: this: {
    availability_zone: "ap-northeast-1a"
    size: 50
    encrypted: true
}
</code></pre>
<p>上記の CUE は成り立つ。まず、CUE では同じフィールドに対する定義を複数回書けるので、 <code>resource: aws_ebs_volume: this:</code> が複数存在していてもエラーにはならない。複数回記述されたフィールドは、その論理積が取られるような形になる。 <code>availability_zone</code> は <code>string</code> かつ <code>"ap-northeast-1a"</code> であり、 <code>size</code> は <code>&#x3C;100</code> かつ <code>50</code> 、という具合である。ここにさらに <code>size: >100</code> や <code>availability_zone: "us-east-1"</code> といった記述を追加すると論理積は空集合となってしまい、CUE の評価は失敗する。また 2 つの定義の双方で、フィールドの過不足があっても問題ない。上記の例の場合、最終的には <code>encrypted: true</code> が存在する形になる。</p>
<p>バリデーションは多様な書き方ができる。string に対しては正規表現も書けるし、論理和 <code>|</code> のオペランドが備わっていて、 enums のように <code>availability_zone: "ap-northeast-1a" | "ap-northeast-1c"</code> といった書き方もできる。また同様に論理和を使った書き方として、アスタリスクを付けるとデフォルト値を指定でき、 <code>size: &#x3C;100 | *50</code> とすれば、具体的に size の指定がなければ 50 として評価される。</p>
<h2>Definition</h2>
<p>CUE で記述されたデータを JSON に変換するには、当然ではあるが最終的に具体的な値を持つ必要がある。様々な AWS リソースのスキーマだけを書いたファイルを取りあえず用意して、このうち一部のリソースしか実際には定義しない、ということもあるだろうが、スキーマだけの状態だと値が確定できず、 <code>cue export</code> は失敗する。</p>
<pre><code class="language-bash">$ cat &#x3C;&#x3C;EOF > sample.cue
resource: aws_ebs_volume: this: {
    availability_zone: string
    size: &#x3C;100
}
EOF

$ cue export sample.cue
resource.aws_ebs_volume.this.availability_zone: incomplete value string:
    ./sample.cue:2:24
resource.aws_ebs_volume.this.size: incomplete value &#x3C;100:
    ./sample.cue:3:11
</code></pre>
<p>このような場合は Definition を使う。頭に <code>#</code> を付けたフィールドは Definition として扱われ、データとしては評価されない。</p>
<pre><code class="language-bash">$ cat &#x3C;&#x3C;EOF > sample.cue
#resource: aws_ebs_volume: this: {
    availability_zone: string
    size: &#x3C;100
}
EOF

$ cue export sample.cue
{}
</code></pre>
<p>Definition を利用するときには <code>&#x26;</code> を使って呼び出す。上記は簡易な例として <code>resource</code> を Definition にしてしまったが、実際に Definition として作りたいのは <code>aws_ebs_volume</code> の方なので、より実践的な書き方としては以下のようになる。</p>
<pre><code class="language-bash">$ cat &#x3C;&#x3C;EOF > sample.cue
#aws_ebs_volume: this: {
    availability_zone: string
    size: &#x3C;100
}

resource: aws_ebs_volume: #aws_ebs_volume &#x26; {
    this: {
        availability_zone: "ap-northeast-1a"
        size: 10
    }
}
EOF

$ cue export sample.cue
{
    "resource": {
        "aws_ebs_volume": {
            "this": {
                "availability_zone": "ap-northeast-1a",
                "size": 10
            }
        }
    }
}
</code></pre>
<p>Terraform resource の定義は JSON だと深いネストを必要とするので、これでも少し冗長に感じる。呼び出し側の記述をもう少しシンプルにしたければ、 Definition をフル活用して以下のようにも書ける。 <code>#resource_name</code> は Terraform らしく、半角英字とアンダースコアしか使えない制約も追加した。</p>
<pre><code class="language-cue">#aws_ebs_volume: {
    #resource_name: =~ "^[a-z_]+$"
    #availability_zone: string
    #size: &#x3C;100
    resource: aws_ebs_volume: "\(#resource_name)": {
        availability_zone: #availability_zone
        size: #size
    }
}

#aws_ebs_volume &#x26; {
    #resource_name: "prod_instance_ebs"
    #availability_zone: "ap-northeast-1a"
    #size: 10
}
</code></pre>
<p>これだと非常にシンプルにはなったが、呼び出し側で <code>aws_ebs_volume</code> に新たなパラメータを追加できなくなっていることには注意が必要だ。頑張れば何か手段があるかもしれないが、今の時点では思い浮かばなかった。</p>
<h2>Package / Modules の分離</h2>
<p>Definition による型や制約は、何らかの形で切り出して、複数のプロダクトなどで使い回したくなってくる。コードの再利用を進める仕組みとして、 CUE にも Package / Modules の概念が存在している。</p>
<p>CUE で Modules を使うには、 <code>module: "example.com/pkg"</code> と記したファイルを <code>./cue.mod/module.cue</code> に配置する必要がある。手動で作ってもよいが、 <code>cue mod init example.com/pkg</code> コマンドで自動生成もしてくれる。このあたりは Go の設計に影響を受けており、モジュール名も <code>github.com/user/repo</code> 形式が <a href="https://cuelang.org/docs/concepts/packages/#creating-a-module">原則とされている</a> 。 <code>cue mod init</code> により、Go での外部パッケージ管理を彷彿とさせる <code>cue.mod/{pkg,usr}</code> といったディレクトリも作成されるのだが、現時点では CUE 自体の Package Management の仕組みがなく、あまり活用する機会がないように思えている。</p>
<p>https://github.com/cue-lang/cue/issues/851</p>
<p>Package を宣言するのも Go と同様で、1 行目に <code>package main</code> のように記述する。なお Package と Module は包含関係にあり、 Module 内に複数 Package が存在できる。 Module はディレクトリで切られるが、その中に異なる Package のファイルが複数配置可能だ。</p>
<p>実践してみる。先の例から、スキーマについては別の Package に切り出すとして、 <code>./schema/terraform</code> に以下のようなファイルを作る。</p>
<pre><code class="language-cue">package ebs

#aws_ebs_volume: {
    #resource_name: =~ "^[a-z_]+$"
    #availability_zone: string
    #size: &#x3C;100
    resource: aws_ebs_volume: "\(#resource_name)": {
        availability_zone: #availability_zone
        size: #size
    }
}
</code></pre>
<p>これを <code>./main.cue</code> で呼び出すときも、やはり Go のような書き方になる。ここでは仮に <code>cue mod init github.com/chroju/cue-sandbox</code> を実行済みとする。</p>
<pre><code class="language-cue">package main

import (
    "github.com/chroju/cue-sandbox/schema/terraform:ebs`
)

ebs.#aws_ebs_volume &#x26; {
    #resource_name: "prod_instance_ebs"
    #availability_zone: "ap-northeast-1a"
    #size: 10
}
</code></pre>
<p>実際の現場で使う場合は、さらに複雑なモジュール構成になっていくのかもしれない。例えば社内標準の <code>#aws_ebs_volume</code> を定義した Package を設け、それを <code>package prod</code> で本番環境相当により厳しくした <code>#aws_ebs_volume</code> と掛け合わせる、といった使い方が想定できる。</p>
<h2>Script で Terraform を実行する</h2>
<p>今更ながら CUE という単語の意味を紐解くと、 <code>Configure Unify Execute</code> の略だとされている。最後の <code>Execute</code> についてだが、CUE には <a href="https://cuelang.org/docs/usecases/scripting/">Scripting</a> というコマンド実行の機能が備わっている。組み込みの <code>tools/exec</code> や <code>tools/file</code> といったパッケージを使って、シンプルなシェルコマンドの実行からファイルの作成削除など、様々な操作が可能だ。</p>
<p>CUE で Terraform を扱う場合、Terraform コマンドの実行前に CUE から JSON への変換などを行う必要があるので、これをスクリプトにまとめると便利になる。詳細は割愛するが、以下のような CUE を書いて、 <code>cue cmd plan</code> と実行することにより、変換から <code>terraform plan</code> の実行、変換後 JSON の削除までを一発で完了させることができた。</p>
<pre><code class="language-cue">package main

import (
	"tool/cli"
	"tool/exec"
	"tool/file"
)

command: plan: {
  echo_start: cli.Print &#x26; {
    text: "Convert cue to JSON ..."
  }

  export: exec.Run &#x26; {
    cmd: ["cue", "export", "."]
    stdout: string
  }

  remove_old_file: file.RemoveAll &#x26; {
    path: "terraform.tf.json"
  }

  generate_file: file.Append &#x26; {
    filename: "terraform.tf.json"
    contents: export.stdout
  }

  echo_plan: cli.Print &#x26; {
    text: "Execute terraform plan ..."
  }

  tfplan: exec.Run &#x26; {
    cmd: ["terraform", "plan", "-out=tfplan"]
  }

  remove_file: file.RemoveAll &#x26; {
    $dep: tfplan
    path: "terraform.tf.json"
  }
}
</code></pre>
<h2>Impression</h2>
<p>ざっくりと型定義、バリデーションなども行いつつ、CUE を使って Terraform を実行するまでを眺めてみた。率直な感想としてはわりと使えそうかもしれないと感じた。どちらかの方向への依存関係が発生するわけではなく、複数の定義を掛け合わせて最終的なデータを作って行くという形式は柔軟性が高い。Terraform 標準の機能では module の中で module を使ったりするとかなり複雑化してくるが、CUE であれば後からパラメータを追加するといったことも簡単にできる。かなり高機能なバリデーションを、 Sentinel や OPA/Rego といった別のツールを使わず、 CUE の中で完結できるのも良い。</p>
<p>一方、注意点も少なくない。当然ながら HCL の機能は使えないため、 <code>bucket = aws_s3_bucket.this.id</code> のようなリテラルは利用できず、懐かしい <code>"${aws_s3_bucket.this.id}"</code> 形式を使う必要がある。また先述したとおり、Package management の仕組みがないのは少々想定外だった。個人的にはスキーマだけを切り出した Module を 1 つのレポジトリで共有して、各プロダクトでそれを import するような使い方を想定していたからだ。インポートの機能としては <code>cue get go</code> コマンドによって Go Module の struct を CUE の struct として読めるという機能はあるので、そう遠くないうちに CUE Module もインポートできるようになるだろうとは思う（Kubernetes のリソースは Go の struct で定義されているため、これが結構便利らしい。残念ながら Terraform resource のスキーマ自体は <a href="https://pkg.go.dev/github.com/hashicorp/terraform-plugin-sdk/v2@v2.24.1/helper/schema#Resource">struct ではない</a>）。VSCode Extension などの入力支援もまだ乏しく、良くも悪くもまだまだ発展途上にあると感じてもいる。</p>
<p>あとは CUE の学習コストをかけてまで移行するメリットを見出せるか次第かなと思う。Lattice の概念に基づく記述は他に経験がなく、慣れるまでに多少の時間はかかったし、ここに書いた記述法でもまだ触り程度であり、CUE の表現力は極めて高く、それなりに学習コストを要する言語ではある。ただ、一度覚えれば Kubernetes にも Terraform にも、その他 JSON や YAML を使った様々な言語も内包し得るというのは魅力に映る。冒頭に貼った NTT コミュニケーションズやメルカリが目指しているのは、おそらくそういう地平なんじゃないだろうか。</p>
<h2>Reference</h2>
<p>今回参考にしたサイトをいくつか貼っておく。公式の Docs を見るのであれば Tutorials と Language Specification は特におすすめである。ただ、これだけではなかなかイメージが掴めず、Cutorials に非常に助けられた。</p>
<ul>
<li><a href="https://cuelang.org/docs/">Documentation | CUE</a></li>
<li><a href="https://cuetorials.com/">Cuetorials</a></li>
<li><a href="https://blog.cedriccharly.com/post/20210523-how-cue-wins/">How CUE Wins | Cedric Charly's Blog</a></li>
<li><a href="https://blog.cedriccharly.com/post/20191109-the-configuration-complexity-curse/">The Configuration Complexity Curse | Cedric Charly's Blog</a></li>
<li><a href="https://qiita.com/riita10069/items/1c9077657fcd62843aaf">CUE 言語の Kubernetes チュートリアル【和訳】 - Qiita</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/cue_terraform</link>
            <guid isPermaLink="false">cue_terraform</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 16 Dec 2022 12:21:02 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『エンジニアリングマネージャーのしごと』を読んだ]]></title>
            <description><![CDATA[<p>https://www.oreilly.co.jp/books/9784873119946/</p>
<p>単なる管理職ではなくて「エンジニアリングマネージャー」に特化した本として良かった。</p>
<p>自分も小規模なチームのリーダーをやりつつ手は動かしているので「エンジニアリングマネージャー」に当たるはずで、ここで悩ましいのがどこまで自分で手を動かすかという線の引き方になる。本書は序盤で「マネージャーのアウトプット＝チームのアウトプット＋影響を与えた他のチームのアウトプット」という大前提を敷いており、たびたびこの方程式を持ち出しては、それにぶら下がる形で各論を述べる、という構成になっているので納得感が得やすい。注力するべきは「チームのアウトプット」を最大化することであり、自分個人のアウトプットの最大化ではない。役割を担っている以上、周囲からもマネージャーとしての仕事が期待されるわけでもある。したがって冒頭の悩みに対する解は、まずはチームのアウトプット最大化に時間を割くべきであり、自分がコーディングなどに使う時間は二の次、というのが明白になる。まぁ言われてみればそれはそうだという話でしかなくて、二足のわらじを履いているようでいながら、実際にはマネージャーのほうに軸足が強く置かれるということになる。このことを明確かつきっぱりと突きつけてくれた上で、そのために何をするべきかも具体化してくれる。</p>
<p>マネージャーというのは自分で直接生産するよりは、連絡をしたり調整をしたり、というような業務が多くなるので、自分が何を成したのかが曖昧になりやすくもある。また責任範囲も大きくなるので、あれこれと心配事が増えやすくもある。このあたりについてもRACIやAppleのDRI（参考 : <a href="https://www.lifehacker.jp/article/170130_businessinsider_mediagene/">ジョブズが会議を生産的にした3つの方法 | ライフハッカー・ジャパン</a>）を使って責任を明確に整理したり、マネージャーの仕事を言語化して4つに分類してくれたりしているので、自分で自分の仕事を見通しやすくなったように感じる。</p>
<p>心配事が増えやすい点に関しては、よく言われる「コントローラブルなものとアンコントローラブルなものを区別して、後者について心配するのをやめろ」という話が出てくる。この手の話は7つの習慣の1つとして「関心の輪、影響の輪」という形で言及されていたり、「<a href="https://ja.wikipedia.org/wiki/%E3%83%8B%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E7%A5%88%E3%82%8A">ニーバーの祈り</a>」などの類似概念も存在する。自分が影響を及ぼし得ないものに対して関心を持っても徒労になるという点には同意する一方で、「ニーバーの祈り」にも書かれているように、「変えられないものと変えるべきものを区別する」には「賢さ」が必要になる、つまり簡単なことではない。チーム内の不文律、チームメンバー構成、社内ルール、現状のアーキテクチャなどなど、こういったものが本当に変えられないのか、変えるのが困難なだけなのか、特にマネージャーという立場においては、如何に前提を疑った上でコントロールしていけるかというのがより重要になってくると感じた。前提や枠組みを疑えるか、という点については以下のエントリーも非常に示唆に富んでいる。「関心の輪、影響の輪」を単なる諦念として扱わないようには注意したい。</p>
<p>https://kamiyakenkyujo.hatenablog.com/entry/2020/11/13/002402</p>
<p>これほどつらつらと様々な概念を連想して思考できたのは、ひとえにScrapboxのおかげで、Scrapboxにメモしながら本を読むのはやはりいいなぁ、と思ったりもしたのだった。</p>
<p>https://scrapbox.io/nishio/%E9%80%A3%E6%83%B3%E3%81%AE%E3%82%B9%E3%83%88%E3%83%83%E3%82%AF</p>
]]></description>
            <link>https://chroju.dev/blog/become_an_effective_software_engineering_manager</link>
            <guid isPermaLink="false">become_an_effective_software_engineering_manager</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 09 Oct 2022 08:26:18 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[日々をそのまま書き下して管理すること、あるいはLogseqとWorkflowyの話]]></title>
            <description><![CDATA[<p><a href="https://logseq.com/">Logseq</a> というNote Takingのためのツールを今年に入ってから何度か試してみては、うまく自分にフィットせずに諦める、ということを繰り返している。</p>
<p>Note Takingの分野だと、昨年ぐらいからは <a href="https://obsidian.md/">Obsidian</a> も流行っているが、LogseqもObsidianと同じく、ローカルのファイルシステムに保存する形式を取っている。Wikiのようにページ間のリンクを容易に作れる、デイリーページの機能がある、Markdownを書ける（Logseqのほうは厳密にはMarkdown likeではあるが）というあたりも両者は似ている。大きく異なる点としては、Logseqでは各ページをアウトライナーのように編集することができ、箇条書きの前後や階層構造を入れ替えたり、特定の階層配下だけを切り出して画面に表示したり、といったことができる点だろうか。タスク管理の機能がLogseqにはデフォルトで内蔵されているが、Obsidianには内蔵されていないという違いもある。LogseqはOrg-modeに似ている気がする。使ったことはないのだが。</p>
<p>僕は長らく <a href="https://workflowy.com">Workflowy</a> や <a href="https://dynalist.io">Dynalist</a> といったアウトライナーを使ってデイリーページを書いてきた。デイリーページ、あるいは日記、あるいは日報。そもそもなんで日報を書くのか、という話は <a href="https://dev.classmethod.jp/articles/diary_driven_work_hacks/">日記駆動仕事術のススメ | DevelopersIO</a> とか <a href="https://next49.hatenadiary.jp/entry/20120529/p2">日報・週報を自分の役に立てるために書く - 発声練習</a> とかに譲る。毎朝その日のToDoをガリガリ書き出して、それを1つずつ潰しつつ、メモを取りつつデイリーページを埋めていくのが僕の1日だ。</p>
<p>アウトライナーというのは箇条書きの文章のアウトラインを編集するツールであり、デイリーページのための機能があるわけではない。毎日デイリーページの階層を切って、その下につらつらと書き連ねている。そんなことをするなら、最初からデイリーページ機能のあるアウトライナーっぽいツールであるLogseqを使えばいいんじゃないか、という思いから試しているわけである。Logseqはその日初めて「journal」という場所を開くと、勝手にその日のページが作られて開くようになっている。Workflowyでその日の階層を切る、というのもそこまでの手間ではないが、勝手にその日のためのまっさらなページが用意され、前日のことは見えなくなる、というのは、試してみると結構体験がいい。</p>
<p>しかしながら、結局Workflowyから移行するところまでは踏み出せない。</p>
<p>おそらく、デイリーページとして使いたいだけならLogseqに勝るものはない気がしている。しかし自分がアウトライナーを使っている目的はデイリーだけではなく、タスク管理全般に使っている。つまるところ「その日1日の全体像の把握」と、「ここ最近自分が気にしていること、やっていることの全体像の把握」だ。今日やったこと、というのが、今日その日だけの関心であればそれでいいのだが、実際はその日にやったことは大きな全体の一部であることが少なくない。そのダイナミクスを管理したい、というのが自分の求めるタスク管理ツールになっている。</p>
<p>例えばWorkflowyでデイリーページをこんな感じで書いているとする。</p>
<p><a href="https://gyazo.com/ac5c0aea656a351f28ac7f0ad44f544a"><img src="https://i.gyazo.com/ac5c0aea656a351f28ac7f0ad44f544a.png" alt="Image from Gyazo" width="502"/></a></p>
<p>このとき、「その仕事」はいざ取りかかってみたら案外考えなくちゃいけないことが多そうだな、という感じになっている。すると「その仕事」はこの日だけの話ではなくなる。そういうときにアウトライナーであれば、</p>
<p><a href="https://gyazo.com/f19760cf45931e5044ccd263e8a5c947"><img src="https://i.gyazo.com/f19760cf45931e5044ccd263e8a5c947.png" alt="Image from Gyazo" width="504"/></a></p>
<p>こんな感じで「その仕事」をデイリーの枠の外に引っ張り出せる。1日1日、という枠を越えてなんか考えなくちゃいけない、ならデイリーの中じゃなく1個上の階層に置いとこ、ということができる。これはざっくりした例だが、自分が認知したいかたちに合わせて自在にメモの階層構造を変化させられるのがアウトライナーの魅力と捉えている。</p>
<p>人生とか生活といったものはナマモノであり、それを脳内にどう入れておきたいか、というのも日々変化していく。ならば「やること」「考えたいこと」あるいは「考えたこと」「気付いたこと」などは全部1個の階層の中に入れ込んで、ぐにゃぐにゃ動かしながら生きていくのが自分の中では自然に思えている。というか、これが出来ないと結構つらい。おそらく、僕は僕の脳の扱いがあまり上手くない。人によっては、こういうことはチラシの裏があれば上手く整理して生活していけるのだろうと思うが、自分の場合は書き下したものが脳内と上手くシンクロしないとストレスに感じてしまう。</p>
<p>翻ってLogseqは、ページを基本単位としたツールだ。Workflowyのように自在に上下関係が変化し、全体と個別とが入れ替わるようなツールではなく、明確な「枠」がページとして切られる必然がある。</p>
<p>デイリーページで今日のページが作られると、それに対応したMarkdownファイルがローカルでは生成されている。それがどうも自分の脳と合わない。毎日がブツ切れになっているように感じてしまい、毎日をゆるやかに結ぶ全体感、というものをLogseq上に見出しづらい。「全体を管理する」ためのページをLogseqに1枚設けて、それとデイリーページの間でやり取りする、という形も試してはみたが、それでも乗れなかった。どうもLogseqの「ページを作る」という動作自体が苦手らしい。日々の思考の中には「今後どうなるかはわからないけど、取りあえずメモしておきたいこと」というものもあるのだが、そういう「取りあえず」をどこに置くかがLogseqだと悩ましい。未確定なのでページを切りたいわけではない。例えば <code>#later</code> みたいなタグをつけて、あとからfilteringして処理することもできなくはないが、Logseqでは文章を別の任意のページへ移動させる機能が現状なく、「取りあえず」で書いたものを全体のページへ移動させたりするには、カットアンドペーストする必要がある。ここさえクリアすれば、もしかしたらフィットしてくるかもしれない、という思いもある。</p>
<p>ツールの選定に長時間を費やすのはバッドプラクティスとされることが多く、自分もこんなことで悩みたくはないなとも思うのだが、日々の思考を支えてくれるツールというのは自分の生産性の根幹にあるだけに、ついつい考え込んでしまう。自分はおそらくLogseqがわりと好きなのだ。ローカルにメモを保存できるという点も、OSSである点も、<a href="https://hub.logseq.com/features/av5LyiLi5xS7EFQXy4h4K8/getting-started-with-advanced-queries/8xwSRJNVKFJhGSvJUxs5B2">Advanced queries</a> という高機能な検索クエリが使える点も。それだけに、なんとかしてLogseqに移行できないかとつい試してみては、やはりダメだと戻ってくる、を繰り返している。</p>
<p>その繰り返しにさすがに嫌気がさしてきたので、現時点での結論を書き記しておくために、エントリーをしたためてみた。</p>
]]></description>
            <link>https://chroju.dev/blog/logseq_vs_workflowy</link>
            <guid isPermaLink="false">logseq_vs_workflowy</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 18 Sep 2022 09:21:09 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[K3s + Cloudflare Zero Trustな環境をuser dataでシュッと建てる]]></title>
            <description><![CDATA[<p>個人のKubernetes環境でベストな形というのを結構ずっと探っている。やりたいこととしてはIaCできちんと管理した形でK8sを運用したい、というのと、クラウドに建てるので、ローカルからセキュアにK8s APIを叩きたい、というあたり。昨年は <a href="http://chroju.dev/blog/kops_argo_cd_private_k8s_cluster">kops と Argo CD でプライベート Kubernetes を建てる - chroju.dev/blog</a> というのを書いたりしたのだが、結構重量級の環境になってしまった故、その後断念している。</p>
<p>最近 <a href="https://k3s.io/">K3s</a> を用いることである程度形になった。K3sはワンバイナリで動作する軽量なK8s実装であり、非常に扱いやすい。またK8s APIを遠隔から実行するにあたっては <a href="https://www.cloudflare.com/ja-jp/products/zero-trust/">Cloudflare Zero Trust</a> を用いることにしてみた。</p>
<p>現在、この環境をEC2 + user dataを使って <code>terraform apply</code> 一発で建てる仕組みを使い始めたので、少しまとめておきたい。</p>
<h2>K3s</h2>
<p>https://k3s.io/</p>
<p>Kubedrnetes (K8s) から諸々の機能を省いて、メモリフットプリントを半分にした実装。名前もKubernetes = 10文字の半分なので5文字でK3s、ということらしい。Rancherが元々開発していたもので、2020年にCNCF入りしている。</p>
<p>最も簡単なインストール方法としては <code>curl -sfL https://get.k3s.io | sh -</code> を実行することだが、あまりスクリプトでのインストールが好きではないので、直接バイナリを落としてきて使っている。バイナリダウンロードによるインストール方法も<a href="https://rancher.com/docs/k3s/latest/en/installation/install-options/">Docsに言及があり</a>、systemd周りの設定を自力でやらなくてはならないぐらいで、特別煩雑な手順にはならない。</p>
<pre><code class="language-bash"># Install k3s
curl -Ls https://github.com/k3s-io/k3s/releases/download/${k3s_version}/k3s -o /usr/local/bin/k3s
chmod +x /usr/local/bin/k3s
ln -s /usr/local/bin/k3s /usr/local/bin/kubectl

cat > /etc/systemd/system/k3s.service &#x3C;&#x3C;EOF
[Unit]
Description=Lightweight Kubernetes
...

Environment=K3S_KUBECONFIG_MODE=644
...
ExecStart=/usr/local/bin/k3s server
EOF

systemctl daemon-reload
systemctl enable k3s
systemctl start k3s
</code></pre>
<p>サーバとしてK3sを起動するときのオプションとしては、 <code>K3S_KUBECONFIG_MODE</code> を適切に設定しなければ、rootでしか <code>kubectl</code> できなくなってしまう点に注意が要る。</p>
<p><code>kubectl</code> もK3sは内包していて、 <code>kubectl</code> のエイリアスとして実行すると <code>kubectl</code> として動作してくれる。</p>
<p>遠隔から <code>kubectl</code> で繋ぎにいくにあたっては、 <code>/etc/rancher/k3s/k3s.yaml</code> をkubeconfigとして用いればよい。ローカルからすぐに確認できるよう、user dataの中でこれをパラメータストアへ投げさせている。</p>
<pre><code class="language-bash"># Register kubeconfig
apt update
apt install awscli -y

KUBE_CONFIG=$(cat /etc/rancher/k3s/k3s.yaml)
aws ssm put-parameter --region ap-northeast-1 --name /chroju/k3s/kube_config --type SecureString --overwrite --value "$KUBE_CONFIG"
</code></pre>
<h2>Cloudflare Zero Trust + kubectl</h2>
<p><code>kubectl</code> はローカルから実行したいが、APIのエンドポイントをインターネット上に開放したくはないので、 Cloudflare Zero Trustを使っている。これはCloudflareが提供するゼロトラスト関連サービスの総称であり、より具体的にはCloudflare TunnelとCloudflare Accessを使う。</p>
<p>Tunnel[^1]は、サーバのインバウンド通信を開放せずとも、サーバ上で稼働するデーモン（cloudflared）がCloudflareと通信を確立することにより、Cloudflare経由でサーバの公開が可能となるサービス。httpを開放してWebサイトを運用するのにも利用できるし、SSHなどもサーバのポート開放を行うことなく通信が可能となる。</p>
<p>Tunnelが開放したエンドポイント自体には認証の仕組みが一切ないため、アクセス制御を行うのにCloudflare Accessを用いる。これはCloudflareのDNSサーバーに登録したドメイン上の任意のパスなどに認証を付与できるサービスで、いわゆるゼロトラストの中心的なサービスにあたると捉えている。個人開発のサービスに簡単に認証が付けられるし、企業ユースならSaaSに対するSSOのようなこともできるらしい。</p>
<p>認証方式は様々なものが用意されているが、最もシンプルなところだとワンタイムコードのメール送信がある。指定したメールアドレスにのみコード送信を許可できるので、メールアカウントさえ守れば防御できる。これを設定すると、当該のエンドポイントへ <code>kubectl</code> で繋ぎに行った際、以下のような認証画面がブラウザで自動的に表示されるようになる。</p>
<p><a href="https://gyazo.com/77fe8ddb6169fb58e4b67003ea00c500"><img src="https://i.gyazo.com/77fe8ddb6169fb58e4b67003ea00c500.png" alt="Image from Gyazo" width="698"/></a></p>
<p>Tunnelを使うにあたっては、先にTunnelを作成しておき、cloudflaredには接続するTunnelの情報を書いたJSONと、接続に必要なSecretなどが書かれたYAMLを読み込ませる形になる。TunnelはTerraformで構築できるので、先にTeraformで構築した後、必要な情報をTerraform <code>templatefile</code> に埋め込んでuser dataを作成している。</p>
<pre><code class="language-bash"># Install cloudflared for kubectl (Kubernetes API)
curl -Ls https://github.com/cloudflare/cloudflared/releases/download/${cloudflared_version}/cloudflared-linux-amd64.deb -o /tmp/cloudflared.deb
dpkg -i ./tmp/cloudflared.deb

mkdir -p /root/.cloudflared
cat > /root/.cloudflared/${cloudflare_tunnel.kubectl.id}.json &#x3C;&#x3C;EOF
{
  "AccountTag": "${cloudflare_account_id}",
  "TunnelSecret": "${cloudflare_tunnel.kubectl.secret}",
  "TunnelID": "${cloudflare_tunnel.kubectl.id}"
}
EOF

cat > /root/.cloudflared/config.yaml &#x3C;&#x3C;EOF
tunnel: ${cloudflare_tunnel.kubectl.id}
credentials-file: /root/.cloudflared/${cloudflare_tunnel.kubectl.id}.json

ingress:
  - hostname: ${cloudflare_tunnel.kubectl.hostname}
    service: tcp://127.0.0.1:6443
    originRequest:
      proxyType: socks
  - service: http_status:404
EOF

cloudflared service install
</code></pre>
<p><code>config.yaml</code> に記載の通りSOCKSによるプロキシとして開放している。あとはローカル側にもcloudflaredをインストールし、 <code>cloudflared access tcp --hostname example.com --url 127.0.0.1:1234</code> で、ローカルの1234 portがKubernetes APIと繋がった形になる。</p>
<p>この方法はCloudflare Docsに <a href="https://developers.cloudflare.com/cloudflare-one/tutorials/kubectl/">Connect through Cloudflare Access using kubectl · Cloudflare Zero Trust docs</a> として掲載されている内容を、ほぼそのまま使わせてもらっている。なお、プロキシ経由で <code>kubectl</code> を実行するにあたり、Docsでは <code>env HTTPS_PROXY=socks5://127.0.0.1:1234 kubectl ...</code> を使っているが、kubeconfigに書いてしまったほうが楽なのでそうしている。</p>
<pre><code class="language-yaml">apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: XXX...
    server: https://example.com
    proxy-url: socks5://127.0.0.1:1234
</code></pre>
<h2>user dataにどこまで含めるべきか？</h2>
<p>ここまでの内容をuser dataに書いてEC2を起動すれば、そのまますぐにローカルから <code>kubectl</code> で繋ぎに行けるような環境は出来上がる。これだけでも良いのだが、自分はCDにArgo CDを使っていて、そのデプロイまでuser dataで済ませるべきか少々悩んだ。</p>
<p>user dataは非常に便利だが、一回性のただのコマンド群なので <code>as Code</code> 的ではない。K8s上に展開するArgo CDに関しては、きちんとマニフェスト管理するべきという考え方もあり、ここは意見が分かれるところとも思う。</p>
<p>まぁしかし、個人の環境だとArgo CDのマニフェストを書き換えて、という機会もそれほどないし、作ったときにはもうArgo CDも動いていて、あとはGitOpsで全部制御できる、となっているほうが嬉しい。ということで割り切ることにした。個人開発では割り切りが大事。</p>
<h2>Cloudflare Zero Trust + Argo CD</h2>
<p>Argo CDのGUIもCloudflare Zero Trustで開放している。</p>
<h3>HelmChart CRD</h3>
<p>Argo CDの導入には、簡単なところでHelmを使いたい。K3sはHelmも内包しているのだが、しかしHelmのコマンドラインは付属していない。ならばChartをどうインストールするのか、というところだが、HelmChartというCRDを使うことになっている。</p>
<p>https://rancher.com/docs/k3s/latest/en/helm/</p>
<p>HelmChartは、HelmでインストールするChartの情報を定義できるCRDであり、これをapplyすることで <code>helm install</code> がJobとして自動的に走る。 <code>helm install</code> を手続き的に実行するのではなく、宣言的にどう管理するかは結構頭を悩ませるポイントだと思うが、こんなスマートな回答があったとは知らなかった。このCRDは <a href="https://github.com/k3s-io/helm-controller">k3s-io/helm-controller</a> を導入することで、K3s以外のK8s環境でも使えるらしい。</p>
<p>ということで、Helmを通じたArgo CDのインストールはこのようなコマンドになった。なお、マニフェストにコメントで書いているが、Argo CD serverのHTTPSは無効化しておく必要がある。HTTP接続があるとArgo CD serverはHTTPSへ307 redirectするのだが、これをCloudflare Tunnel経由だと上手く処理できないためだ（Tunnelのエンドポイントとローカル間はHTTPSにできるので問題はない）。</p>
<pre><code class="language-bash">cat > /tmp/argo-cd-helm-chart.yaml &#x3C;&#x3C;EOF
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: argo-cd
  namespace: kube-system
spec:
  repo: https://argoproj.github.io/argo-helm
  chart: argo-cd
  targetNamespace: argo-cd
  valuesContent: |-
    server:
      extraArgs:
        - --insecure # HTTPSを無効化しないとArgo Tunnelから繋がらない
EOF

kubectl create ns argo-cd
kubectl apply -f /tmp/argo-cd-helm-chart.yaml
</code></pre>
<h3>Cloudflare Tunnel on K8s</h3>
<p>Argo CDのServiceをTunnelで開放するため、今度はTunnelをK8s上に展開するが、これもCloudflareが記事 <a href="https://blog.cloudflare.com/kubectl-with-zero-trust/">Kubectl with Cloudflare Zero Trust</a> を公開しているので、詳細は割愛する。必要なのは接続情報を書いたYAMLと認証情報を書いたJSONであるという点は変わらない。</p>
<h3>ApplicationSetのApply</h3>
<p>Argo CDで管理したいApplicationはApplicationSetとしてまとめてGitHubに置いているので、最後にこれを読ませてやれば、Argo CDがバシバシ必要なApplicationを展開してくれて、GitOpsがすぐに使えるようになる。</p>
<pre><code class="language-bash">curl https://raw.githubusercontent.com/chroju/infrastructure/main/kubernetes/applicatio
n-set/application-set.yaml -o /tmp/application-set.yaml
while true
do
    # Argo CD ApplicationSet Controllerの起動を待つ
    kubectl get deployment/argo-cd-argocd-applicationset-controller -n argo-cd | grep 1
/1
    if [[ "$?" == '0' ]]; then
        break
    fi
    sleep 10
done

kubectl apply -f /tmp/application-set.yaml
</code></pre>
<p>大方これで上手くいくはず、なのだが、ApplicationSet Controllerだけが起動してもダメなのか、実は今のところ上手くいっていない。一応Applyはされるのだが、ApplicationSetがエラーを吐いてしまっている。Argo CDのGUIに入って、ApplicationSetを一度削除してから再度Syncすれば直るので、個人環境だし深入りはしていない。追々直すかもしれないし直さないかもしれない。</p>
<h3>Argo CDのパスワード</h3>
<p>GUIのデフォルトパスワード、昔はPod nameだったりしたが、最近はsecretに入っているので、これもパラメータストアに投げて、ローカルからすぐ確認できるようにしてやる。</p>
<pre><code class="language-bash">kubectl apply -f /tmp/application-set.yaml
ARGO_CD_PASSWORD=$(kubectl -n argo-cd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d)
aws ssm put-parameter --region ap-northeast-1 --name /chroju/k3s/argo_cd_password --type SecureString --overwrite --value "$ARGO_CD_PASSWORD"
</code></pre>
<h2>Impression</h2>
<p>以上の内容を繋ぎ合わせたuser dataの全体像は<a href="https://gist.github.com/chroju/2270753a008be6715e3da47ff4e47a03">Gistにも上げておいた</a>。何度か言及してきた通り、Terraformの <code>templatefile</code> として用いるものとして書いている。</p>
<p>頑張って何もかもuser dataに入れなくてもよかったかもしれないが、 <code>terraform apply</code> を実行するだけで、すぐにローカルから <code>kubectl</code> でもArgo CDでも繋ぎにいける環境がシュッと立ち上がる、というのは結構体験がいい。個人での技術検証が目的だし、これぐらいの気軽さでいいんじゃないだろうか。K8sのバージョンが上がったらサクッとスクラップアンドビルドしちまえ、ぐらいの気概でいきたい。</p>
<p>また、ここまでに登場したCloudflareの機能は全部無料で使えていて、昨今いろんなところで名前を聞くようになった「Cloudflare」の勢いを感じた。自分が個人開発を始めた頃は、VPSの要塞化に頭を悩ませるような時代だったので、シンプルに「インバウンドは全部塞ぐ」が最適解な時代になったのは喜ばしい。</p>
<p>[^1]: Argo Tunnelという呼び方をウェブ上の記事で見かけることがあるが、おそらく旧名称と思われる。</p>
]]></description>
            <link>https://chroju.dev/blog/k3s_cloudflare_zero_trust</link>
            <guid isPermaLink="false">k3s_cloudflare_zero_trust</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 16 Aug 2022 00:07:18 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Twitterの話題はMailbrewで収集する]]></title>
            <description><![CDATA[<p>ここ数年、Twitterを見る時間はなるべく減らすようにしていて、通知は受け取らないようにしているし、見る場合も「タイムライン」ではなくて必要最低限に絞ったリストを使うようにしたりなど、いろいろ工夫している。</p>
<p>それでもTwitterを完全に見ない、というのもなかなか難しくて、あれの良いところとしては「なんとなく眺めていると今話題になっていることがわかる」という点がある。炎上ネタなどはどうでもよいのだが、少しホットになりつつあるセキュリティ事象とか、最近この技術に言及されている機会が多いな、だとか、そういったことはRSSなど他の手段だと収集が難しい。もちろん、それが本当に必要な情報なのか、という視点はあるとは思うが。</p>
<p>以前はこの用途で <a href="https://twitter.com/nuzzel">Nuzzel</a> を使っていた。これはTLやリストで多く言及されているリンクがあると、Slackなどに通知してくれるサービスで、「話題」をキャッチする上で重宝していたのだが、残念ながらTwitterに買収されて閉鎖されてしまった。</p>
<h2>Mailbrew</h2>
<p>それからNuzzel Alternativeをずっと探していたのだが、2か月ぐらい前に <a href="https://app.mailbrew.com">Mailbrew</a> に行き着き、自分の中で運用が安定してきた。月額 $4.99 の有償ではあるが、その価値はあると思う。</p>
<p><a href="https://gyazo.com/e5cf3d647306e668dc2513c5b07ac8d3"><img src="https://i.gyazo.com/e5cf3d647306e668dc2513c5b07ac8d3.png" alt="Image from Gyazo" width="600"/></a></p>
<p>Mailbrewは言うなれば「いろんな情報ソースを組み合わせて自分だけのメルマガ（ <code>Brews</code> と呼ばれる）を作れる」サービス。昨今、SNSやらDev.toのようなブログメディアなどが様々増え、それぞれに通知の仕組みがあるわけだが、その中から必要なものを抽出して集約して1日1回だけとか受け取るようにして、情報過多な状態を脱しましょう、という狙い。 <a href="https://world.hey.com/dhh/not-just-what-you-read-but-how-64648303">Not just what you read but how</a> の中でDHHが言及していたことでも一時話題になったように思う。</p>
<p>Mailbrew自身が <a href="https://mailbrew.com/blog/top-nuzzel-alternatives">The best Nuzzel alternatives</a> と称しているように、使える情報ソースの中に「Twitter Top Links」というものがあり、話題のリンクをピックアップすることもできる。Twitter連携はかなり充実していて、「あるユーザーの最新ツイートを3つだけ」、あるいは「人気のものを3つだけ」などもできるし、「自分のTLで人気のツイートを5つだけ」といったこともできる。最近はTwitterでマンガ連載するようなアカウントもあるけど、これならMailbrewだけで追えて良かったりとか。 <a href="https://twitter.com/ngnchiikawa">ちいかわ</a> なんかはほぼマンガのツイートだけ投稿されていて、日に1〜2ツイート程度なのでめちゃくちゃ相性がいい。</p>
<p><a href="https://gyazo.com/eae7e2cb929eeb33613812ec1ca1c079"><img src="https://i.gyazo.com/eae7e2cb929eeb33613812ec1ca1c079.png" alt="Image from Gyazo" width="600"/></a></p>
<p>他にもいろいろと。RSSなんかにも対応しているのは当然として、 <a href="https://news.ycombinator.com/">Hacker News</a> などの主要なメディアサイトであれば直接的に取り込む機能もある。</p>
<p><a href="https://gyazo.com/6142b19a12d255c3b36feaa989d3f1fd"><img src="https://i.gyazo.com/6142b19a12d255c3b36feaa989d3f1fd.png" alt="Image from Gyazo" width="600"/></a></p>
<h2>SavedとNewsletter</h2>
<p>特徴的な機能として <code>Saved</code> と <code>Newsletters</code> がある。</p>
<p>前者はPocketのようなRead it Later機能。MailbrewはWebブラウザからログインすると、過去のBrewsもすべて読めるのだが、ここで読むと各記事に <code>Save</code> ボタンが付いており、あとで読む用に保存して、Mailbrewの中で読むことができる。また <a href="https://chrome.google.com/webstore/detail/mailbrew-read-later/fgcpnflfkoclnkgkkimfpbehjopdfdem">chrome extension</a> を使うとブラウザからもURLを保存できて、まさにPocketライクに使える。</p>
<p>Newslettersはメルマガの集約機能。Mailbrewが発行してくれるメールアドレス宛にメールを送ると、その内容がMailbrew上で読めるようになる。僕は何本かメルマガを購読しているのだが、GmailのUIだとあんまり「読み物をする」気分にはならず溜まりがちだったのが、Mailbrewだと読む頻度が上がるようになった。</p>
<p>ちなみにSavedとNewslettersの新着は、Brewsの中に埋め込んで表示させることもできる。</p>
<h2>自分の運用</h2>
<p>先のDHHの記事の中に書かれた運用を参考に、毎日朝夕 + 週末の計3種類のBrewsを作っている。</p>
<ul>
<li>毎朝 : Twitter、Reddit、Dev.to、Hacker Newsなどからの技術的な話題ピックアップ</li>
<li>毎夕 : 趣味的な話題のピックアップ</li>
<li>週末 : 確実に読みたいRelease Noteなどの集約</li>
</ul>
<p>日次で受信するBrewは忙しいと読めないこともあるので、必ずしも読まなくてもいいようなホットな話題などを中心にしている。利用しているサービスやOSSのブログの更新や、GitHub ReleasesのRSSは時間のある週末に確実に目を通したいので、まとめて週末に送っている。</p>
<p>この方式で難があるのは <a href="https://aws.amazon.com/jp/about-aws/whats-new/recent/feed/">AWSのWhats'new</a> など、日に10回も更新するようなことがあるブログなのだが、レアケースではあるのでこういったものだけは今はSlackに流している。上手いこと抽出して受信したいとは思うのだが。</p>
<p><a href="https://gyazo.com/73f1ff72cb25a48354278bb077bf7457"><img src="https://i.gyazo.com/73f1ff72cb25a48354278bb077bf7457.png" alt="Image from Gyazo" width="300"/></a></p>
<p>目指しているのは、「WebでのインプットはすべてMailbrewを見ればよい」という状態。あちこち通知を見に行ったりするんじゃなくて、ちょっと手持ち無沙汰なときにMailbrewを開けば読むものが積んである、という状態にしていきたい。 <code>Saved</code> も積極的に使っていて、仕事中などに「これは読んでおこう」というものが出たら取りあえず保存している。MailbrewはPWAではあるのでスマートフォンに「インストール」はできるものの、スマホから <code>Saved</code> を使うことはできないのが玉に瑕ではあるのだが、今のところ非公式な手段でゴニョゴニョしてスマホからもポチポチと保存している。</p>
<p>難を挙げると、今書いた通りモバイルの対応がいまいちな点、Brewsの編集がGUIで若干もっさりしていて面倒な点、Savedがたまにバグって同じURLを何度でも保存できちゃう点、ぐらい。あとはAPIがあると嬉しいのは確か。</p>
]]></description>
            <link>https://chroju.dev/blog/mailbrew_nuzzel_alternative</link>
            <guid isPermaLink="false">mailbrew_nuzzel_alternative</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 11 Jun 2022 01:24:22 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Tailwind CSSでブログのデザインを刷新した]]></title>
            <description><![CDATA[<p>このブログのCSSは、最初に <a href="https://nextjs.org/learn/basics/create-nextjs-app">Next.jsのチュートリアル</a> で書いたものを継ぎ足しながら使ってきており、どこかのタイミングでちゃんと書き直したいなと思っていたので、この度 <a href="https://tailwindcss.com/">Tailwind CSS</a> に差し替えて全部書き直した。</p>
<h2>Tailwind CSS</h2>
<p>CSSに関しては基本的な文法は知っているという程度だし、デザインの知識も修めていない門外漢なので、Bootstrapのような楽にそこそこいい感じにできるフレームワークを探したところ、Tailwindが見つかったというところ。そのためTailwindが良いのか悪いのかという判断もできる立場にはないが、とりあえず形にはなったし、使いやすかったんだろうなと思っている。</p>
<p>Tailwindの一番の特徴は <a href="https://tailwindcss.com/docs/utility-first">Utility-First</a> という考え方にあるそうだ。例えば <code>blog-subtitle</code> のようなclassをつくり、これに対してmarginやらfont-sizeやらという各種の要素をくっつけて、同じclass名であればサイト内どこでも同じデザインになるようにする、というのが定番のパターンだし、僕の認識していたCSSの使い方。一方でUtility-Firstは文字を大きくする <code>text-xl</code> や、パディングを6pxにする <code>p-6</code> といったclassが最初から定義してあって、これを組み合わせて各HTMLタグにclassとして振ることにより、欲しいデザインを作って行く方式。</p>
<p>CSSはすでに定義済みで、そこから必要なclass名を引っ張ってきてHTMLに書き入れるだけなので、HTMLだけを見ていれば良いという点では、デザインに慣れていない人間にはとても楽だった。ドロップシャドウも <code>shadow-hoge</code> のように書くだけで簡単にかけられるし、CSSテクニックを知らなくてもそこそこいい感じに出来る。</p>
<p>ただ、個々の要素をどう組み合わせるかは結局センス頼みになるので、これだけ使っていれば必ず良い感じになるってわけでもないな、とも思う。また、Utility-Firstだと結局inlineでCSSを書くのと似た感覚になり、この規模のサイトなら良いけど、大規模になってくるとメンテナンス大変なんじゃないかなーという感想を抱いた。 <a href="https://coliss.com/articles/build-websites/operation/css/a-look-at-tailwind-css.html">Tailwind CSSのメリットとデメリット | コリス</a> とか <a href="https://coliss.com/articles/build-websites/operation/css/why-tailwind-css-is-not-for-me.html">Tailwind CSSが私には合わなかった理由 | コリス</a> を読んでなるほどなーと思ったりしていた。</p>
<p>いい感じのデザインにするために <a href="https://tailblocks.cc/">Tailblocks — Ready-to-use Tailwind CSS blocks</a> も活用した。サンプルコードが豊富にあり、いくつか参考にさせてもらった。</p>
<h2>before / after</h2>
<p><a href="https://gyazo.com/93f5bab1325a0c02b01f55ed7a18db4d"><img src="https://i.gyazo.com/93f5bab1325a0c02b01f55ed7a18db4d.jpg" alt="Image from Gyazo" width="500"/></a></p>
<p><a href="https://gyazo.com/fc5f8137a4c6c46beaed948bbf3d5315"><img src="https://i.gyazo.com/fc5f8137a4c6c46beaed948bbf3d5315.png" alt="Image from Gyazo" width="500"/></a></p>
<p>改めてbefore / afterを並べると、結構間の抜けたデザインだったのがシュッとした感じになったなぁ、と思う。文字サイズが小さくなったのでリーダビリティが下がったかもしれないので、妥協点を探しながらまた徐々に改善したい。</p>
<p>Tailwindを使ってレスポンシブも簡単にできたのでこれも良かった。</p>
<p><a href="https://gyazo.com/135c6fca92c3472713f22c3a3af3f27d"><img src="https://i.gyazo.com/135c6fca92c3472713f22c3a3af3f27d.gif" alt="Image from Gyazo" width="500"/></a></p>
<p>不具合などまだまだある気がするので、何か見つけたらプルリクやissueを投げていただければ対応します。</p>
]]></description>
            <link>https://chroju.dev/blog/tailwind_css</link>
            <guid isPermaLink="false">tailwind_css</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 17 May 2022 10:21:28 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Astro Slideが届いた]]></title>
            <description><![CDATA[<p><a href="https://gyazo.com/24372536461566dce3a1a0f12554e5dc"><img src="https://i.gyazo.com/24372536461566dce3a1a0f12554e5dc.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>2年ちょっと前にクラウドファンディングでバックした <a href="https://www.indiegogo.com/projects/astro-slide-5g-transformer/x/18968120#/">Astro Slide</a> というスマートフォンがようやく届いた。本体下部に物理QWERTYを搭載していて、独特のスライド機構でクラムシェルを開いたような状態に変形させて使えるという、新しいんだけど懐かしさを感じるようなスマホ。以前から <a href="https://www.www3.planetcom.co.uk/cosmo-communicator">Cosmo Communicator</a> など、この手の端末を幾度か出してきた <a href="https://www.www3.planetcom.co.uk/">Planet Computers</a> の新作になる。この文章もAstro Slideで書いてみている。</p>
<p>当初の発送予定は2021年1月だったが、半導体不足やCOVID-19による生産拠点のロックダウンなどの影響を受け、スケジュールは遅れに遅れて現在進行形で結構燃えている。僕はEarly Bird枠だったし、先に生産が開始されたJPキーボード指定だったのでこれでも受け取れたのは早いほうらしい。</p>
<h2>Impression</h2>
<p><a href="https://gyazo.com/af293fca77d2360637fa0a6b9e1990f6"><img src="https://i.gyazo.com/af293fca77d2360637fa0a6b9e1990f6.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>悪くない。実は物理QWERTYを搭載したスマホ自体初めてなので、10年ぐらい前まで跋扈していた先達たちと比べてどうなのかとかはわからないけど、とりあえず実用できなくはないかなという感想。</p>
<h3>キーボード</h3>
<p>メカニカル構造なだけあって押し心地は悪くない。押し込めばスッと入っていくリニアタイプではなく、ポコっと打ち込んだ感覚があるタクタイルに近い打鍵感。このサイズなら誤タイプを防ぐ意味でこれが正解だとは思うが、たまにちょっと堅すぎるのか打ち漏らすときもある。</p>
<p>配列はめちゃくちゃ独特。これはPlanetの既存端末からそうらしいが、特にハイフンがスペースキーの右かつシフトが必要なポジションにあるのが一番つらい。配列のリマップもできるそうなので改善は可能かもしれないが、まだ試していない。</p>
<p>記号以外に関してはブラインドタッチがそこそこできるレベル。試しに寿司打してみた結果を貼っておく。ハイフンがなぜか検知してもらえず、その分スコアは下がっている。</p>
<p><a href="https://gyazo.com/799644de448ca507f59ef9c2f9c47e5d"><img src="https://i.gyazo.com/799644de448ca507f59ef9c2f9c47e5d.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>ちなみに普段遣いのキーボードでの結果はこう。ミスタイプがひどい。</p>
<p><a href="https://gyazo.com/d82051d3642c960f1baa2a9f8e89cb31"><img src="https://i.gyazo.com/d82051d3642c960f1baa2a9f8e89cb31.png" alt="Image from Gyazo" width="554.445"/></a></p>
<h3>バッテリー</h3>
<p>むちゃくちゃ良いわけではないと思うが悪くもない。 <a href="https://play.google.com/store/apps/details?id=jp.smapho.battery_mix&#x26;gl=us">Battery Mix</a> でしばらく計測した結果を貼る。</p>
<p><a href="https://gyazo.com/de7c13a25f358ded4332b75d2c094b15"><img src="https://i.gyazo.com/de7c13a25f358ded4332b75d2c094b15.jpg" alt="Image from Gyazo" width="600"/></a></p>
<h3>オリジナルアプリ</h3>
<p>いくつかPlanet製のオリジナルアプリが入っている。ほとんど使っていないけど、App Barはいい感じ。物理キーボードのPlanetマークを押すと、いつでもDockっぽいランチャーを呼び出せる。</p>
<p><a href="https://gyazo.com/98e845622e50634fa710479fa47a2998"><img src="https://i.gyazo.com/98e845622e50634fa710479fa47a2998.jpg" alt="Image from Gyazo" width="600"/></a></p>
<h3>スマホとして使えるか</h3>
<p>閉じた状態でスマホとしても使える！というのが売りなわけだが使えないことはない。でも当然ながら分厚い。しばらく触ってからPixel 5aに持ち帰ると薄すぎて感動するぐらい。まぁこれは仕方ない。なので僕はこの端末だけでメインのスマホにすることはないが、やろうと思えばできなくはないんではないか。使い方にもよるとは思うが。</p>
<p><a href="https://gyazo.com/4887fba25e29f17c74a5c1fba33e25f2"><img src="https://i.gyazo.com/4887fba25e29f17c74a5c1fba33e25f2.jpg" alt="Image from Gyazo" width="600"/></a></p>
<h3>クラムシェルとして使えるか</h3>
<p>まあ、使える。タイピングができるのであとはソフトウェア次第で。</p>
<p>多くの場合はSimplenoteを使っている。メインで使っているノートアプリはWorkflowyなのだが、どうもこれが相性悪いようで、今文字を打っている行がうまいこと画面上に表示されてくれず、使えていない。Astroの問題なのかWorkflowyの問題なのか判断もつかずあきらめている。</p>
<p>ソファで膝の上に広げても打てないことはないが、机上に広げるのがやはり安定して打ちやすい。ドトールのテーブルでトレイを端に寄せ、狭いスペースに広げて打ってみたが、あの小さなテーブルならだいぶ体験がよい。</p>
<h3>よくないところ</h3>
<ul>
<li>指紋認証センサー。ほぼ成功したことがないぐらいにひどい。開いて使っているときはキーボードでPINを打ってしまうから気にならなくなるが。</li>
<li>画面の輝度？　ちょっとまぶしくチラチラするように感じる。輝度をかなり落として使っている。</li>
<li>出荷段階で液晶保護フィルムが貼られているが、気泡もだいぶ入っているし自分で買った方がいいと思う。幸いAmazonでわりと普通に買える。</li>
<li>キーボードを収納した状態ではロックされるわけではないので、下のキーボードを指で押すと微妙にぐらつくのがちょっと怖い。大丈夫だとは思うものの。</li>
<li>充電は遅い。まだ0→100％充電したことはないが、これまでの実績ペースだと0→100に3時間ぐらいかかりそう。</li>
<li>Android 12未対応。</li>
</ul>
<h2>設定</h2>
<p>使い始めるにあたり設定した箇所をいくつか書いておく。</p>
<h3>eSIM</h3>
<p>メインスマホにするつもりがなかったのでSIMを挿す気もなかったんだけど、メイン回線で使っているIIJmioなら月440円でeSIMを発行できると知り、それを挿している。こんなに安価に、しかも申し込みから15分ぐらいで回線開通できるのでいい時代だなぁと噛みしめた。メインのSIMとデータ容量はシェアしているので、余るならメイン側の容量を下げればコストもさらに減る。</p>
<p>使い始めるにはまず設定のAstro Settingで、Use eSIM for SIM slot 2にチェックを入れる。</p>
<p><a href="https://gyazo.com/8f4d84965d586c36768b1f6723c06d92"><img src="https://i.gyazo.com/8f4d84965d586c36768b1f6723c06d92.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>その後、プリインストールのeSIM walletというアプリでアクティベートする。このアプリ、SIMが1枚も挿さっていない状態だと無限にエラーをポップアップするのだが、無視してがんばって右下のアイコンを押せばアクティベートのフローに進める。ただ、1回目の試行ではFailureになってしまい、一度再起動してから2回目に試してようやくうまくいった。アクティベートできたら左下の電源アイコンを押して有効化する。その後設定から、APNの設定を入れたら通信できるようになった。</p>
<p><a href="https://gyazo.com/e33a71afad8638315c509dc0b124657d"><img src="https://i.gyazo.com/e33a71afad8638315c509dc0b124657d.jpg" alt="Image from Gyazo" width="600"/></a></p>
<h3>ATOK</h3>
<p>設定の「システム」→「言語と入力」に「物理キーボード」の設定箇所があり、JPキーボードだとデフォルトで「日本語」というキーボードと「日本語 (English)」というキーボードが設定されている。この2つをCtrl + Spaceで切り替えられるのだが、前者はかな入力、後者は英数入力なので、ローマ字入力するにはIMEが別途必要となる。</p>
<p>Gboardをインストールするのが早いが、自分はライセンスがあるのでATOKにした。Gboardは変換候補が入力箇所のすぐ近くに表示されるのだが、これが入力中の文字を隠してしまうことがあり、実用に耐えなかった。ATOKは画面下部に候補表示してくれるのでこの点は良いのだが、変換精度がデスクトップ版と比べて著しく悪いという欠点もある。</p>
<p><a href="https://gyazo.com/236822a1f168669f73dacda16baa70a5"><img src="https://i.gyazo.com/236822a1f168669f73dacda16baa70a5.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>設定としては「システム」→「言語と入力」の「画面キーボード」にATOKを追加して、「物理キーボード」から日本語を外して「日本語 (Engilish)」だけにする。これでAlt + SpaceでATOKの日本語と英数が切り替えられるようになる。</p>
<h3>小さなQWERTYを持つこと</h3>
<p>自分のポリシーというか方針として、小さなQWERTYを持っていたい、というのがある。外出先や旅先で考え事をしたり、ブログのように長文を認めたりするときにノートパソコンを持って行くのでは重いのだけど、スマホのフリックでは入力が遅いので、机上で打てる小さなQWERTYが欲しい。これまでにpomeraやGPD Pocketなどを買ってきていて、Astro Slideはその流れで買っている。</p>
<p>なのでCPUが当初予定から格下げされたことなどはあんまり気にかけていなくて、ひとえに文字を打つ端末として実用に耐えるかで評価しており、その点では及第点かな、と思う。不満点として配列の特殊性といったハードの問題もあるが、Androidの日本語入力環境の問題も結構大きい。当たり前かもしれないがデスクトップ用のIMEのようなカスタマイズができるわけではなく、例えばATOKだと文節調整に矢印キーを使うのだけど、デスクトップだと普段はこれをShift+矢印キーに割り当てているので結構戸惑っている。Android版ATOKではこのあたりのキーリマップはできないので慣れるしかない。なので十全な文字入力環境とは言い難いのだが、じゃあその不満の解消のためだけにmacbook持ち歩くかと言われるとそれも嫌なので、ちょっとカフェで考え事したい、みたいなときには今後しばらくはAstro Slideを使うと思う。</p>
<p>言うまでもなく極めて特殊な端末なので、もろ手を上げて最高！とはちょっと言えないし、そもそも生産出荷状況がいまいちなので、量産される見通しも現段階では立っていない。もし一般に買える段階が来たら、ガジェット好きな人なら買ってもいいんじゃないですかね、ぐらいの感覚。</p>
]]></description>
            <link>https://chroju.dev/blog/astro_slide_first_imporession</link>
            <guid isPermaLink="false">astro_slide_first_imporession</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 06 May 2022 03:17:48 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Apdexという指標 - State of SRE Report 2022 を読んだ]]></title>
            <description><![CDATA[<p>https://www.dynatrace.com/info/sre-report/</p>
<p>APMなどを提供する <a href="https://www.dynatrace.com/ja/">Dynatrace</a> が公開している、State of SRE Report 2022を読んだ。Dynatraceがグローバルに450社に対して調査を行った結果をまとめている。なおグローバルとはいえ調査対象の33%がアメリカでほとんどが欧米、日本は対象に入っておらず、偏りはあると考えたほうが良さそうではあった。企業規模でもグローバル企業が中心のためか、3000人未満の会社は1割程度で、3割の会社が20000人を超えており、大企業がほとんどとなっている。</p>
<p>このレポートではSRE発足から2年以上を経過している企業をMaturing、5年以上をAdvancedと定義しているが、前者が42%、後者が20%となっていた。『サイトリライアビリティエンジニアリング』日本語版が発刊されたのが2017年なので、5年以上SREをやっている企業は、本邦だと2割にも及ばないのではないかという感覚がある。そう考えるとSREはやはり、まだまだ探求が続けられている職種であり、こういった実情を調査するレポートがあるのはありがたい。</p>
<h2>Apdex</h2>
<p>このレポートで初めて知った概念の1つに <a href="https://www.apdex.org/">Apdex</a> があった。ユーザー満足度を示す指標であり、調べたところ2004〜5年頃よりあるものらしい。</p>
<p>ざっくり概要を示すと、こんな指標である。</p>
<ul>
<li>レスポンスタイムの閾値 <code>T</code> を定義し、レスポンスタイムが <code>t</code> のときのユーザーの満足度を以下のように考える
<ul>
<li><code>T >= t</code> : 満足</li>
<li><code>4T >= t > T</code> : 許容</li>
<li><code>t >= 4T</code> 、あるいはエラーの場合 : 不満足</li>
</ul>
</li>
<li>Apdexスコアは全リクエストに対する割合で0〜1の数値で示される</li>
<li>「満足」だったリクエストは1、「許容」だったリクエストは0.5としてカウントする</li>
</ul>
<p>レスポンスタイムの閾値を設けるのはよくある話だが、満足度にグラデーションを設けている点と、エラーレスポンスを加味している点がポイントになる。確かに、単にレスポンスタイムだけを元にして考えると、素早く503を返したレスポンスもOKな扱いになってしまう。</p>
<p>このレポートではSLIの例をいくつかピックアップしており、その1つとしてApdexが挙げられていた。2段階の閾値を設けることになるので検討は難しくなるが、よりユーザー中心でレスポンスの満足/不満足を考える上では参考になりそうに思う。調べたところ、New RelicもDatadogもApdexの算出には対応しているらしい。</p>
<p>また、レポートで挙げられているSLIの例は、Business SLOsとPerformance SLOsに分類されていた。どのようなSLOを設けるにせよ、最終的にはビジネス的な価値に結びついていなくてはならないと考えているので、この分類はするっと飲み込めない部分もあった。が、SLOを考える際に、その指標は直接的にビジネス的な、ユーザーと密接にかかわる指標なのか、単なるパフォーマンス指標なのかという観点はあってよさそうに感じた。</p>
<h2>その他</h2>
<p>その他、気になったところをいくつかピックアップしておく。</p>
<ul>
<li>SREはcultural changeである。</li>
<li>セキュリティは信頼性の主軸であり、DevSecOpsへより注力したいと考えているSREが過半。</li>
<li>信頼性に関するKPIを達成した際に、specific bonuses/rewardsが出る企業が76%。
<ul>
<li>SLOではなく <code>KPIs around reliability</code> と書いているので、単純に信頼性を守れたかというより、チャレンジングな指標を達成できたかではないかと思う。</li>
<li>いずれにせよ、「信頼性を守っても当たり前品質として扱われてしまう」という不満の解決策としてはアリかなと思う。</li>
</ul>
</li>
<li>SLOを設定するにあたり、99%のSREが何らかの困難に直面している。
<ul>
<li>サイロ化したチーム構成によるツールの細分化、複雑化するアプリケーションに適切なSLOを設定することなど。</li>
</ul>
</li>
<li>SREを採用すること、育成すること、いずれも困難と感じているSREが多く、またそのことを組織的な共通認識にすることも難しく感じている。</li>
<li>将来的にAIOpsがSREプラクティスにとって大きな鍵になるのではないか。
<ul>
<li>信頼性劣化に対するプロアクティブなアプローチへの活用、など。</li>
</ul>
</li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/state_of_sre_report_2022_and_apdex</link>
            <guid isPermaLink="false">state_of_sre_report_2022_and_apdex</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 02 May 2022 01:44:58 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[TerraformでAWS Lambda Function URLsをデプロイする]]></title>
            <description><![CDATA[<p>https://aws.amazon.com/jp/about-aws/whats-new/2022/04/aws-lambda-function-urls-built-in-https-endpoints/</p>
<p>AWS LambdaでHTTPSエンドポイントがデフォルト利用できるようになり、API Gatewayを付与する必要がなくなった。早いもので、すでにServerless FrameworkもTerraformも対応しているのだが、せっかくなのでLambdaのデプロイには使ったことがない、Terraformで試してみた。</p>
<h2>Terraform with AWS Lambda</h2>
<p>AWS LambdaでTerraformを管理するというのはあまり一般的なケースではなく、僕もServerless Frameworkなどを使うことが多い。</p>
<p>改めて、なぜTerraformでAWS Lambdaを管理しないのか、言語化してみるとポイントはいくつかある。</p>
<h3>Terraformはattribute差分による状態管理を行う</h3>
<p>Terraformの基本的な考え方は、クラウドリソースのattributeについて、HCLで記述された状態と実際の状態とを比較し、差分があればそれを適用の対象とする、というものである。AWS Lambdaの場合はソースコードをデプロイするわけだが、その差分はソースコードをzip化したもののハッシュ値を用いて比較することが多い。</p>
<p>しかし、Lambdaでアップロードするzipには、依存ライブラリなどすべてのファイルを含めることになるので、ライブラリインストールにおいて予期せぬ差分が発生する場合がままある。その上Terraformの <code>plan</code> 結果で表示されるのはハッシュ値の差分だから、何が実際の差分なのかは判別ができない。</p>
<h3>TerraformはあくまでAWS APIのラッパー</h3>
<p>Terraformは基本的にAWS APIをラップするものでしかない。従ってAWS LambdaのFunctionを作成、変更、削除はできるが、コードの依存ライブラリをインストールして、zipに圧縮して、といった作業をうまいことお膳立ててくれるわけではない。Terraformのbuilt-inな機能を使えば実現は可能だが、Serverless Frameworkなど専用のフレームワークを使ったほうが上手いこと付随処理を隠蔽してくれる。</p>
<h2>Example</h2>
<p>そういったデメリットを理解しつつ、試しに書いてみたTerraformが以下の通り。</p>
<pre><code class="language-hcl">resource "null_resource" "lambda_function_pre_build" {
  triggers = {
    packages = filebase64sha256("${path.root}/function/package.json")
  }

  provisioner "local-exec" {
    working_dir = "${path.root}/function"
    command     = "npm i"
  }
}

data "archive_file" "lambda_function" {
  type        = "zip"
  source_dir  = "${path.module}/function"
  output_path = "${path.module}/lambda.zip"

  depends_on = [
    null_resource.lambda_function_pre_build,
  ]
}

resource "aws_iam_role" "iam_for_lambda" {
  name = "iam_for_lambda"
  managed_policy_arns = [
    "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
  ]


  assume_role_policy = &#x3C;&#x3C;EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

resource "aws_lambda_function" "tweet_url" {
  filename         = data.archive_file.lambda_function.output_path
  function_name    = "tweet_url"
  role             = aws_iam_role.iam_for_lambda.arn
  handler          = "index.handler"
  source_code_hash = data.archive_file.lambda_function.output_base64sha256
  publish          = true
  timeout          = 10

  runtime = "nodejs14.x"

  environment {
    variables = {
      AUTH_TOKEN = "XXXXXX"
    }
  }
}

resource "aws_lambda_function_url" "tweet_url" {
  function_name      = aws_lambda_function.tweet_url.function_name
  authorization_type = "NONE"
}

output "function_url" {
  value = aws_lambda_function_url.tweet_url.function_url
}
</code></pre>
<p>今回はNode.js14.xで書いたので、 <code>null_resource</code> を使って事前に <code>npm install</code> を行い、 <code>data.archive_file</code> によってzip化を行っている。自分で試しに書いてみると、楽ではないがやれなくはないな、というところだった。取りあえずやってみるの大事。</p>
<p>肝心のURLだが、 <code>aws_lambda_function_url</code> をfunctionに紐付けるだけで設定できる。 <code>authorization_type</code> は <code>NONE</code> か <code>AWS_IAM</code> の2択であり、今回は <code>X-AUTH-TOKEN</code> headerを読み込んで、コードの中で簡易的な認証をかける形とした。このほか、CORSの設定ができる。</p>
<p>なお、今回のソースコードは慣れないNode.jsで書いたためめちゃくちゃ汚い気がするので割愛する。以前から個人的に欲しかった、「URLを投げつけると、タイトルを自動取得して『Browsing : タイトル URL』形式でTwitterに投稿してくれる君」を作ってみている。</p>
<h2>Lambda Function URLsでできること</h2>
<p>https://docs.aws.amazon.com/lambda/latest/dg/urls-invocation.html</p>
<p>リクエストからのヘッダー、body、query stringなどの読み取りは一通りできるし、レスポンスにもヘッダー、bodyなどは含められるので、簡単なAPIを作りたい場合などはこれで事足りそうに感じた。</p>
<p>ただ、ドキュメントを読んだ限りではCloudFrontが介在するわけではなさそうだし、エンドポイントのパスを自由に設定できたりもしないので、API Gatewayの完全互換なものではないことには注意したほうがいいかもしれない。</p>
]]></description>
            <link>https://chroju.dev/blog/lambda_function_urls_with_terraform</link>
            <guid isPermaLink="false">lambda_function_urls_with_terraform</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 16 Apr 2022 05:03:05 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Embedded SREとは何か - SREの組織類型についての覚書]]></title>
            <description><![CDATA[<p>先日の <a href="https://line.connpass.com/event/236497/">6社合同 SRE勉強会</a> 最後のディスカッションの中で、 <strong>Embedded SRE</strong> のようなSREの組織類型をどこで知ったのか、という話題が出ていた。これは僕も以前から感じていたことだ。SREの組織類型、特に「Embedded SRE」という単語は最近国内のテックブログでも見かけることが多いが、GoogleのSRE本各種などに直接言及があるわけではない。その場では海外のブログなどで、という程度の話にまとまり、厳密な結論には至らなかったし、僕も原典が何かと言われるとよくはわかっていない。</p>
<h2>Embedded SREとは何か</h2>
<p>SREがプロダクトチーム内の職能横断の1つとして配置される体制をEmbedded SREと呼ぶ。これはプロダクトチーム、開発チームの外で中央集権的に組織され、各プロダクトを横断的に見るようなSREの組織体制と対置されている。プロダクトサイドとしては、チーム外にいるSREとのコミュニケーションパスを無くすことができるし、SREの側もそのプロダクト固有のドメイン知識の中で最適化された作業ができる、というメリットがある。</p>
<p>国内では <a href="https://engineering.mercari.com/blog/entry/20210129-embedded-sre/">開発チームとともに歩むSREチームが成し遂げたいこと | メルカリエンジニアリング</a> でメルカリが、 <a href="https://developers.cyberagent.co.jp/blog/archives/31404/">Topotal CTOの@rrreeeyyyさんにSREについて聞いてみました! | CyberAgent Developers Blog</a> でCyberAgentが言及していたりと、各社取り組んでいる事例が見られる。メルカリのように、元々インフラチームであったものをSREへ改組した場合、そのままの組織体制だとSREは中央集権的になってしまう。プロダクトが増えたり、SREの業務の幅が広がる中で限界を感じ、Embedded SREに転じていく事例が多いと見ている。</p>
<h2>SRE booksにおける「Embed」という表現</h2>
<p>Googleが発刊しているいわゆるSRE booksと呼ばれる『サイトリライアビリティエンジニアリング』『サイトリライアビリティワークブック』、あるいは『SREの探求』においては、SREの組織体制をどうするべきか、という話題には乏しく、「Embedded SRE」という単語も直接は登場しない。</p>
<p>ただ、SREを「Embed」するという表現は『Site Reliability Engineering』の「<a href="https://sre.google/sre-book/operational-overload/">Chapter 30 - Embedding an SRE to Recover from Operational Overload</a>」において見られる。ここでは、SREチームの運用作業が過負荷になった際、その原因となっているチームへ一時的にSREを移籍させ、チームのプラクティス改善を行うというGoogleのケースが紹介されている。SRE booksの中では、SREチームがプロダクトチームからプロダクトを受け入れ、トイルやアラートが多すぎればプロダクトを差し戻す場合があると書かれている通り、GoogleにおけるSREチームはプロダクトとは別チームとしてとどまっているようである。</p>
<p>『SREの探求』では第10章において、少しだけ組織論への言及が見られる。ここで言及されているのは1つが先のGoogleの事例で、これは「Googleモデル」と呼称されている。もう一方は「Netflixモデル」とされている。</p>
<blockquote>
<p>SRE（および他の機能別の役割）をプロダクト専用チームに参加させるものです。この方法では、サービスを開始から廃止まで所有できる機能横断型チームが作られます。開発と継続的な運用はすべて、この機能横断型チーム内で実行されます。大企業の観点からすると、これは概して、従来の組織モデルからの完全な離脱とみなされます。聞いたことがある人もいるでしょうが、このパターンはNetflixモデルと呼ばれる場合があります。</p>
</blockquote>
<p>これは要するに「Embedded SRE」に相当するようと考えていいだろう。</p>
<h2>Embedded SREという呼称を辿る</h2>
<p>メルカリが先のエントリーの中で「Embedded SRE」の出典として引いているのがSlalom Buildによる <a href="https://medium.com/slalom-build/the-many-shapes-of-site-reliability-engineering-468359866517">The Many Shapes of Site Reliability Engineering | by Rob Cummings | Slalom Build | Medium</a> というエントリーである。これが2019年1月に書かれている。</p>
<p>この中で書かれているEmbedded SREは、やはりプロダクトチームの中に組み込まれ、信頼性やスケーラビリティの点で専門を担うとされている。なお、EmbedというとSREを外からプロダクトチームへ埋め込む（参加させる）ような印象を受けるが、ここではプロダクトチームが専任のSREを自ら雇ってもよいとしている。</p>
<p>では、このエントリーが「Embedded SRE」の原典なのかと言えば、実のところこれ以前にもまだ辿っていくことができる。どうもロールとしてのEmbedded SREという呼び方は2018年以前からLinkedInが使っていたようで、 <a href="https://www.usenix.org/conference/lisa18/presentation/andersen">How Bad Is Your Toil?: Measuring the Human Impact of Process | USENIX</a> や <a href="https://www.informationweek.com/devops/3-myths-about-the-site-reliability-engineer-debunked">3 Myths About the Site Reliability Engineer, Debunked</a> の中で確認できる。ただし、いずれも「私はEmbedded SREとして働いています」という程度の使い方であり、Slalom Buildのエントリーのように、組織類型をまとめたような内容のものではない。</p>
<p>明確な組織論として書いているものの1つには、New Relicの <a href="https://www.slideshare.net/newrelic/sreiously-defining-the-principles-habits-and-practices-of-site-reliability-engineering-112178269">SRE-iously: Defining the Principles, Habits, and Practices of Site Reliability Engineering</a> がある。これは2018年8月のスライドであり、Embedded SREはDomain Expertsだとされている。この絵も国内でよく引用されているのを見かける。</p>
<p><a href="https://gyazo.com/c7a3e0bf4c97e9cf1b83711c3ca3727e"><img src="https://i.gyazo.com/c7a3e0bf4c97e9cf1b83711c3ca3727e.png" alt="Image from Gyazo" width="700"/></a></p>
<p>そしてさらに遡ると、LyftのエンジニアであるMatt Kleinという方が2018年6月に書いた <a href="https://medium.com/@mattklein123/the-human-scalability-of-devops-e36c37d3db6a">The human scalability of “DevOps” | by Matt Klein | Medium</a> がある。SREをプロダクトチームの中へ組み込む必要性を説いた上で、それをEmbedded SREと呼んでいる。明確なロールとしてEmbedded SREの在り方を説明したものとしては、僕が辿れた範囲ではこれが一番古いようだった。</p>
<blockquote>
<p>The goal of embedded SREs is to increase the reliability of their products by implementing reliability oriented features and automation, mentoring and educating the rest of the team on operational best practices, and acting as a liaison between product teams and infrastructure teams (feedback on documentation, pain points, needed features, etc.).</p>
</blockquote>
<p>このエントリーは今回初めて目にしたが、DevOpsとは何か、なぜ必要なのか、それを組織をスケールさせながら実践する上で、SREをどのように実装するべきなのかと順序立てて説明しており、非常に読み応えがあった。</p>
<h2>Embedded SREの対置概念</h2>
<p>多くの記事では、SREはプロダクトチームに組み込まれるか、プロダクトチームの外で集約的に組織されるかという2つの組織類型を対置的に書いている。集約型SREについてはEmbeddedほど統一された呼称がないようで、様々に呼ばれている。先のSlalom Buildのエントリーでは、中央集権的に組織され、会社全体の信頼性コンサルティングを行うようなSREは <strong>SRE Center of Practice</strong> と呼ばれているし、New Relicのスライドでは <strong>Pure SRE</strong> と呼ばれている。</p>
<p>SREの元祖たるGoogleが組織類型に言及したのは <a href="https://cloud.google.com/blog/products/devops-sre/how-sre-teams-are-organized-and-how-to-get-started">SRE at Google: How to structure your SRE team | Google Cloud Blog</a> ぐらいだと思うが、この中ではさらに細分化した6種類の分類が書かれている。なお、これが書かれたのは先のエントリー群よりも後、2019年6月になる。僕がEmbedded SREを初めて目にしたのもここだったように思う。</p>
<h3>Kitchen Sink a.k.a Everything SRE</h3>
<p>プロダクト横断的な中央集権のSREチーム。まだ担当プロダクトが少ない、SREの実装の初期段階にあたる。</p>
<h3>Infrastructure</h3>
<p>Kubernetes Clusterや監視システムのような共通で使用されるインフラ整備に携わるSRE。</p>
<h3>Tools</h3>
<p>開発者が信頼性を維持するのに役立つようなツール、ソフトウェアなどを構築、提供するSRE。</p>
<h3>Product/applicaton</h3>
<p>重要なプロダクトの信頼性向上に取り組むSRE。Embeddedのようにプロダクト専任に近い形と思われるが、まだプロダクトの内部には入り込んでいない点が相違点と思われる。</p>
<h3>Consulting</h3>
<p>プロダクトのコードを直接変更は行わず、コンサルティングやツールの提供に責任範囲をとどめる。最初のSREチームを実装する前に、パートタイムのSREをコンサルトとして配置するようなパターンが想定されているらしい。</p>
<p>Embedされていない場合において、その役割は多岐に渡る可能性があることがこのエントリーからは読み取れる。各プロダクトの信頼性向上に尽力する場合もあれば、サポート程度までしか行わない場合、あるいは完全にプラットフォームの整備へ注力する場合（個人的には、これはほぼインフラエンジニアではないかと思ったりするが）まで考えられる。SREチームとプラットフォームのインフラチームを別で用意できるほどに人員が豊富な事例というのはそれほどない気がしていて、僕としてはこのGoogleの6類型を使って、どのロールをどの程度担っているか、担っていくかと考えるのが一番しっくりきている。</p>
<p>なお、 <a href="https://www.harrisonclarke.com/devops-sre-recruiting-blog/embedded-sres-within-the-swe-team-or-a-separate-sre-team-entirely">Embedded SREs within the SWE team or a separate SRE team entirely? - Pros and Cons</a> では、このGoogleの6類型をざっくりとEmbedded SRE Teamsと <strong>Dedicated (Stand-alone) SRE Teams</strong> という2つに分類し直して再度論じている。SREがプロダクトチームの内外どちらにいるか、という点だけで分類するなら、この呼び方がわかりやすいかもしれない。</p>
]]></description>
            <link>https://chroju.dev/blog/types_of_sre_teams</link>
            <guid isPermaLink="false">types_of_sre_teams</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 20 Mar 2022 00:46:33 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[帝京大学通信課程での社会人大学生3年目を終えて]]></title>
            <description><![CDATA[<p>これまでの経緯は <a href="https://chroju.dev/blog/tags/university">#university</a> tagからどうぞ。ついに3年が終わった。2年次編入なので、ストレートであれば卒業も可能だった年 = 4年次、4年生である。卒業はできていない。</p>
<h2>単位修得状況</h2>
<p>修得単位数はこちら。</p>
<p>| 評価 | 2年次 | 3年次 | 4年次 |
|:--:|:--:|:--:|:--:|
| S | 8 | 2 | 4 |
| A | 12 | 8 | 6 |
| B | 4 | 4 | 6 |
| C | 0 | 4 | 0 |
| 合計 | 24 | 18 | 16 |</p>
<p>昨年よりさらに修得単位数が減った。時間が取れていないというほどでもないのだが、単純な話として応用的な科目が多くなり、より時間をかけなければ理解できなくなってきたな、と感じている。特に数学への苦手意識がなかなか抜けない。しかし、例えばフーリエ変換はいろんな科目の基礎になってくるわけで、1つの苦手意識が様々な科目に波及することが、応用的科目が増えるにつれて多くなってきた。たまに心底しんどく思うときはある。もうやめようかな、というのは2回ぐらい今年考えた。まぁでも、今のところやめるつもりはない。</p>
<p>それでも少しずつ理解は進むし、それは純粋に嬉しいし、楽しんで勉強はできている。学部教養というのは基礎的な内容なので、本業にはやはり直接短期的に意味をもたらしてくれることは多くないが、それでも無駄ではないことはわかる。恥ずかしながら光ファイバの物理的な仕組みなんて、大学に通わねば知ることはなかったかもしれないな、と思う。先日拝見した <a href="https://line.connpass.com/event/236497/">6社合同 SRE勉強会</a> でも「全単射」という単語が出てくる機会があったが、この単語も僕は大学で初めて知った。あるいは、学んだことをどうすれば活かしていけるか、ともっと能動的に考えてもいいのかもしれない。</p>
<p>残り34単位。今のペースを守りつつ、あと2年での卒業を目標とすることにした。仮に2年で卒業できなくても、まだバッファが2年ある、という計算。これぐらいならなんとかなるのではないか、いや何とかしよう、という所存。</p>
<h2>今年の変化</h2>
<h3>履修管理はGitHub Projectに移行</h3>
<p>1年目はスプレッドシート、2年目はNotionデータベースのカンバンを使っていて、3年目はGitHub Projectになった。</p>
<p><a href="https://gyazo.com/3bd99a8a6979e96496ac1011fe731b78"><img src="https://i.gyazo.com/3bd99a8a6979e96496ac1011fe731b78.png" alt="Image from Gyazo" width="600"/></a></p>
<p>課題やレポートもGitHubのプライベートレポジトリで管理しているので、結局のところこれが一番シンプルだし自分の日々の仕事と同じペースで進められるのでしっくりきた。</p>
<h3>テプラLiteを買った</h3>
<p>手で自分の氏名と住所を書く機会がとにかく多い。レポートを出すときは返信用封筒と送信用封筒のそれぞれに書かねばならず、さらにレポートに貼り付ける課題票という紙にも氏名が要る。さらに昨年度からはコロナ禍で試験の自宅受験が多くなり、試験答案も封筒で送らねばならなくなった。些細な機会ではあるもののどう考えてもToilであり、自動化は大事ということでテプラを買った。</p>
<p>https://www.kingjim.co.jp/sp/lr30/</p>
<p>テプラLiteはスマートフォンアプリからBLEで通信して使うテプラで、とても手軽に扱えてちょうどいい。最初のうちは通信がうまくいかなかったり、日本語入力のバグっぽいものに捕まったりもしたが、慣れてきたらスムーズに使えるようになった。ついでに家の中のちょっとしたラベルなども作れるようになり、買ってよかったと思う。</p>
<p>氏名と住所のシールを大量に印刷して、レポートを出すときはそれを貼るだけで良くなったのでだいぶ楽になった。</p>
<h3>Ankiを再開した</h3>
<p>一昨年度、とかく「覚える」ために通勤電車内で使っていた <a href="https://apps.ankiweb.net/">Anki</a> 。昨年度は通勤がなくなったのと同時に自然と使わなくなっていたのだが、今年は再開した。何かを覚える上では本当に効果的で優れたツールだと思っている。通勤は相変わらずほとんどしていないのだが、今年は隙間時間に起動して眺めるようにしていた。</p>
<h3>わずか1回の通学機会</h3>
<p>昨年度から試験がオンラインになり、年間数少ない大学通学の機会も消滅していたのだが、今年度は1回だけ通学できた。昨年秋頃、ちょうど第5波と第6波の間で行われた試験だけが対面開催になった。</p>
<p>顔を知っている学生もそれほど多くないので、だからどう、というのもあんまりないと言えばないのだが、それでも少し嬉しかった。キャンパスのある十条駅周辺は<a href="https://sumai.tokyu-land.co.jp/condo/jujo/">再開発の真っ最中</a>で、入学した頃に建っていた建物は軒並み無くなってしまっていた。2024年度竣工予定だそうで、わりと自分の卒業とどちらが早いかチキンレースになりかねないなぁとか思っている（自分は最長で2026年3月まで大学にいられる）。キャンパス内では、試験の合間にイタリアントマトで一息つくのが常だったのに、それもスタバに変わってしまって、席はなかなか空かなくなっていた。駅近くの『煮干そば 流。』が美味かった。</p>
<p><a href="https://gyazo.com/2ab8a5c536caa3318f7e9ecb14befe8e"><img src="https://i.gyazo.com/2ab8a5c536caa3318f7e9ecb14befe8e.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>まん延防止措置と緊急事態宣言が試験オンライン化の条件になっていたので、来年度こそは通学機会が増えてくれたらと思う。たまの気分転換にもなるし、自分が大学生であることの実感を持てるのは、悪いものではない。</p>
<h2>今年受けてよかった科目</h2>
<h3>幾何学</h3>
<p>これは純粋にただただ楽しかった。幾何学を学んだことがない身としては、幾何学って要するに四角形とか図形のことでしょ、ぐらいの頭でつまるところユークリッド幾何学しか想像できなかったんだけど、こんなに様々な考え方があるとは思ってもいなかった。取っ手が付いたマグカップとドーナッツは同じものなんです、とか。平行線が絶対に常に交わらないわけじゃない、とか。</p>
<p>ちょっと余談っぽくはあるけど、『チーム・トポロジー』（topology = 位相幾何学）を読んでしっくりきたのは、この科目を学んでいたおかげかもしれない。</p>
<h3>ディジタル通信</h3>
<p>光ファイバの仕組みとか。あとは標本化定理やフーリエ変換といった、他の科目で学んできたことがここで活かされて勉強を積み重ねていくことの意味というか、喜びみたいのを味わえた気がする。音声をデジタルの波形に変調する仕組みなどもまったく知らない分野だったので楽しめた。</p>
<h3>オペレーティングシステム</h3>
<p>IPAの資格でとか、仕事の中でとか、幾度となく学んできているOSの仕組み、これで何度目か、という感じの。最近は低レイヤー触るということもあんまりないので定期的に学び直すのも良いのだろうなと思っている。今年受けた中ではおそらくもっとも実技というか、今の仕事に直結しそうな科目。</p>
]]></description>
            <link>https://chroju.dev/blog/teikyo_university_learner_third_year</link>
            <guid isPermaLink="false">teikyo_university_learner_third_year</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 15 Mar 2022 10:23:50 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『ライティングの哲学』とエンジニアとアウトライナーと考えること]]></title>
            <description><![CDATA[<p>https://www.hanmoto.com/bd/isbn/4065243270</p>
<p>『ライティングの哲学』は、「書くこと」を職業とする学者やライター4人が集まって、如何に工夫していつも書いているのか、あるいは如何に書けていないのかということを座談会で赤裸々に語る本だ。IT系のエンジニアは別に書くことが飯の種というわけでもないので、一見関係ない本ではありそうなのだけれど、存外に参考になることが多かった。</p>
<p>本書で語られる「書けない」という悩みは、いわば「仕事に向かうために重い腰を上げられない」に近い部分があり、ならば「書かないで書く」という話が出てくる。</p>
<blockquote>
<p>「えーっと」とか「今日はフリーライティングしてみるわけだけど」とかもひとつひとつ全部、箇条書きにしていくんですよ。そうやって書いていると、だんだん思考が凝縮されていって、電話しないといけなかったことを思い出したり、カレンダーに入れ忘れていた用事が出てきたりと、仕事が発生してくる。文章を書くときに構えてしまうことを突破するために、ぼくは以前「書かないで書く」というキーフレーズを考えたんですが、それは要するに「規範的な仕方で書かない」という意味なんですよね。脱規範化するためには、「そんなの書いてるうちに入らない」くらいの雑な書き方であっても書いてしまえばいい。</p>
</blockquote>
<p>頭の中でまとまらない思考も、実際に言語化することでまとまっていき、解決策を思いついたりすることは、ライターではなくともよくある。エンジニアリングの仕事は、1日の大半が何かを考えることで、ともすると頭の中でもやもやとただ考えがちなところを、書きながら考えるようにしてみるとよかったりする。これはつまるところ、ラバーダック・デバッグとか、「壁打ち」と言われる手法と似た話だと思う。頭の中で考えるときにも言語を使うのが人間だとは思うが、それを実際に言葉でアウトプットしてみると、意外とすんなり考えがまとまっていく。壁打ちなどは会話の形式なので音声言語が用いられるが、文字で書くことで思考は目に見える形になり、より扱いやすくなると個人的には感じている。</p>
<p>ライティングというのは要するに、頭の中にある思考を論理的にまとめてアウトプットする過程であり、それは極端な話、エンジニアであっても似たようなことをやってはいて、出力が日本語なのかプログラミング言語なのかが大きな違い、というだけだったりはする。なので、結構エンジニアの立場から共感できる話はこの本には多い。</p>
<h2>エンジニアと「書く」こと</h2>
<p>つい先日も、 <a href="https://dev.classmethod.jp/articles/diary_driven_work_hacks/">日記駆動仕事術のススメ | DevelopersIO</a> というエントリーが話題になっていたように、エンジニアの中でも「書く」ことを勧める話は少なくない。日記、日誌、日報の関連では、『 <a href="https://www.hanmoto.com/bd/isbn/4274226298">達人プログラマー</a> 』にも「エンジニアリング日誌」という話が出てくる。これは、自身の実績を後々客観的に振り返る意味で日報を書くべきだという話であり、 <a href="https://next49.hatenadiary.jp/entry/20120529/p2">日報・週報を自分の役に立てるために書く - 発声練習</a> でも書かれている通り、思考・研究などを生業にする人には当たり前のような習慣なのかもしれない。『数学ガール』などで知られる結城浩さんもたびたび「作業ログ」の重要性に言及しており、 <a href="https://rentwi.hyuki.net/?1335498819534946305s">有料で自身の作業ログを公開</a> までしている。</p>
<blockquote class="twitter-tweet" data-dnt="true" align="center" data-conversation="none"><p lang="ja" dir="ltr">そのような判断をするためには「作業ログ」や「日誌」や「日報」のようなものが重要になります。自分は今日何をしたか。自分は今週何をしたか。自分は今月何をしたか。それらを淡々と振り返る手段を構築しておくことは極めて重要です。</p>&mdash; 結城浩 (@hyuki) <a href="https://twitter.com/hyuki/status/1415649394209169411?ref_src=twsrc%5Etfw">July 15, 2021</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>僕がこの手の「エンジニアと書くこと」について初めて読んだのは <a href="https://naoya-2.hatenadiary.org/entry/20131107/1383792634">「書く」のは特別な道具 - naoyaのはてなダイアリー</a> というエントリーだ。これは先のような振り返りの視点というよりは、『ライティングの哲学』と同じく、「書いて考える」ための話だ。このエントリーは何度も読み返している。何年か前にはSlackにおける「分報」のムーブメントもあったが、あれも書いて考える一環であり、そして一人ではなくチームでの思考を助長する面もあった。</p>
<p>また <a href="https://kirimin.hatenablog.com/entry/2019/08/06/190809">様々なTODOアプリやタスク管理方法を試行した結果最終的にプレーンテキストに行き着いた話 - みんからきりまで</a> のように、タスク管理も「書く」ことでテキストベースで行うという話もある。手法として確立された <a href="https://github.com/todotxt/todo.txt">todo.txt</a> のようなものもあるし、タスクだけではなく、一緒にメモから何から管理していこうとなれば <a href="https://orgmode.org/ja/index.html">Org mode for Emacs</a> もある。</p>
<p>書くことで思考を掘り下げる、やるべきことを明確化する、やったことを記録しておくなどなど、エンジニア界隈での「書く」ことの有用性の話は数多い。</p>
<h2>アウトライナーで書いて考える</h2>
<p>『ライティングの哲学』では、書くツールとしてアウトライナーがピックアップされる。著者の一人である千葉雅也さんは、以前から <a href="https://www.stone-type.jp/tebiki/321/">千葉雅也インタビュー「書くためのツールと書くこと、考えること」｜もの書きのてびき｜書く気分を高めるテキストエディタ stone（ストーン）</a>  などでもアウトライナー <a href="https://workflowy.com">Workflowy</a> の話をたびたびしているアウトライナー愛好家だし、半ば「アウトライナーの本」と言ってもいいかもしれないとすら感じる。</p>
<p>僕もメモを取るためのツールは <a href="https://sites.google.com/site/fudist/Home/qfixhowm">QFixHowm</a> を使ったり、シンプルにKobitoでMarkdownを書いたり点々としてきていて、その中でアウトライナーも使ってきている。アウトライナーが良いのは、文章を前後で入れ替えたり、入れ子の構造を作ったり、入れ子構造のchildだけにフォーカスして画面表示したりと、一度書いた文章を自由に切り貼りできる点にある。ざっくり「箇条書きを超柔軟に使えるツール」と言ってもいい気はしている。何かに行き詰まって、とりあえず今頭にあることを数行ガタガタガタっと書いてみる。その中で「あー、このあたり調べたほうが良さそうだな」というところがあれば、その行だけを画面に表示して、配下に文章をまた足していって……というような、思考を掘っていく過程を視覚的に再現できる。</p>
<p><a href="https://gyazo.com/c14a02d1e92b27484a5cd536504e9243"><img src="https://i.gyazo.com/c14a02d1e92b27484a5cd536504e9243.gif" alt="Image from Gyazo" width="600"/></a></p>
<p>アウトライナーのウェブサービスでは、特に Workflowy と <a href="https://dynalist.io/">Dynalist</a> の2つをよく耳にする。僕も最初に触れたのは2015年に登録した Workflowy で、その後一度アウトライナーを離れてから、2019年に Dynalist を使い始めた。そして先々週ぐらいからは <a href="https://legendapp.com">Legend</a> という比較的マイナーなものを使い始めた。</p>
<p>僕はタスク管理 + 日報のような用途でアウトライナーを使っていることが多い。今やるべきこととか、注意を向けたいことの全体像のリストと、今日やることのリストという主に2つがあり、「全体像のリスト」から「今日やることのリスト」にタスクを持ってきて1日が始まる。日中は「今日やることのリスト」の中でメモを取りながら過ごして、その中でタスクが発生したり、今日やりきれないタスクが出てきたら、「全体像のリスト」へ送る。1日の終わりに、完了したタスクとメモが「今日やることのリスト」に残るので、それを日報として残している。このあたりの方法は、 <a href="http://gofujita.info/notes_mydays.html">その日付をすてろ</a> とか色んなエントリーの影響を受けている。</p>
<p>ただ、ずっとカッチリとメモを残せてきたかと言うとそういうわけではない。僕は基本的には筆無精だし、頭の中で悶々と考え続けてしまう時間が大きい。それをどうにか解消したくて、ずっとメモツールにしがみついたまま生きている。</p>
<p>先ほど、アウトライナーは「箇条書きを超柔軟に使えるツール」と書いたが、一方で箇条書きは「文章を書こう」というモチベには繋がりにくい面も感じている。多くのアウトライナーは箇条書きのようなバレットが必ず先頭につくのだが、どうもこのUIだと細切れの単語しか書けないことが多かった。なのでゴリゴリと長文で思考を書き付けきることができず、断片的なよくわからない単語の固まりにしかならないことがあった。</p>
<p>Legendを使っている理由の一つは、わりと些細な話で、このバレットがキーボードショートカットで消せることにある。でもそれがすごく重要で、これだけで「文章を書こう」という気分がかなり醸成されるようになった。また、Markdownのように <code>#</code> を頭に付けると見出し化してくれる機能もあるのだが、このとき前の行といい感じにマージンを空けてくれて、これもまた書く気分を高めてくれる。それなら要はMarkdownエディタでいいじゃないかという話になりそうだし、それはその通りだと僕も思う。Legendを使ってみて気付いたのは、僕が欲しかったのは自在に階層構造間で文を移動できるMarkdownエディタだったんじゃないか、ということだった。クラウドでの同期ができるなら、org-modeを気に入っていた可能性もある。</p>
<p>もちろん他にもLegendに利点はあって（アウトライナーに興味ない人はこの段落を読み飛ばして大丈夫）、他のアウトライナーがだいたい常に1画面でしか表示できないところ、Legendは複数のタブを作ったり、タブの中にマルチペインで複数のアウトラインを並べて表示できる。僕の使い方で言えば「全体像のリスト」と「今日やることのリスト」を並べられるのがすごくいい。また日付付きのチェックリストを作ると、org-modeのAgenda Viewsのように一覧できる機能もある。アウトラインの全体像をサイドバーに表示して、クリックして好きな箇所を表示できる機能は、日報を振り返る上で重宝する。まだまだ発展途上のようで、正直バグに突き当たることもあったりはするのだが、開発も活発だし、使用感が気に入っている。ちなみに、GmailやGoogle Calendarとも連携できて、それらとアウトライナーの間で情報を行き来させ、ツールをまたいでToDoなどをOrganizeできるというのがLegend最大の売りらしいのだが、そこにはあんまり興味を持てていない。なお、今回DynalistとWorkflowyを避けた理由は、先のアニメGIFの中に書いている。</p>
<p><a href="https://gyazo.com/5a437317f8b056744b82723d4a27c03d"><img src="https://i.gyazo.com/5a437317f8b056744b82723d4a27c03d.png" alt="Image from Gyazo" width="600"/></a></p>
<p>IDEやテキストエディタで好きなカラースキームを選ぶように、文章を書く上でも、気分が上がりやすい、集中しやすい環境を整えるのは重要なことだと捉えている。つい書いてしまうような環境であることが理想的だ。『ライティングの哲学』では、こういう状態を「依存によって書く」と呼んでいた。Twitterについつい何か書き込んでしまうアレだ。あの状態を、手元のアウトライナーで作る。そして脳内にあることがするするとアウトライナーの上に表現されていく。それを整理するうちに考えが整理されていき、仕事が進んでいく。そして書いたメモは、もう少し整形して文章として整えてやれば、そのままScrapboxにストックしたり、ブログなどにアウトプットできる。まだそこまでの域には達していなかったりはするが、そんな状態が理想だな、と思いながら日々書いている。</p>
<p>『ライティングの哲学』ではこういった流れを作り上げる話が展開されているのだが、それはライティングに限らず、考えて仕事をする人全般に応用できる話ではある。</p>
]]></description>
            <link>https://chroju.dev/blog/writing_philosophies_and_engineers_thinking</link>
            <guid isPermaLink="false">writing_philosophies_and_engineers_thinking</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 11 Mar 2022 13:37:07 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[2021〜22年頃のDockerfile事情]]></title>
            <description><![CDATA[<p>先日 <a href="https://cockscomb.hatenablog.com/entry/2022/02/16/092538">GitHub ActionsでDocker Buildするときのキャッシュテクニック - cockscomblog?</a>  を読んで、Dockerに関して最近の動向があまり追えていないなぁ、と思ったのでいろいろと調べてみたことをまとめる。</p>
<h2>Export cache</h2>
<p>先のエントリーの <code>type=gha</code> cache は BuildKit の export cache における機能の1つ。</p>
<p>export cache には <code>gha</code> の他に、 <code>inline</code> 、 <code>registry</code> 、 <code>local</code> の3タイプがある。 inline は image と一緒に cahce をメタデータに書き込んでレジストリへ送る。 registry は image とキャッシュを分けて、キャッシュは cache manifest という形式でレジストリへ送る。ghaはGHA最適化であり、 local は読んでそのままローカルにキャッシュを出力する。</p>
<p><code>inline</code> はmin modeでしか使えない制約がある。min modeは結果イメージのレイヤーしかキャッシュしないが、max modeはすべてのレイヤーをキャッシュする。</p>
<p>そのため <code>registry</code> でmax modeを使うほうがよいのだが、これについてはコンテナレジストリによってはcache manifestに対応していない場合がある。例えばAmazon ECRは対応していない。ECRを使っていて <code>registry</code> を使いたい場合、cache manifestに対応した、例えばGitHub Container Registryへcacheだけを送る、という荒技もあるようではある。</p>
<p>https://github.com/aws/containers-roadmap/issues/876</p>
<p>GitHub Actionsでキャッシュするなら、わりと何も考えずに使える <code>gha</code> が便利。ただし、現段階ではexperimentalであることは念頭に置いたほうが良さそう。その点を懸念するのであれば、 <code>type=local</code> を <a href="https://github.com/actions/cache">actions/cache</a> と一緒に使うのが穏当か。</p>
<h2>apt-get upgrade in Dockerfile</h2>
<p>Dockerfile内で <code>apt-get upgrade</code> など、 base imageに含まれるパッケージを一括でアップグレードする書き方は従来非推奨になっていたが、これは現在非推奨ではなくなった。</p>
<p>https://github.com/docker/docker.github.io/pull/12571</p>
<p>非推奨ではなくなっただけで、推奨になったというわけではない。Dockerfileで <code>apt-get upgrade</code> を書くかどうかは是非が分かれるところだと思う。base imageのパッケージに脆弱性があった場合、それに対処できる可能性があるが、一方でコンテナビルドの冪等性は失われることになる。</p>
<p>僕としては <code>apt-get upgrade</code> して良いのではないかと考えている。理由としては先のPRを提案したItamar氏の <a href="https://pythonspeed.com/articles/security-updates-in-docker/">The worst so-called “best practice” for Docker</a> にほぼ同意するところ。昨年 <a href="https://www.infoq.com/jp/news/2021/03/dockerhub-image-vulnerabilities/">Docker Hub公開イメージ400万の半数に重大な脆弱性が見つかる</a> というレポートもあった通り、Docker Hub上のOfficial Imageであってもパッケージに脆弱性がある場合は少なくない。正攻法としてはImage提供元に連絡してアップグレードしてもらうことだが、実際にコンテナビルドしていてもそれほど早く脆弱性対応されている状況とは認識できていない。ならば <code>apt-get upgrade</code> してこちらで対応してしまうのはありだと思う。冪等性に関してはビルド済みのイメージに対して求めれば運用上は十分であり、「同じDockerfileからビルドすれば同じものができる」状態はあまり求めていない。</p>
<h2>RUNを1行で書くか否か</h2>
<p>かつては「<code>RUN</code>の中でコマンドを <code>&#x26;&#x26;</code> で繋げて1行で書きましょう」というのが盛んに言われていた。マルチステージビルドの登場によりこの状況は変わりつつある。中間イメージのレイヤー数は最終イメージに影響しないので、中間イメージの中であれば <code>RUN</code> を1行で書かなくても良いという話。</p>
<p>ただ注意しなくてはならないのは、 <code>RUN</code> を1行にまとめていた理由はレイヤー数の問題だけではなく、レイヤーキャッシュの観点もあったということ。1行にまとめていたコマンドを複数行に分けることで、キャッシュも別々に取られることになるわけだが、それで不都合がないかは気をつける必要がある。</p>
<p>今回調べていてよく目にしたのが、 <code>RUN apt-get update &#x26;&#x26; apt-get install hoge</code> も複数行に <code>RUN apt-get update</code> と <code>RUN apt-get install hoge</code> で分けられますという話だが、これを分けて嬉しい場面はそれほど多くない気がしている。例えばインストールするパッケージを追加したくて後者を <code>install hoge fuga</code> に変更したとする。このとき <code>apt-get update</code> のレイヤーは、コマンドに変更がないのでキャッシュが使われたままになり、 <code>fuga</code> は古いバージョンのパッケージがインストールされる可能性がある。このことは <a href="https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#run">Best practices for writing Dockerfiles | Docker Documentation</a> の中でも言及されている。</p>
<p>なお、 <code>&#x26;&#x26;</code> で繋げて書く記法は煩わしいものではあるが、 <code>docker/dockerfile:1.4</code> でヒアドキュメントが導入されており、こちらのほうがいくらかマシかなと感じている。</p>
<pre><code class="language-Dockerfile">syntax = docker/dockerfile:1.4
FROM debian
RUN &#x3C;&#x3C;eot bash
  apt-get update
  apt-get install -y vim
eot
</code></pre>
<h2>Dockerfile syntax</h2>
<p>Dockerfile syntaxもどんどん新しい記法が取り入れられており、 <a href="https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/syntax.md">buildkit/syntax.md at master · moby/buildkit</a> にまとめられている。新しい記法はDockerfileのバージョンによって使用可否が変わるので、使いたい記法に合わせてファイルに <code># syntax=docker/dockerfile:1.3</code> というフラグを1行入れる必要がある。</p>
<p>特に <code> RUN --mount=...</code> 記法は非常に便利。<code>--mount=type=hoge</code> の <code>hoge</code> 部分によって機能がまったく異なるので一言ではまとめづらいのだが、すべて目を通しておくと良さそう。例えば <code> RUN --mount=type=cache,target=/root/.cache/go-build go build ...</code> とすると、ディレクトリ指定でのキャッシュを取ることができ、パッケージインストールなどで効果を発揮する。<code>--mount=type=secret</code> では、例えばビルド時に一時的にAPI実行で必要なキーなどを秘匿的に読み込み、最終イメージには焼き込まないようにできる。</p>
<h2>Digression</h2>
<p>AWSとかTerraformとかDatadogとかはわりと追えているんだけど、Dockerfileに関しては全然追えてね〜〜という感じだったのが身に染みた。まぁ、こういうのは気付いた段階でGitHub Releaseとか公式ブログとかをちまちまRSS Readerに突っ込んでいく他ないとは思うのだが、CloudNative界隈に携わっていると本当に追うものが多くて大変という感じ。一度調べてベストプラクティスに則った設計が出来たぞいと思っていても、1年ぐらい経つとすでにDeprecatedですなんてことはざらにある。情報をザッピング的にサクサクと仕入れていく必要性をひしひしと感じているのだが、このあたりはみなさんどうやって効率よく情報を集めているんだろうなぁ、って思う。そしてこういう「定常的な更新確認」においては、やはり2022年においてもRSSが欠かせないな、とも思う。</p>
]]></description>
            <link>https://chroju.dev/blog/docker_practices_2022</link>
            <guid isPermaLink="false">docker_practices_2022</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 28 Feb 2022 00:17:31 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[令和4年最新版 Amazon S3 のストレージクラスと Backup]]></title>
            <description><![CDATA[<p>Amazon S3 のストレージクラスがどんどん増えるなぁとぼんやり数年眺めていたところ、気付けば <strong>8種類</strong> となかなかな数になってしまった。そこで昨年の re:Invent 2021 での更新内容を中心に、 Amazon S3 のいくつかの技術仕様をさらい直してみた、自分用メモを残しておく。</p>
<h2>ストレージクラス</h2>
<p>先述の通り、現状は8種類が存在している。 re:Invent 2021 で発表された Glacier Instant Retrieval が追加されたのが最後となっている。</p>
<p>https://dev.classmethod.jp/articles/reinvent2021-amazon-s3-glacier-instant-retrieval-storage-class/</p>
<p>本記事執筆時点だと、<a href="https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/storage-class-intro.html#sc-compare">日本語版の S3 ドキュメント</a> は最新の状態にはなく、まだ7種類のストレージクラスしか表記されていない。以下、 <a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/storage-class-intro.html#sc-compare">英語版</a> を参考にすることとする。</p>
<h3>標準、IA、Glacier の現状</h3>
<p>古い人間としては、ストレージクラスというと標準、IA、Glacier の3種類という認識が強い。基本的には標準 → IA → Glacier と辿るにつれて、保存料金は低くなり、一方でデータの取り出し料金は高くなる。特に Glacier についてはかなり低料金になるが、取り出しにおいては分単位での時間がかかるようになる。 IA （Infrequent Access）は名前通り低頻度のアクセスが想定されるデータの保存に適しており、 Glacier はほとんど取り出すことのない、例えば監査対応のためのログ保存などに適している。</p>
<p>……と、いうのが基本的な僕の認識だったのだが、これがややこしくなったのが最新ストレージクラス Glacier Instant Retrieval の登場である。これは Glacier という名を冠してはいるが、データの取り出しは標準、IA と同様に数ミリ秒のディレイで実現される。 Glacier シリーズのアイデンティティはその名の通り「氷河」のようにデータが凍結され、すぐに取り出せないことにあると考えていたのだが、現状はそのような区分け方ではなくなっている。</p>
<p>適切なストレージクラスを考えるにあたっては、保存料金と取り出し料金のほかにも、いくつかの観点を踏まえる必要がある。</p>
<h3>最小ストレージ期間とデータサイズ</h3>
<p>標準と Intelligent-Tiering 以外の各クラスは「最小ストレージ期間」の設定があり、その期間内にオブジェクトを削除すると、最小期間相当の料金が発生する。例えば「標準 IA」の最小ストレージ期間は30日であり、オブジェクトを保存開始後に5日で削除しても、30日保存したのと同等の料金になる。</p>
<p>似たところで、データサイズの制約も存在する。標準 IA は最小データサイズが 128KB であり、それより小さいサイズのオブジェクトを保存しても、 128KB 相当の保存料金が発生する。これも標準と Intelligent-Tiering 以外、すべてのクラスに適用されている。</p>
<h3>クラス移行の前提条件</h3>
<p>https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/lifecycle-transition-general-considerations.html</p>
<p>IA については、ストレージクラスを移行する前に、「標準」ストレージクラスで30日保存されている必要がある。 IA は標準と同じく数ミリ秒でデータが取り出せるので、取り出し頻度が多少低ければ取りあえず IA 、としたくなるところだが、ある程度長期間保存されるデータでなければ、 IA は利用できない。</p>
<h3>ストレージクラスの考え方</h3>
<p>ストレージクラスの使い分けは、基本的には <a href="https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/storage-class-intro.html">Amazon S3 ストレージクラスを使用する - Amazon Simple Storage Service</a> を見れば間違いがなさそうなところではあるが、先の通り最新版にはないため、現時点では英語版を見るのを勧めたい。英語版だと、ストレージクラスの比較表（以下に抜粋）において、 IA などが想定する「低頻度のデータアクセス」というのが、具体的にどの程度の頻度なのかも言及があるので、その点でも英語版を読む価値がある。</p>
<p><a href="https://gyazo.com/42ba301e09a66267d1ab0f2acb789a7c"><img src="https://i.gyazo.com/42ba301e09a66267d1ab0f2acb789a7c.png" alt="Image from Gyazo" width="600"/></a></p>
<p>基本的にはこの表にて、アクセス頻度だけでほぼ一意にストレージクラスを決定できるようになっている。</p>
<ul>
<li>アクセスが頻繁 or 保存期間が1か月以内 → 標準</li>
<li>1か月に1回程度 → 1ゾーンIA or 標準IA</li>
<li>四半期に1回程度 → Glacier Instant Retrieval</li>
<li>年に1回程度 → Glacier Flexible Retrieval （旧 Glacier）</li>
<li>年に1回未満 → Glacier Deep Archive</li>
</ul>
<p>標準以外のストレージクラスは、いずれも30日以上の最小ストレージ期間が設定されているため、アクセスが頻繁ではないとしても、30日以内に削除されるようなデータは「標準」で保存するしかない。</p>
<p>アクセス頻度が1か月に1回程度の場合は、1ゾーン IA と標準 IA の2つが選択肢となるが、これらは可用性、回復性の点で差分がある。1ゾーン IA は 1 AZ でしかデータを保存しないため、その分料金は下がるものの、標準 IA が可用性 99.9 % であるのに対して可用性 99.5 % にとどまり、また災害時などはデータが回復しないおそれがある。</p>
<p>3つの Glacier については、先述の通り Glacier Instant Retrieval 以外についてはデータの即時的な取り出しができないため、その点に注意が必要だ。</p>
<p>なお、アクセスパターンの予測がつかない場合は、 Intelligent-Tiering というストレージクラスを使うことにより、アクセス頻度に応じて自動的に最適なストレージクラスへオブジェクトが移行されるようになる（正確には Intelligent-Tiering 自体がストレージクラス相当の概念であり、変動するのは各ストレージクラスに相当する「アクセス階層」と呼ばれるパラメータ）。移行先には、 Glacier Instant Retrieval や Glacier Deep Archive に相当するアクセス階層も存在するが、これら階層への移行を有効化するかどうかは選択できるようになっており、気付けばデータが即時取り出しできなくなっていた、という事態は避けられる。</p>
<h2>AWS Backup の S3 対応</h2>
<p>https://aws.amazon.com/jp/blogs/news/preview-aws-backup-adds-support-for-amazon-s3/</p>
<p>S3 のバックアップ機能として、 AWS Backup が S3 をサポートすることが re:Invent 2021 で発表された。ただし、現状 preview の状態であり、 Oregon でしか利用することはできない。</p>
<p>機能と特徴をざっくりまとめると以下の通り。</p>
<ul>
<li>利用に当たってはバージョニングの有効化が必要となる</li>
<li>バックアップタイミングは、ポイントインタイムと定期の2種類がある</li>
<li>復元はバケット全体、オブジェクト単位の2種類を選択できる</li>
<li>オブジェクト単位で復元する場合、一度のGUI操作で復元できるのは5個までの制限がある</li>
<li>復元先は既存バケット、もしくは新しいバケットをつくるか選べる</li>
</ul>
<p>S3 のデータ回復という点では、従来からバージョニングの機能があり、オブジェクトを更新したり削除しても、その前の版のオブジェクトを残しておいて、後から復元させることができた。そのため、オブジェクト単位のリストアが、バージョニングにおける復元とどう違うのかがいまいち掴めていない。時間指定で戻せるのがポイントだろうか？</p>
<p>バケット全体のリストアについては、使いたい機会もありそうな気はしている。いずれにせよまだ本番利用できる段階にはない。</p>
<h2>ACL の無効化</h2>
<p>https://aws.amazon.com/jp/blogs/news/new-simplify-access-management-for-data-stored-in-amazon-s3/</p>
<p>re:Invent 2021 での大きな発表からもう1つ、 ACL の無効化も取り上げる。S3 のアクセス制御は、オブジェクトポリシーと ACL の2つを利用することができるために非常に複雑であったが、このうち ACL に関しては、バケット単位で機能を無効化することができるようになった。</p>
<h3>ACL 無効化の本質</h3>
<p>「ACL の無効化」は、より厳密には「オブジェクト所有者」を強制的に「バケット所有者」と同一とする設定であり、 GUI での設定箇所も ACL の項ではなく、「オブジェクト所有者」の項にある。このあたり、 ACL を理解していないと少々わかりにくい。</p>
<p>バケット所有者、オブジェクト所有者という概念が、 ACL とどう関係するのか。従来、オブジェクトの所有者は、バケット所有者とは別とすることができたのだが、このとき、バケット所有者からは、そのオブジェクトの管理ができなくなるという仕様があった。というのも、オブジェクトには「オブジェクト ACL」というアクセス権が設定されており、これがデフォルトでは、オブジェクト所有者に対してのみ許可を与える形となっていたからだ。オブジェクト所有者以外へアクセスを許可するには、オブジェクト ACL を変更しなければならなかった。</p>
<p>従って ACL を無効化し、使わないようにする上では、オブジェクト所有者をバケット所有者と一致させることが必須となる。</p>
<h3>他に ACL が必要な場面はないのか？</h3>
<p>ACL を無効化して困る場面はないのだろうか。多くの場面では、 ACL を使って実施できることはバケットポリシーで代替できるが、従来いくつかの権限制御には ACL が必須とされていた。</p>
<p>1つは、サーバーアクセスログを記録するにあたり、ログ配信グループへのアクセス許可を ACL で与える必要があるとされていた。これについてはバケットポリシーでの付与が可能となったため、現状 ACL は必要ではなくなった。（参考: <a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-ownership-migrating-acls-prerequisites.html#object-ownership-server-access-logs">Prerequisites for disabling ACLs - Amazon Simple Storage Service</a> ）</p>
<p>日本語のドキュメントにはこの内容はまだ反映されておらず、 <a href="https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/access-policy-alternatives-guidelines.html">アクセスポリシーのガイドライン - Amazon Simple Storage Service</a> には「バケット ACL の使用が推奨される唯一のユースケースは、Amazon S3 のログ配信グループに、バケットへのアクセスログオブジェクトの書き込みアクセス許可を付与する場合です」との記載が現時点では存在している。 <a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-policy-alternatives-guidelines.html">英語版</a> では、この表記はすでに削除されている。</p>
<p>これ以外では、 <a href="https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html#AccessLogsBucketAndFileOwnership">CloudFront の標準ログを S3 へ保存する際、 ACL を使用している。</a></p>
<p>これをバケットポリシーで置き換えることは現時点ではできないらしい。回避策としては、 CloudFront のもう1つのログ機能である、リアルタイムログを使い、標準ログの使用をやめることが挙げられる。</p>
<p>その他では、オブジェクトレベルで権限制御したい場合などが考えられるが、ほとんどのユースケースではバケットポリシーで制御可能な「ディレクトリ」レベルの権限で十分ではないだろうか。よって多くの場合、 ACL は無効化できそうだと考えている。</p>
]]></description>
            <link>https://chroju.dev/blog/s3_storage_classes_and_backup_in_2022</link>
            <guid isPermaLink="false">s3_storage_classes_and_backup_in_2022</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 22 Jan 2022 12:28:40 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『チームトポロジー』を読んだ]]></title>
            <description><![CDATA[<p>https://www.hanmoto.com/bd/isbn/4820729632</p>
<p>原著の<a href="https://www.amazon.co.jp/dp/1942788819">『Team Topoligies』</a>を昨年、 Twitter のタイムラインで何度か見かけていて、読もうかなと興味を惹かれていたのだが、ありがたいことにそのタイミングでちょうどよく翻訳版が出てくれたのでそちらを読んだ。</p>
<p>興味を惹かれた理由としては、 SRE としての価値最大化を考えていると、組織論を外すことができないという問題意識が強くなっていたから。SRE は開発速度と信頼性のバランシングが責務となるはずだが、専任の SRE チームとして組織すると開発チームとの間でコミュニケーション上のロスが発生し得る。ならば開発チームの中に SRE が属すれば良いかと言えば、 SRE 間の横のつながりも必要なのでそう単純な話でもない。このあたりの SRE チームの構造に関する問題は <a href="https://cloud.google.com/blog/products/devops-sre/how-sre-teams-are-organized-and-how-to-get-started">SRE at Google: How to structure your SRE team | Google Cloud Blog</a> にも言及があるが、ソフトウェア開発全体というレイヤーから組織論を学ぶことで、何かヒントを得たいと考えていた。</p>
<h3>追記（2022-01-16 11:05）</h3>
<p>https://www.tc3.co.jp/state-of-devops-report-2021-team-topologies/</p>
<p>昨年、原著を Twitter 上で見かけていた背景として、 State of DevOps Report 2021 で言及されていたというのが大きかったのかもしれない。</p>
<h2>チームトポロジーとは何か</h2>
<p>トポロジー、直訳したところの「位相幾何学」はちょうど最近大学でも学んだところだが、ネットワーク・トポロジーという言葉もあるし、動的に変化する構造、ぐらいの意味で使われているように思う。チームトポロジーとは、組織や技術の成熟、進化に合わせて、チームの構造も継続的に進化させていく動的なアプローチを指す。</p>
<p>チームの構造を考える上でのキーとしては、認知負荷とコンウェイの法則が繰り返し出てくる。チームの人数はダンバー数を反映して、適切な関係を保てる人数に維持しなくてはならない。またチーム間の関係性もまた、認知負荷を引き下げるべく、何かを共有するのではなく、適切に分離された状態が求められる。本書では API を模した「チームAPI」と呼ばれる仕組みを、他チームからのコミュニケーションの窓口として設けることを提唱している。</p>
<p>そして組織構造を考える上では、コンウェイの法則もまた考慮する必要がある。疎結合で凝集性の高いソフトウェアアーキテクチャとしたいのならば、組織構造もまた、それに倣ったものでなくてはならない。</p>
<h2>プラットフォームチームを兼任する SRE チーム</h2>
<p>チームの役割を曖昧で無制約なものとしないために、本書では各チームを4つのチームタイプに当てはめることを提唱している。そのうち、ストリームアラインドチームは従来フィーチャーチームなどと呼ばれていたような、あるドメインの開発からリリースまで一気通貫に実行できるチームタイプを指す。また、プラットフォームチームは、ストリームアラインドチームが下位のレイヤー（インフラストラクチャーなど）を意識する必要を減らすために、横断的な内部サービス提供を行うとされる。</p>
<p>SRE チームは、このストリームアラインドチームの特殊な類型の1つとされている。横断的なチームであり、各ストリームアラインドチームとコラボレーションしながら、ソフトウェアの変更が適切なストリームに則るようサポートを行う。確かに SRE book でも、 SRE は各プロダクトに常時関わり続けるわけではなく、必要になった段階でコミットし、自律的に信頼性が維持されるようになればコミットを終えるといった動的なサイクルを辿る者とされている。</p>
<p>ただ僕自身もそうだが、国内の SRE チーム（国外の情勢は詳しくない）はインフラチームが改組したもの、インフラチームの役割を兼ねているものが多く、チームトポロジー掲載のチームタイプで言えば、プラットフォームチームの性格を持っている場合が少なくない。言うなればプラットフォームチームと、ストリームアラインドチームの一端とを兼ねた状態になるわけだが、本書に照らし合わせればこれはあまり良い状態とは言えないのだろう。</p>
<p>プラットフォームチームと、ストリームアラインドチームとしての SRE を完全に分離している例としては、僕が知っている範囲では国内ではメルカリが実現している（参考 : <a href="https://engineering.mercari.com/blog/entry/2020-07-16-083548/">どのようにPlatformチームの組織変更をしたか | メルカリエンジニアリング</a>）。しかし、これは人数を必要とする構造であり、特に小さい開発組織では容易なことではない。現実的には、例えば SRE チームがプラットフォームチームとストリームアラインドチーム双方の性格を持ちうることを受け入れつつ、プラットフォームチームに関してはなるべく開発チームとの関係性を疎結合に保ち、密なコラボレーションは SRE としての責務に集中させるなど、 SRE のような横断的なチームについては、その構造とコミュニケーションパスをより深く考える必要があると感じた。</p>
<h2>運用からのフィードバックの重要性</h2>
<p>個人的に、本書で最も重要なポイントは組織構造を「動的」なものとして捉えるという点だと思っている。そのために、組織構造を変化させる必要のある状況に的確に気付く、「組織的センシング」の必要性が説かれている。</p>
<p>その1つとして、運用から開発へのフィードバックが重要だとされている。これもまた SRE の役割として考えなくてはならないことのひとつだ。 SRE は Embedded な形ではないにしても、適切に開発チームへフィードバックができる状態は保っておく必要がある。 SLO はそのものずばり、運用フェーズから開発へとフィードバックされる、客観的に可視化された指標に成り得るものだし、 SRE が積極的に開発チーム（ストリームアラインドチーム）へ介在しなくとも、アラートやレポートによって、ストリームアラインドチームが自律的にフィードバックループを回すための仕組みとして機能し得るのではないだろうか。</p>
<h2>Conclusion</h2>
<p>本書は必ずしも目新しい話ばかりというわけではない。ストリームアラインドチームは、自律性やオートノミーを持ったチームとしてもしばしば耳にしてきた覚えがあり、<a href="https://www.hanmoto.com/bd/isbn/4839970459">『Scaling Teams』</a> などでも言及されているなど、個々の概念自体は従来から存在してもいる。ただ、チームをトポロジー = 動的構造として見ること、認知負荷の観点から適切な構造を探ることなど、既存の組織論をよりもう一歩踏み込んで実践させるための書だと感じた。</p>
<p>いろいろと書いてはみたが、組織論である以上、個人で知見を持っていても仕方ないことであるのも事実であり、仕事の中でも必要に応じてこういった知見を共有しながら検討は進めていきたい。</p>
]]></description>
            <link>https://chroju.dev/blog/team_topologies</link>
            <guid isPermaLink="false">team_topologies</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 15 Jan 2022 16:00:14 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『A Philosophy of Software Design』を読んだ]]></title>
            <description><![CDATA[<p>https://www.amazon.co.jp/-/en/John-Ousterhout/dp/1732102201</p>
<p><a href="https://ky-yk-d.hatenablog.com/entry/2022/01/04/100000">ソフトウェアの複雑さに立ち向かう1つの哲学 :『A Philosophy of Software Design』 を読んだ - こまぶろ</a> という非常に優れた感想エントリーがバズった直後なのだが、同じ書籍の感想を上げさせていただく。あの解像度の記事はちょっと書けないが。</p>
<p>先のエントリーに触発されたわけではなく、僕が本書を買ったきっかけは <a href="https://deeeet.com/posts/practices-for-better-terraform-module/">Practices for Better Terraform Module | Taichi Nakashima</a> で Deep Module に関する一節を読んだことだった。それから1年近く積んでいたのを、2021年12月に重い腰を上げて読んでいた。従って現在の最新版である第2版ではなく、初版の感想になる。余談にはなるが、 Kindle で買う場合は初版と第2版の商品ページが分かれておらず、「すべての形式と版を表示」から選ばなければ第2版が買えないので、注意されたい。</p>
<p><a href="https://gyazo.com/e3204b1e85b22ff7b8976e3989431435"><img src="https://i.gyazo.com/e3204b1e85b22ff7b8976e3989431435.png" alt="Image from Gyazo" width="600"/></a></p>
<h2>動機</h2>
<p>職業プログラマーの経験がないので、ソフトウェア開発のパラダイムや哲学に疎い認識が常にある。特に SRE になってからは、ソフトウェアエンジニアリングが求められる場面も増えたし、 Infrastructure as Code においても依存性をどう排除するか、各種モジュールなどをどういった観点から分離していくか、といったソフトウェア開発の原理原則は応用できる。</p>
<p>そんなときに先の deeeet 氏のエントリーを読み、 Terraform module 作成にこの書籍を応用しているならば、何か自分にも得られるものがあるかもしれない、と読んでみた次第。</p>
<h2>感想</h2>
<p>ソフトウェア開発において「複雑性」を抑制するためにはどうしたらいいか、という方法論をいくつかの観点から述べている本。英語の本なので敬遠してここまで積んでしまったわけだが、実際読んでみると英語は平易なほうで読みやすかった。また言わんとするところもかなりシンプルだなと感じる。</p>
<ul>
<li>複雑性
<ul>
<li>システムの理解や変更を困難としてしまうような性質</li>
</ul>
</li>
<li>なぜ複雑性を避けるべきか
<ul>
<li>シンプルな変更でも複数箇所を更新しなくてはならなくなる</li>
<li>認知負荷の増大</li>
<li>Unknown unknowns (知られていない、ということが知られていないこと) の増大</li>
</ul>
</li>
<li>複雑性はなぜ発生するのか
<ul>
<li>依存性
<ul>
<li>ゼロには出来ないが、削減し、シンプルに、明瞭にするべき</li>
</ul>
</li>
<li>不明瞭さ
<ul>
<li>変数名やドキュメントの不備から発生する</li>
</ul>
</li>
<li>複雑性は徐々に増大していくもの</li>
</ul>
</li>
<li>どうするべきか
<ul>
<li>Deep Module
<ul>
<li>インターフェースがシンプルで、隠蔽された情報が多いモジュール</li>
<li>メソッドや変数だけではなく、例外もまたインターフェースである</li>
</ul>
</li>
<li>Information Leakage
<ul>
<li>別のモジュールを同じ情報に依存させない</li>
</ul>
</li>
<li>メソッドは1つのことだけを完全に遂行する
<ul>
<li>他のメソッドを呼ぶだけのメソッドなどは作らない</li>
</ul>
</li>
<li>コメントはコードの内容をそのまま書くのではなく、抽象度を上げるか詳述するのかどちらか</li>
<li>継承は複雑性に繋がりやすいので留意する</li>
<li>アジャイルは機能レベルで increment するのではなく、抽象のレイヤーで increment することを意識する</li>
</ul>
</li>
</ul>
<h2>Terraform と複雑性</h2>
<p>冒頭で書いた「動機」に鑑みて、 Terraform に引き寄せて少し考えてみる。</p>
<h3>Terraform module と Deep module</h3>
<p>Terraform では抽象化のための機能として module が存在するが、これを扱う上で、 Deep Module の観点はやはり非常に重要だと思う。</p>
<p>僕の場合は AWS と Terraform をセットで使うことが多いので、 AWS に関しての話になるが、例えば EC2 インスタンスを Terraform で立てる場合に記述することになる、 <code>aws_instance</code> のドキュメント <a href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance">aws_instance | Resources | hashicorp/aws | Terraform Registry</a> を見るとパラメータが極めて多く、 Terraform を扱い慣れている自分でも、下までスクロールするのが嫌になる。</p>
<p>AWS を商用利用する場合、その組織内での規約に従い、いくつかのパラメータは決め打ちしたり、デフォルト値を決めておけることも多い。そういった場合に module 化を行えば、インターフェースは削減され、認知負荷の抑制が期待できる。</p>
<p>ただ、これだけでは単にインターフェースが減っただけであり、 <strong>Deep</strong> とは言い難いかもしれない。複数の AWS リソースを組み合わせて作成することで、何か1つの目的に供するような場合に、それらのリソースを1つの module で作成できるようになっていれば、より Deep と言えるものになる。例えば EKS Cluster はクラスターを作成し、権限管理用の IRSA を設定し、ログ出力先となる CloudWatch Log Group を作成し……と非常に手数の多い作業なのだが、これを一括して管理できる module が存在する。これは Deep な Terrform module の1つと言えそうだ。</p>
<p>https://github.com/terraform-aws-modules/terraform-aws-eks</p>
<p>注意が必要なのは、 module の中に複数のリソースを含めたとき、その一方だけを更新したり、別の用途で使用したりするのは困難になる可能性がある点だ。先の EC2 インスタンスを作成するとき、セキュリティグループも同じ module に含めて作成したとして、そのセキュリティグループを他の用途にも使い回そうとすると、不要な依存関係が発生してしまう。セキュリティグループはあるインスタンス専用に作るというよりは、ウェブサーバー用、RDS 用など汎用的に作る場合が多いと考えられるので、インスタンスの module からは切り離し、外から渡せるようにしたほうが複雑性は抑制できる。こういったことは、本書でも general purpose と special purpose を1つの module にするべきではない、という観点で書かれている。</p>
<h3>remote state と Information Leakage</h3>
<p>Terraform に関してもう1つ気になるのは、remote state だ。これは Terraform のある state が output した値を、別の Terraform state から参照できる機能だが、字面通りの「依存」に他ならない。 output している側で何か変更が入り、 output した値が更新されたとして、それを remote state で読み込んでいるあらゆる場所に影響が及ぶことになる。</p>
<p>個人的な印象にもなるが、 remote state はレポジトリをまたいだ依存にも成り得るので、 Unknown unknowns な依存になりやすい傾向にあると感じている。可能であれば <code>data</code> で置き換えたり、そもそも state 間で依存性が発生しないような構成を考えるべきだろう。</p>
<h2>Conclusion</h2>
<p>Terraform で少し考察をしてみたが、複雑性による認知負荷の増大については、 Kubernetes の YAML 地獄でも似たものを感じる。 Helm や Kustomize など、マニフェストを抽象化するためのソリューションはいくつもあるが、まだ決定打は出ていないように思うし、どのツールを使うにしても、本書で述べられている観点は参考にできるのではないかと思う。「複雑性」との戦いは、職種問わず IT でシステムを組んでいれば自ずと発生するので、どのような立場でも読んで益のある本ではないだろうか。</p>
]]></description>
            <link>https://chroju.dev/blog/a_philosophy_of_software_design</link>
            <guid isPermaLink="false">a_philosophy_of_software_design</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 10 Jan 2022 05:57:05 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[2022年時点で知っていることと知らないことと、今年の展望]]></title>
            <description><![CDATA[<p>年間の目標、というのはスパンが長すぎる気がしていてここ数年立ててはいなくて、Q単位での目標だけにしているんだけど、とはいえ年の初めは自分がこれから何を成すのか棚卸しながら考える機会になりやすい。この年末年始もいろいろと考え事をしていた。</p>
<p><a href="https://www.hanmoto.com/bd/isbn/4274226298">『達人プログラマー』</a> に「知識ポートフォリオ」というプラクティスの紹介がある。自分の知識の多寡を金融資産のポートフォリオのように見立てて、定期的にリバランスしたり、分散投資しながら継続的に強化していこうという話だ。これ、ずっとやってみたいと思ってはいたのだが、なかなかその機会が取れなかったのを、今回やってみることにした。自分の中の知識を一度客観的に見つめ直してから、今後何に取り組むのかを改めて考えたいと思ったからだ。なので、この記事では「知識ポートフォリオ」を書いたあと、最後に今年の展望に少し触れてみたい。</p>
<p>書籍の中には具体的なポートフォリオの書き方には言及がないので、似たことを実践している以下の記事を参考にさせてもらった。</p>
<ul>
<li><a href="https://overreacted.io/ja/things-i-dont-know-as-of-2018/">2018年の段階で私が知らないこと — Overreacted</a></li>
<li><a href="https://scrapbox.io/fsubal/%E5%BE%97%E6%84%8F%E3%83%BB%E8%8B%A6%E6%89%8B%EF%BC%88%E6%8A%80%E8%A1%93%EF%BC%89">得意・苦手（技術） - fsubal</a></li>
</ul>
<p>前者の記事は、 React のコアコミッターという「強い」エンジニアの方が、そんな自分でも知らないことはたくさんあるんだよ、という意味で書いたエントリーなので、知識ポートフォリオとは意味合いが異なるのだが、「知らないこと」を真摯に見つめ直すということはとても意義があると思い、常々真似してみたいと考えていた。また、後者の記事も前者の記事も、単に技術の名前をピックアップして「できる」「できない」という話だけをするのではなく、ある程度その判断の根拠を言語化しているので、この点も参考にさせてもらった。</p>
<p>「得意」という言葉を使うのは気が引けるし、つよつよではなくても、自分が業務で使えるレベルであればそれは肯定しておきたかったので、分類は「知っていること」「ある程度知っていること」「知らないこと」の三段階としてみた。自分に知識があると思われる領域を正確に把握しておくことは、生存バイアスの自覚など、心理的な部分にも大いに影響するはずで、軽視したくはない。ちなみにやってみてわかったのだが、どれも完全に書きだそうと思うと際限がないのと、どのレイヤーで書くべきかが悩ましい（RDBMS とするべきか MySQL とするべきか、など）ので、そのあたりは割り切って一旦書いてみている。</p>
<h2>知っていること</h2>
<h3>SRE / DevOps プラクティス</h3>
<ul>
<li>『サイトリライアビリティエンジニアリング』『サイトリライアビリティワークブック』『Lean と DevOps の科学』などを読んで実践を試みている</li>
<li>現状の自身のエンジニアリングの中心課題がここになっている</li>
</ul>
<h3>Terraform</h3>
<ul>
<li>module, for_each, 各種 function などを用いながら記述できる</li>
<li>自動実行のパイプラインを組むことができる</li>
<li>実行エラーや state にまつわるトラブルに一定程度対処できる</li>
<li>terraform-provider-aws に commit 経験がある</li>
<li>同種の他ツール（Pulumi, CloudFormation など）の経験はほとんどない</li>
</ul>
<h3>AWS</h3>
<ul>
<li>Well Architected なプラクティスを理解している</li>
<li>AWS Certified Security - Specialty を取得している</li>
<li>AWS Certified SysOps Administrator - Associate の取得経験がある（expire 済み）</li>
<li>API 体系をある程度把握しており Terraform や CLI を通じて操作できる</li>
<li>EC2, ELB, S3, EKS, ECS, Lambda, Kinesis, CloudFront, SES, SQS, CloudWatch, Aurora, RDS, Elasticache, API Gateway, Cognito, Code series などの経験がある</li>
<li>ただし、まったく知らないサービスも多く、これほど「知っている」と言うのが怖いものもない
<ul>
<li>しかし変に謙遜するのも微妙な気がするのでここに置いた</li>
<li>個々のサービスは置いておいて、 AWS 全体的な管理、運用、利用上のプラクティスを「知っている」の意である</li>
</ul>
</li>
</ul>
<h3>bash</h3>
<ul>
<li>好みはしないが、ある程度複雑化したシェルスクリプトや、長時間稼働のスクリプトをシグナルハンドリングなどを考慮しながら書いたりはできる</li>
<li>awk, sed, cut, tr などを使って標準出力のテキストを編集してごにょごにょする、みたいなことは好きでよくやる (awk, sed は正確には bash の域に含めるべきではないかもしれない）</li>
<li>POSIX 標準で書けとか言われたら無理です</li>
</ul>
<h3>Go</h3>
<ul>
<li>terraform-provider-aws を触ったりしているし、基本的な読み書きはほぼできる、ここ2年ぐらいの OSS commit は半分以上 Go である</li>
<li>自分で何か CLI ツールを作るときなども Go を使うことが多い</li>
<li>Go を専門職とするエンジニアにはどう考えても劣るので、進んで得意と言える気もしてはいないが、一定のレベルには達していると認識している</li>
</ul>
<h3>Linux OS の概念</h3>
<ul>
<li>低レイヤーに詳しくはないが、メモリ、ネットワークIO、ファイルシステム、CPU、ロードアベレージ、プロセス管理など、 Linux OS の運用上把握しておくべき点は把握しており、トラブル時の対応などもできる</li>
<li>Ubuntu の経験が長いが RedHat 系も触れる、それ以外のディストリビューションは趣味で Arch Linux を使っていたのと、 Amazon Linux ぐらい</li>
</ul>
<h3>ネットワーク</h3>
<ul>
<li>プロトコルとしては ssh, http, ssl/tls, tcp, ip, icmp, dns などは概念的に理解している</li>
<li>DNS サーバの設定や権威 DNS の切り替え、 TTL を考慮した設定や運用はできる</li>
<li>TLS をどこで終端させるか、どの範囲を TLS 暗号化するべきかなどは関心が強い領域</li>
<li>IPv6 は理解が薄い</li>
</ul>
<h3>ウェブサービスのインフラ設計、構築</h3>
<ul>
<li>LB を設けて、ウェブサーバを立てて、アプリケーションサーバへリクエストをプロキシして、という一般的なウェブサービスの構成を一通り構築できる</li>
<li>nginx と AWS を用いた場合の経験過多、という偏りは強い</li>
</ul>
<h3>Docker</h3>
<ul>
<li>マルチステージビルドなどを活用しながら Docker コンテナの開発ができる</li>
<li>docker コマンドを一通り使いこなしたり、 <code>docker-compose</code> を使ったりできる</li>
<li>Dockerfile を記述する上でのベスト / バッドプラクティスを知っている</li>
</ul>
<h3>Ansible</h3>
<ul>
<li>一般的な使い方はできる、 Playbook の読み書きはできる</li>
<li>最近はコンテナを使う機会が多く、最新のトレンドなどは把握できていない</li>
</ul>
<h3>ログ管理</h3>
<ul>
<li>fluentd や Amazon Kinesis を使ってログの永続化や各種転送、フィルタリング処理の自動化ができる</li>
<li>構造化ロギングや Twelve Factor App に基づいたロギングプラクティスを理解している</li>
<li>Elastic Stack は Logstash を除いて運用経験があるが、 Elasticsearch の運用はあまり好きではない</li>
</ul>
<h3>システム監視</h3>
<ul>
<li>アプリケーションやソフトウェアに応じた適切な監視設計、設定ができる</li>
<li>Datadog, Nagios, Grafana, influxDB, Hinemos, Mackerel などの構築、運用の経験がある</li>
<li>偽陽性アラートの問題、アラート疲れへの対処、平均、中央値、パーセンタイルなど統計方法の使い分けといったプラクティスを理解している</li>
<li>Prometheus は利用経験がない</li>
</ul>
<h3>CI/CD</h3>
<ul>
<li>ほぼツールの話になってしまうので「知っている」と言っていいのか判断しづらいが、その必要性と実装方法はわかっている</li>
<li>CircleCI、 AWS Code Series、 GitHub Actions の使い方をよく理解している</li>
</ul>
<h2>ある程度知っていること</h2>
<h3>Kubernetes</h3>
<ul>
<li>Pod, Namespace, DaemonSet, ReplicaSet, Service, Deployment など一般的な概念は理解して活用できている</li>
<li>全容が広くてどのレベルまで把握していれば「知っている」と言えるのかの自信がない</li>
<li>EKS などを使っていて、 etcd などコントロールプレーンのコンポーネントは正直きちんと意識はできていない</li>
<li>kubectl, kustomize, helm などを用いたマニフェストの適用、設定、記述などは一通りできる</li>
</ul>
<h3>GitOps</h3>
<ul>
<li>Argo CD と Flux の構築、設定経験がある</li>
<li>CIOps とは異なり、システムの実態と設定とを自律的に sync する仕組みだと認識しており、 CIOps と使い分けることができる</li>
</ul>
<h3>RDBMS</h3>
<ul>
<li>MySQL に関しては構築、設定、ある程度のパフォーマンスチューニングや堅牢性の確保ができる</li>
<li>MySQL 以外の RDBMS は商用運用経験がない</li>
<li>MySQL にしてもそこまで深く理解しているという自覚はなく、300ページの MySQL 本があるとしたら、自分が理解しているのは30ページぐらいだと思う</li>
</ul>
<h3>KVS</h3>
<ul>
<li>redis と memcached の構築、設定経験がある</li>
<li>チューニングなどはほとんど経験がない</li>
</ul>
<h3>CDN</h3>
<ul>
<li>Amazon CloudFront は触っているが他は通じていないので、 CDN という括りだと「知っている」と言っていいのか判断がつかない</li>
<li>書籍『Web 配信の技術』は読んでいるし、ある程度の理解をしているとは思う</li>
</ul>
<h3>mail 関連</h3>
<ul>
<li>POP3, IMAP などのプロトコルと DKIM などの認証技術、 Bounce への対処といった一連のプラクティスは理解し、対策も出来る</li>
<li>とはいえ、それほど問題になる機会が多くなかったりはするので、調べながらじゃないと難しいかも知れない</li>
</ul>
<h3>JavaScript (TypeScript), Python</h3>
<ul>
<li>いずれも Go に次いで書く機会はあり、入門はしていると自覚している</li>
<li>JS はとりあえず文法はわかる、 Node.js や React などメジャーなライブラリがどう使われているかは知っている、という程度で、それぞれに適した形ですぐに書ける、読める、というレベルではない</li>
<li>Python は AWS Lambda 程度でしか使わない</li>
</ul>
<h3>セキュリティ</h3>
<ul>
<li>旧セキュリティスペシャリストの取得経験はある</li>
<li>とはいえアプリケーション開発者ではないので、いわゆる「徳丸本」に書かれているような脆弱性を生まないために、どう気をつけてプログラミングすればいいのか、などはよく知らない</li>
<li>インフラのレイヤーで無駄にポート開放するなとか、暗号化の必要性、適切な権限管理などは理解して実践している</li>
</ul>
<h2>知らないこと</h2>
<h3>SRE、インフラ以外の領域</h3>
<ul>
<li>SRE とインフラエンジニア以外の各 IT エンジニアの領域は基本的にわかっていない</li>
<li>趣味で Ruby on Rails によるウェブサービスを作ったり、 Next.js でブログを作ったりはしているが、業務レベルでそれをこなせる自信はまったくない</li>
</ul>
<h3>マイクロサービス</h3>
<ul>
<li>概念としては知っているが、運用経験はない</li>
<li>よくマイクロサービス（というか分散システム）と付随して語られるサービスメッシュや分散トレーシング、 gRPC なども知らない</li>
</ul>
<h3>GraphQL</h3>
<ul>
<li>REST のように URL でリソースを表現するものではなくて、リクエストに DSL を使う、というぐらいはわかっている</li>
<li>趣味含めて、開発の中で自分で実装をしてみた経験はないし、叩いたこともないかもしれない</li>
</ul>
<h3>低レイヤー</h3>
<ul>
<li>いわゆる OS の低レイヤーにはほとんど触れたことがない</li>
<li>システムコールはいくつか知っているものはあるが、知らないもののほうがほとんどだし、カーネルの知識はない</li>
<li>C言語もまったく知らない、システムプログラミングの経験はない</li>
</ul>
<h3>アルゴリズム</h3>
<ul>
<li>雑学的に知っているものはあるが、業務に活用できたと思う機会はほとんどない</li>
</ul>
<h3>ソフトウェア開発哲学</h3>
<ul>
<li>断片的に SOLID やら何やらを聞いてはいるがちゃんとはわかっていない</li>
<li>Infrastructure as Code のコード設計にも役立つものはあるはずで、すごく「わかりたい」と思っている領域</li>
<li>全貌がよく見えていなくて、どこから手を付けていいのかもよくわからない領域でもある</li>
</ul>
<h3>動画やゲームなど大容量の転送、負荷対策</h3>
<ul>
<li>経験がないので、何が必要なスキルになるのかもわかっていない</li>
<li>単純な負荷対策だけで済まないものと思っている</li>
<li>億単位の RDBMS レコードなども扱った経験がない</li>
</ul>
<h3>データパイプライン、データ分析</h3>
<ul>
<li>パイプラインの構築経験も、データ分析を行ったこともない</li>
</ul>
<h3>HTTP3 / QUIC</h3>
<ul>
<li>どちらも触れる機会がないまま来てしまった</li>
<li>なんなら HTTP/2 すらちゃんと理解していない気がする</li>
</ul>
<h2>今年の展望</h2>
<p>棚卸しをしてみた感想としては Kubernetes と Terraform を除くと、結構古くからの知識で食べている部分が大きい気がした。ネットワークや Linux 、ログ管理のプラクティスなどがすぐに陳腐化することはないので、それはそれでいいのかもしれないが、一方でシステム監視であれば Prometheus exporter にも対応できるようになっておくとか、よりモダンな部分を取り入れて視野を広げていくアプローチも必要かもしれない。</p>
<p>知らないこと、ある程度知っていることに含めたなかでは、業務上 Kubernetes とセキュリティの必要性が高まっているのと、個人的な興味としてはソフトウェア開発哲学まわりが大きい。去年もこのへんやりたいと言いながら、あんまり取り組めた感覚がないので、インプットとアウトプットを集中的かつ効率的に回していく仕組み作りが必要そう。知識ポートフォリオが少しずつ入れ替わっていくような形を目指していきたい。この記事は折りを見て chroju.dev 配下かつブログの外に移して、定期的に更新していこうと考えている。</p>
<p>習慣に落とし込むと、このあたりを意識することとする。</p>
<ul>
<li>技術書の読むスピードを上げる、1冊2週間以内 = 年間24冊が目安
<ul>
<li>ものによっては1週間以内でよい</li>
<li>熟読するより、まずインデックスを脳内に張るために読むことを考えて数をこなせるようにする</li>
</ul>
</li>
<li>インプット自体を増やす
<ul>
<li>勉強会への出席機会が減ってきていたので、増やす</li>
<li>RSS reader でブログを読むことがなくなったので、代替手段を考える</li>
</ul>
</li>
<li>言語化の機会を増やす
<ul>
<li>Scrapbox のメモを1日3page = 年間約1000pageは増やしたい</li>
<li>ブログを2週に1回は書きたい</li>
<li>頓挫してしまった週報は2週間単位で途切れず書くことを目指す</li>
</ul>
</li>
<li>8:30〜12:30 をディープ・ワークの時間にする
<ul>
<li>10:00までプライベートの学び、10:00以降は仕事</li>
<li>プライベートの学びは大学の授業を中心、それがないときは私的なインプットをする</li>
<li>ポモドーロテクニックを使って、 7 pomodoro はこなせるようにしたい</li>
</ul>
</li>
<li>一方で家族や健康は犠牲にしない
<ul>
<li>家族関連のイベントが最優先</li>
<li>ディープ・ワークと仕事を終えたら、だらだら「ながら」で勉強したりしない</li>
<li>BMI が 18 を切っているので、食の見直しと筋トレで体重を 5kg 増やしたい</li>
</ul>
</li>
</ul>
<h2>参考</h2>
<p>知識の棚卸しにあたっては、以下の記事を参考にした。</p>
<ul>
<li><a href="https://roadmap.sh/devops">DevOps Roadmap: Learn to become a DevOps Engineer or SRE</a></li>
<li><a href="https://github.com/cncf/trailmap">cncf/trailmap: 🗺TrailMap files from the cncf/landscape repo</a></li>
<li><a href="https://qiita.com/mogulla3/items/7bf8db3b18980277db52">各社の募集要項からSREに求められるスキルをまとめた - Qiita</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/outlook_and_my_knowledge_portfolio_2022</link>
            <guid isPermaLink="false">outlook_and_my_knowledge_portfolio_2022</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 04 Jan 2022 05:58:42 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Retrospective 2021]]></title>
            <description><![CDATA[<p>振り返りも7年目。過去の振り返りは <a href="https://chroju.dev/blog/tags/retrospective">#retrospective</a> から。</p>
<h2>定量評価</h2>
<p><a href="https://gyazo.com/b5ef90c7d4e80eb8127d61dc2f6d5e6a"><img src="https://i.gyazo.com/b5ef90c7d4e80eb8127d61dc2f6d5e6a.png" alt="Image from Gyazo" width="600"/></a></p>
<ul>
<li>ブログ : 25記事（昨年比 +2）</li>
<li>GitHub Contributions : 445 (-21)</li>
<li>書籍 : 49冊（+12）</li>
</ul>
<p>毎年定量評価としてこのあたりの数値を見ているけど、別に年間通じて追っているわけでもないし、あんまり意味がない気がしてきた。とりあえず今年もまとめてみたけど、まぁそんなにやっぱり変わってないな、というところ。書籍の数は <a href="https://booklog.jp/users/chroju/stats">ブクログの読書記録</a> から引っ張ったが、技術書以外も入っているし、逆に雑誌や電子書籍は含まれないのでザックリ。こちらも毎年40〜50冊ぐらいという肌感がある。</p>
<p>ということで、来年からはこれは見ないかもなぁ、と。 GitHub へコントリビュートすることも、ブログを書くこともそこそこ習慣化したので。いやでも、それが失われないことを確認するのがいいのかもなぁ。健康診断みたいなものかも。正常であることを確認するルーチン。</p>
<h2>定性評価</h2>
<h3>技術領域</h3>
<p>年始頃にこのブログを Next.js で作り直したとき、 <a href="https://jsprimer.net/">JavaScript Primer</a> を読んで JS について学んだりしていた。</p>
<p>また、 Terraform のワークフロー自動化してくれる Atlantis を初めて使って好きになり、 Terraform Advent Calendar にも <a href="https://qiita.com/chroju/items/f77e8391d6ef7c7cb59a">Terraform を自動実行したいなら Atlantis - Qiita</a> という記事を上げた。</p>
<p>今年、新たに手を出した技術領域はそれぐらい。仕事では Kubernetes にずっと取り組んでいるが、ある程度使用技術が固定化されてきたので、それほど今年1年のなかで新たな何かに手を出した、というものはなかった。 Kubernetes と AWS と Terraform が軸、という感じになっている。</p>
<p>何冊か本は読んでいて、このあたり面白かった。</p>
<p>https://www.amazon.co.jp/-/en/Heather-Adkins/dp/1492083127</p>
<p>https://www.amazon.co.jp/-/en/%E7%94%B0%E4%B8%AD-%E7%A5%A5%E5%B9%B3/dp/4297119250</p>
<h3>SRE / DevOps</h3>
<p>SRE としては、常に「何をするべきか」を考えながらずっと従事してきていて、2021年はそれなりの答えがまとまってきた。が、かなり業務内容に沿った話になるので、ここでは書かずに <a href="https://note.com/globis_engineers/">会社のテックブログ</a> に書けたらな、と思っている。</p>
<p>SRE としての活動を定量的に計測、評価していくことへの関心が今は高くて、本としてはこのへんを読んでいた。</p>
<p>https://www.hanmoto.com/bd/isbn/4295004901</p>
<p>https://www.amazon.co.jp/-/en/Alex-Hidalgo/dp/1492076813</p>
<h3>ソフトスキル</h3>
<p>いわゆるリーダースキルとか。</p>
<p>2020年にチームリーダーの立場になり、今年も引き続きこの分野は暗中模索していた。昨年の振り返りで、インプットがこちらに偏りすぎたので2021年は技術のほうへ傾けたいと書いていたが、結局今年もこちらのインプットが多くなった。そのわりに考えをまとめてブログなどに書けていないのは反省点。記事としては <a href="https://chroju.dev/blog/what_is_coaching">思考のリファクタリングとしてのコーチングの技術 - the world as code</a> ぐらい。</p>
<p>先述したように技術的なチャレンジが今年ちょっと控えめになってしまったのもあるので、一度きちんと考えをまとめてアウトプットして、来年は本当に技術側に傾けたい。将来的にマネジメント方向なのか、テック方面でスペシャリスト方向なのか、という二者択一というより、 SRE という職種は双方バランスよくおさめる必要があると思っている。</p>
<p>あと宣伝ではないんだけど、今勤めている会社が社会人教育を事業としているので、ソフトスキル方面の学習リソースが社内に豊富にあって、助かっている。逆に言えば、それに「あてられて」こちらを重視している向きもなくはない。</p>
<h3>プライベート</h3>
<p>取り立てて書くことはなく、2020年の延長戦のような1年だった、という感覚が強い。旅行も去年と同じで1回だけ、あとは気晴らしで近隣のホテルに泊まるぐらいだし、映画、ライブ、美術館博物館のような外出による娯楽も相変わらず少ないままとなっている。健康面も特に問題ない感じ。</p>
<p>来年はさすがに意識的な変化をつけていかないと、いろいろな面で保守的になってしまいそうでこわい。</p>
<h2>やってよかったこと</h2>
<p><a href="https://chroju.dev/blog/best_buy_subscriptions_2021">今年買ってよかったものと、今年のサブスク 2021 - the world as code</a> に書いた、珈琲豆を手で挽くのと、 nosh は取り入れてよかったです。</p>
<h3>Pixela による習慣化</h3>
<p>GitHub の芝のようなビジュアルデータを簡単に作れる API サービス <a href="https://pixe.la/ja">Pixela</a> というものがあるが、習慣化をする上でとてもよくて今年いろいろ工夫して使っていた。</p>
<p>GitHub のそれが、 Contirubution 回数を記録してくれるのと同様、いつ、何回その行動をしたのかを記録するのにちょうどいい。そして記録を自動化できると尚良し、と考えている。 Pixela は webhook を叩くことで、その日のカウントがインクリメントされるというシンプルな使い方ができるので、自動記録も組みやすい。</p>
<img src="https://pixe.la/v1/users/chroju/graphs/phone-open.svg">
<p>例えばこれはスマホを開いた回数の記録。 <a href="https://play.google.com/store/apps/details?id=ch.rmy.android.http_shortcuts&#x26;hl=en_US&#x26;gl=US">HTTP Request Shortcuts</a> と <a href="https://play.google.com/store/apps/details?id=com.arlosoft.macrodroid&#x26;hl=en_US&#x26;gl=US">MacroDroid</a> を組み合わせて、スマホを開いたときに自動的に webhook を叩くように設定した。デジタルデトックスの一環で、徐々にこの芝の色が薄くなればと考えている。 iOS であれば、「ショートカット」を使って同様のことができると思う。</p>
<p>macOS も Monterey になってショートカットが使えるようになったので、記録できるものは増えたのではないかと思う。来年はさらに習慣化のために活用していきたい。なるべく、生活に必要なものを「習慣」にまとめてシンプルにしていきたい。</p>
<h3>週報</h3>
<p><a href="https://chroju.dev/blog/journal_with_notion">読んだ記事などを「週報」として notion にまとめ始めた - the world as code</a> に書いた通り、週報を書く試みを始めた。今のところ頓挫してしまってはいるんだけど、やろうとしたことは間違っていなかったと思うので再開したい。書く内容を少し減らしたほうがいいのだと思う。</p>
<p>今これを書いていても感じているが、年間など長いスパンで振り返るのは急にできるものでもなくて、週間、月間などそれなりの短いスパンで振り返り、立て直しを図っていくことは習慣化していきたい。</p>
<h3>Slack で Release Note を読む</h3>
<p><a href="https://gyazo.com/1d6cd8f45eda88b4fc81e7d209618b5c"><img src="https://i.gyazo.com/1d6cd8f45eda88b4fc81e7d209618b5c.png" alt="Image from Gyazo" width="600"/></a></p>
<p>RSS Reader を通勤中の電車内で読む、という習慣がすっかりなくなってしまったのだが、使っている OSS などの Release Note ぐらいはちゃんと押さえておきたくて、確実に目に入る場所として Slack に流すことにした。自分1人用の workspace を設けているので、そこに GitHub Release や各種ブログの RSS を流している。 Google Calendar の予定なども流しているので、朝にその日の予定と、夜の間に出たリリースを眺めたりできてなかなかよい。</p>
<h2>来年について</h2>
<p>まだあんまり考えてないのだが技術〜〜〜って思っている。セキュリティ、 Cloud Native 関連、ソフトウェアデザインあたりに課題感が強い。特に Cloud Native は使っているわりにあん〜〜〜〜まり追えてないので、ちゃんと追っかけることをまずは始めていく。</p>
<p>なかなか時間を無限に使えるという感じでもなくなってきたので、限られた時間に集中して多量にインプットしていくようなスキルを身につけたい。</p>
<p>もうちょい具体的な目標とかは、また年明けたら考えます。</p>
]]></description>
            <link>https://chroju.dev/blog/retrospective_2021</link>
            <guid isPermaLink="false">retrospective_2021</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 31 Dec 2021 06:28:34 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[今年買ってよかったものと、今年のサブスク 2021]]></title>
            <description><![CDATA[<p>とりあえず書いてはみるものの、今年あんまり買い物してないです。昨年以前は <a href="https://chroju.dev/blog/tags/best-buy">#best-buy</a> と <a href="https://chroju.dev/blog/tags/subscription">#subscription</a> それぞれのタグからどうぞ。</p>
<h2>今年買ってよかったもの</h2>
<h3>TIMEMORE C2</h3>
<p><a href="https://gyazo.com/d5c3c3cb5ee8b38e28eb7bc95a9847c8"><img src="https://i.gyazo.com/d5c3c3cb5ee8b38e28eb7bc95a9847c8.jpg" alt="Image from Gyazo" width="400"/></a></p>
<p>コーヒーグラインダー。これを選んだ契機はあまり覚えていない。</p>
<p>コーヒーは長いこと電動ミル付きのコーヒーメーカーで淹れていたのだけど、コロナ禍で家にいる時間が長くなり、少しコーヒーにもこだわってみようかと思い始めて購入。初めて買ったグラインダーなので、他と比べての良し悪しとかはまったくわからないけれど、特に不便なく使えている。もっと力が要るものかと思っていたが、かなり小さな力で1分もかからずに挽き切れるので手軽。表面に凹凸があって、握ったときに滑りにくく、だいたいいつもキッチンで立ったままゴリゴリと挽いている。仕事中の気分転換にもなっていい。</p>
<p>他にもフィルター、ドリッパーなど「コーヒー沼」を構成する要素はいろいろあるらしいけれど、そこには至らず、現状「豆を挽く」という行為だけで一定満足できている。豆はよく行くカフェで買うことが多い。</p>
<h3>MOONBAT urawaza</h3>
<p>https://www.amazon.co.jp/-/ja/Moonbat-Urawaza-Folding-Umbrella-Seconds/dp/B085PW4BDM</p>
<p>『マツコの知らない世界』で紹介されていた折り畳み傘。定期的に見るテレビ番組ができた、というのもコロナ禍の結構大きな変化。</p>
<p>「3秒で折りたためる傘」というのが売り文句で、本当にその通り3秒で折りたためる。ポイントとしては開閉ボタンが付いているのが1つ、もう1つは傘の布部分が形状記憶になっているので、ひだの1枚1枚を整えたりしなくても、巻き付ける紐部分を持ってくるっと1周させるだけで形が整うということ。少し大きくて重いのが難点ではあるが、仮にこの傘が壊れてもまた同じのを買うと思う。ちなみに Amazon レビューを見ると「耐久性に難あり」という話が多いが、リモートワークも手伝って使用回数が少ないので、まだなんとも。</p>
<h3>AfterShokz OpenComm</h3>
<p><a href="https://gyazo.com/0fe004676e68840e5863ac229f85fc92"><img src="https://i.gyazo.com/0fe004676e68840e5863ac229f85fc92.jpg" alt="Image from Gyazo" width="400"/></a></p>
<p>骨伝導ヘッドセット。</p>
<p>ヘッドセットはコロナ禍でリモートワークがメインになってすぐ、2020年4月に <a href="https://www.poly.com/jp/ja/support/product/voyager-3200">Voyager 3200</a> を買って使っていたのだが、自分の環境が何か悪いのか、どうも接続不良が多くて買い替えることに。 Twitter の TL でも、会社の Slack でも AfterShokz の評判をよく聞いていたので、マイク付きのこのモデルにした。</p>
<p>接続の問題もなくなったし、耳穴を塞がないことがこれほど快適とは思わなかったという具合で、とても気に入っている。ただ、耳は疲れないのだが、こめかみのあたりを両側から押さえつけるような形で装着するので、その部分が3時間もするとちょっと痛くなってくることがある。痛くない日もあるので、装着の仕方が悪いのかもしれない。</p>
<p>ちなみに、今年買ったリモートワーク関連のガジェットはこれぐらい。あと何か買うとしたら電動昇降デスクとかになりそう。</p>
<h3>Bellroy Classic Backpack</h3>
<p>https://ja.bellroy.com/products/classic-backpack</p>
<p>ベストなバックパックってずっとわからずにいる。 PC を持ち運ぶには絶対バックパックを使いたいマンなんだけど、かと言って大きすぎるのは嫌だったり、でも薄マチすぎてペットボトルも入らないようだとさすがに辛かったり、一方で腰に優しい感じのがいいなぁとか、ああでもこうでもないという感じで1〜2年おきに買い替えている。</p>
<p>今年の始めに買ったのがこれで、今のところはここから乗り換えたいなぁという気分にはなっていない。そこそこ厚みは薄いけれど、入れようと思えばペットボトルとオライリー1冊と PC ぐらいは全然入る。PC は背中側に設けられたスリーブに入れるようになっている上、背中に当たる部分が硬質な素材のランバーサポートになっているので、重い PC は常に背中へ密着した状態をキープできて、重さを感じにくくなっている。それでいてあまり無骨なデザインではなく、休日にも使いやすいのがいい。</p>
<h3>ジップロック ごはん保存容器 一膳用</h3>
<p>https://www.amazon.co.jp/-/en/Ziploc-Container-Storage-Pieces-Packs/dp/B07KWGYRMJ</p>
<p>地味なところで。冷凍ごはんは生まれてこのかたラップで適当に包むだけだったのだが、これを買ったところだいーぶ体験が改善した。一包みの分量が一定に保てるし、水分が適度に保たれるようで味も良くなった。</p>
<h2>Subscriptions</h2>
<p>例年通り差分にて掲載。</p>
<pre><code class="language-diff">  * Day One (¥2,800 / year)
  * MoneyForward プレミアム会員 (¥500 / month)
- * Nintendo Switch Online (¥2,400 / year)
+ * Nintendo Switch Online + 追加パック (¥4,900 / year)
  * Amazon Prime Student (¥2,450 / year)
  * Spotify Premium Student (¥480 / month)
  * シネマシティ (¥1,000 / year)
  * Dynalist Pro ($7.99 / month)
  * dアニメストア (¥400 / month)
- * freee (¥1,980 / month)
  * メールマガジン「読書日記／フヅクエラジオ」 (¥800 / month)
  * ATOK Passport (¥300 / month)
  * IFTTT Pro ($1.99 / month)
  * Association for Computing Machinery ($99 / year)
+ * Netflix (Standard) (¥1,490 / month)
</code></pre>
<p><a href="https://www.nintendo.co.jp/hardware/switch/onlineservice/index.html">Nintendo Switch Online</a> は 64 が遊びたくて「追加パック」に乗り換えた。子どもの頃に買って欲しかったけど買ってもらえなかった未練の代表格だったので。64 が。とりあえず『ゼルダの伝説 時のオカリナ』『ムジュラの仮面』はクリアしたくて、その後2年目どうするかは追加ソフトと相談かな。一気に倍額になっているけれど、まぁ1か月換算で500円にも満たないので十分許容範囲かなぁ、というところ。</p>
<p><a href="https://www.netflix.com/jp/">Netflix</a> は <a href="https://godzilla-sp.jp/">『ゴジラ S.P』</a> が観たくて加入。その後1回脱退して、『ブルーピリオド』と『カウボーイビバップ』実写版が観たくて再加入して今に至る、という感じ。退会するときに引き留めるような UX が全然なくて、戻ってきた時に「おかえり！」って言ってくれるのがとても好感している。見たいものがあるときに入ってね、というスタンスのようなので、今後もそういう感じで付き合おうと思う。『TIGER &#x26; BUNNY 2』が見たいのでとりあえず来年6月ぐらいまでは継続になりそう。</p>
<p>freee は業務委託がなくなったので、有料会員をやめた。</p>
<h3>番外 : nosh</h3>
<p><a href="https://gyazo.com/ebc3f49f380ad9f7014a810c0de45bf1"><img src="https://i.gyazo.com/ebc3f49f380ad9f7014a810c0de45bf1.jpg" alt="Image from Gyazo" width="400"/></a></p>
<p>厳密にはサブスクではないが <a href="https://nosh.jp/">nosh</a> を今年から取り入れた。ヘルシーな冷凍宅食サービスで、2週間に1回などのスケジュールを組んで配送してもらい、配送のたびに料金が発生するのでサブスクではない。</p>
<p>うちは2人暮らしの共働きリモートワークが1年以上続いていて、昼食は双方とも短い昼休みで作るモチベーションはなく、かと言って買いに行くのもだんだんバリエーションがなくて飽きてきた、というところに上手くはまった感じ。冷凍庫サイズの限界もあって、2週間に1回6食を届けてもらうスローペースではあるんだけど、今日はちょっと忙しいなとか、雨で買いに行きたくないなというときにサッと使えるジャンクではない選択肢、としてはこれぐらいで十分だったりする。味も良くて、毎回いろんなメニューを試して楽しんでいる。</p>
<p>難点があるとすれば、本当にヘルシーで、ものによっては 200 kcal 程度だったりすること。僕は元来太りにくい体質なので、これだと摂取カロリーさすがに足りなさすぎて BMI がゴリゴリ減る時があり、間食や夕食で調整したりすることもある。ちなみに一番好きなメニューは「鶏モモ肉のディアブル」……だったんだけど、今見たら終売していて悲しくなった。「飽き」を防ぐためなんだろうけど、結構ローテーションがあって好きなメニューが消えることもあるのがちょっとつらい。でも、それを補ってメニューの種類がかなり豊富なので、「食べたいものがない！」なんてことにはならないのがよいところ。</p>
]]></description>
            <link>https://chroju.dev/blog/best_buy_subscriptions_2021</link>
            <guid isPermaLink="false">best_buy_subscriptions_2021</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 27 Dec 2021 10:19:14 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[re:Invent 2021 で個人的に気になったもの]]></title>
            <description><![CDATA[<p><a href="https://aws.amazon.com/jp/about-aws/events/2021/reinvent/">AWS re:Invent 2021</a> で発表されたうち、個人的に気になった内容のメモ。ザックリ読んで、後で触れたい、業務で使えそうと思ったものをサッとメモしただけなので内容の正確性は微妙かも。網羅性と正確性を求める場合は DevelopersIO あたりを読みましょう。</p>
<p>全体的に派手なリリースはそれほど多くはないものの、地味に嬉しいものとか、サービス間の関係性が適切に見直されたものが多かったかな、という印象。</p>
<h2>ECR Public + Docker Hub</h2>
<ul>
<li><a href="https://aws.amazon.com/jp/blogs/containers/docker-official-images-now-available-on-amazon-elastic-container-registry-public/">Docker Official Images now available on Amazon Elastic Container Registry Public | Containers</a></li>
<li><a href="https://aws.amazon.com/jp/blogs/aws/announcing-pull-through-cache-repositories-for-amazon-elastic-container-registry/">Announcing Pull Through Cache Repositories for Amazon Elastic Container Registry | AWS News Blog</a></li>
</ul>
<p>ECR 関連で2つ発表されていて、1つは Docker Hub 上の Docker Official Images が ECR Public からダウンロードできるようになったというもの。 ECR Public は AWS ネットワーク内からダウンロードする分には制限がないので、 Docker Hub のダウンロード制限をこれで回避できる。</p>
<p>2つ目は Pull Through Cache Repositories。 Public なコンテナイメージレポジトリと、 ECR private を同期して、 ECR private の機能を用いてパブリックイメージを管理できるようになるというもの。例えば Private Link を介してイメージをダウンロードしたり、 ECR private の脆弱性検査の機能を使ったりなど。対応しているのは ECR Public だけではなく、ローンチ時点で Quay.io も扱える。で、 ECR Public には Docker Official Images も同期されているので、実質 Docker Hub も一部対応しているような形になった。</p>
<h2>Amazon S3 Event Notifications with Amazon EventBridge</h2>
<p><a href="https://aws.amazon.com/jp/blogs/aws/new-use-amazon-s3-event-notifications-with-amazon-eventbridge/">New – Use Amazon S3 Event Notifications with Amazon EventBridge | AWS News Blog</a></p>
<p>S3 の Event Notification は従来バケットの設定の中に組み込まれていたけど、これが EventBridge で設定できるようになった。</p>
<p>これ、管理の面で結構嬉しくて、というのも Event Notification は何と言うのか、1個のオブジェクトのようなもので、1つのバケットに対して複数の通知を設定する場合でも Terraform でこういう書き方になる。</p>
<pre><code class="language-hcl">resource "aws_s3_bucket_notification" "bucket_notification" {
  bucket = aws_s3_bucket.bucket.id

  lambda_function {
    lambda_function_arn = aws_lambda_function.func1.arn
    events              = ["s3:ObjectCreated:*"]
    filter_prefix       = "AWSLogs/"
    filter_suffix       = ".log"
  }

  lambda_function {
    lambda_function_arn = aws_lambda_function.func2.arn
    events              = ["s3:ObjectCreated:*"]
    filter_prefix       = "OtherLogs/"
    filter_suffix       = ".log"
  }

  depends_on = [
    aws_lambda_permission.allow_bucket1,
    aws_lambda_permission.allow_bucket2,
  ]
}
</code></pre>
<p>この密結合な感じがすごく嫌だったんだけど、 EventBridge であれば1つずつ切り離して別々に設定を書けるはず、と認識している。</p>
<h2>New Amazon Inspector</h2>
<p><a href="https://aws.amazon.com/jp/blogs/aws/improved-automated-vulnerability-management-for-cloud-workloads-with-a-new-amazon-inspector/">Improved, Automated Vulnerability Management for Cloud Workloads with a New Amazon Inspector | AWS News Blog</a></p>
<p>Amazon Inspector に新しい機能がかなり盛り込まれた。</p>
<p>Automated Discovery を有効化すると、EC2 と ECR repository を自動で検知して脆弱性を検査してくれる。 ECR にはもともと脆弱性検査機能はあったわけだが、 Inspector と連携すると <a href="https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning-enhanced.html">Enhanced Scanning</a> が使えるようになり、プログラミング言語のパッケージもスキャンできるようになる（ただしこちらは有料）。まぁアプリケーションの脆弱性スキャンはアプリケーションレポジトリ + GitHub Code Scanning とかでもっと早い段階でスキャンしていたりするだろうとは思うものの。</p>
<p>他にも Security Hub との連携、 AWS Organizations との連携などなど追加要素はかなり多い。</p>
<h2>AWS Mainframe Modernization</h2>
<p><a href="https://aws.amazon.com/jp/about-aws/whats-new/2021/11/introducing-aws-mainframe-modernization/">Introducing AWS Mainframe Modernization</a></p>
<p>これは使う予定のない完全な興味。</p>
<p>オンプレのメインフレームのワークロードを AWS へ移行できるらしい。自分が業務でメインフレームに触れる機会は今後なさそうだが、ついに AWS もここに手を出すのか、という感慨深さがある。ざっとしか読んでいないけど、おそらく z/OS などがクラウドで動きますよ、という話ではなくて、メインフレームで動かしている COBOL などを AWS で動かすためのあれこれ、みたいなものっぽい。</p>
<h2>S3 Glacier Instant Retrieval</h2>
<p><a href="https://aws.amazon.com/jp/about-aws/whats-new/2021/11/amazon-s3-glacier-instant-retrieval-storage-class/">Announcing the new Amazon S3 Glacier Instant Retrieval storage class - the lowest cost archive storage with milliseconds retrieval</a></p>
<p>ミリ秒単位でデータ取得が可能でありながら、標準IAよりは安価に保存が可能な Glacier の新たなストレージクラス。標準IAもミリ秒単位で取得可能なので、ならば標準IAと Glacier Instant Retrieval との違いはどこ？とちょっと疑問なのだが、おそらくデータ取り出し時の料金にコストが跳ねていると思われる。記事執筆時点で Pricing にまだ反映されていないので未確認。</p>
<p>これに伴い、既存の Glacier と呼ばれていたストレージクラスは Glacier Flexible Retrieval に名称変更。ここまで細かくストレージクラスが分かれる必要あるのかは若干疑問だけど、選択肢があるのはいことかな。</p>
<h2>Control Tower が Terraform から操作可能に</h2>
<p><a href="https://www.hashicorp.com/blog/hashicorp-teams-with-aws-on-new-control-tower-account-factory-for-terraform">HashiCorp Teams with AWS on New Control Tower Account Factory for Terraform</a></p>
<p>AWS アカウントの管理ではあんまり Terraform の出番がなかったのでこれは嬉しい。</p>
<h2>AWS Backup for Amaozon S3</h2>
<p><a href="https://aws.amazon.com/jp/about-aws/whats-new/2021/11/aws-backup-amazon-s3-backup/">Announcing preview of AWS Backup for Amazon S3</a></p>
<p>AWS Backup が S3 に対応、バケットのスナップショットを取得できるようになったとのこと。 S3 に保存したデータが消える心配はあまりしていないのだけど、本当に重要なものは別クラウドのオブジェクトストレージにコピーしたりしていたので、これが代わりになるかな？</p>
<h2>Amazon DevOps Guru for RDS</h2>
<p><a href="https://aws.amazon.com/jp/about-aws/whats-new/2021/12/amazon-devops-guru-rds-ml-powered-capability-amazon-aurora/">Announcing Amazon DevOps Guru for RDS, an ML-powered capability that automatically detects and diagnoses performance and operational issues within Amazon Aurora</a></p>
<p>Amazon Aurora のパフォーマンスの問題などを自動的に解析してくれるらしい。</p>
<h2>Sustainability Pillar for the AWS Well-Architected Framework</h2>
<p><a href="https://aws.amazon.com/jp/about-aws/whats-new/2021/12/new-sustainability-pillar-aws-well-architected-framework/">New Sustainability Pillar for the AWS Well-Architected Framework</a></p>
<p>Well-Architected Framework にサステナビリティの柱が新たに追加された。 Well-Architected Framework 、全体を何年か前にザッと読んだっきりになって更新も追えてないので年末とかに読もうかな。</p>
<h2>IP Address Manager</h2>
<p><a href="https://aws.amazon.com/jp/about-aws/whats-new/2021/12/amazon-virtual-private-cloud-vpc-announces-ip-address-manager-ipam/">Amazon Virtual Private Cloud (VPC) announces IP Address Manager (IPAM) to help simplify IP address management on AWS</a></p>
<p>VPC の IP アドレスを GUI で効率的に管理できるサービス。最初に IP のプールを <code>/8</code> の下に <code>/16</code> をいくつか、みたいな感じで具体的なセグメントを切りつつ作っておいて、それを VPC に割り当てる、という形で使えるらしい。このあたりは確かに Excel とか Notion Database とか使って管理していたので、 AWS の中で完結できると地味に良さそう。 IP の割当状況とかも見られるらしい。枯渇しそうになったらアラート上げるとかできるかな。</p>
<h2>Disalbe S3 access control list</h2>
<p><a href="https://aws.amazon.com/jp/about-aws/whats-new/2021/11/amazon-s3-object-ownership-simplify-access-management-data-s3/">Amazon S3 Object Ownership で、S3 内のデータのアクセス管理をシンプル化するためのアクセスコントロールリストの無効化が可能に</a></p>
<p>S3 の ACL を無効化して使わないようにできるらしい。ちょっと笑った。</p>
<p>確かに現状では ACL で出来ることはバケットポリシーでほぼ代替できるので、基本的には使わないものだし、無効化してしまったほうが認知負荷の観点でシンプルになるのはすごくわかる。一方で歴史的経緯から機能自体を廃止はできないのだと想像。これはよい落とし所だと思うし、案外神アプデでは。</p>
<h2>AWS re:Post</h2>
<p><a href="https://aws.amazon.com/jp/blogs/aws/aws-repost-a-reimagined-qa-experience-for-the-aws-community/">AWS re:Post – A Reimagined Q&#x26;A Experience for the AWS Community | AWS News Blog</a></p>
<p>こういう言い方で正しいかわからないけど、 teratail の AWS 版的な認識。 AWS の Forum って確か従来もあったと思うけど、あんまり GitHub Issue ほど活発で活用できるような感覚がなかったし、 Community として知見が集まってくると嬉しいかも。</p>
]]></description>
            <link>https://chroju.dev/blog/re_invent_2021</link>
            <guid isPermaLink="false">re_invent_2021</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 05 Dec 2021 11:30:45 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Alfred で書籍を検索する Workflow を作った]]></title>
            <description><![CDATA[<p>書籍を紹介するとき、つい Amazon の URL を使ってしまうのだが、購入先に関してなるべく中立でありたいという思いもあり、できれば <a href="https://hanmoto.com/">版元ドットコム</a> を使いたい、と常々思っていた。しかし、なかなか書籍名でウェブ検索をかけても版元ドットコムのページは上位に出てこなくて忘れてしまうので、書籍を検索する Alfred Workflow を作った。</p>
<h2>版元ドットコムとは</h2>
<p><a href="http://www.hanmoto.com/about_hanmotodotcom">版元ドットコムとは | 版元ドットコム</a> に詳細は譲りたいが、版元 = 出版社が寄り集まって作っている団体と、その団体が作っているウェブ上の書籍データベースを指す。</p>
<p>参加していない版元による書籍については、当然ながらデータが存在しないし、また検索機能があるものの、それほど強力ではない（例えばアルファベットはケースセンシティブで検索されるっぽい）など弱点も見受けられる。が、サイト内に直接的な購入導線がなく、その点で中立的な書籍データベースとして利用できる。</p>
<h2>workflow の構成</h2>
<p><a href="https://gyazo.com/fbdc2befca2917f48eda6aaf13cd8871"><img src="https://i.gyazo.com/fbdc2befca2917f48eda6aaf13cd8871.png" alt="Image from Gyazo" width="640"/></a></p>
<p>書籍検索の API を叩いて書籍を探し、確定したらそこから ISBN-10 を抽出して <code>https://www.hanmoto.com/bd/isbn/$ISBN</code> に渡して開いている。同様に ISBN を URL に渡すことで書籍のページを開ける、 Amazon.co.jp と <a href="https://booklog.jp/">ブクログ</a> にも対応させている。</p>
<p>また、書籍の情報を参考文献のフォーマットでコピーできる機能も用意した。これは大学でレポートを書く上で以前から欲しいと思っていた機能。例えば <a href="https://www.hanmoto.com/bd/isbn/4873117917">『SRE サイトリライアビリティエンジニアリング』</a> をコピーすると、 <code>Betsy Beyer, Chris Jones, Jennifer Peto, Niall Murphy (Sky株式会社 玉川 竜司 訳) . SRE サイトリライアビリティエンジニアリング. オライリー・ジャパン, 2017, 592p.</code> となる。</p>
<p><a href="https://gyazo.com/8e395ffd192dff934fe710f770ea4902"><img src="https://i.gyazo.com/8e395ffd192dff934fe710f770ea4902.gif" alt="Image from Gyazo" width="600"/></a></p>
<h2>書籍検索API</h2>
<p>書籍情報を検索できる API はいくつか存在しており、今回3つほど試したがどれも一長一短だった。1つ目は版元ドットコムとカーリルが共同で提供している <a href="https://openbd.jp/">openBD API</a> 、2つ目は <a href="https://developers.google.com/books/">Google Books APIs</a> 、3つ目は <a href="https://webservice.rakuten.co.jp/document/">楽天ブックス系API</a> 。</p>
<h3>openBD API</h3>
<ul>
<li>GET は ISBN 指定でしかできない（検索の機能はない）</li>
<li>書誌情報は版元ドットコムによるものと JPRO によるものの2つが同梱されており、充実している
<ul>
<li>JRPO の書誌情報は独特のフォーマットであり、 http://jpo.or.jp/topics/data/20160113a_jpoinfo.pdf で仕様を確認できる</li>
</ul>
</li>
<li>認証は不要</li>
</ul>
<h3>Google Books APIs</h3>
<ul>
<li>検索と、 Google Books 内での ID 指定による get に対応</li>
<li>書誌情報は充実しているが、難あり
<ul>
<li>ISBN など基本的な項目含めてアトランダムに「抜け」が見られる</li>
</ul>
</li>
<li>認証は不要</li>
</ul>
<h3>楽天ブックス系API</h3>
<ul>
<li>各種パラメータ（書名、著者、ISBNなど）指定により GET を行い、複数マッチすれば複数の書籍情報が返る</li>
<li>書誌情報は比較的充実しているが、難あり
<ul>
<li>ISBN-13 が振られている場合、 ISBN-10 の情報は抜けている</li>
<li>著者名の姓名分かち書きなどに統一性がない</li>
</ul>
</li>
<li>和書、洋書で API が分かれている</li>
<li>認証が必要</li>
</ul>
<p>結論としては Google Books APIs を使うことにした。 openBD は検索ができない時点で用途に見合わず、楽天は和書、洋書の一括検索ができない、 ISBN-10 が取得できない場合があるなど、難が多かった。 Google については ISBN がそもそも取得できないという大きな欠点もあるものの、一旦そのような書籍は検索結果から除外する形で妥協している。</p>
<h2>Conclusion</h2>
<p><a href="https://www.hanmoto.com/bd/isbn/4167910195">円城塔『プロローグ』</a> にこんな一節がある。</p>
<blockquote>
<p>なんでも良いがいい加減このくらいの代物は、出典の URL を明記できるくらいの形でどこかに公的なテキストデータとして蓄えておいてもらいたい。『古事記』だよ。勘弁してよ。 (p.17)</p>
</blockquote>
<p>今回、いくつかの書籍情報 API を調べて、なかなかこれといったものがなく悩んでいた際に、この一節を思い出した。書籍情報の絶対的なパーマリンクが欲しい。いつかこのあたり、仕事で少し噛めたらな、とはちょっと思っている。</p>
<p>それはそれとして、Alfred Workflow をサッと作れるようになっておくとやはり便利だな、ということを改めて感じた。この Workflow は完全に個人的なものなので、以下のリンク先で公開してはいるが、 PR などを受け付けるつもりはない。 ISBN で URL を開けるようなサイトなら、 Amazon やブクログ以外にも応用可能と思うので、もし自分なりに使いたいという方がいたら fork してみてほしい。</p>
<p>https://github.com/chroju/alfred-book-search</p>
]]></description>
            <link>https://chroju.dev/blog/alfred_book_search</link>
            <guid isPermaLink="false">alfred_book_search</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 15 Nov 2021 14:28:47 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[思考のリファクタリングとしてのコーチングの技術]]></title>
            <description><![CDATA[<p>コーチングとは、ざっくりした定義だと「対話によって個人の目標達成を支援する、人材開発手法の1つ」とされる。</p>
<p>初めてこの概念に出会ったのは『<a href="https://www.hanmoto.com/bd/isbn/4478069786">ヤフーの1on1</a>』を通してで、この本では 1on1 における相手への働きかけを、ティーチング、コーチング、フィードバックの3つに分類している。ティーチングは相手に知識を「教える」ものであり、フィードバックは評価などを「伝える」ものであるのに対し、コーチングは相手の中にある考えや思いを「引き出す」ものとされる。相手が何か課題を抱えている際に、その答えとなるアドバイスを直接話してしまうのではなく、相手の中で思考を進める支援をして、自ら回答を導く、あるいは自らが本当に考えていることを気付かせるよう促すのが「コーチング」と呼ばれる。</p>
<p>今回、コーチングに興味を持って4冊ほど本を読んでみた。動機としては、自分自身「上司」の立場で 1on1 を行うにあたり、この手法のなんたるかを知っておいたほうがいいと思ったからだ。</p>
<p>また、コーチングの手法を自分自身に応用し、自らの成長に役立てる「セルフコーチング」という概念も存在する。僕は目の前の仕事をこなしたり、自分の立場で求められることを考えて実践するのはある程度得意だが、自分自身が何をしたいのか、5年後どうなりたいのかと言ったことを考えたり言語化するのはあまり得意ではない。コーチングにおける「思考を進める」「自分自身の本当の考えに気付く」という方法論は、こういった自分の弱点克服に役立つのではないかと考えた。</p>
<h2>改めて、コーチングとは何か</h2>
<p>ところでいろいろと調べてはみたものの、具体的にコーチングはこれだ！と一言で言えるものではなく、捉えどころが難しい。</p>
<p><a href="https://research.lightworks.co.jp/coaching-roots">コーチングの不都合な真実　それは信念なのか、それとも科学なのか？</a> という記事によれば、アメリカでコーチングが登場してからまだ30年程度だそうで、様々な流派が存在しており、実際のところ何か明確な定義があるわけでもないらしい。最初に書いた「対話による」「人材開発」という点は共通していると思われるが、そこで具体的に何を話すのか、どういった手法が用いられるのかは、流派によるのだと思う。</p>
<p>したがって、ここで書く内容は、あくまで僕が読んだ4冊から抽出した内容に過ぎず、これ以外の方法論も存在しているという点は予め書き記しておく。</p>
<h2>コーチングの過程</h2>
<p>目標の明確化、現状分析、ギャップの調整という三段階を辿るのが基本とされる。</p>
<p>目標を達成する、成長を支援するならば、その行く先たる目標をまず明確化する必要がある。それも、会社から求められているような have to の目標ではなく、自分が本当にやりたいことをまず探し出すところからコーチングは始まる。</p>
<p>その後、現状を分析した上で、現状と目標との間にあるギャップをどう埋めていくか考え、調整していくのが一連のコーチングプロセスにあたる。</p>
<h2>コーチングは対等な関係で行う</h2>
<p>字面からして上下関係を想像してしまいがちだが、コーチングは対等な関係で行うものであり、そこに上下の別はない。コーチングを受けたい一方が、自分の悩み、課題をまず言語化して客体化し、それに2人で向き合うような形で進めるのが理想とされる。</p>
<h2>具体化していく、考える材料を多く出す</h2>
<p>冒頭に書いた「考えを引き出す」にあたっては、できるだけ多く、具体的に自分の考えを言語化していく必要がある。</p>
<p>コーチングの前提となる考えに、人間は自分が本当に考えていることを自覚していない、という点がある。体面、世間体、社会性などを理由に取り繕ったことを話してしまうということもあるし、言語化していない思考には自分でも気付けないことがある。ソフトウェアエンジニアリングの界隈で言えば、「ラバーダック・デバッグ」や「壁打ち」を想像するとわかりやすい。</p>
<p>また、ある程度具体的な経験をピックアップしなければ、抽象化に結びつけづらい。目標達成に困難を感じる出来事が1つだと、それは一過性のものかもしれないが、複数を挙げて共通点を括り出すことで、より本質的な問題に対処できる可能性がある。</p>
<p>コーチングであれば、うまく質問を通じて相手の話を具体化していく必要があるし、心理的安全性や信頼を確立して、相手が本当のことを多く話せる場を整える必要がある。セルフコーチングであれば、自分の考えをたくさん書き付けながら、曖昧な部分を自ら探して掘り下げていくような過程を辿ることになる。</p>
<h2>習慣や環境へのフォーカス</h2>
<p>コーチングは最終的に何かしら「行動の変化」を伴わなければ意味がない。</p>
<p>そのために、習慣や環境へフォーカスしていく。目標達成が「Go をひとりで書けるようになる」だとして、あまり勉強の時間が取れていないのであれば、どう時間を確保するかを考えたり、コーディングの対象を探すために、 Go の Good First Issue を探しやすいようにするかもしれない。あるいはそもそも別のチームに移動したほうが業務時間で Go を書けるのであれば、移動を調整して環境自体を変えることも考えられる。</p>
<h2>コーチングは継続的に行う</h2>
<p>コーチングは1回行って終わりではなく、継続的に行うものとされる。</p>
<p>1つには、なかなか1回の会話（コーチングは1回あたりだいたい30分程度）では本当の考えまで辿り着けない場合も多いことによる。何度もコーチングを行い、じっくり問いに向き合うことで、自分の目標は何か、どういったキャリアを辿りたいか日常的に考える習慣ができていき、答えも見つけやすくなる。</p>
<p>また、不確実性を排除する観点もある。状況が日々変化していく中で、目標はそのままでいいのか、今やっていることは目標達成の観点からずれてきていないか、新たな問題はないかなど、様々な点を洗い出しながら軌道修正していく。</p>
<h2>conclusion</h2>
<p>正直なところ、本を読んだだけでコーチングスキルが簡単に上がるものではないし、それなりにこれは高度なスキルだという印象が強い。そもそも、悩んでいる相手に対して、パッと何かアドバイスをしたくなる衝動は自分にもあるし、それを押さえて話を聞く、考えを促すという会話スキルにチャレンジしてはいるが、一朝一夕で身につくものではないな、と思う。</p>
<p>コーチング自体が万能のものでもないと思っている。世の中、特にエンジニア界隈だと、キャリアパスは特に考えず、やるべきことをこなしていただけで凄腕エンジニアになれました、という人は多くいるし、成長過程を辿る上で、こういった自問自答が必要となるかは人それぞれだ。
また、コーチングは自分の中に答えを見つける、つまり「自責」の考え方が強いので、例えばトップダウンの傾向が強いような会社だと、コーチングしたところで自分が取れる手立てがない、ということもあり得るのではないかと思う。もちろん、環境要因を変えるために、自分が何をできるか考えることが重要なのだが、過度な自責思考は、人によってはメンタルに重大な影響を及ぼす可能性もあるし、銀の弾丸のようにコーチングを用いるべきではないと考える。</p>
<p>その上で特に着目したいのは、コーチングにおける「考えを具体化する」「言語化して考える」「習慣にフォーカスして行動を変える」「継続的に状況を追跡する」といった方法論だ。今回、『エンジニアリング組織論への招待』もあわせて再読したのだが、その中で「思考のリファクタリング」と呼ばれる言葉がある。人間の思考はバイアスなどで認知がゆがみやすいし、言語化していないことで曖昧なものとなってしまうこともある。この本では、思考をリファクタリングすることで行動を促すために、メンタリングの技術を勧めており、これはコーチングの考え方にも近い。</p>
<p>僕はつい頭の中で考えを転がす悪癖があるので、書き付けて考える、あるいは具体的経験を書き留めておくことは日々の習慣にしていこうと思っている。コーチング上での実践のみにとどまらず、常に自分の思考を疑い、それを言語化、客体化してリファクタリングしながら、自分の目標や問題意識に向き合うことは、エンジニアとしても必要な技術だと捉えている。</p>
<h2>今回読んだ5冊</h2>
<h3>新版 コーチングの基本</h3>
<p>https://www.hanmoto.com/bd/isbn/4534056591</p>
<p>コーチングとはそもそも何なのか、定義付けする上ではこの本が一番よかった。先述の通り、かなり捉えどころのない概念なので、まずはこの本である程度コーチング像を固めてしまうと良いように思う。後半は組織論などになるので、前半だけでも。</p>
<h3>新 コーチングが人を活かす</h3>
<p>https://www.amazon.co.jp/dp/4799326104%0A</p>
<p>コーチングを実践する上での tips が多く書かれている本。具体的にコーチングをどう進めるべきなのか、実践イメージがつかみやすい。</p>
<h3>エンジニアリング組織論への招待</h3>
<p>https://www.amazon.co.jp/dp/4774196053%0A</p>
<p>再読。先述の通り、一部の記述がコーチングに近い話になっており、 Chapter1「思考のリファクタリング」と Chapter2「メンタリングの技術」が特に参考になった。</p>
<h3>トリガー 自分を変えるコーチングの極意</h3>
<p>https://www.amazon.co.jp/dp/4532320496</p>
<p>コーチングにおける「行動の変化」をどう促すべきかにフォーカスした本であり、コーチング自体の方法論ではない。人間の行動は「環境」というトリガーに大きく左右されているとし、習慣や行動を変えるための仕組み化を行うことを述べている。コーチングの如何を問わず、行動変容という点ではとても参考になった。</p>
<h3>人生改造宣言</h3>
<p>https://www.amazon.co.jp/dp/4419067845</p>
<p>これもコーチング自体の方法論の本ではなく、コーチングにおいて行われるアドバイスが tips のようにまとめられた本という趣が強い。ライフハック本に近いかもしれない。</p>
]]></description>
            <link>https://chroju.dev/blog/what_is_coaching</link>
            <guid isPermaLink="false">what_is_coaching</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 14 Nov 2021 00:12:28 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[kops と Argo CD でプライベート Kubernetes を建てる]]></title>
            <description><![CDATA[<p>先日 <a href="https://event.cloudnativedays.jp/cndt2021">CloudNative Days Tokyo 2021</a> を見ていて、知らない kubernetes 関連のツールがまだまだあることを実感した。 AWS サービスや各種 OSS はわりとサクッとローカルで試せたりもするんだけど、 k8s 関係もプライベートでシュッと試せる環境が欲しいよな、ということを考え、クラスターを1個作ってみた。</p>
<h2>利用技術</h2>
<p>Kubernetes のインストールには <a href="https://kops.sigs.k8s.io/">kOps</a> を使った。</p>
<p>そのほかのツールとしては <a href="https://github.com/kubernetes/kubeadm">kubeadm</a> や <a href="https://github.com/kubernetes-sigs/kubespray">kubespray</a> などがある。 kubeadm は以前使ったこともあるのだが、サーバーの中でコマンドを実行することで Kubernetes コントロールプレーンもしくはワーカーノードとして必要な設定が施される。 kops はこれとは異なり、 AWS で必要なリソース各種の構築と、サーバー内の設定の双方をおこなってくれる。今回 kops を選んだのは、 Kubernetes Cluster 一式が一発で構築できるので kubeadm より楽だったから、という理由に尽きる。VPS を使うより AWS のほうがある程度金額面で高くはなるが、検証するなら業務でもよく使う環境のほうがいいだろうということで AWS にした。リザーブドインスタンスを適用すれば、サーバー代自体はそこまで国内主要 VPS と変わらないと認識している。</p>
<p>ちなみに kubespray のことはよく知らない。</p>
<p>また、 Kubernetes 上に manifest を適用するにあたっては <a href="https://argo-cd.readthedocs.io/en/stable/">Argo CD</a> による GitOps を採用した。これは業務で使っているものに揃えた。</p>
<h2>kops</h2>
<p>kops は本当にザックリでよければ、 <code>kops create cluster $NAME</code> コマンドで初期設定を作成し、 <code>kops update cluster $NAME --yes</code> でクラスターの構築が終わる。構築にあたっては <code>~/.kube/config</code> も自動で設定され、そのまま k8s が利用可能となる。もともと AWS で簡単にクラスターを立てることを目的としたツールだったようだが、現在はその他の各種クラウドサービス、 VPS も alpha, beta の状態でサポートされている。</p>
<p>kops の設定情報は <code>create cluster</code> コマンドにオプションで手渡す。例えば <code>--master-size</code> でコントロールプレーンのインスタンスタイプを設定できる。設定情報の実態は、 <code>kops</code> コマンドの実行時に予め <code>KOPS_STATE_STORE</code> 環境変数で設定した S3 バケットに保存される。</p>
<h3>kops + Terraform</h3>
<p>設定を宣言的に Git で管理したければ、 <code>create cluster</code> コマンドに <code>--target=terraform</code> オプションを与えることで、 Terraform の設定を出力させることができる。</p>
<pre><code class="language-bash">$ kops create cluster kops.chroju.dev --zones=ap-northeast-1a --master-size t3.small --node-size t3.small --networking calico --ssh-public-key ~/.ssh/id_rsa.pub --out=. --target=terraform

$ terraform apply -auto-approve
</code></pre>
<p>これは先の S3 バケット内の設定を Terraform 形式に落とし込む形になるが、この後は S3 側の設定は必要としなくなり、 Terraform コマンドだけでオペレーションできるようになる。このほうが、 kops はあくまで設定テンプレートを出力するだけのツールとして扱うことができ、クラスター管理において kops を離れることができるという点でも利がある（ただし、 kops が自動的に <a href="https://kops.sigs.k8s.io/operations/etcd_backup_restore_encryption/">etcd のバックアップ</a>などでも S3 を使用するため、 S3 が不要になるわけではない）。</p>
<h3>ssh 接続を ssm に切り替える</h3>
<p>kops はデフォルトで ssh による各ノードへのアクセスを有効としているが、セキュアではないので AWS SSM による接続へ切り替えたい。 Terraform を編集して ssh の許可を塞ぎ、各ノードの IAM Role に <code>AmazonEC2RoleforSSM</code> policy を追加しておく。</p>
<p><a href="https://gyazo.com/f0c7a85045d7a6d4bc90d15b6cc3819c"><img src="https://i.gyazo.com/f0c7a85045d7a6d4bc90d15b6cc3819c.png" alt="Image from Gyazo" width="600"/></a></p>
<p><a href="https://gyazo.com/53d3c939f3a7446c03ab36a36bf7189d"><img src="https://i.gyazo.com/53d3c939f3a7446c03ab36a36bf7189d.png" alt="Image from Gyazo" width="600"/></a></p>
<p>画像は省略したが、 IPv6 の Port 22 も同様に閉じておく。</p>
<h3>ノード内部設定変更の反映</h3>
<p>kops が出力する Terraform では、各ノード内部の設定には user data を使用している。 Terraform では user data を編集してもインスタンスの再起動は行われないため、即時の反映はされない。この場合は <code>kops rolling-update</code> を実行することで、インスタンスを入れ替えることができる。</p>
<h2>Argo CD</h2>
<p>2021年2月から、<a href="https://artifacthub.io/packages/helm/argo/argo-cd">公式の Helm Chart</a> がリリースされているので、これを使ってインストールした。</p>
<h3>App of apps</h3>
<p>Argo CD による Application の管理には <a href="https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup/#app-of-apps">App of apps</a> パターンを採用した。</p>
<p>Argo CD は、管理対象の Kubernetes manifests を Application と呼ばれる CRD で設定する。対象の Git レポジトリの URL やパスを Application 内で設定することで、定期的にそのレポジトリを fetch して、 Kubernetes クラスター上に apply する。</p>
<pre><code class="language-yaml">apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: guestbook
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/argoproj/argocd-example-apps.git
    targetRevision: HEAD
    path: guestbook
  destination:
    server: https://kubernetes.default.svc
    namespace: guestbook
</code></pre>
<p>この Application 自体も Kubernetes resource なので、 Argo CD で管理したくなる。そこで Application を管理する Application（便宜的に「親 app」と呼ぶ）を作成するパターンが App of apps と呼ばれる。具体的には Helm Chart で以下のようなファイルを作成する。</p>
<pre><code class="language-bash">.
├── Chart.yaml
├── templates
│   ├── argo-cd.yaml
│   └── namespace.yaml
└── values.yaml
</code></pre>
<p>Chart.yaml は適当な内容でよい。</p>
<pre><code class="language-yaml">apiVersion: v1
name: app-of-apps
version: 0.0.1
</code></pre>
<p>values.yaml には管理対象となる Application のデフォルト値を設定しておく。</p>
<pre><code class="language-yaml">metadata:
  namespace: argo-cd
spec:
  destination:
    server: https://kubernetes.default.svc
  source:
    repoURL: https://github.com/chroju/infrastructure
    targetRevision: HEAD
</code></pre>
<p>templates 内に app 1つにつき1ファイルを作成していく。ここで Application を管理していく。以下では、 <code>chroju/infrastructure</code> レポジトリの <code>kubernetes/namespace</code> 配下が Application の同期対象となる。</p>
<pre><code class="language-yaml">apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: namespace
  namespace: {{ .Values.metadata.namespace }}
spec:
  project: default
  source:
    repoURL: {{ .Values.spec.source.repoURL }}
    path: kubernetes/namespace
    targetRevision: {{ .Values.spec.source.targetRevision }}
  destination:
    server: {{ .Values.spec.destination.server }}
    namespace: default
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
</code></pre>
<p>この Helm Chart を管理する Application をさらに作っていくとさすがに切りがないので、ここだけは <code>argocd app create</code> コマンドにより手動で Argo CD へ Application を作成する。すると画面上では以下のように、親 app から各 Application がぶら下がるような形になる。</p>
<p><a href="https://gyazo.com/76782bf27a1953507d99d3088de586f0"><img src="https://i.gyazo.com/76782bf27a1953507d99d3088de586f0.png" alt="Image from Gyazo" width="600"/></a></p>
<p>今後 Application を追加したい場合は、先の Helm の template にファイルを追加していくだけでいいので、今後は Git 上の操作だけで manifest を apply できる、 GitOps の環境ができあがる。</p>
<h3>Argo CD UI へのアクセス</h3>
<p>なお、k8s 上のアプリケーションを expose する手段をまだ持っておらず、 Argo CD は port forward でアクセスしている。常時アクセスしたいものではないし、これでも別に良いような気もしているが、気が向いたら何か手段を講じるかもしれない。</p>
<pre><code class="language-bash">$ kubectl port-forward argo-cd-argocd-server-XXXXXXXXX-XXXXX 8080:8080
</code></pre>
<h2>Next</h2>
<p>とりあえず、 k8s cluster とその上で動く resource がすべて declarative に管理できる状態がこれで出来上がった。まだまだ課題はあるので、ゆっくり育てていきたい。</p>
<ul>
<li>先述の Argo CD port forward をどうするか</li>
<li>Argo CD ログインを何らかの OAuth へ変更したい</li>
<li>監視を実施したい</li>
<li>Reserved Instance を購入したい</li>
<li>定期的なアップデートを実施していきたい</li>
</ul>
<p>実は1年近く前にも kubeadm + ConoHa でクラスター構築したのだが、当時の設定を何も情報残していないし、管理が頓挫したので今回が再挑戦になる。今回こそは続けていきたいところ。</p>
]]></description>
            <link>https://chroju.dev/blog/kops_argo_cd_private_k8s_cluster</link>
            <guid isPermaLink="false">kops_argo_cd_private_k8s_cluster</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 09 Nov 2021 08:13:35 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[AWS Certified Security - Specialty を自宅で受験して合格した]]></title>
            <description><![CDATA[<p><a href="https://gyazo.com/afe0a94aa7617c8478226b7896768be0"><img src="https://i.gyazo.com/afe0a94aa7617c8478226b7896768be0.png" alt="Image from Gyazo" width="600"/></a></p>
<p><a href="https://aws.amazon.com/jp/certification/certified-security-specialty/">AWS Certified Security – Specialty</a> を自宅で受験して合格したのでレポート。</p>
<h2>受験の動機</h2>
<p>AWS のセキュリティサービスってひたすらに数が多くて訳がわからなかったので一度体系的に学び直したくて取ってみた、という感じ。 EC2 建てるときに何に気をつけなくちゃいけないかとか、 IAM の権限のベストプラクティスとか、個別の事例は理解しているけれど包括的に知りたくなった。
基本的に資格を取る、あるいは資格勉強をするときのメリットって、こういった体系立てて知識を付けることにあると思っている。</p>
<h2>取得に向けた学習</h2>
<p>学習期間は1週間しか取れていないのだが、あくまで数年にわたる業務経験 + 1週間の集中学習で合格できているだけなので、誰でも1週間で取れますよとは全然言わないし、自分自身にとってももう少し時間取るべきだったとは反省している（試験は合格したけど、もう少し深掘りしたかった分野がいくつもある）。</p>
<p>逆に業務経験だけで取れたとも思えない。後述の書籍などを読んでいて、名前さえ聞いたことがないサービスに出くわすこともあった。業務経験の知識を試験向けに洗練しつつ、業務で触れたことがない知識を補うように学習していったイメージ。</p>
<p>以下、使った教材を具体的に書いていく。</p>
<h3>要点整理から攻略する『AWS認定 セキュリティ-専門知識』</h3>
<p>https://www.amazon.co.jp/dp/B08DCLRHC7</p>
<p>NRIネットコムのエンジニアの方々が書いている試験対策本。試験範囲を網羅的に押さえる上で良いと思う。一番最初にこの書籍をざっくりと読み通してから、あまり詳しくない部分を個別に補う形で学習を進めた。試験に出そうなところは詳しく、あまり出題されないサービスなどはさらっとした解説になっていて、どこを重点的に学べばいいかわかりやすい。</p>
<p>ちなみにだが、2020年7月の発刊なので、現時点で内容が古くなっているということはほぼないものの、それでも公式に告知されている試験範囲は別途きちんと押さえるべきだと思う。例えば AWS Audit Manager は2020年12月に発表されたサービスなので、本書では当然言及がないが、公式の試験ガイドには記載されている。</p>
<h3>Exam Readiness: AWS Certified Security - Specialty</h3>
<p><a href="https://www.aws.training/Details/eLearning?id=34786&#x26;ep=sec&#x26;sec=spec_security">Exam Readiness: AWS Certified Security - Specialty | AWS トレーニングと認定</a></p>
<p>公式の無料デジタルトレーニング。内容としては短いが、練習問題もいくつか付いているので、雰囲気を掴むのに良い。</p>
<h3>AWS Black Belt &#x26; Developeres.IO</h3>
<p>https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/</p>
<p>名前も知らないようなサービスは Black Belt のスライドで要点を掴むようにした。いわゆるドキュメントを読むよりはわかりやすく、短時間で読めるのでおすすめ。具体的な使い方のイメージを掴みたい場合は Developers.IO でハンズオン記事を探していた。</p>
<h3>模擬試験</h3>
<p>公式で模擬試験が有料で提供されており、受験はしたのだが、個人的にはあまりオススメしない。問題が本番65問に対して20問と少ない上、先のデジタルトレーニングと重複したものも多く（ランダム出題だとすれば僕の運が悪かっただけかもしれないが）、コストパフォーマンス的にいまいちだった。</p>
<h2>重点的に学習した箇所</h2>
<h3>Active Directory 関連</h3>
<p>仕事で Active Directory を扱ったことがなく、まったく土地勘のない領域だった上、 AWS には AD 関連のサービスが複数あり、それぞれの違いと使い方、使用するシチュエーションなどをしっかり押さえるようにした。</p>
<h3>監査、分析系のサービス</h3>
<p>とにかく数が多いので、こちらも使い分け方を頭にたたき込んだ。具体的には Config, CloudTrail, Trusted Adviser, Inspector, Detective, Security Hub, Shield, QuickSight, GuardDuty, Macie あたり。それぞれ何が出来るのか、どの AWS サービスと連携するのか、発見的統制なのか予防的統制なのか、複数 AWS アカウントで使いたい場合はどうすればいいのか、といったところを押さえた。</p>
<h3>知らなかったサービス</h3>
<p>Macie, QuickSight, CloudHSM の3つと、先の AD 関連のサービスは恥ずかしながら存在すら知らなかった。</p>
<h2>自宅受験</h2>
<p>自宅受験するのは初めてだったので、この部屋じゃダメだと言われないか、何かトラブルになったりしないかと、試験そのもの以上に緊張した。結果から言えば特にトラブルはなかった。</p>
<h3>受験環境について</h3>
<p>そこそこ広いリビングの片隅に仕事スペースを設けているのだが、そこで受験した。部屋が広いしリビングなのでいろいろとモノは置いてあるのだが、書籍類やガジェット類を片付けて綺麗にしていれば何も言われることはなかった。</p>
<p>中には風呂場で受験した人もいると聞いていたので、そのレベルで「何もない」場所じゃないといけないのか……？と疑心暗鬼になっていたが、そこまで厳しくはないらしい。ただ、同居の家族の関係で絶対に邪魔が入らない場所が必要だとか、そうなってくると事情は異なってくるし、不安や心配のない環境で受験するのがベターだとは思う。いろいろと余裕があればビジネスホテルなどを借りるのもアリかもしれない。</p>
<h3>PC の再起動を求められる場合がある</h3>
<p>一度試験準備の過程で接続の問題が発生し、試験官から PC の再起動を求められる場面があり、若干ヒヤッとした。というのも、ソフトウェアアップデートを数日放置していることが多く、再起動後にアップデートで数十分待つことになるのではないかと思ったから。幸いアップデートは適用済みだったのですぐに起動したが、試験前日までに一度再起動しておいたほうが良いと思う。</p>
<h3>マルチディスプレイは NG</h3>
<p>試験前に、PC が試験に適したシステム環境になっているか（カメラが使えるか、他のアプリが起動していないかなど）自動で確認するプロセスがあり、その中では警告されることはないのだが、実際にはマルチディスプレイは NG で、いざ試験問題が配信される、という最後のプロセスが一度うまくいかなかった。ちゃんとシステム要件の案内には記載があったので、読み飛ばしていた自分が全面的に悪いのだが、自動チェックで弾かれなかったので油断してしまった。他にも要件はいろいろとあるのでちゃんと読みましょう。</p>
<h2>Impression</h2>
<p>AWS の認定試験は何年も前に一度テストセンターで受けたこともあるのだが、自宅で想像より手軽に受けられたので、もし次回受ける機会があっても自宅でいいかな、と感じた。とはいえ最大3時間、実際には2時間問題を解いていたのだが、かなり集中力を要するので、自宅でそれだけの時間、確実に集中してパフォーマンスを出せるのか、というのも考えたほうがいい。気晴らしついでにホテル受験というのもやってみたくはある。</p>
<p>何にせよ、そこそこお金もかかるものだし、一発合格できてよかった。</p>
]]></description>
            <link>https://chroju.dev/blog/aws_certified_security_specialty</link>
            <guid isPermaLink="false">aws_certified_security_specialty</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 12 Sep 2021 23:50:09 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Kubernetes のアラート戦略]]></title>
            <description><![CDATA[<p>何番煎じだという話だし、あまり目新しいことも書ける気はしないが、自分の思考整理のために書く。あまり環境依存の話にはしないようにするつもりだが、マネージド Kubernetes を基本として考えている（セルフホストはあまり経験がない）。</p>
<p>ちなみにここでテーマにするのは「アラート戦略」であり、「監視戦略」ではない。何を「アラート」するべきかという観点で書いていく。</p>
<h2>Kubernetes の監視レイヤー</h2>
<p>ひとえに「Kubernetes の監視」と言ってもレイヤーが複数ある。</p>
<ol>
<li>Kubernetes 自体が正常動作しているか（コントロールプレーン）</li>
<li>Kubernetes クラスタが正常動作しているか（各種ソフトウェア）</li>
<li>ワーカーノードが正常動作しているか</li>
<li>ワーカーノード上にデプロイしたコンテナが正常動作しているか</li>
<li>コンテナが正常にサービスを提供できているか</li>
</ol>
<p>1点目はマネージド Kubernetes を利用している場合には、不要かもしれない。ただ、その場合も監査や分析用にログ、メトリクスの出力と保存は行っていたほうがいいだろう。3点目に関しても、例えば EKS の Managed Node Group で自動制御となれば、基本的にはマネージドで動作保証されるので、監視する観点は少なくなる。このように1,3点目に関しては、 Kubernetes クラスタとして何を使うかにより、必要な監視に幅が出てくる。</p>
<p>2点目に関しては、 Kubernetes のクラスタ動作を制御するために追加で導入するソフトウェア、例えば <a href="https://github.com/kubernetes-sigs/descheduler">descheduler</a> のようなものを想定している。このようなソフトウェアは正確には「Kubernetes」という言葉が表す範囲の外ではあるが、クラスタの動作をより低いレイヤーで制御するものであり、かつ、マネージドの領域ではないので、マネージド Kubernetes を使っていたとしても独自に監視が必要になってくる。</p>
<p>4点目以降は、どのようなクラスタを選んでも基本的には監視が必要になる。5点目についてはアプリケーションレイヤーの話になるので、 Kubernetes 固有の戦略というよりは、一般的な外形監視などで要件を満たせる場合も多い。</p>
<h2>アラートの基本戦略</h2>
<p>一般的なアラート戦略は <a href="https://www.datadoghq.com/ja/blog/monitoring-101-alerting/">Monitoring 101: Alerting on What Matters | Datadog</a> の内容をよく参考にしている。</p>
<ul>
<li>アラートはレベル分けし、最も緊急のアラートだけを即時通知（ページング）する</li>
<li>アラートは障害の原因ではなく症状に対して設定する</li>
</ul>
<p>特に2点目が重要で、一般的なアプリケーションであれば CPU 使用率の高騰ではなく、それによって引き起こされるアプリケーションの応答遅延のほうを監視するべきだ、ということになる。なぜなら CPU 使用率高騰は、必ずしもユーザー影響を及ぼすとは限らず、偽陽性のアラートになる可能性があるからだ。</p>
<p>Kubernetes においては、先のようにレイヤーが複数に渡るため、「原因」と「症状」が複雑に絡み合う。例えばワーカーノードのスケーリング台数が上限に到達してしまいスケールできず、新たな Pod が起動できなくなった結果、アプリケーションが稼働しなくなったとする。この場合、 Pod が起動できなくなったことはアプリケーションレイヤーからすれば「原因」だが、コンテナレイヤーや、 Kubernetes の正常稼働という観点からすれば「症状」だ。このように、レイヤー別で監視するべき「症状」を考えていく必要がある。</p>
<p>また1点目に関しても、 Kubernetes には Reconcile Loop の概念があるため、何らかの症状が発生したとしても、自動的に回復する場合が少なくなく、そういったものについてはページングは必要なく、翌営業日以降対応できるようチケットを切るなり、チャットに通知するなりでよい。 Reconcile Loop が正常に動作していない場合や、 Reconcile Loop が及ばない範囲の障害が主にページングの対象となる。</p>
<h2>レイヤー別のアラート戦略</h2>
<p>以上を踏まえてレイヤー別のアラート戦略を考える。</p>
<h3>ワーカーノードの正常動作</h3>
<p>ワーカーノードに関しては、何らかのオーケストレーションを利用していない場合は、通常の Linux サーバーと同等の監視が必要になると思われるが、運用経験に乏しいので深く踏み込まないことにする。</p>
<p>EKS Managed Node Group のようなオーケストレーションを利用しており、 Cluster Autoscaler を導入していれば、ノードのダウンや不足は自動的に解消されるので、監視が必要な範囲は限られてはくるが、ゼロではない。</p>
<ul>
<li>ノード台数 / オーケストレーション最大台数</li>
<li>ノードのディスク使用率</li>
</ul>
<p>Kubernetes クラスタにアプリケーションを増やしていけば、いつかはノード台数が設定の最大台数まで達し、それ以上スケールできなくなるおそれがある。そうなる前に設定変更をトリガーできるようにしたい。また、コンテナイメージの pull が積もり、ノードのディスク使用率がかさむと、 CPU やメモリといったリソースを活用しきっていないうちにノードが利用不可になってしまう場合もありえる。いずれもページングの対象ではないだろうが、対応のためにアラートは必要になる。</p>
<h3>Kubernetes クラスタ制御のための各種ソフトウェア</h3>
<p>先述の descheduler のようなソフトウェアだが、これはソフトウェアの種類により監視項目も変わってくるので、一概に言えるものではない。知らぬ間に停まっていた、正常に動作していなかったということがないように、何らかの手段で監視するほうが望ましいと思われる。</p>
<p>主に考えられる手段としてはログに出力されるエラーによるアラート、何らかの通信を受けるソフトウェアであれば、疎通可能であるか、などだろうか。また Prometheus が scrape できるような OpenMetrics の形でメトリクスを提供しているソフトウェアもあるので、その場合は分析用にメトリクスも取得しておきたい。 descheduler であれば、 <code>https://localhost:10258/metrics</code> で2種類のメトリクスを提供している。</p>
<p>個人的にはこのレイヤーの監視が最も重要だと考えている。このレイヤーは仮にエラーであっても、クラスタ自体の稼働、アプリケーションの稼働には影響を及ぼさない可能性があり、適切に監視しなければ見過ごしやすいからだ。</p>
<h3>コンテナの正常動作</h3>
<p>ひとえにコンテナといっても Deployment, Job, DaemonSet など、起動方法は様々であり、それぞれに応じた監視が必要になってくる。</p>
<ul>
<li>Deployment の available / desired</li>
<li>DaemonSet の unavailable</li>
<li>Job, Cronjob の failed</li>
<li>CrashLoopBackoff の発生</li>
<li>ImagePullBackoff の発生</li>
<li>Restart の頻発</li>
</ul>
<p>Deployment については desired と同数の Pod が available になっていない状態が継続している場合、 Reconcile Loop が何らかの異常をきたしている可能性があるので、監視しておきたい。ただし、一時的にコンテナがダウンした場合や、 Horizontal Pod Autoscaler で desired が拡張され、一時的に available が不足するといった場合もあるので、閾値は多少ゆるめでいいと考えている。アプリケーションの提供に必要十分な数の Pod が起動していないのであれば、それはアプリケーションレイヤーで監視するべきであり、ここでは「Deployment の Reconcile Loop が長期間正常に動作していない」という「症状」に着目すればいい。</p>
<p>その他のリソースについても同様に、 Reconcile Loop が働いていない場合にアラートすると考える。 DaemonSet であれば <code>unavailable >= 1</code> が継続している場合、 Job や CronJob であれば failed が多発している場合などだ。これらについては僕としてはページング相当と考えている。</p>
<p>CrashLoopBackoff や ImagePullBackoff は悩ましいところではある。 CrashLoopBackoff, ImagePullBackoff は「コンテナが起動できない」という症状に対する原因に近いと思われるからだ。しかし、例えば Deployment のローリングアップデート中、これらのエラーで新規 Pod がずっと起動できないような場合であれば、 <code>available / desired</code> では検知できないが、こちらの監視でカバーができるし、必要に応じてアラートを上げても良いのではないだろうか（もちろん、 CD pipeline でアラートが上げられるならそちらでも良いが）。 ImagePullBackoff の発生は多くはないだろうが、コンテナレジストリの障害など、発生するパターンがゼロではない。あるいは Restart が多発しているような場合にアラートする手もある。</p>
<h3>アプリケーションの正常動作</h3>
<p>このレイヤーは基本的なアプリケーション監視の考え方とほぼ同等だが、1つ考えておきたいのは、 Readiness / Liveness probe と適切に組み合わせる点だ。Liveness probe では、応答に失敗する Pod を自動的に Restart させることができるので、 Restart により修復できるような可能性があれば、 probe 側で適切に監視させ、その上で一定時間修復されないような場合に、監視ツールからアラートを上げるような仕組みにしておきたい。 Readiness probe は、何らかの原因で一時的に応答できなくなる場合のある Pod に設定することで、外部からのリクエストが受け付けられないような状態を避けることができ、結果的に外部からの監視で偽陽性アラートが発生するのを抑えられる可能性がある。</p>
<h2>Conclusion</h2>
<p>Kubernetes の場合も「症状についてアラートする」「対処が必要なアラートについてページングする」という原則を忘れなければ、一貫した監視戦略を練っていくことができる。気をつけなくてはならないのは、 Reconcile Loop やマネージド Kubernetes の機能により、「対処が必要」な範囲を適切に見極める必要があることと、監視に必要なログやメトリクスの収集方法が、ソフトウェアやレイヤーに応じて異なってくることであり、このあたり難しさを感じている。メトリクスであれば kube-state-metrics の全容のみならず、ホスト側のメトリクス、さらに先述のような OpenMetrics を提供しているアプリケーションもある。まずはメトリクスやログをきちんと収集して可観測性を高めた上で、手持ちの材料を踏まえた監視戦略を都度適切に考えるようにしていきたい。</p>
<h2>参考文献</h2>
<ul>
<li><a href="https://www.datadoghq.com/ja/blog/create-manage-kubernetes-alerts-datadog/">Datadogを使用してKubernetesアラートを自動的に作成および管理する| Datadog</a></li>
<li><a href="https://sysdig.com/blog/alerting-kubernetes/">Alerting on Kubernetes: How to &#x26; best practices | Sysdig</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/kubernetes_monitoring_alerting</link>
            <guid isPermaLink="false">kubernetes_monitoring_alerting</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 29 Aug 2021 12:36:53 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[認知負荷を抑えたお金の管理]]></title>
            <description><![CDATA[<p>なんか急にお金の話が書きたくなったので書く。</p>
<p>10年ぐらい前から「現金は極力使わない」「なるべく処理を自動化して認知負荷を減らす」というモットーで仕組み作ってきたけど、どこかに書き記したことはなかったので書いてみる。ここは一応技術ブログなのだが、特にプログラミング的な要素は何もない（昔はあったんだけど）し、わりとみなさん良くやっている方法だとは思っている。極力自動化する、認知負荷（運用負荷）減らす、みたいな考え方はIT系というか SRE っぽいかもしれない。</p>
<p><a href="https://gyazo.com/40d05a3043da3c8eee6faded0c6289d5"><img src="https://i.gyazo.com/40d05a3043da3c8eee6faded0c6289d5.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>ざっくり図にすると、現状のお金の流れはこんな感じ。要素ごとに説明してみる。</p>
<h2>銀行関連</h2>
<h3>住信 SBI ネット銀行をハブにする</h3>
<p>https://www.netbk.co.jp/contents/</p>
<p>ハブとして使っている銀行。すべてのお金はここに入ってきてから、いろんなところへ流れていく。</p>
<p>もう10年ぐらいは使っているし、特に不満もないので乗り換える予定もない。 ATM 手数料関連で「改悪」と何度か言われてきてはいるけれど、給与受け取り口座にして、デビットを月3万円分使っていれば、毎月10回は ATM 入出金無料になるので、別に不満はない。最近は現金をあまり使わないので、毎月の出金機会は1、2回ぐらいだし。</p>
<p>また、SBI証券との「ハイブリッド口座」の機能があり、お金の移し替えが簡単なのも大きい。貯金に回せるお金は全部ここへ入れていて、さらに投資に回したりもしている。微々たるところではあるが、ハイブリッド口座の金利は2021年8月現在0.01%で、普通の銀行に眠らせるよりはマシになる。</p>
<p>他にも自動定額振り込みの機能、スマホアプリがあればキャッシュカードなしで ATM 取引ができるサービスなど、いろいろ便利に使わせてもらっている。最近はアプリだけで振り込みから何から全部完結するようになった。</p>
<h3>銀行を使い分ける</h3>
<p>他、何かのためにとメガバンクとゆうちょの口座は取りあえず押さえている。いずれも積極的には使っていない。</p>
<p>用途別で銀行口座を分けてはいて、ゆうちょのほうは現状「引き落とし用口座」になっている。毎月のクレジットカード利用料や、 iDeCo の支払いはここからになっており、 SBI 銀から手動で必要額を振り込んでいる。別に SBI 銀から直接引き落としてもいいんだよね、と感じてはいる。ほぼ惰性でこうなっている。</p>
<p>メガバンクのほうは、現在2人暮らしなので家のお金をストックする場所としていたが、最近後述する Kyash の共有口座を使い始めたので休眠状態になりつつある。結果、「銀行を使い分ける」必要性はあまり感じなくなってきたところではある。認知負荷のことを考えると、このあたりはそろそろ見直してよさそう。</p>
<h2>支払い手段</h2>
<p>支払いは基本的にキャッシュレス。優先順位は QUICPay > モバイル Suica > Kyash Card > 現金としている。</p>
<h3>FeliCa / NFC 決済が好き</h3>
<p>最も速い決済手段がスマホでの FeliCa / NFC 決済だと思っているのでこれが最優先。 QR 決済サービスも、友人との送金用途を考えて使ってはいるものの、支払いのときにアプリを立ち上げるのがどうにも面倒であまり使っていない。特に、バーコードをこちらで読み込んで、金額を自分で入力するタイプの支払いだと使うのにだいぶ抵抗がある。何も考えずにタッチして「ピッ」が一番楽。</p>
<p>優先しているのは、後述の Kyash と連携した QUICPay だが、たまに使えない店舗もあるので、その場合はモバイル Suica が次点。</p>
<h3>クレジットカードではなくデビットを使う</h3>
<p>クレジットカードを使わないことにして、デビットカードを代わりに使っている。 MoneyForward を使っているので、クレカの利用額がわからなくなるを気にしているわけではないのだが、使ったお金がすぐに手元から消えるほうが精神衛生的に楽。ポイント還元率などでクレカのほうが得な場合が多いのは理解していて、一時期どのクレカがお得か、みたいなことをやってもいたが、あんまりそこに時間使いたくないなという気にもなってきて、 SBI のデビットだけ使うことにした。</p>
<p>ただ、デビットが使えない場面というのがあるので、クレカも持ってはいる。いくつかの定期的な支払いで使っている。</p>
<h3>Kyash で支払いを集約する</h3>
<p>https://www.kyash.co/</p>
<p>SBI 銀が入金側のハブなら、支払い側は Kyash がハブになっている。 Kyash で Kyash Card と呼ばれるリアルカードを発行し、 QUICPay に紐つけてそちらをメイン決済手段に。カードのほうも持ち歩いて、 FeliCa / NFC 決済が使えないときの代替に。入金手段は SBI デビット。これで Kyash から支払えば、その場で銀行口座から引き落とされるようになる。</p>
<p>Kyash もまたサービス変更でいろいろ言われているが、当初「クレカやペイジーから入金できて、それを送金にも決済にも使えるし、決済時2%還元しますよ（参考：<a href="https://www.itmedia.co.jp/mobile/articles/1808/15/news030.html">送金を身近に　リアルカードで決済シーンも拡大　「Kyash」の戦略を聞く：モバイル決済の裏側を聞く（1/3 ページ） - ITmedia Mobile</a>）」と言っていたのに、銀行連携が中心のバンキングサービスへ趣旨換えしてしまったので、僕のようなクレカ（デビット）連携をメインとしていた初期ユーザーは、それは混乱するであろうというところ。「改悪」というよりは、サービスのターゲット自体が変わったよね、と認識している。</p>
<p>ただ、それでも利点は多いので使用をやめる予定はない。利点の1つは、最近「<a href="https://www.kyash.co/features/share-account">共有口座</a>」と呼ばれる、他の Kyash ユーザーと共同で入出金できる口座機能。現在、家庭のお金はここに入れてここから払うことにしている。従来は共有用の銀行口座を設けて、デビットカードを作って支払っていたものの、デビットは複数人複数名義で持てないので、カードを持っていないほうが支払うのには使えず不便だった。 Kyash なら1つの口座から各々のカードで支払いができてすごく見通しがいい。</p>
<p>もう1つは、クレカ / デビットのプロキシとしての役割期待がある。手持ちのカードはなんであれ、 Kyash に紐つけておけば決済の口がここに集約されるのが気持ちとして楽であり、仮に Kyash の番号が流出だとか不正利用されても、 Kyash さえ停めれば本体側には被害が及ばない。また Kyash と連携さえすれば、どのカードであっても QUICPay 化できる。実際のところ、 SBI デビットは現状 Google Pay には対応しておらず、 Kyash 連携で初めて QUICPay 化できている。このあたりが使っている理由として大きい。</p>
<p>つまるところは「支払い手段の集約」というところに魅力を感じている。送金、カード決済、非接触決済、すべてが Kyash に集まっているというシンプルさが気に入っている。</p>
<h2>投資はほったらかし</h2>
<p>投資は大したことをしていなくて、<a href="https://www.amazon.co.jp/dp/B00F3VLSZW">山崎元『全面改訂 超簡単 お金の運用術』</a> を読んでください、それが全てです、というところ。もうそこそこ古い本になってしまっており、状況や制度が変わった部分もあるが、基本路線は同じ。</p>
<p>一言で言えば iDeCo と（つみたて）NISA には全振り、インデックスファンド中心に買って短期的な売り買いはせず、基本ほったらかし。個別株を買わないわけではないけれど、買うときはリターンを目的とはしていなくて、応援のつもりとか、株主優待目的とかにしている。</p>
<p>長期での投資しか考えていないので、基本的に路線を変えるつもりはない。とはいえまだ始めて10年経つか経たないかぐらいで、今は株高もあって儲かってはいる状態だというのはあるので、将来的に変動要素があれば何か見直しはかけるかもしれない。</p>
<h2>集計は MoneyForward</h2>
<p>https://moneyforward.com/</p>
<p>最後に、集計には MoneyForward 。昔はパスワードを渡すことを忌避していた時期もあったけど、現在は API 連携できる銀行も多いし、便利に使っている。そして一度使うと手放せない。現金を使う機会は月間で先月が5回、先々月が3回だったので、ほぼ全自動ですべてのお金の履歴がここに蓄積されている。</p>
<h2>Conclusion</h2>
<p>お金まわりで、ちょっとした得をする手段というのはいくつもあるんだけど、そのために労力をかけたり何か考えることは基本的に捨て去っている。その代わりに入金はSBI銀、出金は Kyash という具合に集約してシンプルにすることで、認知負荷、運用負荷を下げることに「得」を感じるというのが自分のスタイル。考えることを増やさないようにこれからも運用を続けていくつもり。</p>
]]></description>
            <link>https://chroju.dev/blog/money_management_with_low_cognitive_load</link>
            <guid isPermaLink="false">money_management_with_low_cognitive_load</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 09 Aug 2021 00:19:38 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『Building Secure & Reliable Systems』を読み、 SRE とセキュリティについて考える]]></title>
            <description><![CDATA[<p>https://www.oreilly.com/library/view/building-secure-and/9781492083115/</p>
<p>『Building Secure &#x26; Reliable Systems』は Google による <a href="https://sre.google/books/">SRE Books</a> の3冊目に位置づけられており、タイトル通りセキュリティにフォーカスされている。 SRE とセキュリティの関わり方について問題意識があったので、軽くではあるが読んでみた。</p>
<p>最初に自身の問題意識を具体化して書いておくと、以下のような点である。</p>
<ul>
<li>SRE はセキュリティの責任主体となるべきなのか？
<ul>
<li>仮にそうだとすれば、 SRE のスキル範囲が少々広すぎやしないだろうか？</li>
</ul>
</li>
<li>SRE が守るべき「信頼性」の中にセキュリティも含まれるのか？
<ul>
<li>なんとなく「そうだろう」という思いはあったが、きちんと考えられていない</li>
</ul>
</li>
<li>SRE のプラクティスの中で、セキュリティをどう取り扱っていくべきか？</li>
</ul>
<h2>セキュリティは誰の責任か</h2>
<p>文中の表現を借りれば、本書は SRE book や SRE workbook では触れられていなかった、 SRE におけるセキュリティへの関わり方をまとめた1冊にあたる。ただ、必ずしも SRE だけに向けられた内容ではないし、ましてや SRE がセキュリティに関する最終責任を担うべきだ、といった論調でもない。</p>
<p>本書で繰り返されているのは、セキュリティはすべての人の責任であるということだ。専任の専門家だけではなく、すべての人がセキュリティの確保に携わるべきだとしており、 Preface においては対象読者について以下のように書かれている。</p>
<blockquote>
<p>Because security and reliability are everyone’s responsibility, we’re targeting a broad audience: people who design, implement, and maintain systems. We’re challenging the dividing lines between the traditional professional roles of developers, architects, Site Reliability Engineers (SREs), systems administrators, and security engineers.</p>
</blockquote>
<h2>信頼性とセキュリティの共通点</h2>
<p>本書では「セキュリティ」という概念を、 SRE における「信頼性」の概念と似た性格のものとして取り扱っている。いずれもソフトウェア開発において、速度を優先するというエクスキューズによって軽視される場合が多く、サービスが順調に運用されているうちは、不可視なものになりがちだ。しかしながら、サービスの成熟後に見直しを掛けることは困難であり、信頼性もセキュリティも、設計初期の段階から考慮するのが望ましい。</p>
<p>このような似た性格を負っているため、 SRE が有する信頼性確保に関するプラクティスを、セキュリティ施策にも応用できる。例えばインシデント発生を的確に検出するためには、いずれも可観測性の向上や、適切なロギングが欠かせない。実際にインシデントが発生した場合に備えた、危機対応手順を整備しておくことも必要になる。「100% 完全な状態」というのが不可能というのも両者の共通項であり、本書の中では言及がないが、 SLO の考え方をセキュリティに適用することもまた可能だろう。 eureka による <a href="https://speakerdeck.com/takuya542/auditabilitywosretimufalsecheng-guo-zhi-biao-nijia-etahua">Security / AuditabilityをSREチームの成果指標に加えた話 - Speaker Deck</a> では、実際にセキュリティ関連の指標を SLI として取り入れた例が紹介されている。</p>
<h2>セキュリティ専門家の必要性</h2>
<p>先ほど「セキュリティはすべての人の責任である」という一節に触れたが、これは専門的なセキュリティエンジニアが必要ないということを意味しているわけではない。Chapter 20. Understanding Roles and Responsibilities において、セキュリティに誰が取り組むべきかという点に関してより踏み込んだ解説がされている。</p>
<p>信頼性とセキュリティが性格的に似ている、というアナロジーに今一度頼ろうと思うが、信頼性に関しても SRE だけが集中的に担うものではなく、「すべての人」が意識するべきであり、開発ライフサイクルに組み込むべきだというのが SRE book などで書かれていることだ。しかし、だからと言って SRE が必要ないわけではなく、信頼性確保のスペシャリストの立場から、開発者の作業に協力していくことになる。セキュリティエンジニアについても同様に、微妙な判断を迫られる場面などにおいて専門的見地が必要になるとしている。</p>
<p>では、セキュリティエンジニアを組織内のどこに配置するか。これに関してはいくつかのパターンが紹介されているが、興味を引かれたのは中央に独立したセキュリティチームを置くパターンだ。これによりセキュリティを犠牲にしてローンチを急いでしまうような場面において牽制が働くわけだが、当然ながら開発速度低下が懸念される。そこで各チームにはセキュリティチャンピオンと呼ばれるポジションを設け、セキュリティチームとのコラボレーションを促進する役割を務めることで、開発速度とセキュリティ双方のバランシングを行う。</p>
<p>ちなみに、この「セキュリティチャンピオン」という概念を僕は初めて知ったが、本書が初出というわけではないようで、2014年に <a href="https://xtech.nikkei.com/it/article/NEWS/20140320/545025/">開発チームのなかに「セキュリティチャンピオン」を作れ――AppSec APAC 2014から | 日経クロステック（xTECH）</a> で言及されていたりする。開発チームのセキュリティ意識を向上させる上でも、非常に良い施策ではないだろうか。</p>
<h2>Impression</h2>
<p>冒頭に書いた通り、僕の問題意識の発端はセキュリティの「責任主体」の所在にあったのだが、本書はそれを「全員」と言い切っていて目が覚めた思いがした。当然ながら、本書でも書いているように、専門のセキュリティエンジニアを雇い、微妙な問題などについて最終的なジャッジを下してもらえる状態を作ることがベストではある。ではあるが、高い専門性を持ったセキュリティエンジニアは国内の転職市場では不足しがちではあるし、自身でスキルを高めて、カバー可能な範囲のセキュリティには積極的に責任を負っていく姿勢が必要なのだろうと覚悟できた。</p>
<p>なお、 SRE がセキュリティの最終責任を担う組織体系として、国内では mixi の事例を <a href="https://medium.com/mixi-developers/sre-next-2020-98c6edd81d95">SRE NEXT 2020で、SREとセキュリティに関するお話をします | by Isao Shimizu | mixi developers | Medium</a> で見かけた。専門家が不在である際に、最終責任をどこに担わせるかは組織によるだろうが、 SRE はその有力候補にはなり得るだろうと認識している。ただ、やはり SRE のカバースキルが広すぎる結果にはならないか？という懸念はある。タスクとしては担いつつ、可能であればスキル面は外注するといった方策も考えられるかもしれない。</p>
<p>また、そもそもの話として、セキュリティ上の問題でサービスが停止したりすることがあれば、それは信頼性指標（多くの場合可用性など）を損ねる結果にも繋がってくる。そのため SRE は結局のところ、セキュリティと無関係でいられる道理はない。先に挙げた eureka の例のように、セキュリティに関する指標（例えば検知される脆弱性の数 x 個以内）を SLI として採用してしまうのも1つの手かもしれない。信頼性確保のための仕組みを開発サイクルの中に組み込んでいくための SRE のノウハウは、セキュリティに関しても極めて有効なはずだ。この点、メルカリによる <a href="https://engineering.mercari.com/blog/entry/20201214-bea4717e9a/">DevSecOpsとは何か — 導入する組織が増加している理由 | メルカリエンジニアリング</a> なども参考になる。</p>
<p>組織や文化面の問題意識から読んだため、このエントリーでもそういった記述に関して中心に取り上げたが、本書では設計、実装、保守・運用の各フェーズにおけるより具体的なプラクティスも豊富に盛り込まれている。繰り返し書いてきた通り、ポジションを問わずあらゆる人におすすめできる1冊だと感じた。</p>
]]></description>
            <link>https://chroju.dev/blog/building_secure_and_reliable_systems_with_sre</link>
            <guid isPermaLink="false">building_secure_and_reliable_systems_with_sre</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 26 Jul 2021 07:48:45 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Quick7 を BLE Micro Pro で無線化した]]></title>
            <description><![CDATA[<p>はじめに断ると、結構イレギュラーな感じになったのでオススメはしない。</p>
<p>ロータリーエンコーダ付きのマクロパッドというものが欲しくなり、わりと直感的にカッコいいなというのと、必要十分なキー数だなというところで遊舎工房の <a href="https://shop.yushakobo.jp/products/quick7">Quick7</a> を購入した。これ自体は文字通りクイックに作れてとてもいいキットだった。慣れている人であれば1時間とかそこらで作れると思う。</p>
<p>さて問題はここからで、マクロパッドというものはホームポジションで固定的に使う普通のキーボードと違い、ポジションの自由度が高い。そのため使っているうちに有線が煩わしく思えてきた。幸いにして家には、使っていない <a href="https://shop.yushakobo.jp/products/ble-micro-pro">BLE Micro Pro</a> があったので、では無線化しようと思い至ったのだが、そう簡単な話ではなかった。</p>
<h2>BLE Micro Pro との config 互換性</h2>
<p>BLE Micro Pro (BMP) は自作キーボードでよく使われる <a href="https://github.com/qmk/qmk_firmware">QMK Firmware</a> と高い互換性を持ったファームウェアを使用しているが、完全互換ではない。各種設定は QWK ではC言語で定義することになるが、 BMP ではこれを JSON 形式に変換したものを用いる。この2つが1対1には必ずしも対応していない。</p>
<p>Quick7 で具体的に問題となったのは、キースイッチの押下を感知する基盤のピン設定である。多くの自作キーボードでは、 <code>MATRIX_PINS</code> を用いる。これはキーボードを格子配列にみたてて、行列それぞれにピンを割り当てる方式だ。</p>
<p><a href="https://gyazo.com/7e6426020e6f5e4ec1f9f3a48f76355a"><img src="https://i.gyazo.com/7e6426020e6f5e4ec1f9f3a48f76355a.jpg" alt="Image from Gyazo" width="424"/></a></p>
<p>簡単に言えば上図の1〜6がピン割り当てになる。1と5のピンに通電すれば「D」が押されたと検知する、という具合だ。 QMK Firmware での設定の書き方は、 <a href="https://github.com/qmk/qmk_firmware/blob/bf7e19e9977fc23a41898c90ce973d990717cfb4/keyboards/crkbd/config.h">crkbd (Corne Keyboard)</a> を例にすると以下のようになる。</p>
<pre><code class="language-c">#define MATRIX_ROWS 8
#define MATRIX_COLS 6
#define MATRIX_ROW_PINS { D4, C6, D7, E6 }
#define MATRIX_COL_PINS { F4, F5, F6, F7, B1, B3 }
</code></pre>
<p><a href="https://github.com/sekigon-gonnoc/BLE-Micro-Pro/blob/32358d9f3491cd8fa125908dcf0b43c4dd79c0aa/AboutDefaultFirmware/keyboards/crkbd/crkbd_rev1_master_left_config.json">BMP の場合</a> は以下。</p>
<pre><code class="language-json">"matrix":{"rows":8,"cols":6,"device_rows":4, "device_cols":6,
	"debounce":1,"is_left_hand":1,"diode_direction":0,
	"row_pins":[7, 8, 9, 10],
	"col_pins":[20, 19, 18, 17, 16, 15],
</code></pre>
<p>一方 Quick7 など、一部のマクロパッドにおいては <code>MATRIX_PINS</code> ではなく、１キーにつき1ピンを割り当てる、 <code>DIRECT_PINS</code> という設定を用いている。キー数が少ない故、マトリクスの形を取らなくとも、 Pro Micro のピンが足りるためと思われる（設計者ではないので断言ができない）。そして現状、 BMP の config.json は <code>DIRECT_PINS</code> に対応していない。</p>
<p>ではどうしたか、だが、擬似的に 1x9 のマトリクスとみなすことで対処した。</p>
<p>実は、 <code>MATRIX_PINS</code> で設定している際、行列双方のピンが通電していなければ、キーを検知しないわけではない。例えば先の図で1番のピンだけが通電したとする。このときは、A、D、Gの3キーが押されたと検知する。したがって 1x9 のマトリクスとみなし、 <code>DIRECT_PINS</code> として設定されていた9つのピンを各列に設定すれば、各キー入力の検知は可能になる。</p>
<p>具体的には、 Quick7 の <a href="https://github.com/qmk/qmk_firmware/blob/2ae39ccf380ba3f934295501074c448e60e1c066/keyboards/yushakobo/quick7/config.h">QMK Firmware における DIRECT_PINS</a> は以下の設定であり、</p>
<pre><code class="language-c">#define DIRECT_PINS { \
      { D2, D4, F4 }, \
      { D7, B1, B3 }, \
      { E6, B4, B2 }, \
}
</code></pre>
<p>これに対し、 BMP をこのように設定した。ピンの表記が双方で異なるためわかりづらいかもしれないが、 <code>DIRECT_PINS</code> の各行のピンを横に並べ直すような形で <code>col_pins</code> に設定している。</p>
<pre><code class="language-json">"matrix":{"rows":1,"cols":9,"device_rows":1, "device_cols":9,
	"debounce":1,"is_left_hand":1,"diode_direction":0,
	"row_pins":[13],
	"col_pins":[10, 11, 14,  9, 16, 15, 2, 7, 20],
</code></pre>
<p>ちなみに <code>row_pins</code> に設定している13ピンは、 Quick7 では使われていないピンをダミーで設定した。</p>
<h2>電池基盤格納の物理的な問題</h2>
<p>BMP を稼働させるには、別途<a href="https://shop.yushakobo.jp/products/ble-micro-pro-battery-board?_pos=1&#x26;_sid=9a957617c&#x26;_ss=r">電池基盤</a>を接続する必要がある。 Quick7 はかなりコンパクトな筐体であるため、これをどこに格納するかが問題になった。</p>
<p>多いパターンとしては、遊舎工房で販売されている電池基盤が BMP とほぼ同じ大きさのため、 BMP の裏側に載せるような形で格納するパターンだ。実は手元にあった BMP は、すでにこの形で電池基盤をはんだ付けしてあるものだった。しかし、 Quick7 はトッププレートとボトムプレートの間を 10mm のスペーサーで結んでおり、この隙間に電池基盤付きの BMP は収まらなかった。</p>
<p><a href="https://gyazo.com/da3ca45dc0437e66dc3b079e9755e490"><img src="https://i.gyazo.com/da3ca45dc0437e66dc3b079e9755e490.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>結論としてはシンプルに、 15mm のスペーサーに換装することで対応した。電池基盤を BMP と接着せず、横に並べるような形で配置すれば、もう少し薄くすることは可能かもしれない。</p>
<h2>Conclusion</h2>
<p>はじめに書いたことの繰り返しだが、特にこういったやり方をおすすめする記事ではなく、技術的なメモに近い内容である。ロータリーエンコーダ付きマクロパッドでは、公式に BMP 対応している <a href="https://palette1202.nilgiri-tea.net/">Palette1202</a> なども存在するので、そちらを使ったほうがスムーズかもしれない。また、 QMK Firmware や BMP に僕自身そこまで詳しいとは思っていないので、ここで書いた方法以外の何かスマートな解決策が存在する可能性もある。</p>
<p>とはいえ出来には満足している。普段使いは Corne Cherry で長らく落ち着いてしまったが、たまにはこうやってキーボードを作ることも続けてみたい。</p>
]]></description>
            <link>https://chroju.dev/blog/quick7_with_ble_micro_pro</link>
            <guid isPermaLink="false">quick7_with_ble_micro_pro</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 04 Jul 2021 14:20:58 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[このブログの Lighthouse スコアをほぼ満点にした]]></title>
            <description><![CDATA[<p><a href="https://github.com/GoogleChrome/lighthouse">Lighthouse</a> は Google が公開している、ウェブサイトの監査ツールである。 Performance 、 Accesibility 、 Best Practices 、 SEO 、 PWA という5つの項目に関して監査を実施し、 PWA 以外の4項目については100点満点でのスコアリングを行い、 PWA については機能的な対応状況を確認してくれる。 <a href="https://chrome.google.com/webstore/detail/lighthouse/blipmdconlkpinefehnmjammfjpmpbjk?hl=ja">Chrome Extension</a> と Node による CLI が提供されており、また Chromium ベースのブラウザであれば、 Devtools 内で実行もできる。なお、現時点においては PWA 機能に重点を置いた監査内容になっている。</p>
<p>今回、このブログの Lighthouse スコア改善に取り組んでみた。背景としては、 <a href="https://chroju.dev/blog/blog_with_next_js_vercel">ブログを Next.js + Vercel に移行した - the world as code</a> のときに書いた以下の一節がそのまま当てはまる。</p>
<blockquote>
<p>僕はインフラエンジニア出身の SRE で、経歴を辿るとサーバーや RDB のチューニングでパフォーマンスを維持することには注力してきたけど、フロント側の知識はほぼまったくと言っていいほどない。でも SRE がサイトの信頼性、具体的にはレスポンスの最適化に責務を負っているのに、フロントを理解していないというのはダメだろうと。静的なものを可能な限り CDN に置く時代において、サーバーのインフラ的なチューニングだけの知識だけでは心許なくなった。</p>
</blockquote>
<p>ということで、ウェブアプリの品質とはどのような点が見られるのか、理解を深めることを目的としている。</p>
<h2>Before / After</h2>
<p>最初にスコアの Before / After を貼っておく。対象は先にも挙げた <a href="https://chroju.dev/blog/blog_with_next_js_vercel">ブログを Next.js + Vercel に移行した - the world as code</a> のページである。</p>
<p><img src="/images/2021-06-27/score_before.png" alt="score before">
<img src="/images/2021-06-27/score_after.png" alt="score after"></p>
<p>いずれのスコアも大幅に改善し、ほぼ満点の状態まで引き上げることができた。 Lighthouse の評価ポイントは、 Google が公開している https://web.dev/ にまとめられており、今回のスコア改善にあたっても、主にここを参考として取り組んだ。</p>
<p>ちなみに Best Practices がもともと100点を獲得しているが、 Next.js + Vercel という新しめのフレームワークとデプロイ環境を用いていることもあり、何も考えずともある程度自動的にチューンナップされている面はあるのだと思う。</p>
<p>以下、改善した点を順に見て行く。</p>
<h2>Performance</h2>
<p>パフォーマンスでは、主に表示速度の面でのメトリクス6種類が指標になる。表示速度というと、インフラ側の人間としては単に response time という言葉で括って考えがちなのだが、最初に DOM element が表示されるまでの時間を示した First Contentful Paint (FCP) 、 Largest Contentful Paint (LCP) など、実際にページを表示するクライアントの立場から見れば、複数の観点で速度評価が可能なのだということを知った。</p>
<h3>画像の改善</h3>
<p><img src="/images/2021-06-27/performance_image.png" alt="score before"></p>
<p>Performance で減点材料となったものの1つが画像だった。容量が大きすぎる、あるいは次世代フォーマットである WebP を使うべきだといったものだ。たかがアバター画像で 450KiB は確かに重いかもしれない。</p>
<p>シンプルに WebP 化で改善を図った。 macOS であれば <code>brew install webp</code> でインストールされる <code>cwebp</code> コマンドで簡単に変換ができる。結果、これだけで効果は抜群だった。</p>
<pre><code class="language-bash">❯ ls -l profile.*
-rw-r--r--@ 1 chroju  staff  7181  1 17 19:03 profile.jpg
-rw-r--r--  1 chroju  staff   754  6 25 19:47 profile.webp
</code></pre>
<p>WebP は Safari (iOS/macOS) が2020年になってから標準サポートするなど、まだまだ新しいフォーマットであり、商用のウェブサイトであればきちんと png/jpeg と表示を分けたり、手動変換ではなく <a href="https://www.sakura.ad.jp/services/imageflux/">ImageFlux</a> などによる自動変換を検討するべきだろう。今回はあくまで個人サイトなので、妥協した方式を採っている。</p>
<p>ちなみに、このブログの画像はアバター以外は基本的に <a href="https://gyazo.com">Gyazo</a> 上のものをリンクしており、これについては現状もそのままになっている。当然ながら自ドメイン上にホストしたほうが表示は速くなるので、 Gyazo リンクをやめることも検討している（このエントリーでは試験的にやめてみている）。</p>
<h3>Reduce initial server response time</h3>
<p><img src="/images/2021-06-27/performance_initial_response.png" alt="initial server response time"></p>
<p>TTFB (Time to first byte) の改善を促されている。これについてはインフラ面の改善も視野に入ってくるが、このブログではフルマネージドな Vercel を使っているので、その点での改善は望めない。また、無駄に SSR を使っている箇所があれば SSG を使えないか検討するという手もあるが、このブログは全面的に SSG で組んでいるので、その点も問題はなかった。従って打つ手が難しかったのが正直なところ。</p>
<p>ひとつ気になった点として、レスポンスがキャッシュからのものか否かを Lighthouse は考慮していなさそうだという点があった。というのも、一度ページにアクセスして CDN キャッシュを作ってから再度 Lighthouse に掛けると、このスコアが改善したからだ。 response time の改善においては、キャッシュ活用も含めて検討したほうがいいかもしれない。</p>
<h3>Reduce JavaScript execution time</h3>
<p><img src="/images/2021-06-27/performance_js.png" alt="JavaScript execution time"></p>
<p>JavaScript 実行時間の改善も促された。最も実行時間が長いスクリプトを確認したところ、 <a href="https://github.com/FortAwesome/react-fontawesome">FortAwesome/react-fontawesome</a> であった。使っているアイコンだけではなく、横着してすべてのアイコンを読み込むような設定を書いていたので、これは明確に自分が悪い。これだけで JS の総実行時間が 1.5s -> 0.6s に改善した。</p>
<pre><code class="language-diff">- import { fab } from '@fortawesome/free-brands-svg-icons'
- import { fas } from '@fortawesome/free-solid-svg-icons'
+ import { faGithub, faKeybase, faSpeakerDeck, faTwitter, faInstagram } from '@fortawesome/free-brands-svg-icons'
+ import { faRssSquare, faTags } from '@fortawesome/free-solid-svg-icons'
</code></pre>
<h2>Accessibility</h2>
<h3>Contrast</h3>
<p><img src="/images/2021-06-27/accessibility_contrast.png" alt="Contrast"></p>
<p>Accessibility の点では、色のコントラストで警告が出ていた。エントリーの日付表記の部分はフォントカラーを薄いグレーにしていたのだが、これが背景とのコントラストが十分ではなく、視認性が悪いとのことだった。</p>
<p><img src="/images/2021-06-27/accessibility_devtools.png" alt="Contrast Devtools"></p>
<p>色のコントラストは Devtools の「Elements」タブで color をクリックすることで、適切な状態を確認できる。適切なコントラストは <a href="https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html">WCAG で規定されており</a>、最低でも 4.5:1 を確保したレベル AA 、より望ましくは 7:1 のレベル AAA を満たすべきとされている。上図、グラデーション状態のカラーパレットに波線が引かれているが、このうち上のラインがレベル AA で、下のラインがレベル AAA に当たる。今回はこれを用いてレベル AAA を満たすように文字色を改善した。</p>
<h3>Others</h3>
<p>その他、軽微なところで以下の2点を改善している。</p>
<ul>
<li><code>&#x3C;html></code> に lang 属性が指定されていなかった</li>
<li>Font Awesome によるリンクアイコンに text の設定がなく、スクリーンリーダーなどに対して Not friendly な状態だった</li>
</ul>
<h2>Best Practices</h2>
<p>ここは当初より100点だったので、改善したポイントはない。主に以下のようなポイントがチェックされる。</p>
<ul>
<li>HTTPS を利用している</li>
<li>ロード時に位置情報取得や通知の許可を求めていない</li>
<li>パスワードフィールドへの「ペースト」を禁止していない</li>
<li>フロントエンド JavaScript に既知の脆弱性が存在しない</li>
<li>非推奨の機能（<a href="https://web.dev/appcache-removal/">AppCache</a> や廃止された API）を用いていない</li>
<li>charset や doctype が正しく宣言されている</li>
</ul>
<h2>SEO</h2>
<h3>Tap targets are not sized appropriately</h3>
<p><img src="/images/2021-06-27/seo_tap_targets.png" alt="SEO tap targets"></p>
<p>タップ可能な要素が小さすぎるという警告。スマートフォンで表示した際の誤タップを防ぐべく、最小でも 48x48px を保つようにとされている。</p>
<p>具体的には、ページ最下部に設置した各種ソーシャルサービスのアイコンであり、必要とされるサイズを確保できるように CSS を書き換えた。</p>
<h2>PWA</h2>
<p>PWA に関しては、ここまで見てきた項目のように採点の対象というわけではなく、 PWA として動作するのに必要な設定が成されているかどうかをチェックし、その結果をアイコンで表示するというものになっている。</p>
<p>せっかくなので、今回 PWA 化も施した。モバイルでもデスクトップでも、対応するブラウザで開けばインストールが可能になっている。本当にただ PWA としての要件を満たす状態にしてみた、というだけなので、インストールしたところで更新通知を飛ばしたりとかはしない。オフラインの際に、専用のページへフォールバックさせる、ぐらいのことはしてみている。</p>
<p><img src="/images/2021-06-27/pwa.jpg" alt="PWA"></p>
<p>Next.js における PWA 化は <a href="https://github.com/shadowwalker/next-pwa">shadowwalker/next-pwa</a> を使うのが簡単で、 README 内で <code>Zero Config</code> を謳っているが、実際のところ2、3ファイルを少し書き換えるだけで PWA 化できるようになっている。</p>
<h2>Impression</h2>
<p>少し意外、と言ったらよろしくないかもしれないが、 監査項目において過剰に Google Friendly にするべきだ、というようなものはなく、中立的に Web サイト（Web アプリ）としてクリアしておくべき条件のリストになっていると感じた。例えば AMP に関するチェックが入ってもおかしくはないように思うが、2021年現在においてはすでに下火になりつつあることもあってか、そういった項目はなかった（このあたりの経緯は、折しも昨日 <a href="https://blog.jxck.io/entries/2021-06-26/amp-tone-down.html">本サイトの AMP 提供の停止とここまでの振り返り | blog.jxck.io</a> というエントリーが出たのでちょうど読んだところだったりする）。もっとも、そうは言ってもあくまで Google の採点である、ということには留意が必要かもしれない。 Performance の項で測られている項目も、 Google が掲げる <a href="https://web.dev/vitals/#core-web-vitals">Core Web Vitals</a> との重複が大きい。</p>
<p>とはいえ Lighthouse が「より良い Web サイト」を作る上で1つの指標となるのは確かだし、ここに書いた修正項目は、いずれも納得感を持って修正を加えることができた。インフラよりの技術スタックを持っていると、この中で日頃気にしているのは Performance と Best Practices の一部項目ぐらいがメインだった。しかし UX という点では単に Origin からのレスポンスを早く返すだけではなく、 JS の読み込みといった部分も考慮するべきだし、画像も数が増えてくればより優れた配信方式を検討する必要が出てくる。こういった学びは今後に活かしていきたい。</p>
]]></description>
            <link>https://chroju.dev/blog/improve_lighthouse_scores</link>
            <guid isPermaLink="false">improve_lighthouse_scores</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 28 Jun 2021 00:19:25 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Toil とどう向き合うか]]></title>
            <description><![CDATA[<p>SRE をやっていく上で、「Toil」という概念は切っても切り離せないものであるわけだが、今更ながら「Toil」とはそもそも何なのかということを頭の整理も兼ねてまとめてみたい。</p>
<h2>Toil とは何であるのか</h2>
<p>定義については Google のエンジニアが書いている2冊の書籍『<a href="https://www.oreilly.co.jp/books/9784873117911/">SRE サイトリライアビリティエンジニアリング（以下、 SRE book）</a>』『<a href="https://www.oreilly.co.jp/books/9784873119137/">サイトリライアビリティワークブック（以下、 SRE workbook）</a>』が原典にあたる。これらによれば、 Toil は一言でこう、と言えるものではなく、以下のように複合的な性質を持つタスクのことを呼んでいる。</p>
<ul>
<li>手作業であること</li>
<li>繰り返されること</li>
<li>自動化できること</li>
<li>戦術的であること</li>
<li>長期的な価値を持たないこと</li>
<li>サービスの成長に対してO(n)であること</li>
</ul>
<p>難しいのは、これらが AND 条件でもなければ OR 条件でもないということだ。 SRE book の5章から引く。</p>
<blockquote>
<p>トイルと見なされるすべてのタスクが、必ずしもこれらの性格をすべて備えているわけではありませんが、以下の説明の1つ以上に当てはまるような仕事であれば、その仕事のトイルの度合いは高いと言えるでしょう。</p>
</blockquote>
<p>つまるところ、これらは Toil であるか否かを判別する絶対的な条件というより、 Toil の持つ傾向、性格を表した言葉と考えたほうがいいだろう。 Toil と呼ばれるタスクが、結果的にこういった性格を備えている「場合がある」ということであり、その逆 = こういう性格を備えたタスクが Toil である、とは必ずしも成り立たない。</p>
<p>それを踏まえた上で、改めて Toil をどう定義するかだが、先の6つの性格より、同じく SRE book 5章における以下の記述がより本質を表している。</p>
<blockquote>
<p>私たちがこの50%のゴールを共有するのは、トイルというものは、確認しないままにしておけば拡大し、急速に全員の時間の100%を埋め尽くしてしまう傾向があるためです。トイルを減らし、サービスをスケールさせる作業が、サイトリライアビリティエンジニアリングにおける「エンジニアリング」です。エンジニアリングの作業によって、SREの組織の規模はサービスのサイズに比例しなくなり、純粋な開発チームや運用チームに比べて、より効率的にサービスを管理できるようになるのです。</p>
</blockquote>
<p>サービス（ここで言う「サービス」はプロダクトの意味というよりは、マイクロサービス的な文脈と捉えている）が拡大、もしくは数を増やしていくとき、比例的に増大して人的リソースを消費するものが Toil である。この側面から捉えたほうが Toil を考えやすいのではないだろうか。例えば、プログラムにより自動化されているタスクであっても、サービスが増えたときにプログラムの改修が常に必要なようでは、運用負荷の高い Toil に成り得る。ソフトウェア開発において、プログラマーはコードのエントロピー増大に向き合うことを求められるが、それと同じ事をソフトウェアやサービスを取り巻くあらゆるタスクに敷衍したのが Toil の考え方だと捉えている。</p>
<h2>Toil とは何ではないのか</h2>
<p>Toil とは何であるのかをさらに深掘りするべく、傍証として、逆に Toil は何では「ない」のかをいくつか挙げてみたい。</p>
<h3>Toil とは運用作業全般のことではない</h3>
<p>つまるところ Toil ＝ 運用作業（ここでは、ローンチ後のサービスを保守、維持するためのタスクを「運用作業」と呼ぶことにする）のことだと言いたくもなる。これについては若干判断が難しいところがあって、というのも SRE book と SRE workbook で若干言っていることが違うのだ。</p>
<blockquote>
<p>GoogleのSREの組織では、運用作業（つまりはトイル）を、各人の作業時間の50％以下にするという目標が掲げられています。 （SRE book 5章 トイルの撲滅）</p>
</blockquote>
<blockquote>
<p>Google は、 SRE チームが運用作業（これにはトイル中心の作業もそうでない作業も含まれます）に費やす時間を50%に制限しています （SRE workbook 6章 トイルの撲滅）</p>
</blockquote>
<p>SRE book では両者をほぼイコールのように書いているが、 workbook では、運用作業には「Toil 中心ではない作業」も含まれると書かれている。「中心ではない」というだけで、結局は Toil なのかもしれないが、 SRE book とは書きっぷりが明らかに違う。</p>
<p>僕としては運用作業 ≠ Toil だと捉えている。例えば年に1回程度発生するが、自動化にはそれなりに工数が必要そうな運用作業があったとして、これは Toil だろうか。「繰り返される」という条件には当てはまるが頻度が低いし、「自動化が可能」ではあるものの、工数的にベネフィットがそれほど得られるかはわからない。であるならば、これは運用作業ではあるが、 Toil には分類されない、と考えることもできるのではないか。</p>
<p>あるいは、こういった厳密な Toil / not Toil の仕分けを行うほうが手間でもあるし、 Toil は根こそぎ洗い出して消滅させなければならないものでもないので、あえて運用作業全体をざっくり Toil と扱ってしまうのも手かもしれない。その中でより Toil としての性格が強いものもあれば、そうではないものもあるわけだが、より性格の強いものや、作業時間を圧迫しているものから削減を図っていけば、運用上の支障はなさそうだ。</p>
<h3>トイルとは「つまらない作業」のことではない</h3>
<p>これは SRE book 5章に、明確に「No」であると書かれている。</p>
<blockquote>
<p>トイルは、単なる「やりたくない仕事」ではありません。
つまらない仕事には、長期的な価値があることもあります。そうであれば、それもトイルではありません。</p>
</blockquote>
<p>運用作業にはつまらないもの、大変なものも少なくない。しかし、長期的に価値があるのであれば、それは Toil = 削減対象ではなく、きちんと向き合うべきだというのが SRE book の主張だ。思いつくものとしては、ゼロデイや脆弱性への対応などだろうか。まぁ「つまらない」は主観でしかないので、個人差が大いにあるところだが。</p>
<p>とはいえ、つまらない作業は誰だってやりたくないし、なるべくなら減らしたいと考えるのが自然だろう。その関連で少し触れたいのだが、都内に NoOps Meetup という勉強会がある。</p>
<p>https://www.publickey1.jp/blog/18/noopsnoopsnoops_meetup_tokyo_1.html</p>
<p>名前だけ聞くとかなり過激というか、思い切ったことのようにも聞こえるが、実際には「No Uncomfortable Ops」を掲げており、システム運用作業における「嬉しくない」ことを削減することを目的としている。これは単に「やっていて嬉しくない」というだけではなく、障害のようなユーザーにとっての「嬉しくない」こと、コスト的に「嬉しくない」ことも含まれる。</p>
<p>SRE book では、 Toil を削減するべき理由として、士気の低下を招くということも書かれている。長期的な価値のある作業であれば、徒労感も薄くて士気は下がりにくいと言いたいのだろうが、それは人によると言わざるを得ないし、「やりたくない」ことを減らそう、なるべく自動化しようというのはモチベーションとしてわかりやすい。つまらない作業 = Toil ではないのだが、つまらないことに忙殺されているか、敏感になる必要はありそうだ。</p>
<h2>結局のところトイルとは何か</h2>
<p>そもそも、自分がなぜ Toil の定義にこだわっていたのかと言えば、定義できないものは見つけようがないからだ。SRE として Toil の抑制を図りたいならば、 Toil を見つけなくてはならない。 Toil を見つけるには、 Toil とは何であるのかを定義しなくてはならない。しかし、ここまで見てきたとおり、 Toil とは XXX である、と一言で言い表せるようなものではない。似た性格を持つ単語はいくらか挙げられるが、厳密な定義を考えていくと、それらとイコールで結ぶことはできなくなる。</p>
<p>結論としては、 Toil が何であるか厳密な定義は必要ないと考えている。「 Toil を減らしたい」という言い方をすると、「ではまず Toil なるものを屏風から出してください」という気分になってしまうのだが、どちらかと言えば「 Toil 的なもの」を減らす、ぐらいの心構えでいいのではないか。目的は Toil を厳密に見つけていくことではなく、サービス拡大を妨げるような運用コストの増大を抑制することにある。この目的にさえフォーカスできていればいいのではないか。</p>
<p><a href="https://cloud.google.com/blog/ja/products/gcp/identifying-and-tracking-Toil-using-sre-principles">SRE の原則に沿ったトイルの洗い出しとトラッキング | Google Cloud Blog</a> においては、 Toil の洗い出しの一環として、チームメンバーへのアンケート調査を勧めている。</p>
<blockquote>
<p>どのくらいの時間をトイルに費やしましたか。全体に占めるおおよその割合を、過去 4 週間の平均値でお答えください。</p>
</blockquote>
<blockquote>
<p>トイルに費やした時間の長さについてどの程度満足していますか。</p>
</blockquote>
<p>文面に書かれているとおり、あくまで訊かれているのは「おおよその割合」である。ここで重視されているのは客観的に定義できる Toil の量ではなく、メンバーの主観に基づく負担量やストレス、認知的過負荷といった部分だ。SRE book 『5.4 トイルは常に悪なのか？』でも言及されている通り、簡単なタスクでささやかな達成感を生んでくれるような肯定的な側面も Toil にはある。重要なのは Toil が存在すること自体より、それが無秩序に増大することによる士気の低下のほうだ。</p>
<p>サービスの増加、トラフィックの増大によって増えてしまう運用コストを抑制し、無闇に人員を増やすことなく、安定的なサービスのスケールを行うことが SRE には求められている。SRE にとってもう1つの大きな役割であるSLOとエラーバジェットの管理も、同じ目的に沿うものと言えるわけで、つまるところ SRE とは、サービスの安定的なスケールを、ソフトウェアエンジニアリングによって支援していくことをミッションとした職種なのだと考えている。</p>
]]></description>
            <link>https://chroju.dev/blog/what_is_toil</link>
            <guid isPermaLink="false">what_is_toil</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 16 Jun 2021 03:32:13 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[読んだ記事などを「週報」として notion にまとめ始めた]]></title>
            <description><![CDATA[<p>先日、 <a href="https://chroju.dev/blog/zenn_scrap_with_web_scrap">Zenn の Scraps を、読んだ記事をまとめる場として使ってみる - the world as code</a> という話を書いて、3週間ほどやっていたのだが、大きく3つの理由があってやめることにした。</p>
<ul>
<li>export が現状できないっぽい</li>
<li>検索機能がない</li>
<li>こういう用途で使っているのが自分ぐらいしかいなさそう</li>
</ul>
<p>Zenn Scraps に読んだ記事をまとめ始めた発端は、何かウェブ記事を読んでも、どこにも記録せず霧散してしまうということが少なくなかったからで、定量的な記録として始めていた。実際のところ、読んだ記事すべてを適当に放置していたわけではなく、すぐに活用できそうなものは Scrapbox にまとめている。すぐには活用できないけど、取りあえず頭の片隅に置いておきたい、いつか使えそう、みたいな記事が記録されず「霧散」していたのが課題であり、それを記録する場が欲しかったわけなので、後からログを簡単に辿ったり、検索できたりすることは結構必須の要件だった。それができないとなると利用は難しいかな、という結論になった。</p>
<p>また、どうも Scraps をこういう風に使っている人が他にはいなさそうというのも気にかかった。気にしなくていいのかもしれないとは思う。ただ、Zenn はすべての記事を投稿順にチェックできる UI があり、更新するとそのトップに一時的であれ掲載されることになるので、他の人の目に入る機会がなくはない。それを考えると、あまりに自己本位の目的で、こういうパブリックなコミュニティサイトを使うのはちょっと良くないかもな、と考えるに至った（自分の感傷の問題なので、 Zenn の在り方を問うつもりはないです）。</p>
<p>UX 、使い勝手の面ではかなり気に入っていたので残念ではある。特に Scraps はスレッド型になっているので、あるウェブ記事に関して、補足情報を「レス」の形で追記していけたのがとても体験が良かった。</p>
<p>そして移行先としては notion を使ってみることにした。</p>
<p><a href="https://gyazo.com/7bcf2cac60f6bc8625f36e1352022b97"><img src="https://i.gyazo.com/7bcf2cac60f6bc8625f36e1352022b97.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>https://www.notion.so/Journal-5a988ea052794b88b84d5d06e3b9d6e8</p>
<p>読んだものを記録する習慣を付けるならば、 GUI でサッと書ける場所がいい。検索したい。エクスポートもできるといい。そしてコミュニティサイトを間借りするのではなく、自分専用のスペースの方が気が楽、などというあたりを満たすのが notion かな、という結論。</p>
<p>自分専用の場になったので、技術的なことだけを書かなくてはならないわけでもなくなり、広く日誌のような使い方をしてみようと考えている。 <a href="https://logbook.yuuk.io/">yuuk1/logbook</a> にインスパイアされた面も小さくない。こんな研究日誌は僕には書けないけれども。今のところは読んでいた本の記録と、 journal のトップページに貼ってある <a href="https://pixe.la">Pixela</a> のグラフは、ポモドーロの実行回数を示している（ホットキーを押すとポモドーロタイマーが起動しつつ、 Pixela に webhook を送るような環境を整えている）。自分のコンディションを概観できる場として使っていきたい。</p>
<p>jounarl.chroju.dev みたいなカスタムドメイン振れると嬉しいな、というのも考えたけれど、今のところスマートに実装する方法がなさそうだし、そこまでちゃんとパブリックにしたい場所でもないので見送っている。 <a href="https://super.so/?via=knj">Super</a> という、外部公開した Notion page にカスタムドメインや CDN を付与してくれるサービスがあるらしいが、基本有料なのでステイ。</p>
<p>またしばらくこれで続けてみようと思う。</p>
]]></description>
            <link>https://chroju.dev/blog/journal_with_notion</link>
            <guid isPermaLink="false">journal_with_notion</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 28 May 2021 10:59:45 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Zenn の Scraps を、読んだ記事をまとめる場として使ってみる]]></title>
            <description><![CDATA[<p>「あとで読む」つもりで溜め込んでいた記事を GW にまとめて読んでいたところ、久しぶりに味わう刺激というか快感を覚えまして、それで最近あんまり input 出来ていなかったな、ということに気付きまして。 RSS の消化はいつも通勤電車の中でこなしていたから、 WFH になってから格段に読んでいる数は減っている。</p>
<p>なので意識的に input 増やそうと思い立ち、となると input した数をちゃんと計測して KPI として計れるようにしたいなという発想に至り、そのための手段をいろいろ考えた結果、 <a href="https://zenn.dev">Zenn</a> の Scraps を当座使ってみようということにしてみた。</p>
<p>Zenn についてはだいぶ話題になったのでご存知の方も多いでしょうが、IT系エンジニアのための情報共有コミュニティ。ザッと見たところ「IT系」という明記がなく、単に「エンジニア」と書かれているので、もしかしたら「IT系」じゃなくてもエンジニアリングの話であれば書いて良いのかもしれない。どうなんだろう。で、ここにいわゆるブログのようなまとまった記事を上げる以外に、 <a href="https://zenn.dev/zenn/articles/about-zenn-scraps">Scraps</a> という機能がある。</p>
<blockquote>
<p>スクラップは、スレッド形式で知見やメモをまとめていく機能です。最初にテーマを決めてスクラップを作成したら、あとは自分の好きな単位で、好きなときに情報を足していきます。</p>
</blockquote>
<p>何か調べものをするときとか、手元でメモしながら進めていくことがよくあるけど、それをパブリックにできるイメージ。 <a href="https://naoya-2.hatenadiary.org/entry/20131107/1383792634">「書く」のは特別な道具 - naoyaのはてなダイアリー</a> という話が好きで、僕もよくアウトライナーなんかに書き下しながら考えをまとめたり、何か調べたりすることはよくやっているんだけど、それを公開して誰でも見られるようにする、というのは結構面白いな、と思う。内容は右往左往しているようなものになるので、直接的にそれが他人に「役立つ」ものになるかはわからないけど、他人の scrap を読むと他人の思考を追跡できそうな気がする。</p>
<p>で、ここに読んだ記事を週単位でまとめることを始めてみた。</p>
<p>https://zenn.dev/chroju/scraps/2cf62108a159be</p>
<p><a href="https://gyazo.com/b9d3ef92ae2edb6612c1a1156b185844"><img src="https://i.gyazo.com/b9d3ef92ae2edb6612c1a1156b185844.png" alt="Image from Gyazo" width="600"/></a></p>
<p>こういう感じ。読んだ記事をペタッと貼り付けて、はてブや Twitter の感覚で適当に感想を何かしら書き殴る。あくまで自分用のつもりで書いているので、他人にわかりやすいかどうかは気にしないことにしている。</p>
<p>もちろん、はてブや Twitter でも出来ることではあるのだが、いずれも字数制限が煩わしいし、一度開くと無限に時間を吸い取られる類いのものだからあまり開きたくなかったりもする。 Zenn Scraps なら字数制限はないし、スレッド形式なので、後から追記したいことやさらなる気付きがあれば、「レス」の形で付け足せるのもいい。週単位で Scraps を閉じていけば、 input 量の定量化もわかりやすくなる。</p>
<p>難点としては「このページに辿り着くまでが面倒」というのはある。 Twitter であれば常に1つのパーマリンクを開けばすぐ書き込めるけど、週単位で Scraps を作ると常にリンクが変わってしまうし、 Zenn のトップからわざわざ辿るのも面倒。今は Vivaldi のウェブパネルという、よく訪問するサイトをサイドパネルに常駐させる機能を使って、すぐ開けるようにしている。毎週、これを新しいページのリンクへ更新していくということになる。</p>
<p><a href="https://gyazo.com/cbdd7702cc3858a3e99b10011b5ca4a2"><img src="https://i.gyazo.com/cbdd7702cc3858a3e99b10011b5ca4a2.gif" alt="Image from Gyazo" width="600"/></a></p>
<p>まだ始めたばかりで、今後どうなるかはわからないが、わりとイイ感じに work しそうな気はしている。</p>
<h2>追記</h2>
<p>続き→ <a href="https://chroju.dev/blog/journal_with_notion">読んだ記事などを「週報」として notion にまとめ始めた - chroju.dev/blog</a></p>
]]></description>
            <link>https://chroju.dev/blog/zenn_scrap_with_web_scrap</link>
            <guid isPermaLink="false">zenn_scrap_with_web_scrap</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 08 May 2021 01:58:45 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[terraform test コマンドを試してみる]]></title>
            <description><![CDATA[<p><a href="https://www.hashicorp.com/blog/announcing-hashicorp-terraform-0-15-general-availability">Terraform 0.15</a> にて、Terraform module をテストするための実験的機能として <code>terraform test</code> コマンドが追加された。 module は Terraform の設定を抽象化してくれる存在であり、それ故確かに「テスト」の必要性を感じる場面も少なくない。従来は <a href="https://terratest.gruntwork.io/">Terratest</a> のような OSS がこれを担ってきていたが、 Terraform 自体がテスト機能を内包する方向に動き出したことは興味深く感じている。</p>
<p>詳細な背景や使い方は <a href="https://www.terraform.io/docs/language/modules/testing-experiment.html">Module Testing Experiment - Configuration Language - Terraform by HashiCorp</a> に記載されている。これを参考に自分でも test コマンドを試してみたので、その手順と雑感をまとめてみたい。</p>
<h2>terraform test の動作仕様</h2>
<p>まず、 <code>terraform test</code> がどのように動作するのか簡単にまとめる。</p>
<p>このコマンドは module の root で実行する。テストはスクリプトなどではなく、純粋な Terraform の設定（HCL）で記述し、 module root からの相対パスで <code>./tests/</code> 配下にサブディレクトリを作って、その中にファイルを置く形となる。 <code>./tests/</code> 配下には複数のディレクトリを置くことができ、そのすべてがテスト対象として認識される。 module に渡す引数ごとに複数テストパターンを行いたい場合などに、複数ディレクトリを設けることになる。</p>
<p>テストファイル設置後、 <code>terraform test</code> を実行すると、各 <code>./test/*</code> ディレクトリ内の Terraform ファイルに対して、以下が実行される。</p>
<ol>
<li><code>terraform validate</code></li>
<li><code>terraform apply</code></li>
<li>定義されたテストの実行</li>
<li><code>terraform destroy</code></li>
</ol>
<p>module を使って実際にリソースを構築し、その設定が意図したものになっているかテストした上で、構築した全リソースを削除するまでが一連の流れとなる。</p>
<h2>検証</h2>
<h3>test 検証用 module の作成</h3>
<p>今回、 <code>terraform test</code> を検証するにあたり、以下の module を使用した。AWS S3 バケットを作成して、その中にオブジェクトを保存し、ウェブサイトとして公開するものとしている。</p>
<p><code>aws_s3_bucket.this</code> で使用している <code>policy.json.tpl</code> の記述内容や、 provider 定義については、ここでは割愛する。</p>
<pre><code class="language-hcl">variable "bucket_name" {
  type = string
}

variable "bucket_objects" {
  type = map(object({
    object_key   = string
    filepath     = string
    content_type = string
  }))
}

resource "aws_s3_bucket" "this" {
  bucket        = var.bucket_name
  acl           = "public-read"
  policy        = templatefile("${path.module}/policy.json.tpl", { bucket_name = var.bucket_name })
  force_destroy = true

  website {
    index_document = "index.html"
  }
}

resource "aws_s3_bucket_object" "objects" {
  for_each = var.bucket_objects

  bucket       = var.bucket_name
  key          = each.value.object_key
  source       = each.value.filepath
  content_type = each.value.content_type

  etag = filemd5(each.value.filepath)

  depends_on = [
    aws_s3_bucket.this,
  ]
}
</code></pre>
<h3>test の作成</h3>
<p>module を用意したら、その中に <code>./tests/sample</code> ディレクトリを作成してテストファイルを作成していく。先述の通り、書き方は普通の Terraform とあまり変わりはない。</p>
<p>まず provider 定義だが、ここで builtin の test provider を読み込む必要がある。</p>
<pre><code class="language-hcl">terraform {
  required_providers {
    test = {
      source = "terraform.io/builtin/test"
    }
    aws = {
      source  = "hashicorp/aws"
      version = ">= 3.0.0"
    }
  }
}
</code></pre>
<p>これで test 用の resource が使えるようになる。</p>
<p>続いて実際の設定を書いていくが、 module を読み込んでリソース構築するところまでは通常通り書いていく。今回、引数として渡す S3 のバケット名は、AWS の仕様上毎回ユニークなものでなければならないため、 <code>random_string</code> を使ってランダムなサフィックスを付加している。また S3 バケットに配置するオブジェクトは <code>./tests/sample/static</code> 配下に html と JSON の2つを用意しておいた。</p>
<pre><code class="language-hcl">resource "random_string" "suffix" {
  length  = 8
  special = false
  upper   = false
  number  = false
}

locals {
  bucket_name = "chroju-terraform-test-${random_string.suffix.result}"
}

module "s3_website" {
  source = "../.."
  depends_on = [
    random_string.suffix,
  ]

  bucket_name = local.bucket_name
  bucket_objects = {
    index_html = {
      object_key   = "index.html"
      filepath     = "${path.module}/static/index.html"
      content_type = "text/html"
    }
    avater_jpg = {
      object_key   = "test.json"
      filepath     = "${path.module}/static/test.json"
      content_type = "application/json"
    }
  }
}
</code></pre>
<p>ここからテスト本体を書いていく。テストには先の test provider が提供する、 <code>test_assertions</code> resource を用いる。</p>
<pre><code class="language-hcl">data "aws_s3_bucket" "this" {
  bucket = module.s3_website.bucket_id
}

resource "test_assertions" "s3_bucket" {
  component = "s3_bucket"

  equal "bucket_id" {
    description = "bucket id is valid"
    got         = data.aws_s3_bucket.this.id
    want        = local.bucket_name
  }

  check "website_endpoint" {
    description = "website endpoint is not empty"
    condition   = data.aws_s3_bucket.this.website_endpoint != ""
  }
}
</code></pre>
<p><code>test_assertions</code> 内で書けるテストには2種類ある。1つが <code>equal</code> block であり、構築したリソースから得た値を <code>got</code> 、その値の期待値を <code>want</code> に指定して、両者が文字列として一致していればテスト成功となる。ここでは <code>data.aws_s3_bucket</code> によって、構築した S3 バケットの設定を読み出し、その ID が指定したバケット名と一致することを確認している。</p>
<p>もう1つが <code>check</code> block。 <code>condition</code> に bool 値を返す任意の式や function を記述し、その評価結果が <code>true</code> であればテスト成功となる。 Terraform 0.13 で追加された <a href="https://www.hashicorp.com/blog/custom-variable-validation-in-terraform-0-13">Custom Variable Validation</a> と、仕組みとしては同じだ。上記のサンプルでは、 S3 バケットの <code>website_endpoint</code> という attribute が空文字列ではないことを確認している。この attribute は、 S3 がウェブサイトホスティング設定になっているときのみ、エンドポイントのドメインが設定されるので、それを確認することでテストとしている。</p>
<pre><code class="language-hcl">data "http" "json_access" {
  depends_on = [
    test_assertions.s3_bucket,
  ]
  url = "http://${data.aws_s3_bucket.this.website_endpoint}/test.json"
}

resource "test_assertions" "json_access" {
  component = "json_access"

  equal "response_content_type" {
    description = "content type is valid"
    got         = data.http.json_access.response_headers["Content-Type"]
    want        = "application/json"
  }
}
</code></pre>
<p>さらにテストを書いてみる。今回の module の目的は S3 バケットを使ってウェブサイトを公開することなので、 HTTP provider を使って、実際に HTTP でアクセスできるのかまで確認をしてみた。</p>
<p><code>data.http.json_access</code> には <code>depends_on</code> を設定し、先の S3 バケット自体のテストが終了後にこちらのテストを実行するようにした。これは、バケット作成が未完了の状態では、 HTTP アクセスもできないためだ。 <code>depends_on</code> によって、実行するテストの順序もこのようにある程度コントロールできる。実際のテストでは、アクセスした際の Content-Type が、 <code>application/json</code> になっていることを確認する内容とした。</p>
<h3>test コマンドの実行</h3>
<p>テストを書き終えたら、 module root に戻り、 <code>terraform test</code> コマンドを実行する。実際にリソース構築が実行されるので、環境変数などで対象 provider 向けの API キーなどの設定もあらかじめ必要になる。</p>
<p>無事にすべてのテストが通れば、緑の文字で <code>Success!</code> と表示される。</p>
<p><a href="https://gyazo.com/bf2cc6a49c89a7fc546706fd79b2da76"><img src="https://i.gyazo.com/bf2cc6a49c89a7fc546706fd79b2da76.png" alt="Image from Gyazo" width="600"/></a></p>
<p>失敗したときは、以下のようにその詳細が表示される。ここでは最後の HTTP アクセス時のテストで、期待する値をあえて <code>text/html</code> と誤った値に設定してみた。</p>
<p><a href="https://gyazo.com/a53e110d493a6473bb0c9038f09fc9d1"><img src="https://i.gyazo.com/a53e110d493a6473bb0c9038f09fc9d1.png" alt="Image from Gyazo" width="600"/></a></p>
<h2>現時点での課題や懸念</h2>
<p><code>terraform test</code> は experimental な段階にあり、まだ安定的に動作するものではない。また、僕が行った検証は上記のもののみであって、これから書くことが一般性のある内容かは保証しないとあらかじめ断っておく。</p>
<p>なお experimental 段階だからか、フィードバックがあれば <a href="https://discuss.hashicorp.com/c/terraform-core/27/l/latest">HashiCrop Disucuss</a> のほうに寄せてほしいとのこと。</p>
<h3>設定不備のデバッグが困難</h3>
<p>設定不備により、 <code>terraform apply</code> 自体が失敗したり、テストがうまく動作しないこともあるが、現状ではその場合でも <code>Failed to clean up after tests</code> というメッセージが出力されるため、失敗の原因を掴みにくくなっている。</p>
<p>以下の出力は、先の検証の際に、バケット名をあえて重複した値に設定してみて、 apply をわざと失敗させたときのもの。スクショでは省略したが、実際には定義した各リソースすべてについて <code>Failed to ...</code> のメッセージが表示される。</p>
<p><a href="https://gyazo.com/b1256abf477bc4a1a319ecd55a8a1868"><img src="https://i.gyazo.com/b1256abf477bc4a1a319ecd55a8a1868.png" alt="Image from Gyazo" width="600"/></a></p>
<h3>destroy 失敗するとリカバリーが大変</h3>
<p><code>terraform test</code> では state を作成せずに apply / destroy を行うため、何らかの原因で destroy が失敗した場合は、作成したリソースを手動削除しなければならず、リカバリーが大変なことになる。あらかじめ手で apply / destroy だけは実行してみて、問題なく通ることは確認しておいたほうがいいかもしれない。</p>
<p>また、通常 <code>terraform destroy</code> ではリソース間の依存関係を鑑みて削除処理が行われるが、 <code>test</code> ではそれが上手く動いていない可能性を若干疑っている。先の検証中、 <code>aws_s3_bucket_object</code> と <code>aws_s3_object</code> には <code>depends_on</code> であえて依存関係を明記しているが、バケット削除が先に試みられ、エラーとなることがあったからだ。この点はもう少し確認して、バグのようなら報告しておきたい。</p>
<p><a href="https://gyazo.com/bdc007971ecc40b7196dfbfd9028b8ac"><img src="https://i.gyazo.com/bdc007971ecc40b7196dfbfd9028b8ac.png" alt="Image from Gyazo" width="600"/></a></p>
<h3>構築に時間がかかる場合</h3>
<p>今回の検証対象は S3 バケットだったため、テストの実行は1分程度で完了しているが、 AWS EKS Cluster など、構築完了まで10〜数十分を要するものが対象だと実行の難易度が上がる。 CI に組み込んだりすれば、時間的にも金銭的にもかなりのコストになるだろう。</p>
<p>将来的なテストダブルの実装可能性には触れられているので、それを期待したい。</p>
<h2>Conclusion</h2>
<p><a href="https://www.oreilly.co.jp/books/9784873117966/">Kief Morris『Infrastructure as Code』</a> では、11章にて IaC のテストについてまとめられている。</p>
<p>ここでは「反射的テスト」と名付けて、何らかの構成定義をただ言い換えただけのテストを書くことをアンチパターンとしている。今回の検証で言えば、 S3 バケット名の確認テストがそれにあたるだろう。この種のテストは書いていても切りがないし、要するところ「Terraform が正しく動いているか」というツールの信用性を試すだけのものになってしまう。</p>
<p>では何をテストすれば良いのかについては、以下のように書かれている。</p>
<blockquote>
<p>原則として、テストを書くのは、チェックしたいと思っているロジックにある程度複雑さが含まれている場合だけにすべきだ。（Kief Morris 著. 宮下剛輔 監訳. 長尾高弘 訳. Infrastructure as Code. 初版, オライリー・ジャパン, 2017, p.207）</p>
</blockquote>
<p>確かに Terraform module は内部で Terraform Function や dynamic block を用いて複雑化している場合も多く、そういったところを中心に分岐網羅、条件網羅的にテストを書いていくのがベターな方法になるのかもしれない。また今回 HTTP provider を活用したように、直接構築されるリソース以外で副次的にもたらされる価値があれば、それについてもテストをしておきたい。 HTTP Provider 以外にも、すでに Terraform に存在している、数々の <code>data</code> を上手く活用できるんじゃないだろうか。</p>
<p>Terraform にテスト機能が内包されることで、より module 開発はやりやすくなりそうだと感じたし、 <code>test</code> コマンドの本実装には肯定的な気持ちでいる。</p>
]]></description>
            <link>https://chroju.dev/blog/terraform_test_command_in_experiment</link>
            <guid isPermaLink="false">terraform_test_command_in_experiment</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 03 May 2021 04:36:58 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Alfred で複数行文字列からの候補選択を簡単に実現する]]></title>
            <description><![CDATA[<p><a href="https://www.alfredapp.com">Alfred</a> が好きなのだが、カスタマイズして使うのは結構面倒というジレンマがある。有償の <a href="https://www.alfredapp.com/powerpack/">Alfred Powerpack</a> を購入すると、自分で好きな検索→アクションさせることができる（という話は <a href="https://chroju.dev/blog/how_to_make_alfred_workflow">Alfred は「黒い窓」を使わなくなってからが本番 - the world as code</a> に書いた）ものの、検索候補を Alfred に渡すには、以下のような JSON format を使う必要がある。</p>
<pre><code class="language-json">{"items": [
    {
        "uid": "desktop",
        "type": "file",
        "title": "Desktop",
        "subtitle": "~/Desktop",
        "arg": "~/Desktop",
        "autocomplete": "Desktop",
        "icon": {
            "type": "fileicon",
            "path": "~/Desktop"
        }
    }
]}
</code></pre>
<p>Alfred での検索画面というと下図の形でお馴染みだと思うが、これで言えばインクリメンタル検索の対象となる白い大きな文字が <code>title</code> 、その下に薄い文字色で書かれているのが <code>subtitle</code> になる。また、これら検索候補のいずれかを選択すると、それに応じて「ファイルを開く」「URLを開く」といったアクションに連携されるわけだが、そのアクションに引き渡す URL やファイルパスにあたるのが <code>arg</code> だ。</p>
<p><a href="https://gyazo.com/43ffdb9dd4b64926f89de6e8d8357ca1"><img src="https://i.gyazo.com/43ffdb9dd4b64926f89de6e8d8357ca1.png" alt="Image from Gyazo" width="557"/></a></p>
<p>Alfred をきちんと使うのであれば、こういった各項目を設定していく必要が出るが、時に複数行文字列を渡せばイイ感じに検索させてほしいなと思うときがある。となると bash でシュッとスクリプトを書きたくなるのだが、 JSON の生成をシェルスクリプトで扱うのはかなり難しい。そこで、複数行文字列を渡せばざっくりと Alfred JSON Format に変換してくれるツールを作った。</p>
<p>https://github.com/chroju/alfrednize</p>
<p>例えばローカルで Git レポジトリ管理を行うツールである <a href="https://github.com/x-motemen/ghq">x-motemen/ghq</a> と組み合わせてみると、以下のような出力を得られる。</p>
<pre><code class="language-bash">$ ghq list | head -n 5
github.com/chroju/og-image
github.com/chroju/dotfiles
github.com/chroju/parade
github.com/miiton/Cica
github.com/chroju/homebrew-tap

$ ghq list | alfrednize | jq | head -n 18
{
  "items": [
    {
      "uid": "github.com/chroju/og-image",
      "title": "github.com/chroju/og-image",
      "subtitle": "",
      "arg": "github.com/chroju/og-image",
      "match": "github.com/chroju/og-image",
      "autocomplete": "github.com/chroju/og-image"
    },
    {
      "uid": "github.com/chroju/dotfiles",
      "title": "github.com/chroju/dotfiles",
      "subtitle": "",
      "arg": "github.com/chroju/dotfiles",
      "match": "github.com/chroju/dotfiles",
      "autocomplete": "github.com/chroju/dotfiles"
    },
</code></pre>
<p>見てわかる通り、 JSON の中身は妥協の産物で、各項目すべて同じ内容になっている。細かいことは何もできなくていいので、複数行文字列から候補選択し、選択した文字列をそのまま次へ渡せれば OK 、というつもりで作っている。選択した文字列の加工が必要であれば、 bash でどうとでもできるだろう。</p>
<p>これを Alfred Workflow で設定すると、ローカルの Git レポジトリを検索するツールがシュッと完成する。あとは選択結果を <code>code</code> コマンドに渡せば VSCode で開けるし、あるいはブラウザで開かせてもいい。</p>
<p><a href="https://gyazo.com/4507c51c30b7152734d4f8f4b8a2db57"><img src="https://i.gyazo.com/4507c51c30b7152734d4f8f4b8a2db57.png" alt="Image from Gyazo" width="557"/></a></p>
<p>複数行文字列を渡すだけで Alfred Workflow が使えるのは結構便利で、<a href="https://github.com/junegunn/fzf">junegunn/fzf</a> にかなり近い感覚で Alfred を扱えるようになる。 JSON 生成が必要であるがために、これまでは Workflow を作るだけで何かプログラミング言語を使うことがほぼ必須だったが、 alfrednize があれば bash だけで簡単に作れるようになったのもメリットとして大きい。先の例のように何かコマンドの実行結果を渡すのでもいいし、静的な検索であれば、何かをリストアップしたファイルを作ってシンプルに <code>cat</code> するだけでも使える。</p>
]]></description>
            <link>https://chroju.dev/blog/alfrednize_easy_alfred_json_formatter</link>
            <guid isPermaLink="false">alfrednize_easy_alfred_json_formatter</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 01 May 2021 00:14:03 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[spf13/cobra を testable に使う]]></title>
            <description><![CDATA[<p><a href="https://github.com/spf13/cobra">spf13/cobra</a> という、 Go でコマンドラインツールを作り際によく使われるライブラリがある。 kubectl や GitHub CLI (gh) などにも使われており、かなり人気の高いライブラリなのだが、以前 <a href="https://chroju.dev/blog/parade_aws_parameter_store_cli">AWS Parameter Store をターミナルから操作する Parade を作った - the world as code</a> という記事の中でも言及した通り、そのまま使うとあまり testable な状態にならない。</p>
<p>先日、先の記事で書いた <a href="https://github.com/chroju/parade">Parade</a> というツールのリファクタリングを通じて、 cobra を testable に使う方法を模索したので、それについて書いてみる。</p>
<h2>example に基づいた cobra の利用</h2>
<p>まず、何が問題なのかを明らかにするために、 <a href="https://pkg.go.dev/github.com/spf13/cobra@v1.1.3">cobra v1.1.3 のドキュメント記載の example</a> を参考にコードを書いてみる。</p>
<pre><code class="language-go">package cmd

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
)

var (
	// Used for flags.
	userLicense string

	rootCmd = &#x26;cobra.Command{
		Use:   "cobra",
		Short: "A generator for Cobra based Applications",
		Long: `Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
	}

    tryCmd = &#x26;cobra.Command{
        Use:   "try",
        Short: "Try and possibly fail at something",
        RunE: func(cmd *cobra.Command, args []string) error {
            if err := someFunc(); err != nil {
                return err
            }
            fmt.Println(args[0])
            return nil
        },
    }
)

// Execute executes the root command.
func Execute() error {
	return rootCmd.Execute()
}

func init() {
	cobra.OnInitialize(initConfig)

	rootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "author name for copyright attribution")
	rootCmd.PersistentFlags().StringVarP(&#x26;userLicense, "license", "l", "", "name of license for the project")

	rootCmd.AddCommand(tryCmd)
}
</code></pre>
<p>cobra はサブコマンドのある CLI が念頭に置かれている。15行目の <code>rootCmd</code> がサブコマンド無しの状態のコマンドであり、ここに23行目で <code>&#x26;cobra.Command</code> として定義した <code>tryCmd</code> を、51行目で <code>AddCommand()</code> することにより、サブコマンドを追加している。サブコマンドである <code>tryCmd</code> が呼ばれた際に実行される処理は、26行目の <code>&#x26;cobra.Command{}.RunE</code> に渡された関数が担っている。</p>
<p>example に基づくとこのような実装になるわけだが、パッと見ただけでもいくつか改善したいポイントが出てくる。</p>
<ul>
<li>26行目、 <code>tryCmd</code> の処理が無名関数であり、テストしづらい</li>
<li>30行目、関数の出力処理が <code>fmt.Println</code> で行われており、出力内容のテストがしづらい</li>
<li>13、45行目、 <code>rootCmd</code> のコマンドフラグがグローバル変数で管理されている</li>
<li>同様に、各コマンドもグローバル変数となっている</li>
</ul>
<p>以下、順に見て行きながら改修していく。</p>
<h2>コマンドの実行に無名関数を使うのをやめる</h2>
<p>26行目からの無名関数内でサブコマンドの処理を実行しているが、このままではテストなどを行う場合に扱いづらいので、これをまず改修する。処理を実行する部分は別の関数に分離して、無名関数内から呼び出す形を取ってみる。</p>
<pre><code class="language-go">var {
    tryCmd = &#x26;cobra.Command{
        Use:   "try",
        Short: "Try and possibly fail at something",
        RunE: func(cmd *cobra.Command, args []string) error {
            if len(args) != 1 {
                return fmt.Errorf("expected 1 arg.")
            }
            return try(args[0])
        },
    }
}

func try(value string) error {
    if err := someFunc(); err != nil {
        return err
    }

    fmt.println(value)
    return nil
}
</code></pre>
<p>引数の validation などの処理は呼び出し関数である <code>tryCmd</code> のほうに寄せて、 <code>try()</code> は実処理だけを担うようにしたことで、これだけでもだいぶ見通しがよくなった。実処理に必要な引数も、 <code>args []string</code> という曖昧なものではなく、 string 型1個だということがこれで明示できる。</p>
<h3>出力処理に fmt.Println() を使わない</h3>
<p>さらに、改善ポイントの2つ目に上げた、「出力内容のテストがしづらい」という問題もこれで改善の余地が出た。 <code>try()</code> に引数を自由に設定できるようになったので、 <code>io.Writer</code> を受け取るようにすればよい。これにより、テストの際には <code>&#x26;bytes.Buffer{}</code> を生成して <code>try()</code> に渡すことで、出力をかすめ取ることができるようになる。</p>
<pre><code class="language-go">var {
    tryCmd = &#x26;cobra.Command{
        Use:   "try",
        Short: "Try and possibly fail at something",
        RunE: func(cmd *cobra.Command, args []string) error {
            if len(args) != 1 {
                return fmt.Errorf("expected 1 arg.")
            }

            out := os.Stdout
            errOut := os.Stderr
            return try(args[0], out, errOut)
        },
    }
}

func try(value string, out, errOut io.Writer) error {
    if err := someFunc(); err != nil {
        return err
    }

    fmt.Fprintln(out, value)
    return nil
}
</code></pre>
<p>ちなみに、自分の場合はサブコマンドの引数が長くなる場合もあったので、各コマンドの引数を構造体でまとめるようにしている。ここはお好みで。</p>
<pre><code class="language-go">type tryOption struct {
    Value  string
    Out    io.Writer
    ErrOut io.Writer
}

func try(o *tryOption) error {
    if err := someFunc(); err != nil {
        return err
    }

    fmt.Fprintln(o.Out, o.Value)
    return nil
}
</code></pre>
<h3>グローバル変数をやめる</h3>
<p>続いてグローバル変数をやめたい。まず、 <code>rootCmd</code> と <code>tryCmd</code> については関数で生成するようにする。 <code>tryCmd</code> について書くと、以下のようになる。</p>
<pre><code class="language-go">func newTryCmd() *cobra.Command {
    cmd := &#x26;cobra.Command{
        Use:   "try",
        Short: "Try and possibly fail at something",
        RunE: func(cmd *cobra.Command, args []string) error {
            if len(args) != 1 {
                return fmt.Errorf("expected 1 arg.")
            }

            out := os.Stdout
            errOut := os.Stderr
            return try(args[0], out, errOut)
        },
    }
    return cmd
}

func init() {
    rootCmd.AddCommand(newTryCmd())
}
</code></pre>
<p><code>rootCmd</code> も同様に <code>newRootCmd()</code> 関数で生成する。これにより関数の中で <code>*cobra.Command</code> を操作可能になったので、最初のサンプルでは <code>init()</code> の中で <code>func (c *cobra.Command) PersistentFlags()</code> で行っていた Flag の付与や、同 <code>AddCommand()</code> によるサブコマンドの設定処理も一緒にまかなえるようになった。</p>
<pre><code class="language-go">func newRootCmd() (*cobra.Command, error) {
    var userLicense string

	cmd := &#x26;cobra.Command{
		Use:   "cobra",
		Short: "A generator for Cobra based Applications",
		Long: `Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
	}
	cmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "author name for copyright attribution")
	cmd.PersistentFlags().StringVarP(&#x26;userLicense, "license", "l", "", "name of license for the project")

	cmd.AddCommand(
		newTryCmd(),
	)

	return cmd, nil
}
</code></pre>
<p><code>tryCmd</code> のときと同様、 <code>rootCmd</code> についても出力先は io.Writer を引数で与えるようにする。<code>newTryCmd</code> にも io.Writer の引数を追加すれば、 <code>rootCmd</code> に渡した io.Writer をサブコマンドへと伝播させる形が実現できる。</p>
<p>さらに、 <code>*cobra.Command</code> の <code>func (c *Command) SetOut()</code> と、同 <code>SetErr()</code> にも io.Writer を渡す。これらは <code>*cobra.Command</code> 自身が出力する、 Usage やエラーメッセージの出力先になる。</p>
<pre><code class="language-go">func newRootCmd(outWriter, errWriter io.Writer) (*cobra.Command, error) {
    var userLicense string

	cmd := &#x26;cobra.Command{
		Use:   "cobra",
		Short: "A generator for Cobra based Applications",
		Long: `Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
	}
	cmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "author name for copyright attribution")
	cmd.PersistentFlags().StringVarP(&#x26;userLicense, "license", "l", "", "name of license for the project")

	cmd.AddCommand(
		newTryCmd(outWriter, errWriter),
	)
	cmd.SetOut(outWriter)
	cmd.SetErr(errWriter)

	return cmd, nil
}

func Execute() error {
	o := os.Stdout
	e := os.Stderr

	rootCmd, err := NewRootCmd(o, e)
	if err != nil {
		return err
	}
	return rootCmd.Execute()
}
</code></pre>
<h2>Conclusion</h2>
<p>以上を踏まえると、最終形は以下のような形になる。</p>
<pre><code class="language-go">type tryOption struct {
    Value  string
    Out    io.Writer
    ErrOut io.Writer
}

func newTryCmd(out, errOut io.Writer) *cobra.Command {
    o := &#x26;tryOption{}
    cmd := &#x26;cobra.Command{
        Use:   "try",
        Short: "Try and possibly fail at something",
        RunE: func(cmd *cobra.Command, args []string) error {
            if len(args) != 1 {
                return fmt.Errorf("expected 1 arg.")
            }

            o.Out = out
            o.ErrOut = errOut
            return try(o)
        },
    }
    return cmd
}

func try(o *tryOption) error {
    if err := someFunc(); err != nil {
        return err
    }

    fmt.Fprintln(o.Out, o.Value)
    return nil
}

func newRootCmd(out, errOut io.Writer) (*cobra.Command, error) {
    var userLicense string

	cmd := &#x26;cobra.Command{
		Use:   "cobra",
		Short: "A generator for Cobra based Applications",
		Long: `Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
	}
	cmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "author name for copyright attribution")
	cmd.PersistentFlags().StringVarP(&#x26;userLicense, "license", "l", "", "name of license for the project")

	cmd.AddCommand(
		newTryCmd(out, errOut),
	)
	cmd.SetOut(out)
	cmd.SetErr(errOut)

	return cmd, nil
}

func Execute() error {
	o := os.Stdout
	e := os.Stderr

	rootCmd, err := NewRootCmd(o, e)
	if err != nil {
		return err
	}
	return rootCmd.Execute()
}
</code></pre>
<p>サブコマンドの生成を関数で行ったり、コマンドの出力先を io.Writer を渡すことでまかなったりするのは、いずれも <a href="https://github.com/mitchellh/cli">mitchellh/cli</a> では標準の機能であり、こちらを先に使っていたことで、 cobra も改修して使おうという発想に至れた。同じ目的に使える言語ライブラリが複数存在することはままあるが、それぞれの実装を比較してみると学べることは多いのだと実感した。実際改修にあたる際は、ここで書いたように「何を改善したいのか」というポイントを1つずつ解きほぐしていくと整理しやすい。</p>
<p>また冒頭にも書いた通り、 cobra は多くの著名なツールで使われているので、実例が豊富なのもポイントだと思う。 GitHub CLI の実装は特にここで書いたものと似た形になっており、とても参考になっている。</p>
<p><a href="https://github.com/cli/cli/blob/3ad41e3e651647236ed4ece290afb12dbdc924bf/pkg/cmd/issue/status/status.go">cli/status.go at 3ad41e3e651647236ed4ece290afb12dbdc924bf · cli/cli</a></p>
]]></description>
            <link>https://chroju.dev/blog/go_cobra_testable_refinement</link>
            <guid isPermaLink="false">go_cobra_testable_refinement</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 16 Apr 2021 10:34:15 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[GitHub CLI に不可能はない]]></title>
            <description><![CDATA[<p>タイトルは誇張気味だが、 <code>gh</code> こと GitHub CLI こと <a href="https://github.com/cli/cli">cli/cli: GitHub’s official command line tool</a> には任意の GitHub API を呼び出せる <code>gh api</code> サブコマンドがあるので、あながち間違ってもいない。サブコマンドが実装されていなくとも、アイデア次第で GitHub のあらゆる操作が gh から呼び出せる。</p>
<p>従来から強力な <code>api</code> サブコマンドだったが、実行結果は当然ながら JSON などの形式になるので、結果を整形するには jq を通す必要があった。これが先日の <a href="https://github.com/cli/cli/releases/tag/v1.7.0">1.7.0</a> において、 jq のシンタックスを活用できる <code>--jq</code> オプションと、 <a href="https://golang.org/pkg/text/template/">Go template</a> を活用できる <code>--template</code> オプションが実装されたことで、 gh コマンド単独であらゆる出力整形まで可能になった。</p>
<p>僕もコマンドラインツールをよく書くが、ある API を implement した CLI というのは、 API の発展に従って絶えず更新が必要だし、実行結果の出力形式をどうするかなかなか悩ましい部分も大きい。この <code>api</code> サブコマンドは、そういった問題を「ユーザーにぜんぶ編集可能とさせる」ことで根本的に解決している、発想の逆転がすばらしい。</p>
<p>いくつか僕の使っている alias の実例を挙げてみる。</p>
<h3>watch の管理</h3>
<p>GitHub の watch は、かねてより GUI が貧弱だ。うっかりレポジトリの多い Organization に入ると一斉に多数のレポジトリが watch 対象になるなど事故りやすいが、 GUI からでは watch 解除は「全部解除」か「1つずつ解除」のいずれかしかできず、複数の対象をチェックして解除するような操作ができない。</p>
<p><a href="https://gyazo.com/0fd8a4e3d480dab626fad1490641daa6"><img src="https://i.gyazo.com/0fd8a4e3d480dab626fad1490641daa6.png" alt="Image from Gyazo" width="600"/></a></p>
<p>GitHub CLI で、 watch しているレポジトリ一覧の表示と、 watch 解除のコマンドを作ると、これがだいぶ楽になる。</p>
<pre><code class="language-bash">$ gh alias set watches 'api /users/chroju/subscriptions --paginate --jq .[].full_name'

$ gh watches
chroju/dotfiles
chroju/todo.txt-cli
chroju/chef_web_server
...

$ gh alias set unwatch 'api -X DELETE /repos/$1/subscription'

$ gh unwatch chroju/dotfiles
</code></pre>
<p>あとは <code>gh watches</code> の結果をテキストファイルに書き出し、ファイルを開いて不要なレポジトリだけを残すよう編集し、そのファイルを <code>cat</code> して <code>xargs gh unwatch</code> していけば、一括で watch が解除できる。</p>
<h3>gitignore の生成</h3>
<p>GitHub API から、さまざまな言語の <code>.gitignore</code> の雛形を取得できる。これも alias にしておくと便利だ。</p>
<pre><code class="language-bash">$ gh alias set gitignore 'api /gitignore/templates/$1 --jq .source'

$ gh gitignore Go
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/
</code></pre>
<h3>レポジトリの検索</h3>
<p>「なんかああいう名前のレポジトリあったよな」という朧気な記憶からググったりすることがよくあるが、これもコマンドにする。</p>
<pre><code class="language-bash">$ gh alias set search 'api -X GET search/repositories -f q="$1" --template "{{range .items}}{{.full_name}} ⭐ {{.stargazers_count | color \"yellow\"}} ({{.description}}){{\"\\n\"}}{{end}}"'
</code></pre>
<p>結果はこんな感じ。Go template を用いると、出力の色も変えられるのが嬉しい。</p>
<p><a href="https://gyazo.com/d295b1d84b6ada7abdbb50a52107be42"><img src="https://i.gyazo.com/d295b1d84b6ada7abdbb50a52107be42.png" alt="Image from Gyazo" width="600"/></a></p>
<p>僕はレポジトリ名だけ出力するのが好きなのでそうしているが、 URL を表示するようにすれば、サクッとブラウザで開くこともできる。 <a href="https://github.com/junegunn/fzf">fzf</a> などを通してシュッと開けるようにしておくのもよさそう。</p>
<h3>Atlantis の実行</h3>
<p>Terraform の自動実行ツール <a href="https://www.runatlantis.io/">Atlantis</a> はプルリクエストベースで動作する仕組みになっており、 <code>terraform apply</code> を実行するには、 PR コメントに <code>atlantis apply</code> と書き込む必要がある。これもブラウザから書き込むのは面倒なのでコマンド化してしまう。</p>
<pre><code class="language-bash">$ gh alias set atlantis-apply 'pr comment -b "atlantis apply"'
</code></pre>
<p>この alias だとカレントディレクトリ、カレントブランチの PR に対して apply が実行される、かなり簡易的な形式になっているが、より安全な形式にするならば、 PR number やレポジトリを引数に取らせてもいい。</p>
<p>他、ここでは取り上げていないが REST API だけではなく GraphQL API にも対応している。また <code>gh</code> 単体で完結しない操作であっても、 <code>gh alias set --shell</code> オプションを使えば、シェルコマンドを挟んだワンライナーまでも alias 登録ができる。なので本当になんでもありだ。</p>
<h2>GitHub CLI の config をファイルで管理する</h2>
<p>ここまで多くの設定ができるコマンドラインツールだと、 dotfile の考え方で、設定はファイル管理したくなる。現状、ドキュメントには記載がないが、 GitHub CLI の設定はデフォルトでは <code>~/.config/gh</code> 配下に YAML で保存されている。なお、設定ファイルの保存先ディレクトリは、環境変数 <code>GH_CONFIG_DIR</code> で自由に設定することもできる。 (see: https://github.com/cli/cli/pull/2444)</p>
<p>ファイルは OAuth token などが書かれた <code>hosts.yml</code> 、 GitHub CLI のバージョン情報が書かれた <code>state.yml</code> 、そして alias などの設定が書かれた <code>config.yml</code> の3種類がある。前者2つは秘密情報や動的な値を含んでいるので、 <code>config.yml</code> だけ dotfile 管理すればいいだろう。</p>
<pre><code class="language-yaml"># What protocol to use when performing git operations. Supported values: ssh, https
git_protocol: ssh
# What editor gh should run when creating issues, pull requests, etc. If blank, will refer to environment.
editor:
# When to interactively prompt. This is a global config that cannot be overridden by hostname. Supported values: enabled, disabled
prompt: enabled
# A pager program to send command output to, e.g. "less". Set the value to "cat" to disable the pager.
pager:
# Aliases allow you to create nicknames for gh commands
aliases:
    watches: api /users/chroju/subscriptions --paginate --jq .[].full_name
    gitignore: api /gitignore/templates/$1 --jq .source
    unwatch: api -X DELETE /repos/$1/subscription
    search: api -X GET search/repositories -f q="$1" --template "{{range .items}}{{.full_name}} ⭐ {{.stargazers_count | color \"yellow\"}} ({{.description}}){{\"\\n\"}}{{end}}"
</code></pre>
<p>ウェブブラウザはつい脇道に逸れてしまったり、集中力を乱す要因になりがちなので、仕事中に触る機会は極力減らしたいと考えている。その上で GitHub CLI はかなり有意義なツールになりつつある。</p>
]]></description>
            <link>https://chroju.dev/blog/gh_github_cli_can_do_anything</link>
            <guid isPermaLink="false">gh_github_cli_can_do_anything</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 21 Mar 2021 02:17:22 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[帝京大学通信課程での社会人大学生2年目を終えて]]></title>
            <description><![CDATA[<p>帝京大学理工学部情報科学科通信課程2年目（2年次編入のため、学年は3年生）を終えたので記録する。1年目については <a href="https://chroju.dev/blog/adult_university_learner_first_year">社会人大学生1年目を終えて、大学生活と勉強法とその困難 - the world as code</a> で書いた。</p>
<h2>単位修得状況</h2>
<p>| 評価 | 2年次修得単位 | 3年次修得単位 |
|:--:|:--:|:--:|
| S | 8 | 2 |
| A | 12 | 8 |
| B | 4 | 4 |
| C | 0 | 4 |
| 合計 | 24 | 18 |</p>
<p>いやぁ、鈍化鈍化って感じがしますね。ただ昨年はスクーリング科目（週末2〜3日間通学し、集中的に講義を受けて単位を取得する科目）を6単位取っているので、自宅学習のペースとしては変わらずと言っていいのかもしれない。ダメかもしれない。</p>
<p>コロナ禍で家にいる時間が増えたのだから、大学に費やせる時間も増えてよさそうなものだけど、まぁいろいろもろもろで実際のところあまり増えなかった。これは後述。</p>
<p>残り50単位。頑張ればギリギリあと2年でイケそうだが無理をしなければ3年か、というところ。</p>
<h2>コロナ禍と通信大学生</h2>
<h3>通学機会の消失</h3>
<p>2020年度はコロナ禍により、大学生がかなり影響を受けたことは報道でも周知の通り。小中高校が対面授業を再開するなか、なぜ大学だけがオンライン授業を続けるのかという怨嗟の声もよく聞こえた。</p>
<p>通信課程はあまり影響なかったんじゃないかと思われそうだが、多少の影響はあった。スクーリングや科目修得試験など、年に何回かはキャンパスへ赴く機会もあるのだが、それらはすべてオンラインに切り替えられ、今年度は一度もキャンパスへ足を踏み入れることがなかった。</p>
<p>とはいえ、試験については本人確認の手順などが変更になったぐらいで、単に受ける場所が変わるだけなのでそれほど大きな影響はない。スクーリングに関してはグループワークなどが設けられていることも多く、孤独に勉強する通信学生が唯一ほかの学生と交流できる機会だったので、オンライン化を残念に思う人も少なくなかったのではないかと思う（僕はスクーリング科目の必要単位は取り終えているので無関係）。なお、試験は黙して実施するものなので、「三密」には該当しないのではないかという気もするが、通信制は全国に学生が分散している関係上、試験開催により都市圏と郊外間の移動がそこそこ発生する。大学側の懸念はその点だったらしい。</p>
<p>僕としては、試験のときに大学へ行って、学食でごはんを食べたり、併設のイタトマでケーキ食べながら勉強したりする、ちょっとした楽しみを奪われたのが残念だったぐらいで、「大変な思いをした」という気持ちはない。</p>
<h3>学習環境の変化（マイナス面）</h3>
<p>個人的な話としては、学習環境が多少なり変化した。昨年からの変化で書くので、良ければ冒頭に載せた1年目の記事をあわせて見てほしい。</p>
<p>第一に図書館が使えなくなってしまった。特に予定がない休日は<a href="https://www.library.metro.tokyo.lg.jp/">東京都立中央図書館</a>で勉強させてもらっていたが、緊急事態宣言下では来館サービスを停止しており、それ以外の期間も予約や人数制限が入ったので、今年度は一度も利用していない。調査してレポートを書くような課題が今年度はなかったのでまだ良いものの、もしもそういった機会があれば少々面倒なことになりそう。また、家で勉強するより、場所を変えたほうが気分転換になるのは確かなので、以前よりやる気が出なかった日は少なくなかったな、と思う。</p>
<p>また、暗記が必要な科目については「通勤電車内で <a href="https://apps.ankiweb.net/">Anki</a> を使う」という学習方法を取っていたが、通勤が消滅したのでこれもできなくなった。おかげで暗記の状態がちょっとよろしくないな、と感じる機会が増えた気はする。</p>
<p>もちろん、いずれも個人的な環境、習慣の話で、「新しい生活様式」下に適応すればよいという話ではある。それはそう、なのだが、急な環境変化にはどうにも振り回されてしまう。2021年度もおそらくこの調子が続くのだろうし、次はもう少し適応していきたいところ。</p>
<h3>学習環境の変化（プラス面）</h3>
<p>ちなみに、その他なにか著しくモチベーションが下がっただとか、そういったことはなく、淡々と学習は続けられている。大学の学習を続けること自体はこの2年でだいぶ習慣化できた。</p>
<p>またリモートワークになったことも大きい。今勤めている会社はコアタイムのないフレックス制なので、今は朝の「出勤」を遅らせて10時にして、起床からその時間までを大学の勉強、もしくは趣味の勉強に充てることにしている。毎日の生活リズムがほぼ固定できたことは非常に良かった。一方で自炊やらの機会が増えたり、先述した図書館や Anki の件があったりもしたので、結局学習時間の総量としてはトントンという感覚でいる。</p>
<h2>学習の進め方（2年目）</h2>
<p>これはあんまり昨年と変わっていないので、1年目の記事を見てもらいたい。小さいところで2つほど変化はあり、1つはすでに書いているとおり Anki を使わなくなってしまったこと。</p>
<p>もう1つは履修科目の管理方法。ついつい10年前の大学時代の習慣に引きずられるようで、去年はあの頃のようにスプレッドシートで愚直に管理していたんだけど、今更それもどうよと気付き、今年は Notion の Board View を使ってカンバン的に管理していた。</p>
<p><a href="https://gyazo.com/a9b721a2a663c4d012a47cfc465a5494"><img src="https://i.gyazo.com/a9b721a2a663c4d012a47cfc465a5494.png" alt="Image from Gyazo" width="792"/></a></p>
<p>が、普段のメモには Scrapbox をメインとしていることもあり、どうも Notion を開く習慣ができず、頓挫した。大学のレポートや課題は GitHub の Private Repository で管理しているので、来年度はそこに GitHub Project のカンバンを作って対処しようと考えている。普段見るものに寄せるの大事。</p>
<h2>受けて良かった授業</h2>
<p>実際の授業受けてみてどうよ？って話、特に通信大学だとあんまり流れないよなぁというのを <a href="https://note.com/lumpsucker/n/n2a9ee74956dc">放送大学マイルストーン（仮）｜lumpsucker｜note</a> を見て思ったので自分もやってみる。「マイル」（元ネタは早稲田の<a href="https://e-mile.com/publication/milestone-express/">「マイル」</a>でしょう）名乗れる網羅性はなく、あくまで自分の受けた科目の中だけであり、また難易度などの記述はしていない。</p>
<p>ちなみに2年次に受けた科目はその旨を付記しているが、特に履修年次の制限はないので、何年次でも履修はできる。</p>
<h3>オートマトンと計算理論</h3>
<p>内容としては『アンダースタンディングコンピュテーション』に近い。以前から興味のある分野ではあったものの、自主学習となるとなかなか腰が重く、大学で改めてさらえたのは良い機会だった。僕らの根幹に位置するような分野と捉えている。</p>
<p>https://www.oreilly.co.jp//books/9784873116976/</p>
<h3>情報理論</h3>
<p>クロード・シャノンの『<a href="https://ieeexplore.ieee.org/document/6773024?arnumber=6773024">A mathematical theory of communication</a>』をベースに、情報源符号化と通信路符号化について学んでいく科目。単に概念的な学習にとどまらず、例えば通信路符号化にあたっては、サンプリングの過程を実際にフーリエ変換を使って解いていくなど、歯ごたえがかなりあった。</p>
<h3>コンピュータアーキテクチャ</h3>
<p>コンピュータの物理構造を紐解いていくので、シラバスにも書いてあるが「教養」に近いかもしれない。基本情報処理技術者試験を受けた人であれば、あれのハードウェア関連の内容をさらに深化させたものと考えると近いかもしれない。制御装置、演算装置、記憶装置、それぞれの歴史的変遷や概念を追えるので純粋に面白いのだが、一方で覚えることもかなり多い。</p>
<h3>数理統計学</h3>
<p>社会科学の大学を出ているのでこの分野は一度学んでいるのだけど、改めて。正直コンピュータに直結するのかは「？」だけど、統計知識というのは生きていく上で常に必要なんじゃないかという感覚がある。データを見る、という機会はエンジニアとしてだけではなく、日常生活のなかでも多いし。</p>
<h3>データベース論（2年次）</h3>
<p>データベーススペシャリストは持っていないのだけど、この科目でかなり補充できたのではないかなと感じる。ただし、ほぼ RDBMS の話であり、 NoSQL などにはあまり対応していない。</p>
<h3>グラフ理論（2年次）</h3>
<p>巡回セールスマン問題、木構造、有限マルコフ連鎖、なんて単語が出てくる科目。受ける前はネットワーク分野と関連しそうだな、ぐらいの印象だったけど、複数のノードをどう繋ぐか、繋ぎ方のパターン、ノード間の移動パターンなどに関する理論は、情報科学分野の様々な場面で必要になることがわかって非常に興味深かった。</p>
<h3>技術者倫理（2年次）</h3>
<p>シラバスの言葉を借りると、「技術者はいかにあるべきか」についての内容。実際の科学技術発展に伴う社会問題、倫理的課題などに触れながら、われわれ技術者にはどのような倫理観、社会的責任が求められるのかを追っていく科目。</p>
<p>個人的にはこういう科目を学べるのが大学の醍醐味のように感じる。本を読んだり、ウェブで検索したりして技術知識はいくらでも学んできたけれど、自分が技術者としてどうあるべきか、どういった社会的責任を帯びているかということに、思いを馳せる機会は非常に少なかったように思う。特に情報技術の分野は変化も速く、倫理的課題が大きくクローズアップされることも多い。そういうときに徒手空拳の議論に埋没せず、きちんとした哲学や歴史的経緯への知識を持っていることは結構重要なんじゃないだろうか。</p>
]]></description>
            <link>https://chroju.dev/blog/teikyo_university_learner_second_year.md</link>
            <guid isPermaLink="false">teikyo_university_learner_second_year.md</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 10 Mar 2021 00:22:06 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[k8s HPA target > resource requests という設定方針]]></title>
            <description><![CDATA[<p>言われてみれば当たり前のような話かもしれないが、自分としては大きな気付きだったことを書いてみる。</p>
<p>Kubernetes Horizontal Pod Autoscler (HPA) において <code>type: Resource</code> を用いた場合、閾値の指定は resource requests に対する使用率パーセンテージとなる。例えば CPU の requests 合計が 100m で limits 合計が 200m の Pod に対し、以下の HPA metrics を設定したとする。</p>
<pre><code class="language-yaml">metrics:
- type: Resource
  resource:
    name: cpu
    target:
      type: Utilization
      averageUtilization: 50
</code></pre>
<p>この場合、各 Pod の CPU 使用量が平均で 50m になるよう HPA がスケーリングを行う。</p>
<p>このときふと疑問に思うのが、ならば limits を requests より高い値に設定しても無意味では無いかということだった。 HPA により、リソース使用量が常に requests より低い値になるよう動作するのであれば、 requests より高い値である limits に肉薄した使用量となる機会は少なくなる。もちろん、スケーリングが動作するまでのバースト余地としての意味はあるかもしれないが、少々動作が直観に反する気もする。</p>
<p>そもそも requests というのは、 Pod の起動時に最低限必要となるリソース量を設定するものだ。あまり大きい値だと、 Pod が無駄にリソースを確保してしまうため、 Node のリソース効率が悪くなるし、コンテナの数が増えてくれば、 Pod を起動する際の空きリソースが不足する事態も招きやすくなる。従って requests は、ある程度低めの値を設定しておくのが基本であり、これに対してさらに使用率パーセンテージで閾値をかけると、その値は自ずとかなり低い値になってくる。</p>
<p>この点、随分悩んでいたのだが、先日なんてことはない発想の転換を <a href="https://github.com/kubernetes/kubernetes/issues/72811">Horizontal Pod Autoscaler should use resource limit as its base for calculation · Issue #72811 · kubernetes/kubernetes</a> で見かけた。</p>
<blockquote>
<p>For instance, you might set request to 100m and limit to 250m. Set HPA to 200% cpu utilisation - this way the pods will scale when CPU usage hits 200m.</p>
</blockquote>
<p>HPA の閾値は 100％ を超過した値にも設定できる。従って requests の値よりも高く、 limits に対しては余裕のあるところで閾値設定をする。すると requests よりも多くの CPU を普段は使いながらも、 limits が近づいてくればスケーリングによって不足したリソースを賄うことができる。</p>
<p>言われてみればこれしかないという回答なのだが、ついつい長年の経験から、監視閾値は 100% 未満で設定する他考えられなくなってしまっていた。また各種ドキュメントや書籍を見ても、 100% を超過している例を見なかったのも先入観に拍車を掛けていたように思う。設定や機能についてはドキュメントでいくらでも知ることができるが、こういった実態に即したユースケースというものを、もう少し知っていきたいなと思う。</p>
]]></description>
            <link>https://chroju.dev/blog/k8s_hpa_target_bigger_than_resource_requests</link>
            <guid isPermaLink="false">k8s_hpa_target_bigger_than_resource_requests</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 05 Mar 2021 00:38:32 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[vercel/og-image を日本語に対応させたい]]></title>
            <description><![CDATA[<p>このブログを Next.js へ移した際、 <a href="https://chroju.dev/blog/blog_with_next_js_vercel">ブログを Next.js + Vercel に移行した - the world as code</a> の中で、 OGP 画像の動的生成を行っていることを書いた。使っているのは Next.js の Vercel が提供している <a href="https://github.com/vercel/og-image">vercel/og-image: Open Graph Image as a Service - generate cards for Twitter, Facebook, Slack, etc</a> 。画像を動的生成する API サーバとして動作させることができるのだが、元のレポジトリでは日本語対応ができていないので、 fork して使っている旨を書いていた。</p>
<blockquote>
<p>1つ問題があって、このサービスでは日本語のフォントに対応しておらず、日本語のページタイトルだと文字化けしてしまう。 (中略) これを fork して書き換えて自前で運営しちゃえばいい。 こんな感じ で Google Font から Kosugi を import している。</p>
</blockquote>
<p>しかし、その後フォントのインポートだけでは対応しきれていないことがわかった。ちゃんと日本語が表示できていることもあるのだが、できないこともあり、動作が不安定なのだ。特に Twitter Card として表示された際は表示できていないことが多かった。</p>
<p><a href="https://gyazo.com/f50238a1c1689c1b56e2dd7c4467b7ba"><img src="https://i.gyazo.com/f50238a1c1689c1b56e2dd7c4467b7ba.png" alt="Image from Gyazo" width="592"/></a></p>
<p>結論から言えば、結局まだ対処しきれていないのだが、取りあえずここまででやってみた対策をメモしておく。</p>
<h2>前提 : vercel/og-image のメカニズム</h2>
<p>前提として vercel/og-image の動作メカニズムを最初に書く。やっていることはシンプルで、画像の元になるものを HTML で組み上げ、それを <a href="https://pptr.dev/">Puppeteer</a> （正確には、その Node library 版である <a href="https://www.npmjs.com/package/puppeteer-core">puppeteer-core</a> ） を使ってスクリーンショットを撮り、画像化している。この一連の処理は AWS Lambda で動いている。</p>
<p>従ってこのレポジトリ自体の問題というよりは、 Lambda で Puppeteer を使った際の日本語表示に関する問題と捉えたほうがよい。 AWS Lambda の実行環境に日本語対応のフォントが含まれていないことへのノウハウは、かねてからウェブ上では散見されている。</p>
<h2>puppeteer の言語設定</h2>
<p>puppeteer は初めて使うので言語設定はあまり気にしていなかった。公式の言及ではないのだが、 <a href="https://stackoverflow.com/questions/46908636/how-to-specify-browser-language-in-puppeteer">javascript - How to specify browser language in Puppeteer - Stack Overflow</a> を参考にいくつか設定を追加した。</p>
<pre><code class="language-javascript">export async function getScreenshot(html: string, type: FileType, isDev: boolean) {
    const page = await getPage(isDev);
    await page.setViewport({ width: 2048, height: 1170 });
    await page.setExtraHTTPHeaders({
        'Accept-Language': 'ja-JP'
    });
    await page.setContent(html);
    const file = await page.screenshot({ type });
    return file;
}
</code></pre>
<pre><code class="language-javascript">        options = {
            args: ['--lang=ja'],
            executablePath: exePath,
            headless: true
        };
</code></pre>
<p>また、生成する html においても、 <code>&#x3C;html></code> を <code>&#x3C;html lang="ja"></code> に書き換えている。</p>
<h2>web font の読み込みラグ</h2>
<p>より根本的と思われるところで、 web font の読み込みラグの問題がある。今回日本語化にあたっては、 Google Font （先のエントリー時点では Kosugi と書いていたが、現在は <a href="https://fonts.google.com/specimen/Noto+Sans+JP?preview.text_type=custom">Noto Sans JP</a> を使っている）を使っている。しかし web font 、特に日本語対応のものはロードにそれなりに時間がかかるため、ロードが終わらないうちにスクリーンショットが撮られれば tofu 状態になってしまう。冒頭に書いたように「日本語が表示できたりできなかったりする」という点も、ロード時間が一定ではないことで説明がつきそうだと考えた。</p>
<p>これについては非常に原始的な措置だが、待たせることにした。 Vercel で動かしているので CDN でキャッシュが効くとはいえ、画像生成においてはどう考えても悪手なのだが、一旦やむを得ないものとしている。</p>
<pre><code class="language-javascript">    await page.setContent(html);
    await page.waitFor(1000);
    const file = await page.screenshot({ type });
    return file;
</code></pre>
<p>ちなみに「そもそも web font 使わなければいいのでは？」という話はもちろんあって、これも試したのだが、「日本語が表示できたりできなかったりする」ことに変わりはなかった。同様の報告が https://github.com/vercel/og-image/issues/108#issuecomment-657078789 にも上がっている。</p>
<h2>Conclusion</h2>
<p>以上の対応で9割近くは日本語表示できるようになり、課題だった Twitter でも表示を確認できた。百発百中にしたいのだが。。ついでにデザインも変更して、まぁ一旦はここで妥協かなというところには来ている。</p>
<p><a href="https://gyazo.com/ac58b6df434aa116c2e471564945a35e"><img src="https://i.gyazo.com/ac58b6df434aa116c2e471564945a35e.png" alt="Image from Gyazo" width="591"/></a></p>
<p>余談だが、今回調べる中で Google の Noto フォントが「No tofu」の意味であることを初めて知った。</p>
]]></description>
            <link>https://chroju.dev/blog/vercel_og_image_with_japanese</link>
            <guid isPermaLink="false">vercel_og_image_with_japanese</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 21 Feb 2021 02:01:26 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『Implementing Service Level Objectives』を読んだ]]></title>
            <description><![CDATA[<p>https://www.oreilly.com/library/view/implementing-service-level/9781492076803/</p>
<p>O'Reilly Media より2020年8月に発刊された、 SLO practice のみに着目した1冊を読んだ。英語版のみで、邦訳は現時点で発刊されておらず、 O'Reilly Online Learning で読んだ。</p>
<p>SLO は SRE を実践するにあたっての中心的なプラクティスの1つで、いわゆる SRE book こと『<a href="https://www.oreilly.co.jp/books/9784873117911/">サイトリライアビリティエンジニアリング</a>』では第4章で言及されている。 SRE が「サイト信頼性」を守るにあたり、そもそもの守るべき「信頼性」とは何かを定義しなくてはならないわけで、『<a href="https://www.oreilly.co.jp/books/9784873119137/">サイトリライアビリティワークブック</a>』第20章では、「SREがない場合であっても、SLOを使うことによってSREのプラクティスはできます（p.407）」とさえ書かれている。</p>
<p>それだけ重要な実践なのだが、実際に取り組むのはなかなか難しい。まず、適切な SLO （SLI） をどう決めれば良いのか。よくあるのは「99.9%のレスポンスが一定時間内に返っていること」といった SLO だが、サービスによっては、単にレスポンスが早いことだけがユーザーからの信頼を得る材料とも限らない。また SLO practice にはエラーバジェットの考え方がある。例えば 99.9% の SLO を掲げた場合、月間で許容されるダウンタイムは約40分であり、これを「バジェット」として、底が尽きたら新機能のリリースはストップし、信頼性向上のための施策に舵を切ろう、というのが SRE book でのやり方だ。頭では理解できるが、リリースを実際に停めてしまうのはビジネス的にかなりインパクトの大きいジャッジであり、当然ながら SRE team のみならず、開発チームどころか経営層まで巻き込んでいく必要がある。</p>
<p>技術面だけではなく、組織運営、組織文化といった領域にまで広く踏み込む必要があるのがこのプラクティスで、その実践にあたって本が丸一冊書けてしまうというのも頷ける。この本では技術面、組織文化面、両面から如何に SLO practice を実践していくか、統計的な知識なども交えつつ、かなり細かく記述されている。 SLO の実践は、一度導入したらハイ終わりというものでもなく、絶え間なく計測、評価、改善を繰り返していくものなので、困ったときに末永く参照できる本として、手元に置いておけそうだと感じた。</p>
<p>以下では、印象に残った箇所をピックアップしていく。</p>
<h2>段階を踏んで実践する</h2>
<p>ソフトウェアエンジニアにはおなじみの「小さく始める」やり方がこの本でも踏襲されている。特にエラーバジェットについては、賛同を得て推進するには「長い道のり (long road)」になると書かれている。もちろん、だからできなくても仕方ないという話ではないが、少し安心させられた。</p>
<blockquote>
<p>Thinking about your services with SLIs is the first step; thinking about how you need to be reliable for your users with SLOs is the second; calculating how you’ve performed against your target over time is the third. Actually using your error budget status to have discussions and make decisions is the fourth and final step. ( Chapter 5. How to Use Error Budgets )</p>
</blockquote>
<p>まずは適切な SLI を定めて計測を始めてみること。計測して結果が出なければ、そもそも SLO を守ろうという意識自体生まれにくいのかもしれない。</p>
<h2>エラーバジェットは意思決定の材料</h2>
<p>エラーバジェットが枯渇した際、すべてのリリースを停止するというのが SRE book に書かれた実践だが、本書ではその判断には慎重になるべきだとされている。</p>
<blockquote>
<p>Don’t freeze your pipeline unless you only have one product and believe it to be truly the best choice. ( Chapter 5. How to Use Error Budgets )</p>
</blockquote>
<p>エラーバジェットを、機械的にリリースするか否かをゼロイチで判断するための指標として使うのではなく、重要なのは意思決定の材料として用いることである。大規模なリリースを行うときに、現状バジェットが残っているのかどうか、あまり残っていないのなら、今そのリリースを行うことが経営的にプラスなのかどうなのか、そういった思考プロセスを踏めることが価値になる。</p>
<h2>SLO を元にアラートする</h2>
<p>これは『ワークブック』にも記載がある内容だけど、いわゆる CPU 使用率の閾値監視などではなく、 SLO を元にアラートは上げるべきだとされている。</p>
<blockquote>
<p>Instead of alerting on internal system states (such as CPU usage), alert on what really matters: the user experience (for example, latency, errors, correctness, and other SLO-worthy concepts). ( Chapter 8. SLO Monitoring and Alerting )</p>
</blockquote>
<p>これ自体は比較的一般的な話ではあるが、具体的に SLO ベースのアラートをどう上げるかというと、エラーバジェットのバーンレートを使うのだという。つまり、急激にエラーバジェットが消費されているようなときにアラートを上げるというものであり、具体的には「1時間に2%消費」している場合にページングするという例が載っている。</p>
<p>考え方としては非常に理解できる一方、いくつかの困難も覚える。1つには、半死半生のような状態で、ゆるやかなバーンレートのときに即時対応を行わなくて本当に良いのか、という点。「SLOさえ守っていればOK」という価値観に自分はどうも慣れなくて、何はともあれ落ちていたらすぐ復旧するべきと考えてしまう。これは組織内での取り決めにもよるのだとは思うが。</p>
<p>もう1つは、ではこのバーンレートによるアラートをどう実装したらいいのか、という点。複雑な統計処理を行った上でアラートできるような監視ソフトウェア、サービスはそれほど多くないんじゃないだろうか。メジャーな監視 SaaS である Datadog には SLO の計測機能こそ存在するが、エラーバジェットの機能は有していない。このあたり、具体的なツールを交えた実践例があれば是非聞いてみたい。</p>
<h2>QA との関係性</h2>
<p>Chapter 6. Getting Buy-in になかなか衝撃的な一節がある。</p>
<blockquote>
<p>I have seen the dedicated QA team eventually get disbanded and redistributed into the core engineering team.</p>
</blockquote>
<p>決して QA スキル人材が不要になると言っているわけではない。 SLO practice を進めるうちに、各プロダクトチームが内在的に品質保証 = 信頼性維持のためのプロセスを回すようになるので、 QA 専任のチームというものから形態が変化していくということだ。</p>
<p>これは QA に限らず、 SRE も同様だと考えている。 SRE の考え方が浸透すれば、各プロダクト内で「SRE をする」ようになり、 SRE 専任チームの必要性は薄くなっていく。このあたりについても『ワークブック』などに言及があるので、やはりこの本は SRE 本2冊と並行で読むと学びが深くなると思う。</p>
<h2>Appendix: 英語技術書を読むことについて</h2>
<p>今回、英語技術書を読む習慣をつけようと考えて、その第一弾で本書を読んでみた。全文通読したわけではなく、重要そうなところや気になるところを各章拾い読みした形ではあるが、とりあえず1冊全体に目を通せたので多少自信になった。英語を読む習慣をつけるだけで、アクセスできる資料は何倍にも膨れ上がるので、今後も継続的に読み、そしてもっと読書スピードを上げていきたい。</p>
]]></description>
            <link>https://chroju.dev/blog/implementing_service_leve_objectives</link>
            <guid isPermaLink="false">implementing_service_leve_objectives</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Thu, 28 Jan 2021 03:59:09 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[YubiKey + GPG で統一的な鍵の管理を行う]]></title>
            <description><![CDATA[<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">$5,000で Let&#39;s Encryptを12時間ご利用いただけます。次の12時間で$5,000を寄付しましょう！お礼の印として、<a href="https://twitter.com/Yubico?ref_src=twsrc%5Etfw">@Yubico</a> よりSecurity Key NFCを無料でお受け取りいただけます (送料はかかりません)！<a href="https://t.co/swycXbtpSz">https://t.co/swycXbtpSz</a> <a href="https://t.co/QJwoWKWKS8">pic.twitter.com/QJwoWKWKS8</a></p>&mdash; Let&#39;s Encrypt (@letsencrypt) <a href="https://twitter.com/letsencrypt/status/1288733908771561473?ref_src=twsrc%5Etfw">July 30, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>昨年、 <a href="https://letsencrypt.org/ja/">Let's Encrypt</a> が寄付の返礼として <a href="https://www.yubico.com/%E3%83%97%E3%83%AD%E3%83%80%E3%82%AF%E3%83%84/?lang=ja">YubiKey</a> をプレゼントするキャンペーンを行っていて、以前より YubiKey には興味があったので入手していた。その後長らく放置してしまっていたのだが、前回 <a href="https://chroju.dev/blog/m1_macbook_pro">Macbook Pro (13-inch, M1, 2020) を購入した - the world as code</a> で書いた通り、 PC を新調して移行するにあたり、 GPG 周りを改めて YubiKey を使ってセットアップしてみた。</p>
<p>なお補足すると、先のツイートの <code>$5,000</code> は <code>¥5,000</code> の誤りであり、入手できた YubiKey は <a href="https://www.yubico.com/jp/product/yubikey-5-nfc/">YubiKey 5 NFC</a> である。</p>
<h2>YubiKey とはなにか</h2>
<p>機能は非常に多い。検索するとワンタイムパスワードトークンだとか、二要素認証デバイスなどと記述されている場合があるが、機能はそれだけにとどまらない。国内正規代理店である株式会社ソフト技研の記事 <a href="https://www.yubion.com/post/yubikey-5-%E3%81%AE%E6%A9%9F%E8%83%BD%E3%80%90yubikey%E3%81%A8%E3%81%AF-part2%E3%80%91">YubiKey 5 の機能【YubiKeyとは-part2】</a> からリストアップしてみる。</p>
<ul>
<li>FIDO U2F</li>
<li>FIDO2 or WebAuthn</li>
<li>OTP (One-time Password)</li>
<li>TOTP (Time-based One-time Password)</li>
<li>スマートカード機能（クライアント証明書の格納、 OpenPGP 秘密鍵の格納）</li>
</ul>
<p>今回試したのは最後のスマートカード機能であり、 OpenPGP の秘密鍵を格納して、 PGP による署名、認証等に用いることができるようにした。</p>
<p>他の機能を概観すると、 OTP は、 YubiKey 本体のアイコン部分をタッチしたり、 YubiKey 5 NFC の場合は NFC で通信することによって生成される（ちなみに、あのアイコンをタッチすると指紋認証できるのではと勘違いしていたが、 YubiKey に生体認証の機能はない）。僕が使っているパスワードマネージャー <a href="https://bitwarden.com/">Bitwarden</a> のプレミアム機能と連携できるようだが、現状非プレミアムで使っているため試すに至っていない。 TOTP はいわゆる二段階認証のそれだが、スマホアプリでの認証との比較優位が見い出せなかった。 FIDO, FIDO2 については正直技術的に理解しきれていない部分があり、どこかのタイミングで勉強できればと思っている。</p>
<h2>PGP, OpenPGP, GPG</h2>
<p>名前が似ていて PGP, OpenPGP, GPG を混同しがちだったが、関係性をまとめると以下のようになる。</p>
<ul>
<li>Phil Zimmermann が開発した暗号ソフトウェアが PGP (Pretty Good Privacy)</li>
<li>PGP を元にして、 RFC で定められた暗号文、デジタル署名などの規格が OpenPGP</li>
<li>OpenPGP を元にして、 GNU により公開されているソフトウェアが GPG (GnuPG)</li>
</ul>
<p>GPG には暗号関連の技術で実現する機能の多くが実装されている。公開鍵暗号、デジタル署名、一方向ハッシュ関数、鍵リングの管理など。今回はこの GPG を用いて Git commit へのデジタル署名と、 ssh key の管理を実現し、その鍵の管理に YubiKey を用いることにした。</p>
<p>PGP や GPG については <a href="https://www.amazon.co.jp/dp/B015643CPE/">結城浩『暗号技術入門 第3版　秘密の国のアリス』 (2015, SBクリエイティブ)</a> を参考として学んだ。</p>
<h2>今回実践したこと</h2>
<p>今回の実践にあたって、参考としたのは主に以下の資料。</p>
<ol>
<li><a href="https://support.yubico.com/hc/en-us/sections/360003997900-Guides">Guides – Yubico</a></li>
<li><a href="https://github.com/drduh/YubiKey-Guide">drduh/YubiKey-Guide: Guide to using YubiKey for GPG and SSH</a></li>
<li><a href="https://text.baldanders.info/openpgp/gnupg-cheat-sheet/">GnuPG チートシート（鍵作成から失効まで） | text.Baldanders.info</a></li>
</ol>
<p>1. が YubiKey を販売している Yubico の公式ガイドにあたる。基本的にはこれに従うべきとは思うが、かなりリンクが多くて目的のドキュメントが探しづらかったり、各ページの記載がコマンドを step by step で実行するだけのものが多く、そのコマンドが何を意味するのか掘り下げづらいなど、少々難を覚えた。 2. は執筆者の素性を把握していないのだが、 YubiKey + GPG についてより詳しく手順が解説されており、公式ガイドよりこちらを多くは参照していた。 GPG のコマンドチートシートとして、合わせて 3. を参照した。</p>
<p>先述した通り、やりたいことは「Git commit へのデジタル署名」と「ssh key の管理」の2つで、これを実現するために以下の手順で作業を行った。細かい手順は先の資料に記載があるのでここでは再説明せず、ポイントだけ書いておく。</p>
<ol>
<li>GPG キー (master key x1, sub key x3) の生成</li>
<li>sub key の有効期限設定</li>
<li>生成したキーの YubiKey への import</li>
<li>ローカルマシン側の master key と失効証明書の退避</li>
<li>keybase への鍵登録</li>
<li>Git commit への署名設定</li>
<li>ssh key として GPG キーを使用するための設定</li>
<li>移行後のマシンで YubiKey 内のキーを使用するための設定</li>
</ol>
<h3>GPG キーの生成</h3>
<p>GPG には master key （主鍵）、 sub key （副鍵） の概念が存在する。 master key の公開鍵は公開鍵基盤で広く公開するため、それと紐付く秘密鍵は厳重な管理が求められる。そこで実際の暗号化や署名には master key を直接は使わず、 master key が署名した sub key を用いる。sub key は署名用、暗号化用、認証用の3種類を作るのが一般的になっている。</p>
<p>手順は Yubico の <a href="https://support.yubico.com/hc/en-us/articles/360013790259-Using-Your-YubiKey-with-OpenPGP">Using Your YubiKey with OpenPGP – Yubico</a> に従ったが、一点だけ、この中では RSA 4096 bit を用いる形となっているが、 YubiKey 5 は楕円曲線暗号 ECC P-384 に対応しているので、そちらでもよかったかもしれない。</p>
<h3>sub key の有効期限設定</h3>
<p>以下のコマンドで設定した。期限設定後、期限到達前に延長も可能なので、それほど強い制約を課すものではない。</p>
<pre><code class="language-bash">$ gpg --quick-set-expire $MASTER_KEY_FINGER_PRINT 1y $SUB_KEY_FINGER_PRINT
</code></pre>
<h3>生成したキーの YubiKey への import</h3>
<p>GPG にスマートカードへの書き出し機能が備わっており、これを利用する。 import したキーを読み出す際には、 PIN によって制限がかかる格好となっている。これはデフォルトで <code>123456</code> という値になっているので、あわせて変更が必要となる。 YubiKey の紛失も考えると、チャレンジ回数は制限しておいたほうがよい。</p>
<h3>ローカルマシン側の master key と失効証明書の退避</h3>
<p>YubiKey にキーを import したら、ローカルマシン内の master key は紛失、盗難を回避するために、別のディスクなどへ退避してオフラインで保管することが推奨されている。これが結構悩みどころで、本気で保管するならばある程度冗長性のあるディスクに保存したいところだが、その手のディスクはご自宅にあるとしてもネットワーク接続された NAS の場合が多く、オフラインにならない。一旦 USB メモリに退避はしたものの、現代においてはかなりシビアな運用ではないかという気がしている。</p>
<p>また master key の失効証明書が、キー生成時に macOS の場合は <code>~/.gnupg/openpgp-revocs.d</code> に生成されている。これも盗難された場合には悪用の危険があるため退避が必要だが、 master key の紛失時に必要となるものであるため、 master key とは別途保存が必要となる。</p>
<h3>keybase への鍵登録</h3>
<p><a href="https://keybase.io/">Keybase</a> は公開鍵基盤を提供するサービスであり、ここに公開鍵を登録した。公開鍵基盤では、その鍵が誰のものであるか保証する必要があるわけだが、 Keybase は SNS などを用いて本人であることを保証できる点が特徴となっている。僕のアイデンティティはこちら。</p>
<p>https://keybase.io/chroju</p>
<p>Keybase には秘密鍵も登録可能で、その鍵を用いて Keybase の UI 上で暗号化サービスや、秘匿ファイルの共有なども行うことができる。</p>
<h3>Git commit への署名設定</h3>
<p>先の 2. の資料に則ったので割愛する。 GitHub 側でも　<a href="https://docs.github.com/ja/github/authenticating-to-github/managing-commit-signature-verification">コミット署名の検証を管理する - GitHub Docs</a>　で手順を公開している。</p>
<p><a href="https://gyazo.com/87295cc541be1420bb78497a1cae68b2"><img src="https://i.gyazo.com/87295cc541be1420bb78497a1cae68b2.png" alt="Image from Gyazo" width="303"/></a></p>
<h3>ssh key として GPG キーを使用するための設定</h3>
<p>これも 2. に手順が詳細に記載されている。</p>
<h3>移行後のマシンで YubiKey 内のキーを使用するための設定</h3>
<p>移行後のマシンで YubiKey 内のキーを使うには、 YubiKey を挿した上で以下の手順を行った。</p>
<ol>
<li><code>gpg --card-edit</code> でスマートカードの操作モードに入り、 <code>fetch</code> コマンドで、 YubiKey に登録した URL (keybase) から公開鍵をダウンロード</li>
<li>この鍵を信用するために <code>gpg --edit-key</code> で鍵の操作モードに入り、 <code>trust</code> コマンドで信頼する</li>
<li>新しいマシンを Keybase に登録する</li>
</ol>
<p>インポートした鍵は、新しいマシン上では「知らない鍵」にあたるため、それを信用していいのかどうか GPG 側では「不明」のステータスになっている。これを自身の鍵であるとして信用するのが 2. の手順。自分の鍵の場合、信用度は「ultimate (究極)」になる。</p>
<pre><code class="language-bash">❯ gpg -k            
/Users/chroju/.gnupg/pubring.kbx
--------------------------------
pub   rsa4096 2020-08-23 [SC]
      5B1586BD87F81233D5A72590B2901C02871B6CD5
uid           [  究極  ] chroju &#x3C;chroju@users.noreply.github.com>
sub   rsa4096 2020-08-23 [E] [有効期限: 2022-01-17]
sub   rsa4096 2020-08-23 [A] [有効期限: 2022-01-17]
sub   rsa4096 2020-08-23 [S] [有効期限: 2022-01-17]
</code></pre>
<p>また Keybase はアカウントとデバイスを対応づけることが可能になっており、信頼したデバイスからでなくては操作を受け付けない場合がある。そこで新しいデバイスを導入した際には、 Keybase への登録も忘れずに行う必要がある。</p>
<h2>Impression</h2>
<p>これまで特に ssh 鍵は作ってはキーフレーズを忘れてしまったり何度か作り直したりしていたので、一括管理できる方法を導入してスッキリさせることができた。難点としては YubiKey がなければ ssh も commit も出来ないという点で、こういう運用をするのであれば USB Type-C 対応の YubiKey が必要になりそう。今は常に家で作業しているので、ディスプレイの USB-A ポートが使えるのだが。</p>
<p>また GPG の仕組み、公開鍵基盤の仕組みなどを改めて復習できたのもよかった。 FIDO など、まだ活用できていない YubiKey の機能も今後概観したい。</p>
]]></description>
            <link>https://chroju.dev/blog/yubikey_gpg_with_git_commit_signing_and_ssh</link>
            <guid isPermaLink="false">yubikey_gpg_with_git_commit_signing_and_ssh</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 17 Jan 2021 10:04:25 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Macbook Pro (13-inch, M1, 2020) を購入した]]></title>
            <description><![CDATA[<p><a href="https://gyazo.com/f0ee461dcb5907e157a826e803e47bbb"><img src="https://i.gyazo.com/f0ee461dcb5907e157a826e803e47bbb.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>まったくもって買うつもりがなかったんだけど、 MBP のキーボード上にたっぷりドレッシングがかかったサラダをぶちまけてしまうアクシデントがありまして。。あの初期バタフライキーボードのうっすい打鍵感が、油が間に挟まったのか、さらにうっすくなって押しているのか押してないのだかもわからなくなり、終いには掃除しようとキーを外したところ壊してしまいまして。。泣く泣く Genius Bar に持ち込んではみたものの、過失による修理なので最大10万ぐらいかかるという話で、それならあと数万上乗せして新品買っちゃうかぁ、ということで買った次第。</p>
<h2>なぜ M1 MBP なのか</h2>
<p>まだまだ未知数な M1 に日和って Intel にしておこうかともちょっとだけ思ったのだが、周囲に背中を押されたのと、価格差が無視できないぐらいにあるということで M1 に。</p>
<p>また、ここ数年はパソコンを買い換えるたびに Linux デスクトップという選択肢も検討はしているのだが、毎度断念している。理由としては以下。</p>
<ul>
<li>そもそも macOS でそれほど困ってはいない
<ul>
<li>散見されるデメリットとして Docker Desktop の遅さというのがあるが、 Docker で開発する際は、仕事/プライベートともに開発用の k8s へ apply する場合が多く、 Desktop でのパワーは必要としていない</li>
<li>純粋な Linux や UNIX が Desktop として必要なわけでもない</li>
</ul>
</li>
<li>Alfred, Mission Control, Magic Trackpad による UX はかなり好きで依存している</li>
<li>通信制大学に通っている都合上、 MS Office が必要であり、 Linux を開発機にする場合は別途 macOS or Windows も必要になる</li>
</ul>
<p>2点目に関しては正直なところ、あんまりベンダーロックインされたものに依存するのはよくないんだろうな、と感じてはいる。特に Mission Control が便利で、複数の仮想デスクトップを3本指でするする切り替えながらの開発にはもうだいぶ馴染んでしまった。良くないんだろうなぁ、とは思ってはいるけど、やめられずにいる。</p>
<p>3点目、 MS Office が必要なら WSL2 とか Linux と Windows のデュアルブートという手もあるのだが、1,2点目の理由を覆してまで Windows を買う理由にはならなかった。 WSL2 は仕事で使った経験があるにはあるんだけど、あんまり好みではなかった。</p>
<h2>Impression</h2>
<p>よい。とてもよい。</p>
<p>特に発熱しない点と、バッテリーの保ち。前代の MBP はちょっと動画を開いたり、 Docker をゴリゴリ使ったりするとすぐにファンが回り始めていたのだが、 M1 MBP は半月ほど使っていてファンが回った覚えがほとんどない。そもそもそれほどヘビーな使い方をしてもいないとは思うが、 tmux で常にステータスバーへロードアベレージを表示していたのは要らなくなったなぁ、と感じている。</p>
<p>バッテリーに関してはだいたい8時間で空になる。前代 MBP がどれぐらいか正確なところは測っていないが、体感4時間ぐらいだっただろうか。かなり保つようになった。今ブログをアダプタ付けずに30分ほど書いたところだが1%も減っていない。参考に1週間の使用時間と電池の使用状況を貼っておく。</p>
<p><a href="https://gyazo.com/10acb70d8a686eacdcb2f11a0f44f4c7"><img src="https://i.gyazo.com/10acb70d8a686eacdcb2f11a0f44f4c7.png" alt="Image from Gyazo" width="490"/></a></p>
<p>M1 のソフトウェア対応状況については、 <a href="https://qiita.com/shibukawa/items/797b7cbb7e530842e6f7">M1 Macの開発環境 - Qiita</a> など先人の資料があるので割愛させてもらう。ざっくりと言うと、 M1 未対応のものでもそれなりに Rosetta で動くので、僕の利用範囲で「使えなくて困った」ものは今のところない。なぜか Ansible が上手く入れられていないが、 Python はもちろん arm 対応しているので自分の問題だと思う。</p>
<p>ただし、過渡期故の面倒くささは否めない。例えば Homebrew は <a href="https://brew.sh/2020/12/01/homebrew-2.6.0/">2.6.0</a> で arm 対応してはいるが、公式には Rosetta での使用が推奨されており、 arm 版 brew をインストールする場合は、 Intel 版とは別で <code>/opt/homebrew</code> というフォルダを作成して使うように促されている。これについては <a href="https://soffes.blog/homebrew-on-apple-silicon">Homebrew on Apple Silicon — Hi, I’m Sam</a> を真似して、 Intel 版には <code>ibrew</code> という alias を貼って使っている。</p>
<p>当然ながら既存の Brewfile もそのままは使えず、今は必要なものが出てきたら、その時々で <code>brew install</code> して、ダメだったら <code>ibrew install</code> し直すというフローになっている。長らく dotfiles として管理してきたが、 Intel Mac 用、 M1 Mac の arm 用、 Rosetta 用で <a href="https://github.com/chroju/dotfiles/tree/7431baa021faaefe46578827024eb825d8a6e05d/Brewfiles">Brewfile が3つに分かれる事態になってしまった</a> 。他にも VSCode など、本リリース前のバージョンしかまだ arm 対応していないソフトウェアもあり、いちいち調べる必要がある、というのは買う前に覚悟が必要。</p>
<p>まぁ、とはいえ続々 M1 対応が進んではいるし、キーボードもシザーキーボードで打ちやすいし、そして前モデルから10万近く安くなっているし、かなり良い買い物だったと感じている。</p>
]]></description>
            <link>https://chroju.dev/blog/m1_macbook_pro</link>
            <guid isPermaLink="false">m1_macbook_pro</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 11 Jan 2021 09:22:53 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[ブログを Next.js + Vercel に移行した]]></title>
            <description><![CDATA[<p>ということで、 feed を購読していただいていた方は <code>https://chroju.dev/feed.xml</code> に購読先を変更いただけますと幸いです。移行前のブログが <code>https://chroju.github.io</code> 、移行後のブログが <code>https://chroju.dev/blog</code> です。この記事までは双方に並行で上げていますが、今月中に以下の移行措置を行う予定でいます。</p>
<ul>
<li>移行前ブログから、移行後ブログへのリダイレクトを設定</li>
<li>移行前ブログでの更新は停止</li>
<li>移行前ブログの feed 更新も停止</li>
</ul>
<h2>なぜ Next.js なのか</h2>
<p>今回の移行理由は「 <a href="https://nextjs.org/">Next.js</a> を使ってみたかったから」に尽きる。</p>
<p>僕はインフラエンジニア出身の SRE で、経歴を辿るとサーバーや RDB のチューニングでパフォーマンスを維持することには注力してきたけど、フロント側の知識はほぼまったくと言っていいほどない。でも SRE がサイトの信頼性、具体的にはレスポンスの最適化に責務を負っているのに、フロントを理解していないというのはダメだろうと。静的なものを可能な限り CDN に置く時代において、サーバーのインフラ的なチューニングだけの知識だけでは心許なくなった。</p>
<p>Next.js を選んだのは、昨年後半あたりにその名を周りのフロントエンジニアから聞くことが多くなってきたのが直接的な契機だった。 Next.js は、かつて ZEIT という名前だった Vercel が提供している React.js のフレームワーク。 Vercel 自身が Next.js をデプロイできるプラットフォームを運営していて、 Next.js のコードを置いたレポジトリを連携するだけで、簡単にサイトをビルド、公開できる。</p>
<p>実は React.js + Netlify という組み合わせは昨年少し試してみていたこともあり、 React の知識を応用できそうで入門しやすいかなと感じた。また Server Side Rendering と Static Site Generator 双方の機能を持っているし、開発元の Vercel でデプロイすると、自動的に「サーバーサイド」（実体は AWS Lambda だが）まで構築してくれるというところに面白さを感じた。コンテナやサーバーありきのアーキテクチャの考え方から脱したかったんですよね。ついサーバー側を中心としてサービスを捉えちゃうんだけど、 Next.js だとはじめに javascript ありきで、そこから必要なサーバーサイド側のリソースが生成される形になっている。</p>
<p>ブログは4年間ほど hugo + github.io を使って運営していた。 Next.js を試せれば、対象はなんでもよかったんだけど、どうせなら長くサンドボックスとして使えるようにしようと、 hugo から移行を決めた。 hugo には大きな不満を覚えていたわけではないが、正直裏側をちゃんと理解していなくて、たまに手が届かない部分があったりしたので、フルスクラッチで自分でコード書いてブログ作るってのはありなんじゃない？と思った。</p>
<h2>技術背景</h2>
<p>フルスクラッチでコードを書く羽目になるのを覚悟していたのだが、実際のところは <a href="https://nextjs.org/learn/basics/create-nextjs-app">Create a Next.js App | Learn Next.js</a> という公式のチュートリアルがズバリ「markdown から ssg でブログを生成するサイト」を作る内容になっていたので、このチュートリアルを完走して出来上がったコードを少し改変するだけでこのブログは出来上がってしまっている。このチュートリアル、かなり親切な内容になっていてわかりやすかったのでおすすめ。</p>
<p>自分で改変した部分で特筆するものとしては、以下の通り。</p>
<h3>RSS の追加</h3>
<p><a href="https://logana.dev/blog/rss-feeds-in-a-nextjs-site">RSS Feeds in a nextjs site | Logan's Blog</a> を参考とした。 RSS の XML を生成できる <a href="https://www.npmjs.com/package/rss">rss - npm</a> を使用しており、 npm build 時に一緒に XML も生成している。</p>
<p><a href="https://gyazo.com/fee34366b43ebac65a962cfc420b3ea7"><img src="https://i.gyazo.com/fee34366b43ebac65a962cfc420b3ea7.png" alt="Image from Gyazo" width="632"/></a></p>
<p>トラブルとしては、どうも markdown の中に制御文字が紛れてしまっていたようで、上図のように XML にエラーがあるとブラウザから警告が出てしまった。このブラウザ側の警告、 line と column の位置にズレがあるのか、デバッグに苦労した。 W3C が <a href="https://validator.w3.org/feed/">W3C Feed Validation Service, for Atom and RSS</a> という feed xml の validator を公開していて、こちらを使ったほうがデバッグしやすかった。</p>
<h3>OGP 画像の動的生成</h3>
<p>実は Vercel　が <a href="https://og-image.now.sh/">https://og-image.now.sh/</a> という、 OGP 画像の動的生成サービスを保有している。先のチュートリアルの中では、これを使って OGP 画像を link タグに設定する手順まで含まれている。だが1つ問題があって、このサービスでは日本語のフォントに対応しておらず、日本語のページタイトルだと文字化けしてしまう。</p>
<p>解決策としては、このサービスは OSS で <a href="https://github.com/vercel/og-image">vercel/og-image: Open Graph Image as a Service - generate cards for Twitter, Facebook, Slack, etc</a> に公開されていて、おまけに Vercel へデプロイ可能になっているので、これを fork して書き換えて自前で運営しちゃえばいい。 <a href="https://github.com/chroju/og-image/commit/7dda4b605b3b3d8a4d0deace2d03745797c7b6be">こんな感じ</a> で Google Font から Kosugi を import している。また Vercel の無料プランだとメモリは 1024 MB 以下、リージョンは1箇所しか使えないので、そのあたり vercel.json も書き換えてやる必要がある。</p>
<p>チュートリアルでは OGP 最低限の設定しか成されないので、 <a href="https://ogp.me/">The Open Graph protocol</a> を参考にいくつか追加している。</p>
<h3>Syntax highlight の導入</h3>
<p><a href="https://prismjs.com/">Prism</a> を使っている。 <a href="https://highlightjs.org/">highlight.js</a> と迷ったのだが、 Prism のほうが導入が簡単そうかなぁ、という素人の感想。 <code>useEffect()</code> で読み込むだけだったので。</p>
<p>Prism はハイライト対象の言語が選択式になっていて、必要なものだけ import して使う形になる。これについては <a href="https://github.com/mAAdhaTTah/babel-plugin-prismjs">mAAdhaTTah/babel-plugin-prismjs: A babel plugin to use PrismJS with standard bundlers.</a> を使わせてもらった。 Prism の対応言語のみならず、プラグインやテーマも一括して babel で管理できて便利。</p>
<pre><code class="language-json">{
    "presets": [
        "next/babel"
    ],
    "plugins": [
        [
            "prismjs",
            {
                "languages": [
                    "javascript",
                    "css",
                    "bash",
                    "diff",
                    "docker",
                    "go",
                    "hcl",
                    "json",
                    "markdown",
                    "nginx",
                    "python",
                    "ruby",
                    "typescript",
                    "vim",
                    "yaml"
                ],
                "plugins": [
                    "line-numbers"
                ],
                "theme": "tomorrow",
                "css": true
            }
        ]
    ]
}
</code></pre>
<h3>ifamely 対応</h3>
<p>外部サイトをリンクする際に、ブログカードと言うのだろうか、 OGP から情報を持ってきて見栄えよい表示を実現するのに <a href="https://iframely.com/">ifamely</a> というサービスを使っている。こういうやつ。</p>
<p><a href="https://gyazo.com/688003d1a9d81829312ef7c8f3e9f06a"><img src="https://i.gyazo.com/688003d1a9d81829312ef7c8f3e9f06a.png" alt="Image from Gyazo" width="644"/></a></p>
<p>これが上手く表示できなかった。原因としては、 markdown から生成した HTML を <code>dangerouslysetinnerhtml</code> に渡してレンダリングしているのだが、この関数が <code>dangerously set</code> と危険性の認識を示しているように、 XSS を防ぐ目的で、渡された script タグを実行しないようにしていること。 ifamely は外部 script の実行が必要になっている。</p>
<p>対処としては <a href="https://medium.com/@suncommander/how-to-inject-scripts-using-dangerouslysetinnerhtml-on-client-side-rendering-973037cc06b7">How to inject scripts using dangerouslysetinnerhtml on Client-Side Rendering? | by SunCommander | Medium</a> を参考に、 <a href="https://github.com/nfl/react-helmet">nfl/react-helmet</a> を使って別途必要な script だけ読み込んでいる。ただやり方的にちょっとダーティーだなという気はしている。</p>
<h3>その他</h3>
<p>細かくいろいろやっている。</p>
<ul>
<li>front matter の扱いが適当で統一されていなかったので YAML で統一した</li>
<li>fontawesome を導入した</li>
<li>CSS をちょっと書いた</li>
</ul>
<h2>今後</h2>
<p>CSS はあんまりこだわりたくないのだが、もう少しだけ頑張る必要がありそう。 <code>blockquote</code> だけ表示がおかしい状態になっている。</p>
<p>それ以外は一応動く状態になっているし、明らかに移行前よりレスポンスが良くなった。が、 lighthouse によるとまだまだ全然なので、折りを見て少しずつ良くしていきたいなあと思っている。今更だけど Web の標準に強くなっていきたい。</p>
<p>あと Next.js は概念的にはコンポーネントと props さえわかっていれば OK という感じで飲み込めたのだが、そもそも ES2015 ちゃんとわかってないとか、チュートリアルでは js だったけど TypeScript で書き直してみたいなぁ、などということも考えている。</p>
<p><a href="https://gyazo.com/a593ac2e3b804f319b56c80a687f3c9b"><img src="https://i.gyazo.com/a593ac2e3b804f319b56c80a687f3c9b.png" alt="Image from Gyazo" width="983"/></a></p>
]]></description>
            <link>https://chroju.dev/blog/blog_with_next_js_vercel</link>
            <guid isPermaLink="false">blog_with_next_js_vercel</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 02 Jan 2021 01:19:59 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Retrospective 2020]]></title>
            <description><![CDATA[<p>年間振り返りエントリー6年目。</p>
<ul>
<li><a href="https://chroju.github.io/blog/2015/12/31/looking-back-2015/">2015</a></li>
<li><a href="https://chroju.github.io/blog/2016/12/28/looking_back_2016/">2016</a></li>
<li><a href="https://chroju.github.io/blog/2017/12/29/looking_back_2017/">2017</a></li>
<li><a href="https://chroju.github.io/blog/2018/12/31/looking_back_2018/">2018</a></li>
<li><a href="https://chroju.github.io/blog/2019/12/31/looking_back_2019/">2019</a></li>
</ul>
<p>昨年までは「総括」という単語を使っていたが、今年は Retrospective にしてみた。英語でかっこいいよね、という単純な理由もあるが、いま属している会社がスクラムを基軸としているので、個人の振り返りやタスクのサイクルの中でもスクラムのプラクティスを意識できればな、という思いもある。</p>
<p>昨年同様に定量、定性の両面で振り返る。</p>
<h2>定量評価</h2>
<h3>ブログ</h3>
<p>昨年比4本減の23本書いた。あんまり書いていないな、という自覚は自分でもあった。後述するけど、プライベートで技術探求やインプットがあんまり回っていなくて、学んだことをブログに書くサイクルを確立でてきていなかった。とはいえ本をそれなりに読んだりしてはいるし、単純に怠慢だとも言える。</p>
<p>Advent Calendar は今年も去年と同様、 Terraform と会社（グロービス）2本立て。どちらも Terraform ネタなんだけど、会社で書いたほうが LGTM とはてブをだいぶ集めてくれたのは嬉しいような微妙なような。</p>
<ul>
<li><a href="https://chroju.github.io/blog/2020/12/05/terraform_cloud_with_alfred/">Terraform Cloud を Alfred や CLI から操作する | the world as code</a></li>
<li><a href="https://qiita.com/chroju/items/13d8f5c6719e2f4711f3">Terraform について、やっていることをすべて話そう - Qiita</a></li>
</ul>
<h3>GitHub Contributions</h3>
<p><a href="https://gyazo.com/0ff9d65e1f99aba07bd6adc5d781d470"><img src="https://i.gyazo.com/0ff9d65e1f99aba07bd6adc5d781d470.png" alt="Image from Gyazo" width="720"/></a></p>
<p>Public repository で 466 。昨年が 290 なのでかなり増えたのだけど、なんで増えたのかがいまいちわかってない。が、今年も引き続き、使っている OSS で何かあれば issue や PR をちゃんと上げることを意識した。もう習慣になっていると言ってよさそう。 <a href="https://github.com/future-architect/vuls/issues/1083">vuls でバグ報告したら15分で直った</a> のがちょっと面白かった。</p>
<p>private のほうは会社が Kubernetes と Terraform で Infrastructure as Code が一段と進んだので 4000 越えてる。昨年比 2800 ぐらいの増加。その代わり GitHub Notification がパンクしててなんも読めてない、みたいな感じなので年末年始でどうにかしようと思ってたんだ。今思い出した。</p>
<h3>読書</h3>
<p>印象に残ったのをピックアップ。</p>
<ul>
<li><a href="https://www.amazon.co.jp/dp/4873119014">Kubernetesで実践するクラウドネイティブDevOps</a></li>
<li><a href="https://www.amazon.co.jp/dp/4122018331">失敗の本質―日本軍の組織論的研究</a></li>
<li><a href="https://www.amazon.co.jp/dp/479810261X">静かなリーダーシップ</a></li>
<li><a href="https://www.amazon.co.jp/dp/4873118484">エンジニアのためのマネジメントキャリアパス</a></li>
<li><a href="https://www.amazon.co.jp/dp/4478108536">独学大全 絶対に「学ぶこと」をあきらめたくない人のための55の技法</a></li>
<li><a href="https://www.amazon.co.jp/dp/4862760643">なぜ危機に気づけなかったのか ― 組織を救うリーダーの問題発見力</a></li>
</ul>
<p>自分でもびっくりするぐらい「技術書」が少ない。理由としては Kubernetes という変化の早い分野が今年は中心だったので、本よりドキュメント読んでいるほうが多かった、というのはあったように思う。あとは O'Reilly Online で横断検索していろんな本から探っていたので、読了した本というとかなり少ない。その中でも特にいいな、と思っていたのが冒頭に上げた「Kubernetesで実践する〜」で、これが日本語で出版されたときは嬉しかった。 k8s の長期的な運用にフォーカスして、何を気にしなければならないのか、広範なエコシステムの中でどんなツールを使えばいいのか、ということを詳説した本で、右も左も分からない頃すごく役だった。</p>
<p>あとはチームリーダーになったために、マネジメントやリーダーシップ関連の本をよく読んでいた。結構な数は読んだと思うので、年が明けたら一旦こちらのインプットは停めて、また技術方面に軸を寄せたい。</p>
<h2>定性評価</h2>
<h3>注力した領域</h3>
<ul>
<li>Kubernetes
<ul>
<li>会社のプロダクション環境で Kubernetes が動き始めた。</li>
<li>いまだに全然わからんと思いながらやっていっている。</li>
<li>やることが多い、知るべきことが多い、大変。学習コストすんごい。</li>
<li>でも好き。</li>
</ul>
</li>
<li>Terraform
<ul>
<li>ずっと継続。自分の中で一番コアにいるツール。</li>
<li>Terraform 自体より、自動実行とかライフサイクルを考えることが多かった。</li>
</ul>
</li>
<li>クラウドアーキテクチャ全般
<ul>
<li>サーバーは要るか要らないか、コンテナは要るか要らないか、AWSは要るか要らないか、みたいな</li>
<li>選択肢がすごい増えているし、何がベストなのか考えるのが難しくなっている感覚</li>
<li>SPA、SSG、SSR あたりを考え始めると、 SRE と言えどフロントも無視できなくなってきた</li>
</ul>
</li>
<li>リーダースキル
<ul>
<li>後述</li>
</ul>
</li>
</ul>
<h3>ライフスタイル</h3>
<p>激しく変化した。というか変化していない人はいないだろう。</p>
<p>インドアな人間なのでそこまでしんどくはないし、新しい生活様式を受け入れるのでてんやわんや、ということもなかったんだが、会社、プライベート含め「周囲はどうだろうか？」ということを考えると自分が良ければ OK とはいかなかったり。外出していいのか、あれはやっていいのか、旅行してもいいのか、みたいな、自分の行動すべてに関して是非の判断が入るような生活はとても疲れる。</p>
<p>おそらくこれは不可逆な変化なんだろう、とは思っている。今は転職を全然考えていないが、次に転職するとき、リモートワークを認めてくれない会社にはもう入れないだろうなと思う。コロナ禍が完全に沈静化するにはあと1年じゃ効かないと思っているが、それを終えた先に社会がどうなっているのかはまだわからない。変化にはまだまだ柔軟でいる必要がある。</p>
<h3>リーダースキル</h3>
<p>社会人生活10年目で、ちゃんと職責与えられてリーダーをやる経験を初めてした。名ばかりのは何度かあったが。</p>
<p>とはいえメンバー個々人がスキル高くて自主的にガンガン仕事するようなチームなので、マイクロマネジメントの必要もないし、リーダーが何かしなきゃって強い責務が生じているでもないのだけど、それでもリーダーって何やったらいいんだろうな？というのをずっと考え続けた1年だった。問題を解決したり、強い意見を出すというよりは、意思決定の最終決定をすることと、その決定された意思に基づいた活動を支えること、何か問題があったり、起きそうであればそれを取り除くことが職責なのかなと今は思っている。</p>
<p>それがちゃんと行動習慣に落ちているかというと、まだそうでもないので来年の課題。</p>
<h3>常に疲れていた</h3>
<p>これらの変化があったせいなのか、常に疲れているな、という感覚がある1年だった。</p>
<p>理由としては、ずっと家にいるが故に、家事、仕事、プライベートといったさまざまなタスクが全部常にスタックされている感覚があったのがひとつ。出勤していると、会社にいるときは仕事のことだけ考えればいいし、メリハリがあったんだけど、家で仕事をしていると昼休みのうちに洗濯できそうとか、お茶を入れているときに「このへん汚れてるから掃除しなきゃ」って気付いちゃったりだとか、そういう感じで「やること」が無限に増えるし、やろうと思えばいつでもどのタスクにも着手できる、っていう、メンタル的にはわりと地獄みたいな状態だった。</p>
<p>どうすればいいかな、と考えてみてもまぁどうにもならなさそうなのだが、やらなくていいことを増やしたほうが良さそうかなと思っている。長期的に考えると書斎がほしい。家の中であっても、物理的に隔離された場所で仕事をするのがベストっぽいように思う。</p>
<h2>来年について</h2>
<p>軽くいきたい。</p>
<h3>がんばらない</h3>
<p>最後に書いた「常に疲れていた」の話があるのでがんばらないようにしようかと。やることを減らす、やらなきゃって思わないようにすることを徹底したい。来年もコロナには悩まされそうだし、ちょっとギア落として、とにかく生存することを目標にする年というのがあってもいいんじゃないかと。</p>
<h3>小さなサイクルを回す</h3>
<p>別の言葉だとフットワークを軽くする。本を1週間ぐらいでザッと読むとか、気になる技術領域があったら、休日半日ぐらいでサッと触って感触をつかんでみるとか、それでその結果はちゃんとブログに落とし込んで、サイクルを小さく回していきたい。</p>
<p>やることが増えたことへの対処の1つになるとも思っている。1個1個の「やること」を小さくしてしまえば負担は軽くなる。インフラから SRE になったことで、知るべき技術領域がかなり増えたというのもある。先述したようにフロントエンドも気にしたりしているが、8年9年のキャリアで本当にフロントは一切触ってこなかったりしたので。広く浅く、サービスの信頼性を守るための知識をつけたいな、という気持ちが強い。</p>
<h3>技術的な興味、方向性</h3>
<p>今あんまり手を出したい技術というのがなくて。 Kubernetes が大変なのでもっとやらなきゃってのでいっぱいなのでそれでいいかなとは思っている。あとは「小さく」というところで知らない技術を触る、少しだけ触るという機会はどんどん設けたい。この年末年始も Next.js でブログを作ることをしていて、実はもう出来上がっていてあとはリダイレクト設定するだけだったりする。新しいことをやるのはやっぱり楽しいので、なんだろう。これをやるぞ！って決めるというよりは、ノリでやっていこうかな、と。</p>
<p>こんなとこだろうか。社会は大変な状況だけど仕事は面白くてのっている感覚はあるので、無理せず楽しく来年は生きていきたい。</p>
]]></description>
            <link>https://chroju.dev/blog/retrospective_2020</link>
            <guid isPermaLink="false">retrospective_2020</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Thu, 31 Dec 2020 02:22:28 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Best Buy and Subscriptions 2020]]></title>
            <description><![CDATA[<p>一昨年より、年末にサブスクリプション契約をまとめるエントリーを上げているので今年もやってみる。今年はついでに、あんまりこれまでやったことがなかった「今年買ってよかったもの (Best buy) 」もまとめてみた。ステイホームにより、普段あんまり買わないものをそこそこ買ったので、せっかくなので紹介してみよう、という思い。</p>
<h2>Best buy 2020</h2>
<p>WFH 関連の物品については、 <a href="https://chroju.github.io/blog/2020/11/21/wfh_for_half_year/">WFH を始めて半年が過ぎ、調えたり諦めたりしたこと | the world as code</a> や <a href="https://chroju.github.io/blog/2020/04/15/remote_work_infrastructure_engineer_under_covid_19/">COVID-19 とリモートワーク - 設備だけではなくルーチンも大事 | the world as code</a> に書いているので除外した。とはいえ、ほぼおうちグッズしかない。</p>
<h3>デンタルフロス</h3>
<p>https://www.amazon.co.jp/dp/B07B5CD8NY</p>
<p>地味だが今年一番買ってよかったかもしれない。</p>
<p>昨年、親知らずを抜くために歯医者へ10年ぶりぐらいに行ったところ、治療が終わっても定期検診の予約をその場で4か月後に入れさせられるタイプの歯科だったので、そのまま定期的に通う習慣ができた。そのなかで歯科衛生士に強く勧められてフロスを使い始めた。</p>
<p>デンタルフロス、歯と歯の間にねじ込むのが少し怖くて使うのを躊躇していたのだけど、いざ使うとびっくりするぐらい汚れが取れる。電動歯ブラシを使ったり、それなりに歯磨きに気は遣っていたけど、それでも歯間って磨ききれないのだということを理解した。なんでも日本人はデンタルケアのリテラシーが低く、フロスもあまり使われていない（僕も使っていなかったし）そうだが、これは絶対使ったほうがいいと思うようになった。</p>
<p>ちなみにP字型ではなくY字型のものがいいとのこと。奥歯に使うとき、どちらが使いやすいか想像するとわかりやすい。最も良いのは、常に真新しいフロスを歯に当てて使えるリールタイプだそう。</p>
<h3>HASAMI</h3>
<p><a href="https://gyazo.com/73468be1d6cd5149c3b8cced5e1b2a28"><img src="https://i.gyazo.com/73468be1d6cd5149c3b8cced5e1b2a28.png" alt="Image from Gyazo" width="669.76"/></a></p>
<p>波佐見焼の陶磁器ブランド。実家を出てから10年ぐらい、食器は実家から持ってきたものと、1番くじなどで手に入れたものを使い続けていたのだが、ここらで統一感のあるシリーズで揃えるのもいいか、と買ってみた。</p>
<p>そもそも食器の知識が一切ないとこから始まったので、〇〇焼と付くような日本の焼き物は白地に青、みたいな保守的なイメージしかなく、こういうモダンなデザインがあること自体知らなくて驚いた。高いものが欲しいわけではないので、形状のバリエーションがあって、シンプルなものを探していて HASAMI をチョイスした。使い勝手は良いし、ネイビーの皿に載せるとだいたいのものが映える感じになって食事が楽しい。</p>
<p>最後まで比較していたのが美濃焼の <a href="http://www.sakuzan.co.jp/product/">SAKUZAN DAYS</a> 。こちらもカラフルで好き。</p>
<h3>H&#x26;F BELX のノンカフェインティー</h3>
<p>https://www.handfbelx.com/stores/</p>
<p>家で仕事をするときに飲むものはコーヒー、炭酸水、ノンカフェイン or 低カフェインのお茶の3種類。コーヒーはカフェイン摂取量の都合上、1日2杯と決めているし、炭酸水はお金がかかるのでお茶が一番飲む機会が多く、いろいろと探した1年だった。</p>
<p>ノンカフェインのお茶が最近は増えていて嬉しい。特にこの H&#x26;F BELX はノンカフェインティー専門の店で、種類がかなり豊富で飽きない。特にルイボスをベースにフレーバーを付けたお茶が多くあり、紅茶代わりのアールグレイや、甘いものが欲しいとき用のピーチなどが気に入っている。難点は店舗数が少ないこと。</p>
<p>他の店だと、無印良品にもノンカフェインティーが多く、トウモロコシ茶や韃靼そば茶をよく飲んでいる。</p>
<h3>ネスレ アールグレイポーション</h3>
<p>https://www.amazon.co.jp/dp/B01C44IV78</p>
<p>お茶絡みでもうひとつ。水や氷で割るとアイスティーになる、濃縮紅茶のポーション。昔からティーソーダが好きなのだが、あれはあんまり売っているものではないので、夏場はこれをウィルキンソンの炭酸で割って飲んでいた。人工甘味料が入っているし、そこまで香りがいいわけではないのだが、僕には十分。</p>
<h3>極 お米保存袋</h3>
<p>https://www.amazon.co.jp/dp/B07X5FSBDP</p>
<p>お米を冷蔵庫で保存したいけれど、大きな容器を入れられるほど冷蔵庫に容量がないんだよな、という長年の課題が解決した雑貨。ジッパーと空気弁が付いていて、最小限の容積でお米を冷蔵庫に保存できる。レビューを見ると「すぐに破れた」「ジッパーが閉めにくい」といった声もあるけど、特に問題なくもう半年以上使っている。破れたら買い換えるのも、この価格ならいいかな、と思っている。</p>
<h2>Subscriptions 2020</h2>
<p>昨年との diff です。</p>
<pre><code class="language-diff">  * Day One (¥2,800 / year)
  * MoneyForward プレミアム会員 (¥500 / month)
  * Nintendo Switch Online (¥2,400 / year)
  * Amazon Prime Student (¥2,450 / year)
  * Spotify Premium Student (¥480 / month)
  * シネマシティ (¥1,000 / year)
  * Dynalist Pro ($7.99 / month)
  * dアニメストア (¥400 / month)
  * freee (¥1,980 / month)
  * メールマガジン「読書日記／フヅクエラジオ」 (¥800 / month)
- * Online Learning with O’Reilly (about $500 / year)
+ * ATOK Passport (¥300 / month)
+ * IFTTT Pro ($1.99 / month)
+ * Association for Computing Machinery ($99 / year)
</code></pre>
<p>唯一解約されている O'Reilly は 一番下の ACM への乗り換えなので、実質的に今年は解約がなかった。安定してしまった。 ACM と O'Reilly の関係についてはもう有名な話なのでググってもらえると。</p>
<p>O'Reilly 、いくら読み放題と言っても値が張るし、そこまで読まないし、ということで長年躊躇していたが、いざ契約してみるとこれは「読み放題」であることが価値、というよりは、「数万冊のクオリティがある程度保証された技術書を横断検索できる」ことに大いに価値があった。ググる代わりに、オライリーを横断検索する権利を買う、って考えると「あ、安いかも」って思える。特に今年は Kubernetes に入門した年だったのでいろいろと悩む場面があり、そのたびにここで検索して複数の書籍から情報をピックアップして使っていた。</p>
<p>追加した ATOK Passport は、 Google 日本語入力の開発が滞っている、というような話を夏頃目にして、まぁ確かに、というのと、他の IME も試してみるか、というところで使ってみている。ただ正直、そこまで変換精度優れているか？という疑問がある（数学、コンピュータ系のちょっと込み入った単語になると全然変換されない）のと、設定項目が多すぎるのとで、首を傾げながら使っている節は強い。</p>
<p>IFTTT は突然有料化されてしまい、もう何年も使っているので急に手放すこともできず、お金を払い始めた。最初の年は自由に価格決めていいよ、ってことだったので最低価格にしている。</p>
<p>つい先日 <a href="https://k-tai.watch.impress.co.jp/docs/column/minna/1297192.html">「サブスク」費用を全部足し算したら、けっこうキツい - ケータイ Watch</a> という記事が話題になっていて、まぁこの記事はモバイル回線みたいな「それ生活費じゃない？」みたいなとこまでサブスク扱いしていてもにょる部分はあるのはあるんだけど、最近なんでもサブスクというか、月額課金制になりすぎじゃないかな、という感覚は強い。経営知識がないので、買い切りから月額制に切り替えるのってどういうメリットがあるのかいまいちわからない。毎月拠出可能な固定費なんて上限があって、その中で何を契約するか選ぶわけだから、月額制にすると例えば ATOK が全然違う領域のdアニメストアと比較検討されたりするわけで、不要な競争生じてない？とか思ってしまう。どうなんだろ。消費者的にも ATOK よりdアニメストアのほうが大切なので ATOK 切ります、みたいな意味のわからない比較はあんまりしたくない。今ぐらいが限界かなぁ、とは思っている。</p>
]]></description>
            <link>https://chroju.dev/blog/shopping_and_subscriptions_2020</link>
            <guid isPermaLink="false">shopping_and_subscriptions_2020</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 29 Dec 2020 08:15:29 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『なぜ危機に気づけなかったのか』を読んだ]]></title>
            <description><![CDATA[<p>https://www.amazon.co.jp/dp/B01E3R0VX6</p>
<p>「問題発見」の技術、メソッドを知りたくて、 Michael A. Roberto の『なぜ危機に気づけなかったのか（原題 : Know What You Don't Know ）』を読んだ。</p>
<p>問題発見を学びたいと思ったきっかけはリーダー職に就いたこと。チームの問題、メンバー個々の問題というのをきちんと察知してアクションできるようになりたかったのだけど、具体的にどうすればいいのか考えあぐねていたので本に頼ってみた。</p>
<p>僕らソフトウェア系のエンジニアは「問題解決」が本職と言ってもいいぐらいだけど、問題を解決するにあたっては、解決するべき問題をまず的確に見つける必要がある。それがつまり「問題発見」の技術ということになる。</p>
<p>ところが長年、この分野に関してあまり良い本に巡り会えなかった。真っ先に名前が挙がるのは『ライト、ついてますか』だと思うのだが、この本はどちらかと言えば、何かトラブルが顕在化した後で、では解決するべき問題は具体的になんなのか、それをどう捉えて解決していくべきなのかという、「正しい問題定義」の本に近い。</p>
<p>https://www.amazon.co.jp/dp/4320023684</p>
<p>僕が求めている「問題発見」の技術はそうではなくて、可視化されていない問題、あるいは見過ごされていたり、自覚されていない問題を如何にあぶり出すか、という技術のことだ。ラムズフェルド元アメリカ国務長官の <a href="https://ja.wikipedia.org/wiki/%E7%9F%A5%E3%82%89%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%81%A8%E7%9F%A5%E3%82%89%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E3%81%82%E3%82%8B">Unknown unknowns</a> という言葉が近い。そしてこの本は原題を見ればわかる通り、僕の求めていたことにドンピシャな本だった。</p>
<p>本書では問題発見に必要なスキルを7つに分類していて、それぞれ実際に起きた問題事例を教訓として、具体的なプラクティスに落とし込んでいるので飲み込みやすかった。</p>
<ul>
<li>フィルターを避ける</li>
<li>人類学者になる
<ul>
<li>
<blockquote>
<p>人に質問するだけでなく、その行動を見守らなければならない。というのも、人の発言と行動は一致しないものだからだ。 (p.7)</p>
</blockquote>
</li>
</ul>
</li>
<li>パターンを探す
<ul>
<li>
<blockquote>
<p>リーダーが目前の問題を明確に把握していなければ、役に立つ類似点を見つけて、それを正しく使うことはできない。この方法を使えば、暗黙の想定を明らかにし、事実と想定の区別をつけざるを得なくなる。 (p.136)</p>
</blockquote>
</li>
<li>
<blockquote>
<p>想定の検証:七つの重要な質問</p>
</blockquote>
</li>
<li>
<blockquote>
<ol>
<li>この状況における事実は何か。</li>
</ol>
</blockquote>
</li>
<li>
<blockquote>
<ol start="2">
<li>暖味な、あるいは不明瞭なことは何か。</li>
</ol>
</blockquote>
</li>
<li>
<blockquote>
<ol start="3">
<li>明確な想定と暗黙の想定と考えられることは何か。</li>
</ol>
</blockquote>
</li>
<li>
<blockquote>
<ol start="4">
<li>事実と想定を混同していないか。</li>
</ol>
</blockquote>
</li>
<li>
<blockquote>
<p>（略）</p>
</blockquote>
</li>
</ul>
</li>
<li>点を結びつける
<ul>
<li>
<blockquote>
<p>最初に自分の意見を述べるよりは、リーダーは会議のファシリテーター(進行役)に徹したほうがいい。リーダーは公開されていない情報を明るみに出すために積極的に介入し、メンバーを自由閣達な対話に引き込むべきであろう。 (p.167)</p>
</blockquote>
</li>
</ul>
</li>
<li>価値のある失敗を奨励する</li>
<li>話し方と聴き方を教える
<ul>
<li>
<blockquote>
<p>往々にして相手が話し終わらないうちに結論を出してしまうことがある。相手が話している最中に、どう答えようかと考えることがある。特定の言葉や意見の意味について、さまざまな憶測をめぐらし、話し手も自分がよく知っているのと同じ言葉づかいでしゃべっているものと早合点することが多い。 (p.216)</p>
</blockquote>
</li>
<li>
<blockquote>
<p>ある人が反対意見を述べても、それが多奴派の考え方をただちに変えることはないだろう。しかし、それによって異なった考え方が刺激されることが多い。 (p.227)</p>
</blockquote>
</li>
</ul>
</li>
<li>ゲームの録画を見る</li>
</ul>
<p>今は WFH で slack でのやり取りがメインになっているので、特に「フィルターを避ける」「人類学者になる」という観察を重視するスタイルは強く意識したいところだし、「点を結びつける」「話し方と聴き方を教える」に書かれているような、話し方や MTG でのコツについてはすぐにでも実践していきたい。「話し方と聴き方を教える」での指摘は結構刺さるものがあった。</p>
]]></description>
            <link>https://chroju.dev/blog/know_what_you_dont_know</link>
            <guid isPermaLink="false">know_what_you_dont_know</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 22 Dec 2020 09:47:57 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Alfred は「黒い窓」を使わなくなってからが本番]]></title>
            <description><![CDATA[<p>前回のエントリー <a href="https://chroju.github.io/blog/2020/12/05/terraform_cloud_with_alfred/">Terraform Cloud を Alfred や CLI から操作する | the world as code</a> の中で、 Alfred Workflow の話に触れたので、改めて書いてみる。</p>
<h2>Alfred Workflow とは何か</h2>
<p>Alfred というと黒い小さな入力フィールドがスッと出てきて、そこで色んなものをインクリメンタルサーチできるもの、というイメージが強いけれど、実際のところそれだけにはとどまらない。 Alfred Workflow をざっくり言えば、あるアクションを <code>trigger</code> し、 <code>input</code> を行い、それを受けて何らかの <code>action</code> を実行し、 <code>output</code> を出す、という4段階の流れを組み合わせることで、様々なツールを実現するもの、ということになる。</p>
<p><code>trigger</code> は読んで字のごとくトリガーで、 workflow を起動する契機になる。「黒い窓」から実行するのであれば、 trigger は設定しなくてもかまわない。 <code>input</code> は入力値で、あのよくある「黒い窓」での検索も <code>input</code> にあたる。正確に言えば、あの検索で選んだ候補が <code>input</code> になる。では <code>input</code> は何に対しての入力なのかと言えば、 <code>action</code> だ。 action が input から要は引数を取って、 URL を開いたり、ファイルを開いたりといったアクションを行う。 <code>output</code> は aciton の結果をどこかへ出力したい場合に使うもの、ということになる。そしてこれら4つは、どれも必須ではない。 <code>action</code> を <code>input</code> 無しに実行することだってできる。</p>
<p>例えば trigger には <code>Hotkey</code> というものがある。読んで字のごとく、任意のキーバインドで workflow を起動する場合に使う。そして action には <code>Launch Apps/Files</code> というアプリやファイルを起動できるものがある。この2つを組み合わせてみる。</p>
<p><a href="https://gyazo.com/e044827d8c15416085e2ee05254ed435"><img src="https://i.gyazo.com/e044827d8c15416085e2ee05254ed435.png" alt="Image from Gyazo" width="375"/></a></p>
<p>これで <code>Command + Shift + g</code> を押すと Gyazo が起動する workflow が出来た。 OS 標準のスクリーンショットを撮るのと似た感覚で、3つのキーを押すだけで簡単に Gyazo が起動できる。</p>
<p>このように、 Alfred で出来ることは「黒い窓」でやることだけに縛られないし、何かを検索してフィルタリングすることも必須ではない。組み合わせ次第で非常に多くの効率化が実現できる。</p>
<h2>Hotkey の有効活用</h2>
<p>Hotkey を使った例をもう1つ挙げる。</p>
<p>Alfred Workflow は export が可能になっていて、ウェブ上で広く公開されている Workflow がいくつもある。そのうちのひとつ、 <a href="https://www.packal.org/workflow/div">Div</a> を重宝している。</p>
<p><a href="https://gyazo.com/eb633b0877674babf5064207a8fa1c92"><img src="https://i.gyazo.com/eb633b0877674babf5064207a8fa1c92.gif" alt="Image from Gyazo" width="600"/></a></p>
<p>同種のツールだと有償の <a href="https://apps.apple.com/jp/app/magnet-%E3%83%9E%E3%82%B0%E3%83%8D%E3%83%83%E3%83%88/id441258766?mt=12">Magnet</a> が有名かもしれない。ウィンドウを画面の右半分、左下4分の1などにスナップさせてくれるツールで、 Magnet と異なるのは Alfred からのコマンド操作になるという点。</p>
<p>使い方は Alfred に <code>div 800 600</code> とウィンドウサイズを絶対的に指定してもいいし、右半分であれば <code>div right</code> といったコマンドも用意されている。そしてこの Workflow 、コマンドに対して Hotkey を割り振れるよう、あらかじめ blank の領域が用意されている。</p>
<p><a href="https://gyazo.com/fb13d8f6fbdae70144b5e87dc13c37b8"><img src="https://i.gyazo.com/fb13d8f6fbdae70144b5e87dc13c37b8.png" alt="Image from Gyazo" width="504"/></a></p>
<p>僕は <code>Command + Shift</code> と矢印キーの組み合わせで、最大化したり左右半分に寄せたりできるように組んでいる。この Hotkey はグローバルなキーバインドになるので、他のアプリケーションと重複しないよう、3キー程度の組み合わせにするのが無難だと思う。</p>
<h2>webhook を飛ばす</h2>
<p>最後にもう1つ、 Hotkey 以外での使い方も紹介する。</p>
<p>僕はタスクやメモに <a href="https://dynalist.io">Dynalist</a> というアウトライナー、要はツリー構造のエディタを使っている。</p>
<p>この Dynalist に inbox という機能がある。ツリーのある階層を inbox に指定すると、特定の webhook に投げた文字列がすべてその階層直下に保存されるというもので、例えば fav した Tweet を投げ込むフローを組んだりだとか、いろいろ応用ができる。</p>
<p>日頃仕事や勉強中に、わざわざ Dynalist を開いてメモするのは面倒なので、これも Alfred から投げられるようにしている。</p>
<p><a href="https://gyazo.com/50ebf792cd4459f42bb839516d996793"><img src="https://i.gyazo.com/50ebf792cd4459f42bb839516d996793.png" alt="Image from Gyazo" width="600"/></a></p>
<p>Hotkey を trigger にしているが、その次の <code>Keyword</code> と書かれているのは input に当たり、要するところ、これがあの「黒い窓」を使った入力ということになる。この設定では Hotkey でもこの Workflow は起動するし、 input の上部に書かれた <code>di</code> というキーワードを Alfred に打つことでも起動する。</p>
<p>「黒い窓」の入力を受けて、次の <code>Run Script</code> が action に当たる。自由に bash コマンドを実行できる。</p>
<p><a href="https://gyazo.com/1596fadbdeec9b0e8d357e31b3f19946"><img src="https://i.gyazo.com/1596fadbdeec9b0e8d357e31b3f19946.png" alt="Image from Gyazo" width="600"/></a></p>
<p>ここで入力を <code>{query}</code> として受けて、 webhook を飛ばしている。</p>
<p>最後の <code>Post Notification</code> と書かれているのが output に当たり、 macOS の通知に curl の実行結果を表示させている。これはあっても無くてもいい、保険のようなものではある。</p>
<p>これは「黒い窓」を使う Workflow ではあるが、しかし検索は行っていない。単なる入力用のフィールドとして、あの窓を使うこともできる。</p>
<h2>Conclusion</h2>
<p>ということで、結構いろんなことができる。ここで挙げた以外にも <code>trigger</code> , <code>input</code> , <code>action</code> , <code>output</code> には様々な種類があるし、それらを組み合わせることのできる <code>utilities</code> というものも存在する。まぁ、スクリプトが実行できる時点で何でもありではある。</p>
<p>ちなみにいわゆるよくある「黒い窓」で検索をするやつ、あれは <code>Script Filter</code> という input に該当する。 <code>Script Filter</code> の中で bash や python などのスクリプトを書き、決まった形式の JSON を出力するようにすると、あの検索が発動する。なので前回エントリーのように、動的に検索対象を引っ張ってくることもできるし、固定的な値から検索したいのであれば、 JSON を cat するだけでも OK だ。 HTTP status code の一覧を検索できるようにしたら便利かな、とか今は考えている。</p>
]]></description>
            <link>https://chroju.dev/blog/how_to_make_alfred_workflow</link>
            <guid isPermaLink="false">how_to_make_alfred_workflow</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 16 Dec 2020 09:29:31 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Terraform Cloud を Alfred や CLI から操作する]]></title>
            <description><![CDATA[<h3>追記 : 2020-12-07</h3>
<p><code>alfred-terraform-cloud-workflow</code> を <code>alfred-tfcloud-workflow</code> に名称変更しました。（追記ここまで）</p>
<p>この記事は <a href="https://qiita.com/advent-calendar/2020/terraform">Terraform Advent Calendar 2020</a> 5日目の記事です。</p>
<p><a href="https://www.hashicorp.com/products/terraform">Terraform Cloud</a> がフルリリースされて1年あまり経過しました。僕はこの1年だいぶ便利に使わせてもらっていて、 state file の保存のみならず、チームで共有する  private module の管理のほか、 Terraform の実行も現在は Cloud 上ですべて賄っており、手で <code>terraform apply</code> を打つ機会もほとんど無くなりました。</p>
<p>そんな便利な Terraform Cloud ですが、現状 UI はウェブのみとなっており、 hashicorp が得意とする CLI は用意されていません。そのため画面ポチポチクリック業がそれなりの頻度で発生しており、地味にストレスになっています。そこで macOS 用のランチャーアプリである <a href="https://www.alfredapp.com/">Alfred</a> を使って、一部機能を検索、操作できるようにしてみました。</p>
<h2>alfred-tfcloud-workflow</h2>
<p>Alfred には有料版 (Powerpack) 限定で、 workflow という拡張機能があります。これはデフォルトの検索機能に加えて、自分で任意の検索コマンドをスクリプトで組んで追加できるというものです。今回はこれを活用して Terraform Cloud の検索用 workflow を作成しました。 GitHub で OSS として公開しているので、手元の Alfred でも使っていただけます。</p>
<p>動作イメージは GIF で見てもらうと早いかと思います。</p>
<p><a href="https://gyazo.com/a6ddc5a3f1aee2d8a41f5fc43639138e"><img src="https://i.gyazo.com/a6ddc5a3f1aee2d8a41f5fc43639138e.gif" alt="Image from Gyazo" width="600"/></a></p>
<p>こんな感じで Alfred で検索して、該当の URL をサクッと開くことができます。検索可能なのは workspace 、 private module registry 、 run の3つです。 run はあまり耳馴染みがないかもしれませんが、 Terraform Cloud 上で実行される plan, apply がこう呼ばれます。この Alfred workflow では、実行中の run 、要するに承認待ち状態のままになっているものを検索可能としています。 Terraform Cloud 上での <code>plan</code> は実行に時間がかかることも多いので、いつでもサッと開けるようになっていると非常に便利です。</p>
<h3>使い方</h3>
<p>以下のレポジトリの Releases から、最新の <code>.alfredworkflow</code> ファイルをダウンロードして、 Alfred へインポートしてください。</p>
<p>https://github.com/chroju/alfred-tfcloud-workflow</p>
<p>インポート後に変数の設定が必要です。 Alfred の Preferences を開き、 <code>organization</code> に検索対象とする organization を設定してください。 organization はここで決め打ちとなるため、複数の organization を動的に切り替えて検索することには現在対応していません。</p>
<p><a href="https://gyazo.com/c7a29e90b469d8b6052cec6b834328fa"><img src="https://i.gyazo.com/c7a29e90b469d8b6052cec6b834328fa.png" alt="Image from Gyazo" width="489"/></a></p>
<p>もう1つ、 <code>TF_CLI_CONFIG_FILE</code> という変数も用意されています。こちらは <a href="https://www.terraform.io/docs/commands/cli-config.html#development-overrides-for-provider-developers">Terraform における同名の環境変数</a>と同じものです。この workflow は <code>$HOME/.terraformrc</code> から API token を読み込んで使用しますが、別のパスのファイルを使いたい場合は、ここに設定します。パス変更が必要ない場合は空欄で大丈夫です。</p>
<p>これでセットアップは完了です。 <code>tfcws</code> で workspace 、 <code>tfcmd</code> で private module registry 、 <code>tfcruns</code> で run がそれぞれ検索できるようになったはずです。</p>
<p>なお、先のサンプル GIF では Terraform のロゴが設定されていましたが、配布の workflow にはライセンスの関係でロゴ画像は含めていません。お好みでご自身で設定してください。</p>
<h2>内部実装 : tfcloud</h2>
<p>ここからは内部実装の話をします。</p>
<p>とはいえ、ここで Alfred workflow の作り方を長々説明するのはアドカレの趣旨に反すると思いますので、その点は割愛します。ざっくり説明すると、 Alfred が定めるフォーマットで JSON を食わせると、あのインクリメンタル検索の候補として流れるという、それだけです。従って原始的な実装であれば、 curl で Terraform Cloud の API をたたき、結果を jq で整形するような形でも workflow は作成可能です。ただそれでは面白くないなという思いもあり、今回は go で Terraform Cloud の CLI ツール <code>tfcloud</code> を作って中で実行しています。</p>
<p>https://github.com/chroju/tfcloud</p>
<p>この CLI ツールは単独でももちろん利用可能です。普通に使う分には出力も human readable な形ですが、一部コマンドについて、隠れオプションを渡すことで Alfred に適合した JSON 形式で出力するようになっており、この仕組みを workflow 内部で呼び出しています。先ほど掲載した workflow は <code>tfcloud</code> のバイナリを内包した形で配布しているので、別途インストールは不要になっています。依存関係をあまり気にせず、ワンバイナリで配布できる Go は、こういう場面で便利ですね。</p>
<h3>tfcloud だけの機能</h3>
<p><code>tfcloud</code> を単独でも使ってみたい場合は、 <code>brew install chroju/tap/tfcloud</code> でインストール可能です。</p>
<p>tfcloud には少しだけ、 CLI 版でしか実行できない機能も存在しています。個人的に推したいのは、 Terraform Cloud workspace の Terraform version をアップグレードする機能です。</p>
<p>Terraform Cloud では各 workspace 個別で Terraaform version を設定する必要があるため、メジャーバージョンアップの際などに数十の workspace を GUI でポチポチと upgrade して回らなくてはならず、かなり骨が折れます。 <code>tfcloud workspace upgrade</code> コマンドを実行すれば、カレントディレクトリに紐付いた workspace の Terraform version を CLI からアップグレードできます。</p>
<p><a href="https://gyazo.com/90b3f9d30a47a74025c9f29a9a14d5c8"><img src="https://i.gyazo.com/90b3f9d30a47a74025c9f29a9a14d5c8.png" alt="Image from Gyazo" width="557"/></a></p>
<p>このように <code>-u</code> オプションでバージョン指定して upgrade もできますし、指定しなければ自動的に最新が当たります。ただし、 <code>required_version</code> と整合性がとれないバージョンには上げないようになっています。オススメの使い方は、 <code>tfcloud workspace list</code> で各 workspace の Terraform version が一覧できるので、これと併用してバージョンアップを進めることです。</p>
<p>このほかに、 remote backend の記述内容を元にして、 workspace をイチから自動作成するようなコマンドも実装を検討しています。</p>
<h3>Terraform Cloud / Enterprise API</h3>
<p>なお、 tfcloud がやっていることは、単純に Terraform Cloud の API を叩いて、結果を整形して出力しているだけです。</p>
<p>Terraform Cloud の API は、 <a href="https://www.terraform.io/docs/cloud/api/index.html">Terraform Cloud / Enterprise API</a> という形で提供されています。Terraform Enterprise の SaaS 版にあたるのが Terraform Cloud と言えるようで、両者の API は共通しています。 Go による API ライブラリも hashicorp から提供されており、その名も <a href="https://github.com/hashicorp/go-tfe">go-tfe</a> と、 Enterprise 由来のものになっています。 <code>tfcloud</code> もまた、その名に反して Enterprise でも動作するはずですが、筆者は Enterprise の使用経験がないため、試してはいません。</p>
<p>Terraform Cloud / Enterprise API （以下、 tfe API） は GUI におけるほとんどの機能を実装していますが、1点だけ Registry Modules API のみ、以下のようにちょっと癖があります。</p>
<ul>
<li>tfe API は Registry Modules API を一部しか実装しておらず、一部は <a href="https://www.terraform.io/docs/registry/api.html">Registry standard API</a> (public な Terraform Registry の方) を踏襲している。</li>
<li>残念ながら <code>go-tfe</code> は Registry standard API 踏襲部分については実装がない。</li>
<li>Registry standard API に対する Go のライブラリは提供されていない。</li>
<li>tfe API と terraform registry API では、出力フォーマットの JSON 形式が異なる。</li>
<li>tfe API と terraform registry API では、 API endpoint の URL も異なる。</li>
</ul>
<p>ということで、 registry 周りの API だけ一部自分で実装する羽目になりました。これについては <a href="https://github.com/hashicorp/go-tfe/issues/136">issue も上がっています</a>が、 <code>go-tfe</code> で対応しないとしても、 Registry standard API 用のライブラリを別途リリースしてほしいところです。</p>
<h2>Conclusion</h2>
<p>以上、 Alfred や CLI から Terraform Cloud を操作できるようになるまでを簡単にご紹介しました。アドカレの〆切駆動で開発したので最後はかなりギリギリで作っており、粗もあるかと思いますが、何か気になることがあれば issue や PR をいただけるととても嬉しいです。</p>
<p>ただ CLI を得意とする hashicorp ですので、どこかのタイミングで公式の CLI が出てくれないかな、とはちょっと期待しています。</p>
]]></description>
            <link>https://chroju.dev/blog/terraform_cloud_with_alfred</link>
            <guid isPermaLink="false">terraform_cloud_with_alfred</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 04 Dec 2020 22:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[分割無線キーボード Caravelle-BLE を組んだ]]></title>
            <description><![CDATA[<p><a href="https://gyazo.com/401377e6fb90c742683d75ff9a01efdf"><img src="https://i.gyazo.com/401377e6fb90c742683d75ff9a01efdf.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p><a href="https://booth.pm/ja/items/1644450">Caravelle-BLE</a> という自作キーボードキットを組んだ。</p>
<p>昨年12月からずっと <a href="https://yushakobo.jp/shop/corne-cherry/">Corne Cherry</a> に <a href="https://imkulio.com/">IMK corne case</a> を<a href="https://www.instagram.com/p/B6EziQcgbcw/?utm_source=ig_web_copy_link">合わせたもの</a>を使っていてかなり満足していて、今年買ったキーボードキットはこれが初めて。</p>
<p>Caravelle-BLE は昨年リリースされたキーボードキットで、当時から欲しいとは思っていた。ポイントとしては分割かつ、 Bluetooth Low Energy (BLE) を使った無線通信にデフォルトで対応していることと、3Dプリンタ製のケースが付属していること。自作キーボードキットは多くの場合、キースイッチをはんだ付けした基盤に、同サイズのプレートを表裏それぞれにネジ止めした「サンドイッチ構造」と呼ばれるつくりをしている。この構造はシンプルなのだが、基盤とプレートの間にほこりが入りやすいだとか、打鍵感や打鍵音が損なわれるという弱点がある。ケースで側面を覆えばこれは解消されるのだけど、立体造形は少し手間が要ることもあってか、キットに同梱されていることは少ない。 Caravelle-BLE はこれを同梱しているという点で珍しく、興味を持った。</p>
<p>昨年の初期ロットは早々に売り切れていて、それ以来諦めていたのだが、先日たまたま在庫があるのを見つけて購入した。</p>
<h2>build log</h2>
<p>久しぶりにキットを組むので少々手こずった。特に BLE 対応のキーボードは初めて組むこともあり、コンデンサのはんだ付けなど、慣れないことも多かった。</p>
<p>基本的にはマニュアル通りに進めれば難易度はそれほど高くないと思うが、1点だけ、3Dプリントされたケースのネジ穴に「バリ」と言っていいのか、些末なプリント素材が詰まっていたのがイレギュラーだった。ピンセットなどで軽く力を入れればパキパキと取れるので、ネジ止めの前に穴をきちんと確認すればつまずくほどのこともないと思う。</p>
<p><a href="https://gyazo.com/a9db94b1bced2a8266bacbef40b33a02"><img src="https://i.gyazo.com/a9db94b1bced2a8266bacbef40b33a02.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>また、 Bluetooth 接続は出荷時にファームウェア設定済みで、マスター（左手側）とスレーブ（右手側）が同時起動した時点で双方が接続され、マスターが PC と通信する、という形を取る。マニュアルにはスレーブ、マスターの順に接続確認をするよう書かれているが、同時に電源を入れてしまうとスレーブは PC と接続できなくなってしまうので注意したい。僕は当初このあたりに手こずったが、幾度かマスター、スレーブ双方のペアリング設定をリセットすることでうまくいった。</p>
<h2>キースイッチ</h2>
<p><a href="https://gyazo.com/badbbc1c4d1fa1b0a2c081378c98c9cc"><img src="https://i.gyazo.com/badbbc1c4d1fa1b0a2c081378c98c9cc.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>基本的にはリニア、修飾キーなどの一部だけタクタイルにするハイブリッド構成が好きで、リニアは <a href="https://yushakobo.jp/shop/gateron-ink-switches/">Gateron Ink Black</a> 、タクタイルは <a href="https://yushakobo.jp/shop/a02zi/">Zilent V2</a> を好んでいるのだが、今回は気分を替えて前者を <a href="https://yushakobo.jp/shop/alpaca-switch-10/">Alpaca</a> にしてみた。 Gateron Ink Black とカタログスペック上の押下圧はほぼ変わらないのだけど、打鍵感は軽めに感じられる。底打ちしたときに軽快な音がするのが心地よくてわりと好き。</p>
<p>ちなみにキーキャップは手元にフルで合うものがなかったので適当にはめている。 GMK Modern Dolche 2 の GB に参加しているので、届いたら差し替えたい。</p>
<h2>印象</h2>
<p>まだ半日しか経っていないので何とも言えないところはあるが、無線だと机上がスッキリして想像以上に気分がいい。打鍵感もかなり良く、無線通信にも目立った問題は感じていない。たまに左右で意図した順序と逆に（スレーブ側が遅れて）入力される感覚があるので、パラメータを少し調整するかもしれない。</p>
<p>キー数は Corne に親指部分左右1つずつ、人差し指の内側に左右2つずつの計6キーを追加した形で、まだ若干持て余している。人差し指内側のキーについては Corne でもほしい、括弧を割り当てて使いたいと思っていたので念願なのだが、まだ指が慣れずにいる。慣れれば便利ではあると思う。また、キーマップもほぼ Corne のものを使い回せたので、すぐに割り当ては終わった。</p>
<p>それにしても、これほど完成度が高く高機能なキットが14400円（本記事執筆時点）というのは、自分の感覚が麻痺しているわけではなくどう考えてもお買い得。購入できて本当によかったし、末永く Corne と一緒に使っていきたい。</p>
]]></description>
            <link>https://chroju.dev/blog/caravelle_ble</link>
            <guid isPermaLink="false">caravelle_ble</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 22 Nov 2020 10:20:41 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[WFH を始めて半年が過ぎ、調えたり諦めたりしたこと]]></title>
            <description><![CDATA[<p>3月末からほぼずっと WFH ことリモートワークの状態になり、早半年が過ぎた。今はたまに出社するが、ほぼ毎日 WFH の状態になっている。 WFH を始めた直後に <a href="https://chroju.github.io/blog/2020/04/15/remote_work_infrastructure_engineer_under_covid_19/">COVID-19 とリモートワーク - 設備だけではなくルーチンも大事 | the world as code</a> というエントリーも書いたが、それから経験が積まれた今、改めて WFH はどうなんだ、ということを書いてみたい。</p>
<h2>マルチディスプレイは要らなかった</h2>
<p><a href="https://gyazo.com/69896457ebc304486d408fa8d63ea0c2"><img src="https://i.gyazo.com/69896457ebc304486d408fa8d63ea0c2.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>元々、部分的なリモートワークが OK な会社だったので、家に作業可能な環境は元々あるにはあったのだが、1日8時間労働を週5で続けるとなると粗が見えてくるもので、様々なものを買った。今後会社が替わっても、業種が替わらない限り WFH は長く続きそうだし、思い切ってお金を費やしていった。その中でも大きかったのがディスプレイと椅子。</p>
<p>ディスプレイは24インチ WQHD から、27インチ 4K に替えた。 DELL の U2720Q という、よく売れていそうなモデル。 Amazon 限定で U2720QM という、付属ケーブルだけが異なっていて少し安いモデルがあるので、そちらのほうが売れているかもしれない。僕が買おうとしたときには売り切れていたので、 U2720Q のほうを DELL 直販で買った。決め手は解像度はもちろん、 USB Type-C 1本で映像出力と給電双方が取れること。ずっと作業していると、ケーブルを少しでも減らしたい欲求が強くなり、 MBP に Type-C 1本挿せば OK という環境を整えた。</p>
<p>このディスプレイを買って以降、 MBP はクラムシェルモードで使っていて、マルチディスプレイはすっかりやらなくなってしまった。就職してから10年ぐらい、マルチディスプレイは必要不可欠だと思っていたのに、どうもそうではなかったらしい。解像度の高いディスプレイの中で複数ウィンドウを並べるほうが、物理的にディスプレイを並べるよりも机がスッキリするし、視線移動も少なくて済むので、集中力も削がれにくいことに気付いた。</p>
<p>ちなみにウィンドウの配置には <a href="https://www.alfredapp.com/">Alfred</a> の <a href="https://pawelgrzybek.com/div-simple-alfred-windows-manager/">Div</a> というプラグインを使って、キーボードだけでシュッと並べられるようにしている。</p>
<p><a href="https://gyazo.com/eb633b0877674babf5064207a8fa1c92"><img src="https://i.gyazo.com/eb633b0877674babf5064207a8fa1c92.gif" alt="Image from Gyazo" width="600"/></a></p>
<h2>WORKAHOLIC で椅子を買った</h2>
<p>椅子はイトーキの <a href="https://shop.itoki.jp/shop/g/g24083226/">YL8</a> という3万円ぐらいのものを使っていたのだが、バロンチェアこと、オカムラの <a href="https://www.okamura.co.jp/product/seating/baron/">Baron</a> に乗り換えた。</p>
<p>馬喰町にオフィスチェア専門のセレクトショップ <a href="https://www.iamworkaholic.jp/">WORKAHOLIC</a> という店があり、そこで実際に試しながら買った。来店予約のときに、使っている机の高さ、天板の厚さなどを伝えると、それに合わせた状態の昇降デスクを用意して待ってくれるので、椅子と机を合わせたときにどういう状態になるか想像しやすく、体験がよかった。今は2時間の時間制になっているので、ある程度見たい椅子に目星をつけて行かないと時間が足りないかもしれない。2時間、手当たり次第に試していると、意外にすぐに過ぎる。なお、品揃えは<a href="https://www.rakuten.ne.jp/gold/of9/sp/">楽天</a>でチェックできる。</p>
<p><a href="https://gyazo.com/7b3cef2c2c21613d012b6afbbbf90dbe"><img src="https://i.gyazo.com/7b3cef2c2c21613d012b6afbbbf90dbe.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>Baron の決め手は結構細かいところで、アームレストが内側60度まで曲げられるがために、机に思いっきり近づいたり、体勢の自由が利くことが大きいポイントになった。アームレストで肘を支えましょうとはよく聞くのだが、アームレストが天板とつっかえて、机と距離が離れることになり、上手くキーボードの位置と合わせて使えないのが今まで不満だったのだ。WORKHOLIC で正しい座り方を教えてもらったところ、やはりアームレストをちゃんと使って肘を支え、肩の力を抜くべきだという。そしてアームレストと机の高さを合わせることで、足裏が宙に浮いてしまうならば、フットレストを使って調整する。この座り方を徹底し始めたところ、集中力が持続しやすくなった。</p>
<p>以下の記事にも、この「正しい座り方」が解説されている。</p>
<p>https://www.itmedia.co.jp/bizid/articles/0902/19/news115.html</p>
<h2>通勤時間による脳の GC</h2>
<p>「脳のGC（ガベージコレクション）」という言葉は <a href="https://and-engineer.com/articles/XoSQwRAAACMAmQTN">「サウナは、脳のガベージコレクション」。エンジニア兼サウナ経営者が、サウナの魅力を徹底解説！ | アンドエンジニア</a> から拝借した。僕もサウナや銭湯は好きで、頭の中を整理する時間に使うことがある。難点はいいアイディアを思いついても上がる頃には忘れがちなことで、裸で走ったアルキメデスは圧倒的に正しかったんだなとしみじみ感じている。</p>
<p>しかし風呂に行かずとも、自分にとって通勤時間がわりと「脳のGC」になっていたなと思う。勤め先は都内なので、会社から歩いて1分、10分、15分という具合に3つぐらいの駅を選ぶことができて、ちょっとモヤモヤしている日は遠めの駅まで歩きながら頭を整理することがよくあった。それでもどうにもならなさそうな日は、答えを求めてそのまま本屋に寄ったり、ノートに書き出すためにカフェに寄ったり。</p>
<p>WFH になって、そういう時間はすべて失われてしまった。仕事が終わるとすぐに「今日の夕食は何にしよう」という次の思考が始まってしまい、休まることがなくて、一時期は結構疲弊していた。仕事をする場所とプライベートな場所が同じなので、その間がシームレスで脳が動き続ける。通勤の時間は、緩やかに「仕事モード」から「プライベートモード」へ繋ぐ役割を果たしていた。</p>
<p>最近は終業後に一度散歩することを習慣化し始めた。これでまた「脳のGC」が進むようになったし、仕事を終えたことの区切りもつけられるようになった。</p>
<h2>WFH がオフライン出社をすべて置き換えるわけではない</h2>
<p>WFH は好きなのだけど、会社でやっていたことを全部置き換えるものではないと悟った。それは諦めた。</p>
<p>具体的には、複数人で意見を出し合ったり、何かを検討するような場にはあまり向いていない。例えば OKR をチームで設定するときなど、付箋で大量に意見を出して、ホワイトボードに並べながら検討することが多いのだが、これをオンラインで再現するのはなかなかに難しかった。</p>
<p>ということで、チームでグループワークが必要な際には基本的に物理出社するようになった。たまに物理出社して、リアルな場で MTG をすると、普段 zoom などで会話するのに比べて受け取る情報量が圧倒的に多いことを強く感じる。微妙な表情の変化やしぐさなどから、「あれ？○○さん何か納得できてない感じ？」って話を振るようなことがオフラインでは可能だけど、 オンラインだと容易ではない。あまりこういう抽象的な言葉を使うのは好きではなかったのだが、どうしても「場の空気」というものは存在するし、それはオンラインでは感じ取れないものだったりする。</p>
<p>もちろん、フルリモートで維持されている開発組織があるのも知っているのだけれど、自分の場合は合わなかった。ならばそこは柔軟に、「WFH を諦める」部分があってもいいんじゃないかと思っている。</p>
<h2>WFH がすべての人に適しているわけではない</h2>
<p>そして当然ながら、 WFH は誰もが肯定するものではない。僕は大好きだが、他の人が周りにいないとなかなか調子が出ないんだよね、って人も中にはいる。</p>
<p>だから WFH にせよオフィスで働くにせよ、どちらの方式でも強制はしたくないな、と強く思っているし、妥協点は常に探らなければならないと感じている。誰もが自由にしていいよ、というのもちょっと違うと思っていて、周りが誰も出社していないのに自分が出社しても仕方がない、ということもある。それであれば週に1回はチームで出社するだとか、別の方策を探さねばならない。</p>
<h2>『リモートワークの達人』</h2>
<p>https://www.amazon.co.jp/dp/4150505608</p>
<p><a href="https://blog.magnolia.tech/entry/2020/11/09/004356">「リモートワークの達人」を読んだ、そして悔しい思いをした - Magnolia Tech</a> で話題になっていたので、僕もこの本を読んでみた。たしかにリモートワークに必要なことは全部書いてある、って言いたくなるような本だった。</p>
<p>何より、「全部常にリモートワークで回るよ」という全肯定ではなくて、働き方をフレキシブルにするとよい、ということに力点が置かれている点がよかった。集中したい時間はリモートで、それが終わったら出社するような、ハイブリッドな働き方を認めている。コロナ禍、特に緊急事態宣言の最中では完全リモートワークがやむなしだったが、今後長く感染症と付き合う上では、ハイブリッドが妥当な選択肢になっていくんじゃないかと思う。</p>
<p>自分の場合では、総合的には QOL が上がったと感じている。通勤時間がなくなって、時間を自由に使える幅が広がったこと。家事を回しやすくなり、平日はほぼ毎日自炊するようになったこと。おかげで家にいる時間をもっと充実させたくなって、実家を出て10年ぐらいして、おそらく初めて食器を買ってみたりもした。買ったのは波佐見焼の食器で、 xx 焼と付くような焼き物はもっと渋いイメージをしていたのだけれど、モダンな感じですごく気に入っている。食器に関する知識が広がって嬉しかった。</p>
<p><a href="https://gyazo.com/b87c5b4de7cc3eeaa1b6a5138a6046e9"><img src="https://i.gyazo.com/b87c5b4de7cc3eeaa1b6a5138a6046e9.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>今後 WFH が一般化するのかはよくわからない。 IT 系以外の業界だと、すでにその比率はかなり下がっているようにも感じるし、 IT 系であっても、コロナ禍が過ぎ去ってからも続けるかどうかはまちまちだろう。でも、僕としてはこのフレキシブルな状況が続いてほしいと思っている。そして WFH のやり方は今後もずっと模索を続けるんだと思う。もっとも、それはオフィスで働く場合と、変わらないという話でもあるけれど。</p>
]]></description>
            <link>https://chroju.dev/blog/wfh_for_half_year</link>
            <guid isPermaLink="false">wfh_for_half_year</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 21 Nov 2020 06:37:04 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[EKS Best Practices Guide for Security を読んだ]]></title>
            <description><![CDATA[<p><a href="https://aws.github.io/aws-eks-best-practices/">Amazon EKS Best Practices Guide for Security</a> を読んだ。今年5月に公開された比較的新しい文書で、いわゆる docs.aws.amazon.com の中に収録されておらず、単独で github.io にホストされている。ともすると、 UI からは AWS official な文書なのかわかりにくいのだが、以下の通り、 official でアナウンスされている。</p>
<p>https://aws.amazon.com/jp/about-aws/whats-new/2020/05/introducing-amazon-eks-best-practices-guide-for-security/</p>
<p>EKS と銘打たれている通り、 Kubernetes ではなく EKS にフォーカスした記述は少なくない。例えば暗号化についての項では、 <a href="https://aws.amazon.com/jp/about-aws/whats-new/2020/02/announcing-36-percent-faster-ebs-optimized-performance-on-additional-aws-nitro-system-based-amazon-ec2-instances/">Nitro</a> におけるトラフィックのデフォルト暗号化に触れていたりする。しかし大半は Kubernetes あるいは Docker そのもののプラクティスになっていて、 EKS に限らずとも、 Kubernetes 使用者にとって学べることは多い。内容は Identity and Access Management に始まり、 Pod や Network 、 Runtime といった各要素のセキュリティプラクティスを俯瞰し、 PCI DSS のようなコンプライアンス関係についても少し記述を割いている、かなり包括的な内容となっている。</p>
<p>すべてオープンソースでの公開となっており、 https://github.com/aws/aws-eks-best-practices から issue や Pull Request を出すこともできる。また、 <code>for Security</code> と銘打っている以上、他にも <code>for XXX</code> が続くのではないかと期待されるところだが、レポジトリに GitHub Project が設けられており、そこから Performance 、 Reliability 、 Cost Optimization などが計画されていることが垣間見える。つい先日は <code>for Cluster Autoscaler</code> が追加された。個人的に、 AWS のドキュメントを読んで組めるのは「とりあえず使える Kubernetes」であり、そこからプラスアルファで行うべきプラクティスは非常に多く、なかなか捉えどころも難しいように感じている。何年か前の状況に置き換えると、 EC2 で nginx と Rails を動かすだけならそれなりに簡単だけど、セキュリティグループや LB をきちんと扱えているか、 Scaling をどうするのかといった非機能的要件になると話が変わってくるようなイメージだ。それがオフィシャルな Best Practices としてまとまり、さらにオープンに編集可能というのは非常に嬉しいことだなと感じている。</p>
<p>以下、自分が読んだ中でメモした箇所をいくつか挙げておく。</p>
<ul>
<li>Pod Security
<ul>
<li>コンテナイメージに shell を入れるべきではない
<ul>
<li><code>sh</code> ぐらいは入れていることがあるので、そこまで徹底出来る方が確かに好ましそう</li>
</ul>
</li>
<li>Pod Security Policy
<ul>
<li>https://kubernetes.io/docs/concepts/policy/pod-security-policy/</li>
<li>root での起動を許可しないなどいくつかルールを定め、そのルールに従った Pod 以外は起動できなくするもの</li>
<li>まだ beta だが使ってみたいところ</li>
</ul>
</li>
</ul>
</li>
<li>Multi-tenancy
<ul>
<li>Namespace を使った Soft multi-tenancy や、 cluster 自体分離する Hard multi-tenancy について説明されている
<ul>
<li>個人的には Soft で限りなく済ませておきたい気持ちが強い</li>
<li><a href="https://loft.sh/blog/kubernetes-multi-tenancy-best-practices-guide/">Kubernetes Multi-Tenancy – A Best Practices Guide | Loft Blog</a> あたりも参考に</li>
</ul>
</li>
</ul>
</li>
<li>Detective Controls
<ul>
<li>audit log の解析や監視</li>
<li>同様に CloudTrail log も</li>
<li>地力で監視するのはどう考えても大変なので自動化して何か考えたいが。。</li>
</ul>
</li>
<li>Infrastructure Security
<ul>
<li><a href="https://github.com/aquasecurity/kube-bench">aquasecurity/kube-bench: Checks whether Kubernetes is deployed according to security best practices as defined in the CIS Kubernetes Benchmark</a>
<ul>
<li>CIS Kubernetes Benchmark に則っているかチェックしてくれるツール</li>
</ul>
</li>
<li>Amazon Inspector の活用</li>
</ul>
</li>
<li>Incident response and forensics
<ul>
<li>実際にセキュリティインシデントが発生したら、どう対処するか
<ul>
<li>Network Policy を使った通信の遮断</li>
<li>該当 node に対して cordon を実施</li>
<li>問題のある node や pod に label を付与してわかりやすくしてから対処する</li>
<li>などなど</li>
</ul>
</li>
</ul>
</li>
<li>Image Security
<ul>
<li>大原則として、余計なソフトウェアなどは極力入っていないことが望ましい
<ul>
<li>可能であれば <code>FROM scratch</code> する</li>
</ul>
</li>
<li><a href="https://github.com/wagoodman/dive">wagoodman/dive: A tool for exploring each layer in a docker image</a> などを使ってイメージを縮小する</li>
<li><a href="https://github.com/projectatomic/dockerfile_lint">projectatomic/dockerfile_lint</a> を使って Dockerfile に lint をかける</li>
</ul>
</li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/eks_best_practices_for_security</link>
            <guid isPermaLink="false">eks_best_practices_for_security</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 17 Oct 2020 03:57:20 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[SRE としてのキャリアパスを考える]]></title>
            <description><![CDATA[<p>長らく、明確なキャリアパスというものを描かずに10年近くやってきているのだが、ふと「きちんとキャリアパスを作るべきなのではないか？」という考えに至り、ここ半月ほどいろいろと考えていた。</p>
<h2>キャリアパスの必要性</h2>
<p>キャリアパスの必要性を感じたきっかけとしては2つある。</p>
<ul>
<li>チームリーダーになった</li>
<li>ストレスチェックで、キャリアパスを描くことを推奨された</li>
</ul>
<p>1点目がもっとも直接的な動機であって、チームリーダーという立場になった。マネジメントというほど大仰なものを担っているわけでもないのだが、チームのディレクションなどが必要な立場と言える。するとチームをどうしたいのか？という命題を考える必要が出てきて、そもそもじゃあ自分は今後どうしたいのか？ということも考える必要があるんじゃないかと考えた、という具合。</p>
<p>2点目、会社で受けるストレスチェックというものがあると思うが、あの中で自己肯定感の低さによりストレスを受けている状態にあると診断された。自己肯定感が低いこと自体はもとより自覚はしているのだが、対策として「キャリアパスを作る」ことが挙げられていたのが目を引いた。キャリアパスと自己肯定感がどう結びつくのかいまいちわからなかったのだが、目標を明確化して、そのプロセスを辿っていることを自覚することにより、自己肯定感を高めることができるらしい。「技術書典6」で購入した『<a href="https://booth.pm/ja/items/1312451">理論と事例でわかる自己肯定感</a>』という本にも言及があった。確かに、今学んでいることや、今の業務が、自分にとって長期的に重要なことなのかどうか、思い悩むことが多く、自分の成果に自信を持てないことは少なくなかった。</p>
<blockquote>
<p>「これでよい」気持ちは、結果よりもプロセスを実感していることが影響します。例えば、将来への目標を持っていると感じること、成長への努力をしていると感じていること、といったことです。 [^1]</p>
</blockquote>
<p>という経緯があり、今までは技術的な興味と、実際の仕事を経て「解決したい」と考えた問題とをベースにキャリアを積んできたのだが、30歳も過ぎたことだし、キャリアパスを今一度考え直した。</p>
<h2>キャリアパスの描き方</h2>
<p>ソフトウェアエンジニア向けのキャリアに関する本を何冊か読んではみたのだが、正直キャリアパスはこう作ろう！みたいな本はあんまり見つからなかった。ベストセラー『SOFT SKILL』では「自分のキャリアから何を手に入れたいのか。5〜10年後の自分をどうしたいのか。少し時間をかけて、そのことについて考えてみよう」[^2]という記述にとどまり、それをどう描いていくか詳しくは言及がない。他の本などでも、だいたいは「5年後どうなりたいのか考えてみましょう」みたいな内容で、「いや、特にないんですけど」という人に対する処方箋は乏しい。</p>
<p>https://www.amazon.co.jp/SOFT-SKILLS-%25E3%2582%25BD%25E3%2583%2595%25E3%2583%2588%25E3%2582%25A6%25E3%2582%25A7%25E3%2582%25A2%25E9%2596%258B%25E7%2599%25BA%25E8%2580%2585%25E3%2581%25AE%25E4%25BA%25BA%25E7%2594%259F%25E3%2583%259E%25E3%2583%258B%25E3%2583%25A5%25E3%2582%25A2%25E3%2583%25AB-%25E3%2582%25B8%25E3%2583%25A7%25E3%2583%25B3%25E3%2583%25BB%25E3%2582%25BD%25E3%2583%25B3%25E3%2583%25A1%25E3%2582%25BA-ebook/dp/B01GDS0994</p>
<p>この観点で最も参考になったのが <a href="https://note.com/kobaka7/n/n233f6a0d0886">キャリアに関するセルフコーチングのやり方｜こばかな｜note</a> というエントリー。詳細はリンク先を読んでもらいたいが、考え方の1つとして、「思いつく選択肢をとりあえずたくさんあげてみ」るというものがある。「5年後どうなりたいか」に答えにくいのは、これがオープンクエスチョンであるからであり、ではそもそもどんな選択肢があり得るのかをまず出してみることにより、この問いはクローズドクエスチョンに変化する。</p>
<p>また、選択肢を書き出すことによって、そもそも選択肢が少ない状態にあることにも気付ける。すると、まずは選択肢を増やそう、例えば世の中で自分の5歳ぐらい上のエンジニアで有名な方はどのようなキャリアを築いているのか調べてみよう、といった具体的行動に変化できる。</p>
<h2>キャリアパス、キャリア戦略</h2>
<p>もう1つ引きたい記事がある。</p>
<p>https://www.lifehacker.jp/2014/10/141030strategy.html</p>
<p>ここではキャリアパスではなく、「戦略」という言葉が使われている。パスを思い描くだけで完結せず、そのパスを実現するためにどういった能力を得て、どうやって戦うのかという「戦略」まで言及されている。</p>
<p>戦略と言うと、ルメルトの『良い戦略、悪い戦略』[^3]という本が好きだ。この本は基本的には経営的な目線ではあるが、個人や小規模なチームの活動にも応用できる内容なので、非常におすすめしたい。ざっくり言ってしまうと、良い戦略は状況の「診断」、それに基づき「基本方針」の決定、基本方針を実行するための具体的な「行動」の3つから成るという内容で、状況をきちんと分析して重大な問題を見極めることと、そこにリソースを集中的に投下する重要性を説いている。</p>
<p>https://www.amazon.co.jp/%25E8%2589%25AF%25E3%2581%2584%25E6%2588%25A6%25E7%2595%25A5%25E3%2580%2581%25E6%2582%25AA%25E3%2581%2584%25E6%2588%25A6%25E7%2595%25A5-%25E6%2597%25A5%25E6%259C%25AC%25E7%25B5%258C%25E6%25B8%2588%25E6%2596%25B0%25E8%2581%259E%25E5%2587%25BA%25E7%2589%2588-%25E3%2583%25AA%25E3%2583%2581%25E3%2583%25A3%25E3%2583%25BC%25E3%2583%2589%25E3%2583%25BB%25EF%25BC%25B0%25E3%2583%25BB%25E3%2583%25AB%25E3%2583%25A1%25E3%2583%25AB%25E3%2583%2588-ebook/dp/B087X4WJLR</p>
<p>僕のキャリアパスに関する悩みの出発点は、自己肯定感の欠如だった。それを埋めるのに必要なのは、単なるキャリアパスというより、自身の行動が確固たる戦略に基づいているという確信なのではないかと、ここまで考えていて思い至った。まぁもちろん、キャリアパスを描くだけで満足して終わる、という人もいないだろうが、方向性を作った上で、戦略を描いてそれに取り組んでみて、初めて自分の目的は達成できそうだ。</p>
<p>『良い戦略、悪い戦略」では、戦略とは「仮説」であるとも書かれている。つまり、短期間でその有効性の検証と修正が必要ということだ。パスや戦略を描くのがゴールではなく、それが常に自分にとって意味のあるものになっていることを確認し直す作業も必要になる。</p>
<h2>SRE のキャリアパスを考える</h2>
<p>ソフトウェアエンジニアのキャリアには、スキル上の選択肢と、事業上の選択肢の2つがあると捉えている。技術 or マネジメントというような、よく言われる2択や、フロントをやめてバックエンドやります、みたいな話は前者だ。その技術を持ってどの会社にコミットしたいのか、というのが後者になる。</p>
<p>特にプログラマーであれば、開発したいプロダクトという事業の選択も描きやすいかもしれない。 SRE はプロダクトサイドからは少し離れる（という言い方は適切ではないかもしれないが）ことも多いので、こんなサービスを作りたい、という事業的なビジョンと職務が直結させづらいと感じることもある。ただ、金融業なのか、ゲーム関係なのかなど、携わる事業によって SRE が注力するべきポイントと、求められる信頼性は大きく変化するので、事業の選択肢もまったくの無関係ではない。僕は金融系の経験が長く、ミッションクリティカルなシステムの運用には長けているが、今後もそのキャリアを積みたいかと言えば No だったりする。</p>
<p>また事業領域という点では、サービス運営ではなく、プラットフォーム側、つまりはクラウドサービスや CDN などの中の人になる道も、インフラ系のエンジニアには存在する。この場合は SRE という肩書きではなくなるが、 SRE から選ぶ道としては現実的な線だろう（現に知人でも何人かいる）。</p>
<h2>実際にキャリアパスと戦略を考えてみる</h2>
<p>最後に、ここまで書いたことを受けて、自分でもろもろ実際考えてみたキャリアのことを書き連ねて終わりたい。正直なところ、まだまとまりきってはいないのが現状だ。</p>
<ul>
<li>自分の価値観
<ul>
<li>自身の知識と技術を源泉として対価を得たい
<ul>
<li>労働時間や年齢などを根拠とした対価を得たくない</li>
<li>常に知的好奇心を満たしたい</li>
<li>その時代にあった知識へ常にアップデートを続けていたい</li>
</ul>
</li>
<li>インターネットの自由を重要視したい
<ul>
<li>使い方を狭めたり、ユーザーの自由を奪ったりする方向へは進みたくない</li>
<li>ユーザーがインターネットを通じて、情報を得られる、発信できる自由を尊重したい</li>
</ul>
</li>
</ul>
</li>
<li>キャリアパスのスキル的な選択肢
<ul>
<li>SRE としてスペシャリストになる
<ul>
<li>SRE 方面の技術に長けた存在になる</li>
<li>SRE のプラクティス実践に長けた存在になる</li>
</ul>
</li>
<li>エンジニアチームのマネジメントキャリアを進む</li>
<li>プラットフォーム側のエンジニアになる
<ul>
<li>AWS の中の人など</li>
<li>経験として興味はあるが、現在は SRE でプロダクトに責務を負うほうが関心が強い</li>
</ul>
</li>
<li>SRE 以外のエンジニアルートを進む
<ul>
<li>現状、 SRE でいることに不満などはなく、あまりこの道は考えていない</li>
<li>強いてあるとすれば、 SRE として必要なプログラミングスキルを磨くために、期限付きでサーバーサイド等をやる</li>
</ul>
</li>
<li>現在大学進学しているので、その道を究めて研究職へ進む
<ul>
<li>現実的な道だとは捉えていない</li>
</ul>
</li>
</ul>
</li>
<li>事業的な選択肢
<ul>
<li>文化、芸術、学術とインターネットを絡めた事業に携わっていたい
<ul>
<li>現在は教育関係のサービスに携わっており、マッチしている</li>
<li>「インターネットの自由」というキーワードを念頭に置きたい</li>
<li>まだ深掘りができておらず、具体的にどういったサービスに今後携わりたいかは常に考えたい</li>
</ul>
</li>
</ul>
</li>
<li>直近の方向性
<ul>
<li>35歳を1つの区切りとして捉えつつ、 SRE として高いレベルに達していたい
<ul>
<li>組織に SRE を導入し、立ち上げ、サイクルを回していく一連の過程を自分が再現できるようにしておきたい
<ul>
<li>そのスキルをもって、やりたい事業があれば SRE として瞬時にコミットできる人材になりたい</li>
<li>SRE のプラクティスを組織横断的に適用するためのヒューマンスキル</li>
</ul>
</li>
<li>インプットとアウトプットをより高いレベルで行っていきたい
<ul>
<li>英語の習得（英語が出来るだけで、アクセスできる情報量は格段に多くなるので、レバレッジが高い）</li>
<li>プログラミングスキルの向上、それに伴い OSS への contribution
<ul>
<li>OSS は「インターネットの自由」の1つでもあり、 contribution は常に続けたい</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>[^1]: 川鯉光起, 尾澤愛実, 福本江梨菜, 納富隆浩, 浜崎誠, 小笠原晋也. 理論と事例でわかる自己肯定感. 第2版, 教育心理学を学ぶ会, 2019, p.8.
[^2]: John Z,. Sonmez. SOFT SKILLS: The software developer's life manual. Manning Publications, 2015. (ジョン・ソンメス, 長岡高弘(訳). SOFT SKILLS ソフトウェア開発者の人生マニュアル. 日経BP社, 2016, 第3章.)
[^3]: Richard P. Rumelt. GOOD STRATEGY, BAD STRATEGY: The difference and why it matters. Crown Business, 2011. (リチャード・P・ルメルト, 村井章子(訳). 良い戦略、悪い戦略. 日本経済新聞出版社, 2012, 410p.)</p>
]]></description>
            <link>https://chroju.dev/blog/career_path_vision_strategy</link>
            <guid isPermaLink="false">career_path_vision_strategy</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 06 Oct 2020 05:48:02 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[GitHub default branch を意識しなくて済むようにする]]></title>
            <description><![CDATA[<p>https://github.blog/changelog/2020-08-26-set-the-default-branch-for-newly-created-repositories/</p>
<p>10月1日より、 GitHub で新規レポジトリの default branch が <code>main</code> に変更される。この設定はオプトアウト可能であり、ユーザーや organization それぞれで必要に応じてあらかじめ設定しておく必要があるわけだが、みなさま確認はお済みだろうか。</p>
<p>default branch 名として <code>master</code> を使うことの是非の話はさておき、今後は default branch がレポジトリによって多種多様になる可能性が高い。これまでは何も考えず <code>git switch master</code> を打っていた操作が、レポジトリごとに「main だっけなんだっけ」みたいな思考を挟まなくてはならないのはさすがに面倒である。ということで、 default branch を少なくともローカルでは意識しない生活を送ることにした。</p>
<h2>default branch をコマンドで取得する</h2>
<p>端的に結論から言えば、 <code>git symbolic-ref --short refs/remotes/origin/HEAD</code> を打てばよい。</p>
<pre><code class="language-bash">$ git symbolic-ref --short refs/remotes/origin/HEAD
origin/master
</code></pre>
<p>具体的にこれは何をしているかと言えば、 <code>.git/refs/remotes/origin/HEAD</code> から情報を取得している。 <code>.git/refs</code> は git レポジトリ内の各種参照情報が格納されたディレクトリであり、その中でも <code>.git/refs/remotes</code> には追跡ブランチの情報が格納されている。例えば追跡ブランチ <code>origin/hoge</code> が存在すれば <code>.git/refs/remotes/origin/hoge</code> ファイルが存在し、その内容は <code>origin/hoge</code> の最新 commit hash となっている。 <code>.git/refs/remotes/origin/HEAD</code> はリモートリポジトリの HEAD が参照するブランチの情報が格納されており、つまるところここから default branch が取得できる。</p>
<p>ファイルを直に <code>cat</code> しても値は取得できるが、安全性を鑑みて <code>.git/refs</code> 配下を触る場合は <code>git symbolic-ref</code> コマンドを使うことが推奨されている。このあたり、詳しくは以下の記事を参照した。 Git に関してはこの git book を読めばだいたい解決すると認識している。</p>
<p>参照 : <a href="https://git-scm.com/book/ja/v2/Git%E3%81%AE%E5%86%85%E5%81%B4-Git%E3%81%AE%E5%8F%82%E7%85%A7">Git - Gitの参照</a></p>
<h2>default branch へ switch するサブコマンドをつくる</h2>
<p>default branch の取得方法がわかったので、あとは好きにこれを使えばいいのだが、僕の場合は <code>git switch master</code> が一番よくつかうコマンドだったので、これを改め、 <code>git default</code> コマンドで default branch へ switch できるようにした。</p>
<p>git には、 PATH が通った場所に <code>git-hoge</code> の命名規則に沿ったコマンドがある場合、 <code>git hoge</code> のサブコマンド形式で実行できるようになるという性質がある（参考 : <a href="https://blog.ton-up.net/2013/12/12/git-subcommand/">gitのサブコマンドを自分で作る - blog.ton-up.net</a>）。これを利用して、 <code>/usr/local/bin/git-default</code> に以下のスクリプトを書いて保存した。</p>
<pre><code class="language-bash">#!/bin/bash
git switch $(git symbolic-ref --short refs/remotes/origin/HEAD | cut -f 2 -d '/')
</code></pre>
<p><code>origin/master</code> という慣れ親しんだものが絶対ではなくなる、と知ったときにはかなり同様したが、まぁ結局のところ名前なんて飾りであるとも思うし、意識しなくて済むものは意識しない形にどんどん持って行こうと思う。</p>
<h2>追記 2020-09-22) default branch 変更の手順</h2>
<p>そもそもの default branch 変更の手順だが、 <code>branch -m</code> コマンドで master からブランチ名を変更した上で、 <code>push -u origin HEAD</code> した後、 GitHub 側で repository settings から設定変更を行うことになる。</p>
<pre><code class="language-bash">$ git branch -m master main
$ git push -u origin HEAD
</code></pre>
<p>ただ、 <code>.git/refs/remotes/origin/HEAD</code> は <code>git clone</code> した際に確定してしまっており、この手順を行っても自動的に GitHub の設定に追従することはない。 <code>symbolic-ref</code> コマンドで別途編集してやる必要がある。</p>
<pre><code class="language-bash">$ git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
</code></pre>
<h3>追記2 2021-01-10)</h3>
<p>もしくは以下のコマンドでも OK 。</p>
<pre><code class="language-bash">$ git remote set-head origin --auto
</code></pre>
<p>（追記2 ここまで）</p>
<p>また、 <code>git init</code> した際の default branch については、 <code>.gitconfig</code> で global に設定できる。</p>
<pre><code class="language-ini">[init]
  templatedir = ~/.gittemplates
  defaultBranch = main
</code></pre>
<p>default branch 変更に関しては、 github/renaming で guidance が公開されているので、こちらも合わせて参照したい。</p>
<p>https://github.com/github/renaming</p>
]]></description>
            <link>https://chroju.dev/blog/github_default_branch_chaging</link>
            <guid isPermaLink="false">github_default_branch_chaging</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 21 Sep 2020 10:25:32 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[脳内 dump のための Dynalist と、永続する外部脳としての Scrapbox]]></title>
            <description><![CDATA[<p><a href="https://chroju.github.io/blog/2020/08/12/notion_and_scrapbox/">前回のエントリー</a> で notion と Scrapbox の個人的な比較と、階層整理に関するお気持ちを書いた。その上で、現状じゃあ notion とか Scrapbox とかどうやって使ってんの、という話を今度書きます、と書いて1か月ぐらい経っちゃったので書く。</p>
<h2>個人で整理したい情報には何があるのか</h2>
<p>そもそも何の情報を整理したいんだという話がある。ていうか、なんで情報整理なんてしたいんだという人もいるような気はする。特にデジタルツール使ってなくて、簡単なメモ帳だけ持っててそれで十分やっていけてます、というような人とか。</p>
<p>僕はわりと頭の中でごちゃごちゃと考えるタイプ、人からは時に「頭でっかち」と言われることもあるようなタイプで、あんまり脳の性能が良い気がしていない。タスクがわーっと振ってくるとてんやわんやになって、何をやればいいのかわからず、下手をするとやる気が消失する。逆に、取り組んでいるタスクが興に乗って過度に集中すると、何も書き出さず頭の中でひたすら考えては試しまくる、というようなことをやってしまい、終わって数日経ってから「あのとき何をしたんだっけ？」となることもある。従って、外からインプットした情報、自分の中で考え出した情報を書き留めておく場を常に欲している。書いて考えを落ち着ける、書いて考えをまとめる、書いて状況を整理する、それで初めて行動可能になる、というときがある。</p>
<p>なので、取りあえずメモリをダンプしておくところがほしいというのが1つ。今何やってんだっけ、今何しなくちゃなんだっけ、っていう現在進行形の頭の中をそのまま書き出して取っておくところがほしい。この用途で <a href="https://dynalist.io">Dynalist</a> を使っている。そうじゃなくて半永久的に保存しておくようなメモには <a href="https://scrapbox.io">Scrapbox</a> を使っていて、一部だけ <a href="https://www.notion.so">notion</a> を使っている状況。</p>
<h2>Dynalist</h2>
<p>https://dynalist.io/</p>
<p>アウトライナー。アウトライナー自体それほど知られたツールでもない気がするのだが、文を並べて階層構造をつくったり、並び順を入れ替えたりして整理できるツール、と言えばいいんだろうか。エンジニア界隈で一番有名なアウトライナーは Emacs org-mode な気がする。</p>
<p>冒頭に書いたとおり脳内のダンプ場所という感じ。ちなみに Brain dump っていう、頭の中にあることを全部書き出して整理するメソッドがあるらしいんだけど、そういう一過性のものというよりは、頭の中にあることをここに一度書き出して、脳内の状態と差分が出たら逐次更新して同期するみたいな感じで使っている。たまに訳わからなくなると書き直したりはするけど。</p>
<p>やっていることとしては <a href="https://kirimin.hatenablog.com/entry/2019/08/06/190809">様々なTODOアプリやタスク管理方法を試行した結果最終的にプレーンテキストに行き着いた話 - みんからきりまで</a> に近いのかもしれない。結局 TODO アプリって、そのアプリの思想に則ったタスク管理を強いられる側面があるし、タスク以外のちょっとしたメモとか参考資料のリンクなどを上手く保存できるものでもない。そこで柔軟性を鑑みてアウトライナーに行き着いた感覚。僕も昔、テキストファイルでタスク管理していた頃があったけど、さすがに機能が物足りなくてやめたことがあった。 Dynalist だと繰り返しタスクの設定ができて、取り消し線を引くと1週間後に自動リスケジュールしてくれたりとか、 CSS いじれて見た目わかりやすくできたりとか、いろいろメリットを感じている。日付を付与する機能もあって、1週間後までの日付が付いた行とかを検索できて、タスク管理には便利。絵文字も積極的に使って見やすくしている。</p>
<p><a href="https://gyazo.com/af15029835976b60074f714d74800932"><img src="https://i.gyazo.com/af15029835976b60074f714d74800932.png" alt="Image from Gyazo" width="600"/></a></p>
<p>もっと言うと <a href="http://gofujita.info/notes_mydays.html">その日付をすてろ</a> に書かれていることが一番近い。今やっている、気にしなくてはならないプロジェクトを並べておいて、その中に進捗書いたり、細分化したタスクを並べたりしている。ちなみに上のスクショが現時点の実際の Dynalist で、このブログも「memo ツールのブログを書く」の階層配下に直接書いているところ。</p>
<p>「今日」やることは1個「Today」という階層を掘り下げてそこに並べて区別している。1日の始まりに「Today」の中にタスクを書き出す。日中はそれを見つつ、上の階層にあるプロジェクトを広げてメモを取ったりする。終わったタスクは順次取り消し線を引く。1日の終わりに、終わったタスクは消して、残ったタスクは次の日に持って行くか、さらに数日送るのあれば日付だけくっつけて一旦「icebox」階層に移動させる（<a href="https://en.wikipedia.org/wiki/Tickler_file">Trickler file</a> を意識している）、要らないものは消す。そういうサイクルでやっていっている。</p>
<p>「Today」の中はメモを放り込む場所でもあって、水平線の上はメモ扱いにしている。例えば「あとで読む」サービスの Pocket を長いこと使っていたんだけど、 Pocket を開く機会が特に通勤が無くなってからかなり減ってしまったことに気付き、今は読みたい記事も「Today」に放り込むようになった。 Dynalist には「inbox」という機能があり、ある階層を「inbox」として指定すると、 webhook に対して投げた文章を全部その中に保存してくれるようになる。これを使っている。「Today」に入れたものは1日の最後に見直して振り分けするルールにしているから、嫌でも目に入って何かしら処理されることになる。</p>
<h2>Scrapbox</h2>
<p><a href="https://gyazo.com/1ba2bc436624d264d9b8eb956c73c9cb"><img src="https://i.gyazo.com/1ba2bc436624d264d9b8eb956c73c9cb.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>なんでも入れておくメモ。便利。本当に便利。何回か取り上げているのでもう詳しくは書かないけど便利。2017年から、もう3年以上使っているけど、乗り換えたいなとかしんどさを感じるなとかが全然なくてすごい。</p>
<p>最近は public にブログのような使い方をしている人も増えてきているけど、僕は private で使っている。理由としては public 状態だと「この内容は公に書いていいんだっけな」というジャッジが挟まってしまうから。メモするときに認知負荷をかけたくない。検索窓で「これ過去に書いたことあったっけ」っていうワードを探して、特に引っかからなければ何も考えずページ作って書く、という動作をスムーズにやりたい。</p>
<p>ただ、 public な Scrapbox というのもすごく面白そうだとは思っている。ブログのようにある程度磨かれた形ではなくて、多少生の状態の文章をどんどんアウトプットするための場所なので、スピーディかつ本音のままに近い文章が書けるし読める。最近 <a href="https://scrapbox.io/hub/100DaysToOffload">100DaysToOffload - hub</a> という記事を見かけた。1年100記事という「量」の目標だけを掲げて、質などその他のことは何も考えないことで、とにかくガンガンにアウトプットしようというプラクティス。この用途には Scrapbox は最適だと思う。他人の public Scrapbox を読むのはすごく好きで、 <a href="https://b.hatena.ne.jp/entrylist?url=https%3A%2F%2Fscrapbox.io%2F&#x26;mode=rss">scrapbox.io 全体における、はてなブックマーク新着人気エントリーの RSS</a> を購読している。</p>
<p><a href="https://gyazo.com/af1ae6bec2312bad62551050a2681e77"><img src="https://i.gyazo.com/af1ae6bec2312bad62551050a2681e77.png" alt="Image from Gyazo" width="600"/></a></p>
<p>ここ半年ぐらいは <a href="https://pixe.la">Pixela</a> と連携して、 Scrapbox にどれぐらい書き込んでいるか、草を生やして可視化できるようにしてみている。別に義務感で Scrapbox やっているわけじゃないんだけど、「おー、結構書いてるな」というのがわかると純粋に楽しい。設定方法は <a href="https://blog.a-know.me/entry/2019/10/22/182629">Scrapbox への更新がどれくらい活発におこなわれているかを Pixela で可視化する - えいのうにっき</a> で解説されている。</p>
<h3>Gyazo</h3>
<p><a href="https://gyazo.com/fb6bb8cdd0f7899d4498613c3f55f702"><img src="https://i.gyazo.com/fb6bb8cdd0f7899d4498613c3f55f702.png" alt="Image from Gyazo" width="600"/></a></p>
<p>副次的に、Scrapbox を開発している NOTA が同じく運営する Gyazo も便利で、こちらはお金を払っている（月額390円）。スクリーンショットの共有サービスと思われている側面が強いけど、当然ながら画像ファイルであればなんでも格納できて、ポイントとしてはすべての画像について OCR スキャンがかかるところ。 Chrome 用の Gyazo 機能拡張を使えばウェブページまるごとスクショして、その内容を検索できるようになるし、 Kindle など電子書籍も気になったところは iPad でスクショ撮ってメモ書き込んで Gyazo に突っ込んで検索できるようにしている。 Scrapbox に貼る画像も基本的には Gyazo に上がる形になるのだが、 Scrapbox 側で Gyazo の OCR 結果までは検索できないのがちょっと残念なところ。</p>
<h2>notion</h2>
<p><a href="https://chroju.github.io/blog/2020/08/12/notion_and_scrapbox/">前回の記事</a> で使い道は書いたので割愛。あくまで補足的な使い方。</p>
<h2>ツールの使い分け</h2>
<p>Dynalist と Scrapbox の2つを主に行き来しながら使っているわけだけど、たまにこれらをどっちかにまとめられないかな、というのは考える。でも結局無理だなというのが今のところの結論。 Scrapbox の、情報や知識が勝手に繋がっていく感覚は Dynalist には無理だし、 Scrapbox はアウトライナー的な使い方ができなくもないけれど、先述した日付に関する機能などはないので、 Dynalist 的に使おうとするとしっくりこない。まぁ適材適所かな、と考えている。タイトル通り、揮発性の一時的な脳内 dump ツールと、不揮発性の永続的なストレージと考えると棲み分けもスッキリする。</p>
]]></description>
            <link>https://chroju.dev/blog/dynalist_and_scrapbox_and_gyazo_notion</link>
            <guid isPermaLink="false">dynalist_and_scrapbox_and_gyazo_notion</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 13 Sep 2020 09:46:53 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[notion と情報管理、あるいは階層整理欲求と非階層整理の両立]]></title>
            <description><![CDATA[<p>Scrapbox を長らくメモ環境としてはメインで使っていて、それは今も変わらないのだけど、それと並行して notion も使い始めたので、そのあたりについて書こうと思う。</p>
<h2>Scrapbox の哲学</h2>
<p>このブログでも過去に取り上げたことがあると思うのだが、 Scrapbox には哲学がある。ただ漠然と使うより、 <a href="https://scrapbox.io/shokai/Scrapbox%E3%81%AE%E5%93%B2%E5%AD%A6">Scrapboxの哲学 - 橋本商会</a> を一度読んでから使い始めたほうがいい。</p>
<p>哲学の1つに <a href="https://scrapbox.io/shokai/%E9%9A%8E%E5%B1%A4%E6%95%B4%E7%90%86%E5%9E%8BWiKi%E3%81%AF%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%AB%E3%81%97%E3%81%AA%E3%81%84">階層整理型WiKiはスケールしない - 橋本商会</a> というものがある。ドキュメントツールの中には階層整理の形で設計されたものも多いが、階層分類というのは「どこに分類したらいいかわからない」という、いわゆる「こうもり問題」に苛まれることが多い。それを受けて、 Scrapbox は分類のための UI を持っておらず、ノート本文内の単語を <code>[ ]</code> で囲ってリンクにする（<a href="https://scrapbox.io/help-jp/%E3%83%96%E3%83%A9%E3%82%B1%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0">ブラケティング</a> と呼ぶ）ことにより、リンク同士が勝手につながって、勝手に整理されていくという形式を取っている。これは Wiki が昔から持っている機能ではあるが、ブラケティングをした瞬間に、リンク先、あるいはそのさらにリンク先のページが画面下部に勝手にずらずらと表示されるなど、ページ同士の繋がりがよりわかりやすく提示されるように設計されている。</p>
<p>この考え方が僕もとても好きで、知識の類は片っ端から Scrapbox に突っ込んでいる。過去に書いたメモのことなんて、忘れていることが大概だ。だから勝手に繋がってくれることが、確かにセレンディピティをもたらしてくれる。「この本の著者のことはよく知らないなぁ」と思いながら読書メモをしたためたら、その著者について、過去に聞いたあるスピーチの中で言及されていたことがわかった、なんてことはよくある。</p>
<h2>階層構造への欲求</h2>
<p>とはいえこのことが、階層型に対して Scrapbox が完全な上位互換となることを意味するとは思っていない。階層型と、 Scrapbox のような非階層型とは対立するものではなくて、一長一短で並立する関係と捉えている。</p>
<p>自分は ops 寄りのエンジニアである故もあり、システム関係のドキュメントを作る場合が特に多い。システムAの構成図、基本設計書、障害対応手順と作り、システムB、C、Dにも同様のものを作る。これを Scrapbox でやれるかと言うと、ちょっと厳しいなという思いが強まる。ほしいのは一覧性だ。ここに自分が管理している全システムの情報が集まっている、ということが、階層管理だとこんな感じで視覚的に認知できるのが嬉しい。</p>
<p><a href="https://gyazo.com/d86ed78d43dd08156d7676857beb7838"><img src="https://i.gyazo.com/d86ed78d43dd08156d7676857beb7838.png" alt="Image from Gyazo" width="218"/></a></p>
<p>これが Scrapbox だと、各システムの様々なドキュメントがどれも同じカードの形でバラバラと一覧表示されることになる。検索をかければ欲しいドキュメントはすぐに見つかるのかもしれないが、そこに「全体感」のような感覚は生まれづらい。もちろんこれは好みもあるわけで、この手のドキュメントでも Scrapbox だとか、タグ管理でイケる人はイケるんだろう。</p>
<h2>階層と非階層の両立としての notion</h2>
<p>自分の考えとして階層、非階層は排他ではなくて、ある組織が管理したいドキュメントのうち、階層で管理したいものとそうでないものは併存し得ると考えている。 notion というツールに分があるのは、その双方を混在させずに管理できる点にある。</p>
<p>notion の基本構造は階層整理だ。すべてのページは階層のどこかに位置することを基本としており、画面左側のメニュー部分には、常に全体の階層が表示されている。一方で、階層を伴わない整理機能として「データベース」というものが存在している。これがなかなか言葉で説明しづらいのだが、本当に RDB のレコードのような形でページが保存されていて、それをテーブル、カンバン、カレンダーなど、好きなビューを切り替えながら一覧できる機能、というイメージに近い。ページにはタグなどのメタ情報を複数付加することができ、それをキーにしてビューを構成する。以下はメタ情報をカラムとしたテーブルのビューから、あるメタ情報（status）をキーにしたカンバンへと切り替えるデモとして撮ってみた。</p>
<p><a href="https://gyazo.com/c87de21a0a8230a8ee85d7fcf659c8c6"><img src="https://i.gyazo.com/c87de21a0a8230a8ee85d7fcf659c8c6.gif" alt="Image from Gyazo" width="1000"/></a></p>
<p>そしてデータベースの中のページは、先の全体階層の中には表示されない。データベースの中だけで緩やかにスペースが区切られるようなイメージで、データベース内のページは、先のビューを使って一覧をする形になる。ただし、全体で検索をかければ、階層内のページも、各データベース内のページも同様にヒットする。ということで、 notion は大きな階層と、その節々でデータベースという小さな非階層を併存させた構造を取る。</p>
<p>この構造、なかなか使い勝手がいい。例えば先述したような、システムに関するドキュメントは階層構造で整理して、無限に増え得る技術 tips などの資料はデータベースでタグを付与しながら書き溜める、といった使い方が考えられる。 notion は階層構造のツールだとよく言われるけれど、個人的にはこのハイブリッド性こそが魅力の本質ではないかなと捉えている。従来の階層構造ツールでも、 Evernote のようにタグ対応しているものはもちろん存在していたが、すべてのページを階層の中にも位置づけるし、タグも付与できちゃうというものが多く、自分の経験からすると、結局どっちつかずになってしまうことが多かった。 notion は階層で分類するノートと、タグで分類するノート（＝データベース）を明確に分離することができるのが新鮮に感じている。</p>
<h2>notion の使い所</h2>
<p>というわけで notion は良いツールだと感じていて、個人でちょっと使っている。魅力を感じているところ、つまるところ使い所は他に2点ある。</p>
<p>PDF の保存が1つ。最近 Scrapbox もファイルアップロードに対応したが、 notion が便利なのはページの中に PDF を埋め込んでプレビューできること。別ページで PDF 開かなくていいのが良い。様々なホワイトペーパー、製品の説明書、 ScanSnap でスキャンした書類など PDF は数多くあるものの、今までは Dropbox に取りあえず突っ込んで終わり、だったのが、 notion を使うとメタ情報としてタグ付けて整理してその場で閲覧までできるようになった。</p>
<p><a href="https://gyazo.com/d8ba1b502caeef15231dd761f9c73b6e"><img src="https://i.gyazo.com/d8ba1b502caeef15231dd761f9c73b6e.png" alt="Image from Gyazo" width="880"/></a></p>
<p>もう1つは表。正確には先のデータベース機能になるのだが、スプレッドシートは大仰、 Markdown や Scrapbox のテーブルだと表現力がちょっと弱い、というその中間あたりをうまい具合に notion が突いている。カラムごとにデータ型の指定もできるので、これまでスプレッドシートをやむなく使っていたケースをわりと notion に移行できた。</p>
<p><a href="https://gyazo.com/42b1d8a237892a6a48a9f23cc5ea79f8"><img src="https://i.gyazo.com/42b1d8a237892a6a48a9f23cc5ea79f8.png" alt="Image from Gyazo" width="808"/></a></p>
<p>これ以外の知識や情報などのノートには引き続き Scrapbox を使っているし、メインと言えるのはあくまで Scrapbox 。 notion のデータベースはタグによる分類を実現できるものではあるけれど、Scrapbox はメタ情報としてタグを付与する、という考え方ではなくて、ノートの中の適当な単語や一文を <code>[]</code> で囲んでおけば、同じ単語が出てきたノート同士が勝手につながる、という思想なわけで、こちらのほうが使う上での心理的、認知的負荷は遥かに低いし、セレンディピティの恩恵も受けやすい。 Scrapbox がまだ苦手としているところを notion に担わせる形になっている。</p>
<p>逆に「組織」で使うとしたらどちらのツールを選ぶか、と問われたら notion を選ぶ気がしている。アイディア出しが重要になってくる開発やプロダクトデザイン、研究などの職種であれば、セレンディピティの点で Scrapbox が良いのだろうけど、ある程度固定的な情報を扱う ops の人間からすると notion のほうが組織の情報管理にはマッチする感覚が強い。このあたりは「情報をどう取り扱いたいのか」という組織のニーズによりけりなんだと思う。ドキュメントツールには、何かしら背景に設計思想があるはずなので、そこを押さえた上で、自分たちの情報管理思想とマッチするものを選ぶべきなんだろう。逆に特に設計思想が感じられず、世の中で使われているからという理由だけでタグも階層もその他いろいろ多機能になってます、みたいなツールは使いづらい場合が多い。</p>
<p>今回は notion に焦点を当てて書いたけど、後日 Scrapbox と notion と、あと情報管理という点でもう1つ使っている Dynalist 含め、自分のユースケースをまとめられたらと思っている。</p>
]]></description>
            <link>https://chroju.dev/blog/notion_and_scrapbox</link>
            <guid isPermaLink="false">notion_and_scrapbox</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 12 Aug 2020 12:57:36 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Terraform Cloud の terraform バージョンアップを GitHub Actions で自動化する]]></title>
            <description><![CDATA[<p>Terraform Cloud がサービス開始して約1年、 state file の保存のみならず、 <code>plan</code> と <code>apply</code> の実行環境としてもバリバリ使わせてもらっている。ちょっと面倒なのが、 plan 等を実行する workspace の Terraform バージョン設定である。常に <code>latest</code> を使うというアグレッシブな設定もできるが、そうしない限りは手動でバージョンアップが必要になっている。</p>
<p><a href="https://gyazo.com/ddda6bbe377f7c0c09a9bed473e24374"><img src="https://i.gyazo.com/ddda6bbe377f7c0c09a9bed473e24374.png" alt="Image from Gyazo" width="921"/></a></p>
<p>まぁガンガン <code>latest</code> にしていくのも考え方によってはありかもしれないが、メジャーバージョンアップ（ Terraform の場合 0.12 → 0.13 をメジャーバージョンアップと呼びたい）までされてしまうのは抵抗がある人も多いのではないだろうか。そもそも Terraform には remote config の中にバージョン指定を出来る箇所があり、自分の場合はこんな感じで 0.12 台のみを許可している。</p>
<pre><code class="language-hcl">terraform {
  backend "remote" {
    hostname = "app.terraform.io"
    organization = "sample"

    workspaces {
      name = "sample"
    }
  }
  required_version = "~> 0.12.0"
}
</code></pre>
<p>望むらくは、この <code>required version</code> をもとにしていい感じにバージョン設定してほしい。なのでそういう GitHub Actions を作った。</p>
<h2>terraform-cloud-updater</h2>
<p>https://github.com/marketplace/actions/terraform-cloud-workspace-auto-update</p>
<p>input として最低限、対象の Terraform ファイルが保存された <code>working_dir</code> を指定し、環境変数 <code>TFE_TOKEN</code> で Terraform Cloud の API トークンを渡してあげれば動作する。</p>
<pre><code class="language-yaml">on:
  push:
    branches:
      - master

jobs:
  tf_cloud_update:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: check update
        id: check
        uses: chroju/terraform-cloud-updater@v1
        with:
          working_dir: ./terraform
        env:
          TFE_TOKEN: ${{ secrets.TFE_TOKEN }}
      - name: result
        run: echo "${{ steps.check.outputs.output }}"
        if: "${{ steps.check.outputs.is_available_update == 'true' }}"
</code></pre>
<p>デフォルトの設定だと workspace のバージョンアップまでは自動で行わず、新しいバージョンが見つかったら <code>outputs.is_available_update</code> の値が <code>true</code> になり、バージョン情報が <code>outputs.output</code> にセットされるだけだ。あとは <code>is_available_update</code> で条件分岐して、例えば slack などで通知する方式を想定している。 <code>comment_pr</code> という input を <code>true</code> にすれば、 Pull request をトリガーとして使った際にコメントで通知してくれる機能も作ってはあるが、バージョンチェックであれば cron 形式で定期実行するほうがいいだろう。</p>
<p>input の <code>auto_update</code> を <code>true</code> にすることで、自動的に更新まで行ってくれる。その際、 required version との整合性を確認し、整合しない場合には更新は行わず、通知だけが行われる。以下は <code>comment_pr</code> を <code>true</code> にした場合のサンプルだが、 <code>outputs.output</code> からも同様のメッセージが取得できる。</p>
<p><a href="https://gyazo.com/c05c61d030dd2b6f06bd9573a905152a"><img src="https://i.gyazo.com/c05c61d030dd2b6f06bd9573a905152a.png" alt="Image from Gyazo" width="741"/></a></p>
<h2>実装</h2>
<h3>go-tfe</h3>
<p>https://github.com/hashicorp/go-tfe</p>
<p>Terraform Cloud の API ライブラリは hashicorp が公開している。名前が <code>tfe</code> になっているが、これは Terraform Enterprise と Cloud の共通 API ライブラリだからであって、 Cloud で特に問題なく使えた。</p>
<p>ちなみに Go で CLI ツールとして書いているので、この Action のもとになっているレポジトリを build すれば、ローカルで実行する CLI としても使うことができる。</p>
<pre><code class="language-bash">$ terraform-cloud-updater -h
Usage: terraform-cloud-updater [--version] [--help] &#x3C;command> [&#x3C;args>]

Available commands are:
    check     Check if new Terraform version is available
    update    Update Terraform cloud workspace terraform version
</code></pre>
<h3>required version の処理</h3>
<p>一番面倒くさかったのが required version だった。セマンティックバージョニングはいわゆる小数ではなく、ドットを2つ挟んだ数値形式なので、単なる数値比較を行なうことができず、逐一ロジックを組んでいった。また required version を示すオペランドの中には、 <code>~> 0.12</code> （0.12.0 以上かつ 0.13.0 未満の意）といった複数の意味をはらんだものもあり、これも自前で判定ロジックを組んだ。</p>
<p>と、いろいろ書いた末に「セマンティックバージョニングをよろしくやってくれるライブラリあるんでは？」と思って探してみたら当の hashicorp から公開されていたわけなのだが。勉強になったのでいいか、と思いつつ、こちらも比較で見てみようと思っている。</p>
<p>https://github.com/hashicorp/go-version</p>
<h3>初めての GitHub Actions</h3>
<p>GitHub Actions 自体はよく使っているものの、自分で Action を作るのはこれが初めてだった。ここでは詳細な作り方などには触れないが、 Action を実行する Dockerfile と entrypoint.sh を書き、あとはメタ情報を定義した action.yml を設置するだけでよいので、非常にお手軽に感じた。ちなみに Action は JS か Docker で作れるのだが、後者を選んだのは単に JS が書けないから。書けるのであれば実行速度などを鑑みても JS のほうがいいと思う。</p>
<p>なお、 GitHub Actions は <a href="https://github.com/marketplace">GitHub Marketplace</a> で公開ができる。そのための操作も非常にシンプルで、レポジトリのルートに action.yml を置くと勝手に判定されて、 Marketplace で公開するためのボタンが表示されるようになっていた。</p>
<p><a href="https://gyazo.com/229fea07a252ea16fb56de4637fe3553"><img src="https://i.gyazo.com/229fea07a252ea16fb56de4637fe3553.png" alt="Image from Gyazo" width="461"/></a></p>
<h2>Terraform のバージョン管理という根深い問題</h2>
<p>Terraform のバージョン管理問題はなかなか根深い。というのも Terraform の仕様上、一度使用したバージョンより古いバージョンに戻ることはできないようになっているからだ。そのため複数の Terraform レポジトリを扱っている場合、バージョンは <code>required version</code> に従って一括で揃えられるようにしたいという欲求が大きい。</p>
<p>複数の Terraform バージョンを切り替えるためのコマンドラインツール tfenv においても、 <a href="https://github.com/tfutils/tfenv/issues/124">tfenv doesn't read the required_version from conf.tf · Issue #124 · tfutils/tfenv</a> ということで、 required version に則って自動的に切り替えてほしいという issue が挙がっており、このあたりは悩んでいる人が多いのではないかと推察している。</p>
]]></description>
            <link>https://chroju.dev/blog/terraform_cloud_auto_update_with_github_actions</link>
            <guid isPermaLink="false">terraform_cloud_auto_update_with_github_actions</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 31 May 2020 23:06:51 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[COVID-19 とリモートワーク - 設備だけではなくルーチンも大事]]></title>
            <description><![CDATA[<p><a href="https://gyazo.com/2ace9ccce7aa3fd31bed95985a17dace"><img src="https://i.gyazo.com/2ace9ccce7aa3fd31bed95985a17dace.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>COVID-19 の影響で僕も絶賛リモートワーク中なのだが、せっかくなのでどんな感じでやっているのか記録も兼ねて書いておく。</p>
<h2>インフラエンジニアはリモートワークに慣れている</h2>
<p>僕は新卒から9年間 IT インフラ領域で働いていて、当初からリモートワークの片鱗のようなものはやっていた。多くのインフラエンジニアがそうだと思うけど、夜間休日にアラート対応を行う必要があり、またデータセンターに籠もりながら仕事をすることもあるので、いつでもどこでも働ける環境を持っている人が多いのではないかと思う。</p>
<p>僕の場合、 BYOD 的に自分の PC を使っていいのか、会社支給の PC が必須なのかは時期によって異なるものの、いずれにせよ「常に PC を携行していつでも仕事できるようにしておく」状態が求められてきた。データセンターに行って作業して、会社に戻る時間が勿体ないので近くのカフェで仕事して帰ったりしていたし、サンライズ出雲の中で朝6時ぐらいに対応したこともあったし、山梨のワイン祭りでオープンエアーのなか、ほろ酔い状態で障害対応せざるを得なかったこともあった。</p>
<p>ということで、リモートワーク自体は従前からずっとやってはいた。</p>
<h2>フルタイムのリモートワークは話が違う</h2>
<p>だから会社以外で働くことに抵抗はあんまりなかったし、 PC 1台あればなんとかなると思ってた。それが2年ぐらい前、 初めてフルタイムでリモートワークをしたときに、そうじゃないんだとわかった。</p>
<p>当時、怪我が理由でやむを得ず在宅勤務を1週間やらせてもらったことがあった。その頃はデュアルディスプレイも外付けの良い感じなキーボードも持っていなかったものの、障害対応の経験から「なんとかなるだろ」と軽く考えていた。が、会社の環境との差分が徐々にストレスになってきて、1日目が終わらないうちにデュアルディスプレイがどうしても欲しくなり、仕方なくテレビと繋いでぎこちないデュアルディスプレイ環境を作っていた。その後ちょうど今から1年ぐらい前に、大学へ入ったことと転居したことを契機に「きちんとした作業環境を作ろう」と思い、机や椅子も含めてすべて準備した。今のフルリモートワークは、1年前に「たまたま」設備を整えていたから出来ているもので、これが2年前だったらやっぱり難しかっただろうと思う。</p>
<p>もうひとつ、設備面だけではなくて、働き方やルーチンの面も重要だと思っている。オフィスで働くことは、単に働きやすい設備が整っているだけではなくて、働くための環境、体験があることを意味するのだと思う。それは同僚が近くにいて、すぐに声を掛けられることだったり、出退勤という物理的な移動を通じて、仕事の開始終了を明確に区切れることだったり。家でひとりで働くとき、オフィスでの体験を完全には再現できない。その状態で、じゃあどうすればオフィスと同じようなパフォーマンスを発揮できるか？という視点、いわば設備というハードに対して、ソフト面の整備も重要になってくる。</p>
<p>特に今の状況は、リモートワークを強いられているのでストレスが強いという思いがある。今働いている会社はもともとリモートワーク OK だったけれど、それは裁量で会社に来てもいいし、来ないこともできるという意味で、今の「リモートワーク強制」とはまったく違う。今日はちょっと気分を替えてリモートワークしよう、であれば、それだけでパフォーマンスにはプラスになるかもしれない。しかし常に家で仕事をしていると、必然パフォーマンスは従来より上がりにくくなる。</p>
<p>てことで以下では、ハードとソフト、両面から自分のリモートワーク環境についてまとめてみる。</p>
<h2>リモートワーク環境（ハード面）</h2>
<p>まずハードについてだけど、正直言うともっと改善したい。超最高級の環境にはなっていない。ぶっちゃけ妥協してしまった。平日ずっとこの環境で作業をすることまで想定していたらもっと良いものを買っていたと思う。なのでこれから揃える人は、考えられる限り最高の環境を作ったほうがいいんではないだろうか。てわけであんまり参考にしないでほしさはある。</p>
<h3>椅子 / イトーキ サリダ YL8</h3>
<p>https://www.amazon.co.jp/%25E3%2582%25A4%25E3%2583%2588%25E3%2583%25BC%25E3%2582%25AD-%25E3%2582%25AA%25E3%2583%2595%25E3%2582%25A3%25E3%2582%25B9%25E3%2583%2581%25E3%2582%25A7%25E3%2582%25A2-YL8-GRBL-AEL-%25E3%2582%25A2%25E3%2582%25B8%25E3%2583%25A3%25E3%2582%25B9%25E3%2582%25BF%25E3%2583%2596%25E3%2583%25AB%25E8%2582%2598%25E4%25BB%2598-%25E3%2582%25B0%25E3%2583%25AC%25E3%2583%25BC%25C3%2597%25E3%2583%2596%25E3%2583%25A9%25E3%2583%2583%25E3%2582%25AF/dp/B07FCYCXDF</p>
<p>コストパフォーマンスに優れた椅子。3万円ぐらいだが、ランバーサポート、可動式のアームレスト、固定リクライニング、背もたれのメッシュなどが付いていて悪くない。ただあくまでコストパフォーマンスというところで、座面の硬さだとか、ヘッドレストが頭に合わないだとか、気になるところもある。フルリモート前提ならもっと高いのを選ぶと思う。</p>
<p>今だと後継で YL9 が出ているので、そちらのほうがいいかもしれない。</p>
<h3>充電器 / Anker PowerPort I PD</h3>
<p>https://www.amazon.co.jp/Anker-PowerPort-PowerIQ%25E3%2580%2590Power-Plus%25E3%2580%2581MacBook%25E3%2580%2581Galaxy-XZ1%25E3%2580%2581%25E3%2581%259D%25E3%2581%25AE%25E4%25BB%2596Android%25E5%2590%2584%25E7%25A8%25AE%25E5%25AF%25BE%25E5%25BF%259C/dp/B072KBG9W4</p>
<p>最大30W供給する USB Type-C 1ポートと Type-A 4ポート搭載の充電器。これに Type-C 2本と micro USB 1本、ライトニング 1本、Fitbit Versa 2 の独自充電ケーブル1本繋いで使っている。充電は1箇所でまとめてできるようにしておくとやっぱり便利。</p>
<p>そのまま机上に置くと見た目があまりにあまりなので、 <a href="https://www.muji.com/jp/ja/store/cmdty/detail/4549337495555">無印良品のポリプロピレンメイクボックス</a> に隠している。</p>
<h3>キーボード / Corne Cherry</h3>
<p><a href="https://gyazo.com/edea1bbb4afc7873a265c0888685b5cc"><img src="https://i.gyazo.com/edea1bbb4afc7873a265c0888685b5cc.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>自作キーボード。自作じゃなくてもいいので、手に合うキーボードは必須と思う。と言いながらも、自作だとキースイッチの重さや押した感触、キー数、左右分離か否か、キーキャップの触り心地などなど隅々まで好きにできるので、冗談抜きに自作はおすすめではある。作るのも半日あればできるし、値段も HHKB 買うのとそんなに変わらない、はず。沼にはまらなければ。</p>
<h3>その他</h3>
<p>その他ざっくりこんなの使っている。</p>
<p>| 品物 | 品名 | amazon link |
|--|--|--|
| 机 | ノーブランドの謎のやつ | https://www.amazon.co.jp/dp/B0045XJPWM |
| ディスプレイ | I-O DATA EX-LDQ241DB | https://www.amazon.co.jp/dp/B077Y79Q2V |
| PCスタンド | NEXSTAND | https://www.amazon.co.jp/dp/B01HHYQBB8 |
| ヘッドセット | VOYGER 3200 | https://www.amazon.co.jp/dp/B07SMR5RD2 |</p>
<h2>リモートワーク環境（ソフト面）</h2>
<p>ソフトと言うかルーチンというか、こんなことを気をつけている。</p>
<h3>仕事開始のルーチン</h3>
<p>通勤というのは結構仕事開始のルーチンとして大きかったのだと思う。それが無くなった今、何か別の手段で自分の身体と精神に「今から仕事だぞ」と言い聞かせる、スイッチの切替が必要になっている。</p>
<p>僕の場合はノイキャンイヤホンで音楽を聞き始めることと、ポモドーロ・テクニックのタイマーを入れることがスイッチになっている。外界からの遮断と、タイマーを入れることによる明確な時間の区切りがいい感じに作用してくれている。コーヒーを淹れるとか、「やるぞ」って声を出すとか、なんでもいいので何かしらルーチンを定めると捗る。</p>
<p>ちなみにノイキャンイヤホンは定番の <a href="https://www.amazon.co.jp/dp/B07TKGGZ47">SONY WF-1000XM3</a> を使っている。音楽流さず、ただ耳にはめてノイズキャンセリングしてるだけでも効果がある。</p>
<h3>ポモドーロ・テクニック</h3>
<p>先程言及したポモドーロ・テクニックは、タイマーをかけて25分間集中して、5分間休憩するというサイクルを繰り返すもの。人間の集中力の限界はそれほど長くないので、強制的に中断することで集中力の持続性を高めたりとか、25分という短い時間を区切ることで集中しやすくするとか、そういった効果があるらしい。</p>
<p>僕の場合、これはリモートワークのときに限らず導入しているのだけれど、リモートワークのときは特に集中力が削がれやすかったりもするので、相性がいいと思う。また逆の観点で、いつまでもだらだら仕事を続けてしまうのを防ぐ効果もある（リモートワークでは「帰宅」が発生しないので、仕事を際限なく続けたくなりがち）。</p>
<p>タイマーには <a href="https://apps.apple.com/jp/app/just-focus/id1142151959?mt=12">Just Focus (AppStore link)</a> を使っている。25分経つと強制的に画面をロックしてくれる強力なやつで、タイマーが鳴ったのにずるずる作業を続けたりすることがない。</p>
<h3>昼休みは必ず外に出る</h3>
<p>休憩時間がもったいなくて家で過ごしたくもなるのだが、昼休みは必ず外に出るようにしている。気分転換の効果がひとつと、フルリモートだと通勤がなくなるので、運動不足解消の意味がひとつ。</p>
<p>最近は感染症予防のこともあるので、もっぱら外食ではなく中食をしている。また「外出は1日1回にしましょう」という話もあるので、昼休みが唯一の外出機会になる日が多い。</p>
<h3>ボイスチャットを躊躇しない</h3>
<p>自分がやれているかは置いておいて、ボイスチャットを躊躇するべきではないと感じている。基本常に slack が開かれていて、コミュニケーションが取れる状態があるのは大前提として、文字ベースのやり取りより話したほうが早いじゃん、ということはどうしてもある。そういうとき10秒でも1分でもサクッと話すことを躊躇しないでおくとわりと捗る気がしている。</p>
<p>あと、「ちょっとここわかんないんだけど」ってときに作業中のコードを共有する手段として、 VSCode の Live share がすごくいい。めっちゃ快適。デスクトップ共有するぐらいならこっちのほうが絶対いい。ターミナルまで共有されるのがちょっと怖くはあるが。</p>
<h3>Nintendo Switch</h3>
<p>これハードじゃんって感じだけど Nintendo Switch は買ってよかったなというのが精神的に大きいのでソフト面で入れてみた。</p>
<p>最近だと『あつまれ どうぶつの森』がなんとなく外出欲を満たしてくれるのと、『Fit Boxing』が運動不足解消に使えるのと。『リングフィットアドベンチャー』が流行っていたけど、『Fit Boxing』ならジョイコンだけで遊べるので、ダウンロード版を買ったらサクッと始められる。</p>
<h2>自分が最もパフォーマンスを発揮できる状態を、自分でつくる</h2>
<p>つらつら書いたけれど、自宅はもともと仕事する場所じゃないので、そこでどうパフォーマンスを発揮できるようにするかを考えなきゃいけないよね、という話。そしてハード面ばかりに意識が向きがちだけど、ルーチンとかも見直すことで結構生産性上がったりするよ、という話。</p>
<p>正直、この状況がいつまで続くかわからないし、感染症が終息した後もきっとリモートワークはある程度普及したままになるだろうなと思うので、今のうちにゴリゴリ環境作りしていくのが吉だと思う。</p>
]]></description>
            <link>https://chroju.dev/blog/remote_work_infrastructure_engineer_under_covid_19</link>
            <guid isPermaLink="false">remote_work_infrastructure_engineer_under_covid_19</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 15 Apr 2020 14:10:50 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[HCL をパースして、構造を組み替えて再出力する]]></title>
            <description><![CDATA[<p>Terraform などで使われる、 JSON 互換の HCL (Hashicorp Configuration Language) というデータフォーマットがある。 HCL で書かれた設定をパースすることについてはいくつかエントリーを見かけるのだが、 HCL を出力するほうについてはあまり見かけないので書いてみる。</p>
<h2>tfmodule</h2>
<p>事の発端としては tfmodule という CLI ツールを作ったことによる。</p>
<p>https://github.com/chroju/tfmodule</p>
<p>Terraform module を使うときは、 README などを読んで必要な変数を確認し、それに応じて設定を書いていく流れが一般的である。しかし何分これが面倒だったので、一発で module の構造をパースして、テンプレートを吐き出してくれるようなものを作れないかと考えた。</p>
<p>例えばこんな <code>variable</code> と <code>output</code> を定義している module があったとする。</p>
<pre><code class="language-hcl">variable "instance_type" {
  type        = string
  description = "EC2 instance type"
  default     = "t3.micro"
}

variable "instance_counts" {
  type        = number
  description = "Number of instances to create"
  default     = 2
}

output "instance_arns" {
  value = aws_instance.instance.*.arn
}
</code></pre>
<p>これに対して tfmodule は以下のようなテンプレートを出力する。</p>
<pre><code class="language-hcl">module "instances" {
  source = "./modules/instances"

  // EC2 instance type
  // type: string
  instance_type = "t3.micro"
  // Number of instances to create
  // type: number
  instance_counts = 2
}

output "instances_instance_arns" {
  value = module.instances.instance_arns
}
</code></pre>
<p>処理としては HCL をパースして構造を読み取り、 module の形に再構成して出力をしている。このツールを作る中で、 HCL の出力に関して知見を得ることができた。</p>
<h2>HCL のデータ構造</h2>
<p>HCL をパースするには、まず HCL の構造を理解する必要がある。これについては、今回は Terraform における HCL を解析するので、 <a href="https://www.terraform.io/docs/configuration/syntax.html">Syntax - Configuration Language - Terraform by HashiCorp</a> を読むと早い。正確には、このページに書かれているのは「 Terraform における HCL の使い方」でしかないので、 HCL 自体の言語仕様を知る場合には  <a href="https://github.com/hashicorp/hcl/blob/hcl2/hclsyntax/spec.md">hcl/spec.md at hcl2 · hashicorp/hcl</a> を読んだほうがよい。ちなみに Read the Docs に https://buildmedia.readthedocs.org/media/pdf/hcl/guide/hcl.pdf という URL で PDF のホワイトペーパーも置かれているのだが、こちらは一部内容が古い部分がある。</p>
<p>ざっくり、  HCL は <code>Arguments</code> と <code>Blocks</code> という2種類のデータ構造から構成される。</p>
<pre><code class="language-hcl">image_id = "abc123"
</code></pre>
<p>これが <code>Arguments</code> 。いわゆる key value の形を取る。</p>
<pre><code class="language-hcl">resource "aws_instance" "example" {
  ami = "abc123"

  network_interface {
    # ...
  }
}
</code></pre>
<p>これが <code>Blocks</code> 。 <code>{}</code> によって複数の要素を囲った形を取る。冒頭、上記で <code>resource</code> と書かれた部分は <code>type</code> と呼ばれ、その block の種別を表す。それに続くダブルクォートで囲われた2つの文字列は <code>label</code> と呼ばれ、 block を一意に識別する役割を持つ。 label の数は type ごとに定義することができ、 Terraform であれば resource の label は2つ、 variable や output の label は1つと定義されている。</p>
<p>block の <code>{}</code> で囲われた部分は body に当たる。そして body は中に attribute と block を内包することができる。また、ファイル全体も body と呼ばれる。 HCL のデータ構造は、このような入れ子構造になっている。</p>
<pre><code>File
└── Body
    ├── Attribute
    ├── Attribute
    └── Block
        └── Body
            ├── Attribute
            └── Block
                └── ...
</code></pre>
<h2>hclsimple / hclparse</h2>
<p>HCL を扱うには、本家 Hashicorp が公開している <a href="https://pkg.go.dev/mod/github.com/hashicorp/hcl/v2">github.com/hashicorp/hcl/v2</a> を使うのが常道である。このライブラリには、さらに用途別でいくつかのサブパッケージが含まれている。</p>
<p>パースをする際には hclsimple や hclparse を使うことができる。最も直感的に扱いやすいのは hclsimple で、 Go の <code>json.Marshal()</code> のように、 hcl を構造体へ変換できる。以下は <a href="https://pkg.go.dev/github.com/hashicorp/hcl/v2@v2.3.0/hclsimple?tab=doc">hclsimple package · go.dev</a> からの抜粋。</p>
<pre><code class="language-hcl">type Config struct {
	Foo string `hcl:"foo"`
	Baz string `hcl:"baz"`
}

const exampleConfig = `
	foo = "bar"
	baz = "boop"
	`

var config Config
err := hclsimple.Decode(
	"example.hcl", []byte(exampleConfig),
	nil, &#x26;config,
)
if err != nil {
	log.Fatalf("Failed to load configuration: %s", err)
}
fmt.Printf("Configuration is %v\n", config)
</code></pre>
<p>しかし、この方法は HCL の構造が予想可能な場合にしか使えない。不特定の構造が予期される場合には、 hclparse を使うことにより、 <code>hcl.File</code> という組み込みの構造体へ変換できる。一般的にパースだけの用途であれば、この2つを使えば十分と考えている。</p>
<h2>hclwrite</h2>
<p>tfmodule では hclwrite というサブパッケージを用いている。名前通り、これは HCL の出力に主眼を置いたサブパッケージになっている。先の <code>hclsimple.Decode()</code> が <code>json.Marshal()</code> と似ているので、 <code>json.Unmarshal()</code> にあたるメソッドが存在すれば嬉しいのだが、残念ながらそういった便利な機能は備わっていない。</p>
<p>hclwrite による HCL の出力はかなり愚直な方法を取る。以下のように、先程示した HCL のデータ構造を、頭から順に作っていくような形になる。</p>
<pre><code class="language-go">f := hclwrite.NewEmptyFile()

rootBody := f.Body()
moduleBlock := rootBody.AppendNewBlock("module", []string{m.Name})
moduleBody := moduleBlock.Body()

moduleBody.SetAttributeValue("source", cty.StringVal(m.Source))
moduleBody.AppendNewline()

for _, v := range *m.Variables {
        if isNoDefaults &#x26;&#x26; !reflect.DeepEqual(v.Default, hclwrite.TokensForValue(cty.StringVal(""))) {
                continue
        }
        moduleBody.AppendUnstructuredTokens(v.generateComment())
        moduleBody.SetAttributeRaw(v.Name, v.Default)
}
</code></pre>
<p><code>hclwrite.NewEmptyFile()</code> で返る <code>hclwrite.File</code> に、順に要素を詰め込んでいく。その後 <code>hclwrite.File.Bytes()</code> を呼ぶと、いわゆる <code>terraform fmt</code> が実行された状態の、整形された HCL が出力される。</p>
<h3>SetAttributeXXX</h3>
<p>上に示したように、 <code>SetAttributeXXX()</code> というメソッドで attribute をセットできるのだが、 key は単純に string を渡せばいい一方、 value についてはそうではなく、種別にいくつかのメソッドが用意されている。</p>
<p>最もよく使うのは <code>SetAttributeValue()</code> で、これは value として <a href="https://pkg.go.dev/github.com/zclconf/go-cty">github.com/zcolconf/go-cty</a> の <code>cty.Value</code> を取る。 cty をあんまり理解できていないのだが、 HCL が内部で利用している型システムで、 <code>cty.StringVal()</code> で文字列型、 <code>cty.BoolVal()</code> で真偽値型の <code>cty.Value</code> が返るようになっている。</p>
<p>また、Terraform では <code>var.example</code> のようなリテラルを使うことがあるが、これは <code>SetAttributeTraversal()</code> で埋め込むことができる。主にはこの2つのいずれかを使うことになる。もう1つ <code>SetAttributeRaw()</code> というものがあり、これは <code>hclwrite.Tokens</code> という、いわばバイト列をそのまま埋め込んだような構造体を引数に取ることができる。要するに「なんでもあり」なのだが、それ故に godoc には「出来れば <code>SetAttributeValue()</code> か <code>SetAttributeTraversal()</code> を使うように」と書かれている。</p>
<h3>AppendUnstructuredTokens</h3>
<p>HCL に attribute でも block でもない要素を埋め込みたいときがある。つまるところコメントなのだが、これについてはコメント埋め込み用のメソッドが hclwrite に見つからなかったので、 <code>AppendUnstructuredTokens()</code> というメソッドを使っている。</p>
<p>その名の通り構造化されていない <code>hclwrite.Tokens</code> を直接追加するメソッドで、コメントの追加は以下のように実装している。</p>
<pre><code class="language-go">...
moduleBody.AppendUnstructuredTokens(v.generateComment())
...
func (v *Variable) generateComment() hclwrite.Tokens {
        tokens := hclwrite.Tokens{
                {
                        Type:  hclsyntax.TokenSlash,
                        Bytes: []byte("//"),
                },
                {
                        Type:  hclsyntax.TokenIdent,
                        Bytes: []byte(v.Description),
                },
                {
                        Type:  hclsyntax.TokenNewline,
                        Bytes: []byte("\n"),
                },
                {
                        Type:  hclsyntax.TokenSlash,
                        Bytes: []byte("//"),
                },
                {
                        Type:  hclsyntax.TokenIdent,
                        Bytes: []byte("type:"),
                },
        }
        tokens = append(tokens, v.Type...)
        tokens = append(tokens, &#x26;hclwrite.Token{
                Type:  hclsyntax.TokenNewline,
                Bytes: []byte("\n"),
        })
        return tokens
}
</code></pre>
<p><code>hclwrite.Tokens</code> はバイト列のようなものと先程書いたが、正確には <code>hclwrite.Token</code> の slice である。ではこの <code>hclwrite.Token</code> とは何なのか、 godoc から抜粋する。</p>
<pre><code class="language-go">type Token struct {
	Type  hclsyntax.TokenType
	Bytes []byte

	// We record the number of spaces before each token so that we can
	// reproduce the exact layout of the original file when we're making
	// surgical changes in-place. When _new_ code is created it will always
	// be in the canonical style, but we preserve layout of existing code.
	SpacesBefore int
}
</code></pre>
<p>バイト列、と書いたように、ここに <code>Bytes</code> でリテラルが埋め込まれる。 <code>Type</code> はそのリテラルの種類を示しており、例えばリテラルがドットであれば <code>hclsyntax.TokenDot</code> 、スラッシュであれば <code>hclsyntax.TokenSlash</code> といったものが用意されている。</p>
<h2>tfmodule での実装</h2>
<p>hclwrite にも HCL をパースするためのメソッドが存在しているので、 hclwrite だけを使っている。</p>
<pre><code class="language-go">src, err := ioutil.ReadFile(path)
if err != nil {
        return err
}

file, diags := hclwrite.ParseConfig(src, path, hcl.InitialPos)
if diags.HasErrors() {
        return diags
}

body := file.Body()
for _, block := range body.Blocks() {
        switch block.Type() {
        case "variable":
                variables = append(variables, parseVariable(block))
        case "output":
                outputs = append(outputs, parseOutput(block))
        case "resource":
                resources = append(resources, parseResource(block))
        }
}
</code></pre>
<h2>参考となる OSS</h2>
<p>長々書いてきたが、正直まだきちんと hashicorp/hcl を理解できたとは思っておらず、もう少し楽な実装がありそうな気がしている。ただ、なかなか実装例を見かけることが少ない。 <a href="https://github.com/shuaibiyy/awesome-terraform">shuaibiyy/awesome-terraform</a> で Terraform 関連のツールをいくつか見てみたりもしたのだが、特に hclwrite を使っているものは見つけられなかった。今のところ参考になりそうなのは2つほど。</p>
<p>https://github.com/apparentlymart/terraform-clean-syntax</p>
<p>Terraform の開発に関わっている apparentlymart 氏の個人レポジトリ。 <code>terraform fmt</code> のように、 HCL を Terraform 0.12 の書式で整形し直してくれるコマンドラインツールで、がっつり hclwrite を使っている。 tfmodule での実装は、かなりこれを参考にさせてもらった。</p>
<p>https://github.com/hashicorp/terraform-config-inspect</p>
<p>この記事を書く中で見つけた、 tfmodule と似た terraform module の解析ツール。 Hashicorp の org 内にあるのだが、今まで気付いていなかった。 hclwrite は使っていないが、 terraform module をどのように解析しているか、という点で学べる点がありそうだった。</p>
]]></description>
            <link>https://chroju.dev/blog/hcl_parse_and_output</link>
            <guid isPermaLink="false">hcl_parse_and_output</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 11 Apr 2020 09:24:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[社会人大学生1年目を終えて、大学生活と勉強法とその困難]]></title>
            <description><![CDATA[<p>昨年 <a href="https://chroju.github.io/blog/2019/06/14/become_parallel_worker_and_university_student/">パラレルワーカー兼大学生になることになった · the world as code</a> で書いたように社会人大学生を始めたのだが、なんとか1年目を終えたので大学生活がどんな感じなのかとか、所感などを書いていく。</p>
<h2>履修結果</h2>
<p>19科目38単位を登録して、結果は以下のようになった。成績は S, A, B, C の4段階で評価されている。</p>
<ul>
<li>S評価 : 4科目8単位</li>
<li>A評価 : 6科目12単位</li>
<li>B評価 : 2科目4単位</li>
<li>単位未修得 : 7科目14単位</li>
</ul>
<p>比較的成績は良かったのだと思うけれど、それ以上に目立つのが未修得の単位の多さである。これに関しては見積もりが甘かったとしか言いようがない。大学の単位を取るのは自分が思っていたより大変だった。この点はあとで詳述する。</p>
<p>ところでこのように書くと14単位も「落とした」ように見受けられそうだが、実際には不合格になったわけではなくて試験すら受けていない。何が違うのかと言うと、通信課程においては（通常課程がどうなのかは知らないが）登録した単位は2年間履修可能であるため、来年度に試験を受けて修得ができる。つまりまだ「落とした」というわけではない。ここ重要。</p>
<p>卒業必要単位が124単位、10年前に卒業した大学の単位を充当して修得済みと認定されているのが32単位、今年度修得したのが24単位、残り68単位。今年のペースを考えると、おそらく1年は留年することになる。</p>
<h2>通信制大学の過ごし方</h2>
<p>以下はあくまで帝京大学理工学部情報科学科の場合なので、他の通信制大学だとまた違う過ごし方になるはず。</p>
<h3>授業形態</h3>
<p>まず前提となる授業形態について書いておくと、ざっくり3種類ある。</p>
<ul>
<li>メディア授業
<ul>
<li>LMS (Learning Management System) と呼ばれるポータルサイトで公開されたビデオ、スライド等の教材を使って学習する。</li>
</ul>
</li>
<li>テキスト授業
<ul>
<li>市販のテキストを主に使って学習する。 LMS で補助教材が公開される場合もある。</li>
</ul>
</li>
<li>スクーリング授業
<ul>
<li>キャンパスへ実際に足を運び、2〜3日間集中的に対面授業を行い、最後に試験を受験して単位を修得する。</li>
</ul>
</li>
</ul>
<p>通信制大学をよく知らない人にはスクーリングの存在が意外に思われそうだが、法令により通信制大学の卒業単位のうち30単位はスクーリングが必要となっているらしい。原則的に週末2日間を朝から夜まで集中的に講義を受け、最後に試験を受ける形になる。手軽といえば手軽なのかもしれないが、2日間終日の講義というのはなかなか集中力的に堪えるものがある。</p>
<p>メディア授業とスクーリング授業に関してはご想像される通りだと思う。 LMS で公開される教材の種類は授業によってまちまちなので、以下のように様々な種類の教材を使い分けていくことになる。</p>
<ul>
<li>紙の書籍</li>
<li>電子書籍（指定された教科書のほとんどは紙だが、まれに電子で手に入るものもある）</li>
<li>PDF 化されたスライド資料</li>
<li>動画</li>
<li>LMS 内で閲覧するダイナミックなコンテンツ</li>
</ul>
<h3>単位修得の方法</h3>
<p>単位修得には必ず単位修得試験を受ける必要がある。レポートや課題提出だけで単位修得ができるようにはなっていない。そして単位修得試験を受ける条件として、 LMS 上の小テストや課題の提出、レポートの提出などが課されることになっている。</p>
<p>試験は年に4回、I期〜IV期という形で受ける機会がある。このうちI期とIII期、II期とIV期で受けられる科目はそれぞれ同じになっており、1科目につき2回受験機会があるということになる（I期で不合格だった科目をIII期で受けるのはダメだったように思う）。したがって最悪の場合は全科目ガッツリ時間をかけて勉強して、III期とIV期だけ受けるということもできなくはない。逆に負荷を分散して、各期でだいたい同じ数の科目を受けるようにもできる。自分のライフスタイルにある程度あわせてプランニングできるのはありがたい。</p>
<h2>勉強方法</h2>
<p>勉強は主に平日だと帰宅後の1〜2時間程度と、通勤電車の中での時間を費やしていた。休日は時間を取れるだけ取るという形で、日によっては朝から夜まで費やすこともあった。</p>
<h3>iPad Pro 12.9 + Liquid Text + GoodNotes</h3>
<p>教材を読んだり見たりするときはだいたい iPad Pro を使っている。 Apple Pencil を使ってザクザク書き込めるし、先に書いた様々な種類の教材をだいたいなんでも扱えるのがいい。</p>
<p><a href="https://gyazo.com/295d808c197d43fc123cc14b9fa6ab7d"><img src="https://i.gyazo.com/295d808c197d43fc123cc14b9fa6ab7d.jpg" alt="Image from Gyazo"/></a></p>
<p>特によく使っているのが <a href="https://apps.apple.com/jp/app/liquidtext/id922765270">Liquid Text</a> で、 PDF やウェブページを取り込んで、自由に書き込みをしたり、要らない部分を見えなくしたり、文章や画像をピックアップして欄外にまとめ直したりできる。なかなか使ってみないと便利さがわからない難しいアプリだけど、資料を読みながら情報を整理して理解をしていくという過程ですごく役に立つ。保存処理がたまに分単位で時間を要するのが欠点。</p>
<p>単なるメモ書きの用途には <a href="https://apps.apple.com/jp/app/goodnotes-5/id1444383602">GoodNotes</a> を使っている。こちらも PDF をインポートできるので、さっくり PDF が見たいだけの場合は GoodNotes を使っていることもある。</p>
<h3>Anki</h3>
<p>https://github.com/ankitects/anki</p>
<p>いわゆる暗記カードをデジタルで作って学習できるアプリケーション。カードに LaTeX や HTML 、画像ファイルなどを埋め込める高機能な点が嬉しい。またカードを実際にめくっていく学習モードは <a href="https://ja.wikipedia.org/wiki/%E5%BF%98%E5%8D%B4%E6%9B%B2%E7%B7%9A">忘却曲線</a> などを踏まえて実装されていて、覚えが悪いカードは数分後、すでに覚えたと判断したカードは忘れている可能性のある数日後に再出題してくれて、効率的な暗記ができる。</p>
<p><a href="https://gyazo.com/ac1f2c7f8eeb41b5174253faef6b3a1a"><img src="https://i.gyazo.com/ac1f2c7f8eeb41b5174253faef6b3a1a.png" alt="Image from Gyazo" width="923"/></a></p>
<p>カードはもちろん自作する必要があるので当初は面倒に感じていたが、カードを作る過程で一度勉強して、その後復習としてカードを使った学習ができるのはわりとよかった。 macOS 上で作ったカードデッキを Android へ移して、通勤電車の中でよく Anki していた。</p>
<h3>Visual Studio Code + LaTeX</h3>
<p>レポートやプログラミング課題の作成環境。詳細は <a href="https://chroju.github.io/blog/2019/06/24/write_repot_with_vscode_tex/">VSCode と TeX で大学のレポートを書く · the world as code</a> で書いた。</p>
<h3>Scrapbox</h3>
<p>https://scrapbox.io/</p>
<p>説明が難しいが、すごく簡単に使える Wiki のようなもの。最終的に授業全体で得た知識をまとめておくのに使っている。</p>
<h3>東京都立中央図書館</h3>
<p>勉強は家でする場合も多いが、特にレポートを書く際に参考資料を漁りたいときは東京都立中央図書館を使っている。</p>
<p>蔵書と閲覧席が極めて多いというのが大きい。特にコンピュータ書が豊富に置かれた図書館というのは知る限りほとんど存在しないので重宝している。本来であれば大学図書館が使えればいいのだが、帝京大学理工学部のキャンパスは宇都宮で、自宅から100km以上離れているため日常利用は難しい。</p>
<h2>1年目の所感</h2>
<h3>単位修得の難しさ</h3>
<p>冒頭に「修得できなかった単位数」の話を書いたとおり、単位修得は想定していた以上に難しいものがあった。</p>
<p>大学の単位1単位あたり、学習時間の目安は45時間である。ざっくり卒業に120単位必要なので、年間30単位とすると1350時間。これを1日あたりで割るとだいたい4時間になる。働いている人が確保する時間としてはなかなか厳しいものがある。</p>
<p>おまけにプライベートの学習時間全部を大学に当てられるわけでもない。最新の技術も追いたいし、仕事で未知の技術に触れる機会があったら、どうしてもそちらのキャッチアップが優先になる。仮に試験前の時期であったとしても、仕事より優先するのは難しい。</p>
<p>また暗記力の衰えも感じる。仕事のために新しい技術をインプットする場合、ざっくりとした全体感や概念に関する目録を頭の中に作るようなイメージがあって、細かいことは本やドキュメントを見ればいいので覚えないことが多い。これが結構試験を受ける上でネックになっている。対策としては先の Anki を使ったりして、意識的に暗記をしていくしかない。</p>
<h3>授業間の関連性</h3>
<p>シラバスなどを見ればわかることではあるが、授業間には関連性がある。ある授業を受けるにあたり、別の授業の履修が前提となっていることがあり、時にそれは暗黙的なこともある。今年度の場合で言えば微分積分2が難しくてなかなか進められなかったのだが、他の授業で微分積分が必要になる場合が少なくなく、「微分積分が出来ていない」ことを理由として修得できない科目が複数出てきてしまった。これも修得単位が少なくなった理由の1つになっている。</p>
<h3>孤独感</h3>
<p>スクーリングを除けば1人で授業は進める必要があるので、孤独感は強い。寂しいなどという話ではなく、教員や同級生への質問ができないので、わからないことを打破するのが難しい場合がある。</p>
<p>もちろんチャネルがないわけではない。教員とは LMS のメッセージ機能でやり取りができるが、しかしオフィスアワーがあるわけではないので、じっくり質問するようなことはできない。同級生とのやり取りには、大学から提供されている Office 365 内の Teams が使えるのだが、だいぶ過疎気味で積極的な連絡は取りづらい状況にある。</p>
<h3>教材と環境構築</h3>
<p>これは極一部の授業の話ではあるのだが、1〜2科目ほど Java Applet を題材とした授業があった。既知の通り Applet は Java 11 で廃止済みであり、使うには古い Java をあえてインストールして環境構築する必要がある。そこにどうにも躊躇いが生じ、今年はこれらの授業を断念した。</p>
<p>聞くところによれば Processing への移行が段階的に進んでいるらしく、一時的な問題だとは捉えている。とはいえ、一部このような古い教材が使われていることへの懸念は覚えた。</p>
<hr>
<p>だいぶネガティブなことも書いてしまったが、1年を通じて「如何に学習を進めるべきか」という指針は立てられたように思う。別に急いで卒業したいわけでもないので、きちんと身につくような学習を2年目も続けていきたい。</p>
]]></description>
            <link>https://chroju.dev/blog/adult_university_learner_first_year</link>
            <guid isPermaLink="false">adult_university_learner_first_year</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 28 Mar 2020 02:25:27 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[cVim から SurfingKeys へ移行した]]></title>
            <description><![CDATA[<p>ブラウザをキーボードだけで操作するツールが好きだ。かつては Vim like なキーバインドをもたらしてくれる Firefox 向けの Vimperator を愛用していたが、その開発停止後は Chromium 拡張機能の「cVim」を Vivaldi 上で長らく使っていた。しかし残念ながらこちらも開発が停滞しており、先日 Chromium の仕様変更に伴い、ついに看過できない動作上の不具合が起きてしまった。</p>
<p>https://github.com/1995eaton/chromium-vim/issues/726</p>
<p><code>Hint-a-Hint</code> と呼ばれるコア機能がある。 <code>f</code> を押下するとページ内の各リンクにユニークなアルファベットが割り振られ、そのアルファベットを押下するとそのリンク先へ遷移できる（下図参照）。キーボードだけでのブラウジングを行う上で欠かせない機能なのだが、これが使えなくなってしまった。</p>
<p><a href="https://gyazo.com/5a1764e7f9dbe36f6a7a7ee77898cbb5"><img src="https://i.gyazo.com/5a1764e7f9dbe36f6a7a7ee77898cbb5.png" alt="Image from Gyazo" width="600"/></a></p>
<p>その後有志が fork で修正バージョンを公開したり、 cVim 自体の開発引き継ぎを表明する方が現れたりもしているが、先行きが不透明であるため <a href="https://github.com/brookhong/Surfingkeys">SurfingKeys</a> という別の拡張へ乗り換えることにした。</p>
<h2>SurfingKeys</h2>
<p>https://chrome.google.com/webstore/detail/surfingkeys/gfbliohnnapiefjpjlpjnehglfpaknnc</p>
<p>名前に「Vim」と入っていないためか今までノーマークだった。 cVim の開発停滞を危惧する以下の issue の中で代替候補として挙げられており、それで初めて知った。</p>
<p>https://github.com/1995eaton/chromium-vim/issues/723</p>
<p>知名度の高い代替としては <a href="https://chrome.google.com/webstore/detail/vimium/dbepggeogbaibhgnhhndojpepiihcmeb">Vimium</a> なども存在するが、自分の中でキラーとなっていた以下機能をいずれも搭載していなかった。逆に言えば、探した中では SurfingKeys がこれらの機能を唯一網羅していた。</p>
<h3>Emacs Keybind</h3>
<p>Vim じゃねーのかという話なのだが、 <code>&#x3C;input type="text"></code> なフォーム上で、 bash などで使える文字列編集のショートカットの話である。例えば <code>Ctrl-w</code> で直前の単語削除、 <code>Ctrl-a</code> で先頭までカーソル移動など。これが Vimperator にも cVim にも搭載されていて便利だったのだが、よくよく考えると Vim とは何の関係もないので、他の Vim like key bind 系の拡張には搭載されていなかった。</p>
<p>あるいはこの機能だけ他の拡張を使ってもいいのだが、それも見つからなかった。なんなら cVim からこの部分だけ抜き出して独自拡張作ろうかと思った（けど挫折した）ぐらいには依存している。</p>
<h3>JavaScript への keymap 設定</h3>
<p>任意の JavaScript 無名関数へ keymap を設定し、詰まるところブックマークレットをキーボードで呼び出すというもの。ブックマークレットというのも死語になった印象があるが、 Pocket にページを保存するときなどによく使う。</p>
<p>正直なところ、一番のコアはこれではないかという思いがある。 JavaScript を書いてそれに自在な keymap ができるのであれば、実質的にあらゆるブラウザ操作に自ら Keymap が可能ということになる。 Vimium はこのあたり「行儀がよい」という言い方でいいのか、すでに Vimium 内で搭載されている機能に対して、別の Keymap を割り当てるということしかできない。</p>
<h3>設定の外部化</h3>
<p>キーマッピングツールは自分で独自のキーマップを設定できるようになっているものが多い。 Vimperator はローカルのファイルを、 cVim は GitHub Gist の URL を指定することで、外部ファイルから設定を読めるようになっていた。これと同等のものが欲しかった。</p>
<h2>設定</h2>
<p>ということで当然ながらカスタマイズしつつ使っているのだが、そのうち目星そうなものについて書いていく。主に Vimperator や cVim に存在していた機能を再現したものが多い。</p>
<p>設定は GitHub Gist に書いたものを読み込ませる機能があり、それを活用している。 URL を指定する際には Gist の <code>raw</code> の URL を指定しなくてはならない点に注意が要る。リンクは <a href="https://gist.github.com/chroju/2118c2193fb9892d95b9686eb95189d2">こちら</a> 。</p>
<h3><code>p</code>, <code>P</code> による URL ペースト</h3>
<p>Vimp, cVim から引き継いだ機能。 <code>p</code> や <code>P</code> を押下したとき、クリップボードに URL が含まれていればその URL に遷移させる。文字列に <code>http</code> が含まれなければ検索結果を表示するようにしている。</p>
<pre><code class="language-javascript">// paste URL
mapkey('p', 'Open URL in clipboard', function() {
    Clipboard.read(function(response) {
        var markInfo = {
            scrollLeft: 0,
            scrollTop: 0
        };
        markInfo.tab = {
            tabbed: false,
            active: false
        };
        if (response.data.indexOf("http") == 0) {
            markInfo.url = "https://www.qwant.com/?r=JP&#x26;sr=ja&#x26;l=en_gb&#x26;h=0&#x26;s=1&#x26;a=1&#x26;b=0&#x26;vt=0&#x26;hc=1&#x26;smartNews=1&#x26;smartSocial=1&#x26;theme=1&#x26;i=1&#x26;donation=1&#x26;q=" + encodeURIComponent(response.data);
        } else {
            markInfo.url = response.data;
        }
        RUNTIME("openLink", markInfo)
    });
});
mapkey('P', 'Open clipboard URL in new tab', function() {
    Clipboard.read(function(response) {
        var markInfo = {
            scrollLeft: 0,
            scrollTop: 0
        };
        markInfo.tab = {
            tabbed: true,
            active: true
        };
        if (response.data.indexOf("http") == 0) {
            markInfo.url = "https://www.qwant.com/?q=" + encodeURIComponent(response.data);
        } else {
            markInfo.url = response.data;
        }
        RUNTIME("openLink", markInfo)
    });
});
</code></pre>
<h3>Quick mark</h3>
<p>もともとは Vim の mark を意識した Vimperator の機能だったと記憶している。任意の URL にアルファベット1文字（例えば amazon.co.jp に <code>a</code> ）を割り当てておいて、 <code>goa</code> で現在のタブに、 <code>gna</code> で新しいタブにその URL を開いてくれる。つまりはブックマークを素早く呼び出すものである。</p>
<p>これは実装されている方のブログがあったので、それをそのまま使わせていただいた。ただ最近はよく使うウェブサービスを全部 <a href="https://getstation.com/">Station</a> に載せるようにしているため、ブックマーク的によく行くページというのが GitHub ぐらいしかない状況にはなっていると今回改めて気付いた（ GitHub は複数のページを同時に開きたい場合が多く、1サービス1タブが基本の Station 上だと不便）。</p>
<p>https://fewlight.net/20200225/</p>
<h3>ブックマークレット</h3>
<p>以下の書き方で JavaScript の無名関数にキーをマッピングできる。</p>
<pre><code class="language-javascript">mapkey('&#x3C;Key>', '&#x3C;Description>', function(){
    // some code
});
</code></pre>
<p>登録しているものは先述の Pocket 登録のほか、 Amazon の URL から様々なクエリ文字列を削ぎ落として綺麗にするためのもの、 markdown 等特定形式での URL コピーなどいろいろ。</p>
<h3>theme</h3>
<p>ominibar と呼ばれるコマンド入力用のバーが実装されているのだが、その CSS を好きにカスタムできる。デフォルトが白いのだがダークな感じがいいな、と探していたところ、カラーテーマ Dracula にインスパイアされたものが見つかったので、使わせてもらっている。</p>
<p>https://gist.github.com/emraher/2c071182ce0f04f3c69f6680de335029</p>
<h2>機能</h2>
<p>ところでこの SurfingKeys 、恐ろしく多機能らしく全部は使いこなせていない。例えば Markdown をクリップボードに入れた状態で特定のキーを押すと HTML プレビューしてくれる機能、自動スクロールしながらページ全体のスクリーンショットを撮ってくれる機能などがあるらしい。が、そこまでは使えていなくて、 Vimperator や cVim でやっていたことが引き継げればいいかなという感覚で使っている。</p>
]]></description>
            <link>https://chroju.dev/blog/surfing_keys_alternative_to_vimperator</link>
            <guid isPermaLink="false">surfing_keys_alternative_to_vimperator</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 13 Mar 2020 00:25:32 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[EKS 学び始めに使った資料のまとめ]]></title>
            <description><![CDATA[<p>EKS を今年はじめぐらいから調べて使い始めているのだが、それにあたって参考にした資料群を一度まとめておく。</p>
<h2>EKS 全体</h2>
<ul>
<li><a href="https://eksworkshop.com/">Amazon EKS Workshop :: Amazon EKS Workshop</a></li>
<li><a href="https://speakerdeck.com/mumoshu/eksbesutopurakuteisu2019-dot-2-number-jawsdays">Kubernetes on AWS/EKSベストプラクティス2019.2 #jawsdays - Speaker Deck</a></li>
</ul>
<p>AWS がオフィシャルで提供する Workshop がハンズオンしながら学べてわかりやすい。ドキュメントを脇に携えつつ、まずはこれの「Beginner」にあるコンテンツを全部通すといい感じになれる。「Intermediate」「Advanced」の内容は人によって要不要が分かれるので、各項で何が学べるのか調べつつ、不要であれば飛ばしてもいいかもしれない。</p>
<p>2つ目に挙げている mumoshu 氏の資料が情報量多くてすごい。EKS を使う上で考えなくてはならない点がかなり網羅されている。この資料を読んで、「何言ってるかわからない」と感じるページが無くなるように学習を進めたりしていた。ただし1年前のものなので、一部内容が古くなっている点は注意。</p>
<h2>EKS on Fargate</h2>
<ul>
<li><a href="https://qiita.com/mumoshu/items/c9dea2d82a402b4f9c31">入門 EKS on Fargate - Qiita</a></li>
<li><a href="https://blog.inductor.me/entry/eks-for-fargate">EKS for Fargateが出たので社内でファーストインプレッションの情報シェア会をやりました - inductor's blog</a></li>
<li><a href="https://amsy810.hateblo.jp/entry/2019/12/04/151642">EKS on Fargate：virtual-kubelet の違い + Network/LB 周りの調査 - @amsy810's Blog</a></li>
</ul>
<p>ちょうど Fargate が EKS 対応してすぐの時期にあたり、 Fargate を採用するべきか、採用するのであればどのような場面で採用するべきかを考えた。 Fargate って Fargate 以前の EKS と比べてどうなの？という点については前者2つの URL が参考になった。最後のエントリーは Fargate とは何者なのか？ということを知る上で勉強になるのだが、まだ半分ぐらい理解できていない自覚がある。</p>
<h2>EKS 特有の観点</h2>
<p>Kubernetes ではなく、 EKS にしか存在しない特有の観点というものがいくつかある。</p>
<h3>IAM Roles for Service Accounts (IRSA)</h3>
<ul>
<li><a href="https://aws.amazon.com/jp/blogs/news/introducing-fine-grained-iam-roles-service-accounts/">Kubernetes サービスアカウントに対するきめ細やかな IAM ロール割り当ての紹介 | Amazon Web Services ブログ</a></li>
<li><a href="https://onsd.hatenablog.com/entry/2019/09/21/015522">IAM Roles for Service Accounts を　Terraformで手軽に体験してみる - onsd’s blog</a></li>
</ul>
<p>Kubernetes の権限管理の仕組みである Service Accounts と、 AWS の権限管理サービスである IAM を連携した仕組みが IRSA 。導入が2019年9月と比較的最近であり、資料はまだ少なめな印象がある。また IRSA 登場以前に書かれたエントリーでは、 kube2iam など別のソリューションがベストとされていることもあり、注意したい。現時点では IRSA を基本的には使えばいいと捉えている。</p>
<h3>Amazon VPC CNI Plugin</h3>
<ul>
<li><a href="https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/pod-networking.html">ポッドネットワーキング (CNI) - Amazon EKS</a></li>
<li><a href="https://github.com/aws/amazon-vpc-cni-k8s">aws/amazon-vpc-cni-k8s: Networking plugin repository for pod networking in Kubernetes using Elastic Network Interfaces on AWS</a></li>
<li><a href="https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/cni-upgrades.html">Amazon VPC CNI Plugin for Kubernetes のアップグレード - Amazon EKS</a></li>
</ul>
<p>EKS には CNI として VPC と連携するためのものがデフォルトインストールされている。あまりこれに特化して解説した資料が見つからなかったのでひたすら公式を読んでいる。 <a href="https://docs.projectcalico.org/introduction/">Calico</a> の導入方法にも触れられている。</p>
<h3>kubectl</h3>
<ul>
<li><a href="https://dev.classmethod.jp/cloud/aws/eks-update-get-token-cmd/">[アップデート]EKSを使う際にaws-iam-authenticatorが不要になりました! ｜ Developers.IO</a></li>
</ul>
<p>これも2019年5月と比較的最近のリリースで、 aws-iam-authenticator を勧めるのはすでに old な方法になっている。現状は <code>aws eks update-kubeconfig</code> を打つだけで <code>~/.kube/config</code> が更新されて kubectl が使えるようになる。シンプルで好き。</p>
<h3>監視</h3>
<ul>
<li><a href="https://www.datadoghq.com/ja/blog/eks-monitoring-datadog/">Monitoring your EKS cluster with Datadog | Datadog</a></li>
<li><a href="https://www.datadoghq.com/ja/blog/eks-cluster-metrics/">Key metrics for Amazon EKS monitoring | Datadog</a></li>
</ul>
<p>EKS 特有の監視方法やプラクティスは Datadog blog を参考とした。 Datadog はこれに限らず、システム監視について体系的にまとまった記事を量産していていつもお世話になっている。</p>
<p>Kubernetes 自体の監視については <a href="https://blog.manabusakai.com/2019/08/monitoring-kubernetes/">我々は Kubernetes の何を監視すればいいのか？ | はったりエンジニアの備忘録</a> を読んだりしたが、まだはっきり答えが出せていない。調べているとよく名前を見かける <a href="https://github.com/kubernetes-retired/heapster#heapster">kubernetes-retired/heapster</a> がすでに Deprecated になっていたり、変化も激しい。</p>
<h2>Kubernetes 全般</h2>
<h3>Google Cloud Blog</h3>
<ul>
<li><a href="https://cloud.google.com/blog/ja/products/gcp/5-principles-for-cloud-native-architecture-what-it-is-and-how-to-master-it">クラウドネイティブ アーキテクチャ、5 つの原則 | Google Cloud Blog</a></li>
<li><a href="https://cloud.google.com/blog/products/gcp/kubernetes-best-practices-mapping-external-services">Kubernetes best practices: mapping external services | Google Cloud Blog</a></li>
<li><a href="https://cloud.google.com/blog/products/gcp/kubernetes-best-practices-organizing-with-namespaces">Kubernetes best practices: Organizing with Namespaces | Google Cloud Blog</a></li>
</ul>
<p>Kubernetes 自体のプラクティスについては、やはり Google のほうが豊富に資料を用意している。特に <a href="https://cloud.google.com/blog/topics/kubernetes-best-practices">Kubernets best practices</a> の各記事は一読しておいて損はなさそう。どう使えばいいのか迷ったらここを読む感じにしていた。</p>
<h3>書籍</h3>
<ul>
<li><a href="https://learning.oreilly.com/library/view/cloud-native-devops/9781492040750/">Cloud Native DevOps with Kubernetes</a></li>
<li><a href="https://learning.oreilly.com/library/view/kubernetes-best-practices/9781492056461/">Kubernetes Best Practices</a></li>
<li><a href="https://learning.oreilly.com/library/view/kubernetes-in-action/9781617293726/">Kubernetes in Action</a></li>
<li><a href="https://learning.oreilly.com/library/view/kubernetes-up-and/9781492046523/">Kubernetes: Up and Running, 2nd Edition</a></li>
</ul>
<p>いずれも <a href="https://www.oreilly.com/online-learning/">O'Reilly online learning</a> で読んでいる。全部通読したわけではなくて、何か調べたいことがあったときに逐次辞書のように引いている。特に1番目の『Cloud Native 〜』は Kubernetes の初歩から始まり、 Kubernetes cluster をどのように運用していくのか、カオスエンジニアリングやシークレット管理の話、デプロイまわりなどかなり幅広くまとまっていておすすめ。1つのベンダーにとらわれることなく、各種 OSS や SaaS に少しずつ触れているので、cluster 運用に活用するツールの比較検討を進める端緒として使いやすい。最近日本語版も出ている。</p>
<p>https://www.oreilly.co.jp//books/9784873119014/</p>
<p>あとデプロイ（CI/CD）まわりもいろいろ読んだと思うのだけど、どれを読んだかちょっと思い出せなくなってしまった。</p>
]]></description>
            <link>https://chroju.dev/blog/eks_first_step</link>
            <guid isPermaLink="false">eks_first_step</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 01 Mar 2020 04:15:17 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[AWS Organization 等、マルチアカウント管理サービスをどう使うか]]></title>
            <description><![CDATA[<p>https://qiita.com/chroju/items/ddf6266b704fe26b5d7c</p>
<p>昨年末に Qiita のほうでこのようなエントリーを出した。このときは Organizations には触れていなかったのだが、その後年明けから Organizations はじめ「マルチアカウント管理のためのサービス」に触れてきたので、改めてまとめたい次第。</p>
<p>率直に言ってマルチアカウント管理のためのサービスは多すぎると感じている。 Organizations が代表的だが、その他にも Control Tower が近年出てきたり、 AWS SSO は使えるのかどうなのかとか。あとはサービスによってマルチアカウント制御の仕組みを独自で持っているものもあったりする。そんな中で何をどう使えばいいかがまったくもってわからんので、一旦自分なりの考えをまとめておく。あくまで自分なりの答えなのでベストプラクティスなどと呼ぶつもりはないが、一つの指針として参考になったらよいなと考えている。</p>
<p>なお、本記事は2020年2月時点の情報に基づく。1年も経てば状況はまたガラリと変わっているだろう。現時点で「マルチアカウント管理のためのサービス」としては、以下のものがある、という状態である。</p>
<ul>
<li>AWS Organizations</li>
<li>Control Tower</li>
<li>AWS Single Sign-On</li>
<li>CloudFormation StackSets</li>
</ul>
<p>だいぶ長いしまとまっていないので、時間がなければ最後までスクロールして Conclusion を見たほうがはやい。</p>
<h2>マルチアカウント管理とはつまるところ何がしたいのか</h2>
<p>そもそも「マルチアカウント管理」とは具体的に何を欲しているのか。自分の場合、まとめると以下4点になる。</p>
<ul>
<li>権限管理 : IAM User を個別に作ると面倒なのでログイン管理を集約したい</li>
<li>設定管理 : 各アカウントの基本的な設定は一括で統一的に適用したい</li>
<li>監査 : マルチアカウントの利用状況を効率的に監査してガバナンスを効かせたい</li>
<li>集約化 : ログなどをアカウントごとに蓄積すると閲覧しづらいので集約管理したい</li>
</ul>
<p>混乱が生じやすいのは、これらの目的を魔法のように解決してくれるサービスがあるわけではない点だろう。まぁ「それはそうだろ」という話でもあるのだが、それにしてもマルチアカウント管理のサービスが Organization 1つに統一されているわけでもなく、各種サービスでできることが重なっていたり微妙に違っていたりもする中、様々組み合わせなければ「やりたいこと」が実現できないので見通しづらい。</p>
<p>以下では、これら目的視点で各サービスを見ていく。</p>
<h2>AWS Organizations はほぼ必須</h2>
<p>https://aws.amazon.com/jp/organizations/</p>
<p>Organizations はどんな場合であれ、マルチアカウントを使うのであれば有効化してよい。というのはコストメリットが大きくなるため。1つには Reserved Instance を複数アカウントで共有する機能を利用できるようになるので、柔軟な RI 購入が実現できるようになる。もう1つは「<a href="https://docs.aws.amazon.com/ja_jp/awsaccountbilling/latest/aboutv2/useconsolidatedbilling-discounts.html">ボリューム割引</a>」の考え方があり、複数アカウントを Organizations で一括請求にまとめることで、価格が低くなる可能性が高まる。</p>
<p>また、この後で触れていくが、一部サービスについては Organizations を活用して管理を効率化できるものがある。そのため「何はなくてもとりあえず Organizations に契約アカウントはまとめておく」ようにすると、恩恵を受けられる機会は多くなる。  Organizations には、実行可能な API をアカウント単位で制御する SCP といった機能などもあるが、こういった付随機能がよくわからなくても、極論とりあえず Organizations を有効化しておくだけでもいい。</p>
<h2>Control Tower を使う場面はかなり限られる</h2>
<p>https://aws.amazon.com/jp/controltower/</p>
<p>Control Tower はそもそも何者なのかすごくわかりにくいのだが、以下の機能を持つ Organizations のメタ管理サービスみたいなものと捉えている。</p>
<ul>
<li>Landing Zone</li>
<li>Account Factory</li>
<li>ガードレール</li>
<li>SSO</li>
</ul>
<p>Landing Zone とは AWS が提唱するマルチアカウント構成のベストプラクティスを指す。以下のページに構成図が載っているので、あわせて見てもらうとわかりやすいのだが、つまるところ監査専用アカウント、ログ集約専用アカウントを設けて、それらの間を AWS SSO を使って行き来するというようなものである。 Control Tower はボタン1つでこの構成を用意してくれるというものだ。</p>
<p>https://aws.amazon.com/solutions/aws-landing-zone/</p>
<p>自動でいい感じにやってくれるなら最高じゃないか、と思いたくなるところなのだが、曲者なのがこれに付随する Account Factory という機能である。 Landing Zone で生成されたログ集約用アカウントや監査用アカウントで管理してくれるのは、この Account Factory を使って新規作成したアカウントに限られる。したがってすでに Organizations を利用済みだったり、 AWS アカウントを準備している場合に、それを Landing Zone へ組み込むということができない。そのため Control Tower を有効活用できるのは、これから AWS を使い始るような場合に限られる。</p>
<p>なお、ガードレールは Config Rules 等を使って Landing Zone 内の各アカウントを監査する機能であり、 SSO は先に言及した通りである。これらも自動的にセットアップしてくれるのだが、 Account Factory で作成していないアカウントはやはり制御下に追加できない。今後このあたり改善されないだろうかと期待している。</p>
<h2>SSO vs switch role</h2>
<p>権限管理については IAM User と switch role の仕組みを使うか、 AWS SSO を使うかの2択だろう。 switch role は、あるアカウントの IAM User から別アカウントの IAM role へ権限の切り替えを行う方法で、詳しくは <a href="https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_use_switch-role-console.html">ロールの切り替え (コンソール) - AWS Identity and Access Management</a> に掲載されている。 AWS SSO は読んで字の如く、マルチアカウントでシングルサインオンを実現するサービスである。</p>
<p>基本的には Active Directory (AD) をすでに有している、あるいはその管理を厭わないのであれば SSO を使えばよいし、そうでなければ switch role という考え方をしている。 AWS SSO は非常に便利な機能ではあるのだが、ID ソースとして利用できるのが AD か SSO 自身の ID ストアのいずれかに限られている。そして後者は API が存在せず、 GUI 上で管理しなくてはならないので手間が大きい。そのため AD ほぼ一択という状況なのである。</p>
<p>switch role であれば単なる IAM の活用に過ぎないので、 Terraform 等を利用した管理が実現できる。マルチアカウントの ID 管理を Terraform に落とし込むのは若干面倒ではあるものの、一度セットアップしてしまえば難しくはない。エムスリーさんのブログに非常にわかりやすくまとめられていたので貼っておく。</p>
<iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fwww.m3tech.blog%2Fentry%2Fterraform_across_aws_accounts" style="border: 0; width: 100%; height: 190px;" allowfullscreen scrolling="no"></iframe>
<p>ちなみに、 AWS はサードパーティの SAML IdP にも対応しているので、 G Suite などを持っているのであれば、それを活用するのも手である。</p>
<h2>設定管理の集約化における銀の弾丸はない</h2>
<p>マルチアカウントを管理していると、各アカウントで設定を揃えたい部分が出てくる。例えばよく使う IAM Policy を全アカウント作っておきたいとか、そういうもの。これに関しては残念ながら万能な解決策は今のところ存在しない。</p>
<p>https://aws.amazon.com/jp/blogs/news/new-use-aws-cloudformation-stacksets-for-multiple-accounts-in-an-aws-organization/</p>
<p>最も「万能な解決策」に近いのが CloudFormation StackSets だろう。もともとマルチアカウントに設定展開する機能を持っていた StackSets だが、先日 Organizations と連携して、新たに Organization へ追加されたアカウントへ自動展開が可能になった。アカウント作成時の初期設定をこれに全部任せてしまえるわけである。</p>
<p>しかし API の公開がまだなので、 StackSets for Organizations の設定は手作業となってしまう。まぁ、そこにこだわらなければこれが万能解に近い。すべて完全なコード化を行いたいのであれば、 Terraform を先のマルチアカウント展開させる方式で活用することになる。個人的には現時点ではこっちを選んでいる。</p>
<h3>Organizations による一括設定</h3>
<p><a href="https://gyazo.com/bb36385c76a16531b3e764ef6930efdc"><img src="https://i.gyazo.com/bb36385c76a16531b3e764ef6930efdc.png" alt="Image from Gyazo" width="600"/></a></p>
<p>Organizations には「信頼されたアクセス」と呼ばれる機能がある。この画像のようにサービスごとに「アクセスの有効化」ボタンが用意されており、これを押すことで有効となる機能だ。</p>
<p>これは何なのかという話だが、サービスごとに意味するところが異なるので、それぞれ調べて使う必要がある。そして一部サービスについては（具体的には CloudTrail）、これを有効化することで Organization 内の全アカウントで機能を有効化することができる。一方、例えば Config は全アカウントの状況を集約したダッシュボードを作れるようになるだけであり、機能の有効化までは賄われていない。</p>
<p>これもまた直感に反しているというか、わかりにくいなと思う機能の1つではある。</p>
<h2>自動監査系のサービスはお好みで</h2>
<p>各種ログであったり、 AWS の使用状況であったりを AWS が自動的に監査してセキュリティ上の懸念を通知してくれるというサービスは様々ある。 GuardDuty, Config Rules, Amazon Detective, Security Hub などなどが該当するだろう。これらもマルチアカウント集約が可能であったりはする。</p>
<p>しかし何分サービスの数も多いので、とにかく全部使っておけばよいというものでもなくなってきている。もちろん「やるべきか否か」で言えば「やるべき」になるのだろうが、監査をすべて有効化したところで、その通知をさばいて対処するのは人間である。結局通知がさばけないのであれば通知だけされても意味はない。セキュリティ上、何を優先的に確認しなければならないのか、チームなり会社なりで方針を決めた上で活用していかなくてはならない。</p>
<p>各種監査系サービスのマルチアカウント管理について、調べた範囲で対応状況を記載しておく。</p>
<h3>AWS Config</h3>
<ul>
<li>Config Aggregater という集約機能がある</li>
<li>Organization 内のアカウントからデータ集約させることができる</li>
</ul>
<h3>Amazon GuardDuty</h3>
<ul>
<li>Organization には連携しない</li>
<li>マスターアカウントとして任意のアカウントを決めて、そのアカウントから集約したいアカウントを「招待」する形で集約化できる</li>
</ul>
<h3>AWS Security Hub</h3>
<ul>
<li>GuardDuty と同様</li>
</ul>
<h3>Amazon Detective</h3>
<ul>
<li>GuardDuty と同様</li>
</ul>
<p>まぁ、正直全部 Organizations と連動してほしい。</p>
<h2>Conclusion</h2>
<p>何もまとまらないのだが、あえてまとめるとこんな感じかと。</p>
<ul>
<li>Organizations をまず有効化して、 Organizations を基軸に集約化を考える</li>
<li>Control Tower, SSO は最悪一旦無視してもいい</li>
<li>Infrastructure as Code 過激派じゃなければ CFn StackSets は便利</li>
<li>マルチアカウントを一括設定する Terraform の使い方は習熟しておくとよい</li>
<li>監査、管理系の各サービスは、個別にマルチアカウント管理の方法が異なるのでそれぞれ調べる必要がある</li>
</ul>
<p>僕としては Organizations を中心に、もう少しシュッとした感じになってくれることを期待している。</p>
]]></description>
            <link>https://chroju.dev/blog/aws_control_tower_and_organization</link>
            <guid isPermaLink="false">aws_control_tower_and_organization</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 29 Feb 2020 05:10:31 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[読書用に Likebook Ares という電子ペーパー Android を買った]]></title>
            <description><![CDATA[<p><a href="https://gyazo.com/b7b9be7e703967341570e53d210877eb"><img src="https://i.gyazo.com/b7b9be7e703967341570e53d210877eb.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>読書するときはカラーの画面ではなくて刺激が少ない電子ペーパーを使いたい派なので、もっぱら Kindle Paperwhite を使っていた。この端末には概ね満足していたのだが、残念ながら弱点がないわけではない。「お前は一体何を言っているんだ」と思われそう（実際言われた）が、まず Kindle 以外の電子書籍は読めない。DRMフリーの電子書籍ファイルなら読むことも可能だが、ファイルを Kindle へ送るにはメールに添付して送信するという旧態依然とした手段を取る必要がある。また Software Design のような図表の多い PDF だと、ページめくりの速度がかなり重く、実用には適さなかった。</p>
<p>つまるところ Kindle に限らずあらゆる電子書籍を電子ペーパーで読みたいのである。ということを数年来ぼんやりと考えてはいたのだが、この何年かで Android を積んだ電子ペーパーの類がいくつか出ているということを最近知った。そして検討の結果 <a href="https://www.amazon.co.jp/dp/B081WT1T1W?tag=diary081213-22">Likebook Ares</a> という端末を購入してみた。</p>
<h2>電子ペーパー Android の選択肢</h2>
<p>言うまでもないのだがニッチ分野であり、選択肢は多くない。見たところ僕が買った Boyue というメーカーの Likebook というシリーズと、もうひとつ Onyx の BOOX というシリーズのほぼ二択に絞られる。いずれも中国のメーカーで時代を感じる。</p>
<p>正直性能面での違いはカタログ上だとあまり感じなかった。 Likebook を買ったのは値段が数千円安かったというただそれだけの理由である。 BOOX に利があるとすれば、東京都内のビックカメラであれば現物展示している店舗がいくつかあるので、実際に触って買えることだろうか。ビックカメラの在庫検索で確認ができる。</p>
<h2>Likebook Ares vs Kindle Paperwhite</h2>
<p>実のところ1日しかまだ触っていないのだが、その上で率直なところ Kindle はよく出来ていると感じた。</p>
<p><a href="https://gyazo.com/5b8b3e236aa4fc5c52549afa1f433279"><img src="https://i.gyazo.com/5b8b3e236aa4fc5c52549afa1f433279.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>※ 写っている本文は『<a href="https://www.amazon.co.jp/dp/B07NN9ZK4L/?tag=diary081213-22">ビット・プレイヤー</a>』（グレッグ・イーガン, 山岸真 訳, 早川書房, 2019）</p>
<p>だいたい同じ大きさのフォントで Likebook と Kindle Paperwhite 双方を表示して並べてみると、明らかに Kindle のほうが読みやすい。とはいえこれは Likebook が悪いというわけでもない。僕がかなり小さなフォントで読むのが好きだという関係上、いずれもフォントサイズは最小にしている。すると当然の如く字は掠れやすくなってしまうのだが、 Kidnle にはフォントの「太さ」を調節する昨日があるため、小さくてもくっきりとした文字で読みやすくなるという次第。 Likebook では Kindle の Android アプリで表示しているわけだが、このアプリでは太さ調節はできないので、どうしても見やすさには限界がある。</p>
<p>Kindle Paperwhite はきちんと読書用にチューニングされた端末なのだ、というのがこれで初めて理解できた。 Android の読書アプリはカラー画面での表示を前提に作られているから、電子ペーパーでは読みづらい可能性があるというのを受け入れなくてはならない。 Android 電子ペーパーならどんなアプリでも読めてウハウハじゃん、というわけでもなかったのだ。</p>
<p><a href="https://gyazo.com/6668cfa439c4e8fe24b9426d0993e7af"><img src="https://i.gyazo.com/6668cfa439c4e8fe24b9426d0993e7af.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>ちなみに英語はわりと Likebook でも読みやすい。これは O'Reilly Online Learning のアプリで『<a href="https://learning.oreilly.com/library/view/cloud-native-devops/9781492040750/">Cloud Native Devops with Kubernetes</a>』(Justin Domingus, John Arundel, O'Reilly Media Inc., 2019) を読んでみたところだが、日本語ほど線が細い印象はない。単純に自体の問題だとは思う。</p>
<h2>Pros</h2>
<p>とはいえ使い物にならないというレベルではないし、明らかな利点も多い。</p>
<h3>電子書籍アプリは概ね問題なく動く</h3>
<p>Kindle と O'Reilly のほかに Google Play Books も試したが、いずれも概ね問題なく動く。ということで「あらゆる電子書籍を電子ペーパーで読みたい」という願いは達成できそう。</p>
<p>「概ね」と言っているのは、挙動の面でもやはり Kindle のほうがストレスレスに感じることも少なくないため。PDF で動作が重いということもなく、 Likebook のほうが全体的にするするとは動くのだが、なぜかストレスがたまにある。これはなんかもう言語化できない感覚的なものであって、慣れれば気にならなくなるとは思っている。</p>
<h3>端子が USB Type-C</h3>
<p>Kindle Paperwhite は2018年発売の最新モデルでも microUSB で、日常的に使うガジェットではほぼこいつだけ microUSB で少しだけ困っている。その点 Likebook は Type-C である。</p>
<h3>SD カードに対応している</h3>
<p>つまり容量の拡張ができる。まぁ Kindle Paperwhite でも容量に困ったことはないのだけど、拡張可能であるに越したことはない。</p>
<h2>Cons</h2>
<p>先のフォントの問題以外で感じるのは以下あたり。</p>
<h3>文字入力の精度が悪い</h3>
<p>デフォルトで Android キーボードという QWERTY のタッチキーボードが使えるのだが、精度がよろしくない。通常の状態と、数字や記号が入力できる状態を切り替えて使うことがよくあるが、切替ボタンを押した際のタッチ判定が切替後まで残ってしまって、切替後のボタンが誤タッチされてしまう。</p>
<p>Google 日本語入力のような他のキーボードが入れられるのかはまだ試していないが、タッチ判定の問題とすればハードウェアの問題なので、改善はしないだろうと予想している。</p>
<h3>アプリの切り替えは遅い</h3>
<p>ひとつのアプリを使っている分には、動作速度は Kindle Paperwhite と同等か、多少速いかなぐらい。しかしアプリの切り替えは遅い。起動も遅い。メモリが足りていない感覚がある。</p>
<h2>総評</h2>
<p>概ね悪くない。が、文字掠れの問題で嫌気が差したら Kindle Paperwhite に戻るかもしれない。とりあえずしばらくは使ってみたい。</p>
<p>この「文字掠れ問題」は BOOX など他の端末に移行したところで解消は難しそうなので、結局のところ Kindle でもっと簡単に epub 読めるようになるのが最善の道だろうということがわかった。</p>
]]></description>
            <link>https://chroju.dev/blog/likebook_ares_e_ink_android_review</link>
            <guid isPermaLink="false">likebook_ares_e_ink_android_review</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 22 Feb 2020 09:58:45 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[AWS Lambda による Web Scraping プラクティス in 2020]]></title>
            <description><![CDATA[<p>久しぶりに AWS Lambda 上でスクレイピング処理を実装しようとしたところ、 PhantomJS 開発終了以来あんまりスクレイピングしていなかったこともあり、勝手がまったくわからなくなっており、いろいろ調べたので書いておく。</p>
<p>なお、あくまでデータ取得のための簡単なスクレイピングであり、 E2E テストのような複雑なシナリオが想定される用途でも適用可能なプラクティスではないと思われる。また筆者が使いたい言語は第一に Go で第二が Python である。</p>
<h2>スクレイピング用ライブラリは主に2種類</h2>
<p>スクレイピングに活用できるライブラリは各言語様々あると思われるが、ざっくり2種類に大別できると考えている。</p>
<ul>
<li>直接 HTTP アクセスするライブラリ</li>
<li>Headless ブラウザを使うライブラリ</li>
</ul>
<p>外部のツールに依存せず、ライブラリの機能だけで HTTP アクセスや DOM の解析を行うものが前者。そのライブラリさえ import すれば使うことができるので、基本的にはこの手のものを使うほうが楽だと思われる。ただしブラウザの機能を再現しているわけではなく、生の HTML をそのままダウンロードするだけなので、凝ったことはできない可能性がある。</p>
<p>凝ったこととはなんぞと言えば、例えばブラウザ表示した画面のスクリーンショットを撮りたい、 JS で動的に DOM 生成されるページをうんにゃらしたい、といった場合がある。こういった用途では Headless ブラウザを使うことになる。</p>
<h2>直接 HTTP アクセスするライブラリ</h2>
<p>個人的には <a href="https://github.com/PuerkitoBio/goquery">PuerkitoBio/goquery</a> を使うことが多い。 README から例を抜粋するが、 CSS クラスタの記法で取得する要素を指定できるのが好き。</p>
<pre><code class="language-go">  // Find the review items
  doc.Find(".sidebar-reviews article .content-block").Each(func(i int, s *goquery.Selection) {
    // For each item found, get the band and title
    band := s.Find("a").Text()
    title := s.Find("i").Text()
    fmt.Printf("Review %d: %s - %s\n", i, band, title)
  })
</code></pre>
<p>ライブラリを import すればいいだけなので、ビルドなども特別なことはない。</p>
<h2>Headless ブラウザを使うライブラリ</h2>
<p>Headless ブラウザを操作するフレームワークとしては <a href="https://selenium.dev/">Selenium</a> が有名。各種メジャーな言語で実装があるのだが、残念ながら Go に対応した公式のパッケージは提供されていない。そのため Python で使うことにしている。</p>
<p>Selenium を使うときはライブラリのインポートだけではなく、実際にウェブアクセスするための Headless ブラウザと、 Selenium がブラウザ操作するための <a href="https://www.w3.org/TR/webdriver/">WebDriver</a> も Lambda のデプロイパッケージに含める必要がある。</p>
<h3>Headless ブラウザと WebDriver</h3>
<p>Headless Chrome を使いたいところなのだが、そのまま AWS Lambda のランタイム上で使えるわけではない。各種 FaaS ランタイム向けに Headless Chromium をビルドした serverless-chrome というプロジェクトがあるので、これを使わせてもらう。</p>
<p>https://github.com/adieuadieu/serverless-chrome</p>
<p>WebDriver には Chrome (Chromium) 向けの ChromeDriver を <a href="https://chromedriver.chromium.org/downloads">Downloads - ChromeDriver - WebDriver for Chrome</a> からダウンロードして使う。</p>
<p>注意しなければならないのは、 Selenium, serverless-chrome, ChromeDriver の三者で compatible な version の組み合わせが決まっているということ。任意のバージョンを好きに組み合わせて動くわけではない。現状 serverless-chrome のドキュメントがこれをアップデートしきれていないようで、以下の issue に有志が稼働確認した組み合わせを書き込んでいるのが見受けられるので参考にしている。</p>
<p>https://github.com/adieuadieu/serverless-chrome/issues/133</p>
<p>本記事執筆時点において、最新の serverless-chrome を使った Selenium for Python との compatible な組み合わせが検証済みになっていない。そのため新し目の API が使えない、ということがしばしばある。例えば自分が経験したものとしては、 <code>element.screenshot_as_png()</code> が利用できず、要素単位でのスクリーンショットが取得できなかった。代替策として、 <a href="https://github.com/SeleniumHQ/selenium/issues/2898">Can't get the screenshot of the current element · Issue #2898 · SeleniumHQ/selenium</a> に記載のある、要素の座標から PIL でページスクリーンショットを切り取る方式を使っている。</p>
<h3>Lambda layer を使った Headless ブラウザ等のデプロイ</h3>
<p>Lambda にはデプロイパッケージサイズに 50 MB の制限があるので、 Headless ブラウザと chromedriver は Lambda layer を用いてデプロイし、 Function 本体のデプロイパッケージから分離する。</p>
<p>Lambda layer にデプロイしたファイルは、 Lambda 実行時に <code>/opt</code> 配下に展開されるので、それに合わせて Selenium からパスを指定して読み込む。自分の場合は以下の Makefile で Lambda layer 向けの zip パッケージを作成しているが、この場合は <code>/opt/bin</code> 配下に <code>chromedriver</code> と <code>chromium</code> が配置されることになる。</p>
<pre><code class="language-make">layer_headless_chrome/bin:
	mkdir -p layer_headless_chrome/bin

layer_headless_chrome/bin/headless-chromium: layer_headless_chrome/bin
	wget https://github.com/adieuadieu/serverless-chrome/releases/download/v1.0.0-37/stable-headless-chromium-amazonlinux-2017-03.zip -O chromium.zip
	unzip chromium.zip
	mv headless-chromium layer_headless_chrome/bin/
	rm chromium.zip

layer_headless_chrome/bin/chromedriver: layer_headless_chrome/bin
	wget https://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip -O chromedriver.zip
	unzip chromedriver.zip
	mv chromedriver layer_headless_chrome/bin/
	rm chromedriver.zip
</code></pre>
<p>Selenium を使うときは、割愛した書き方をするとこういう感じ。</p>
<pre><code class="language-python">from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.binary_location = "/opt/bin/chromium"
driver = webdriver.Chrome(chrome_options=options, executable_path="/opt/bin/chromedriver")
</code></pre>
<h3>日本語フォントの内包</h3>
<p>特にスクリーンショットを撮りたい場合、 Lambda のランタイムには日本語フォントが存在しないため、デプロイパッケージに含めてやらなければ文字化けする。</p>
<p>これはそう面倒な問題でもなく、通常 Linux では <code>$HOME/.fonts</code> にフォントファイルを置けば読んでくれるので、デプロイパッケージを zip するときに <code>.fonts</code> 配下へ使いたいフォントファイルを置いておけばよい。僕は IPA フォントを使っているので、 Makefile だとこういう感じ。</p>
<pre><code class="language-make">.fonts:
	mkdir .fonts

.fonts/ipaexg.ttf .fonts/ipaexm.ttf: .fonts
	curl https://ipafont.ipa.go.jp/IPAexfont/IPAexfont00401.zip -o IPAexfont.zip
	unzip IPAexfont.zip
	mv ./IPAexfont00401/*.ttf ./.fonts/
	rm -rf ./IPAexfont00401
	rm IPAexfont.zip
</code></pre>
<h3>Serverless Framework によるデプロイ</h3>
<p>Lambda layer と Function を個別にデプロイするのは面倒なので、 Serverless Framework を遣う。先に書いた Makefile の例に倣い、 <code>./layer_headless_chrome</code> 配下に Headless ブラウザと chromedriver が置かれているものとして、以下のようなサンプルになる。</p>
<pre><code class="language-yaml">functions:
  sample_function:
    handler: sample_function.lambda_handler
    layers:
        - { Ref: HeadlessChromeLambdaLayer }
    role: LambdaBasicExecution
    package:
      include:
        - '.fonts/**'

layers:
  headlessChrome:
	path: layer_headless_chrome
</code></pre>
]]></description>
            <link>https://chroju.dev/blog/web_scraping_with_aws_lambda_2020</link>
            <guid isPermaLink="false">web_scraping_with_aws_lambda_2020</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 01 Feb 2020 05:24:52 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[SRE NEXT 2020 に行ってきた]]></title>
            <description><![CDATA[<p>https://sre-next.dev</p>
<p>SRE NEXT 2020 に行ってきた。</p>
<p>SRE という職種が国内で広まったきっかけは <a href="https://tech.mercari.com/entry/2015/11/18/153421">インフラチーム改め Site Reliability Engineering (SRE) チームになりました - Mercari Engineering Blog</a> のエントリーだと思っているのだけど、ここから4年と少し。東京とはいえ、 SRE をテーマにカンファレンスが開催される規模になってきたというのはちょっとした驚きもある。実際来場者が何人だったのかは把握していないが、使われていた4つの部屋に入り切らないのではというぐらいの人がいて、実際に SRE をやっている、あるいは社内に SRE チームがあるという人は半数ぐらいだったらしい。</p>
<p>発表はいずれもかなり具体的なものが多く、 SRE 本はみんな読んでいるよね？という前提の上で、あの本をこう解釈して、うちではこうやって運用しているよ、という話が多かった。最後のパネルディスカッションでも「SRE を始めるにあたり、どんなスキルがあればよいか？」というような質問があったのだが、 SRE を定義づけるのはスキルではなくてミッションなのだと思う。デプロイ頻度を上げたとき、トレードオフで劣化してしまいがちな「サイト信頼性」をどう担保するか。そのミッションに共感して携わってさえいれば SRE だと言える。むしろ特定のツールやスキルに固執して、ミッションが曖昧な状態だと SRE とは言い難い。</p>
<p>とはいえもちろんツールだとか、どのような資料を参考にしているのかも気になるところで、各社が実際の運用で使っている OSS やドキュメント類の話も非常に参考になった。具体的に気になったのは以下。各項目末尾の括弧は、その資料やツールの話が出てきたセッションナンバー。</p>
<ul>
<li><a href="https://www.sciencedirect.com/science/article/pii/0005109883900468">Ironies of automation - ScienceDirect</a> (A0)</li>
<li><a href="https://www.researchgate.net/publication/231537926_The_ironies_of_automation_still_going_strong_at_30">The ironies of automation… still going strong at 30? | Request PDF</a> (A0)</li>
<li><a href="https://ja.coursera.org/learn/site-reliability-engineering-slos">Site Reliability Engineering: Measuring and Managing Reliability | Coursera</a> (C4)</li>
<li><a href="https://docs.datadoghq.com/ja/monitors/service_level_objectives/event/">Event based SLO</a> / <a href="https://docs.datadoghq.com/ja/monitors/service_level_objectives/monitor/">Monitor SLO</a> (C4)</li>
<li><a href="https://github.com/argoproj/argo-rollouts">argoproj/argo-rollouts: Progressive Delivery for Kubernetes</a> (D5)</li>
<li>Production Readiness Check by Production-ready Microservices (B7)</li>
</ul>
<p>ここからは特に印象に残ったセッションを掲載する。すべて載せられればよかったのだが、結構な分量になりそうなので掻い摘んでみる。</p>
<h2>分散アプリケーションの信頼性観測技術に関する研究</h2>
<div style="left: 0; width: 100%; height: 0; position: relative; padding-bottom: 56.1972%;"><iframe src="https://speakerdeck.com/player/058b950f8955432f8263496498a0390a" style="border: 0; top: 0; left: 0; width: 100%; height: 100%; position: absolute;" allowfullscreen scrolling="no" allow="encrypted-media"></iframe></div>
<p>基調講演その1。</p>
<p>多くの SRE は基本的には既存の技術を用いてサイト信頼性の向上に貢献するけれど、より低いレイヤーからそもそも可観測性を高めるにはどうしたらいいか、レイテンシを狭めるにはどうしたらいいかというお話。自分はこの先このレイヤーで仕事をすることはなさそうに思っているけど興味深く聴けた。レイテンシ最小化のために、フォグコンピューティングのように小規模なデータセンターが点在する形になる、という方向性は、 <a href="https://aws.amazon.com/jp/about-aws/global-infrastructure/localzones/">AWS Local Zones</a> などですでに実現しつつもあるのだろうと思う。</p>
<h2>40000 コンテナを動かす SRE チームに至るまでの道</h2>
<p>https://techblog.yahoo.co.jp/entry/20191222793763/</p>
<p>Yahoo! のような大規模なサービス企業になると、インフラチームは Private PaaS を動かして社内の開発者へ「サービス提供」する形になる。それが 40000 のコンテナで提供されているとのこと。</p>
<p>顧客ロイヤルティの指標である Net Promoter Score を社内に対して調査しているというあたりが面白かった。他にも社外ではなくて社内に対して SLA を定義しているという話もあった。 DevOps 以来の考え方として、アプリチームとインフラチームはなるべく境界をなくすべきというのが是のように思い込んできたけど、逆に明確な境界を引いて、 AWS の責任共有モデルよろしく、両者の責任範囲を限定してしまう方式もありなのだな、というのが気付きだった。</p>
<h2>成長を続ける広告配信プラットフォームのモニタリングを改善してきた話</h2>
<div style="left: 0; width: 100%; height: 0; position: relative; padding-bottom: 56.1972%;"><iframe src="https://speakerdeck.com/player/7b9b2ed526bd4247acf0517295cdd6d1" style="border: 0; top: 0; left: 0; width: 100%; height: 100%; position: absolute;" allowfullscreen scrolling="no" allow="encrypted-media"></iframe></div>
<p>偽陽性のアラートを減らす、そのためにアラートの整理を定期的に実施するべきであるという2点と、実際に Kubernetes 環境をどのようなツールで監視しているかの話。特に Kubernetes の監視については現在目下検討中なので参考になった。 influxDB + Telegraf + Grafana （俗に言う TIG Stack ）と New Relic とのこと。</p>
<h2>delyにおける安定性とアジリティ両立に向けたアプローチ</h2>
<div style="left: 0; width: 100%; height: 0; position: relative; padding-bottom: 56.1972%;"><iframe src="https://speakerdeck.com/player/5d3d1b565ce54370a2b99b59fadd200f" style="border: 0; top: 0; left: 0; width: 100%; height: 100%; position: absolute;" allowfullscreen scrolling="no" allow="encrypted-media"></iframe></div>
<p>SRE のミッションを「プロダクト開発の速度を <strong>安全に</strong> 高める」ことと定義して、それを如何に成し遂げていくかという話。一般的にはエラーバジェットを用いることになるのだけど、実際のところはバジェットを使い切ったときに新規デプロイを中止するのは現実的ではなかったり、導入が難しい側面がある。では、他に解決するべき、プロダクト開発速度を落とす要因はないのだろうか？と改めて問い直して、コードやシステムから「想定外の複雑さ」を取り除いていこうという結論に至る。 SRE 本に掲載されたプラクティスをただ愚直に導入するのではなくて、その目的はそもそも何か、その目的を達する手段は他にないだろうか？という良い問い直しでした。</p>
<h2>SRE Practicies in Mercari Microservices</h2>
<div style="left: 0; width: 100%; height: 0; position: relative; padding-bottom: 56.1972%;"><iframe src="https://speakerdeck.com/player/1af1bddd18484d61ae524fbaf8dafc4b" style="border: 0; top: 0; left: 0; width: 100%; height: 100%; position: absolute;" allowfullscreen scrolling="no" allow="encrypted-media"></iframe></div>
<p>国内で最初期に SRE チームを発足させていたメルカリさんの SRE プラクティス。具体的な運用方法の話が出てくるので参考にしたいことだらけ。 SLO、CI/CD、On-call、Toil とテーマを分けて話をしてくれたのでとても聞きやすかった。特に SLO の振り返りの話が興味深くて、 SLO のみならず Toil の量や顧客（SRE が信頼性向上施策を提供する相手である、マイクロサービスチームのこと）満足度と絡めて評価するとのこと。例えば SLO が達成されていても、 Toil が多いし顧客満足度も低ければ、その SLO 達成にあまり意味はないということになるので、 SLO を厳しくしてみる。 SLO 達成、 Toil も少ないが、顧客満足度が低いのであれば、顧客が求める SLI は別のところにあるのではないかと考え、 SLI を変えてみる。達成 / 未達成の2択ではなく、その SLO に意味はあるのか？というところも運用を踏まえて振り返る視点は重要だと感じた。</p>
]]></description>
            <link>https://chroju.dev/blog/sre_next_2020</link>
            <guid isPermaLink="false">sre_next_2020</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 27 Jan 2020 15:21:52 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Terraform の秘匿情報を mozilla/sops で管理する]]></title>
            <description><![CDATA[<p>Terraform を使う上での長年の悩みとして、秘匿情報 (secrets) をどう扱うべきかというものがある。例えば AWS Secrets Manager への secrets の登録を Terraform で行うとして、 tf file には平文で secrets を書き記すことになってしまう。これをそのまま Git repository に commit するのは当然ながらよろしくない。</p>
<p>いろんな Terraform ユーザーに話を聞いたりしてもなかなか解決しなかったこの問題だが、ようやく決定版と言えそうな解決策として <a href="https://github.com/mozilla/sops">mozilla/sops</a> を使う方法を見つけた。</p>
<h2>SOPS</h2>
<p>https://github.com/mozilla/sops</p>
<p>Secrets OPerationS の略らしい。 YAML や JSON など Key/Value 形式の設定ファイルにおいて、 Value の箇所だけを暗号化できるコマンドラインツールである。 homebrew でインストールできる。</p>
<pre><code class="language-bash">$ brew install sops
</code></pre>
<p>暗号化にあたり、まず鍵を指定しておく必要がある。鍵は AWS KMS や GCP KMS などの各種クラウドサービスの暗号化サービスに対応していて、環境変数で使うキーを指定する。鍵がファイルだったり手入力のパスフレーズだったりすると扱いに困りがちだが、クラウドの KMS であればキーへのアクセス権を適切に管理するだけでいいので、これは嬉しいポイント。</p>
<pre><code class="language-bash">$ export SOPS_KMS_ARN='arn:aws:kms:ap-northeast-1:999999999999:key/XXXXXXXX-XXXX-XXXX-bd50-ac0ec6d03d63'
</code></pre>
<p>新しく暗号化したファイルを作る場合は、 <code>sops</code> コマンドに secret を保存するファイル名を引数として与えて実行する。</p>
<pre><code class="language-bash">$ sops secrets.yaml
</code></pre>
<p>すると、そのファイルの編集画面が <code>$EDITOR</code> で開く。ファイル名の拡張子からファイル形式が自動的に判断されて、以下のようにサンプルが表示される。</p>
<pre><code class="language-yaml">hello: Welcome to SOPS! Edit this file as you please!
example_key: example_value
# Example comment
example_array:
- example_value1
- example_value2
example_number: 1234.5679
example_booleans:
- true
- false
</code></pre>
<p>別にこのサンプルを踏襲する必要はまったくなくて、すべて消して好きなように内容は書いてよい。そしてファイルを保存したタイミングで、 value 部分に暗号化が施される。例えば以下のような YAML を書く。</p>
<pre><code class="language-yaml">db_user: user
db_password: password
</code></pre>
<p>これを保存後に <code>cat</code> してみると以下の通り。</p>
<pre><code class="language-yaml">db_user: ENC[AES256_GCM,data:vioDUg==,iv:j7O4xlHMcfb6DzY0ptSa38tkeCFKy2e8qVGwTCG3M8k=,tag:qqcothINK6OKhJb/3jvuxw==,type:str]
db_password: ENC[AES256_GCM,data:vCo7u6AggyU=,iv:3y90FXchrZfXQ7b6JGfVJABdxk5r+mIezTf9jb19VdM=,tag:3Gq5IrDeJiz46snahFn4Og==,type:str]
sops:
    kms:
    -   arn: arn:aws:kms:ap-northeast-1:999999999999:key/XXXXXXXX-XXXX-XXXX-bd50-ac0ec6d03d63
        created_at: '2020-01-17T14:04:58Z'
        enc: AQICAHgIueX8MsuSyX/hToTAJGoN2l3ZRsFfBaJMo5aNEN6CPAG4Y2Bo1oWyGA+enYwwsaa+AAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMbbKFmXXsd1DuWI/5AgEQgDt7SbVbUUD4rsLO1mNC0MdCU5kXZt0qrL/SrCIwGWLUwFO8jYlJrgZFlOY2jKL1ODMXjfvUiM6YsQOqVw==
        aws_profile: ""
    gcp_kms: []
    azure_kv: []
    lastmodified: '2020-01-18T04:48:01Z'
    mac: ENC[AES256_GCM,data:2Rf0IgpyGXJxWCtFDn7Fl1Gv4qPMN9IXuWt+w71Iu9ngFBp4URSDCSthyxbXtt8jhiTl4IgvLkv0lyYAGa/dM+l/2OcR3LeZldv4oR3cm6LjErwKD8O65Lh7Z9J+LR/TmS7E4I0lN+JhePn8qrIGjL4x3J16mD45I2dNtlAoRus=,iv:HEttY0FACDix5plof0mP4B2lkikPcKiLEVSt7dqpql0=,tag:ZZR7witKJgZS/jf5rprXeQ==,type:str]
    pgp: []
    unencrypted_suffix: _unencrypted
    version: 3.5.0
</code></pre>
<p>最初の2行の通り、確かに暗号化が施されている。 <code>sops:</code> 以下は sops が付加するメタ情報で、見ると暗号化に使ったキーの ARN が埋め込まれている。復号には <code>sops -d filename</code> コマンドを使うが、このときは環境変数ではなくてこの YAML 内の ARN の指示先が復号キーとして扱われる。なのでチームメンバー内でこのファイルを共有するのであれば、該当のキーに対するアクセス権限をそれぞれが保持さえしていれば、容易に復号することができる。 ARN が割れたところで何かクラックできるわけではないので、この状態のファイルであればパブリックレポジトリに入れても良さそうな気もするのだが、気になるのであればプライベートレポジトリで commit しておけばいい。</p>
<p>なおこのファイルに対して再度 <code>sops filename</code> コマンドを使うと、複合した状態で YAML を再編集できる。編集後は編集した箇所と、メタ情報の一部だけが書き換わるので、 <code>git diff</code> で差分を見るときもわかりやすい。</p>
<h2>terraform-provider-sops</h2>
<p>本題の sops を使った Terraform での秘匿値管理だが、残念ながら HCL を直接暗号化することには対応していない。しかし community provider として terraform-provider-sops がありがたいことに存在している。</p>
<p>https://github.com/carlpett/terraform-provider-sops</p>
<p>これは data source として、 sops で暗号化されたファイルからの値読み込みを提供してくれる provider だ。先の <code>db_user</code> と <code>db_password</code> を書き入れた <code>secrets.yaml</code> を作成した状態で、同じディレクトリに以下のような <code>sample.tf</code> を作成してみる。</p>
<pre><code class="language-hcl">provider "sops" {}

provider "aws" {
  version = "~> 2.0"
  region  = "ap-northeast-1"
}

data "sops_file" "secrets" {
  source_file = "secrets.yaml"
}

resource "aws_ssm_parameter" "sensitive" {
  for_each = data.sops_file.secrets.data
  type     = "String"
  name     = each.key
  value    = each.value
}
</code></pre>
<p>すると <code>terraform plan</code> の結果は以下の通りになる。</p>
<pre><code class="language-bash">  # aws_ssm_parameter.sensitive["db_password"] will be created
  + resource "aws_ssm_parameter" "sensitive" {
      + arn    = (known after apply)
      + id     = (known after apply)
      + key_id = (known after apply)
      + name   = "db_password"
      + type   = "String"
      + value  = (sensitive value)
    }

  # aws_ssm_parameter.sensitive["db_user"] will be created
  + resource "aws_ssm_parameter" "sensitive" {
      + arn    = (known after apply)
      + id     = (known after apply)
      + key_id = (known after apply)
      + name   = "db_user"
      + type   = "String"
      + value  = (sensitive value)
    }

Plan: 2 to add, 0 to change, 0 to destroy.
</code></pre>
<p>普段の Terraform の使い勝手とほぼ変わらず、簡単に秘匿値を取り扱うことができてこれはうれしい。普通に tf file を書き、秘匿したい値だけは YAML へ切り出して sops で暗号化し、一緒に git commit してしまえば管理は簡単そうだ。</p>
<h3>Terraform Cloud での活用</h3>
<p>sops の暗号化を AWS KMS key で行い、 aws provider を併用している場合について、Terraform Cloud 上でも正常に復号可能か試してみた。</p>
<p>結論から言えば復号できたのだが、若干動作が腑に落ちていない。 Terraform Cloud で aws provider を使う場合、 provider を以下のように記述して、 Terraform Cloud 側で API キーを <code>AWS_ACCESS_KEY</code> と <code>AWS_SECRET_KEY</code> の2変数に設定する形が一般的かと思う。</p>
<pre><code class="language-hcl">provider "aws" {
  version = "~> 2.0"
  region  = "ap-northeast-1"
  access_key = "${var.AWS_ACCESS_KEY}"
  secret_key = "${var.AWS_SECRET_KEY}"
}
</code></pre>
<p>どういうわけだが、ここで設定した API キーはあくまで aws provider でしか読み込まれない気がするのだが、そのキーに KMS の復号権限があれば、 sops の復号も動作した。設定が楽で助かるのは助かるが、どうしてこれで動くのかがよくわかっていない。気が向いたら深堀りしておきたい。</p>
<p>なお Terraform Cloud で community provider （GitHub の <a href="https://github.com/terraform-providers">Terraform Providers org</a> で管理されていない provider）を使うときは、あらかじめ Git repository 内の <code>terraform.d/plugins/linux_amd64</code> 配下に provider のバイナリを含めておく必要があり、少々面倒。このことについては <a href="https://www.terraform.io/docs/cloud/run/install-software.html#custom-and-community-providers">Installing Software in the Run Environment - Runs - Terraform Cloud - Terraform by HashiCorp</a> に記載されており、将来的にはより良い方法を提供したいとも書かれているので期待したいところ。</p>
<h2>Conclusion</h2>
<p>本当にずっと悩まされてきた課題をスマートな形で解決できてものすごいテンションが上がっている。実はもともと Kubernetes の secrets 管理の方法を調べる中で見つけたツールで、「これは Terraform にも活用できるのでは？」と調べてみたところ、なんと provider を作ってくれている人がいると気付いた、という形の出会いだった。1月から今年は幸先が良さそう。</p>
]]></description>
            <link>https://chroju.dev/blog/terraform_with_sops</link>
            <guid isPermaLink="false">terraform_with_sops</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 18 Jan 2020 04:17:06 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[プライベートにも OKR を取り入れてフォーカスする]]></title>
            <description><![CDATA[<p>前回のエントリー <a href="https://chroju.github.io/blog/2019/12/30/looking_back_2019/">2019年総括 · the world as code</a> で少し触れた「個人OKRの導入」について書く。年始だし目標の話を書くのはちょうど良さそうでもある。</p>
<h2>個人の生活と OKR</h2>
<p>OKR というのは Google が採り入れていることで名高い目標管理メソッドで、最近日本国内でもテック系企業が採用している例が増えている。改めて説明するつもりもないが、以下のような点が特徴だと捉えている。</p>
<ul>
<li>目標を完遂することは求めず、達成確度 70% 程度の定性的な目標を3〜5個掲げて運用する
<ul>
<li>目標の数を少なく絞り、フォーカスするべき領域を明確にする</li>
<li>目標は数値が入った指標などではなく、人を鼓舞するような定性的な内容にする</li>
<li>あえて達成が困難な目標を掲げることで、パフォーマンスの最大化を図る</li>
<li>その性質上、人事評価に用いるのは NG とされる</li>
</ul>
</li>
<li>各目標について、どのような状況があれば「達成した」と言えるのかを示す定量的な成果指標を3個程度設定する
<ul>
<li>目標が Objective (O) 、成果指標が Key Result (KR) と呼ばれる</li>
</ul>
</li>
<li>サイクルは四半期ごとと短く設定し、さらに1週間ごとに進捗の確認を行うことで素早く行動する</li>
</ul>
<p>基本的には組織や企業の目標管理メソッドなのだが、これをあえて個人の生活に採り入れることを昨年の第2四半期から始めた。自分が注力するべき領域をフォーカスでき、短いスパンで進捗を確認して軌道修正ができることは、個人生活においてもメリットが大きい。クリスティーナ・ウォドキーによる書籍『OKR シリコンバレー式で大胆な目標を達成する方法』（日経BP社 2018）においても、及川卓也氏の解説の中で、個人で OKR を採用するメリットについて触れられている。</p>
<blockquote>
<p>個人的なタスクが失敗しがちな理由はその優先度を上げずに時間を確保しないということだけが理由ではない。進捗が見えづらいためにモチベーションが維持できないことも、タスクを継続する阻害要因だ。（中略）タスクの優先度を明確にし、継続するためのモチベーションを維持するために、実は OKR が役に立つ。</p>
</blockquote>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B07B2R1ZDL/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/512xkUh8Y8L._SL160_.jpg" alt="OKR（オーケーアール）" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B07B2R1ZDL/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">OKR（オーケーアール）</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 20.01.13</div></div><div class="amazlet-detail">日経BP (2018-03-15)<br />売り上げランキング: 6,481<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B07B2R1ZDL/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>ちなみにこの本の原題は『RADICAL FOCUS』らしい。</p>
<h2>具体的な運用</h2>
<p>とはいえ組織向けに作られた本来の OKR を、そのまま個人生活に適用するのは難しい。金曜日に互いの成果を称え合う「ウィン・セッション」なんて一人じゃやりようがない。なのでいいとこ取りをしながら、以下のような運用をしている。</p>
<ul>
<li>四半期の最初に OKR を作成する
<ul>
<li>「O」は2つ、各「O」に「KR」は3つ設ける
<ul>
<li>「O」は技術者関係で1つ、それ以外で1つ</li>
</ul>
</li>
<li>健全性指標は2つ設ける</li>
</ul>
</li>
<li>毎週金曜日にウィン・セッションとチェックインミーティングを合わせたような振り返りを行う
<ul>
<li>その週に実行できたこと、できなかったことの振り返り</li>
<li>各 KR の達成自信度レベルの見直し</li>
<li>向こう4週間の予定確認</li>
<li>翌週に OKR に関してやるべきことの設定</li>
</ul>
</li>
</ul>
<p>ツールは紙、具体的にはコクヨの測量野帳を使っていた。先の OKR 本では毎週の状況報告をメールで行うこととしていたが、チームで運用しているわけではないのでメールである必要がない。何かデジタルのメモツールというのも考えたが、しっくりくるものがなくて紙にしていた。</p>
<h2>結果どうだったのか</h2>
<p>ぶっちゃけあんまり上手くいっていない。</p>
<h3>目標設定自体がなかなか難しい</h3>
<p>具体的な OKR の内容は本当にプライベートなものも含まれていたりするのであんまり見せたくないのだが、一例として前四半期の「O」の1つは以下のような内容だった。</p>
<ul>
<li>O: SRE として部門の半数の人に認知される成果をつくる
<ul>
<li>KR: 毎週1本ブログを書いている</li>
<li>KR: 社内全インフラ構成のコードリーディングと、インフラ構成の肝を理解する</li>
<li>KR: Terraform のコードリーディングと PR で存在感を強める</li>
</ul>
</li>
</ul>
<p>目標自体はまぁ良いと思う。今の部門に配属されて3か月経ったタイミングだったので存在感を高めたかったのが理由。半数というのは少ない感じもあるが、部門内にはエンジニア以外の人も相当数いるので妥当と考えた。</p>
<p>ただ KR については今見直すと妥当とは言い難い。ブログを書いたところで部門の人に見てもらっているわけではないし、社内の存在感とはあんまり関係がない。3つ目の KR についても同様と言えるし、2つ目については仕事の話ではあるけれど、これで認知が高まるかというと微妙じゃないだろうか。 KR は「収益を xx% 増加させる」といった定量的な指標であるべきなのだが、どうもこれが上手いものが思いつかない。</p>
<h3>継続できていない</h3>
<p>昨年は第2四半期から3回 OKR を回してみたが、いずれも最後の1か月ぐらいで失速して、毎週欠かさず振り返りを継続できなかった。</p>
<p>あんまり前に進んでいる感触が得られなかったというのが理由として大きい。しばらくいそがしくて、何週間も OKR のためのタスクを実行できなかった頃がある。すると今週は達成できませんでした、来週やります、という中身のない振り返りが何度も続くことになる。これで嫌になってやめてしまうことが少なくなかった。</p>
<h2>今年の運用</h2>
<p>うまくはいかなかったが、個人で OKR を使うことが無意味だとはあまり思っていない。自由に使える時間も限られる中で、自分が何にフォーカスするべきかを定めておく意味は大きいし、短いサイクルで振り返ることで得られるものも（振り返りが継続できなかったりはしたものの）大きいのは確かだという感触はあった。今年は少し運用を替えて継続してみる。</p>
<h3>KR は1つだけ定量的じゃなくても可とする</h3>
<p>KR に定量的じゃない目標を1つだけ入れてもいいことにした。思いつかないものをいつまでも考えても仕方ないので、まずは回しやすいルールに替えてみる。</p>
<h3>KR に行動を入れない</h3>
<p>これは OKR 本に書いてあったことなのだが、昨年は KR が思いつかない末に苦しみ紛れに入れてしまった。例えば先に挙げた「毎週1本ブログを書いている」だけど、1週でもブログを書かなかったらアウトになるので達成が難しいし、毎週の振り返りが書いたか否かのゼロイチでしかなくなるので、振り返りに意味を感じづらくなる。今年は絶対に行動を入れない。</p>
<h3>振り返りはデジタルで、毎週時間を予め確保する</h3>
<p>振り返りはデジタルに替える。端的に言ってそのほうが書くのが早くてストレスが小さく、継続しやすそうだから。また、振り返りの時間は土曜朝に近所のパン屋で15分でやることにする。その時間が空いているかどうか、前の週の振り返りの際に確認して、空いていなければ代替の時間をあらかじめ確保するようにする。</p>
<h2>参考資料</h2>
<p>OKR とは何か？については市販の本がいろいろ出ているけれど、とりあえず <a href="https://rework.withgoogle.com/jp/guides/set-goals-with-okrs/steps/introduction/">Google re:Work - ガイド: OKRを設定する</a> に Google 式のやり方が端的にまとまっているので、まずこれを見ると良いと思う。具体的な事例が知りたければ、国内企業ブログがいくつも引っかかる。</p>
<p>個人での OKR 実践については、いくつか事例を探せたので参考にさせていただいている。特に1番目に挙げたエントリーが非常に具体的かつ定量的な目標設定ができていて、目標設定後の日々の運用にも言及していてすごく参考になった。ここではダイエットという定量的に測りやすい目標を掲げているけれど、そもそも定量的評価しやすい目標を逆算的に選ぶのもありかもしれない。</p>
<ul>
<li><a href="http://shopetan.hatenablog.com/entry/2018/12/10/000000">ダイエットを支える技術 - OKRとセルフマネジメントで15キロ痩せる - 未来永劫</a></li>
<li><a href="https://kths.hatenablog.com/entry/2019/01/04/222959">2019年の個人OKRをつくってみた - これはただの日記</a></li>
<li><a href="https://qiita.com/maKunugi/items/2616e337c259256726b8">個人開発でOKRを試したいので運用方法を考える - Qiita</a></li>
</ul>
<p>また目標を作るにあたっては、読書猿氏の『アイデア大全』『問題解決大全』を参考にしている。それぞれアイデア出しと問題解決のための古今東西様々な手法が掲載された本で、目標設定の上でも役に立っている。特に活用しているのが「スケーリング・クエスチョン」（今の自分を100点満点で評価し、100点に足りない点数の理由は何か、それを埋めるにはどうしたらいいかを考える）というメソッド。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4894517450/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/417MFc9ImBL._SL160_.jpg" alt="アイデア大全" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4894517450/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">アイデア大全</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 20.01.13</div></div><div class="amazlet-detail">読書猿 <br />フォレスト出版 (2017-01-22)<br />売り上げランキング: 29,323<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4894517450/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4894517809/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/51eIDa4w4VL._SL160_.jpg" alt="問題解決大全――ビジネスや人生のハードルを乗り越える37のツール" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4894517809/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">問題解決大全――ビジネスや人生のハードルを乗り越える37のツール</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 20.01.13</div></div><div class="amazlet-detail">読書猿 <br />フォレスト出版 (2017-11-19)<br />売り上げランキング: 60,500<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4894517809/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
]]></description>
            <link>https://chroju.dev/blog/okr_in_private</link>
            <guid isPermaLink="false">okr_in_private</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 13 Jan 2020 09:48:26 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[2019年総括]]></title>
            <description><![CDATA[<p>総括エントリー5年目。</p>
<ul>
<li><a href="https://chroju.github.io/blog/2015/12/31/looking-back-2015/">2015</a></li>
<li><a href="https://chroju.github.io/blog/2016/12/28/looking_back_2016/">2016</a></li>
<li><a href="https://chroju.github.io/blog/2017/12/29/looking_back_2017/">2017</a></li>
<li><a href="https://chroju.github.io/blog/2018/12/31/looking_back_2018/">2018</a></li>
</ul>
<p>昨年の総括は「定量評価してみる」という話を書いていて、でも今見ると定量評価というよりはやったことの単なる羅列みたいになっちゃってたのでいい加減毎年使える KPI みたいなものを定めてみようかなという気がした。といったところで自分のようなインフラエンジニアの定量評価に使える KPI ってなんだろうというのが結構難しい。まぁアウトプットの量が一番わかりやすいのかな、とは思うのでブログ、 GitHub の Contributions 、読書した本から定量的に見てみる。その後定性評価として、数値化できないあれこれを書いていく。</p>
<h2>定量評価</h2>
<h3>ブログ</h3>
<p>27本書いた。月に2本以上と考えるとなかなかではないかと思う。最後の 4Q においては個人的な目標として毎週書くというのを少し意識してみたのだけど、それに遠からずな感じには書くことができた。2013年以降、ブログを継続的に書けているのは自分でも評価するべき点だと捉えている。ネタとしては Terraform に関することが多かった。</p>
<p>また Advent Calendar は <a href="https://qiita.com/advent-calendar/2019/terraform">Terraform</a> と会社（<a href="https://qiita.com/advent-calendar/2019/globis">グロービス</a>）で2つ参加し、後者は Qiita で書いた。</p>
<h3>GitHub Contributions</h3>
<p><a href="https://gyazo.com/41bb80011f83fcc63537d8479f68de26"><img src="https://i.gyazo.com/41bb80011f83fcc63537d8479f68de26.png" alt="Image from Gyazo" width="776"/></a></p>
<p>Public repository について 290 contibutions 。今年から初めて仕事でも GitHub を使うようになったので、 private 込み（仕事への commit 具合も見たいので、デフォルトの表示はこちらにしている）だと 1200 を越える。</p>
<p>最近何年かは terraform-provider-aws に何件かプルリク出すことはできていて今年もそれはできた。他だと tfnotify にプルリクを出してマージしてもらえたり、 terraformer に issue 立てて少し話ができたりしたのはよかった。自分はそれほどガツガツ OSS commit しているわけではなくて、普段 OSS を使っていて何か気付いたことがあったら issue やプルリクを出す、程度の活動をしている。もうちょっと貢献したいような気もするけれど、 commit 自体が目的というわけではないので現状これぐらいでいいのかなとも思っている。何か想定通りの動作をしなかったときにコードを読む、レポジトリに当たるという姿勢は大事にしたい。すでに issue 化されているときも多いのだけど、そういうときはブログに書くなどして何かしらアウトプットすることをやっていきたい。</p>
<h3>読書</h3>
<ul>
<li>入門 監視</li>
<li>Web API The Good Parts</li>
<li>分散システムデザインパターン</li>
<li>プロダクションレディマイクロサービス</li>
<li>SCRUM BOOT CAMP THE BOOK</li>
</ul>
<p>大学の本は除いた。結構大学の教科書や参考書を読んでいることが多くて、純粋に仕事を意識した技術書はぜんぜん読めていなかった。</p>
<p>新しい会社で働くことになり、マイクロサービスやコンテナによるアーキテクチャを意識するようになったことと、スクラムが社内のスタンダードになっていることから、そのあたりの本を年の後半に何冊か読んだ。いずれも実践に結び付けられていないしブログに感想とかもまとめてないからすごくよくない。来年は大学で履修登録する科目数を少し減らして、仕事の比重を高めるつもりでいる。</p>
<h2>定性評価</h2>
<h3>注力した領域</h3>
<ul>
<li>Terraform
<ul>
<li>ブログに Terraform ネタが多かったように、 Terraform に一番注力していた。</li>
<li>今年は v0.12 が公開されたり、 Terraform Cloud が GA になったりと大きなニュースも多く、今後さらに注目されそうなので引き続き注力したい。</li>
</ul>
</li>
<li>Serverless
<ul>
<li>S3 + CloudFront による SPA など、マネージドサービスだけでシステムを組む機会が増えた。</li>
</ul>
</li>
<li>GCP
<ul>
<li>仕事で GCP を初めて扱い始めた。</li>
<li>正直まだほとんどわかっていないので、これは今後の課題になっている。</li>
</ul>
</li>
<li>大学の勉強
<ul>
<li>大学の話は年度終わりに別途書くつもりなのでここでは割愛。</li>
<li>数学やアルゴリズムの基本などを今年は学んでいた。</li>
</ul>
</li>
</ul>
<p>特に Terraform については、去年書いた「プレゼンスを上げたい」のプレゼンスを発揮できそうな分野かな〜〜〜？？という思いになりつつある。自分の技術者としての売りにできるよう昇華させていく。</p>
<h3>勤務状況</h3>
<p>正社員を辞めて一時的な無職を経て契約社員＋業務委託契約となったことでだいぶ生活自体が変化した。大きくは労働時間が減ったことと、リモートワークを週1日以上するようになったこと。正社員時代はちょっとした時間シフトする勤務体系もあったのだが、それが無くなったことでだいぶ心身も安定した気がしている。仕事で macOS 使うのも GitHub 使うのも slack 使うのも今年からが初めてで、まぁほんといろいろと変わった。</p>
<p>いろんな働き方を経験することは、時代を考えても良いことと考えている。あまり1つの働き方にとらわれず、今後も柔軟な選択ができたらよいし、柔軟な選択ができるよう力をつけておきたい。</p>
<h3>自作キーボード</h3>
<p>このブログでも何度か書いてきている通り、今年は自作キーボードに手を出した。3台組み立てて1台積んでいて1台注文済み発送待ちの状態。先日ザッと遣った金額を考えてみたけれど、ちゃんと数えなくても 10 万は確実に越えていて少し恐ろしくなった。</p>
<p>しかし趣味的な面を抜きにしても、電子工作という分野に初めて触れられたのはよかった。手先を遣うことは苦手だと勝手に思い込んできていたので、きちんとした道具を買って、きちんと手順を踏めば自分でも工作が出来ると知れたのがすごい収穫だった。さすがに自分で基板設計するところまでは踏み込まないつもりでいるけれど、興味を持った分野は臆さず手を出していきたい。</p>
<h3>個人 OKR の導入</h3>
<p>ブログには書いていないのだが、今年の 2Q から以下のルールで個人 OKR を回していた。</p>
<ul>
<li>四半期ごとに OKR を2つ定める（仕事系とプライベート系）</li>
<li>OKR の内容は達成見込み 60 %程度のものにする</li>
<li>毎週振り返りを行い、各 KR の達成見込み、先週やったこと、来週やるべきことを確認する</li>
<li>四半期が終わるときに総合的な評価を行い、次の四半期の目標を定める</li>
</ul>
<p>基本的には <a href="https://rework.withgoogle.com/jp/guides/set-goals-with-okrs/steps/grade-OKRs/">Google re:Work - ガイド: OKRを設定する</a> のやり方に則っている。昨年の総括で書いたことの1つに「インプットとアウトプットのサイクルを早めたい」というのがあって、 OKR であれば早いペースで明確な目標を立てて commit していくサイクルを回せそうだと思ったので取り入れてみた。</p>
<p>実際のところは四半期終盤になると振り返りの時間を取らなくなったりもして、きちんと運用できたとは言い難いのだが、毎週振り返って成果を出そうとするリズムを作れたことには結構効果があった。先述した「ブログを週1で更新する」というのもこの一貫だった。これについても来年早いうちに別途エントリーでまとめてみようと思うし、今後も続けていく。</p>
<h2>来年について</h2>
<p>来年は3つ最注力分野として定めている。</p>
<ul>
<li>コンテナ</li>
<li>英語</li>
<li>チームビルディング</li>
</ul>
<p>コンテナを仕事で使う機会に恵まれたので来年は一番注力していく。より正確には Kubernetes になるとは思うのだが、特定のツールに縛られるのではなくて、 VM をコンテナに置き換えるにあたり、どのようなワークフローを作り、どのような OSS を組み合わせていけばよいのかをゼロベースで考えていく。システムの安定性、クラウドの利用料金、開発スピードの向上などなど、考慮したいことはたくさんある。</p>
<p>英語は会話できればもちろんよいのだが、読み書き面をもう少し頑張りたい。英語のドキュメントを読む機会が今でもないわけではないし、そこまで苦手というわけでもないのだが、やっぱり日本語に比べると読書スピードが半分以下に落ちてしまう。 <a href="https://chroju.github.io/blog/2019/12/20/subscriptions_2019/">Subscriptions 2019 · the world as code</a> でも書いた通り O'Reilly のオンラインラーニングに登録したこともあり、読解スピードの向上に努めたい。</p>
<p>3点目については、年齢もあるのか、いや年齢の問題というわけではないか、チームや組織というものの在り方を考えなくてはならないなと感じることが増えてきた。端的な例としてはコンウェイの法則がある。コンテナによるアーキテクチャを取り入れ、さらにマイクロサービス化を進めたほうが SRE の観点からメリットが大きいと感じたとしても、組織構造がモノリシックなままでは開発フローが最適化されないわけで、どうしても組織体制への働きかけも必要になってくる。マネージメントまではいかないけれど、チームや組織の力を最大化していく、チームとしての開発やシステム運用を効率化していくにはどうしたらいいのかという部分を考えられるようになりたい。自分はどう考えても内向型で、組織を引っ張る立場には向いていないとは自覚している。であれば、他の立場からどのようなアプローチができるかということを掘り下げていきたい。</p>
]]></description>
            <link>https://chroju.dev/blog/looking_back_2019</link>
            <guid isPermaLink="false">looking_back_2019</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 30 Dec 2019 05:36:57 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[GCP 公開の Terraform modules から module による効果的な抽象化を学ぶ]]></title>
            <description><![CDATA[<p>Terraform はずっとほぼ AWS でしか使っていなくて、最近 GCP で使い始めたところ結構使い勝手が違って驚いている。その中でも公式提供されている Terraform modules がかなり良くて、 GCP 使わない人でも参考になるので紹介してみる。</p>
<h2>Terraform modules for Google Cloud</h2>
<p>https://github.com/terraform-google-modules</p>
<p>上記 GitHub Organization にて、現時点で 64 の module が公開されている。 Organization のメンバーを見ると GCP に属している方が多いので、どうも Google 公認で提供されているものらしい。 AWS にも <a href="https://github.com/terraform-aws-modules">Terraform AWS modules</a> という Organization があるが、こちらは見る限り AWS 関係者ではなく有志による提供となっている。昨今のアレじゃないけど、 Google のほうが OSS コミュニティと良い関係を築こうという意思が見て取れるなぁという気がしなくもない。</p>
<p>公開されている module はいろいろあるが、一例として IAM に関して見てみる。 GCP の IAM に関する Terraform resources は <a href="https://www.terraform.io/docs/providers/google/r/google_project_iam.html">Google: google_project_iam - Terraform by HashiCorp</a> で触れられている通り、何種類かのものが存在するのだが、ざっくり以下2種類に気を付ける必要がある。</p>
<ul>
<li><code>google_project_iam_member</code> : Role とメンバーを1対1で紐つける</li>
<li><code>google_project_iam_binding</code> : ある Role と紐付くメンバーすべてを管理する</li>
</ul>
<p>GCP ではあらかじめ複数の権限が割り当てられた Role というものが存在し（ AWS のマネージドポリシーみたいなものと考えればいいかもしれない）、これとメンバーを紐つけて権限の割り当てを行う。前者の <code>member</code> は1対1対応しか作れないので、ある Role に複数のメンバーを結びつけたい場合（が大半だと思うが）はちょっと不便だ。しかし一方で <code>binding</code> はある Role と紐付く <strong>すべての</strong> メンバーを管理する。そのため Terraform を apply する前に、すでに Role と紐ついたメンバーがいて、 Terraform 内ではそのメンバーを宣言していなかった場合、 <code>apply</code> 時に除外されてしまうことになるので注意が必要となる。</p>
<p>という、それぞれ一長一短ある resource をうまいこと使い分けなくてはならないのだが、 GCP が module で解決策を提示してくれている。 <a href="https://github.com/terraform-google-modules/terraform-google-iam/tree/master/modules/projects_iam">terraform-google-iam/modules/projects_iam at master · terraform-google-modules/terraform-google-iam</a> からサンプルを引用する。</p>
<pre><code class="language-hcl">module "project-iam-bindings" {
  source   = "terraform-google-modules/iam/google//modules/projects_iam"
  projects = ["my-project_one", "my-project_two"]
  mode     = "additive"

  bindings = {
    "roles/compute.networkAdmin" = [
      "serviceAccount:my-sa@my-project.iam.gserviceaccount.com",
      "group:my-group@my-org.com",
      "user:my-user@my-org.com",
    ]
    "roles/appengine.appAdmin" = [
      "serviceAccount:my-sa@my-project.iam.gserviceaccount.com",
      "group:my-group@my-org.com",
      "user:my-user@my-org.com",
    ]
  }
}
</code></pre>
<p>2つの resource の使い分けを気にする必要はなく、 <code>bindings</code> 変数に role と members の1対多のリストを渡せばいいだけ。既存の紐付きを置き換える ( <code>authoritative</code> ) のか、既存のものは触らず新たな紐付きを追加する ( <code>additive</code> ) のかは <code>mode</code> 変数で指定ができ、さらにデフォルトは安全側に倒れて <code>additive</code> となっている。だいぶ使いやすく抽象化されていると言っていい。</p>
<p>抽象化のロジックを見てみる。呼び出している <a href="https://github.com/terraform-google-modules/terraform-google-iam/blob/master/modules/projects_iam/main.tf">module</a> 自体はわりと簡素な内容になっている。というのも、見ればわかるのだが、ロジック部分を <code>helper</code> という別の module に飛ばしているからだ。ここではほぼ resource 作成だけが行われている。</p>
<pre><code class="language-hcl">module "helper" {
  source   = "../helper"
  bindings = var.bindings
  mode     = var.mode
  entity   = var.project
  entities = var.projects
}

resource "google_project_iam_binding" "project_iam_authoritative" {
  for_each = module.helper.set_authoritative
  project  = module.helper.bindings_authoritative[each.key].name
  role     = module.helper.bindings_authoritative[each.key].role
  members  = module.helper.bindings_authoritative[each.key].members
}

resource "google_project_iam_member" "project_iam_additive" {
  for_each = module.helper.set_additive
  project  = module.helper.bindings_additive[each.key].name
  role     = module.helper.bindings_additive[each.key].role
  member   = module.helper.bindings_additive[each.key].member
}
</code></pre>
<p>使っている resource は、やはり先程見た <code>iam_binding</code> と <code>iam_member</code> の2つだ。それぞれ <code>for_each</code> が使われていることから、変数 <code>bindings</code> で指定された role と members と project あたりをいい感じに list に変換して、選択された mode に応じて <code>module.helper.set_authoritative</code> か <code>module.helper.set_additive</code> に代入しているのだろうと想像がつく。代入されていないほうの変数は空のリストになるので、 resource の作成は行われない。</p>
<p>実際に <a href="https://github.com/terraform-google-modules/terraform-google-iam/blob/master/modules/helper/main.tf">helper</a> を覗いてみると、確かにそのようなロジックになっている。 <code>module.helper.set_authoritative</code> について追ってみる。</p>
<pre><code class="language-hcl">  set_authoritative = (
    local.authoritative
    ? toset(local.keys_authoritative)
    : []
  )
</code></pre>
<p><code>local.authoritative</code> による三項演算子だ。 <code>local.authoritative</code> は先の <code>mode</code> が <code>authoritative</code> だった場合にのみ値が代入されるようになっており、 やはり <code>authoritative</code> を指定した場合に限り、 <code>set_authoritative</code> にリストが代入されているとわかる。そして代入される値は、 <code>keys_authoritative</code> を set に変換したものとなっている。では <code>keys_authoritative</code> とは何か。</p>
<pre><code class="language-hcl">  keys_authoritative = distinct(flatten([
    for alias in local.aliased_entities
    : [
      for role in keys(var.bindings)
      : "${alias}--${role}"
    ]
  ]))
</code></pre>
<p><code>local.aliased_entities</code> は project のリストと思ってよい。二重ループになっているため少しわかりづらいが、各 project ごとに <code>bindings</code> から keys, すなわち <code>role</code> の値を取り出し、 project 名と繋げた文字列の配列を作っている。前述したサンプルのように、 projects と role をそれぞれ2つずつ指定している場合であれば、 2 × 2 で長さ4の配列が作られることになるわけだ。 <code>helper</code> の別のところでは、この4つの project - role それぞれに紐つけるべきメンバーのリストが生成されている。最終的に <code>for_each</code> のループによって、これらを組み合わせて <code>iam_binding</code> が生成されている。</p>
<p>ここではざっくりと GCP Terraform modules の中身を見てみたが、これ以外にも非常に多くの Terraform functions を上手く使って抽象化を試みている。コメントも多く盛り込まれていて読みやすいので、各 functions はどういう場面でどのように活用できるのか、とても参考になる。</p>
<h2>Conclusion</h2>
<p>Terraform provider はその仕組み上、各クラウドサービスの API サービスをそのまま愚直に変換したものであり、 API の仕様を把握していなければ上手く扱えないこともある。しかし我々が欲しているのはクラウドリソースのコード化という点のみであり、 API の仕様を細部まで常に気にしなくてはならない、という状況は歓迎したくない。 GCP の modules はそういった低レイヤーな知識がなくとも、簡潔な記載でクラウドリソースを使えるようにしてくれているものが多い。 Terraform modules を作るとき、単に組織内でのデフォルト値を埋め込んでいるだけ、のような使い方になってしまうことも少なくないと思うが、 GCP のそれは「抽象化」という観点で module を作る上で、大きなヒントになりそう。</p>
<h2>Appendix: GCP with Terraform 所感</h2>
<p>おまけで、 Terraform で GCP を扱うときに、 AWS を扱うときとこのへんが感覚違うなーと思う点をいくつか。</p>
<ul>
<li>認証に JSON が必要なのはちょっと面倒。</li>
<li>個々のユーザーでは credential json 吐き出せなくてサービスアカウントが必要なのも面倒。</li>
<li>でも複数の project に横断的にリソースを作るのは AWS マルチアカウントより遥かに楽ですごい。</li>
<li>各 resource とも attibute references ( outputs で出力できるやつ) がちょっと少なめな印象を受ける。</li>
<li>一部 resoruce はドキュメントから直接 Cloud Shell で実践できるボタンがあって強い。
<ul>
<li>https://www.terraform.io/docs/providers/google/r/dns_managed_zone.html とか。</li>
</ul>
</li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/terraform_gcp</link>
            <guid isPermaLink="false">terraform_gcp</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 24 Dec 2019 10:16:59 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Subscriptions 2019]]></title>
            <description><![CDATA[<p>契約中のサブスクリプションサービスや定期課金サービスをまとめる企画第2回。 Subscriptions というタイトルだけどサブスクリプションじゃないです。定額課金全般。昨年の <a href="https://chroju.github.io/blog/2018/12/17/subscriptions_2018/">Subscriptions 2018 · the world as code</a> からの差分という形で書いてみる。</p>
<h2>昨年から継続しているサービス</h2>
<ul>
<li>Day One</li>
<li>MoneyForward</li>
<li>Nintendo Switch Online</li>
<li>Amazon Prime ( Amazon Prime Student に変更 ¥4,900 → ¥2,450 / year)</li>
<li>Spotify Premium ( 学割に変更 ¥980 → ¥480 / month)</li>
<li>シネマシティ</li>
</ul>
<p>今年から大学生になって Amazon Prime と Spotify は学生料金に変更した。なんか大人げない気もするけど、出費が年間で数十万増えているのは事実だし、多少は恩恵を受けておこうかと。</p>
<p>ちなみに Amazon Prime Student は正確には Prime とサービス内容が一部異なって、学生向けの特典がいくつか追加されている。が、あんまり把握していなくて、書籍を3冊以上同時購入すると 10% ポイント還元というのだけ使わせてもらっている。が、ついつい物理書籍は書店で買って持ち帰るほうがテンション上がるのでそこまで使えていない。</p>
<p>Spotify Premium は学生であることを証明するのに、大学ポータルサイトへのログインが必要でちょっとおもしろかった。詳しい仕組みはわかっていないけど <a href="https://spotify-international.sheerid.com/?country=JP&#x26;locale=ja&#x26;_ga=2.75700821.1319129748.1574830245-2082534824.1572787825">SheerID</a> というものらしい。</p>
<h2>昨年以降解約したサービス</h2>
<h3>GitHub</h3>
<p>お金を払うとプライベートレポジトリが無制限に使えていたのだけど、これが無料プランにも開放されたので有償である必要がなくなった。</p>
<h3>Todoist</h3>
<p>タスク管理を後述する Dynalist に移行して解約した。何か魅力がなくなったわけではなくて、リスト型のタスク管理サービスとしてはとても満足していた。単にタスク管理のやり方を替えただけ。</p>
<h3>esa.io</h3>
<p>昨年のエントリーにも書いていた通り、解約を1年前の時点で検討していたので。現在メモツールとしては Scrapbox と Dynalist を使っている。</p>
<h2>新たに契約したサービス</h2>
<h3>Dynalist ($7.99 / month)</h3>
<p>アウトライナーサービス。アウトライナーというと文章を書くときに論理構造を練る上で使うものというイメージが強いけれど、要するところ階層型の情報整理全般に活用できるので、自分の場合はタスク管理というか、今気になっていることをリストアップするのに使っている。</p>
<p><a href="https://gyazo.com/4d756a768859c57f2751f88c7624bb26"><img src="https://i.gyazo.com/4d756a768859c57f2751f88c7624bb26.png" alt="Image from Gyazo"></a></p>
<p>Todoist をはじめ、タスク管理用のサービスってほとんどが「やること」を1つずつ書いていくチェックリスト型になっているものの、実際のタスクってもっと漠然としていることも多い。例えばアドベントカレンダーを書く、というタスクがあったとして、これはさらに「ネタを探す」「ネタを決める」「x日までに下書きをする」「x日までに予約投稿する」といったサブタスクに細分化できる。また「ネタを探す」タスクが書いてあったら、その下に考えたネタを書き連ねていきたいという欲求もある。こういう感じでタスクだけではなくて、今自分の頭の中にあるものをざざっとダンプする目的で使い始めた。</p>
<p>メモサービスはもう1つ Scrapbox も使っている。 Dynalist がメモリダンプで Scrapbox が不揮発性のディスクみたいなイメージ。 Dynalist にとりあえず気になることをメモして、調べて具体的な情報になったら Scrapbox に移す、みたいなことをしている。</p>
<p>ただ、タスク管理のためにまともに使おうとすると、月額 $7.99 というそれなりの金額で Pro プランになる必要がある。 Pro だと日付を設定した項目を Google Calendar に連携してくれたり、繰り返しタスクを作ったりできるようになる。まぁ今のところは必要経費扱い。</p>
<h3>d アニメストア (¥400 / month)</h3>
<p>映像配信サービスは1つでいいと思っていたのに契約してしまった。同居者と折半で払ってるのでまぁという感じ。</p>
<p>アニメのラインナップは随一と聴いていたけど確かに強くて、『機動警察パトレイバー アーリーデイズ』みたいな古い OVA もあるし、ライブイベント『涼宮ハルヒの激奏』が入っているのを見つけたときには変な声が出た。たかだか 12 年前なのに、声優ライブイベントの様子とか、それを観覧する客席の空気とかに隔世の感があってとんでもねぇなって気持ちになったので契約者は見るのオススメ。</p>
<h3>freee (¥980 / month)</h3>
<p>個人事業主になったものの確定申告こわいので契約した。年払いだと安くなるけど、1年非正規雇用状態を続けるかもわからなかったので取りあえず月額課金でやっていっている。一番安いプランだけどそこそこしますね。。</p>
<h3>Online Learning with O’Reilly ($199 / year)</h3>
<p>ご存知アメリカのオライリーによるオンラインラーニングサービス。だいぶ前に1か月間お試しだけしたんだけど、なにせなかなかにお高いので本登録はせずに放置していて。それが今年の Black Friday に 50% OFF のプロモコード来たのでよっしゃ！って思って登録したんですね。んで決済に最初 Kyash 使ったんですよ。でも Kyash って定期支払とかで使えないことあるじゃないですか。で、弾かれて。弾かれたんでまぁしゃーないよねって思って別のデビットカードで決済し直したんですよ。そしたら定価で決済されててアレ？ってなって。どうも1回決済失敗したときにプロモコード外れてたらしくて。マジで？？？ってなったんだけどもうどうしようもなくて。いやー、やっちゃいましたね。今年最後に最大のやらかし。</p>
<p>だいたい月に1冊3000円の技術書を買うペースだとこれぐらいの金額を年間消費するので、そういうつもりでいればいいのかなと。さすがに使わないともったいなさすぎるので来年は英語頑張る。</p>
<h3>メールマガジン「読書日記／フヅクエラジオ」 (¥800 / month)</h3>
<p>http://fuzkue.com/entries/595</p>
<p>行きつけのカフェの店主が出してるメルマガ。 fuzkue という新宿・初台にちょっと変わったカフェがあって。本の読める店を標榜していて、私語や PC 厳禁で長時間居座り OK でガンガン本を読んでくれっていう場所で、店主さんも読書が好きな方でずっと読書日記をウェブサイトに載せていて、それがまとめられて出版されたりもしていてというおもしろい話。カフェにはそう頻繁に行けるわけでもないのでカンパの意味も込めて購読している。本当に読書の話と、店の話が主になった日記なので、匿名だけどその日のお客さんの様子なども出てきて、一度明らかにこれ俺やんけってのが出てきたときには小躍りしたりしました。</p>
<p>メルマガ購読ってこれが人生初めてだし、今後購読することもない気がしてます。</p>
]]></description>
            <link>https://chroju.dev/blog/subscriptions_2019</link>
            <guid isPermaLink="false">subscriptions_2019</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 20 Dec 2019 12:15:36 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Terraform state 概論]]></title>
            <description><![CDATA[<p>この記事は <a href="https://qiita.com/advent-calendar/2019/terraform">terraform Advent Calendar 2019 - Qiita</a> の 14 日目です。</p>
<p>Terraform State （以下、本記事では <code>tfstate</code> と呼称します）をご存知でしょうか。 Terraform を使っていて tfstate をご存知ではない人はまぁまずいないはずだとは思いますが、直接の編集が非推奨となっているためデリケートな扱いが求められる一方で、 Terraform を使っていると折に触れて立ち向かわなくてはならない憎いやつです。</p>
<p>Terraform を上手く使うことは、 tfstate を上手く取り扱うこととニアリーイコールだと個人的に思っています。そんな tfstate のことをいろいろとまとめてみました。ていうかまとめすぎてえらいことになったので、年末年始のお暇なときにでも読んでみてください。</p>
<p>全体は以下4つに分かれています。</p>
<ul>
<li>tfstate 入門 : 文字通り入門的な内容です。</li>
<li>tfstate 理論 : tfstate にまつわる Terraform の挙動に関して理論的な内容です。</li>
<li>マクロ tfstate 論 : マクロな視点で考えた、 tfstate の運用管理プラクティスです。</li>
<li>ミクロ tfstate 論 : ミクロな視点で考えた、 tfstate の編集などの話です。</li>
</ul>
<hr>
<h2>tfstate 入門</h2>
<p>本項では tfstate の基本的な性質、特徴について触れていきます。</p>
<h3>tfstate の基礎</h3>
<p>tfstate は Terraform が管理するインフラストラクチャーの状態をプレーンテキストで保存したファイルです。データ構造は Terraform の他の設定ファイル（以下、 <code>tffile</code> と呼称します）とは異なり、 JSON が用いられています。</p>
<p>tfstate は自動生成されるファイルであり、手動で書き換えることは非推奨とされています。具体的なタイミングとしては <code>terraform apply</code> コマンドが実行された際に新規作成、もしくは既存のものが更新され、 <code>apply</code> した結果構築、変更されたインフラストラクチャーの状態が記録されます。</p>
<p>また <code>terraform plan</code> コマンドが実行された際には、 tfstate から前回 <code>apply</code> 実行時のインフラストラクチャーの状態を読み取り、それと設定ファイルに記載されたインフラストラクチャー設定との差分から <code>plan</code> 結果を出力します。この挙動については後ほど詳説します。</p>
<h3>tfstate の保存場所</h3>
<p>特に設定していなければ、デフォルトの保存場所は <code>terraform apply</code> を実行したカレントディレクトリ上の <code>terraform.tfstate</code> という名前のファイルになります。しかし、先述の通りこのファイルは次回 <code>apply</code> 実行の際に必要となります。ローカルに置いたままでは複数人で <code>terraform</code> を実行できなくなってしまうため、何らかの手段で共有する必要があります。</p>
<p>共有する上で、 VCS を用いることは非推奨とされています。これは例えば複数人が <code>git clone</code> して同時に <code>terraform apply</code> を実行してしまった場合などに、競合が発生する可能性があるからです。 tfstate は常に唯一無二のファイルがどこかに存在し、誰もがそのファイルを参照する必要があります。</p>
<p>そのため tfstate の保存にはオブジェクトストレージ等を用いることになります。これを設定するのが  <code>backend</code> という設定です。</p>
<pre><code class="language-hcl">terraform {
  backend "s3" {
    bucket = "example"
    key    = "tfstate/terraform.tfstate"
    region = "ap-northeast-1"
  }
}
</code></pre>
<p>上記の設定では Amazon S3 を backend として指定しています。この設定を記載した状態で <code>terraform init</code> を実行すると、 backend へのアクセスが可能か確認され、問題なければ <code>plan</code> や <code>apply</code> の際にこのパス上のファイルを tfstate として取り扱うようになります。</p>
<p>backend に指定可能なストレージは Terraform がサポートしているものに限られますが、 Azure BLOB Storage 、 Google Cloud Storage といった、メジャーなクラウドサービスの各オブジェクトストレージにはいずれも対応しています。また 2019 年からは、 Terraform を制作した hashicorp が backend サービス <a href="https://www.terraform.io/docs/cloud/index.html">Terraform Cloud</a> を公開しており、ユーザー5人までのチームであれば、無償で利用することも可能です。</p>
<h3>tfstate は何のために存在するのか</h3>
<p>tfstate という仕組みが設けられている理由はいくつかあり、詳しくは <a href="https://www.terraform.io/docs/state/purpose.html">State - Terraform by HashiCorp</a> に解説されています。ここでは「Terraform の管理対象を明確化する」という点について考えてみます。</p>
<p>すでに EC2 インタンスが 4 台動いている AWS アカウントに、 Terraform を実行してもう 1 台インスタンスを追加した場合を考えます。次に <code>plan</code> したとき、 tfstate があれば、前回構築したインスタンスの ID が記録されているので、そのインスタンスとの差分を確認すればよいことになります。しかし tfstate が無いとすると、 5 台のうちどれが前回構築したインスタンスかわからず、差分を取ることが困難になります。また、 Terraform は前回実行時以降に tffile から削除したリソースは、現実のリソースも削除しようとしますが、前回実行時の記録がなければ、残る 4 台のインスタンスは Terraform が構築したものなのか、そうでないのか判別ができません。</p>
<p>このように、 tfstate は Terraform の管理対象を明確化してくれます。逆に言えば、AWS アカウント内のすべてのリソースを1つの tfstate で管理対象とするのか、例えばサービスごとだったり、システムの構成単位ごとだったり、何かしらの単位で tfstate を分割していくのかは、個々のユースケースに併せて考えていく必要があります。</p>
<h3>もうひとつの tfstate</h3>
<p>ところで、あまり意識することはありませんが、 tfstate はもう1つあります。 <code>terraform init</code> 実行時に作成される <code>./.terraform/terraform.tfstate</code> です。</p>
<p>このファイルにはリソースの情報ではなく、 backend の情報が含まれます。<code>terraform init</code> では backend との疎通確認が行われますが、その結果が問題なければ、 backend 設定がこのファイルへ出力されます。この tfstate は <code>init</code> 実行時に動的に生成されるため、永続的に保存しておく必要はありません。</p>
<hr>
<h2>tfstate 理論</h2>
<p>本項では、 tfstate が Terraform によって実際どのように用いられているのか、理論的な部分（？）に触れていきます。</p>
<h3>tfstate のファイル構造</h3>
<p>手動で読み書きする機会が基本的には存在しないので、案外 tfstate の内容を目にする機会はないのかもしれません。改めて紐解いてみると、以下のような構造をしています。</p>
<pre><code class="language-json">{
  "version": 4,
  "terraform_version": "0.12.18",
  "serial": 3,
  "lineage": "XXXXXXXX-XXXX-XXXX-XXXX-f4e9614b100e",
  "outputs": {
    "example": {
      "value": "example",
      "type": "string"
    }
  },
  "resources": [
    {
      "module": "module.iam.module.core",
      "mode": "managed",
      "type": "aws_instance",
      "name": "example",
      "provider": "module.example.provider.aws.example",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "arn": "arn:aws:ec2::...",
            ...
          }
        }
      ]
    }
  ]
}
</code></pre>
<p>各項目の意味はドキュメントがあるわけではないのであんまりわかっていません。上部に書かれているのはいずれもメタ情報にあたるようで、キーになりそうなのは <code>serial</code> ぐらいかと思います。これは版番号を表しており、 <code>terraform apply</code> によって tfsate が書き換えられるタイミングでインクリメントされます。また <code>terraform_version</code> は、この tfstate が生成される際に用いられていた Terraform のバージョンです。これより古いバージョンの Terraform でこの tfstate を扱おうとすると警告が出て実行できません。特に手動で Terraform を実行している場合、実行者間でバージョンを合わせる必要があるので注意が必要です。</p>
<p>肝になるのはその後の <code>outputs</code> と <code>resources</code> です。 <code>outputs</code> は文字通り Terraform で <code>outputs</code> を設定している場合に限り、その値が記述されます。 <code>resources</code> が、実際に Terraform が構築したリソースの設定情報を記述したオブジェクトの配列です。各オブジェクトの主な項目は以下のとおりです。</p>
<ul>
<li><code>module</code> : 該当 resource が module に内包されている場合、その module 名（内包されていない場合はこの項目自体存在しません）</li>
<li><code>mode</code> : data, managed（生成した resource）のいずれか</li>
<li><code>type</code> : resource type</li>
<li><code>name</code> : resource name</li>
<li><code>provider</code> : その resource 生成に使われた Terraform provider 名</li>
<li><code>instances</code> : 最後に <code>terraform apply</code> を実行した時に適用された設定情報の配列</li>
</ul>
<p>各 resource オブジェクトには <code>type</code> と <code>name</code> が含まれますが、これによって Terraform 設定ファイルに記載している resource と紐ついています。以下の Terraform resource で言えば、 <code>aws_instance</code> が <code>type</code> で <code>foobar</code> が <code>name</code> に当たります。</p>
<pre><code class="language-hcl">resource "aws_instance" "foobar" {
  ...
}
</code></pre>
<p>また <code>instances</code> 内には、 <code>aws_insntace</code> であればインスタンスIDなどの、現実のリソースを一意に特定する情報が含まれます。これにより resoruce オブジェクトは Terraform resource と現実のリソースとの1対1対応を定義しています。なお、お気付きの通り <code>instances</code> は配列です。 <code>for_each</code> や <code>count</code> を使った場合など、1つの resource block で複数のインフラリソースを構築した場合には、複数のリソース情報が入ります。</p>
<h3>terraform plan と tfstate</h3>
<p><code>terraform plan</code> を実行した際には、 tfstate を元にして設定ファイルと現実のインフラとの差分が導かれます。とはいえ、 tfstate に書き出された設定を、直接 terraform 設定ファイルの内容と比較して差分を出しているわけではありません。 tfstate からは、先述のように各 Terraform resource と対応する現実のリソースが存在するのかどうかを読み取るだけです。そして存在していれば、その設定情報を API などを用いて実際に取得し、設定ファイルとの比較を行うことになります（）。もしも Terraform resource に対応するリソースの情報が tfstate に存在しなければ、そのリソースは新規作成するべきものと判断されます。</p>
<p><strong>2021-08-22追記 : 正確には <code>terraform plan</code> を実行した際、差分確認が行われる直前に、 <code>terraform refresh</code> が裏で実行され、 tfstate の状態が最新の設定と同期されています。 <a href="https://www.terraform.io/upgrade-guides/0-15.html">Terraform 0.15</a> においては、この <code>refresh</code> 時に実設定と state の差分が発見された際、その旨が plan 結果にも付記されるようになりました。なお、 <code>plan</code> 時に <code>refresh</code> を行いたくない場合、 <code>-refresh=false</code> オプションが利用できます。</strong></p>
<p>つまり、 <code>terraform plan</code> の挙動を表にまとめると以下のようになります。</p>
<p>あるリソースが……</p>
<p>| tffile に | tfstate に | 現実のリソースと tffile の差異が | plan 結果は |
|-----------|------------|----------------------------------|-------------|
| ある      | ある       | ない                             | No changes  |
| ある      | ある       | ある                             | change      |
| ある      | ない       | 差異は確認しない                 | add         |
| ない      | ある       | 差異は確認しない                 | destroy     |</p>
<p>従って tfstate の <code>resources[].instances</code> を仮に手動で書き換えても、 <code>terraform plan</code> の結果は変動しません（インスタンス ID のような、そのリソースを一意に特定する項目は除きます）。それでは tfstate を現実のリソース状態に合わせる <code>terraform refresh</code> は不要なのではないかと思われそうですが、例えば Terraform で構築したリソースを GUI から手動で削除してしまったような場合には、 <code>refresh</code> によって tfstate からも削除の上で、設定ファイルから削除する操作が必要になってきます。</p>
<hr>
<h2>マクロ tfstate 論</h2>
<p>本項ではマクロに見たときの tfstate について、具体的には tfstate の運用方法などについて触れていきます。</p>
<h3>tfstate の保存場所</h3>
<p>「入門」で記したように、 tfstate の保存場所として利用できる backend には様々な種類のものが用意されています。それでは、この中でどれを選ぶべきなのでしょうか。</p>
<p>2019年末の時点においては、 Terraform Cloud がベストと考えています。その理由を1つずつ見ていきます。</p>
<h3>フルマネージドであるということ</h3>
<p>tfstate を保存するためだけに作られた、フルマネージドのストレージであるという特徴はやはり強みとして大きいです。 Terraform Cloud は以下の機能をもっています。</p>
<ul>
<li>自動的にいつ誰が実行したか履歴を蓄積してくれる</li>
<li>tfstate 保存場所をわざわざ作る必要がない</li>
<li>Terraform Cloud が Terraform 自動実行の機能も備えている</li>
</ul>
<p>1点目について。履歴を自動的に追跡し、誰がいつ <code>apply</code> を実行したかがわかるほか、あまり必要となる機会はないものの、各回での tfstate の差分も見ることができます。</p>
<p><a href="https://gyazo.com/c4961c003d884fc9959dc5786782769c"><img src="https://i.gyazo.com/c4961c003d884fc9959dc5786782769c.png" alt="Image from Gyazo" width="682"/></a></p>
<p>2点目については、例えば S3 だとバケットをあらかじめ作成する必要があるわけですが、 Terraform Cloud の場合は一度アカウントだけ作ってしまえば、その後は保存場所を手で作ったりする必要がありません。3点目については tfstate 保存の問題とは直接関係しませんが、 Terraform Cloud は Terraform 自動実行の機能も備えるなど、 hashicorp が提供しているだけあって Terraform を運用する上で便利な機能が備えられています。それら機能をすぐには使わないとしても、いつでも使えるよう tfstate だけは保存しておく、というのはアリだと思います。</p>
<h3>Remote State の利便性を活かしやすい</h3>
<p>Terraform Cloud を使う場合の利点として、より重要なのは Remote State の利便性を活かしやすい点にあると考えています。</p>
<p>Remote State とは、別の tfstate が output している値を読み取り、変数として活用できる Terraform の機能です。例として、 AWS のネットワークを構築する際、以下のように <code>output</code> を設定しておくと、他の Terraform からこの値を読み取ることができます。</p>
<pre><code class="language-hcl">resource "aws_vpc" "example" {
  cidr_block           = "192.0.2.0/24"
}

output "example_vpc_id" {
  value = aws_vpc.example.id
}
</code></pre>
<p>先に少し触れましたが、 AWS アカウント全体を1つの tfstate が管理下に置くのではなく、いくつか分割する場合がありますが、その場合でもこの機能を使えば相互に値を参照し合うことができます。あるいはマルチアカウント構成の場合でも、他のアカウントから設定値を読み込むことができるのは非常に便利です。 VPC Peering を行う場合などに重宝します。</p>
<p>Remote State から設定値を読み出す場合、当然ながらその tfstate に対する読み取り権限が必要になります。仮に S3 に置いている場合、バケットポリシーを適切に設定して、クロスアカウントでの読み取りを許可する必要が出てきます。</p>
<p>これを Terraform Cloud に変えると、 Terraform 実行者は誰もが Cloud 上のすべての tfstate を参照し合うことが可能になります。 tfstate をあえて管理対象クラウドの外に引っ張り出して集めておくことにより、集約的な設定データベースのように取り扱うことができます。</p>
<p><a href="https://gyazo.com/5f6edc1d4ea6593710d8fb5a09b259cb"><img src="https://i.gyazo.com/5f6edc1d4ea6593710d8fb5a09b259cb.png" alt="Image from Gyazo" width="501"/></a></p>
<hr>
<h2>ミクロ tfstate 論</h2>
<p>本項ではミクロに見た tfstate として、ファイルの編集処理に着目します。</p>
<h3>既存リソースの取り込み</h3>
<p>Terraform を扱う上で鬼門になる要素の1つに、「既存リソースの取り込み」があります。 tffile を書かなくてはならないのと同時に、 tfstate にも記述を加えなくてはならない点が厄介です。</p>
<p>この問題を解決するために <a href="https://github.com/dtan4/terraforming">dtan4/terraforming</a> や <a href="https://github.com/GoogleCloudPlatform/terraformer">GoogleCloudPlatform/terraformer</a> が開発されてきました。これらのツールで対処可能であれば、ツールを利用するのが手早いと思います。ツールが残念ながら対応していないリソースを取り込みたい場合には、 <code>terraform import</code> コマンドを使うことになります。</p>
<p><code>terraform import</code> は tfstate への取り込みだけを行う機能で、 tffile は作成してくれませんが、ある程度工夫することで楽はできます。まず、 tffile に Terraform resource の枠だけ作成してから <code>terraform import</code> を実行します。枠とは以下のように attributes を何も書き込まない状態です。 <code>import</code> は、対応する resource の記述が tffile に存在していないと動作しないため、 <code>import</code> 実行前にこれだけは必要になります。</p>
<pre><code class="language-bash">$ cat main.tf
resource "aws_lambda_function" "example" {
}

$ terraform import aws_lambda_function.example exampleFunction
aws_lambda_function.example: Importing from ID "exampleFunction"...
</code></pre>
<p>import が完了次第、 import した resource を引数にして <code>terraform state show</code> を実行します。するとこのように、 tfstate の記述を元にして、現在の設定情報が HCL の形で出力されます。</p>
<pre><code class="language-bash">$ terraform state show aws_lambda_function.example
# aws_lambda_function.example:
resource "aws_lambda_function" "example" {
    arn                            = "arn:aws:lambda:ap-northeast-1:999999999999:function:exampleFunction"
    function_name                  = "exampleFunction"
    handler                        = "Handler"
    id                             = "exampleFunction"
    invoke_arn                     = ...
    last_modified                  = "2019-12-13T03:35:41.026+0000"
    memory_size                    = 512
    ...

    timeouts {}

    tracing_config {
        mode = "PassThrough"
    }
}
</code></pre>
<p>あとはこれをコピペして tffile を fix すれば取り込み完了です。 <code>terraform state show</code> が v0.12 より HCL 形式で出力されるようになったことで、取り込み処理が非常に楽になりました。注意点として、この HCL には tffile には必要のない <code>attributes references</code>  に該当する値も含まれています。そのままにしていても害はありませんが、不要な値を持っておくべきでもありませんので削除しておきましょう。 <code>attributes references</code> について詳しくは、本ブログの <a href="https://chroju.github.io/blog/2019/11/02/terraformer_includes_unnecessary_resource_attributes/">Terraformer が import した resource は不要な属性を含む場合がある · the world as code</a> を参照してください。</p>
<h3>tfstate の保存場所を変更したい</h3>
<p>tfstate を現在の保存場所から別の場所へ移したい場合があると思います。最近であれば Terraform Cloud がローンチされた際、 S3 などから移行した方は多かったでしょうし、 S3 内でファイルの key（パス）だけ替えたいといった需要もあるかと思います。</p>
<p>この操作は意外と簡単で、まず一度 <code>terraform init</code> を実行してから、 tffile の <code>backend</code> の部分を移行先のパスに書き換えてもう一度 <code>terraform init</code> を実行するだけです。 Terraform が以下のように backend の変更を検知して、 tfstate ファイルを移動させるか尋ねてくれます。これを承諾すれば、 Terraform がファイル移動を賄ってくれます。</p>
<p><a href="https://gyazo.com/f2ba5d64ab5e699f631ba3922824023f"><img src="https://i.gyazo.com/f2ba5d64ab5e699f631ba3922824023f.png" alt="Image from Gyazo" width="650"/></a></p>
<p>これは「入門」の項で記載した <code>./.terraform/terraform.tfstate</code> に書かれた backend 設定と、 tffile に書かれた backend 設定に差異があったとき、 backend が変更されたとみなして実行される処理です。</p>
<h3>tfstate の編集</h3>
<p>tfstate の編集が必要になるのは、 tffile、 tfstate、現実のリソースの三者間で乖離が発生してしまい、 <code>terraform plan</code> の結果が予期せぬものになってしまうような場合です。 tfstate が変更されてしまった、というケースは無いものとして考えると、 tffile を変更したか、現実のリソースを変更したか、いずれかの場合ということになります。このうち現実のリソースを変更した場合については、先にも触れましたが <code>terraform refresh</code> コマンドを実行すれば事足ります。</p>
<h3>tfstate の編集 - tffile を変更（リファクタリング）した場合</h3>
<p>最も手数を要するのが、リファクタリングなどにより tffile 上の resource name を変更したり、 module の構成を変更したりした場合です。 <code>aws_instance.foo</code> を <code>aws_instance.bar</code> にリネームした場合、 tfstate 上の <code>foo</code> は tffile 上に見つからないので削除対象とされ、 tffile 上の bar は tfstate 上に見つからないので新規構築対象とされてしまいます。</p>
<p>このようなときには <code>terraform state mv</code> コマンドを使って、変更前の名前から変更後の名前へと移し替えていきます。先の例で言えば</p>
<pre><code class="language-bash">$ terraform state mv aws_instance.foo aws_instance.bar
</code></pre>
<p>となります。この <code>aws_instance.foo</code> のような記述形式は Terraform のドキュメント内で <code>address</code> と呼ばれています。 address の書式は resource type と resource name をドットで繋いだ形です。 module に内包された resource の場合は <code>module.(module 名).(resource type).(resource name)</code> の形になります。 module を入れ子にしていると、さらに <code>module.(module 名).module.(module 名)...</code> と数珠つなぎで繋がっていきます。</p>
<p>mv の対象がかなりの数に上ってくると、 address を手で書いてコマンド実行するのが面倒になってきます。こういうときは一旦 <code>terraform plan</code> を実行してしまいましょう。先に書いた通り、 mv 前の tfstate に残っているリソースは削除対象に、 mv 後の tffile に新しく命名されたリソースは新規構築対象になるので、 <code>will be (destroyed|created)</code> という文字列で grep することで、 mv 前後の address をそれぞれ取得できるはずです。</p>
<p><a href="https://gyazo.com/88e0dbb61fb4b9ee1620a174999b1b71"><img src="https://i.gyazo.com/88e0dbb61fb4b9ee1620a174999b1b71.png" alt="Image from Gyazo" width="493"/></a></p>
<p>あとはいい感じに shell script にでも編集し直して実行してしまいましょう。</p>
<h3>tfstate の編集 - リスト化した場合</h3>
<p>注意が必要なのが、もともとバラバラに定義していたリソースを、 count などで一括処理する形へ変更した場合です。この場合、 mv 先は <code>aws_instance.web_servers[0]</code> のようにリストの1要素という形になりますが、この <code>web_servers</code> というリスト自体が tfstate にまだ存在していない状態だと、そのリストへ要素を追加するという処理は実行できません。</p>
<p><a href="https://gyazo.com/3543958dcee3f500bb135976875c8815"><img src="https://i.gyazo.com/3543958dcee3f500bb135976875c8815.png" alt="Image from Gyazo" width="689"/></a></p>
<p>対処としては、一旦 <code>count = 0</code> として、リストを空の状態で <code>terraform apply</code> を実行し、 tfstate へリストを作成した上で mv を実行することになります。</p>
<h3>tfstate の直接編集</h3>
<p>さて、最後に禁断の tfstate 直接編集についても少し触れておきます。禁断の、と言っても本当に手で編集してほしくなければバイナリにするでも暗号化するでも方法はあると思うので JSON で書くということはそういうことなんでしょう、とは思っています。</p>
<p>とは言ったものの、私は直接 tfstate 編集することはここ2年ぐらいもうやっていないような気がします。 <code>state</code> サブコマンドの実装でかなり状況が改善されつつはあるというのが1つ。それでも編集が必要なケースについては、もう諦めて Terraform を書き直したほうが早いと思っているのが1つ。 tfstate 直接編集はあまりに尖ったスキルすぎて、チーム内での共有などがしづらいというのが1つです。</p>
<p>Terraform が多少乱れたり使い物にならなくなったところで、先述したように <code>import</code> などを上手く使えば、ゼロから作り直すこともできなくはありません。 Martin Fowler が提唱した<a href="https://www.infoq.com/jp/news/2014/11/sacrificial-architecture/">「犠牲的アーキテクチャー」</a>という考え方がありますが、一旦すべて書き直したほうが結局コストも低く、クオリティも高くなる可能性はあります。 tfstate を直接編集しなければならない状況に追い込まれたら、そのように思考を転換するのも一手かと思います。</p>
<p>どうしても直接編集をする場合は、 <code>terraform state pull > terraform.tfstate</code> で一度ダウンロードしてから編集を行い、完了後に <code>terraform state push terraform.tfstate</code> する形を取ります。編集中は <code>terraform plan -state=terraform.tfstate</code> をこまめに行い、致命的な編集ミスがないことを都度確認することを勧めます。</p>
<hr>
<h2>最後に</h2>
<p>自分の経験として、 Terraform を使っていて悩まされる機会が多いのが tfstate です。そこでいくつかプラクティスをまとめて記事にしようと思っていたのですが、いつの間にか分量が膨らみ、どうせならと網羅的な「概論」という形になってしまいました。</p>
<p>tfstate の挙動や背景を知ることで、 Terraform への理解も一層深まると思いますので、ここに書いていないことについても是非深堀りしてみてください。</p>
<h3>更新履歴</h3>
<ul>
<li>2021-08-22 : <code>terraform plan</code> 時における <code>refresh</code> の実行に関して追記。</li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/terraform_state_introduction</link>
            <guid isPermaLink="false">terraform_state_introduction</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 13 Dec 2019 12:50:10 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Terraform meetup tokyo#3 に参加した]]></title>
            <description><![CDATA[<p><a href="https://terraform-jp.connpass.com/event/153286/">Terraform meetup tokyo#3</a> に参加してきました。今回「Blog枠」という形で参加させてもらったので、そのノルマも兼ねて書いています。</p>
<h2>Terrraforrm meetup tokyo について</h2>
<p>Terraform ユーザーグループによるイベントは月1回開催されており、この meetup と source code reading が交互に行われます。 meetup は今回が3回目の開催で、自分は前回に続き2回目の参加でした。</p>
<p>LT や発表枠ももちろんあるのですが、この meetup で特徴的なのは World Cafe だと思います。 World Cafe の定義について、詳しくは <a href="http://world-cafe.net/about/">ワールド・カフェとは？ | ワールド・カフェ・ネット</a> に譲りますが、 meetup ではランダムな最大6人グループで自由に議論する時間が30分×2回設けられています。 Terraform はまだ枯れきったソフトウェアとは言い難く、ベストプラクティスの模索が常に行われているような状況なので、ユーザー間でユースケースを共有し合えるこのような試みは、非常に有意義に感じています。</p>
<h2>イベントレポート</h2>
<p>以下、簡単に今回のレポートです。</p>
<h3>スポンサー枠: Terraform Enterprise を導入して Terrform v0.10 から v0.12 に上げた話 / sudoyu</h3>
<iframe src="//www.slideshare.net/slideshow/embed_code/key/93ZBaBpaIVY4Pg" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/RecruitLifestyle/journey-to-terraform-enterprise-with-upgrading-v010-to-v012" title="Journey to Terraform Enterprise with upgrading v0.10 to v0.12" target="_blank">Journey to Terraform Enterprise with upgrading v0.10 to v0.12</a> </strong> from <strong><a href="https://www.slideshare.net/RecruitLifestyle" target="_blank">Recruit Lifestyle Co., Ltd.</a></strong> </div>
<p>Terraform Enterprise の導入レポートでした。現在だと Terraform Cloud も同様の機能を持っていると認識していますが、社内のコード管理に IP アクセス制限をした GitHub Enterprise を用いており、その制約上 Cloud は導入が難しかったとのこと。気になるのは金銭面ですが、「 Terraform スペシャリストを雇うより安いと判断した」という言葉が印象的でした。</p>
<h3>LT1: terraform vs cdk / oracle</h3>
<div style="left: 0; width: 100%; height: 0; position: relative; padding-bottom: 56.25%; padding-top: 30px;"><iframe src="https://docs.google.com/presentation/d/1jXCZ-MnT9-x7etUGdeN62GuK2GmF1XAT99s5PlYiiIY/preview?usp=embed_googleplus" style="border: 0; top: 0; left: 0; width: 100%; height: 100%; position: absolute;" allowfullscreen scrolling="no" allow="encrypted-media"></iframe></div>
<p>最近新たに AWS コード化界隈に参戦した cdk と Terraform の比較の話です。 Terraform で言う hoge が cdk では fuga に対応する、というようなことがまとめられているので、概念理解の助けになりました。まだ cdk は触ったことがないので、触ってみたいところ。</p>
<h3>LT2: GitHub Actions で Terraform を plan/apply してみた / dehio3</h3>
<div style="left: 0; width: 100%; height: 0; position: relative; padding-bottom: 56.1972%;"><iframe src="https://speakerdeck.com/player/2518a2eee62840c992a05b474dd217b7" style="border: 0; top: 0; left: 0; width: 100%; height: 100%; position: absolute;" allowfullscreen scrolling="no" allow="encrypted-media"></iframe></div>
<p>GitHub Actions の workflow はすでに公式で <a href="https://github.com/hashicorp/terraform-github-actions">hashicorp/terraform-github-actions: Terraform GitHub Actions</a> が公開されています。プルリクをトリガーして plan した結果をコメントに貼ってくれる、王道な workflow を簡単に導入できちゃうのがいいですね。</p>
<h3>LT3: Deep Dive HCL / Keke</h3>
<div style="left: 0; width: 100%; height: 0; position: relative; padding-bottom: 56.1972%;"><iframe src="https://speakerdeck.com/player/d77bdadfea614f7583e92530cd202297" style="border: 0; top: 0; left: 0; width: 100%; height: 100%; position: absolute;" allowfullscreen scrolling="no" allow="encrypted-media"></iframe></div>
<p>Terraform の tf ファイルを記述する際には HCL と呼ばれる言語（書式？）が使われますが、その構造や仕様について説明された LT でした。私も HCL のパースなどに使える <a href="https://github.com/hashicorp/hcl">hashicorp/hcl</a> は少し読んだことがありますが、 <a href="https://buildmedia.readthedocs.org/media/pdf/hcl/guide/hcl.pdf">仕様のホワイトペーパー</a> が公開されていることは知りませんでした。後で読んでおきたい。</p>
<h3>LT4: インフラ実装をUMLで設計する / Toshihiko Nozaki</h3>
<div style="left: 0; width: 100%; height: 0; position: relative; padding-bottom: 56.1972%;"><iframe src="https://speakerdeck.com/player/b167fd6b61534447b4e18c4b4473f5c6" style="border: 0; top: 0; left: 0; width: 100%; height: 100%; position: absolute;" allowfullscreen scrolling="no" allow="encrypted-media"></iframe></div>
<p>Infrastructure as Code に関しても、きちんと UML を書いてコンポーネント分割して書こうというお話でした。このあたりの話はすごく興味があります。Kief Morris『Infrastructure as Code』でも、 Robert C. Martin『Clean Code』を挙げた上で、「インフラストラクチャのコーダーにも、ソフトウェアデベロッパと同じくらい重要なテーマだ」と書かれています（p.184）し、メンテしやすいコードを書くことは追求していきたい。</p>
<h3>LT5: 各環境とRoot Module(tfstate)・workspaceの対応付けパターンを比較してみた / k_bigwheel</h3>
<div style="left: 0; width: 100%; height: 0; position: relative; padding-bottom: 56.25%; padding-top: 30px;"><iframe src="https://docs.google.com/presentation/d/1N1GBk72OBgBtz5cYRmR22OqD3N8NIlZIgkGCSdRuPlg/preview?usp=embed_googleplus" style="border: 0; top: 0; left: 0; width: 100%; height: 100%; position: absolute;" allowfullscreen scrolling="no" allow="encrypted-media"></iframe></div>
<p>開発、検証、本番環境で tfstate を分けることが多いと思いますが、その際に module や workspace をどう使って分割するべきか、というお話。各パターンのメリデメを細かくまとめられた資料が印象的でした。この手の話は空中戦になりやすかったりもするので、きちんと「書いて考える」ことが重要だなーと気付かされました。</p>
<h3>World Cafe</h3>
<p>World Cafe では Terraform をこれから社内へ導入していきたい方、 GCP で使っている方や AWS で使っている方など、様々なバックグラウンドを持った方とお話ができました。出た話題を簡単にピックアップしておきます。</p>
<ul>
<li>CloudFormation や Ansible と比較した Terraform の訴求ポイントはどこか？</li>
<li>provider のバージョンアップへの追随はどうしているか？</li>
<li>社内で認知度が低い場合、どう広めていったらよいか？</li>
<li>Terraform Cloud をすでに利用しているか？</li>
<li>Terraform レポジトリのディレクトリ構成はどんな感じ？</li>
</ul>
<h3>Additional LT: 突撃！隣の Terraform / chaspy</h3>
<div style="left: 0; width: 100%; height: 0; position: relative; padding-bottom: 74.9296%;"><iframe src="https://speakerdeck.com/player/3ff8a8e594124b9188ff028b59531bfa" style="border: 0; top: 0; left: 0; width: 100%; height: 100%; position: absolute;" allowfullscreen scrolling="no" allow="encrypted-media"></iframe></div>
<p>ここまででメインは終了ということで私は帰ってしまったのですが、その後の延長線で追加 LT があったらしいです。内容は「突撃！隣の Terraform」ということで、 Kyash とメルカリで実際どのように Terraform のディレクトリ構成を切っているか見に行った話だったようです。これは聞いてみたかった。。。</p>
<h2>Impression</h2>
<p>前回も今回もそうでしたが、 Terraform のファイルやディレクトリをどう構成していくかという点で悩んでいる人が結構多いという印象を受けました。ていうか私自身がそうです。そういう状況を踏まえても、やっぱり World Cafe で直接情報交換ができるというのはすごく嬉しい機会だなと改めて感じました。次回以降いらっしゃる方は、何か話したいネタ、聞きたいネタを用意してくると捗ると思います。</p>
<p>最後になりましたが、運営いただいた主催者の方々、フード提供いただいた HashiCorp さん、ありがとうございました。</p>
]]></description>
            <link>https://chroju.dev/blog/terraform_meetup_tokyo_3</link>
            <guid isPermaLink="false">terraform_meetup_tokyo_3</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 04 Dec 2019 12:43:01 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[CUI 開発環境 2019 - tmux, fzf, ghq, Starship, aws-vault, etc]]></title>
            <description><![CDATA[<p><a href="https://chroju.github.io/blog/2019/06/14/become_parallel_worker_and_university_student/">パラレルワーカー兼大学生になることになった · the world as code</a> で書いた新しい職場に入って、実はエンジニア人生9年目にして初めて macOS をメインで与えられる職場に入りまして。今まで全部 Windows だったというなかなか自分でも信じがたい事実（まぁ Linux で VM 立ち上げてその中で作業したりコーディングしてたりもしたけど）。それで macOS だと常に zsh 開いておけるし（ Windows でもできなくはないが）、シェルで生活する時間が大幅に増えたので、これを期にと CUI の開発環境を整えたので一旦まとめておく。ざっくり以下の技術あたりを使っているので順に書く。</p>
<ul>
<li>tmux</li>
<li>fzf</li>
<li>ghq</li>
<li>Starship</li>
<li>aws-vault</li>
</ul>
<h2>tmux</h2>
<p>https://github.com/tmux/tmux</p>
<p>4年ぐらい前に一度入門したものの、 iTerm2 のタブと画面分割があれば別にいいかなという感じで使わなくなっていたのを改めて使い始めた。きっかけになった理由は実はだいぶ些細で、 macOS の全画面表示ってメニューバーを隠してしまうので時間がわからないのが困って、ステータスバーに時刻を表示したくなったというところ。実際使い始めてみるとセッションを作って長くかかるコマンドを裏で実行させたままデタッチして別のことやる、みたいなのがなかなか便利で手放せなくなりつつはある。</p>
<p>以前使っていた tmux.conf を引っ張り出してはみたが、 powerline 周りの設定は忘れているし、学習コストかけたくもなかったので外部プラグインへの依存はやめた。 tmux デフォルトのステータスバーを使って時刻などは表示している。</p>
<p><a href="https://gyazo.com/094ef9703c2af0f99d811193548d57b8"><img src="https://i.gyazo.com/094ef9703c2af0f99d811193548d57b8.png" alt="Image from Gyazo" width="795"/></a></p>
<h2>fzf + ghq</h2>
<p>https://github.com/junegunn/fzf</p>
<p>fzf は以前から興味はあったけど使ってなくて、というか動作原理がよくわかっていなかったのだが、ちゃんと使ってみたらすごく便利だった。</p>
<p>複数行のテキストを標準入力から突っ込むと、曖昧検索ができる TUI が開き、そこで検索をして1つ結果を選択すると、その文字列を吐き出すという、日本語で書くとこういう動作をする。例えば git のブランチ切り替えだとか、複数のファイルから1つ選んで開くとか、そういう「多くの選択肢から絞りたい」操作をするのに役立つ。まぁ見たほうが早いと思う。</p>
<p><a href="https://gyazo.com/69ddc6d8e70ddc5ae4ea83c26bd9cd4c"><img src="https://i.gyazo.com/69ddc6d8e70ddc5ae4ea83c26bd9cd4c.gif" alt="Image from Gyazo" width="1000"/></a></p>
<p>こういう感じ。ただ、手でこういう風に <code>fzf</code> コマンドをわざわざ打つのではなくて、基本的な使い方としてはよく使うコマンドを関数として定義して <code>.zshrc</code> などに書いておいて、必要に応じて呼び出すという形を取る。</p>
<p>https://github.com/motemen/ghq</p>
<p>これと組み合わせて使うとすごく良いのが ghq 。ローカルに置く git レポジトリを管理してくれるツールで、 <code>.gitconfig</code> に以下のように root となる場所を書いた上で <code>ghq get chroju/chroju.github.io</code>  と打つと root 配下に <code>git clone</code> してくれる。そして <code>ghq list</code> で、 root 配下に置かれた git レポジトリの一覧をずらっと出力してくれる。つまり fzf と組み合わせるとこういう関数が書けるということ。これがだいぶ快適で1日100回ぐらい打ってる。</p>
<pre><code class="language-bash">fghq() {
  local dir
  # fzf-tmux は tmux で検索用 TUI をペイン分割して表示してくれるコマンド
  dir=$(ghq list > /dev/null | fzf-tmux --reverse +m) &#x26;&#x26;
    cd $(ghq root)/$dir
}
</code></pre>
<p>他にも fzf はアイディア次第でいろんなことができそう。例えば AWS CLI と組み合わせて、 <code>ec2 describe-instances</code>  結果を食わせてインスタンス停止するとか、よくやるオペレーションを関数化しておいても便利かなと。</p>
<h3>ghq と GOPATH</h3>
<p>余談的な話。自分は Go を書く機会が多い。で、 Go のレポジトリは最近状況が変わってきてはいるけれど、 <code>$GOPATH </code> で指定したディレクトリを root として、 <code>$GOPATH/src/github.com/chroju/...</code> という具合の場所に置かれるというのがスタンダードになっている。</p>
<p>Go とそれ以外のコードでレポジトリの置き場が替わるのも嫌なので、自分は <code>$GOPATH/src</code> にあたるディレクトリを ghq の root として設定している。幸い Go も ghq も <code>github.com/chroju/chroju.github.io</code> という形でディレクトリを掘って clone してくるので、この設定によって Go でも非 Go でも気にせず同様の構成でディレクトリが管理できている。</p>
<p>このあたりは以下のエントリにインスパイアされている。</p>
<p>https://songmu.jp/riji/entry/2019-03-28-go-modules.html</p>
<h2>Starship</h2>
<p>http://starship.rs/</p>
<p>プロンプトをいい感じにしてくれる Rust 製のツール。スクショは tmux のときに貼ったものを参照。</p>
<p>以前までは zsh のプロンプト設定を自分で書いていたんだけど、あんまり可読性のいい記法ではないし、しばらく経つと書き方を忘れてしまうので外部ツールに頼って楽をすることにした。 Starship が良いのはシェル依存ではないので、仮に今後 Fish に移りたくなってもそのまま持っていけるということ。 <code>brew install</code> して <code>eval "$(starship init zsh)"</code> したらその瞬間からプロンプトがいい感じになる。</p>
<p>設定も豊富でよい。デフォルトの状態で git 関係の表示、ディレクトリ表示はやってくれるし、カレントディレクトリに <code>go.mod</code> があれば Go のバージョン、 <code>requirements.txt</code> があれば Python のバージョンを表示してくれる。設定の追加もできて、自分の場合は <code>AWS_PROFILE</code> を設定していたらそれを表示するようにしている。基本的には使わない環境変数だけど、たまに動作確認などでセットしたまま忘れてたりするので、事故防止になっていい感じ。</p>
<p>powerline font を求められることだけ面倒なんだけど、たぶん設定変更して絵文字を使わないようにしてやればそれも要らなくなる気がする。</p>
<h2>aws-vault</h2>
<p>https://github.com/99designs/aws-vault</p>
<p>macOS の Keychain と連携して AWS API のアクセスキーを管理してくれるツール。別の AWS アカウントへ switch する <code>assume role</code> 操作がすごく楽になるのでそれで使っている。以下は README からの引用だけど、 <code>~/.aws/config</code> をこんな風に書いて <code>aws-vault exec prod-readonly -- aws ec2 describe-instances</code> という具合に実行すると、これで switch ができる。</p>
<pre><code class="language-ini">[profile jonsmith]
region = us-east-1

[profile prod-readonly]
region=us-east-1
role_arn = arn:aws:iam::111111111111:role/ReadOnly
source_profile = jonsmith
</code></pre>
<p>重宝するのは、これで Terraform も assume role での実行ができること。以前 <a href="https://chroju.github.io/blog/2018/12/10/terraform_with_aws_assume_role/">Terraform で AWS assume role が使用できない場合がある · the world as code</a> で書いたとおり、基本的に Terraform は assume role に対応できていないので、この方法を使うのが一番ラクだと思う。</p>
<h2>Conclusion</h2>
<p>https://github.com/chroju/dotfiles</p>
<p>今書いたような設定は全部 dotfiles としてレポジトリにまとめているので、コードで見てもらったほうが早いのかも知れないです。 Ansible 流して会社 macOS の設定が数分で終わったときにはやるやんけ自分ってちょっと思いました。</p>
]]></description>
            <link>https://chroju.dev/blog/development_environment_2019</link>
            <guid isPermaLink="false">development_environment_2019</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 17 Nov 2019 03:45:58 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Terraform Source Code Reading#3 に参加した]]></title>
            <description><![CDATA[<p>https://terraform-jp.connpass.com/event/150359/</p>
<p>先週開催されたこちらのイベントに参加しました。</p>
<h2>参加の動機</h2>
<p>Terraform の AWS provider には何度か commit 経験はあるものの、 Terraform 本体のソースコードや、本体と provider 間のやり取りに関してはあんまり読んだことがなくて、コードリーディングを進めてみたかったというのが1つ。また自分はソフトウェアエンジニア出身ではないので、そもそものコードリーディングのやり方があんまり効率良い感じがしていなくて、他の方々（特に Terraform なのでインフラ寄りの方が多そうだし）がどんな感じで読んでいるのか知りたかったのが1つという感じです。</p>
<p>ソースコード読んでコントリビュートもしている人が参加する勉強会となるとそれなりに強い人がいっぱいいそうでだいぶドキドキしてました。</p>
<h2>当日の流れ</h2>
<p>当時は20人に少し足りないぐらいの人数が参加してましたが、全員で1つのことをやるのではなく、読みたいソースコードごとにグループ分けがありました。具体的には Terraform 本体を読むグループ、 AWS provider を読むグループが2つ、その他の provider を読むグループが1つの計4グループ。私はと言えば AWS provider を読んでました（あれ？）。</p>
<p>で、特に当日は決められた筋書きはなし。各グループで集まった人同士でやりたいことを話し合って決めて、それぞれで進めていき、最後に全員で一言ずつ成果報告をするという形でした。</p>
<h2>やったこと</h2>
<p>私のグループでは issue を漁ってプルリクエストを送れそうなものがあったら送ってみようという形で進めました。4人グループで、 contribute 経験者が私含めて2人、他2人はこれからやってみたい、という感じでした。</p>
<h3>contribute チャンスをどう見つけるか</h3>
<p>しかし正直結構難しい。例えば OSS contribute を志し始めた人へのアドバイスとして <code>good first issue</code> ラベルが付いたものが取り組みやすい、というものがありますが、<a href="https://github.com/terraform-providers/terraform-provider-aws/labels/good%20first%20issue">今日時点で2299件中17件しかありません。</a> もちろん絶対数で見ればそれなりの数がありますけど、比率で言うと1%未満だし、年単位で塩漬けにされている issue も多くて必ずしも手を付けやすいものではないかなという印象がありました。</p>
<p>当日1つ、 Pull Request のきっかけとして有力な方法かもしれないと見つけたのが、 <a href="https://github.com/aws/aws-sdk-go/releases">aws-sdk-go の release</a> を定期的に見ること。これがなかなかエゲツない頻度で更新されていて、 API が更新されれば Terraform 側にもそれを吸収しなくてはならない場合というのが当然出てきます。なので aws-sdk-go 側の更新を見張っていれば contribute チャンスも見えてくるのではないかと。</p>
<p>あとは自分の経験上ですけど、ドキュメントに小さな誤字があることは案外多いのでチャンスも転がってますよという話をしました。実際、当日ドキュメント修正で時間内にプルリクエストを上げられた方がいました。</p>
<p>Terraform のコードはとにかく膨大なので、なかなか contribute するぞ！という目的で挑んでも難しい部分がある気がしました。自分のこれまでを振り返ってもバグを踏んでから contribute に至ったのがほとんどです。</p>
<h3>validators.go に関する知見</h3>
<p>https://github.com/terraform-providers/terraform-provider-aws/issues/9445</p>
<p>これは個人的な話ですが、以前上記 issue にハマったことがありました。 <code>aws_route</code> resource には、ルーティング先に各種ゲートウェイを指定する <code>nat_gateway_id</code> や <code>transit_gateway_id</code> といった argument があります。本来であればゲートウェイの種類ごとに異なる argument を遣うべきところ、 <code>gateway_id</code> という argument が NAT ゲートウェイとインターネットゲートウェイのどっちも受け付けちゃうんですね。なので値のバリデーションをして、 NAT ゲートウェイは受け付けないようにするべきというのがこの issue です。</p>
<p>この issue 、私はバリデーションの実装方法に迷ったのと、すでに author が自分でやると言っていたので放っておいてました。しかし今回の勉強会でこの話をしたところ、 <a href="https://github.com/terraform-providers/terraform-provider-aws/blob/master/aws/validators.go">validators.go</a> というファイルがあり、ここにバリデーション処理が集約されていると教えてもらいました。自分で気付けていなかったことを知ることができてとても有意義な経験でした。</p>
<p>これでプルリクも出せるようになったし、先の「俺がやる」と言ってる人も数か月放置してるから、もうこっちで出しちゃってもいいかなと思ってます。</p>
<h2>感想</h2>
<p>みんなで議論をするような形を想像していたところ、もくもく会に近い雰囲気だったのでちょっと想像とは違いました。が、具体的にコードを踏まえた話が出来たのは楽しかったです。 Terraform ユーザーグループはこの Code Reading と meetup を交互に繰り返す形ですが、いずれもただ前に出た人が発表するのではなく、参加者同士話す場を中心にしているのがとてもいいなと思いました。</p>
<p>ただグループ分けに関してはレベル別とか目的別とかでもいいんじゃないかなーという気はしました。読む対象レポジトリごとのグループ分けだと、メンバー間の意識や目的をなかなか揃えにくく、どうしようかと悩む、迷う時間が少なくなかったです。あるいは個々人で目的を持って読んでいくもくもく会的な感じですよ、と言い切ってしまうか、かなと。</p>
<p>ちなみに読んだだけで終わるのもアレだったので、後日ですが issue 1個解決を図ってみました。定期的に issue を覗いてやれそうなものにチャレンジしていくのも勉強としては良さそうです。</p>
<p>https://github.com/terraform-providers/terraform-provider-aws/pull/10819</p>
]]></description>
            <link>https://chroju.dev/blog/terraform_source_code_reading_3</link>
            <guid isPermaLink="false">terraform_source_code_reading_3</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 10 Nov 2019 06:11:37 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Terraformer が import した resource は不要な属性を含む場合がある]]></title>
            <description><![CDATA[<p>小ネタです。</p>
<p>以前このブログの <a href="https://chroju.github.io/blog/2019/05/14/read_terraform_source_code/">3rd Party tool をきっかけに Terraform のソースコードを少し嗜んだ話 · the world as code</a> というエントリーでも取り上げた <a href="https://github.com/GoogleCloudPlatform/terraformer">terraformer</a> 。既存のクラウドリソースを元に terraform file を作成してくれる便利ツールなのだが、時に必要ない属性値を resource に含んだファイルを作ることがある。</p>
<pre><code class="language-hcl">resource "aws_s3_bucket" "tfer--chroju-002E-net" {
  acl            = "private"
  arn            = "arn:aws:s3:::chroju.net"
  bucket         = "chroju.net"
  force_destroy  = "false"
  hosted_zone_id = "XXXXXXXXXXXXXX"
  region         = "ap-northeast-1"
  request_payer  = "BucketOwner"

  versioning {
    enabled    = "false"
    mfa_delete = "false"
  }

  website {
    index_document = "index.html"
  }

  website_domain   = "s3-website-ap-northeast-1.amazonaws"
  website_endpoint = "chroju.net.s3-website-ap-northeast-1.amazonaws.com"
}
</code></pre>
<p>例えばこれは自分の S3 バケットを import してみた実際の結果（一部マスクあり）なのだけど、いくつか不要な値を含んでいる。具体的には <code>arn</code> , <code>website_domain</code> , <code>website_endpoint</code> の3点。ドキュメント <a href="https://www.terraform.io/docs/providers/aws/r/s3_bucket.html">AWS: aws_s3_bucket - Terraform by HashiCorp</a> を見るとわかるが、これらは <code>Attributes References</code> 、つまり他の resource から参照可能な属性であって設定に必要な値ではない。</p>
<p>ではこれは余計な値でバグなのではないか、と思いたくなるところなのだけど、面白いのはこのまま <code>terraform</code> コマンドを打ってもエラーにはならないということ。以下、試しに ARN を <code>hogefuga</code> という値に変更して <code>terraform apply</code> して、その後再度 <code>plan</code> で結果を確認してみたサンプルを貼る。</p>
<script id="asciicast-2HP4t3MJhnhogQj1QgubaHydG" src="https://asciinema.org/a/2HP4t3MJhnhogQj1QgubaHydG.js" async></script>
<p>ARN は AWS 側が一定の法則に則って自動採番する ID であり、当然ながらユーザーが任意で変更はできない。それなのに <code>plan</code> の結果として ARN の変更は予告され、そして <code>apply</code> も通ってしまうのが面白い。しかし <code>apply</code> 後に <code>plan</code> を実行すると、依然差分として表示はされるので、実際に <code>apply</code> が通ったわけではない。当たり前だけど、ちょっと挙動としては不安にもなる。</p>
<p>ちなみにこの状態から ARN を削除してみても、 <code>terraform plan</code> の結果は <code>No Changes</code> になり、 ARN が削除されるようなことはない（そりゃそうなんだが）。そのため Terraformer の import 結果に不要な値が含まれていたら、運用上の混乱を避ける意味でも、手で削除してしまうのが無難ではある。</p>
<h2>原因</h2>
<p>ではなぜこのような挙動になるのかだが、原因は Terraform の実装にある。</p>
<p>Terraform の各 resource にどのような attributes を含むかは、 <code>&#x26;schema.Resource.Schema</code> に <code>map</code> の形で定義されている。 AWS S3 の場合は <a href="https://github.com/terraform-providers/terraform-provider-aws/blob/master/aws/resource_aws_s3_bucket.go">terraform-provider-aws/resource_aws_s3_bucket.go at master · terraform-providers/terraform-provider-aws</a> で、冒頭だけ抜き出すとこのような形。</p>
<pre><code class="language-go">		Schema: map[string]*schema.Schema{
			"bucket": {
				Type:          schema.TypeString,
				Optional:      true,
				Computed:      true,
				ForceNew:      true,
				ConflictsWith: []string{"bucket_prefix"},
				ValidateFunc:  validation.StringLenBetween(0, 63),
			},
			"bucket_prefix": {
				Type:          schema.TypeString,
				Optional:      true,
				ForceNew:      true,
				ConflictsWith: []string{"bucket"},
				ValidateFunc:  validation.StringLenBetween(0, 63-resource.UniqueIDSuffixLength),
            },
</code></pre>
<p>そしてここに並列で <code>Attributes References</code> に含まれる値も並んでいる。どれが <code>Arguments</code> （設定値）でどれが <code>Attributes</code> なのかを識別できるような箇所はない。そのため resource の中に <code>Attributes</code> にあたる値を書き入れても、エラーにはならない。</p>
<p>また Terraformer を使用した際の挙動としては、 Terraform の <code>refresh</code> コマンドに相当するメソッドを呼び出す形になる。 <code>refresh</code> といえば現在のクラウドリソースの状態を取得して、 tfstate を書き換えるというもの。 tfstate 側には <code>Attributes</code> に相当する値も含まれているため、 <code>refresh</code> を呼ぶ形だと <code>Attributes</code> も一緒に読み込んでくる形になる。だから Terraformer が作成する tf ファイルには、 <code>Attributes</code> が含まれるということになる。</p>
<p>現状、先述の通り Terraform の実装として <code>Arguments</code> と <code>Attributes</code> を識別する方法がないため Terraformer がこのような挙動をするのはやむを得ないと考えている。 Terraformer は Terraform の API を効率よく活用することで、個々のクラウドリソースの API を最小限にしか知る必要がない形で実装されている。各値が <code>Attributes</code> かどうかという情報は Terraform 側が持つべきであって、 Terraformer に実装させる必要はないだろう。幸い、見てきた通り <code>Attributes</code> を含めても Terraform はエラーにならないので、割り切ることもできなくはない。</p>
<h2>Impression</h2>
<p>以上、トリビアに近い小ネタを書いてみた。きっかけは実際に terraformer を使っていてこの挙動に気づいたことなのだけど、もうすぐ <a href="https://terraform-jp.connpass.com/event/150359/">Terraform Source Code Reading#3 - connpass</a> というイベントに参加することもあり、少し Terraform のコードを読む機会が欲しかった形。このイベント、それなりにレベル高いことやろうとしてるので、生きて帰れるのかむちゃくちゃ不安。</p>
]]></description>
            <link>https://chroju.dev/blog/terraformer_includes_unnecessary_resource_attributes</link>
            <guid isPermaLink="false">terraformer_includes_unnecessary_resource_attributes</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 02 Nov 2019 07:58:17 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[GitHub Actions (2019) ファーストインプレッション]]></title>
            <description><![CDATA[<p>GitHub Actions が新しくなって2か月ほど経つが、遅ればせながらいろいろと触ってみたのでインプレッションを書き留めておく。</p>
<p>まず最初に断っておくと、2019年8月に発表された GitHub Actions をこのエントリーでは「新版」、それ以前のものは「旧版」と表記する。タイトルも「新版」にしようかと思ったが、今後またリニューアルされた場合にどれが「新」なのかわからなくなるので「(2019)」とした。GitHub は新版に対して「GitHub Actions v2」とか、何かしら旧版と識別できる名称を付けるべきだったと思う。ググラビリティが著しく低くてわりと困っている。</p>
<p>Actions を書いたのは以下の2レポジトリ。前者はこのブログを支える hugo の自動化で、 <code>source</code> ブランチに <code>push</code> するとビルド結果を <code>master</code> へ <code>push</code> してくれる。後者は Go の一般的なビルドで、タグを切るとテストしてビルドしてバイナリを GitHub Release に貼ってくれる。</p>
<p>https://github.com/chroju/chroju.github.io</p>
<p>https://github.com/chroju/parade</p>
<h2>何が変わったのか</h2>
<p>GitHub Actions 旧版については昨年末に公開されて早々に触り、このブログにも感想を書いている。</p>
<ul>
<li>関連 : <a href="https://chroju.github.io/blog/2018/12/15/github_actions_first_impression/">GitHub Actions - Dockerfile を突っ込んで自動化するという考え方 · the world as code</a></li>
</ul>
<p>当時との差異として強く感じるのは2点ある。1つ目は記述言語自体変わったことで、 HCL から YAML に変わった。そもそも HCL は HashiCorp Configuration Language という名前通り、 もともと Terraform などの HashiCorp 製ツールの中だけで使われていた DSL なので、 HashiCorp と関わりの薄い GitHub がなぜ HCL を採用したのかが疑問だったし、これでよかったのではないかという気がしている。</p>
<p>2つ目は Action の実行環境。先のエントリーでも書いたが、GitHub Actions 旧版は一連のプロセスが Action という単位に分割され、 実行環境は各 Action で Docker コンテナが個別に起動されていくという形を取っていた。一方の新版では、 Linux / macOS / Windows の中から選んだ VM をワークフロー全体を通した実行環境として利用する。各 Action において旧版同様に Docker コンテナを立ち上げることもできるが必須ではなく、 VM 上で直にコマンドを実行させることもできる。これにより、ちょっとしたコマンドを実行したいときでさえ Dockerfile を書かなくてはならないというようなことは無くなったので、設定の柔軟性が高くなったと感じる。またワークフロー全体で1つの実行環境を共有するようになったことで、ソースを checkout してビルド、テストしてデプロイするという流れを組む、一般的な CI/CD 相当の Action を書きやすくなった。</p>
<p>もともと GitHub Actions は「CI/CD だけではなくて、 DevOps 全体における自動化サイクルを構築するもの」とされていた。先のエントリー内でもリンクした <a href="https://jp.techcrunch.com/2018/10/17/2018-10-16-github-launches-actions-its-workflow-automation-tool/">GitHubからワークフロー自動化ツール、Actions登場――独自サービス提供の第一弾 | TechCrunch Japan</a> を読むとよくわかる。</p>
<blockquote>
<p>誰かがリポジトリで「緊急」というタグを使った場合、<a href="https://twilio.kddi-web.com/availability/">Twilio</a> を使ってメッセージを送信するという仕組みを作ることができる。レポジトリを検索する一行のコードを書いてgrepコマンドで実行することもできる。</p>
</blockquote>
<p>つまり、レポジトリに直接紐付けられた FaaS に近いものを作ろうとしていたように見える。しかし実際のところユーザーが旧版でやろうとしたことの多くは CI/CD の範囲であり、今回の新版では、 CI/CD に軸足を置いた旨が明確に示されている。</p>
<p>https://cloud.watch.impress.co.jp/docs/news/1205405.html</p>
<h2>Impression</h2>
<p>自分のレポジトリ2つほどで使ってみた経験から感じたことを書こうと思うが、本職プログラマーではないためゴリゴリに重いビルドの CI で苦労した経験などが少なく、書けることは限定的だと思う、と前置きする。</p>
<h3>CI を始めるのに必要なことが YAML を書くことしかない</h3>
<p>YAML を書いて push すればそれだけでジョブが始まるのは体験としてすごく楽。 Circle CI にせよ AWS の開発者向けツールにせよ、何かしら GUI 操作は避けられなかったが、 GitHub Actions は完全に YAML だけで済む。 <code>GITHUB_TOKEN</code> という環境変数が自動的に発行されるので、自レポジトリへの操作も簡単にでき、タグを切る、 release にバイナリを添付するといった、 GitHub 上でやりたかった操作はだいたいすぐに出来るようになる。</p>
<h3>Action を共有できる</h3>
<p>ワークフローを組み立てる個々の Action は Docker コンテナか JavaScript で書くことができる。 Docker の Action は Dockerfile とその中で実行する処理内容を書いた <code>entrypoint.sh</code> 、 GitHub Actions 向けのメタ情報を書いた yaml から成るのだが、これを GitHub レポジトリで公開して、他者と共有することができる。 Circle CI の Orbs に近い。</p>
<p>すでに GitHub が公開する Action が https://github.com/actions にいくつか設けられており、これらは例えば Go や node.js といった言語環境構築といった、広く使われうるものが準備されている。その他 OSS などが Action を公開している場合ももちろんあって、例えば GitHub Release に Go のバイナリを添付してくれる goreleaser という CI で絶対使いたい超便利ツールがあるが、すでに Action を公開しており、簡単に導入できる。</p>
<p>https://github.com/marketplace/actions/goreleaser-action</p>
<h3>Trigger が豊富</h3>
<p>旧版の頃からそうだったけど、 Trigger が豊富なのがいい。 Git のプルリクエストや <code>push</code> をトリガーにする場合に、特定のファイルが変更されたのみトリガーさせることができるとか最高（インフラマンなので、インフラ用レポジトリに Ansible と Terraform 両方詰め込んでたりがあるあるなので、ディレクトリ単位で実行振り分けしたいことは多い）。</p>
<p>あと使い道は思いついていないが cron で定期実行できるのも興味深かった。 CI / CD を時間トリガーで実行したいケースはあまり無かろうと思うので、どちらかといえば先述のように旧版から希求していた「DevOps全体における自動化サイクルを構築する」ためのものだろうか。例えば issue の自動的なチェックだとか、レポジトリに関係する自動化タスクはここに定義しておくと見通しが良くなりそうではある。</p>
<p>長々と書いたけど個人的には楽、とにかく管理が楽というそれに尽きる。最近特に AWS Code 3兄弟をガチャガチャする機会が多くて Terraform 書いたり GUI ポチポチしたりというのに疲弊していたので、余計に「YAML 置けば OK」というのが魅力的に見えてるのだとは思う。もちろん他のツールのほうが利がある部分もあるわけだが、積極的に使っていきたいなとは感じている。</p>
]]></description>
            <link>https://chroju.dev/blog/github_actions_2019_first_impression</link>
            <guid isPermaLink="false">github_actions_2019_first_impression</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 30 Oct 2019 13:52:38 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[AWS Parameter Store をターミナルから操作する Parade を作った]]></title>
            <description><![CDATA[<p>https://github.com/chroju/parade</p>
<p><a href="https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-parameter-store.html">AWS Systems Manager のパラメータストア</a> をよく使っている。例えば Git で管理ができない秘匿情報を SecureString の形で保存しておいたり、 Infrastructure as Code を実行する際、 Terraform で構築したリソースの設定値を Ansible に橋渡しをするために使ったり、各種ツールやアプリケーションで参照したい設定値の保管場所として便利に使うことができる。</p>
<p>欠点として、今どんな値が格納されていたか？　どんなキー名で格納されていたか？を確認したいときの操作が若干面倒というのがあった。マネジメントコンソールではキーの一覧から、目当てのキーをクリックしてページ遷移しなければ値を見ることができない。またキーを検索する場合も、完全一致か前方一致での検索しかできず、目的のキーをなかなか探せないことが多かった。まぁ AWS CLI を <code>grep</code> などと組み合わせてうまいこと使うのが解なのだろうとは思うのだけど、手を動かす題材としても良さそうだったので、 go で CLI ツールを作って対処することにした。</p>
<h2>Parade</h2>
<script id="asciicast-ST2F5vAVnk5998C0KtkH6f5GN" src="https://asciinema.org/a/ST2F5vAVnk5998C0KtkH6f5GN.js" async></script>
<p>名前にあまり意味はない。パラメータストアなので "para" の付く英単語がいいなと適当に探して命名した。みんな OSS の名前ってどうやって決めてるのか教えてほしい。</p>
<p>シンプルに値を読み書きすることだけ、もっと言えば読むことだけが目的だったので、機能は少ない。コマンド体系は redis-cli を参考にしていて、 <code>keys</code>, <code>get</code>, <code>set</code>, <code>del</code> の4つのサブコマンドから成る。先述の通り、キーの検索が面倒というのが発端になっているので、特に <code>get</code> を強化した。何もオプションを与えなければ <code>get hoge</code> でキー名 "hoge" がある場合に限り値を出力するけれど、キー名の記憶が曖昧な場合などは <code>--ambiguous</code> あるいは <code>-a</code> オプションを付ければ部分一致するキー名をすべて拾ってきてくれる。このとき、一致箇所を赤字で表示するようこだわってみた。また <code>SecureString</code> にも対応していて、自身に復号の権限さえあれば、 <code>-d</code> オプションで復号した値を出力することもできる。</p>
<p>逆に <code>set</code> で値を登録するときは、任意のキーIDを指定した暗号化ができない（デフォルトのキーでの暗号化は可能）など、機能は現状最小限になっている。本当に手元でサクッとパラメーターを確認することを意図したツールにしている。</p>
<h3>類似ツール</h3>
<p>似たところだと <a href="https://github.com/segmentio/chamber">segmentio/chamber</a> が挙げられると思う。が、 chamber はあくまでシークレットマネージャーツールであることが主眼に置かれており、そのバックエンドとしてパラメータストアが使えるだけなので、パラメータストアの読み書き自体を目的とした parade とはちょっと軸足が違うかな、と思っている。</p>
<h2>使用技術</h2>
<p>いくつか初めて使う技術を盛り込めたのでよかった。</p>
<h3>aws-sdk-go</h3>
<p>AWS 関連のスクリプトを書く際は Python の boto3 を使うことが多く、今回 aws-sdk-go はほぼ初めてちゃんと使う機会になった。ドキュメントは <a href="https://docs.aws.amazon.com/sdk-for-go/api/">AWS Documentation</a> として公開されてもいるが、個人的には <a href="https://godoc.org/github.com/aws/aws-sdk-go">GoDoc</a> のほうが慣れもあって読みやすかった。</p>
<p>またユニットテスト用の mock が用意されているのが嬉しい。 Parade ではパラメータストアへのアクセス部分で以下のようなコードを書いている。</p>
<pre><code class="language-go">type SSMManager struct {
	svc ssmiface.SSMAPI
}

func New() (*SSMManager, error) {
	sess := session.Must(session.NewSession())
	svc := ssm.New(sess)

	return &#x26;SSMManager{
		svc: svc,
	}, nil
}

func (s *SSMManager) GetParameter(query string, withDecryption bool) (*ssm.Parameter, error) {
	params := &#x26;ssm.GetParameterInput{
		Name:           aws.String(query),
		WithDecryption: aws.Bool(withDecryption),
	}

	resp, err := s.svc.GetParameter(params)
	if err != nil {
		return nil, err
	}

	return resp.Parameter, nil
}
</code></pre>
<p>最初に定義した構造体 <code>SSMManager</code> に埋め込んでいる <a href="https://github.com/aws/aws-sdk-go/blob/master/service/ssm/ssmiface/interface.go">ssmiface.SSMAPI</a> が、各 API を呼ぶメソッドを実装した Interface になっているため、ダミー値を返すメソッドを書いた mock を用意することで、ユニットテストができるようになっている。</p>
<pre><code class="language-go">type mockSSMClient struct {
	ssmiface.SSMAPI
}

func NewMock() *SSMManager {
	svc := &#x26;mockSSMClient{}

	return &#x26;SSMManager{
		svc: svc,
	}
}

func (m *mockSSMClient) GetParameter(i *ssm.GetParameterInput) (*ssm.GetParameterOutput, error) {
    return &#x26;ssm.GetParameterOutput{Parameter: p}, nil
}
</code></pre>
<h3>spf13/cobra</h3>
<p>https://github.com/spf13/cobra</p>
<p>Go のコマンドラインツールを作るためのパッケージの1つ。競合として <a href="https://github.com/urfave/cli">urfave/cli</a> や <a href="https://github.com/mitchellh/cli">mitchellh/cli</a> もあるが、 cobra が現時点で最もスター数が多く、用例も多いのかなと勝手に思っている。作成者が Docker, Google, MongoDB あたりに関わっているゲキヤバな人であることもあってか、 <a href="https://kubernetes.io/docs/reference/kubectl/">kubectl</a> や <a href="https://istio.io/">Istio</a> などでも使われている。</p>
<p>使ってみた感想としてはなんでも出来る、そしてサクッと書ける良いツールではあった。が、サブコマンドのテストが書きづらい。というのも、以下のように <code>&#x26;cobra.Command</code> で変数として定義する方式を取るから。</p>
<pre><code class="language-go">var versionCmd = &#x26;cobra.Command{
  Use:   "version",
  Short: "Print the version number of Hugo",
  Long:  `All software has versions. This is Hugo's`,
  Run: func(cmd *cobra.Command, args []string) {
    fmt.Println("Hugo Static Site Generator v0.9 -- HEAD")
  },
}

func init() {
  rootCmd.AddCommand(versionCmd)
}
</code></pre>
<p>この点を気にする人は多いようで、検索するとワークアラウンドはいろいろと出てくる。</p>
<ul>
<li><a href="https://www.bradcypert.com/testing-a-cobra-cli-in-go/">Testing a Cobra CLI in Go - Brad Cypert</a></li>
<li><a href="https://text.baldanders.info/golang/using-and-testing-cobra/">Cobra の使い方とテスト — プログラミング言語 Go | text.Baldanders.info</a></li>
<li><a href="https://stackoverflow.com/questions/35827147/cobra-viper-golang-how-to-test-subcommands">go - Cobra + Viper Golang How to test subcommands? - Stack Overflow</a></li>
</ul>
<p>またコードを見るとわかる通り、サブコマンドが <code>error</code> を「戻さない」のも感覚的に慣れなかった。 <code>cobra.Command.Run</code> ではなく <code>cobra.Command.RunE</code> を使うと <code>error</code> を戻せるのだが、試しに戻したところ勝手に Usage をまるっと出力されてしまって、出力しないようにするにはどうしたらいいのか探すのが面倒になって諦めた。なんでも出来るツールはその分内部がブラックボックスにはなりやすいわけで、個人的には薄い実装のほうが好みなのだと思う。</p>
<h3>GitHub Actions</h3>
<p>Pull Request を発行したときの <code>golint</code> やテストの実行と、 tag を切ったときのバイナリ生成と GitHub Release への添付を GitHub Actions で書いている。初めて書いてみたけど正直まだ感覚がつかめていない。このブログを生成する hugo の実行を今 CircleCI にまかせているので、それを GitHub Actions へ移すときにもう一度学んでみて記事にしようと思っている。</p>
<p>GitHub Release へのバイナリ添付には <a href="https://github.com/goreleaser/goreleaser">goreleaser</a> を使った。すでに GitHub Actions で使うための Action を公開してくれているので、めちゃくちゃ便利に扱えて感動した。</p>
<p>https://github.com/marketplace/actions/goreleaser-action</p>
]]></description>
            <link>https://chroju.dev/blog/parade_aws_parameter_store_cli</link>
            <guid isPermaLink="false">parade_aws_parameter_store_cli</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 13 Oct 2019 23:23:39 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[SRE になって3か月目に考える、 SRE とは何か、如何に実践すべきか]]></title>
            <description><![CDATA[<p><a href="https://chroju.github.io/blog/2019/06/14/become_parallel_worker_and_university_student/">パラレルワーカー兼大学生になることになった · the world as code</a> というエントリーで SRE の立場でやっていくということを書いて、実際働き始めて3か月近くが経過した。インフラ系の運用専門のエンジニアから SRE という立場に変わって実際のところ何が変わったのか、今後何をするべきなのかということを、ここで改めてまとめておきたい。</p>
<h2>改めて SRE を定義する</h2>
<p>SRE の職種で転職活動をしていたとき、カジュアル面接で「SREとはなんだと思うか？」と聞かれたことがあった。そのときには「ソフトウェアエンジニアリングを用いてシステム運用を行うこと」と応えているが、今から考えると「半分正解」ぐらいの応えだったように思っている。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117917/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/51Ybz%2B6kIsL._SL160_.jpg" alt="SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117917/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 19.09.21</div></div><div class="amazlet-detail"><br />オライリージャパン <br />売り上げランキング: 79,446<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117917/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>定義は原典から引くべきだと思うので、『SRE book』を確認してみると、第1章にまずこのように書かれている。</p>
<blockquote>
<p>SREとは、ソフトウェアエンジニアに運用チームの設計を依頼したときにできあがるものです。</p>
</blockquote>
<blockquote>
<p>SREは、これまで運用チームが行ってきたことをソフトウェアの専門性を持つエンジニアが行い、エンジニアが人手による管理を自動化するソフトウェアを設計し実装する能力を持ち、それをいとわないということから成り立っています。</p>
</blockquote>
<p>やはり運用とソフトウェアエンジニアリングを結びつける内容が書かれていて、先に挙げた私の回答が間違っているわけではない。「半分正解」と書いたのは、それではなぜソフトウェアエンジニアリングを運用業務に持ち込まなくてはならないのか、という部分まで押さえていなかったからだ。</p>
<blockquote>
<p>常にエンジニアリングを行っていなければ、運用にまつわる負荷が増大し続け、負荷についていくためだけでもチームにはさらに多くの人数が必要になります。最終的には、運用に注力する旧来のグループは、サービスのサイズに比例して大きくなってしまいます。</p>
</blockquote>
<p>つまり、サービスの拡大に比例して増大していく運用負荷を抑えるという目的に対して、ソフトウェアエンジニアリングによるレバレッジを利かせることによって対応する職種、それが「SREの定義」に対する完全な答えになると考えている。ソフトウェアエンジニアリングを用いることは SRE の一側面であることは確かだが、あくまでそれは手段である。 SRE の目的は、その職種名自体が表しているように、サービスの信頼性を維持することであって、そのための効率的手段としてソフトウェアエンジニアリングが位置づけられる。</p>
<p>また「信頼性」という言葉も定義しておかなくてはならなさそうだが、ここでは SRE book の謝辞 注釈にある、以下の文を引いておく。</p>
<blockquote>
<p>ここでは、信頼性とは「［システムが］求められる機能を、定められた条件の下で、定められた期間にわたり、障害を起こすことなく実行する確率」です。</p>
</blockquote>
<h2>インフラエンジニアと SRE</h2>
<p>ソフトウェアエンジニアが運用を担うということがことさらに強調されているということは、これまでシステム運用を担ってきたのはソフトウェアエンジニアではないということになる。海外での実情や職種の分かれ方はよく知らないが、日本ではインフラエンジニアが運用を兼ねる場合が多かったように思う。その後近年の SRE ブームも手伝って、インフラチームと呼ばれていた部署を SRE に改組する企業が増えてきた。国内での SRE ブームに火を点けた、 SRE という職種を初めて広めたのはメルカリだと思っているのだが、同社でも SRE チームはインフラチームから発展したものだった。</p>
<iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Ftech.mercari.com%2Fentry%2F2015%2F11%2F18%2F153421" style="border: 0; width: 100%; height: 190px;" allowfullscreen scrolling="no"></iframe>
<p>しかし SRE がソフトウェアエンジニアリングを生業とする集団であるとするならば、インフラエンジニアがそのまま「今日から SRE になります」と言って簡単になれるものではない。 SRE はインフラエンジニアが単純に次世代型へ移行したものではない。ソフトウェアエンジニア、インフラエンジニアという、技術領域を元にした職種の分類ではなく、 SRE は信頼性という責任領域を後ろ盾とした職種になる。そこで必要とされる技術はソフトウェアエンジニアリングはもちろん、信頼性を担保する上ではインフラ部分への理解も欠かせず、非常に手広いものになる。</p>
<p>SRE のブームが来る少し前に Infrastructure as Code のブームが始まり、インフラエンジニアもコードを書けなくてはならないという風潮は出来上がっていた。ただ、 Infrastructure as Code で実際に書くものは多くの場合 YAML や HCL といった定義ファイルであり、ソフトウェア開発に至るわけではない。「運用」という側面で一致しているとはいえ、インフラエンジニアから SRE への移行は、それなりに大きなハードルを乗り越えるジョブチェンジになる。</p>
<h2>エラーバジェットとトイルバジェットから始める SRE の実践</h2>
<p>僕もインフラエンジニアから SRE へ移った身だし、正直なところ現段階でソフトウェアエンジニアリングが得意だと言い切れもしないのだが、ではそういったエンジニアが SRE をやることが無意味かと言えば、そうも思わない。ソフトウェアエンジニアリングを主戦場としてこなかった人間が SRE を実践することにももちろん意味はあると思っている。</p>
<p>冒頭で書いたようにソフトウェアエンジニアリングは SRE に求められる「半分」の側面であり、もう「半分」はサービスの信頼性確保という大目的の部分である。 SRE ではこれを「エラーバジェット」という考え方を導入することにより実現している。100％の可用性を闇雲に目指すのではなく、そのサービスに必要な可用性を SLO として定めた上で、その可用性目標を1から引いた値をエラーバジェットとして設けることにより、バジェットが満たされるまではリスクを取ってサービス開発しても良いものとして運営する。これにより、ただただ「守る」ことを考える従来の運用メソッドとは異なり、サービス開発のベロシティとサービスの信頼性確保という両輪のバランスを、明確な数値目標によって確保できる。株式会社はてなで SRE に従事していた yuuki 氏は、これを「サイト信頼性を制御する」と表現していた。</p>
<iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fblog.yuuk.io%2Fentry%2F2019%2Fthinking-sre" style="border: 0; width: 100%; height: 190px;" allowfullscreen scrolling="no"></iframe>
<p>手段としてソフトウェアエンジニアリングを高いレベルでこなすことができないとしても、まずこの考え方を導入し、信頼性の「制御」に責任を持ったチームとして SRE を設置することは意義があると考えている。特にサービスの拡大、成長が著しく見込まれている場合には、エラーバジェットという考え方がもたらす効用は大きい。</p>
<p>また、もうひとつ SRE の責務として重要な点として、サービス拡大に伴って増加する運用業務、いわゆる「トイル」の抑制が存在する。サービスが急激に拡大する際に足を引っ張りがちなのが、この信頼性確保と、トイルの増大という2点になる。SRE book において、 Google は「トイルを業務量全体の50%に抑える」という目標値を提示しているが、Google が公開しているもう1冊の SRE 関連書籍『<a href="https://landing.google.com/sre/books/">The Site Reliability Workbook</a>』では、これをエラーバジェットに対して「トイルバジェット」と呼んでいる。</p>
<p>Workbook では「class DevOps implements SRE」という言葉も出てくる。 DevOps は、すばやくリリースを行いたい開発担当者と、システムの可用性を守りたい運用担当者を対立関係に置くのではなく、両者を協力させていこうという、少々曖昧な部分のある一種の運動だったが、 SRE はこれにエラーバジェットとトイルバジェットという概念を持ち込むことで、両者の協力状況を可視化した。まずはこれを、自社の運用の現場に持ち込んでみることから始めてみてもいいのではないだろうか。まずは自社のサービスにとって、必要な「信頼性」とは具体的にどのような値であり、どの程度の数値を目標にするべきか SLO を考えなくてはならない。シンプルにサービスの稼働率だけ確保できればいいのかもしれないし、レスポンスタイムが一定値以下であることが求められるかもしれない。その数値も99.9%なのか、もうひとつ9を増やすべきなのか、あるいは繁忙期と閑散期、日中と夜間で目標を変えるべきなのかなど、考えることは山のようにある。そしてそれをどう測定するのか。レスポンスタイムはトップページだけで考えていいのか、全リクエストなのか、平均値なのか、パーセンタイルで考えるのか。トイルの計測はより難しいと感じていて、どの仕事をトイルと分類して、どのように所要時間を測るのかを決めなければならない。</p>
<p>ここでは SLO の策定と、それに基づく「測定」から SRE の実践を始めることを書いたが、 SRE を如何に実践していくかについては、 Google が<a href="https://cloud.google.com/blog/ja/products/gcp/how-to-start-and-assess-your-sre-journey/">チェックリスト</a>を公開している。</p>
<p>このチェックリスト内でもやはり、 SLO の策定はいの一番に上げられている。 SLO 策定 → 計測の開始 → 計測結果を踏まえた問題改善 というサイクルがあってこそ、 SRE は効果的に問題解決に当たれるのではないだろうか。</p>
<h2>自分のキャリアと SRE</h2>
<p>とはいえソフトウェアエンジニアリングを得意としていないことに甘んじ続けるわけにもいかない。特にトイルを抑制するには、手作業を自動化したり、システムが自律的に動作するようにしたりする上で、何かしらソフトウェアを書く機会というのはほぼ確実に生まれてくる。</p>
<p>SRE としてやっていくにあたって、自分には何が足りないのか。自分のキャリアを改めて振り返ると、専門性を持っていると言えるのは以下の領域と考えている。</p>
<ul>
<li>システム監視と復旧手順の作成</li>
<li>ドキュメンテーション</li>
<li>Infrastructure as Code</li>
<li>種々の自動化</li>
</ul>
<h3>アーキテクチャの知識の必要性</h3>
<p>これまで2社務めてくるなかで、構築よりも運用よりのエンジニアとして仕事に従事してきたがために、特にシステムの監視設計と実装、アラートを受信したときの対応手順、復旧手順の作成や、それらのドキュメンテーションといった部分に多く時間を割いてきた。しかしこれらはリアクティブな対応であって、 SRE の文脈ではトイルに分類される部分が多い。そもそも障害を起こさない、あるいは障害が起きても自律的にシステムが復旧するようなアーキテクチャを考えることが、 SRE には求められるはずだ。自分にはそれが圧倒的に足りていない。マイクロサービスアーキテクチャの知識はほぼゼロに等しいし、システムの自律的な動作において不可欠な技術になりつつある Kubernetes にもそれほど詳しくはない。 AWS のマネージドサービスを用いてある程度可用性の高い仕組みを整えることはできるが、まだまだ知らないことも多い。</p>
<h3>ソフトウェアエンジニアリングの知識の必要性</h3>
<p>またトイルの抑制にあたる業務もやってこなかったわけではなく、特に Terraform や Ansible を用いた Infrastructure as Code の導入や、手作業を AWS Lambda や自前のコマンドラインツールを用いて自動化していくことにも務めてきた。これらの経験はそのまま SRE としても役立つはずだし、実際この3か月の間でも、いくつか自動化の仕組みを整えてきた。これに関しては今後も継続的に伸ばしていきたい。</p>
<p>ただ、改めて思うのは Infrastracture as Code の効果的な実践が難しいということ。 IaC は何が嬉しいのかと言えば、サービスがスケールしたときに、一度コード化したリソースであれば瞬時に環境を準備できるという点が上げられる。しかしその利点を享受するには、再利用性の高いコードを書く必要がある。 Terraform には module 、 Ansible には role という形で、コードをパッケージ化して再利用するための仕組みが用意されている。これを上手く作っていかなくては、新たなサービスや環境が必要なときに、また一からコードを書かねばならず、結局のところ手作業でインフラを構築したほうが早いという結論になりかねない。これでは IaC はトイルと化してしまう。</p>
<p>SRE はソフトウェアエンジニアによるシステム運用の方法論だが、それは直接的にソフトウェアエンジニアリングを行うことを想定しているのみならず、ソフトウェアエンジニアリングの知識が、トイルの抑制のための自動化などに役立つという意味でもあると考えている。100回実行が見込まれる作業Aを自動化することはもちろん意味がある。しかしより意味のある自動化コードとは、それが作業A'や作業A''にも応用できるものである。そのためには業務を適切に抽象化する必要がある。これはソフトウェアエンジニアリングの方法論に近しい。例えば単一責任原則を知っていれば、より変更に強い Terraform module が書けるかもしれない。</p>
<h3>問題発見の技術</h3>
<p>もう1つ、これまで重視してこなかったが今後重要になるだろうと考えているのが「問題発見」の技術。トイルの抑制、信頼性の確保、いずれも的確にそれらを阻害している要因 = 問題をあぶり出して対処することが求められる。つまりは問題発見の技術である。安宅和人の『イシューからはじめよ』において、ただ闇雲に問題解決に当たり、大量の仕事をこなすことで目的を達成しようとする行為は「犬の道」と呼ばれている。ここではより生産性の高い問題 = イシューを見つけた上で仕事に当たることの重要性が説かれている。</p>
<blockquote>
<p>「限界まで働く」「労働時間で勝負する」というのは、ここでいうレイバラーの思想であり、この考えでいる限り、「圧倒的に生産性が高い人」にはなれない。冒頭で書いたとおり「同じ労力・時間でどれだけ多くのアウトプットを出せるか」というのが生産性の定義なのだ。</p>
</blockquote>
<p>トイルの抑制を目指す SRE にもこの考え方は必要だ。先に書いたことにも重なるが、闇雲に自動化をしたり、何か改善を加えたりするのではなく、いま本当に必要な自動化や改善はどれなのかを正しく見極めていく必要がある。 SLO の策定と計測も、対処するべき問題を正しく見極めるためのメソッドの1つと言える。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4862760856/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/513RqLSIjYL._SL160_.jpg" alt="イシューからはじめよ――知的生産の「シンプルな本質」" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4862760856/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">イシューからはじめよ――知的生産の「シンプルな本質」</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 19.09.21</div></div><div class="amazlet-detail">安宅和人 <br />英治出版 (2010-11-24)<br />売り上げランキング: 197<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4862760856/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<h2>Conclusion</h2>
<p>以上、自分が SRE としてやっていくにあたり、大きく3点の学びを進めていきたい。</p>
<ul>
<li>アーキテクチャの知識の獲得</li>
<li>ソフトウェアエンジニアリングの知識の獲得</li>
<li>問題発見の技術の獲得</li>
</ul>
<p>差し当たっては読みたい本がいくつか上げられたので読んでいこうと思う。ただアーキテクチャの知識という点についてはしっくりくる本が見つかっていない。『<a href="https://www.amazon.co.jp/dp/4774143073">大規模サービス技術入門</a>』など非常に良い本ではあるのだが、さすがに古くなっている部分もあり、この本の現代版がほしいなと思っているところ。 ISUCON の過去問なども有益ではないかと考えている。ほか2点に関しては以下の本を候補としている。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4048930656/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/51LkcwTMC8L._SL160_.jpg" alt="Clean Architecture 達人に学ぶソフトウェアの構造と設計" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4048930656/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Clean Architecture 達人に学ぶソフトウェアの構造と設計</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 19.09.21</div></div><div class="amazlet-detail">Robert C.Martin <br />KADOKAWA (2018-07-27)<br />売り上げランキング: 4,607<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4048930656/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4532318092/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/512JtXCrx%2BL._SL160_.jpg" alt="良い戦略、悪い戦略" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4532318092/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">良い戦略、悪い戦略</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 19.09.21</div></div><div class="amazlet-detail">リチャード・P・ルメルト <br />日本経済新聞出版社 <br />売り上げランキング: 29,863<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4532318092/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>3点の中に実際のソフトウェアエンジニアリング、コーディングを入れなかったのは自分でもちょっとおもしろいなと思うのだが、どちらかと言うとソフトウェアエンジニアリングを効果的に行うための方法論のほうが今は重要だと考える故ではある。もちろんソフトウェアエンジニアリングも並行して進めるべきだとは考えていて、 GitHub で Terraform 関係など、 issue に対して PR を投げたり、自分なりのツールを書いたりしていきたい。</p>
<p>考えれば考えるほど難易度が高くて気が遠くなりそうな職種なのだが、それだけ挑戦しがいもあるので、食らいついていきたい。</p>
]]></description>
            <link>https://chroju.dev/blog/what_is_sre_for_me</link>
            <guid isPermaLink="false">what_is_sre_for_me</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 18 Sep 2019 14:22:43 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[AWS DHCP オプションセットを RFC から理解する]]></title>
            <description><![CDATA[<p>AWS には DHCP オプションセットという仕組みがある。 DNS サーバーや NTP サーバーの IP アドレスをこれに設定し、 VPC と関連付けておくと、 DHCP の仕組みを使って EC2 インスタンスへ自動的に設定の配布を行なってくれる。</p>
<p>これまで特に不具合もなく使っていたのだが、 Ubuntu 18.04 を初めて使うにあたり、 DHCP オプションセットに設定できる <code>domain-name</code> をスペース区切りで複数指定したところ、スペースが「032」という文字列で置換された状態で設定されてしまい、 DNS が正常に機能しないという事象が起きた。以下は実際の設定ではないが、こういうイメージ。</p>
<pre><code class="language-bash">$ cat /etc/resolv.conf
nameserver 127.0.0.53
options edns0
search ap-northeast-1.compute.internal032example.com
</code></pre>
<p><a href="https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/VPC_DHCP_Options.html">DHCP オプションセットのドキュメント</a> を見ると、たしかに <code>domain-name</code> の複数指定は「一部の Linux オペレーティングシステム」でしか動作しないとある。しかし「一部」と言われても、ディストリを替えたら動きませんでした、だとわりと困る（今回の場合は 16.04 なら複数指定が動作したが、 18.04 では NG だった）ので、そもそもなぜこの項目が「一部」の Linux ディストリでしか有効にならないのか、 DHCP オプションの仕様から調べ直してみた。</p>
<h2>DHCP Options を定義する RFC</h2>
<p>そもそも DHCP Options とはなんぞ？という話だが、これは <a href="https://tools.ietf.org/html/rfc2132">RFC 2132</a> で定義されている。</p>
<blockquote>
<p>Configuration parameters and other control information are carried in tagged data items that are stored in the 'options' field of the DHCP message.</p>
</blockquote>
<p>DHCP message の中には 'options' field が設けられており、ここに各種設定パラメータを載せることができる。 DHCP というと IP アドレスやデフォルトゲートウェイの配布というのが主な機能ではあるが、それ以外の様々な設定値がここに載ってくる。</p>
<p>DHCP Options はなんでも情報を載せられるわけではなく、何を載せられるのかが RFC 内で定義されており、それぞれのオプションを表す <code>Code</code> と呼ばれる整数値が割り当てられている。また 2132 以外の RFC で定義されている DHCP Options も存在している。以下は一例。</p>
<ul>
<li><a href="https://tools.ietf.org/html/rfc2241">RFC 2241</a> : DHCP Options for Novell Directory Services</li>
<li><a href="https://tools.ietf.org/html/rfc3397">RFC 3397</a> : Dynamic Host Configuration Protocol (DHCP) Domain Search Option</li>
<li><a href="https://tools.ietf.org/html/rfc4833">RFC 4833</a> : Timezone Options for DHCP</li>
</ul>
<h2>AWS オプションセットと RFC</h2>
<p>さて、それでは AWS オプションセットで設定可能な各値は、 RFC で言うとどのコードに当たるのかという話になる。結論から書くと以下の通りだった。Section というのは RFC2132 で記載のあるセクション番号を指す。</p>
<p>| Code | Section | Option name          |
|------|---------|----------------------|
|    6 |     3.8 | domain-name-servers  |
|   15 |    3.17 | domain-name          |
|   42 |     8.3 | ntp-servers          |
|   44 |     8.5 | netbios-name-servers |
|   46 |     8.7 | netbios-node-type    |</p>
<p>問題の domain-name は Code 15 に当たる。</p>
<blockquote>
<p>This option specifies the domain name that client should use when resolving hostnames via the Domain Name System.
The code for this option is 15.  Its minimum length is 1.</p>
</blockquote>
<p>記載の通り、想定されているのは単数形の "domain name" である。他の、例えば先の表にもある Code 6 のように、複数の値を取ることが想定されている場合は　"a list of ~" という書き方がされていることから考えても、 Code 15 のこの記載は、複数の値を想定していない。</p>
<p>AWS DHCP オプションセットにおいて、 <code>domain-names</code> にスペース区切りで複数のサフィックスを指定した場合、一部の Linux ディストリビューションによってはそのまま複数の値として扱われるのは言い方がよくないが「たまたま」ということになる。おそらくスペース区切りの文字列をそのまま resolv.conf に書き入れるような実装になっており、複数のサフィックスがそのまま適用されるということになる。一方で Ubuntu 18.04 などはスペースが "032" に書き換わる、これは ASCII printable characters において 32 がスペースなので、おそらくはそのような変換が噛まされているのだと思われる。</p>
<h2>対処</h2>
<p>以上のように RFC 上そうなっているから、というのが冒頭の「不具合」の理由になるため、対処はしようがない。そもそもドキュメントに注意書きがされているのだし、 16.04 で複数指定できていたのがむしろラッキーだったんだろう。 DHCP に頼らず別の方法で設定するしかない。</p>
<p>望むらくは <code>domain-names</code> の実装を AWS に変更してもらえないものかなとは思う。 domain name を複数指定できる DHCP Option は実は別にあって、 RFC3397 に載っている <a href="https://tools.ietf.org/html/rfc3397#section-2">Code 119</a> がそれに当たる。こちらを採用してもらえれば、憂いなく domain name の複数指定が実現できるようになる。</p>
<h2>余談</h2>
<p>ちなみに冒頭に載せた Ubuntu 18.04 と DHCP オプションセットを巡ってはもう1つ問題があって、先の <code>resolv.conf</code> のイメージにもあるように、 nameserver が <code>127.0.0.53</code> で設定されてしまうという事象が発生する。</p>
<p>これに関してはまったく別の問題で、Systemd のバグらしい。 DHCP なんぞ基本的かつ根幹の部分だと思うのだが、意外にハマりどころがあって難儀している。</p>
<ul>
<li><a href="https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1624320">Bug #1624320 “systemd-resolved appends 127.0.0.53 to resolv.conf...” : Bugs : systemd package : Ubuntu</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/dhcp_options_rfc</link>
            <guid isPermaLink="false">dhcp_options_rfc</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 11 Sep 2019 12:34:11 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[パスワード管理サービスを Bitwarden でセルフホストする]]></title>
            <description><![CDATA[<p>パスワード管理と言えば 1Password や Lastpass あたりのクラウドサービスが人気だと思うのだが、どうにも第三者の運営するサービスに機密情報を預けるというのが苦手で、長らくオープンソースのファイル保存型パスワードマネージャーである <a href="https://keepass.info/">KeePass</a> を使ってきた。これは保存したパスワードなどはファイルに書き出されて暗号化されるという形を取るので、そのファイルを Dropbox に置くことでマルチデバイスでの同期を図っている（Dropbox に預けるのは OK で 1Password は NG というのは理屈に合わないというのはわかっている）。</p>
<p>そこに来て、最近始めた仕事でかなり　BYOD というべきか、会社の PC からでも家の PC から（要するにリモートワーク）でも会社で使っているサービスにログインして仕事をする、というスタイルが求められる場合が増えた。従って会社と家の PC でパスワードを共有したいのだが、会社の PC に私用で使っている Dropbox をインストールするのも気が引けるなどして、いい機会だしということで　KeePass に代わるサービスを探すことにした。使い始めたのは Bitwarden 。</p>
<p>https://bitwarden.com/</p>
<p>基本的には 1Password と同様にクラウドでパスワード管理してくれるサービスなのだが、パスワード管理サーバーのソースが GitHub で公開されており、サーバーをセルフホストして使うことができるようになっている。よってクラウド型パスワードマネージャーのメリットである「どの端末からでもインターネットに繋がればパスワードを取得できる」というメリットは享受しつつ、第三者にパスワードを預けるという形を回避できる。</p>
<h2>Bitwarden サーバーの Deploy</h2>
<p>デプロイ方法は公式にやり方が書いてあるので難しくない。</p>
<p>https://help.bitwarden.com/article/install-on-premise/</p>
<p>プロセス1つ上げればいいのかと軽く考えていたのが、 Docker コンテナ6個上げる必要があるのはちょっと予想していなかったが、 <code>docker-compose</code> コマンドでサクッと上げられるので手間は少なかった。サーバーはコンテナ6個と言うことでミニマムなものを使うわけにもいかず、 AWS EC2 の t3.small を1台手配している。従ってコスト的には全然美味しくなくて、ぼちぼちリザーブドインスタンスを買うつもりでいる。当初は VULTR で立てていたのだが、セキュリティに関して安物のサーバーを使うのも微妙だし、後述する各種運用のことを考えると使い勝手に懸念もあったので EC2 へ移した。</p>
<p>また https を使うために Let's Encrypt が組み込まれており、証明書も作成できるのだが、そのために独自ドメインが必要になる。やはりコスト的には全然旨味はない。</p>
<h2>Bitwarden サーバーの運用</h2>
<h3>監視</h3>
<p>停まると困るので Mackerel で死活監視している。まだ運用開始から1か月ちょっとなので落ちたことはないが、 EC2 だしたまに落ちる可能性は考慮するべきとは思っている。</p>
<h3>セキュリティ</h3>
<p>当然ながらセキュリティが気になるところなのだが、自宅だけから使うわけでもないので、 80/443 ポートの全開放は致し方なしというところ。それ以外のポートはすべて閉じている。メンテナンスのために ssh したくなる機会はあるが、 AWS Systems Manager を使うことにして、穴は閉じた。</p>
<p>https://dev.classmethod.jp/cloud/aws/session-manager-launches-tunneling-support-for-ssh-and-scp/</p>
<p>マスターパスワードはかなり長めにして、もちろん2段階認証をかけている。併せて Mackerel のログ監視を使って、400番のエラーが出た場合は Slack に通知させるようにした。挙動を見たところ、パスワードや2段階認証の誤りで弾かれた場合には 400 を返すらしいのだが、パスワード認証を終えて2段階認証をこれから行う、という場合でも400が出るようで、自分がログインするときにも通知されてしまってはいる。今の所已む無しと言うことで許容した。</p>
<p><a href="https://gyazo.com/4991a63e46cec9238e77f575d7a31deb"><img src="https://i.gyazo.com/4991a63e46cec9238e77f575d7a31deb.png" alt="Image from Gyazo" width="952"/></a></p>
<p>ポート開放の話は、自分が使いたいときだけ Slack からスラッシュコマンドで穴を開ける、というようなやり方もできそうだし、検討はしたい。</p>
<h3>バックアップ</h3>
<p>Bitwarden のドキュメントにバックアップするべきファイルの情報は書かれているが、横着して AWS Backup で日次バックアップを EBS まるごと取得している。</p>
<h2>使い勝手</h2>
<p>肝心の使い勝手の面は、今のところ満足している。 KeePass をはじめ各種類似ツールがエクスポートした情報を読めるようになっているので、移行は一瞬で済んだ。</p>
<p>ツールは各 OS 向けのデスクトップアプリ、各モバイルアプリ、 Chrome 拡張、コマンドラインツールと豊富に用意されているが、デスクトップに関しては Chrome 拡張だけで事足りている感じ。パスワードに URL を紐つけて登録しておくと、そのドメインのサイトにアクセスした際、自動でサジェストしてくれたり、上手くいけば自動入力までやってくれるのでストレスが少ない。</p>
<p><a href="https://gyazo.com/0e43ed5b79ff92b0848c686ee17550a4"><img src="https://i.gyazo.com/0e43ed5b79ff92b0848c686ee17550a4.png" alt="Image from Gyazo" width="597"/></a></p>
<p>なんかプレミアム会員 $10.00/年 を買ってコード入れて機能開放すると、 YubiKey 使った2段階認証とかも使えるようになるらしくて、それはそれで興味がある。が、有償でやるまでもなーーとか考えたり、いやでも t3.small 常時稼働させてるならもう $10.00/年 ぐらい誤差じゃん、、、という気もして、ちょっと悩んでる。</p>
]]></description>
            <link>https://chroju.dev/blog/bitwarden_introduction</link>
            <guid isPermaLink="false">bitwarden_introduction</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 18 Aug 2019 01:51:15 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[VSCode と TeX で大学のレポートを書く]]></title>
            <description><![CDATA[<p>大学のレポートを書くにあたって、約10年前に文系大学に通っていた頃は Google Docs を使っていたので、今回もそれでいいかと考えていたのだが、情報系のレポートということで数式を買いたりする必要もあり、 Google Docs だと何かと不便だった。そこで理系が数式を書くのに使うと聞いたことある TeX なるものを使えるのではないかと思い、まったく知らないところから調べて使ってみた。</p>
<h2>TeX とは</h2>
<p>正直 TeX が何なのかがわかっていない。調べると「組版システム」と出てくるのだが、システムという単語が多義的すぎてよくわからない。言語の名前なのか TeX 記法で書いたテキストを PDF などに変換するソフトウェアなのか何なのか。</p>
<p>取りあえず理解しているのは元々の TeX はオープンソースであり様々な拡張（ディストリビューション）が出ており、そのうち1つに LaTeX と呼ばれるより手軽に扱える実装があること。日本語対応の TeX, LaTeX もまた拡張の1つという形であったこと、程度。</p>
<h2>クラウドの TeX エディタ</h2>
<p>始めは Google Docs からの乗り換え検討という形だったので、クラウドエディタがあればいいと発想していた。探してみたところ、2つほど見つかった。</p>
<ul>
<li><a href="https://cloudlatex.io/">Cloud LaTeX | Build your own LaTeX environment, in seconds</a></li>
<li><a href="https://www.overleaf.com/">Overleaf, Online LaTeX Editor</a></li>
</ul>
<p>Cloud LaTeX は国内のポスドク向け就転職サイトを運営するアカリクという会社が管理していて、使っている学生も多いように見受けられた。一方の Overleaf は海外のサービスだが、やりようによっては日本語も使えるらしい。</p>
<p>しかしよくよく考えると Visual Studio Code で書きたいし、普通に手元で書いて GitHub で管理すればええやんという結論になって、いずれも採用を見送った。</p>
<h2>Visual Studio Code の TeX 環境構築</h2>
<h3>MacTex のインストール</h3>
<p>macOS の場合は MacTeX というものがあるので Homebrew Cask でインストールする。</p>
<pre><code class="language-bash">$ brew cask intall mactex
</code></pre>
<p>MacTeX は TeX Live というディストリビューションを含んだ macOS 向けの GUI などの集合らしい。ということで TeX Live としての初期設定を行う必要がある。まず、各種コマンド群に対して PATH を通す。</p>
<pre><code class="language-bash">$ export PATH=$PATH:/usr/local/texlive/2019/bin/x86_64-darwin
</code></pre>
<p>続いて TeX Live 内の各種パッケージを管理する <code>tlmgr</code> コマンドで、 TeX Live を最新にアップデートしておく。</p>
<pre><code class="language-bash">$ sudo tlmgr update --self --all
</code></pre>
<p>これで使えるようになった。 TeX ファイルをコンパイルするには <code>ptex2pdf</code> コマンドを使えばいい。</p>
<pre><code class="language-bash">$ ptex2pdf -l example.tex
</code></pre>
<h3>VSCode の設定</h3>
<p>拡張機能 LaTeX Workshop を使う。</p>
<p>https://github.com/James-Yu/LaTeX-Workshop</p>
<p>デフォルトの状態でもシンタックスハイライトやサジェストの機能が使えるが、 VSCode 内でコンパイルしたりするには <code>settings.json</code> にコンパイル用のコマンドを記入したりする必要がある。自分の場合は以下のように設定している。</p>
<pre><code class="language-json">"latex-workshop.latex.tools": [
    {
        "name": "ptex2pdf",
        "command": "ptex2pdf",
        "args": [
            "-l",
            "-ot",
            "-kanji=utf8 -synctex=1",
            "%DOC%"
        ]
    }
],
"latex-workshop.latex.recipes": [
    {
        "name": "ptex2pdf",
        "tools": [
            "ptex2pdf"
        ]
    }
],
"latex-workshop.message.log.show": true,
"latex-workshop.message.badbox.show": true,
"latex-workshop.latex.autoClean.run": "onBuilt",
"latex-workshop.latex.autoBuild.run": "onFileChange",
"latex-workshop.view.pdf.viewer": "tab",
</code></pre>
<p>ビルド用のコマンドを定義するのは <code>latex-workshop.latex.tools</code> と <code>latex-workshop.latex.recipes</code> の部分。 <code>tools</code> で実行するコマンドを定義する。VSCode のコマンドから呼べるのが <code>recipe</code> と呼ばれ、 recipe と tools を紐つけるための設定が <code>latex-workshop.latex.recipes</code> になる。ここでは tools と recipes いずれも同じ名前にしてしまったのでわかりづらいが、 VSCode のコマンドパレットで <code>ptex2pdf</code> という recipes を実行すると、 tools の <code>ptex2pdf</code> で定義したコマンドが実行される、という形になる。</p>
<p>コマンドは先述の通り <code>ptex2pdf</code> で、 <code>-l</code> は LaTeX フォーマットを使うことを明示するオプション、　<code>-kanji=utf8</code> は漢字を使う上で必要なオプション、 <code>-synctex=1</code> は TeX のエディタと PDF ビューアを一緒に開いているとき、相互に位置ジャンプできるようにしてくれるらしい。 <code>-kanji</code> と <code>-synctex</code> は TeX の追加オプションなので、これらを使うために <code>-ot</code> が必要になる。</p>
<p>その他の設定は <a href="https://github.com/James-Yu/LaTeX-Workshop/wiki/Compile">Wiki</a> を見ればわかるが、順に以下の意味。</p>
<ul>
<li>エラーメッセージがエディタ内に表示されるようになる</li>
<li>エラーメッセージが「問題」パネルに表示されるようになる</li>
<li>TeX のコンパイル時に自動生成される <code>.aux</code> ファイルなどをビルド時に自動削除する</li>
<li>ファイルに変更を加えたときに自動でコンパイルする</li>
<li>TeX からコンパイルした PDF を VSCode のタブで表示する</li>
</ul>
<p>これでこんな感じで PDF プレビューを見ながらレポートが書けるようになった。</p>
<p><a href="https://gyazo.com/3b01c439a1899793741277dead1f3f5f"><img src="https://i.gyazo.com/3b01c439a1899793741277dead1f3f5f.png" alt="Image from Gyazo" width="1184"/></a></p>
<p>左側のメニューに「TeX」アイコンも追加されるので、ここから各種コマンドを実行することもできる。コンパイルが上手くいかなかった場合はここから <code>Terminate current compilation</code> を実行すれば、コンパイルを一旦中止できる。</p>
<h3>GitHub での管理</h3>
<p>TeX ファイルは GitHub のプライベートレポジトリで管理している。これはまぁ、普通に管理するだけなので難しいことはない。</p>
<p>ワープロソフトを使っていると、印刷したときに正しく表示できるよう装飾面にも気を遣わなくてはならなくて面倒だったんだけど、 TeX だとマークアップさえしておけばいい感じの見た目にしてくれるので、本文を書くことに集中できてとてもいい。数式を書くための組版システム、という位置付けだとは思うが、文系でも使って利があるものだと思う。</p>
]]></description>
            <link>https://chroju.dev/blog/write_repot_with_vscode_tex</link>
            <guid isPermaLink="false">write_repot_with_vscode_tex</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 24 Jun 2019 07:57:55 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[gRPC ちょっと理解した]]></title>
            <description><![CDATA[<p><a href="https://grpc.io/">gRPC</a> に入門した。favicon のマスコット？めっちゃかわいいですね。。</p>
<p>きっかけは <a href="https://chroju.github.io/blog/2019/05/14/read_terraform_source_code/">3rd Party tool をきっかけに Terraform のソースコードを少し嗜んだ話 · the world as code</a> という記事で触れたように、 Terraform 0.12 で Terraform Core と Provider が gRPC で通信するようになったため。知ってなてくは Terraform を使えないわけでも Provider を書けないわけでもないのだが、昨今よく聴く単語だし、 microservices などにも必要な要素技術なので入門してみた。</p>
<h2>教材</h2>
<p>ちょうど WEB+DB PRESS の最新号で特集されていたので、主にこれを使った。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4297105330/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/51SCTYcyT%2BL._SL160_.jpg" alt="WEB+DB PRESS Vol.110" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4297105330/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">WEB+DB PRESS Vol.110</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 19.06.21</div></div><div class="amazlet-detail">藤村 大介 森田 リーナ 渡邉 祐一 市原 創 板倉 広明 高橋 征義 笹田 耕一 大原 壯太 新倉 涼太 末永 恭正 久保田 祐史 牧 大輔 東 邦之 星 北斗 池田 拓司 竹馬 光太郎 はまちや2 竹原 八谷 賢 <br />技術評論社 <br />売り上げランキング: 13,606<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4297105330/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>あとは公式のドキュメント。英語で簡単な Tutorial が書かれているほか、 gRPC のレポジトリ内にある <a href="https://github.com/grpc/grpc/tree/master/examples">examples</a> というフォルダに言語別の実装例が書かれていて参考になった。</p>
<h2>学んだこと</h2>
<h3>写経</h3>
<p>gRPC とは何か、などとここで改めてまとめても仕方ない感があるので、それについては割愛する。 WEB+DB PRESS を読もう。</p>
<p>当該号の特集では、 gRPC の4種類の通信方式（Unary, Server streaming, Client streaming, Bidirectional streaming）それぞれの簡単な実装サンプルと、実践例として gRPC を用いたタスク管理サービスの作り方が掲載されており、これを適宜写経しながら進めた。コードはいずれも GitHub で公開されている。</p>
<p>https://github.com/vvatanabe/go-grpc-basics</p>
<p>https://github.com/vvatanabe/go-grpc-microservices</p>
<h3>Ruby での再実装</h3>
<p>単に写すだけというのもつまらないので、ちょっとした応用もやってみた。 gRPC には遣り取りするデータのシリアライズフォーマットを定義した Protocol Buffers (protobuf) を元として、サーバ / クライアントの実装を様々な言語で生成することができるという特徴がある。そこで、誌面のサンプルはサーバ / クライアントともに Go で書かれていたが、クライアント側を Ruby で書いてみることにした。</p>
<p>対象にしたのは Server streaming gRPC のサンプルコード。主に公式の <a href="https://grpc.io/docs/quickstart/ruby/">Ruby 向け Tutorial</a> を見つつ、先の examples 内の実際のコードも見ながら進めたが、以下の記事も参考にした。</p>
<p>https://qiita.com/yururit/items/bc7c0eda63d5fa30289a</p>
<p>まず、必要な gRPC 関連の gem をインストール。</p>
<pre><code class="language-bash">$ gem install grpc
$ gem install grpc-tools
</code></pre>
<p>続いて protobuf から Ruby 用のクライアントコードを生成しようと思ったのだが、サンプルコードでは protobuf の package が <code>file</code> という名前で定義されており、これをそのまま Ruby のコードに変換すると、 File class と衝突する形になってしまった。そのため package 名を <code>filedl</code> という名前に変更してからコード生成を実行している。ネーミングセンスは気にしないことにした。なお、このコマンドは元のサンプルコードの <code>downloader</code> というフォルダ内に <code>ruby</code> フォルダを掘り、その中で実行している。</p>
<pre><code class="language-bash">$ mkdir lib
$ grpc_tools_ruby_protoc -I ../proto --ruby_out=lib --grpc_out=lib ../proto/filedl.proto
</code></pre>
<p>Ruby のコードは以下のようになった。元々の Go によるサンプルコード（<a href="https://github.com/vvatanabe/go-grpc-basics/blob/master/downloader/client/main.go">go-grpc-basics/main.go at master · vvatanabe/go-grpc-basics</a>）とだいたい同じ動きをするようにしている。</p>
<pre><code class="language-ruby">this_dir = File.expand_path(File.dirname(__FILE__))
lib_dir = File.join(this_dir, 'lib')
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)

require 'grpc'
require 'filedl_services_pb'

def main
    stub = Filedl::FileService::Stub.new('localhost:50051', :this_channel_is_insecure)
    filename = ARGV[0]
    resps = stub.download(Filedl::FileRequest.new(name: filename))
    blob = ""
    resps.each do |r|
        blob &#x3C;&#x3C; r.data
    end

    p "done " + blob.size.to_s(10) + " bytes"

    file = File.open(filename,"w")
    file.puts blob
    file.close
end

main
</code></pre>
<p>これで <code>ruby client.rb test</code> などと実行することで無事に動作が確認できた。異なる言語間でシリアライズされたデータの遣り取りがだいぶ簡単に実装できてなるほどねぇという感じはした。あと Ruby を3年ぶりぐらいに書いたのでところどころ文法にビビったりした。 <code>&#x3C;&#x3C;</code> 演算子とか。</p>
<p>成果物はすべて <a href="https://github.com/chroju/learning_grpc">chroju/learning_grpc</a> に上げておいた。</p>
<h2>Terraform と gRPC</h2>
<p>一通りドキュメントを見てはみたが、正直そんなにガッツリ gRPC 使ってどうこうみたいなことは書いていないような気がする。 RPC 使ってますよ（これは Terraform 0.11 以前から同様）という話と、 "Although technically possible to write a plugin in another language, almost all Terraform plugins are written in Go." という一文が <a href="https://www.terraform.io/docs/extend/writing-custom-providers.html">Writing Custom Providers - Guides - Terraform by HashiCorp</a> にあるぐらい。将来的に Go 以外でも書けるようにするんですかね。どうなんですかね。</p>
<p>コードで言えば <a href="https://github.com/hashicorp/terraform/tree/c7058eaa52435e2c603319d194f903261ccfdc1f/docs/plugin-protocol">terraform/docs/plugin-protocol · hashicorp/terraform</a> に protobuf の定義ファイルがある。また、 Provider は <code>terraform/plugin</code> の <code>Serve</code> という関数を <code>main.go</code> に書く必要があり、この関数が Terraform Core に Provider を渡しているようなのだが、 <a href="https://github.com/hashicorp/terraform/blob/ba6e243bd97fda935f903da0d420e5ed94e35c9e/plugin/serve.go#L56-L83">この実装</a> を見ると、現時点では gRPC 向けに既存のメソッドを変換したりする処理が入っているみたい。 Provider を書く際には、 gRPC を意識する必要は基本的にはなさそう。</p>
]]></description>
            <link>https://chroju.dev/blog/grpc_entry</link>
            <guid isPermaLink="false">grpc_entry</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 21 Jun 2019 08:05:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[パラレルワーカー兼大学生になることになった]]></title>
            <description><![CDATA[<p>4月に帝京大学理工学部情報科学科の通信課程に入学したのと、来月から2つの職場で働くために、パラレルワーカー兼大学生という字面だけ見るとよくわからない立ち位置でやっていくことになった。特にこの2つの動きが何か連関していたわけでもないので、1つずつ書いてみる。</p>
<h2>大学生</h2>
<p>大学は2011年に一度出ているので、今回が再入学になる。いわゆる一般教養にあたる単位は取得済みとみなされ、2年次編入となった。</p>
<h3>なぜ大学に再入学したのか</h3>
<p>先に出ている大学は社会学部で、計算機科学や情報学の学問的な知識をきちんと学んだことがなかったから、というのが直接の動機になる。いわゆる文系コンプレックスに近かったんだと思う。この職業をやっていく中で、そういったことをなんとなくのもやっとした感覚として抱いていたのだが、実際進学してしまおうと決意した契機は SRE book だと思う。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117917/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/51Ybz%2B6kIsL._SL160_.jpg" alt="SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117917/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 19.06.14</div></div><div class="amazlet-detail"><br />オライリージャパン <br />売り上げランキング: 5,126<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117917/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<blockquote>
<p>Googleは、さまざまな問題に関してあえて一から考えることをいとわない会社であり、多くの博士号所有者を含む最高の人材を雇用しています。ツールはプロセス中で一連のソフトウェアや人々、データと共に動作する要素に過ぎません。ここでは、万能の解決策を教えてくれるものはありませんが、それこそが本質なのです。（序文より）</p>
</blockquote>
<p>この2, 3年ぐらいはレガシーな環境の運用設計を見直したり、改善したりといった仕事を主に担当していたのだけど、この「あえて一から考える」ということに難しさを覚えることが多くあった。例えばシステムからのアラートが多いので改善をしたい、という話になったとき、一から考えるのであれば何故アラートを発報しているのか、そもそもこの監視の設計で、このシステムに対しては適切な監視になっているのか、システムを監視するとはどういうことなのか、という点から問い直す作業になるのだと思う。しかし実際には、プロジェクトメンバーの経験から「オーソドックスな監視設計」と思われるものをこねこねと作り上げて、それをパッチのように継ぎ宛てて対処するだけに終わってしまうことも少なくなかった。なぜ経験を引っ張り出してくるのかと言えば、他に依拠できる客観的な知識体系を持っていないからであって、その知識体系の候補となりうるのが学問的な知識なのかもしれないな、ということを考えた。車輪の再発明をしないための学びであり、車輪を適切に応用していくための学びをしたかった。</p>
<p>もちろん、市販されている技術書などで賄うこともできるとは思うけど、この業界であと30年はやっていくことを考えると、3年間費やせば取得できる学士ぐらい持っていて損はないと思っている。学士があれば、その後修士、博士に進むということもなくはないかもしれないしれないし、可能性を広げておく意味で決断した。ちなみにいきなり修士からというのも考えはしたが、基礎的な知識体系を獲得したい、という目的からすると学士からきちんと押さえるべきだと考えた。</p>
<h3>なぜこの大学学部学科なのか</h3>
<p>こういう言い方をすると申し訳ない部分もあるが、わりと消去法に近い。東京近郊でスクーリング可能な情報系の通信制大学、という時点でわりと絞られる。最も有名であろう通信制大学である、放送大学という手もあったのだけど、学部が教養学部になってしまうので、それよりは理工学部の卒業歴を持っておきたいとか、理工学研究科を有している大学のほうが安堵感があるかな、みたいなふわっとした思いもあったりする。</p>
<h3>2か月半ほど通ってみての感想</h3>
<p>思っていたより大変。というのも、試験を受ける時期が1年間に4回あり、そのうち最も早いのが7月初旬にあるのだが、その試験を受けるには6月初旬にレポートを出さなくてはならなかったりしたため。通信制の新入生は4月末ぐらいに履修登録の期限が設けられていたので、GW明けぐらいから本気出せばいいかと安易に考えて連休は遊びまくったのがよろしくなかった。連休明けに初めて日程に気付き、5月はだいぶヒーヒー言いながら勉強していた。</p>
<p>ただ、4回の試験のうち、1回目と3回目、2回目と4回目で受けられる科目は同一であるため、基本的に時期が遅いほうで受けるよう日程を組めば、勉強期間も長めに取れて余裕が出そうということがわかったので、これから調整すればもう少しマシかもしれない。最短の3年間で残る90単位近くを取りきれるかは少し自信がない。15回ぐらいある授業を自力で進めてレポート書いて試験、って、思った以上に力が要る。最近こちらにかかりきりで、技術動向を追うようなことができてなかったりするのも芳しくなくて、しばらくはリズムを調整していきたい。</p>
<p>余談めいた部分だと学割が使えるようになった。さすがに収入がそれなりにある身で使うのは大人げない気がするのでほとんど使ってはいないが、 Spotify（半額）と Amazon Prime（半額、書籍や文房具購入時に還元）だけは「まぁいいか」と思って使わせてもらってる。一度だけ美術館でも使ったが普通に使えた。</p>
<h2>パラレルワーカー</h2>
<p>具体的には先月で正社員契約をやめ、今月から週1で業務委託の仕事をしていて、来月からはそれに加えて別の会社で週4契約社員として働くことになった。フリーランサーに近くはあるし、税制の面を考えて開業届も出しているけど、いわゆるフリーランスの働き方ともちょっと違うのでパラレルワーカーと名乗ってみている。</p>
<p>業務委託を始めるにあたり、税のこととか何もわからなかったので、技術書典6できりみんちゃんさんの『<a href="https://kirimin-chan.booth.pm/items/1313813">フリーランスを完全に理解できる本</a>』を買って参考にさせてもらった。他にも何冊か読んでみたけど、これがかなりコンパクトにまとまっていてめちゃめちゃわかりやすかったです、ありがとうございます。</p>
<h3>なぜパラレルワーカーになったのか</h3>
<p>あんまりパブリックに書きたい理由でもないのでやめておく。別に働き方改革したいとか、会社勤めが嫌になったとかではないし、学業があるから仕事減らしたいでもない（そのうち、そう思うかもしれんが）。そもそも自分は仕事以外の人脈でIT系のエンジニアとの繋がりをほぼ持っていないので、よくある「知人伝いに仕事をもらう」ということは出来そうにないし、著名人ってわけでもないのでフリーランサーに向いているとも思っていない。なんか結果的にこうなってしまった。ただ、それほど嫌な気持ちはなくて、経験として面白そうだとは感じている。</p>
<p>前職をやめた理由というのは存在していて、少し固めな BtoB 中心の事業領域の中で、自分がやれることの天井が見え始めたから、というのが近いと思う。よりベロシティが高い環境に身を置きたかったとも言えるし、もっと個人的な話だと SRE にクラスチェンジしたかった、というのもある。抽象的な書き方でアレだけど。</p>
<h3>どうやって仕事を探したのか</h3>
<p>転職ドラフト、forkwell、Wantedlyなどなど、最近はIT系のエンジニアお仕事系サイトも多いので、いろいろと駆使して全部合わせると10社ぐらい会わせていただき（選考に進まなかった会社も多い）、あとは少ない知人経由の会社も受けたりして、最終的に契約に至った。前回の転職のときはエージェントを使ったので、今回の仕事探しでは使わないでみようという考えが強かった。結果的に、 GitHub やブログの URL を貼ったレジュメを送って、自分はこれができます、とアピールし、相手もそれを見た上で、この人にならこれが任せられるかもしれない、という気持ちで話してくれるという形になったので、話しやすいなと感じることが多かった。どこかが取ってくれるだろう、ではなくて、自分はこれができるから御社で働かせてほしいと売り込む、能動的な姿勢も養えたように思う。</p>
<p>ちなみに職種は SRE で探した。流行りの仕事だからか、システム運用かつソフトウェアエンジニアリングというスキル領域を満たす人材がまだ少ないのか、求人は結構な数があるような感触を受けた。 SRE はシステムのコアな部分に関わるので、業務委託だとどうなんだろうという気がしていたが、わりと正社員に近い役割でやらせてもらえる会社さんもあった。なお、業務委託で探していたのだけど、最終的に「契約社員はどうか」と言ってもらえる会社さんがあったので契約社員＋業務委託という2契約になっている。</p>
<h3>働き方は変わるのか</h3>
<p>2社パラレルになる以外はあんまり変わらないと思う。リモート可能でフレックス制がだいぶ積極的に使われてるっぽい会社さんということもあり、労働時間は減りそう（前職はそこそこ残業してた）というぐらい。収入も前職でそこそこもらっていたのだが、同等な額が入りそうなので困窮する心配もなさそう。</p>
<h2>ということで</h2>
<p>2つの話を一緒に書いたので長くなったけど、来月から肩書き3つでやっていく感じでコンテキストスイッチ大変そうだけど頑張っていこうと思う。仕事探しの話、学生の話など、個々の部分にフォーカスした具体的なことはまた別途書くかもしれない。</p>
]]></description>
            <link>https://chroju.dev/blog/become_parallel_worker_and_university_student</link>
            <guid isPermaLink="false">become_parallel_worker_and_university_student</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 14 Jun 2019 09:19:10 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Netlify Functions と Go で動的なウェブページを作る]]></title>
            <description><![CDATA[<p>5年間ぐらい chroju.net というドメインを取って自分のプロフィールを掲載していて、裏側では AWS の Serverless な仕組みがいろいろ動いていたりしたのだけど、先日 chroju.dev というドメインを取ったのでそちらにプロフィールを載せ替え、仕組みも Netlify Functions に変更した。</p>
<h2>従来の仕組み</h2>
<p>従来の仕組みは以下の Qiita のエントリーにまとめていた。</p>
<p>https://qiita.com/chroju/items/827dbb9e820f41820e14</p>
<p>やりたかったのは、プロフィールの中に自分のブログの最新記事リストを自動的に埋め込むこと。紆余曲折を経て、あらかじめ jinja2 でテンプレートを作っておき、ブログの更新を RSS と IFTTT 経由で hook して Lambda を叩いて、その Lambda がテンプレートから html を生成して S3 に設置、という形をこのときは取っている。つまり動的チックだが、実際にアクセスが来るのは静的な HTML ではある。ページ内に書いてある通り、各サービスの仕様がその後変わっているので、現時点でこのメカニズムを採用するのはモダンではなくなっている。</p>
<p>なお、 chroju.net のドメインはもう失効したが、このページ自体はまだ生きている。気まぐれに消すと思うので、動いていなくてもあしからず。</p>
<p>https://chroju-profile.s3-ap-northeast-1.amazonaws.com/index.html</p>
<h2>今回の仕組み</h2>
<p>シンプルに、 URL へアクセスがあったときにサーバーサイド（実際にはサーバーレスだけど）で RSS から最新記事のタイトルとリンクを読み込んで、テンプレートに埋め込んで HTML を返す、というメカニズムに変えることにした。</p>
<p><a href="https://www.netlify.com/docs/functions/">Netlify Functions</a> はコードを書いた GitHub レポジトリと連携を設定すると、それを自動的に AWS Lambda にデプロイして URL から実行できるようにしてくれる仕組み。つまり Lambda と API Gateway の設定を面倒見る必要なく、コードを書くことだけに集中ができる。基本的には API を作ったりするのが主な用途だと思うけど、もちろん <code>text/html</code> を返しても良いので、今回はそれを利用している。言語は JavaScript と Go が使えるが、自分のスキルを鑑みて Go にした。</p>
<h2>実装</h2>
<p>HTML のテンプレートには Go の標準ライブラリの <code>html/template</code> を使った。また RSS の読み込みとパースには https://github.com/mmcdole/gofeed を利用している。最新のコードは https://github.com/chroju/portfolio に置いている。</p>
<pre><code class="language-go">package main

import (
	"bytes"
	"html/template"
	"io"
	"log"

	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
	"github.com/mmcdole/gofeed"
)

func handler(request events.APIGatewayProxyRequest) (*events.APIGatewayProxyResponse, error) {
	fp := gofeed.NewParser()

	feed, _ := fp.ParseURL("https://chroju.github.io/atom.xml")
	ghitems := feed.Items[:3]
	feed, _ = fp.ParseURL("https://chroju.hatenablog.jp/feed")
	hbitems := feed.Items[:3]

	tmpl := template.Must(template.New("index.html").Parse(htmlTemplate))
	buf := new(bytes.Buffer)
	w := io.Writer(buf)

	err := tmpl.ExecuteTemplate(w, "base", struct {
		GitHubIOEntries   []*gofeed.Item
		HatenaBlogEntries []*gofeed.Item
	}{
		GitHubIOEntries:   ghitems,
		HatenaBlogEntries: hbitems,
	})
	if err != nil {
		log.Fatal(err)
	}

	return &#x26;events.APIGatewayProxyResponse{
		StatusCode: 200,
		Body:       string(buf.Bytes()),
	}, nil
}

func main() {
	lambda.Start(handler)
}
</code></pre>
<p>先述の通り裏側は AWS Lambda なので、 Lambda の書き方に沿うことになる。 Lambda の実行時に呼び出す関数は handler と呼ばれる。この handler は特に API Gateway から呼ばれることになるので、 API Gateway とやり取りするために <code>*events.APIGatewayProxyRequest</code> を受け取り、 <code>*events.APIGatewayProxyResponse</code> を返すように実装する必要がある。今回はそのなかで html を Response Body に入れて返している。</p>
<p>テンプレートは行数も多くなるので、本来であれば別ファイルに切り出したいところなのだが、 Netlify Functions でコード以外のファイルを一緒にデプロイする方法がわからなかった。そのため今はテンプレート全行を定数に代入する形でべた書きしている（上述のコードの中では省略した）。</p>
<p>あとは build 用のコマンドを Makefile に書いておく。これで <code>functions</code> というフォルダ内にバイナリが置かれることになる。</p>
<pre><code class="language-make">build:
	export GO111MODULE=on
	go get ./...
	go build -o functions/profile ./...
</code></pre>
<p>設定したコマンドと、バイナリの在り処を <code>netlify.toml</code> に書き、このレポジトリを Netlify Functions に連携することで、レポジトリの push を検知して自動的に build してデプロイしてくれるようになる。とても手軽。</p>
<pre><code class="language-toml">[build]
    command = "make build"
    functios = "./functions"
</code></pre>
<h2>misc</h2>
<p>コード以外の設定をいくつか。</p>
<h3>Font Awesome</h3>
<p>SNS のアイコンを表示するために何年かぶりに Font Awesome を触ったところ、設定方法が替わっていたように思うのだが、以前の記憶が曖昧ではある。従来は CDN 上の CSS を <code>link</code> タグで直接読み込む形を取っていたと思うのだが、現状この形式は推奨されておらず、ユーザー登録すると個別の ID が払い出され、その ID に紐ついた js を読み込んで使う、という形になったらしい。</p>
<p>管理画面上で使用するプランや、 Web Font か SVG かの選択などを行えるようになっているので、おそらくそれを反映して、 js が適した css を動的に読み込むようになっているのだと思われる。 Font Awesome がバージョンアップした場合にも自動的に latest を読み込んでくれるようなので、メンテナンスの手間は減って便利になっている。</p>
<h3>DNS</h3>
<p>chroju.dev は Google Domains で取得したが、 Netlify Functions を使うにあたって Netlify の Managed DNS を使うと CDN を噛ませて速くしてくれるみたいな話だったので、名前解決は Netlify にまかせている。</p>
<p>https://www.netlify.com/docs/dns/</p>
<p>残念ながら API がまだ無いようで、 chroju.net の時代は Route53 に乗せて API 経由でゴニョゴニョしていたことが出来なくなってしまったのでどうしようかな、という課題が残された。まだ Beta 扱いのようではあり、今後に期待したい。</p>
<h3>Redirect</h3>
<p>Netlify Functions はカスタムドメインは使用できるものの、個々の Function を実行するパスの自由度はなくて、デフォルトだと <code>/.netlify/functions/</code> 配下に置かれる。しかし https://chroju.dev へアクセスが来たときに Functions を実行して返したいわけなので、 <code>netlify.toml</code> でリダイレクトを設定した。 200 で返すことにより、ユーザーのアドレスバーには https://chroju.dev/ が表示されたままでリダイレクトさせることができている。</p>
<pre><code class="language-toml">[[redirects]]
    from = "/"
    to = "/.netlify/functions/profile"
    status = 200
</code></pre>
<h3>go mod</h3>
<p>今回初めて go mod を利用したけど便利だった。利用にあたっては公式のドキュメントと以下のエントリーを参考にした。</p>
<ul>
<li><a href="https://songmu.jp/riji/entry/2019-03-28-go-modules.html">最近のGo Modulesプラクティス ~ ghqユーザーの場合も添えて | おそらくはそれさえも平凡な日々</a></li>
</ul>
<h2>Conclusion</h2>
<p>すごく簡単に AWS Lambda と API Gateway が使えて楽しかった。対応言語が Go と JS だけなど制約もあるが、単発で動かす Lambda とエンドポイントがほしいだけの場合であれば、 AWS ではなく Netlify Functions でデプロイしたほうがいろいろと不便がなさそう。</p>
]]></description>
            <link>https://chroju.dev/blog/go_dynamic_web_page_netlify_functions</link>
            <guid isPermaLink="false">go_dynamic_web_page_netlify_functions</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 10 Jun 2019 08:43:55 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Corne Chocolate を組み立てる、40%キーボードに目覚める]]></title>
            <description><![CDATA[<p><a href="https://gyazo.com/a1907073d1c0e66e41ef19e5c755151a"><img src="https://i.gyazo.com/a1907073d1c0e66e41ef19e5c755151a.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>前回の記事で書いたとおり Corne Chocolate を買って、無事に組み立てが完了した。</p>
<h2>Corne Chocolate</h2>
<p><a href="https://yushakobo.jp/shop/corne-chocolate/">Corne Chocolate</a> は <a href="https://twitter.com/foostan?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor">foostan</a> 氏が設計、販売している自作キーボード。</p>
<ul>
<li>分割型</li>
<li>42キーのいわゆる40%キーボード</li>
<li>Cherry MX 対応と Kailh Choc (Low Profile) 対応の2バージョン、それぞれホットスワップ</li>
<li>オプションでフルカラー LED 実装可能</li>
</ul>
<p>といった特徴がある。私がこれを買ったのは Lily58 Pro を使うなかで数字列が要らないのではないか、つまり40%キーボードで良いのではないかと悟ったからであり、40%の分割型で Kailh Choc 対応という3つの希望を満たしてくれるのがこれだった。ちなみに Cherry MX 対応のほうは Corne Cherry と呼ばれる。略して crkbd と表記されることもあるみたい。</p>
<h2>購入、組み立て</h2>
<p>Lily58 Pro と同じく遊舎工房さんの実店舗で購入して組み立てた。組み立ては Lily58 Pro とわりと似ているというか、ダイオードが表面実装タイプで、キーソケットも同じ Kailh Choc のスワップタイプのものだったので、はんだ付けの工程はまったく同じで手間取ることがなかった。最初に使えるようになるまでは5時間ぐらい。</p>
<p><a href="https://gyazo.com/37817309abaa100339c1eecb4c4be121"><img src="https://i.gyazo.com/37817309abaa100339c1eecb4c4be121.jpg" alt="Image from Gyazo" width="400"/></a></p>
<p>大変だったのは LED 。 Corne に関して他の方のビルドログを探ってみても、一様に LED のはんだ付けが難しいという話が出てくるが、確かに難しかった。LED は PCB 基板の裏側からはんだ付けする必要があるのだけど、裏側にそのまま表面実装ではんだ付けする Underglow 用のものと、基板に空いた穴に LED をはめ込んではんだ付けする Backlight 用のものとの2種類がある。難しいと言われるのは Underglow 用のものの方みたいなんだけど、はんだ付け初級者としてはどちらも難しかった。</p>
<h3>Backlight LED</h3>
<p>写真でわかりづらいかもしれないが、 Backlight LED はこのように穴のなかにはめこんで、基板側のランドと繋ぐ必要がある。</p>
<p><a href="https://gyazo.com/f642119bfce092e5c3ee07fd66740ca3"><img src="https://i.gyazo.com/f642119bfce092e5c3ee07fd66740ca3.jpg" alt="Image from Gyazo" width="400"/></a></p>
<p>ただ、基板のランドと LED とが平らに並ぶ（「ツライチ」と呼ぶらしい）わけではなく、少し段差があって、その間をうまくはんだでブリッジさせることが難しかった。ただ、上手くいかなければ一度はんだ吸い取り線で一度はがしてやり直せるので、確かに Underglow よりは楽だと思う。</p>
<h3>Underglow LED</h3>
<p>表面実装なので、何も考えずランドに予備はんだを盛ってから取り付ける方式でやってみたんだけど、それだと LED が浮いてしまってうまくいかず、一度外してやり直そうと思っても LED の裏側にまではんだが入り込んでしまっているので外せなくて終いにはランドを剥がしてしまった。</p>
<p><a href="https://gyazo.com/e1f2cce60faa3d27ab881c4638cb0e8a"><img src="https://i.gyazo.com/e1f2cce60faa3d27ab881c4638cb0e8a.jpg" alt="Image from Gyazo" width="400"/></a></p>
<p>その後いろいろと調べてみたところ、 <a href="http://nok0714.hatenablog.com/entry/2019/03/02/194138">Corne Chocolateビルドログ - nokの雑記</a> に図解されているように、予備はんだを盛るのではなくて、 LED を先に基板に置いてしまって、端子部分に横からはんだを差し入れるようにするのが良いらしいとわかった。その後気づいたけれど、これは Corne Chocolate ではなくて、前バージョンにあたる <a href="https://github.com/foostan/crkbd/blob/master/corne-classic/doc/buildguide_jp.md">Corne Classic のビルドガイド</a> にも載っている方法だった。</p>
<p>幸いにも遊舎工房さんで Corne の PCB 単体での販売があったので、それで1枚追加で購入して改めてやり直した。やり方を変えてそれなりにスムーズに実装できるようになったが、この方法はちゃんとはんだが盛れているか目視では確認しづらくて、頻繁に通電してちゃんと光るか確認しながら進めた。ビルドガイドにもある通り、 LED はすべて接続されていて、1つがダメだとその先のものがすべて光らなくなるので、番号順に実装を進めていった。わからなかったのが、光らない LED があるものの、その先の LED は光っており、しかし色がおかしい、という事態。これがどうにも克服できなかった。電気的な部分はまったくわからないなりに <a href="https://marksard.github.io/2018/08/04/make-the-crkbd/">コルネキーボードを作りました ～LED取り付けに四苦八苦記～ | キオクノロンダリング</a> などを参考に、どの端子がどういう働きをしているかなどを確認してみて、導線で上手いことジャンパすれば直らないかなと四苦八苦した結果、原理はわからないけれど、光らない LED と、その1つ手前の LED の DOUT 同士を繋いでみたところ、光らない LED は光らないままだけど色はちゃんと出るようになった。 Underglow が1つ光らないのは諦めて、いまのところこれで妥協している。</p>
<p><a href="https://gyazo.com/1f366b2b467921be1dd3fa4ae6a21da1"><img src="https://i.gyazo.com/1f366b2b467921be1dd3fa4ae6a21da1.jpg" alt="Image from Gyazo" width="400"/></a></p>
<h2>キーキャップとキースイッチ</h2>
<p>キースイッチは前回の Lily58 Pro で茶軸を買っていたので、今回は赤軸を買ってみた。軽くサクサク打ててとてもよかったんだけど、小指で押さえるキーや、一定時間押しっぱなしにする修飾キーはタクタイルのクリック感があったほうが押し込みやすかったので、今は以下のようなハイブリッドにしてみている。</p>
<p><a href="https://gyazo.com/a7464fae428d09232d8f6d96257401f5"><img src="https://i.gyazo.com/a7464fae428d09232d8f6d96257401f5.jpg" alt="Image from Gyazo" width="600"/></a></p>
<p>キーキャップは monksoffunk 氏が DMM.make で販売しているものを買ってみた。</p>
<p>https://make.dmm.com/item/1009205/</p>
<p>DMM.make では3Dプリント用のデータをアップロードして出品することができる。ユーザーがそのデータに対して注文をかけると、 DMM で実際にプリントして物品を送ってきてくれる仕組み。3Dプリントされた物品を手に持ったことがないのでどんなものかと思ったけど、手触りはさらさらしているものの程よいざらつきもあって、とても打ち心地のいいキーキャップだった。Kailh Choc 用のキーキャップは、<a href="https://yushakobo.jp/shop/pg1350cap-blank/">遊舎工房にも置かれている Kailh 自身が販売しているもの</a>ぐらいしか出回っていないと思うのだけど、それと比べても見た目、打ち心地ともに上回って満足している。</p>
<p>ちなみにプリントする素材が選べるのだが、PA12GB ブラック磨きを選択している。販売ページの断り書きに「破損の恐れがあるためキャンセルを促される連絡があるかもしれません」とあるけれど、これはこのキーキャップが DMM 側の規定サイズを満たさず、品質保証ができないためのようで、実際に一度は DMM 側から強制的にキャンセルされた。その後サポートから「破損の可能性を受け入れた上で再注文したい」と申し出たところ無事に購入することができ、再注文から9日で到着した。確かに1個だけ軸が折れたものが混ざっていたけれど、キットには予備のキーキャップがいくつか入っているので問題はなかった。</p>
<p><a href="https://gyazo.com/7336dc16b0729f856685ff7ba63b0e74"><img src="https://i.gyazo.com/7336dc16b0729f856685ff7ba63b0e74.jpg" alt="Image from Gyazo" width="400"/></a></p>
<h2>キーマップ</h2>
<p>まだ適宜変更は入ると思うけど、いまのところ以下のようになっている。</p>
<pre><code class="language-c">const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  [_QWERTY] = LAYOUT_kc( \
  //,-----------------------------------------.                ,-----------------------------------------.
        TAB,     Q,     W,     E,     R,     T,                      Y,     U,     I,     O,     P,  BSLS,\
  //|------+------+------+------+------+------|                |------+------+------+------+------+------|
     CTLGUI,     A,     S,     D,     F,     G,                      H,     J,     K,     L,  SCLN,  QUOT,\
  //|------+------+------+------+------+------|                |------+------+------+------+------+------|
     SFTESC,     Z,     X,     C,     V,     B,                      N,     M,  COMM,   DOT,  SLSH,  RALT,\
  //|------+------+------+------+------+------+------|  |------+------+------+------+------+------+------|
                                   LGUI, LOWER,SPCALT,      ENT,RASLNG,  BSPC \
                              //`--------------------'  `--------------------'
  ),

  [_RAISE] = LAYOUT_kc( \
  //,-----------------------------------------.                ,-----------------------------------------.
       LRST,    F1,    F2,    F3,    F4,    F5,                     F6,    F7,    F8,    F9,   F10,   F12,\
  //|------+------+------+------+------+------|                |------+------+------+------+------+------|
       LTOG,  LHUI,  LSAI,  LVAI, XXXXX, XXXXX,                   LEFT,  DOWN,    UP, RIGHT,  VOLU,  BRIU,\
  //|------+------+------+------+------+------|                |------+------+------+------+------+------|
       LMOD,  LHUD,  LSAD,  LVAD, XXXXX, XXXXX,                  XXXXX, XXXXX, XXXXX,  MUTE,  VOLD,  BRID,\
  //|------+------+------+------+------+------+------|  |------+------+------+------+------+------+------|
                                   LGUI, LOWER,SPCALT,      ENT,RASLNG,   CAD \
                              //`--------------------'  `--------------------'
  ),

  [_LOWER] = LAYOUT_kc( \
  //,-----------------------------------------.                ,-----------------------------------------.
       EXLM,     1,     2,     3,     4,     5,                      6,     7,     8,     9,     0, XXXXX,\
  //|------+------+------+------+------+------|                |------+------+------+------+------+------|
       TILD, XXXXX, XXXXX, XXXXX, XXXXX, LCBRS,                  RCBRS,  MINS,   EQL, XXXXX, XXXXX, XXXXX,\
  //|------+------+------+------+------+------|                |------+------+------+------+------+------|
        GRV,    AT,  HASH,   DLR,  PERC, XXXXX,                   ASTR,  UNDS,  PLUS,  CIRC,  AMPR,  ASTR,\
  //|------+------+------+------+------+------+------|  |------+------+------+------+------+------+------|
                                   LGUI, LOWER,SPCALT,      ENT,RASLNG,  BSPC \
                              //`--------------------'  `--------------------'
  )
};
</code></pre>
<p>デフォルトでは RAISE と LAWER を同時押しすることで変更できる ADJUST レイヤーも含む4レイヤー用意されているが、3レイヤーでなんとか収まった。LOWER が記号や数字、RAISE がファンクションキーや LED の調整などの操作系のキーという振り分けになっている。</p>
<p>42キーとだいぶキー数が減ったことで、1つのキーに Tap Dance や Mod-Tap によって複数の役割をもたせている箇所も増えている。左側の「SFTESC」や、親指部分の「SPCALT」はいずれも Mod-Tap で同時押ししたときと単推しのときで役割を変えている。また LOWER レイヤーの左右それぞれ一番内側中段にある「LCBRS」「RCBRS」は Tap Dance によって <code>[</code>, <code>(</code>, <code>{</code> の3種類の括弧を切り替えられるようにしたものなんだけど、3回タップするのはわりと手間で、ちょっと今見直そうか迷っている。</p>
<p>渾身のキーが右親指の「RASLNG」。これは長押しすると RAISE、単推しで IME 無効化、2回連続押しで IME 有効化という3種類の役割を担っている。IME の on/off 切り替えは1つのキーでトグルさせるのではなく、別々のキーに割り当てたほうが冪等な操作ができて良い、と私も思っているのだけど、例えば左親指で off で右親指で on のように振り分けるとどちらがどっちだったか覚えるのが煩わしいという問題と、同じ IME 操作をするのに意識が左右に散らばってしまって不快という問題があり、1つのキーを押した回数で冪等に切り替える方式を採用した。 Tap Dance の設定を以下のように書いており、1回押したときに <code>LANG2</code> と <code>F13</code> 、2回押したときに <code>LANG1</code> と <code>F16</code> を発行するようにしている。LANGの各キーコードによる IME の切り替えは macOS にしか対応しないので、 Windows では IME の設定により、ファンクションキーで IME の有効無効を切り替えられるようにした形。</p>
<pre><code class="language-c">enum {
  SINGLE_TAP = 1,
  SINGLE_HOLD = 2,
  DOUBLE_TAP = 3,
};

typedef struct {
  bool is_press_action;
  int state;
} tap;

int lang_dance (qk_tap_dance_state_t *state) {
  if (state->count == 1) {
    if (!state->pressed) return SINGLE_TAP;
    else return SINGLE_HOLD;
  }
  else if (state->count == 2) {
    return DOUBLE_TAP;
  }
  else return 6;
}

static tap xtap_state = {
  .is_press_action = true,
  .state = 0
};

void x_finished_1 (qk_tap_dance_state_t *state, void *user_data) {
  xtap_state.state = lang_dance(state);
  switch (xtap_state.state) {
    case SINGLE_TAP:
        register_code(KC_F13);
        register_code(KC_LANG2);
        break;
    case SINGLE_HOLD:
        layer_on(_RAISE);
        break;
    case DOUBLE_TAP:
        register_code(KC_F16);
        register_code(KC_LANG1);
        break;
  }
}

void x_reset_1 (qk_tap_dance_state_t *state, void *user_data) {
  switch (xtap_state.state) {
    case SINGLE_TAP:  
        unregister_code(KC_F13); 
        unregister_code(KC_LANG2);
        break;
    case SINGLE_HOLD: 
        layer_off(_RAISE);
        break;
    case DOUBLE_TAP:
        unregister_code(KC_F16);
        unregister_code(KC_LANG1);
        break;
  }
  xtap_state.state = 0;
}
</code></pre>
<p>これは自分で思いついたわけではなくて、実装にあたっては以下の記事を大いに参考にさせていただいた。</p>
<ul>
<li><a href="https://qiita.com/miyaoka/items/e3f7242b4767cd599364">変わり種ErgoDox紹介 + IME話 - Qiita</a></li>
<li><a href="https://thomasbaart.nl/2018/12/13/qmk-basics-tap-dance/">QMK Basics: Tap dance, or how to let a key do more with one, two, three – Thomas Baart</a></li>
</ul>
<h2>Impression</h2>
<p>記号キーがどこにあるかはまだ全然覚えていないし、特にパスワードを打つときすごく苦労しているけれど、見込んでいたとおり、すべてのキーがホームポジションから1キーだけ離れたところに収まっているというのは無茶苦茶快適で大満足している。早いけれど、とりあえずはこれで End Game と考えていいんじゃないかなぁと感じているぐらい。40%キーボードが実用に足るとは1か月前にはさらさら考えていなかったのが嘘のように「40%でキー数は十分」と思うようになってきている。 LED についても要らないでしょと思っていたし、実用上の意味はまったくないんだけど、実際光ってみるとカッコよく見えてしまい、作り直しまでしてこだわってしまったので、やってみないとわからないことって多いなぁと。</p>
<p>End Game っぽいとは言え、自作キーボード周りの買い物や工作がこれで終わりではなくて、まだ買いたいものもある。<a href="https://keyhive.xyz/shop/aluminum-corne-helidox-case">IMK Corne Case — KeyHive</a> で今アルミ製のケースのグループバイが始まっていて、ちょっと高いけど買おうかなぁと思っている（実際の購入は遊舎工房さんの日本プロキシを用いる予定）。あとせっかくなので Kailh Choc の他のキースイッチも Novelkeys から個人輸入で買ってみようかな、と。はんだ付け工具一式も揃ったんだし、また興味を引かれるキーボードを見かけたら買ってみたい。今回 PCB を追加で買ったときに、足りなくなった部品を買いに秋葉原の秋月電子通商やら西川電子部品やらにも初めて足を踏み入れて、今まで知らなかった領域の知識が増えるのがとても楽しかったし、この経験は今後も活きるといいなと思っている。</p>
]]></description>
            <link>https://chroju.dev/blog/corne_chocolate_build_log</link>
            <guid isPermaLink="false">corne_chocolate_build_log</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 09 Jun 2019 08:30:59 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[転職ドラフトに5回参加した感想とエンジニアの給与について]]></title>
            <description><![CDATA[<h2>tl;dr</h2>
<ul>
<li>転職ドラフトに5回参加した結果について</li>
</ul>
<h2>転職ドラフトに5回参加した</h2>
<p>転職ドラフトというサービスがありまして、何かというと隔月で2週間に渡りドラフトが開かれ、そのときにレジュメと希望年収を登録した上でドラフト参加登録をしておくと、企業がそれを見て「こいつほしいわ」と思ったら想定年収込みで採用のお誘いをかけてくれるというものです。もちろん、それで採用確定になるわけじゃなくて、そこから通常の採用フローを経て実際の入社となるわけだけど、転職ドラフト上で提示した年収の90%を下回る金額で採用することは禁止されているので、いろいろとこう安心感があるみたいなそういうもの。これに昨年夏から5回ほど参加した。転職絶対するぞみたいな感じというより、今の自分の GitHub アカウントや Qiita やこのブログを載せたレジュメを見て、おいくら万円なら雇ってくれる会社あるんだろうか、という市場価値を少し測ってみたいという興味から参加した。幸い、参加した回はいずれも指名がもらえて、何度かカジュアル面談という形で話をさせてもらったりもした。</p>
<h2>結果</h2>
<p>最近金額公表が流行っているし金額載せても別にいいんだけど、自分のような無名の人間が載せて意味があるのか知らんし、仮に需要あるなら有料 note とかで販売したほうが良さそうだしってことで、指名金額はこちらの希望年収にプラマイいくらで来たかという形で載せる。希望年収は今もらっている金額を元にしていて、まぁざっくり同世代平均年収よりはウン百万かは高いぐらいで、そんなに謙虚な額にはしていない。</p>
<h3>第13回</h3>
<ul>
<li>希望年収ジャスト 3件</li>
<li>+20万円 1件</li>
<li>-40万円 1件</li>
</ul>
<p>うち3社とカジュアル面談</p>
<h3>第14回</h3>
<ul>
<li>希望年収ジャスト 1件</li>
</ul>
<h3>第16回</h3>
<ul>
<li>希望年収ジャスト 2件</li>
</ul>
<p>うち1社とカジュアル面談</p>
<h3>第17回</h3>
<ul>
<li>希望年収ジャスト 6件</li>
<li>-50万円 1件</li>
</ul>
<p>うち1社とカジュアル面談</p>
<h3>第18回</h3>
<ul>
<li>希望年収ジャスト 2件</li>
</ul>
<h2>指名は想定よりもらえた</h2>
<p>正直言って想定より指名が来たという感覚だった。 GitHub にコードを載せたりしてはいるけど、最大で星もらってるレポジトリでも 4 Stars とかだし、自分としては特に強い自覚はないし、5回のドラフトを経た今でもそれは変わらない。ただ、たまに Twitter で「GitHub にコードを上げている IT エンジニアは全体のx割」みたいな結構少ない数字を見かけることがあるけれど、あれが実際そうなのだろうなという気はしている。カジュアル面談をしていても GitHub に上げているコードの話やブログのエントリーに関する話題を出してもらえたりして、アウトプットをしていてよかったというのはすごく実感した。あとは SRE という職種を自分は希望しているけれど、この職種で採用市場に出回っている人材自体、現状少ないんではないかなという気はしている。インフラエンジニアはもちろんそれなりの数がいるだろうし、コードを書くエンジニアもそうだろうけど、その双方に興味を持つことで、多少なり希少価値が出せてるんではないかなと思う。</p>
<h2>カジュアル面談ってなんなんだ</h2>
<p>会いに行った企業はいずれも選考なしのラフな面談、いわゆるカジュアル面談という形で会わせてもらったが、企業によって形式はまちまちだった。参加者としては、指名されて初めてその企業を知るという場合も多いので、まずは企業のことを知ってもらう機会として設けられているのだと思うけど、実際に時間いっぱいほとんど説明だけに費やされる企業さんもあれば、すべてこちらからの質問だけの時間を取ってくれてなんでも聞いてくださいという感じの企業さんもあり、また逆に、選考ではないのだがかなりの時間質問攻めにされてタジタジになったりした企業さんもあったりした。ただ、あくまで選考ではないので、その結果を突きつけられたりなどということはなかった（その企業の選考には進まなかったので、もし進んでいたら一瞬でお断りにされるとかあったのかもしれないが）。企業側としても「カジュアル面談って何すればいいんですかね？」と悩まれていたりもするようで、そのままその言葉を面談の場で投げられることもあった。俺も聞きたい。</p>
<p>企業側のスタンスも本当にまちまちで、こちらのブログをだいぶ読んでくれていて恥ずかしくなるぐらいにその話をしてもらうようなこともあれば、どうもこれは人手がとにかく欲しくて青田買いのように声かけまくって知名度を上げようという意図っぽいかな？ということもあった。別にそれが悪いとかそういうことではなく、職や金がほしいエンジニアと、人がほしい会社とのマッチング機会としてわりといい感じに機能しているんではないかなこのサービスは、と思った。こちらとしても、事前に自分の考えなりを読んでもらえているというのは、ミスマッチの可能性が抑えられそうで良かった。</p>
<h2>エンジニアとお金と評価について</h2>
<p>何か月か前に Google 退職者による年収公開が散発的に起きたりとか、昨今 IT 系のエンジニアとお金の話をよく見かけるようになった気がしていて、まぁ自分が30代になったので、観測範囲がそうなっただけかもしれないけれど、以前はタブー視されることも多かった「お金の話」がわりとラフにされるようになったんじゃないかみたいな感触は覚えている。それは自分としてはいいことだと思うし、私はこれだけしかもらえていなかった、という話に周囲の人がもっともらうべきだというアドバイスをしたり、あの会社はこれしか払わないのかみたいな話が回ったりとかして、界隈全体で適正な給与が払われるようになればいいなという想いがあるし、俺がお金ほしいというよりは、みんなでお金もらおうぜみたいなことは感じている。</p>
<p>今回のドラフトで実際に何度か指名を得たことで、なるほど自分はこれぐらいの金額を払ってもいいと評価してもらえるのか、と客観的な確認ができたことは、ある程度の自信につながった。ただ、必ずしもその金額はスカウターのように自分の能力を表す指標ではないということも思っている。先に書いたように、希少価値のある、ニッチな領域を攻めれば技術力はそこそこでも高給がもらえるチャンスは広がるだろうし、そもそもあくまでウェブ上でのアウトプットや自己申告のレジュメだけでの評価額なので、実際に選考に進んだら「やっぱこいつねーわ」ってなる可能性もある。また先日バズっていた <a href="https://speakerdeck.com/sogitani1107/shi-shi-togei-yu-toping-jia-falseguan-xi">仕事と給与と評価の関係 - Speaker Deck</a> という記事でも書かれている通り、会社の体力によって払える金額も当然変わる。給与は様々な要因によって決まるものであり、その人物の客観的な評価指標としては機能しないので、多ければ多いほど良いのは確かだけど、それをエンジニアとしての自分の戦闘力みたいに考えない、自惚れないようには注意が必要だなと思う。</p>
<p>なので、転職ドラフトは参加する分には無料だしリスクもないので、お金がそんなにもらえていないと感じるエンジニアは、これぐらい欲しいという額を多少背伸びしてもいいので希望してみて、とりあえず参加してみるといいんじゃないかなと思う。これぐらいお金が欲しいです！と表明して、それを複数の企業にアピールできる機会なんてのは早々ないので。自分も今は一旦不参加状態にしているけれど、今後また転職意欲の有無に関わらず、ふらっと参加してみたりするんじゃないかなーと今は思っている。</p>
]]></description>
            <link>https://chroju.dev/blog/result_of_job_draft_and_engineers_salary</link>
            <guid isPermaLink="false">result_of_job_draft_and_engineers_salary</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 28 May 2019 01:15:42 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Lily58 Pro 最強のキーマップを目指して]]></title>
            <description><![CDATA[<p>自作キーボード Lily58 Pro に関するエントリーシリーズ第3弾、おそらくこれで最後。</p>
<ul>
<li>第1弾 購入編 : <a href="https://chroju.github.io/blog/2019/04/25/how_i_learned_to_stop_worrying_and_love_the_original_keyboards/">Lily58 Pro または私は如何にして市販品を探すのをやめて分割キーボードを自作するようになったか · the world as code</a></li>
<li>第2弾 作成編 : <a href="https://chroju.github.io/blog/2019/04/27/making_lily58_pro_with_a_beginner/">電子工作初心者が Lily58 Pro を買ってから作って持ち運ぶまで · the world as code</a></li>
</ul>
<p>自作キーボードの大きな魅力の一つが自由なキーマップを作れる点で、市販のキーボードのキーマクロ機能の比ではなく、本当にすべてのキーを自由にアサインできる。 Dvorak ももちろん可能だし、「俺が考えた最強の配列」を作ることもできる。また Lily58 をはじめ多くのキーボードはフルキーボードを比較してキー数が少なく設定されていることが多いため、レイヤーの概念などを駆使して、1つのキーに複数の機能をアサインすることも必要になってくる。どのキーにどの役割をいくつ与えるか、という組み合わせも考えていくと、途方もないほどに自由度が高い。</p>
<h2>QMK Firmware</h2>
<p>https://github.com/qmk/qmk_firmware</p>
<p>例の Ergodox 含め、多くの自作キーボードがファームウェアとして QMK Firmware という OSS を活用している。自作キーボード制作者は自身のキーボードを作成したら、そのキーマップ設定を追加して Pull Request を送ることで QMK Firmware 本体のレポジトリに merge されるようで、現在買えるような自作キーボードであれば、基本的には上記レポジトリから clone すれば、すぐにデフォルトキーマップを焼き込めるようになっている。もちろん、そこから自分でキーマップを変えていくこともできる。</p>
<p>QMK Firmware では単にキー配置を司るだけではなく、多くの付随的な機能を提供している。</p>
<h3>レイヤー</h3>
<p>shift キーのように、レイヤー切り替えキーを押下している間のみ、キーアサインが別のものに変換される機能。キー数が少ないキーボードではほぼ必須の機能であり、多くの場合 LOWER と RAISE の2つのレイヤーキーがデフォルトでアサインされている。</p>
<h3>Tap Dance</h3>
<p>1回押した場合と、すばやく複数回押した場合でキーアサインを切り替える機能。複数種類の括弧を1つのキーでまかなえるようにしたり、欧米圏でウムラウト付きのアルファベットなどを出す際に使われているのをよく見る印象。</p>
<h3>Mod-Tap</h3>
<p>他のキーと同時に押した場合は Modifier key = shift や control などの修飾キーに、単独で押した場合は別のキーに切り替える機能。確かに修飾キーというのは同時押しが基本なので、同時に押さない場合は別のキーとして扱う、というのはなんだか頭いいな、と思う発想だった。</p>
<h3>Modifier Keys</h3>
<p>修飾キー + 他のキーを押した状態を、1つのキーにアサインしてしまえる機能。どちらかと言えばキー数に余裕がある場合に、よく使うキーボードショートカットをアサインする、などの利用をするっぽい。</p>
<h3>One Shot Keys</h3>
<p>通常、修飾キーを使う際は同時押しが必要になるが、一度押すとそのキーが押された状態になり、別のキーを押すと押された状態が解除される、という機能。 Windows の固定キーに近い。</p>
<p>他にもマウス操作をキーにアサインできるとか、 Unicode のアサインも可能なので :thinking_face: を1キーで出せるとかいろいろできる。つまり <strong>単純なキーの配置だけではなく、どの機能を使うと自分の理想的な運指になるか</strong> ということを考える必要があり、沼と呼ぶに非常にふさわしい。</p>
<p>なお Lily58 は対応していないが、キーボードにありがちな LED を光らせる設定も QMK Firmware でまかなうことができる。一部機能に関しては <code>rules.mk</code> というファイルに有効化の設定を書かなくてはならないため、ドキュメントを読みながら対応する必要がある。機能を有効化すると、その機能に関するコードがファームウェアに内包されるようになる仕組みと思われる。私の <code>rules.mk</code> はこんな感じ。</p>
<pre><code class="language-c"># Build Options
#   change to "no" to disable the options, or define them in the Makefile in
#   the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE = no       # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = no        # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes       # Audio control and System control(+450)
CONSOLE_ENABLE = no         # Console for debug(+400)
COMMAND_ENABLE = no         # Commands for debug and configuration
NKRO_ENABLE = no            # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE = no       # Enable keyboard backlight functionality
MIDI_ENABLE = no            # MIDI controls
AUDIO_ENABLE = no           # Audio output on port C6
UNICODE_ENABLE = no         # Unicode
BLUETOOTH_ENABLE = no       # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no        # Enable WS2812 RGB underlight.
SWAP_HANDS_ENABLE = no      # Enable one-hand typing
TAP_DANCE_ENABLE = yes

# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no    # Breathing sleep LED during USB suspend

# If you want to change the display of OLED, you need to change here
SRC +=  ./lib/glcdfont.c \
        ./lib/rgb_state_reader.c \
        ./lib/layer_state_reader.c \
        ./lib/logo_reader.c \
        ./lib/key_count.c \
        ./lib/uptime.c \
</code></pre>
<h2>Lily58 デフォルトキーマップ</h2>
<p>すべて自分で考えて配置するのは大変なので、デフォルトキーマップを元に編集することにした。本記事執筆時点で、デフォルトキーマップは以下の通りになっている。</p>
<pre><code class="language-c">/* QWERTY
 * ,-----------------------------------------.                    ,-----------------------------------------.
 * | ESC  |   1  |   2  |   3  |   4  |   5  |                    |   6  |   7  |   8  |   9  |   0  |  `   |
 * |------+------+------+------+------+------|                    |------+------+------+------+------+------|
 * | Tab  |   Q  |   W  |   E  |   R  |   T  |                    |   Y  |   U  |   I  |   O  |   P  |  -   |
 * |------+------+------+------+------+------|                    |------+------+------+------+------+------|
 * |LCTRL |   A  |   S  |   D  |   F  |   G  |-------.    ,-------|   H  |   J  |   K  |   L  |   ;  |  '   |
 * |------+------+------+------+------+------|   [   |    |    ]  |------+------+------+------+------+------|
 * |LShift|   Z  |   X  |   C  |   V  |   B  |-------|    |-------|   N  |   M  |   ,  |   .  |   /  |RShift|
 * `-----------------------------------------/       /     \      \-----------------------------------------'
 *                   | LAlt | LGUI |LOWER | /Space  /       \Enter \  |RAISE |BackSP| RGUI |
 *                   |      |      |      |/       /         \      \ |      |      |      |
 *                   `----------------------------'           '------''--------------------'
 */

 [_QWERTY] = LAYOUT( \
  KC_ESC,   KC_1,   KC_2,    KC_3,    KC_4,    KC_5,                     KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_GRV, \
  KC_TAB,   KC_Q,   KC_W,    KC_E,    KC_R,    KC_T,                     KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_MINS, \
  KC_LCTRL, KC_A,   KC_S,    KC_D,    KC_F,    KC_G,                     KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT, \
  KC_LSFT,  KC_Z,   KC_X,    KC_C,    KC_V,    KC_B, KC_LBRC,  KC_RBRC,  KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH,  KC_RSFT, \
                             KC_LALT, KC_LGUI,LOWER, KC_SPC,   KC_ENT,   RAISE,   KC_BSPC, KC_RGUI \
),
/* LOWER
 * ,-----------------------------------------.                    ,-----------------------------------------.
 * |      |      |      |      |      |      |                    |      |      |      |      |      |      |
 * |------+------+------+------+------+------|                    |------+------+------+------+------+------|
 * |  F1  |  F2  |  F3  |  F4  |  F5  |  F6  |                    |  F7  |  F8  |  F9  | F10  | F11  | F12  |
 * |------+------+------+------+------+------|                    |------+------+------+------+------+------|
 * |   `  |   !  |   @  |   #  |   $  |   %  |-------.    ,-------|   ^  |   &#x26;  |   *  |   (  |   )  |   -  |
 * |------+------+------+------+------+------|   [   |    |    ]  |------+------+------+------+------+------|
 * |      |      |      |      |      |      |-------|    |-------|      |   _  |   +  |   {  |   }  |   |  |
 * `-----------------------------------------/       /     \      \-----------------------------------------'
 *                   | LAlt | LGUI |LOWER | /Space  /       \Enter \  |RAISE |BackSP| RGUI |
 *                   |      |      |      |/       /         \      \ |      |      |      |
 *                   `----------------------------'           '------''--------------------'
 */
[_LOWER] = LAYOUT( \
  _______, _______, _______, _______, _______, _______,                   _______, _______, _______,_______, _______, _______,\
  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,                     KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12, \
  KC_GRV, KC_EXLM, KC_AT,   KC_HASH, KC_DLR,  KC_PERC,                   KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_TILD, \
  _______, _______, _______, _______, _______, _______, _______, _______, XXXXXXX, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, \
                             _______, _______, _______, _______, _______,  _______, _______, _______\
),
/* RAISE
 * ,-----------------------------------------.                    ,-----------------------------------------.
 * |      |      |      |      |      |      |                    |      |      |      |      |      |      |
 * |------+------+------+------+------+------|                    |------+------+------+------+------+------|
 * |   `  |   1  |   2  |   3  |   4  |   5  |                    |   6  |   7  |   8  |   9  |   0  |      |
 * |------+------+------+------+------+------|                    |------+------+------+------+------+------|
 * |  F1  |  F2  |  F3  |  F4  |  F5  |  F6  |-------.    ,-------|      | Left | Down |  Up  |Right |      |
 * |------+------+------+------+------+------|   [   |    |    ]  |------+------+------+------+------+------|
 * |  F7  |  F8  |  F9  | F10  | F11  | F12  |-------|    |-------|   +  |   -  |   =  |   [  |   ]  |   \  |
 * `-----------------------------------------/       /     \      \-----------------------------------------'
 *                   | LAlt | LGUI |LOWER | /Space  /       \Enter \  |RAISE |BackSP| RGUI |
 *                   |      |      |      |/       /         \      \ |      |      |      |
 *                   `----------------------------'           '------''--------------------'
 */

[_RAISE] = LAYOUT( \
  _______, _______, _______, _______, _______, _______,                     _______, _______, _______, _______, _______, _______, \
  KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,    KC_5,                        KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    _______, \
  KC_F1,  KC_F2,    KC_F3,   KC_F4,   KC_F5,   KC_F6,                       XXXXXXX, KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT, XXXXXXX, \
  KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,   _______, _______,  KC_PLUS, KC_MINS, KC_EQL,  KC_LBRC, KC_RBRC, KC_BSLS, \
                             _______, _______, _______,  _______, _______,  _______, _______, _______ \
</code></pre>
<p>これに対する自分の意見は以下。</p>
<ul>
<li>右GUI、右Shiftは不要</li>
<li>Backspace が右親指の位置にあるが、最初は慣れないと思うので右上にも配置したい</li>
<li>LOWER レイヤーにすべての記号がアサインされているが、 Lily58 は数字キーも存在するのでいくつかは重複アサインとなっており、不要</li>
<li>ファンクションキーは数字キーと同じ列にそれぞれ配置するとわかりやすそう（F11とF12は諦める）</li>
<li>矢印キーは Vim の感覚から <code>hjkl</code> にあると覚えやすそう</li>
</ul>
<p>これを踏まえてキーマップを作成した。</p>
<h2>現時点で最強のキーマップ</h2>
<p>自作キーボードは親指を駆使させ、小指を使わなくさせる傾向にあることが多い。　Ergodox の親指用キーの多さなどは顕著である。多くの人は小指より親指のほうが動かしやすいと思うので理に適った話ではあるが、しかし使い慣れたキー配置からの移行コストもあるわけで、一旦折衷的なキーマップとした。 まずはデフォルトのレイヤー。</p>
<pre><code class="language-c">/* QWERTY
 * ,------------------------------------------.                    ,-----------------------------------------.
 * | ESC   |   1  |   2  |   3  |   4  |   5  |                    |   6  |   7  |   8  |   9  |   0  |BackSP|
 * |-------+------+------+------+------+------|                    |------+------+------+------+------+------|
 * | Tab   |   Q  |   W  |   E  |   R  |   T  |                    |   Y  |   U  |   I  |   O  |   P  |  -   |
 * |-------+------+------+------+------+------|                    |------+------+------+------+------+------|
 * |CTL/GUI|   A  |   S  |   D  |   F  |   G  |-------.    ,-------|   H  |   J  |   K  |   L  |   ;  |  '   |
 * |-------+------+------+------+------+------|   [   |    |    ]  |------+------+------+------+------+------|
 * |LShift |   Z  |   X  |   C  |   V  |   B  |-------|    |-------|   N  |   M  |   ,  |   .  |   /  |CTL+Sp|
 * `------------------------------------------/       /     \      \-----------------------------------------'
 *                    | LAlt | LGUI |LOWER | /Space  /       \Enter \  |RAISE |BackSP| ESC  |
 *                    |      |      |IMEon |/       /         \      \ |IMEoff|      |      |
 *                    `----------------------------'           '------''--------------------'
 */

 [_QWERTY] = LAYOUT( \
  KC_ESC,           KC_1,   KC_2,    KC_3,    KC_4,    KC_5,                                KC_6,           KC_7,    KC_8,    KC_9,    KC_0,    KC_BSPC,      \
  KC_TAB,           KC_Q,   KC_W,    KC_E,    KC_R,    KC_T,                                KC_Y,           KC_U,    KC_I,    KC_O,    KC_P,    KC_BSLS,      \
  TD(TD_CTL_GUI),   KC_A,   KC_S,    KC_D,    KC_F,    KC_G,                                KC_H,           KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT,      \
  KC_LSFT,          KC_Z,   KC_X,    KC_C,    KC_V,    KC_B,            KC_LBRC,   KC_RBRC, KC_N,           KC_M,    KC_COMM, KC_DOT,  KC_SLSH, LCTL(KC_SPC), \
                                     KC_LALT, KC_LGUI, LT(1, KC_LANG1), KC_SPC,    KC_ENT,  LT(2,KC_LANG2), KC_BSPC, KC_ESC  \
),
</code></pre>
<p>Backspace と ESC は右親指で押すことを目指すが、現時点では一般的な位置にも配置している。最左列、下から2番目のキーは Tap-Dance により、1回押すと ctrl、2回押すと GUI とした。これは macOS でキーボードショートカットが GUI（⌘）に割り当たっている一方、 GNU Readline の各種ショートカットが ctrl と位置がバラけるのが嫌だったため。これも移行措置として、通常の位置にも GUI を置いている。</p>
<p>なお、 Tap-Dance はどのキーを何回押したときにどう動作させるか、という定義を書く必要があり、キーマップ以外に以下のようなコードを追加している。</p>
<pre><code class="language-c">enum {
  TD_CTL_GUI = 0
};

qk_tap_dance_action_t tap_dance_actions[] = {
  [TD_CTL_GUI] = ACTION_TAP_DANCE_DOUBLE(KC_LCTRL, KC_LGUI)
};
</code></pre>
<p>LOWER、RAISEの各キーは Mod-Tap により、単独で押した場合に <code>KC_LANG1</code> と <code>KC_LANG2</code> というキーをそれぞれ割り当てている。ドキュメントに記載はないのだが、これらは macOS のかな/英数に相当するらしく、 IME の切り替えが Toggle ではなく一発で出来るようになる。 US キーボードを使っていると IME 切り替えは ctrl + space などで Toggle させるしかなかったため、このアサインが出来るのは嬉しかった。</p>
<p>参考 : <a href="https://qiita.com/miyaoka/items/e3f7242b4767cd599364#_reference-af7104110d01879c97d3">変わり種ErgoDox紹介 + IME話 - Qiita</a></p>
<p>最右最下は正直余ってしまったので、 ctrl + space を割り当てた。 Windows での IME 切り替えに現在使っているが、 Windows でも OS 側の設定で <code>KC_LANG</code> 各キーを IME 切り替えに割り当てられるらしいので、後日対応の予定。</p>
<h3>LOWER</h3>
<pre><code class="language-c">/* LOWER
 * ,-----------------------------------------.                    ,-----------------------------------------.
 * |      |      |      |      |      |      |                    |      |      |      |      |      |      |
 * |------+------+------+------+------+------|                    |------+------+------+------+------+------|
 * |      |      |      |      |   ~  |      |                    |      |      |      |  _   |  +   |      |
 * |------+------+------+------+------+------|                    |------+------+------+------+------+------|
 * |      |      |      |      |   `  |      |-------.    ,-------|      |      |      |  -   |  =   |      |
 * |------+------+------+------+------+------|   (   |    |    )  |------+------+------+------+------+------|
 * |      |      |      |      |      |      |-------|    |-------|      |      |      |      |      |      |
 * `-----------------------------------------/       /     \      \-----------------------------------------'
 *                   | LAlt | LGUI |LOWER | /Space  /       \Enter \  |RAISE |BackSP| RGUI |
 *                   |      |      |      |/       /         \      \ |      |      |      |
 *                   `----------------------------'           '------''--------------------'
 */

[_LOWER] = LAYOUT( \
  _______, _______, _______, _______, _______, _______,                     _______, _______, _______, _______, _______, _______, \
  _______, _______, _______, _______, KC_TILD, _______,                     _______, KC_UNDS, KC_PLUS, _______, _______, _______, \
  _______, _______, _______, _______, KC_GRV,  _______,                     _______, KC_MINS, KC_EQL,  _______, _______, _______, \
  _______, _______, _______, _______, _______, _______,  KC_LPRN, KC_RPRN,  _______, _______, _______, _______, _______, _______, \
                             _______, _______, _______,  _______, _______,  _______, _______, _______ \
),
</code></pre>
<p>LOWER は記号キー用とした。通常配置で盛り込みきれていない記号キーだけに絞っている。</p>
<p>当初はハイフンを9に割り当てるなど、一般的配列と近い位置に配置していたが、わざわざ遠くへ押しに行く必要もないと考え直し、左右とも人差し指近くに集中させた。</p>
<h3>RAISE</h3>
<pre><code class="language-c">/* RAISE
 * ,-----------------------------------------.                    ,-----------------------------------------.
 * |      |      |      |      |      |      |                    |      |      |      |      |      | DEL  |
 * |------+------+------+------+------+------|                    |------+------+------+------+------+------|
 * | F11  |  F1  |  F2  |  F3  |  F4  |  F5  |                    |  F6  |  F7  |  F8  |  F9  | F10  | F12  |
 * |------+------+------+------+------+------|                    |------+------+------+------+------+------|
 * |      |      |      |      |      |      |-------.    ,-------| LEFT | DOWN |  UP  |RIGHT |      |      |
 * |------+------+------+------+------+------|   [   |    |    ]  |------+------+------+------+------+------|
 * |      |      |      |      |      |      |-------|    |-------| BRID | BRIU | VOLD | VOLU | MUTE |      |
 * `-----------------------------------------/       /     \      \-----------------------------------------'
 *                   | LAlt | LGUI |LOWER | /Space  /       \Enter \  |RAISE |BackSP| CAD  |
 *                   |      |      |      |/       /         \      \ |      |      |      |
 *                   `----------------------------'           '------''--------------------'
 */
[_RAISE] = LAYOUT( \
  _______, _______, _______, _______, _______, _______,                   _______, _______, _______, _______,  _______, KC_DEL,  \
  KC_F11,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,                     KC_F6,   KC_F7,   KC_F8,   KC_F9,    KC_F10,  KC_F12,  \
  _______, _______, _______, _______, _______, _______,                   KC_LEFT, KC_DOWN, KC_UP,   KC_RIGHT, _______, _______, \
  _______, _______, _______, _______, _______, _______, _______, _______, KC_BRID, KC_BRIU, KC_VOLD, KC_VOLU,  KC_MUTE, _______, \
                             _______, _______, _______, _______, _______, _______, _______, LCTL(LALT(KC_DEL)) \
),
</code></pre>
<p>RAISE は機能的なキー担当。先述の方針通りにファンクションキーと矢印キーを並べている。</p>
<p>また Macbook に搭載されている輝度や音量調節のキーをよく使っていたので、それらも割り当てた。 Windows でも動いてくれるとうれしいのだが、いまのところ動かないので要調整。</p>
<p>右親指あたりにある「CAD」というキーは ctrl + alt + delete の同時押しに相当している。 Windows 最悪のあのキーバインドが簡単に打てて QOL がだいぶ上がった。右上の Delete は Windows で使うことがあるかもしれない、ということで念の為配置している。今のところ必要になったことはない。</p>
<h2>Conclusion</h2>
<p>この配置になるまで5回ぐらいはキーマップの変更を経ているが、ようやく安定したかなというところ。自作キーボードは組み立て終わってからが沼だとはよく言ったものだなと思う。</p>
<p>なるべく親指の役割を増やす、ホームポジションから手を動かさず済むようにする、というのは実際にやってみると確かに負荷が少ない。もともと自分は「腕を動かすのが嫌」という理由でトラックパッドとトラックボールを愛用してもいるので、キーボード上で指の移動距離を減らす、という考え方にもハマりこんでしまった。</p>
<p>そしてその結果、自分でも面白い変化だと思うが、「数字列」が遠いと思うようになってきた。指を動かす範囲は上下左右1キー以内に現状ほぼ収まってきたので、たまに数字列だけ2キー分指を伸ばさなくてはならないのがどうにも気持ち悪い。</p>
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-permalink="https://www.instagram.com/p/BxzgRXqAKWD/" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BxzgRXqAKWD/" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div> <div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> この投稿をInstagramで見る</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div></a> <p style=" margin:8px 0 0 0; padding:0 4px;"> <a href="https://www.instagram.com/p/BxzgRXqAKWD/" style=" color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;" target="_blank">corne chocolate 買っちった</a></p> <p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">@<a href="https://www.instagram.com/chroju/" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px;" target="_blank"> chroju</a>がシェアした投稿 - <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2019-05-23T12:17:49+00:00">2019年 5月月23日午前5時17分PDT</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script>
<p>つまりこういうことである。 Lily58 から数字列をザックリ削ったような形状の <a href="https://github.com/foostan/crkbd">Corne Chocolate</a> を買ってしまった。キーマップを見てもらってもわかる通り、58キーだとちょろちょろ余ることもわかったし、42キーでも案外イケそうな気はしている。願わくば、これで End Game に至るといいのだが。</p>
]]></description>
            <link>https://chroju.dev/blog/pursue_the_best_keymaps_with_qmk_firmware</link>
            <guid isPermaLink="false">pursue_the_best_keymaps_with_qmk_firmware</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 24 May 2019 12:49:37 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[3rd Party tool をきっかけに Terraform のソースコードを少し嗜んだ話]]></title>
            <description><![CDATA[<h2>tl;dr</h2>
<p>今回あんまりまとまった話でもなくて、いろいろ調べていたら手元のメモがだいぶ長くなったのでせっかくだし公開してみよう、程度のものです。正直文章化が上手くできているとも思えなくて、読みにくいと思いますしスルー推奨です。一応3行でまとめておきます。</p>
<ul>
<li>terraformer に issue を上げたら Terraform の内部実装に絡めた返答をもらったが、すぐに理解できなかった。</li>
<li>そこで terraformer と Terraform のコードリーディングをしてみて、その過程を書いてみた。</li>
<li>Terraform 内で使われている gRPC の勉強が必要とか、コードリーディングの効率を上げたいといった課題も見つかり、良い機会になった。</li>
</ul>
<h2>terraformer</h2>
<p>terraformer というツールをご存知でしょうか。</p>
<p>https://github.com/GoogleCloudPlatform/terraformer</p>
<p>既存のクラウドリソースの状態を読み解き、 tf ファイルと tfstate ファイルを生成してくれるツールです。同様のツールとしては <a href="https://github.com/dtan4/terraforming">dtan4/terraforming</a> が著名で、 terraformer の README.md 内でも言及があるほどですが、この2つにはそこそこ差異が見られます。</p>
<p>まず機能面においては、 terraforming が指定したリソースの tf ファイル、 tfstate ファイル相当の情報を愚直に標準出力に出す、非常にシンプルな実装をしているのに対し、 terraformer は tf ファイルと tfstate ファイルを同時生成するほか、 <code>provider.tf</code> や、<code>terraform apply</code> したときに動的に生成される、インスタンス ID のような computed な値を出力するための <code>outputs.tf</code> まで生成してくれる至れり尽くせりなツールになっています。また、例えば <code>terraformer import aws --resources=route53</code> を実行すると Route53 に関するすべての情報を取得する、つまり <code>aws_route53_zone</code> と <code>aws_route53_record</code> 双方が生成される形になります。先のコマンドで生成されるファイルは以下のとおりです。</p>
<pre><code class="language-bash">$ tree
.
├── outputs.tf
├── provider.tf
├── route53_record.tf
├── route53_zone.tf
└── terraform.tfstate

0 directories, 5 files
</code></pre>
<p>そして実装面でもだいぶアプローチが異なるのですが、それについては最後に触れようと思います。</p>
<h2>発端となった issue</h2>
<p>本題に入りますが、 先日 Route53 Records の <code>import</code> を terraformer で行ったところ、エイリアスレコードに関してちょっとした問題が起きたため、 issue を上げました。</p>
<p>https://github.com/GoogleCloudPlatform/terraformer/issues/65</p>
<p>何を言っているかというと、 Route53 の DNS Record には当然ながら TTL の設定ができるのですが、そのレコードがエイリアスレコードである場合は TTL の設定ができない（Terraform 的な言い方をすると、2つの要素が競合 = Confilict した状態）はずなのに、 terraformer は <code>ttl = "0"</code> として設定を入れてしまっている、という話です。この状態で <code>terraform plan</code> を実行すると、競合する要素が定義されているよ、というエラーになります。</p>
<p>これに対して開発者の sergeylanzman 氏が返答してきたのが、以下の文です。</p>
<blockquote>
<p>It's know issue(#25) terraformer can't get today details about each field.</p>
</blockquote>
<p>これだけではいまいちわからなかったので、ここで言及されている <a href="https://github.com/GoogleCloudPlatform/terraformer/issues/25">#25</a> の issue を引用してみると、このような内容になっています。</p>
<blockquote>
<p>Today terraformer use terraform.ResourceProvider interface for get ProviderSchema with Attributes.
In other interface we can get more Attributes from providers(like deprecation options)
Need use schema.Schema from github.com/hashicorp/terraform/helper/schema</p>
</blockquote>
<p>どうも terraformer が使っている terraform 側の interface の都合が絡んでいるようです。現在は <code>terraform.ResourceProvider</code> を使っているが、これを <code>schema.Schema</code> に変更したほうが、より詳細な情報を取得できる、という内容に読み取れます。私は Terraform の動作、ソースコードを広く把握できているわけではないので、この返答をもらっても飲み込むことができず、ソースコードにあたってみることにしました。</p>
<h2>terraformer と Terraform を読み解く</h2>
<p>まず terraformer の動作原理を少し確認しました。 import コマンドの実装部分は <a href="https://github.com/GoogleCloudPlatform/terraformer/blob/master/cmd/import.go">terraformer/cmd/import.go</a> 内の <code>func Import()</code> にあります。ここではコマンドのオプション <code>--resources</code> で与えられたリソース名（Route53, S3 など）に対し、 for 文でそれぞれ以下のような処理が実行されています。</p>
<pre><code class="language-go">		err = provider.InitService(service)
		if err != nil {
			return err
		}
		err = provider.GetService().InitResources()
		if err != nil {
			return err
		}

		if len(options.Filter) != 0 {
			provider.GetService().ParseFilter(options.Filter)
			provider.GetService().CleanupWithFilter()
		}

		refreshedResources, err := terraform_utils.RefreshResources(provider.GetService().GetResources(), provider.GetName(), provider.GetConfig())
		if err != nil {
			return err
		}
		provider.GetService().SetResources(refreshedResources)
</code></pre>
<p>見たところ <code>provider.InitService()</code> で各サービス（Route53など）に対する初期化処理を行い、さらに <code>provider.GetService().InitResources()</code> で、各サービス内の個別リソース（Route53 Record や Zone など）に対する初期化を行い、その上で <code>terraform_utils.RefreshResoures()</code> というメソッドを呼ぶ、と何段階かを経ているのが読み取れます。ここの <code>provider</code> とはいわゆる Terraform Provider ではなく、 terraformer 内の <code>terraform_utils.ProviderGenerator</code> という interface を指しており、AWS、GCP等の各 Provider 向けにこれを実装しています。例えば AWS に関しては <a href="https://github.com/GoogleCloudPlatform/terraformer/blob/master/providers/aws/aws_provider.go">terraformer/providers/aws/aws_provider.go</a> 内の <code>AWSProvider</code> が該当し、この中に <code>func InitService()</code> が定義されています。<code>InitService</code> で行われる処理は文字通り初期化処理で、例えば terraformer はすべての AWS サービスに対応しているわけではないので、ここで対応非対応の判定を行っていたりするようです。</p>
<p>続いて <code>provider.GetService().InitResources()</code> ですが、 Route53 の場合は <a href="https://github.com/GoogleCloudPlatform/terraformer/blob/master/providers/aws/route53.go">terraformer/providers/aws/route53.go</a> で定義されており、まずホストゾーンの情報をすべて取得してから、各ホストゾーンに対してレコード情報の取得を行う、という実装になっています。以下に、レコード情報を取得する部分を担っているメソッドである <code>createRecordsResources()</code> のソースを引用してみます。</p>
<pre><code class="language-go">func (Route53Generator) createRecordsResources(svc *route53.Route53, zoneID string) []terraform_utils.Resource {
	resources := []terraform_utils.Resource{}
	listParams := &#x26;route53.ListResourceRecordSetsInput{
		HostedZoneId: aws.String(zoneID),
	}
	recordSet, err := svc.ListResourceRecordSets(listParams)
	for _, record := range recordSet.ResourceRecordSets {

		resources = append(resources, terraform_utils.NewResource(
			fmt.Sprintf("%s_%s_%s", zoneID, aws.StringValue(record.Name), aws.StringValue(record.Type)),
			fmt.Sprintf("%s_%s_%s", zoneID, aws.StringValue(record.Name), aws.StringValue(record.Type)),
			"aws_route53_record",
			"aws",
			map[string]string{
				"name":    aws.StringValue(record.Name),
				"zone_id": zoneID,
				"type":    aws.StringValue(record.Type),
			},
			route53AllowEmptyValues,
			route53AdditionalFields,
		))
	}
	if err != nil {
		log.Println(err)
		return []terraform_utils.Resource{}
	}
	return resources
}
</code></pre>
<p>AWS の API を呼んで、実際に情報を取得しているのがここの6行目の箇所で、取得した list を格納した <code>recordSet</code> 変数に対して <code>for</code> を回し、必要な情報を格納した <code>resources</code> 変数を返り値として戻す、という構成になっています。しかし <code>resources</code> に情報を格納するコードを読んでみると、 API から取得した情報を格納しているのは14行目からの <code>map[string]string</code> を作っている箇所だけで、 name, zone_id, type という3つの要素しか格納されていません。これでは Route53 Record の情報としては当然ながら不足しています。</p>
<p>どうもこれを補うのが <code>terraform_utils.RefreshResources()</code> の箇所と見受けられます。「見受けられます」とぼかした書き方をしましたが、すみません、ここから先はちょっと追いきれませんでした。ここからいくつかのメソッドを呼び出す過程があり、長くなりそうなので説明は省きますが、ここで最終的に <code>terraform.ResourceProvider</code> に行き着くことができます。 goroutine を使って並行に <code>terraform.ResourceProvider.Refresh()</code> というメソッドを呼んでいるようです。</p>
<p>追いきれなかったのは、この <code>Refresh()</code> メソッドが何をやっているのかわからなかったためです。以下に <a href="https://github.com/hashicorp/terraform/blob/master/plugin/resource_provider.go">terraform/resource_provider.go at master · hashicorp/terraform</a> から引用します。</p>
<pre><code class="language-go">func (p *ResourceProvider) Refresh(
	info *terraform.InstanceInfo,
	s *terraform.InstanceState) (*terraform.InstanceState, error) {
	var resp ResourceProviderRefreshResponse
	args := &#x26;ResourceProviderRefreshArgs{
		Info:  info,
		State: s,
	}

	err := p.Client.Call("Plugin.Refresh", args, &#x26;resp)
	if err != nil {
		return nil, err
	}
	if resp.Error != nil {
		err = resp.Error
	}

	return resp.State, err
}
</code></pre>
<p><code>p.Client.Call</code> という箇所がありますが、この <code>Client</code> というのは RPC Client です。 Terraform は本体とプロバイダ間の通信に RPC を用いているのですが、私自身 RPC 周りの知識が一切ないため、今回はここでストップと相成りました。ただ、ある程度の推測は可能です。この <code>Refresh()</code> メソッドの戻り値である <code>terraform.InstanceState</code> は <a href="https://github.com/hashicorp/terraform/blob/master/terraform/state.go">terraform/state.go at master · hashicorp/terraform</a> で定義されており、この構造体の中にある <code>Attributes</code> というフィールドが <code>Attributes are basic information about the resource</code> とドキュメントされています。ここから推測するに、 terraformer の import 処理は、 <code>terraform.ResourceProvider.Refresh()</code> により <code>terraform.InstanceState</code> としてクラウドリソースの情報を取得している、と考えてよさそうです。</p>
<p>だいぶ回り道をしてようやく本題に戻りますが、</p>
<blockquote>
<p>Today terraformer use terraform.ResourceProvider interface for get ProviderSchema with Attributes.
In other interface we can get more Attributes from providers(like deprecation options)
Need use schema.Schema from github.com/hashicorp/terraform/helper/schema</p>
</blockquote>
<p>この1行目については、これまでの過程で確認できました。3行目で、これに代わって使うべきとされている <code>schema.Schema</code> を見てみようと思いますが、これについては Terraform の <a href="https://www.terraform.io/docs/extend/schemas/index.html">Developer 向けガイド</a> を見たほうがわかりやすそうでした。</p>
<pre><code class="language-go">// Provider returns a terraform.ResourceProvider.
func Provider() terraform.ResourceProvider {
    // Example Provider requires an API Token.
    // The Email is optional
    return &#x26;schema.Provider{
        Schema: map[string]*schema.Schema{
            "api_token": {
                Type:        schema.TypeString,
                Required:    true,
            },
            "email": {
                Type:        schema.TypeString,
                Optional:    true,
                Default:     "",
            },
        },
    }
}
</code></pre>
<p>このように、 <code>schema.Schema</code> は Terraform の Provider や Resource などの形式を定義する際に用いる構造体で、その要素が Required なのかオプションなのか、また他の要素と競合し得るのか、といった詳細な情報を持たせることができるものです。一方、現状 terraformer が使用している <code>terraform.InstanceState.Attributes</code> は単に Terraform Resource の要素をキーバリュー形式で格納した map に過ぎず、各要素がどのような意味を持つのかまで判断する材料にはなりません。そのため <code>schema.Schema</code> を使う形に変更すれば、私が指摘した Route53 Record で競合してしまっていた要素の検出も実装することができる、という、そういう意図だったようです。</p>
<h2>terraformer の実装を解釈する</h2>
<p>今見てきたように、 terraformer の import は以下のような実装となっています。</p>
<ol>
<li>対象のクラウドサービスの API を呼び出し、 import 対象である resource の ID など、最低限の情報だけをまず読み込む。</li>
<li>取得した ID 等を元に、 Terraform Provider から <code>terraform.ResourceProvider.Refresh()</code> を呼ぶことで、 import に必要なすべての情報を取得する。</li>
</ol>
<p>これは terraforming のアプローチとは大きく異なります。というのも、 terraforming はクラウドサービスの API を呼び、最初から必要なすべての情報を取得して書き出す実装となっているからです。 terraformer があえて処理を2段階に分けたのは、 Terraform resource はクラウドサービス側の仕様変更に伴って内実が頻繁に変わる可能性があるため、 Terraform resource の定義に関する処理を Terraform Provider 側へ任せる意図があったと思われます。 Terraform resource として必要な情報を取得する処理は Terraform Provider に任せてしまうことで、 terraformer は最初の初期化処理と、 tf, tfstate ファイルを書き出す処理に集中することができており、これは疎結合で良い実装だなと感じました。ただ、一方で Terraform Provider をあらかじめダウンロードしておく必要があったり、処理が増えるために少々動作が遅いと感じることがあったり、というデメリットも見られます。</p>
<h2>Conclusion</h2>
<p>今回、サードパーティツールが直接 Terraform や Terraform Provider のコードを呼び出していたため、それをきっかけとして Terraform に対する理解を深める良い機会になりました。ただ知識不足によりすべてが読み解けたわけでもなかったため、特に RPC については勉強してみようかと思っています。ちょうど Terraform 0.12 から gRPC を用いた実装に変更されますが、 gRPC と言えば昨今の microservices を追う上でも欠かせないプロトコルのようですので、その意味でも押さえておきたいところです。</p>
<p>また今回コードリーディングには VSCode を使って頑張って検索したり F12 で定義ジャンプしたりしていたのですが、もっと効率の良いやり方がありそうだなという気もしてます。1日作業になってしまったので、もう少しコードリーディングには慣れていきたいです。</p>
]]></description>
            <link>https://chroju.dev/blog/read_terraform_source_code</link>
            <guid isPermaLink="false">read_terraform_source_code</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 14 May 2019 11:30:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[電子工作初心者が Lily58 Pro を買ってから作って持ち運ぶまで]]></title>
            <description><![CDATA[<p><a href="https://chroju.github.io/blog/2019/04/25/how_i_learned_to_stop_worrying_and_love_the_original_keyboards/">前回の記事</a> を Twitter に載せたところ予想外に RT と fav をちょいちょいいただきまして、もしその流れで「製作編」を楽しみにしていた方がいたらとても申し訳ないなと思っていて、何分前回書いた通り私は電子工作ビギナーもいいところで、今回もだいぶ危なっかしい手順踏みつつもなぜか完成してしまったぐらいの感覚でいるので、これから書くことは参考にはならないかと思います。というか参考にせず別のもっときちんとした方の教えを乞うてください、と予防線を張った上で、初心者が見よう見真似こんな感じでやってみたよ、という体験談として読んでいただければと。</p>
<p>前提を再度書いておきますが、中学校の授業以外でハンダ付けしたことがない超ビギナーが Lily58 Pro という自作キーボードを組み立てたお話です。このエントリーも Lily58 Pro で書きました。</p>
<h2>買ったもの</h2>
<p>お買い物ですが、キーボードキットは遊舎工房さんの実店舗、はんだ付け関連の工具は Amazon とダイソー（？！）を使いました。</p>
<h3>キーボードキット</h3>
<p>Lily58 Pro は必要なものがキットになった状態で売られていますので、それを買います。私はロープロファイルである Choc 用のものを買いましたが、 Cherry MX 軸用のバージョンもあります。基盤は共通で、キーソケットを変更することでどちらにも対応するようなキットになっています（一度キーソケットをはんだ付けしたら変更はできないです）。</p>
<ul>
<li><a href="https://yushakobo.jp/shop/lily58-pro/">Lily58 Pro | 遊舎工房</a></li>
</ul>
<p>他に必要なものはキースイッチ、キーキャップ、左右のキーボードを結ぶ <a href="https://yushakobo.jp/shop/trrs_cable/">TRRSケーブル</a> 、パソコンと接続するための micro USB ケーブルです。いずれも遊舎工房さんに置いていて、店員さんが必要なものをピックアップしてくれたので助かりました。</p>
<p>キースイッチは、現在遊舎工房さんに取り扱いがあるのは赤軸（リニア）、茶軸（タクタイル）、白軸（クリッキー）の3種類で、私が行ったときには赤軸が在庫切れになっており、白軸はオフィスで使うには適さないため茶軸としました。結果的に快適に使えているので、他の軸に替える必要もなさそうです。荷重はいずれも 50g ですが、もっと重いものが欲しい場合には海外通販になりますが、 NovelKeys などで購入できます。</p>
<p>https://novelkeys.xyz/products/novelkeys-x-kailh-low-profile-heavys</p>
<h2>工具</h2>
<p>Amazon で以下のものを購入しました。はんだごては温度調節機能があったほうがよいという話だったので、それを満たす上で高すぎないものとしています。作業マットは正直よくわからなかったものの、難燃性っぽいものを買っています。少しゴムの匂いが強くてしんどかったです。ボンドガン（グルーガン）については後述します。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B006MQD7M4/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/41lybXoY2YL._SL160_.jpg" alt="白光 ダイヤル式温度制御はんだこて FX600" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B006MQD7M4/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">白光 ダイヤル式温度制御はんだこて FX600</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 19.04.27</div></div><div class="amazlet-detail">白光(HAKKO) (2012-01-18)<br />売り上げランキング: 145<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B006MQD7M4/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B0016V7JOC/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/41ay2mKLMQL._SL160_.jpg" alt="goot はんだこて台 ST-11" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B0016V7JOC/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">goot はんだこて台 ST-11</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 19.04.27</div></div><div class="amazlet-detail">太洋電機産業(goot) <br />売り上げランキング: 343<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B0016V7JOC/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B002L6HJ9G/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/319e2DQ2dEL._SL160_.jpg" alt="エンジニア 卓上導電マット A4サイズ 230×330×2mm ZCM-05" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B002L6HJ9G/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">エンジニア 卓上導電マット A4サイズ 230×330×2mm ZCM-05</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 19.04.27</div></div><div class="amazlet-detail">エンジニア(ENGINEER) <br />売り上げランキング: 16,687<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B002L6HJ9G/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B001PR1KPG/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/51zS%2BBizlfL._SL160_.jpg" alt="goot はんだ吸取り線 CP-2015" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B001PR1KPG/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">goot はんだ吸取り線 CP-2015</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 19.04.27</div></div><div class="amazlet-detail">太洋電機産業(goot) <br />売り上げランキング: 2,543<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B001PR1KPG/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B003EILCG6/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/41FvMv7Rs1L._SL160_.jpg" alt="SK11 ボンドガン ピタガン 木材 紙 皮革 プラスチック用 GM-100" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B003EILCG6/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">SK11 ボンドガン ピタガン 木材 紙 皮革 プラスチック用 GM-100</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 19.04.27</div></div><div class="amazlet-detail">SK11(エスケー11) <br />売り上げランキング: 3,044<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B003EILCG6/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>はんだは、これがいいのかどうかわかんないんですけど、ダイソーにもあるという話を聞いて行ってみたら本当にあったので、それを使っちゃいました。練習用にだけ安いのを取りあえず使おうという魂胆だったんですが、練習しているうちに「意外になんとかなりそう？」という気持ちになり、そのまま本番でも使ってしまいました。はんだの良し悪しは自分にはわからないですけど、100均で本当によかったのかなというのは若干不安です。ちなみに 1.0mm 径を使っていますが、細かい部品もあるので 0.8mm 径のほうが使いやすかっただろうなと思ってます。</p>
<p><a href="https://gyazo.com/699cae5af37726f228c13880c8a2f80f"><img src="https://i.gyazo.com/699cae5af37726f228c13880c8a2f80f.png" alt="Image from Gyazo" width="600"/></a></p>
<p>またこれ以外に、ピンセットとプラスドライバーは家にあるもの（何年か前にミニ四駆やったときに買った）を使っています。 Lily58 Pro はリード線を切るような機会はないため、ニッパーは不要です。</p>
<h2>はんだ付け</h2>
<p>ぶっつけ本番はさすがに嫌だったので、はんだ付け練習キットのようなものがあればと思い Amazon で探したのですが、そこまで親切に（例えば説明用冊子が付いているとか）なっているものは見つけられず、コンデンサーや抵抗器がじゃらじゃら突っ込んであるセットがいくつかあったので、その中から適当なものを選びました。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00ODZOMHK/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/511Lqo5RHZL._SL160_.jpg" alt="基板 半田 付け 練習 キット 部品 付 5 セット 組み" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00ODZOMHK/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">基板 半田 付け 練習 キット 部品 付 5 セット 組み</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 19.04.27</div></div><div class="amazlet-detail">nobrand <br />売り上げランキング: 125,367<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00ODZOMHK/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>ネットでいくつか資料を読んで、基板に適当に何度かはんだ付けを試しました。どれぐらいはんだを流し込めばいいのか、多くは 1〜2 mm と書かれているのですが目測でいまいちよくわからないし、感覚を掴むまで少し苦労しました。とりあえず盛り盛りにする必要はないししても意味はないということと、はんだを流し終えて離したあとも1, 2秒程度はこてを当てている必要があり、長く当てすぎてもよろしくないということを学びました。中学の頃にはんだが白くくすんだようになることが多かったんですが、その理由が「熱し過ぎによる酸化」であることを初めて知るなどしました。</p>
<p>参考にした資料は以下のものです。</p>
<ul>
<li><a href="http://handa-craft.hakko.com/support/good-soldering.html">理想のはんだ付け | はんだ付けテクニックを学ぼう！ | [HAKKO]</a></li>
<li><a href="http://mightyohm.com/files/soldercomic/translations/FullSolderComic_JP.pdf">ハンダ付けなんて簡単だ！ ※PDF</a></li>
<li><a href="https://www.youtube.com/watch?v=wo5O6kP6SBU">シャドー半田　動画 - YouTube</a></li>
<li><a href="https://www.youtube.com/watch?v=ZA-ehWjRfYM">はんだ付けの詳細.m2p - YouTube</a></li>
</ul>
<h2>組み立て</h2>
<p>そして組み立てなのですが、なんかですね、はんだ付け練習してたらフロー状態に入ってしまったというか、なんかもうこのままイケるのでは？？？？という謎の自信と早く作りたいという欲求で頭が満たされてしまい、ろくに写真も撮らずにガリガリ進めてしまったので製作工程の様子とかほぼ写真ないんですよね。無事に組み上がったからいいけど、はんだ付け練習したその日によく組み上げたな自分とは思ってます。使っているうちにボロが出るかもしれない。。。</p>
<p>基本的にはビルドガイドがありますので、それに沿ってやるだけではあります。なお、このレポジトリの中に Pro ではない Lily58 のビルドガイドも入ってますので、間違えないように注意が必要です。 Qiita にログを残してくれている方もいたので、そちらの記事も合わせて参考にしました。</p>
<ul>
<li><a href="https://github.com/kata0510/Lily58/blob/master/Pro/Doc/buildguide_jp.md">Lily58/buildguide_jp.md at master · kata0510/Lily58</a></li>
<li><a href="https://qiita.com/ebi_fry306/items/28d3d47ea74e0dc42484">ゼロから始める自作キーボード Lily58Pro編 - Qiita</a></li>
</ul>
<p>つまずいたポイントとしては最初から少しつまずきまして、ダイオードに向きがあるということをはじめは飲み込めませんでした。暗い写真しか残ってなかったので説明しづらいですが、この下の写真の、両端に端子が付いた四角い小さな部品がダイオードなわけですが、小さい上に黒い表面にグレーの線で向きが示されているので、最初はそれを目視できず何分か悩みました。完全に電子工作初心者丸出しです。視力に自信がなければルーペがあってもいいかと思います。</p>
<p><a href="https://gyazo.com/3893851c7e5590eb4c543b26dba076c1"><img src="https://i.gyazo.com/3893851c7e5590eb4c543b26dba076c1.png" alt="Image from Gyazo" width="600"/></a></p>
<p>あとは「ジャンパ」という単語の意味がわからなかったり（はんだで複数の端子を繋げることみたいです）。 OLED 取り付けの手順はオプション故か端折られていたので、以下の記事を参考にさせてもらいました。</p>
<ul>
<li><a href="http://learningoctopus.com/helix_keybord_buildguide1">電子工作初心者がおくる自作キーボード制作ガイド【Helix】　前編</a></li>
</ul>
<h3>Pro Micro の固定</h3>
<p>1つビルドガイドにない手順として、先の Qiita 記事に言及がある、 Pro Micro の micro USB 端子固定作業を追加で行いました。固定は記事をそのまんま参考にしてグルーガンを使いましたが、普通の強力接着剤でも良いような気がしています。不安だからと盛りすぎると、他のパーツに干渉して組み立てが難しくなるので注意です。自分は少しだけやすりで削る羽目になりました。</p>
<p>同じパーツをいくつもはんだ付けしていくので途中集中力も切れかけましたが、休憩を入れながら5〜6時間ほどで組み立てはおわりました。</p>
<h2>ファームウェアの書き込み</h2>
<p>組み上がったらファームウェアを自分で書き込む必要があります。多くの自作キーボードでは <a href="https://github.com/qmk/qmk_firmware">qmk/qmk_firmware: keyboard controller firmware for Atmel AVR and ARM USB families</a> というものを使っているようで、 Lily58 Pro の場合もこれを使います。コマンドとしてはレポジトリを <code>git clone</code> してきて <code>cd</code> し、以下を打つだけです（前提として必要になるライブラリを <code>brew install</code> しておかなくてはならないので、それについては qmk_firmware のマニュアルを参照してください）。</p>
<pre><code class="language-bash">$ make lily58/rev1:default
$ make lily58/rev1:default:avrdude
</code></pre>
<p>最初のコマンドでファームウェアをビルドし、2つ目のコマンドで書き込みます。従って2つ目のコマンドを打つ際にはキーボードを接続してある必要があります。2つ目のコマンドを打つと、以下のように reset 待ちになるので、キーボードのリセットボタンを押せばファームウェアが書き込まれます。左右それぞれで書き込み作業を行う必要があります。</p>
<p><a href="https://gyazo.com/471b930c2bf43614c6f84f609d021b92"><img src="https://i.gyazo.com/471b930c2bf43614c6f84f609d021b92.png" alt="Image from Gyazo" width="600"/></a></p>
<h3>キーマップ</h3>
<p>qmk_firmware の中にキーマップを定義しているファイルがあるので、これを書き換えることでキーマップを変更できます。ファイルは <code>keyboards/lily58/keymaps/default</code> の中にあるので、これをコピーします。</p>
<pre><code class="language-bash">$ cp -R keyboards/lily58/keymaps/{default,chroju}
</code></pre>
<p>中に <code>keymaps.c</code> があるので、これを書き換えれば OK です。ソフトウェアエンジニアであれば、中を覗けば察しはつくと思います。指定できるキーコードは <a href="https://docs.qmk.fm/#/keycodes">Keycodes - QMK Firmware</a> を参考にします。私が大きく変更した点としては、 <code>Delete</code> をフルキーボードのように右上に配置したのと、 Lower のときに 1 を F1 、 2 を F2 という形でわかりやすいように割り当てたあたりでしょうか。記号キーについてはまだ模索しています。</p>
<p>ビルドと書き込みについては、先のコマンドの <code>default</code> をコピー後のディレクトリ名に替えるだけです。</p>
<pre><code class="language-bash">$ make lily58/rev1:chroju
$ make lily58/rev1:chroju:avrdude
</code></pre>
<h3>OLED</h3>
<p><a href="https://gyazo.com/d5ae8514c92841e9bf6c119cae575162"><img src="https://i.gyazo.com/d5ae8514c92841e9bf6c119cae575162.png" alt="Image from Gyazo" width="450"/></a></p>
<p>OLED ですが、デフォルトだと入力したキーがそのまま表示されるようになっており、パスワード入力中など困りそうだったので、少し表示する内容を変更しました。 <a href="http://ubansi.hatenablog.com/entry/2019/03/21/223613">Lily58 Proのディスプレイ表示(OLED)を改造してみる - エンジニアの醤油漬け</a> を大いに参考にさせていただき、1分あたりのタイプ数をタイプスピードとして表示するようにしています。C言語は初めて書いたんですが、 Pro Micro というか Pro Micro が互換性を持つ <a href="https://stackoverflow.com/questions/27651012/arduino-sprintf-float-not-formatting">Arduino が sprintf で float の表示に対応していないこと</a> を知らず、1時間ぐらいハマったりしました。</p>
<pre><code class="language-c">#include &#x3C;stdio.h>
#include "lily58.h"

char typespeed_msg[64];
uint32_t type_count = 0;

void set_typespeed(void){
    type_count++;

    uint32_t uptime_millsec = timer_read32();
    uint32_t minutes = uptime_millsec / 60000;
    if (minutes == 0) {
      minutes = 1;
    }
    float type_speed = (float)type_count / minutes;

    char str_type_speed[12];
    dtostrf(type_speed, 6, 2, str_type_speed);

    snprintf(typespeed_msg, sizeof(typespeed_msg), "Speed: %s keys/m", str_type_speed);
}

const char *read_typespeed(void) {
  return typespeed_msg;
}
</code></pre>
<p>また右側の OLED は <a href="https://qiita.com/guri3/items/844675b637c88515a989">HelixのOLED表示を簡単にカスタマイズするサービスを作った - Qiita</a> を使ってカスタマイズし、黒地に白で表示してカッコよさそうなもの、というところでパッと思い浮かんだロゴを表示してます。 UNDERTALE は2周しただけでそこまで思い入れがあるわけでもないので、いいアイデアが浮かべばまた変更します。こういうカスタムができるので OLED 付きのキーボードにしたのは正解でした。本当は日付とかも表示したいんですけど、 Arduino がクロック持っていないので仕方ないとこですね。。</p>
<p><a href="https://gyazo.com/33cdc50c077aa3a2797c6221ce7a7b51"><img src="https://i.gyazo.com/33cdc50c077aa3a2797c6221ce7a7b51.png" alt="Image from Gyazo" width="450"/></a></p>
<h2>完成</h2>
<p><a href="https://gyazo.com/5258d45614fee3f2a9db76d908b960f9"><img src="https://i.gyazo.com/5258d45614fee3f2a9db76d908b960f9.png" alt="Image from Gyazo" width="600"/></a></p>
<p>ちゃんと動かない可能性は多少覚悟していたんですが、思ったよりあっさりと動いてほっとしました。何日か使って仕事にも使ってみましたが、いまのところ特に問題はないです。というか打ち心地もよくて素晴らしいです。めちゃくちゃ気に入ってます。キー数が減ったのでタイポはまだ多く、慣れが必要だと感じています。</p>
<p><a href="https://gyazo.com/56691d0cc3be6a1a4844b87b8b55fa2c"><img src="https://i.gyazo.com/56691d0cc3be6a1a4844b87b8b55fa2c.png" alt="Image from Gyazo" width="600"/></a></p>
<p><a href="https://gyazo.com/67c3fa0eec3a7cb4d3fe42c0ee618882"><img src="https://i.gyazo.com/67c3fa0eec3a7cb4d3fe42c0ee618882.png" alt="Image from Gyazo" width="600"/></a></p>
<p>Barocco MD600 と比べるとだいぶ薄くなりました。ところで左の親指のところにまさかの Caps Lock がハマっていますが、 2U の無刻印キーキャップを持っていないだけで、実際はスペースキーです。</p>
<p><a href="https://gyazo.com/fc40548d466b0b452e8116a4755c6d31"><img src="https://i.gyazo.com/fc40548d466b0b452e8116a4755c6d31.png" alt="Image from Gyazo" width="600"/></a></p>
<p>持ち運びには<a href="https://www.muji.net/store/cmdty/detail/4549738743835">無印良品のナイロンブック型ポーチ</a>を使っています。コードを収納できるポケットもあり、メッシュポケットに片側を入れられるので、2つのキーボードが擦れあってアクリルが傷つく心配もなく、 Lily58 のために作られたのではないかと思うぐらいピッタリでびっくりしました。</p>
<p>以上、ビルドログでした。なかなか作業は大変でしたが、仕上がったとき、実際動いたときの満足感は最高に気持ちよかったですし、出来上がりにもとても満足しています。もう1個、2個と作りたいかと言うとどうだろうなーという感じではあるんですけど。</p>
]]></description>
            <link>https://chroju.dev/blog/making_lily58_pro_with_a_beginner</link>
            <guid isPermaLink="false">making_lily58_pro_with_a_beginner</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 27 Apr 2019 03:41:43 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Lily58 Pro または私は如何にして市販品を探すのをやめて分割キーボードを自作するようになったか]]></title>
            <description><![CDATA[<h2>2019-05-04 追記</h2>
<p>本文内で「Ergonomic 配列」という言葉を用いていましたが、より正確には「Column Staggered 配列」という言葉が当てはまりそうなので修正しました。上下が揃った「格子配列」の状態から、各キー列が上下に少しズレて指の長さに合うようになっている配列をこう呼ぶようです。</p>
<p>参考: <a href="https://ascii.jp/elem/000/001/609/1609599/index-5.html">ASCII.jp：人はなぜキーボードを自作するのか？　“キーボー道”への誘い (5/6)｜KTUの自作キーボー道</a></p>
<h2>tl;dr</h2>
<ul>
<li>分割キーボードは市販品の選択肢がない</li>
<li>従って自作キーボードに手を出す気はなかったが手を出すことになった</li>
<li>Lily58 Pro がかわいい</li>
</ul>
<h2>Introduction</h2>
<p>昨今、キーボードの自作が流行っているのは知ってはいるものの、手を出す気は先日までさらさらなかったんですね。というのも自分は手先が器用ではないというのが大きいところで。最後にはんだごてを使ったのは中学生の「技術」の授業ですが、四苦八苦して作った懐中電灯がうんともすんとも言わなくてだいぶしょんぼりした記憶があります。なのでやりたくはないしやれるとも思わなかったし、練習すればできるとしても、今の自分がそこに労力かけるのはちょっと違うかなみたいな気持ちがありました。</p>
<p>と言っているところからの即落ち2コマみたいでアレなんですが、先週末に <a href="https://yushakobo.jp/shop/lily58-pro/">Lily58 Pro</a> を購入、構築して使い始めました。めちゃくちゃかわいいですね？？</p>
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-permalink="https://www.instagram.com/p/BwmRdowgVD2/" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BwmRdowgVD2/" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div> <div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div></a> <p style=" margin:8px 0 0 0; padding:0 4px;"> <a href="https://www.instagram.com/p/BwmRdowgVD2/" style=" color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;" target="_blank">17年ぶりぐらいの半田付けだけど無事に Lily58 Pro 組み上がったんだがめちゃくちゃ可愛くないこれ？？？</a></p> <p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">@<a href="https://www.instagram.com/chroju/" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px;" target="_blank"> chroju</a>がシェアした投稿 - <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2019-04-23T12:26:54+00:00">2019年 4月月23日午前5時26分PDT</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script>
<p>どうしてこうなったのかという話を書きます。</p>
<h2>分割キーボード Lover のジレンマ</h2>
<p>私はここ数年、メインのキーボードは Barocco MD600 を使っていました。数年前、 ErgoDox が話題になった少し後ぐらいに、 HHKB サイズで分割可能なキーボードということで話題をさらった機種です。</p>
<p><a data-flickr-embed="true"  href="https://www.flickr.com/gp/chroju/hY667o" title="Baroccoとどいた"><img src="https://c1.staticflickr.com/1/579/31813875193_36398a3d15.jpg" width="500" height="500" alt="Baroccoとどいた"></a><script async src="//embedr.flickr.com/assets/client-code.js" charset="utf-8"></script></p>
<p>使い始めてまだ2年ほどで全然現役ですし、使い心地にもかなり満足していたのですが、最近になって「キーボードを持ち運びたい」というニーズが（自分の中で）出てきました。 MD600 は HHKB サイズということでギリギリ持ち運べなくもないのですが、積極的に持ち運びたいかというとそんなこともなく、可能であればもう少し小さいものがほしいというのが正直なところでした。</p>
<p>というわけで持ち運び用キーボードを探し始めたのですが、 MD600 にすっかり身体が慣れてしまったために、条件として「分割」が必須になります。「分割しない」という手はもう選べません。使ってみるとわかるんですが、分割キーボードの使い心地に慣れると、たとえ HHKB だろうと RealForce だろうと色あせてきます。大事なのはキータッチじゃなくて身体全体の姿勢だったんだなという悟りを開くわけです。なので私は「分割キーボード」というのは素晴らしいガジェットだと評価していますが、他人に勧めることはしません。戻れなくなります。</p>
<p>そしてここで壁にあたるのですが、市販品の分割キーボードは残念ながら選択肢が多くはないのが実情です。小さくて分割、というところだと、現在まず候補に上がるのは Barocco シリーズの新機種 MD650L かと思います。ロープロファイルに変更することで MD600 と比べてさらに薄くなった品で、というか「持ち運べる」「市販品の」分割キーボードはほぼこれ一択じゃないでしょうか。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B07FK74QY5/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/11NGjsnBsJL._SL160_.jpg" alt="Mistel BAROCCO MD650L 分離式 メカニカルキーボード 英語配列 Cherry ML Switch ML1A 採用 アイボリー/グレー MD650L-LUSMGAB1" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B07FK74QY5/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Mistel BAROCCO MD650L 分離式 メカニカルキーボード 英語配列 Cherry ML Switch ML1A 採用 アイボリー/グレー MD650L-LUSMGAB1</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 19.04.25</div></div><div class="amazlet-detail">MiSTEL (2018-02-27)<br />売り上げランキング: 4,353<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B07FK74QY5/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>ネックだったのはキースイッチに Cherry ML を使っているという点で、どうもこれが調べた限りだとわりと評判悪いみたいです。とはいえ「自分には合う」という可能性もあるので、触って確認できればよかったんですが、ツクモなど秋葉原で数店舗を巡ってみても実機を置いているところはなく、評判が微妙っぽい機種を触らずに買うという勇気も出なくて泣く泣く諦めました。</p>
<p>これ以外にも <a href="https://www.amazon.co.jp/dp/B00CPYH6FQ">Kinesis Freestyle</a> など、分割キーボードの選択肢自体は無くはないものの、持ち運び可能なサイズという条件を満たすものは見つけられませんでした。かろうじて <a href="https://ultimatehackingkeyboard.com/">Ultimate Hacking Keyboard</a> がありますが、サイズ感は MD600 とあんまり変わらないように見受けられます。そもそもにして、 MD600 の発売から2年以上を経てもなお、分割キーボードを製造、販売しているメーカーは多くありません。ウェブで IT エンジニアの動向に触れていると、分割キーボードが今の主流であるかのように感覚が麻痺ってきますが、どう考えてもそんなことはなくて、あくまでカルト的な人気なわけですね。他には「HHKBを2台横に並べる」といった剛の者が選ぶ道もありますが、さすがにちょっとそれは遠慮しておきました。</p>
<h2>自作という選択</h2>
<p>まぁ、というわけで「ないから作るか」という結論に至ります。おそらく、昨今自作キーボードに手を出している方の中には同じ動機の方が少なくないんじゃないでしょうか。というのも、国内で販売されている自作キーボードキットには、分割タイプが結構多いです。例えばもっともポピュラーであろう Helix や、 Ergodox のような配列の iris があります。</p>
<ul>
<li><a href="https://yushakobo.jp/shop/helix-keyboard-kit/">Helix キーボードキット | 遊舎工房</a></li>
<li><a href="https://keeb.io/products/iris-keyboard-split-ergonomic-keyboard?variant=8034004860958">Iris Keyboard - PCBs for Split Ergonomic Keyboard – Keebio</a></li>
</ul>
<p>昨年末話題になった freee さん社内の自作キーボード事情に関する記事でも、人気トップ2がこの2種でした。</p>
<iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fdevelopers.freee.co.jp%2Fentry%2Fkeyboards-2018" style="border: 0; width: 100%; height: 190px;" allowfullscreen scrolling="no" allow="autoplay; encrypted-media"></iframe>
<p>市販品の選択肢が非常に限られていたのに対して、自作界隈では分割キーボードがよりどりみどりです。はじめのうちは気になる機種をいくつか試しに眺めているだけでしたが、魅力的なものが非常に多く、なんとか頑張れば自作でイケるんじゃないかという思いが強くなりました。ただ、一方で先の freee さんのエントリーにおいても上手く作れない方の話が載っていたりして、不安があったのも事実です。 DIY だと市販のキーボードより安くなりそうに思えるところですが、実際のところ自作キーボードキットは1万円以上のオーダーで売られているので、別に金銭面でのメリットがあるわけではありません。1万数千円のキットを買って、はんだ付けに失敗して使えなくなったらまぁショックですよね。</p>
<h2>Lily58 Pro</h2>
<p>冒頭に書いたとおり、最終的に Lily58 Pro を選びましたが、私の条件は以下でした。</p>
<ul>
<li>Low Profile</li>
<li>キー数は60前後</li>
<li>可能であれば ~~Ergonomic 配列~~ Column Staggered 配列</li>
<li>OLED あり</li>
</ul>
<p>持ち運びを前提に考えているため、より薄型を実現できるロープロファイルがまず必須条件です。その点、当然キー数も抑えればそれだけ小型になりますが、数字キーすら排除したいわゆる 40% キーボードは使いこなせる自信がなかったので選択肢から外しました。分割じゃないですけど、 VORTEX CORE とかちいさかわいくて好きなんですけどね。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B075FWF9RW/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/412H6dZvqUL._SL160_.jpg" alt="VORTEX CORE メカニカルミニキーボード 英語US配列 47キー Cherry MX 赤軸 VTG47REDBEG" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B075FWF9RW/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">VORTEX CORE メカニカルミニキーボード 英語US配列 47キー Cherry MX 赤軸 VTG47REDBEG</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 19.04.25</div></div><div class="amazlet-detail">ヴォーテックス (Vortex) (2017-09-07)<br />売り上げランキング: 12,716<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B075FWF9RW/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>~~Ergonomic 配列~~ Column Staggered 配列と書いていますが、より正確に言えば親指にキーが多く配置されているものです。 Helix のような完全な格子配列ではなく、 Ergodox 系の親指用のキーが少し飛び出て配置されている感じ。 OLED というのは Helix にも付いている、マイコンボード（ProMicro）の上に付けた 32 x 128 の小さなディスプレイで、キーボードの情報やなにか画像を表示したりして遊ぶことができます。まぁこれは完全に好みです。せっかくなら遊べるほうがいいなと。</p>
<p>それら条件すべてに合致したのが Lily58 Pro でした。先の iris などもとてもよかったんですが、 Lily58 はちょうど遊舎工房さんに在庫があるということだったので、実店舗できちんと確かめながらパーツを買えそうだったというのもあり、それにしました。キースイッチがはめ込み式で、後から別のスイッチへ変更することもできるようになっているのも魅力でした。私が遊舎工房に行ったときはちょうど目当てだった Kalih Low Profile Choc の赤軸が在庫切れだったんですが、「取りあえず他の軸を買って、あとから赤に替えることもできますよ！」と店員さんに教えてもらいました。完全に沼という感じがします。ちなみに茶軸にしました。</p>
<p><a href="https://gyazo.com/c38ce1ac5a855d063c9a3d81af3c10b8"><img src="https://i.gyazo.com/c38ce1ac5a855d063c9a3d81af3c10b8.jpg" alt="Image from Gyazo" width="400"/></a></p>
<p>その後事前の心配もどこへやら、5時間ほどで無事に組み上げることができたのですが、そのあたりの「製作編」についてはまた別エントリーで書こうかなと思います。</p>
]]></description>
            <link>https://chroju.dev/blog/how_i_learned_to_stop_worrying_and_love_the_original_keyboards</link>
            <guid isPermaLink="false">how_i_learned_to_stop_worrying_and_love_the_original_keyboards</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Thu, 25 Apr 2019 09:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[HashiCorp ファン必須科目である mitchellh/cli を履修する]]></title>
            <description><![CDATA[<h2>mitchellh/cli について</h2>
<p>Go にはコマンドラインツールを書くのに役立つフレームワークが数多くありますが、今回はググってもあんまり日本語情報が出ず、また godoc に example も少なくて掴みどころが難しい、 <a href="https://github.com/mitchellh/cli">mitchell/cli</a> に触れてみます。正直、有名どころの <a href="https://github.com/urfave/cli">urfave/cli</a> や <a href="https://github.com/alecthomas/kingpin">alecthomas/kingpin</a> に比べて使い勝手が良いとは言いづらいフレームワークだと感じていますが、 mitchellh氏のレポジトリにあることからもわかる通り、 Terraform 等の HashiCorp OSS 群で使われているフレームワークということで、あえて学んでみました。</p>
<p>なお、ただ実装を読むだけではつまらないですし、せっかくなら使ってみたかったので、現在拙作の <a href="https://github.com/chroju/nature-remo-cli">nature-remo-cli</a> 内でも活用しています。実例として良ければご参照ください。</p>
<h2>基本</h2>
<p>まずはとにかく README.md にある example コードを見てみます。</p>
<pre><code class="language-go">package main

import (
	"log"
	"os"

	"github.com/mitchellh/cli"
)

func main() {
	c := cli.NewCLI("app", "1.0.0")
	c.Args = os.Args[1:]
	c.Commands = map[string]cli.CommandFactory{
		"foo": fooCommandFactory,
		"bar": barCommandFactory,
	}

	exitStatus, err := c.Run()
	if err != nil {
		log.Println(err)
	}

	os.Exit(exitStatus)
}
</code></pre>
<p><code>mitchellh/cli</code> は基本的にサブコマンドのあるコマンドを実装するためのツールです。 <code>c.Commands</code> にセットしている <code>map[string]cli.CommandFactory</code> がサブコマンドの定義箇所で、キーになっている文字列をサブコマンドとして実行されたとき、その値の <code>CommandFactory</code> が実行される、という形を取ります。ではこの <code>cli.CommandFactory</code> は何者かと言うと、以下のように <code>cli.Command</code> と <code>error</code> を返す関数として定義されています。</p>
<pre><code class="language-go">type CommandFactory func() (Command, error)
</code></pre>
<p>従って上記の example のような変数で <code>CommandFactory</code> を返す形ではなく、ここで無名関数を定義してしまう形も可能です。具体的なところだと Terraform の実装 (https://github.com/hashicorp/terraform/blob/master/commands.go#L80-L85) などを見るとイメージが掴みやすいと思います。私はこちらの書き方のほうが明示的で好みです。この Terraform の実装では <code>error</code> にあたる返り値として決め打ちで <code>nil</code> を返していますが、私も同様に実装しています。あんまりここで <code>nil</code> 以外の値を返すパターンが思いつきません。</p>
<h2>cli.Command の実装</h2>
<p>次に、先の <code>CommandFactory</code> が返していた <code>cli.Command</code> の実装を見てみます。 <code>cli.Command</code> は <code>help</code>, <code>Run</code>, <code>Synopsis</code> の3つのメソッドを必要とする interface です。</p>
<pre><code class="language-go">type Command interface {
	Help() string
	Run(args []string) int
	Synopsis() string
}
</code></pre>
<p><code>Synopsis()</code> は、サブコマンド無しでコマンド実行したときに出力される、そのサブコマンドの使い方を記した50字程度の注釈を返すよう設定します。 例として nature-remo-cli を使ってみると、こんな感じで表示されます。</p>
<pre><code>Available commands are:
    aircon    Control Air Conditionar
    init      Initialize remo with your OAuth token
    signal    Control Signals
    sync      Sync local config with your latest one
</code></pre>
<p><code>Help()</code> はそのままの意味で、 <code>-h</code> や <code>--help</code> を付けて実行した場合に返す内容を設定します。よくある Usage の自動生成のような機能はありませんので、愚直にヒアドキュメントなどで書いていく必要があります。</p>
<p><code>Run()</code> で実行したい処理を書いていきます。1つ注意したいのが、返り値として渡せるのが <code>int</code> 型、つまりはリターンコードのみであり、 <code>error</code> インターフェースや、エラーメッセージを含めた <code>string</code> などは返せないという点です。従ってエラーの処理やエラーメッセージの出力は、 <code>Run()</code> の中ですべて済ませる必要があります。</p>
<h3>cli.Command 内での出力処理</h3>
<p>ではエラーメッセージをどのように出力するかですが、 <code>cli.Command</code> の中に <code>cli.Ui</code> を埋め込んで活用するのが一般的です。</p>
<pre><code class="language-go">type HogeCommand struct {
	UI cli.Ui
}

func (c *HogeCommand) Run(args []string) int {
	c.UI.Output("Normal Message")
	c.UI.Error("Error Message")

	return 0
}
</code></pre>
<p><code>c.UI.Output()</code> は標準出力に、 <code>c.UI.Error()</code> は標準エラー出力にいい感じに吐いてくれます。他にも対話式にユーザーの入力を待ってくれる <code>Ask()</code> や、さらにはユーザー入力を隠してくれるので秘密情報を入力させるのに便利な <code>AskSecret()</code> といった便利なメソッドも <code>cli.Ui</code> に用意されています。</p>
<p>さて、 <code>fmt.Println()</code> などを使わず <code>cli.Ui</code> をわざわざ使うと何が嬉しいのかと言えば、お察しのとおりかと思いますが一つにはテストが書きやすくなる面があります。 <code>cli.MockUi</code> という、標準出力先と標準エラー出力先にあたる buffer を有した構造体があるので、テストのときにはこれを使うことで出力のチェックができます。この点については Vault での実装 (https://github.com/hashicorp/vault/blob/df18871704fe869e9be45b542a6b1eb2fe46c293/command/audit_disable_test.go) などが参考になるかと思います。他にも <code>cli.Ui</code> を満たす構造体がいくつか用意されていて、ほしい機能があれば追加できるようになっており、例えば <code>cli.ColoredUi</code> は出力の色指定ができるので非常に便利です。ANSI エスケープシーケンスの8色を指定するための定数も<a href="https://godoc.org/github.com/mitchellh/cli#pkg-variables">用意されています</a> ので、簡単にターミナルへ色付きの出力をすることができます。</p>
<h2>極めてシンプルな CLI ツール</h2>
<p>ざっくりここまでの説明で主要な使い方は網羅しました。説明を省いたものとして AutoComplete の支援機能などがありますが、せいぜいがそんなもので、非常に薄い実装のフレームワークになっています。他のコマンドラインフレームワークによくある機能はほとんどなく、オプションの処理すら担ってくれません（<code>-h</code> や <code>--version</code> はデフォルトで対応していますが、それだけです。nature-remo-cli では spf13/pflag を合わせて使う形にしました）。さすがにちょっと不親切というか、あくまで HashiCorp で使うための最低限の機能だけを実装したものなのかな、という感触があります。</p>
<p>ただ一方では、サブコマンドごとに <code>cli.Command</code> を満たす構造体を別々に実装する、つまりはコードがサブコマンド単位で強制的に分かれる形になるので、コードの可読性は高い状態を保てるように感じています。 <a href="https://github.com/hashicorp/terraform/tree/master/command">Terraform のコマンド実装</a> など、一度でも Terraform を使ったことがある人が見れば、すぐに知りたい実装がどこにあるのか見通せるようなファイル構成になっています。したがって冒頭にも書いた通り、 HashiCorp のツールをよく使う人であれば、知っておいて損はないのではないかなと思っています。</p>
]]></description>
            <link>https://chroju.dev/blog/mitchellh_cli</link>
            <guid isPermaLink="false">mitchellh_cli</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 27 Mar 2019 14:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Terraform で疲れないために]]></title>
            <description><![CDATA[<p><strong>追記（2019-02-27） : 一部表現等見直しました。論旨は変わっていないです。</strong></p>
<p><a href="https://speakerdeck.com/shogomuranushi/infrastructure-as-code-is-very-tired">Infrastructure-as-Code-is-very-tired - Speaker Deck</a></p>
<p>こちらの記事を読みました。スライド内で触れられている <a href="https://qiita.com/shogomuranushi/items/e2f3ff3cfdcacdd17f99">Terraform Best Practices in 2017 - Qiita</a> については私も読んだことがあり、以下の記事で言及させてもらっていたり。悩みますよね、 Terraform 運用。</p>
<ul>
<li><a href="https://chroju.github.io/blog/2017/12/27/how_to_use_terraform_modules/">Terraform moduleは何が嬉しいのか · the world as code</a></li>
</ul>
<p>私もある程度ポリシーめいたものをもって、これはコード化するべき、これは手で作ってもいい、みたいな線を引いてはいるものの、あまりそれを言語化してみたことがなかったので、いい機会だしまとめてみます。疲れないようにするべき、コード化がすべてではない、という視点は先のスライドと共有できると思っています。なお、私の場合はほぼ AWS にしか Terraform を使っていません。</p>
<h2>柔軟性、再利用性を過度に求めない</h2>
<p>端的に言うとこれがすべてで、私の場合は module をそんなに使ってはいないです。スライド内では DynamoDB のコードを書こうとしたときに、どう再利用しようかと考えて module 実装に向かうところが描かれていましたが、基本的には必要性がない限り module 化はせず、再利用のこともあまり考えないというのが個人的なスタンス。</p>
<p>というのも、 module の維持管理がやっぱり辛いから。そもそものところでAWS リソースの設定項目は常に変化していきますので、一度 module を作っても、それが新しい設定項目に対応していないので更新が必要、なんてことはザラにあります。例えば最近だと IAM ユーザーやロールにタグが付けられるようになる、という変更が2018年11月に入っていますが、 Terraform はすでにこれに対応済みです。</p>
<ul>
<li><a href="https://aws.amazon.com/jp/blogs/security/add-tags-to-manage-your-aws-iam-users-and-roles/">Add Tags to Manage Your AWS IAM Users and Roles | AWS Security Blog</a></li>
<li><a href="https://www.terraform.io/docs/providers/aws/r/iam_user.html">AWS: aws_iam_user - Terraform by HashiCorp</a></li>
</ul>
<p>となると、 IAM ユーザー用の module を作っていた場合、このタグに関する新たな設定箇所に対応するべきかどうかを判断して、必要に応じて module の更新を行うことになります。このようなことが、年間に何回かは発生します。</p>
<p>またこのような AWS 側の更新以外でも、 module を再利用していくなかで、やっぱりこういう使い方をしたい、変数をなにか付け足したい、という内部的な要因で更新を迫られるケースは往々にしてあります。最初から将来的な利用ケースをすべて見越して、完璧に再利用可能な module を作ることは難しいです。おそらくスライド中ではそれをやられようとされていたのかなと見受けます。 Terraform resource に設定可能なすべての変数を module から設定できるようにし、設定しない場合は default 値を埋め込むようなコードを見かけたので。個人的には、そこまでいってしまうとやっぱり管理コストが大きくなりすぎるように思える。</p>
<p>あと、同様の理由で Terraform module registry も使っていません。これは先に上げた『Terraform module は何が嬉しいのか』という過去記事の中でも言及していますが、 module registry にあるのは多くが「設定可能なすべての変数を設定できるようにした module」のようで、使う上でコストが高いというか面倒だなと思ってしまうためです。また Terraform resource 自体の更新に追随するのは、イコールで AWS のアップデートに追随することなので受け入れていますが、 module の更新についていくコストはちょっと余計に感じるので割きたくない、という感じ。</p>
<h2>module は抽象化のために使う</h2>
<p>では module をまったく使っていないのかと言うとそんなことはないです。使っているのは基本的に抽象化のためです。</p>
<p>先のスライドでも言及がある、複数サービスを繋いで使うような場合がそれに当たります。 ELB と EC2 と RDS と、それらで使うセキュリティグループをワンセットで立ち上げることがよくある、みたいな。そういうときは、そのワンセットをポンと立ち上げられる module を作り、いくつか可変な値を変数で設定できるようにしてあげるととても楽です。</p>
<p>また、例えば先の RDS と EC2 とセキュリティグループをセットで作る、という場合、その時点で EC2 の IP から RDS の 3306 への通信をセキュリティグループで開ける必要がある、みたいな自明な設定が出てきます。こういうものも抽象化が可能なので、 module 内で自動的に処理しています。 Route53 で正引きと逆引きを両方設定するのは面倒なので、IP とホスト名を渡すと両方自動的に作ってくれる module を作ったりとかしています。</p>
<p>なんでも module にするというのは旨味がやっぱり少ないので、人間がやらなくてはならない具体的作業を抽象化できそうな場合に限り module 化をします。ただ、あくまで何回かその操作を行う可能性がある場合です。マネコンや CLI をいじっていて、この操作って何度もやってるし面倒だな、と感じたときに module 作成のトリガーが引かれるイメージです。</p>
<h2>何のために Infrastructure as Code するのか</h2>
<p>Infrastructure as Code を進める目的は、抽象化以外だと、自分の場合は以下の2点が大きいです。</p>
<ul>
<li>設定作業、設定変更作業のトレーサビリティ確保</li>
<li>設定の標準化による運用コストの抑制</li>
</ul>
<p>前者は AutoScaling の台数設定とか頻繁に変えると思いますが、コードで commit 履歴残しておくと、いつ何のためにこの設定にしたのか、という妥当性を後追いできるので精神衛生に良いです。正直現状の設定値がどうなっているか、というのは畢竟現物を見てしまえばわかるわけで、設定のバックアップの意味というよりは、「なぜ」その設定にしたのかという根拠が残っていることの効果を強く感じています。ちなみに単に設定変更履歴を追いたいだけであれば AWS Config でも十分だったりするわけで、 Git を使う意味というのは commit message だとか Pull Request を通したやり取りのような、人間の思想が残る点にあると思っています。スライドの p.64 では「何回も作らない」 CDN などの設定はコード化しないとありましたが、自分の場合は「なぜ」を残す意味があると判断したら、設定変更が頻繁ではないだろうものでもコード化します。このように、ツールの使い所は目的に応じて変化するものであり、万人に適用可能な最適解は無いと考えています。</p>
<p>2点目の「設定の標準化」に関しては、社内に複数存在する AWS アカウントで、それぞれ CloudTrail の設定が異なっていたりしたら困るので、一律に揃えたいときにコード化してそれを全部に対して当てていく、というような使い方をします。設定差異が存在する、というのは平常時であればそんなに気にしませんが、いざ問題が起きたときはやはり「なぜ」というのが問われる部分になりますので、必要性がなければ設定を標準化しておくことは運用コストの低減に繋がります。その設定がレポジトリを通じて、メンバー間に可視化されているというのも意味が大きいです。</p>
<h2>Conclusion</h2>
<p>つらつらと書きましたが、スライドの内容には基本的に同意で、何のために IaC したいのか、という ROI の観点は常に考慮が必要だと感じています。 Ansible でサーバーの設定作業をコード化して、その後の設定変更も全部 Playbook の変更で頑張っていたけど、徐々に無理になってきたので設定変更手順を Wiki に書いて Playbook は破棄した、その方が「管理コスト」という面では低くなった、なんて経験もあります。手作業は残ってても構わないと思います。ただし、代替として手順を書くとか、設定をエクスポートするなりして残す、ということは必要に応じてやらなくてはならないですが。</p>
<p>Terraform というツールは大好きなので、自分の目的にどう合わせていけるか、今後も試行錯誤を重ねていきます。</p>
]]></description>
            <link>https://chroju.dev/blog/make_terraform_less_tiring</link>
            <guid isPermaLink="false">make_terraform_less_tiring</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 25 Feb 2019 13:32:12 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Usage の書き方について標準仕様を探る]]></title>
            <description><![CDATA[<p>仕事柄オペレーション作業で使う小さなコマンドラインツールを作ることはよくありますが、地味に悩むのが <code>-h</code> オプションを使ったときに表示される「Usage」の書き方だったりします。こういうやつ。</p>
<pre><code class="language-sh">usage: git [--version] [--help] [-c name=value]
           [--exec-path[=&#x3C;path>]] [--html-path] [--man-path] [--info-path]
           [-p|--paginate|--no-pager] [--no-replace-objects] [--bare]
           [--git-dir=&#x3C;path>] [--work-tree=&#x3C;path>] [--namespace=&#x3C;name>]
           &#x3C;command> [&#x3C;args>]
</code></pre>
<p>この括弧の種類と使い方がよくわかっていなくて、どこかで定められた標準があるんであればそれを使いたいなと思い色々調べてみたメモです。</p>
<h2>en.wikipedia</h2>
<p>いきなり Wikipedia かよというところではありますが、英語版 Wikipedia に <a href="https://en.wikipedia.org/wiki/Usage_message">Usage message</a> という項目があって、複数の問題点があるとか指摘が入っていますが参考にはなる内容で、ここに書き方が載っています。以下引用。</p>
<pre><code class="language-sh">Usage: program [-aDde] [-f | -g] [-n number] [-b b_arg | -c c_arg] req1 req2 [opt1 [opt2]]
</code></pre>
<p><code>-aDde</code> が引数を取らないオプションで <code>-n</code> は取るオプション、 <code>-f</code> と <code>-g</code> は排他、 <code>-b</code>と <code>-c</code> は引数を取ってかつ排他、括弧が付いていない <code>req1</code> と <code>req2</code> は必須オプションで、 <code>opt2</code> は <code>opt1</code> と一緒に使う必要がある、ということのようです。わかりやすい。ちなみに NetBSD のコーディングスタイルを元にしているとのこと。個人的にはよく見かける書式な気がしますし、これでFAではとも思います。いきなり結論に至りました。</p>
<p>このページ他にも面白いことはいろいろ書いてあって、個人的に気になったのが、この Wikipedia のページで面白かったのが一番下にある「Anti-patterns」というものです。「要出典」扱いになっているので、いずれ消えるかもしれないですが引用してみます。</p>
<blockquote>
<p>A properly written command line program will print a succinct error message that describes the exact error made by the caller rather than printing the usage statement and requiring the user to figure out what the mistake was.</p>
</blockquote>
<p>要はエラーメッセージ代わりに「Usage」を出すべきではないという話で、 Usage は <code>-h</code> などで明示的に呼ばれたときに限り、 stdout に流せと言っています。これ結構悩むところで、最近のコマンドツールで間違った使い方をしたときに Usage を出してくれるものって実際よくありますし（git もそうですね）、それはそれで親切な気もするんですよね。で、その場合の Usage はあくまでエラーメッセージの一環として表示していて、ユーザーが意図した結果ではないわけで、パイプやリダイレクトに流れてしまっても困るので、自分としては stderr に出すべきかなという思いがあります。 en.wikipedia に書かれた主張もよくわかるんですが、実際どうするべきなんでしょうね。ここもどこかに推奨が書かれてるなら読んでみたい。</p>
<h2>POSIX</h2>
<p>他にも探してみますと、 Open Group のページに POSIX.1-2017 での定義が書かれています。</p>
<p><a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#tag_12_01">Utility Conventions</a></p>
<p>ほぼ先程の NetBSD のコーディングスタイルと同一です。なのでやっぱりこれでよさそう。</p>
<h2>docopt</h2>
<p>一方で少し毛色の違う定義を書いているのが docopt です。</p>
<p><a href="http://docopt.org/">docopt—language for description of command-line interfaces</a></p>
<p>引数処理を1つずつ実装しなくとも、一定の定義に則った Usage の文章を書くと、それに基づいて引数処理を勝手にやってくれるという便利なライブラリです。いくつかの言語で実装がありますが、 Python で比較的よく見かける気が。</p>
<p>では docopt の Usage 書式を見てみましょうとなるわけですが、これが "docopt is based on conventions that have been used for decades in help messages and man pages for describing a program's interface." と書かれてはいるものの、若干見慣れない定義のように感じます。</p>
<pre><code class="language-sh">Usage:
  naval_fate ship new &#x3C;name>...
  naval_fate ship &#x3C;name> move &#x3C;x> &#x3C;y> [--speed=&#x3C;kn>]
  naval_fate ship shoot &#x3C;x> &#x3C;y>
  naval_fate mine (set|remove) &#x3C;x> &#x3C;y> [--moored|--drifting]
  naval_fate -h | --help
  naval_fate --version
</code></pre>
<p>先の NetBSD や POSIX の定義と異なるのは <code>&#x3C;></code> や <code>()</code> が使われているあたりで、前者は使う位置が決まっている引数、後者は必須引数を表すそうです。必須の引数は1行目の <code>new</code> のような括弧の使わないものがそうではないかという気もしますが、上記の4つ目の例のように排他かつ必須の場合など、少しパターンの異なる場合に、必須であることを明示したい意図で使うとかですが若干飲み込みづらくよくわかりませんでした。</p>
<p>位置引数を表す <code>&#x3C;></code> については見覚えがあります。上記の例だと1番最初のもの、 <code>ship &#x3C;name> new</code> じゃなくて <code>ship new &#x3C;name></code> で位置が固定なのだと、要は <code>ship new</code> サブコマンドの引数として <code>name</code> を渡すってわけですよね。昨今このようにサブコマンドを繋げて使うタイプのコマンドが増えてきたので、それへの対応として生み出された書式と捉えられます。Terraform なんかがそうですけど、例えば以下の Usage で <code>&#x3C;></code> が使われていて、この場合はサブコマンドを先に置いて、オプションなどがある場合はサブコマンドの後に使えという意味になるわけです。</p>
<pre><code class="language-sh">Usage: terraform state &#x3C;subcommand> [options] [args]
</code></pre>
<p>サブコマンドは「1つのことを上手くやる」という、『UNIXという考え方』に記載のあるUNIX哲学と反していないかと言う意見もありますし、従来 UNIX/Linux にビルトインで実装されてきたコマンドでは想定されていなかった範囲に思います。そこを補完する、現代的な多機能コマンドツールを実装する際に、 docopt の定義は有用かもしれません。</p>
<p>参考: <a href="http://www.songmu.jp/riji/entry/2017-08-27-subcommand.html">サブコマンドはUNIX哲学と相反していないのか | おそらくはそれさえも平凡な日々</a></p>
<p>基本的には NetBSD や POSIX の定義に則り、サブコマンドが存在するようなリッチなコマンドを実装する場合には docopt を参考にしてみるとバランスが取れそうです。</p>
]]></description>
            <link>https://chroju.dev/blog/how_to_write_usage</link>
            <guid isPermaLink="false">how_to_write_usage</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 19 Feb 2019 12:52:03 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『入門 監視』を『ウェブオペレーション』『SRE』と一緒に読もう]]></title>
            <description><![CDATA[<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873118646/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/41Jlj3e0CDL._SL160_.jpg" alt="入門 監視 ―モダンなモニタリングのためのデザインパターン" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873118646/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">入門 監視 ―モダンなモニタリングのためのデザインパターン</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 19.01.31</div></div><div class="amazlet-detail">Mike Julian <br />オライリージャパン <br />売り上げランキング: 463<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873118646/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>監視という、この業界に携わっていれば誰でも関係したことがあるだろう分野について、まとまった本がこれまでなかったというのは感じていて、一度「監視概論」みたいなエントリーをまとめてみたいと考えていたこともあったのですが、オライリーに先を越されました（何様）。タイトルのインパクトがすごいです。</p>
<p>ただ、「監視オンリー」でまとまった本は確かに思い浮かばないものの、この分野に言及した本が一切なかったというわけではなくて、これまでですと自分は『ウェブオペレーション』と『SRE サイトリライアビリティエンジニアリング』を監視設計の上では参考にしていました。改めて本書と並行して今回この2冊もさらってみたのですが、合わせ技のように使うととてもいいのではないかなぁと思っています。</p>
<h2>入門 監視</h2>
<p>文字通り「監視」という行為自体にフォーカスしきった本という印象を受けました。1章でまずアンチパターンを挙げて、それを踏まえて2章でデザインパターンを解説する。3章では監視した結果をどう扱うのかに関わる、アラート、オンコール、インシデント管理のプロセスに触れて、4章は付随する分野である「統計」の話、5章以降が実際の監視対象別のプラクティスをまとめた各論、という感じです。まずは3章までが大前提なのでとても重要で、5章以降は実際に自分が監視するシステムの構成などに併せて参照すればいい気がしました。ネットワーク機器を監視する上での SNMP への恨みつらみが書かれた9章など、自分としてはめちゃくちゃ頷きながら読みましたが、クラウドファーストな昨今、ネットワーク機器とは無縁な人も多いでしょう。4章の「統計」もとても重要ですが、少し付随的な内容かな、という印象です。</p>
<p>とても名言が多い本で、世の中でなんとなく採用されてきたセオリーっぽいプラクティスを、きちんと理由を裏付けた上でバッサリ切ったりしてくれます。Linux 動かしてるとなんとなく CPU とメモリの使用率と各種 IO で閾値を設けがちですが、必ずしも必要ではないと言ってくれています。これすごいわかる。</p>
<blockquote>
<p>動かすサービスによっては、元々リソースをたくさん使うものもありますが、それで問題ないのです。 MySQL が継続的に CPU 全部を使っていたとしても、レスポンスタイムが許容範囲に収まっていれば何も問題はありません。これこそが、CPUやメモリ使用率のような低レベルなメトリクスではなく、「動いているか」を基準にアラートを送ることが有益である理由です。</p>
</blockquote>
<p>低レベルの監視が情報をもたらしてくれることももちろんありますが、無計画に閾値を仕掛けると、往々にして狼少年にしかならないです。この本では一貫してユーザーに近い側、ビジネス的に必要なサービスレベルを維持できているかという視点で監視をするべきだと訴えています。</p>
<p>他にも監視の設定は100％自動化するべきだとか、Ops以外も含めてチーム全員監視を扱えるスキルを持つべきだとか、昨今有効とされている話を明確に書いてくれています。それだけに我が身を振り返って胸が痛くなる部分も多いです。小説を読んでいて「心がつらい」ことを理由に一度本を閉じる、ということが稀によくあるのですが、技術書でそうなったのは初めてでした。</p>
<h2>ウェブオペレーションとSRE</h2>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873114934/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/51-ThZ6FRfL._SL160_.jpg" alt="ウェブオペレーション ―サイト運用管理の実践テクニック (THEORY/IN/PRACTICE)" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873114934/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">ウェブオペレーション ―サイト運用管理の実践テクニック (THEORY/IN/PRACTICE)</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 19.01.31</div></div><div class="amazlet-detail"><br />オライリージャパン <br />売り上げランキング: 140,197<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873114934/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117917/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/51Ybz%2B6kIsL._SL160_.jpg" alt="SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117917/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 19.01.31</div></div><div class="amazlet-detail"><br />オライリージャパン <br />売り上げランキング: 23,351<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117917/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>一方の『ウェブオペレーション』ですが、『入門 監視』より7年前の本であるものの、重なる記載も少なくありません。例えば「自動的に新しいノードやメトリクスを発見する」べきであるとされていたり。</p>
<p>こちらは表題通り「オペレーション」の本なので、あくまでシステム運用をする中で必要となる一要素としての監視、として書かれている面が強いです。『入門 監視』の3章をもっと精緻にしたイメージでしょうか。例えば各コンポーネントの監視を検討する前に、技術的コンポーネントの依存関係を把握する必要があると言及されていたりします。一例としてDNSサーバーが落ちたら、いくらシステム自体は正常でもユーザーはアクセスできないよね、とか。また『入門 監視』と同様、ビジネス的なインパクトの面、つまりサービスが実際使えているかどうかという観点で監視をするべきだとしていますが、その観点についてはより詳細に分類して示しています。</p>
<blockquote>
<p>確認には5つのレベルがある。可用性（存在しているか）・機能性（動いているか）・品質（うまく動いているか）・状況（あらゆる要件を満たしているか）・信頼性（信頼できるか）だ。</p>
</blockquote>
<p>SRE本にも似たことが言えて、こちらは監視自体の言及は第10章ぐらいしかないものの、オンコール対応、SLA、ポストモーテムという、監視を取り巻くプロセスの扱い方については非常に手厚いです。SLAをきちんと設定して、その前提から考えよう、というのは、先の2冊と共通する「ユーザー視点での監視」に繋がる話で、やっぱりどれも同様の思想で書かれている本だな、と感じます。</p>
<p>ウェブオペレーションを生業としている身からすると、システム監視はやはり、あくまでシステム運用の一要素です。ですので監視だけを独立して考えることはあまりなく、全体的な運用プロセスの中に如何にして位置づけるかということをよく考えます。如何に小さなコストで間違いなく的確な監視を行うか、という。そういう観点ではやはり、SRE本や『ウェブオペレーション』に掲載されているようなマクロな観点が不可欠で、一方で『入門 監視』は、実際何をどのように監視すればいいのかという、ミクロな観点で指針を示してくれるように感じました。</p>
]]></description>
            <link>https://chroju.dev/blog/practical_monitoring</link>
            <guid isPermaLink="false">practical_monitoring</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Thu, 31 Jan 2019 13:31:19 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[NTT技術史料館に行ってきた]]></title>
            <description><![CDATA[<p><a href="https://gyazo.com/11167a2e4afcb61c05ff3102f20dfc67"><img src="https://i.gyazo.com/11167a2e4afcb61c05ff3102f20dfc67.png" alt="Image from Gyazo" width="600"/></a></p>
<p>東京都武蔵野市にあるNTT技術史料館に行ってきました。</p>
<p>自分が最初に触ったコンピュータは多分 Power Macintosh G3 MT か初期の VAIO あたりで、それ以前の電子計算機というのは書籍の中で触れてはいるけれど見たことはないという感じで。もっと言えば基本情報技術者試験ですら自分にとっては「歴史」の勉強に近かったりして、例えばトークンリングとか習いますけど、実際に実装されてるのは見たことが多分なかったりします。そういうのが仕事に対して何か致命的な影響があるかと言うと特にないとは思うんですが、自分が寄って立つ技術の歴史にもう少し触れておきたいし、実物見たほうが実感が湧いて理解もしやすいだろうみたいなことはずっと考えていて、まぁそういう動機で行きました。</p>
<p>正直、ここの展示がコンピュータの歴史かと言うと怪しくて、というのもNTTの技術史料ですので電子計算というより情報通信技術が基本です。グラハム・ベルに始まり、インターネットまで。なので若干（自分の勝手な）期待とズレちゃった感はありますが、知らないことも多くてとても楽しめました（マウンテンビューの Computer History Museum にあたるものが国内にないかなーと思うんですが。今まで行った中だと電通大のUECコミュニケーションミュージアムが一番近いかも）。</p>
<p><a href="https://gyazo.com/ac0a20262ea8cbd67cd8fe70073260d9"><img src="https://i.gyazo.com/ac0a20262ea8cbd67cd8fe70073260d9.png" alt="Image from Gyazo" width="600"/></a></p>
<p>圧巻だったのがクロスバ交換機。如何にも「こういうの好きだろ、おらっ」って感じの外観。電話回線交換を自動化するために作られた初期の機械ですが、今考えれば「たかがそれだけのこと」に身長を超える大きさの機械がいくつも並列に並べて使われていた、というのを身をもって知ることができるのはいい体験でしたし、高度経済成長を思わせる巨大で武骨な機械ってのはやっぱそそります。そもそも交換機発展の歴史すらよく知らないし。当時はソフトウェアという概念が無く、各回線の接続ロジックがすべてこのハードウェア上で表現されていたので、電話サービスの設計に何か変更が入るとハードウェアレベルで改修しなくてはならなかったというのも隔世の感があります。</p>
<p><a href="https://gyazo.com/82c7400660988d1aedd2dce4721d714f"><img src="https://i.gyazo.com/82c7400660988d1aedd2dce4721d714f.png" alt="Image from Gyazo" width="600"/></a></p>
<p><a href="https://gyazo.com/0282d8f9aa1d36ffba83132f5ee0652a"><img src="https://i.gyazo.com/0282d8f9aa1d36ffba83132f5ee0652a.png" alt="Image from Gyazo" width="600"/></a></p>
<p><a href="https://gyazo.com/0cffe26d63393ef21512b00fbf3dd2ce"><img src="https://i.gyazo.com/0cffe26d63393ef21512b00fbf3dd2ce.png" alt="Image from Gyazo" width="600"/></a></p>
<p>その後電話交換はコンピュータ制御になりますが、そのあたりの分厚いフローチャートやプログラムコード、パンチカードなどが見られるのもまた素晴らしい。</p>
<p><a href="https://gyazo.com/25d065bc8cdd5ee47cc1af65ce378c57"><img src="https://i.gyazo.com/25d065bc8cdd5ee47cc1af65ce378c57.png" alt="Image from Gyazo" width="600"/></a></p>
<p>ヒヤリ・ハット事例集。</p>
<p><a href="https://gyazo.com/32b730159e21185ee0e8de23d7624ec3"><img src="https://i.gyazo.com/32b730159e21185ee0e8de23d7624ec3.png" alt="Image from Gyazo" width="600"/></a></p>
<p>これは海底ケーブルの中継機。めっちゃでかくて重厚で、深海の水圧というものを想像する。</p>
<p><a href="https://gyazo.com/89d64879a929bb4f8c3f0bcdda1d6a4a"><img src="https://i.gyazo.com/89d64879a929bb4f8c3f0bcdda1d6a4a.png" alt="Image from Gyazo" width="600"/></a></p>
<p>個人的に面白かったのが、建築をテーマにした一角があったこと。通信に鉄塔が必要なのは自明ですけど、通信機と配線を収容するNTTビルについても、NTT内部の建築部門が長年尽力して保守運用に効率的な形を追求してきたというのは想像が至っていませんでした。現在では建築部門を内部に抱えているわけではなく、会社ごと独立してNTTファシリティーズと化しているみたいですが。</p>
<p><a href="https://gyazo.com/895ee987ebbc6d4bb44004ebec5deda7"><img src="https://i.gyazo.com/895ee987ebbc6d4bb44004ebec5deda7.png" alt="Image from Gyazo" width="600"/></a></p>
<p>展示されているミニチュアの局舎を見て、「あーあー、あるわ、こういうNTTビル。この形には技術的な裏付けがあったのか」と納得したりする。このあたりの知識を付けると、街を見る目も変わりそうで面白い。</p>
<p><a href="https://gyazo.com/9904c28f3f66baa22f4d6e57e629f947"><img src="https://i.gyazo.com/9904c28f3f66baa22f4d6e57e629f947.png" alt="Image from Gyazo" width="600"/></a></p>
<p>館内に展示されている機器は、実際に使われたあとでお役御免になったものを保存しているのが多いので、当時のメモ書きのようなものが残されているのも時代を感じて最高です。</p>
<p><a href="https://gyazo.com/336feb11315fe8e1a8b40c6509e3ceaf"><img src="https://i.gyazo.com/336feb11315fe8e1a8b40c6509e3ceaf.png" alt="Image from Gyazo" width="600"/></a></p>
<p><a href="https://gyazo.com/6aedbb30c753aac7424473e34cce1bae"><img src="https://i.gyazo.com/6aedbb30c753aac7424473e34cce1bae.png" alt="Image from Gyazo" width="600"/></a></p>
<p><a href="https://gyazo.com/883a316be2e7734a3d27c056b82059f7"><img src="https://i.gyazo.com/883a316be2e7734a3d27c056b82059f7.png" alt="Image from Gyazo" width="600"/></a></p>
<p>2時間前後滞在しましたが、知らないことも多くて解説をちゃんと読んでいたら全然時間足りませんでした。一般公開は木金の13～17時半のみというだいぶ厳しい制限があるんですが、行くならこの時間をフルに使うつもりのほうがいいかもしれません。</p>
<p><a href="https://gyazo.com/66911cccdb4aea411c437753f491d5f1"><img src="https://i.gyazo.com/66911cccdb4aea411c437753f491d5f1.png" alt="Image from Gyazo" width="600"/></a></p>
<p>ちなみにあんまり人いないです。人感センサーの照明がバシバシ落ちる。</p>
]]></description>
            <link>https://chroju.dev/blog/ntt_history_center_of_technologies</link>
            <guid isPermaLink="false">ntt_history_center_of_technologies</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 28 Jan 2019 14:41:48 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[次世代 Web カンファレンスに行ってきた]]></title>
            <description><![CDATA[<p>https://blog.jxck.io/entries/2018-09-15/next-web-conf-2019.html</p>
<p>Web の今とこれからについて、スライドによる発表ではなくて、複数の登壇者による議論をするという体裁のイベントです。本当にその場でリアルタイムに喋ってる、筋書きどこまで作ってるかはセッションにもよる気がしますが資料というものは存在しません。録画は公開されるみたいです。カンファレンスの中でパネルディスカッションが数セッション用意されることは珍しくないですが、朝から夜まで全部議論という場は初めてでとても刺激的でした。どんな話が出てくるかわからないし、登壇されてるのは一線で活躍されている方々なので、多くの情報も様々な思いもお持ちでいろんな話がどんどん飛び出してくる。ハッシュタグはセッション別に用意されているので、 Twitter でも並行して様々な話が進んでだいぶインプット過多な感じで最後のほうはちょっとぽわっとしてました。</p>
<p>SRE、Security、Microservices、HTTPS、HTTP/3の5セッション聴きましたが、特に日常業務に近い SRE と HTTPS で実入りが大きかったように感じます。</p>
<p>SRE は SRE book を軸として、各社実際にどういった形で運営、運用しているのかという話が聴けたのがよかった。 Error Budget は今回参加された方々の社ではいずれも適用してないとか、プロアクティブな運用（いわゆる改善とか運用のための基盤づくりとか）とリアクティブな運用（≒Toil）をいかに 50:50 で維持するかの話とか。SRE は個々の技芸によるものではなくて、組織運用の話であり、マイクロサービス化に従って個々のサービスオーナーチームにセルフサービスなオペレーションをどんどん渡せるようにしていくべき、みたいな話にはとても同意しましたし、だからこそ SRE をよく言われる「ソフトウェアエンジニアリングを導入したインフラエンジニア」としてだけ捉えてしまうと立ち行かなくなるんだよな、みたいなことは思いました。どちらかと言えばシステムの基盤や、 Toil の発生を如何にマネージするかが肝になるので、単に実装技術があるだけじゃダメで、もっとマクロな視点で動けないとあかんのですよね。自分はこれが弱い。</p>
<p>HTTPS の話は言うまでもなく昨今 Symatenc やら Google やらの界隈がとても元気で、私も去年は実務上多くの影響を受けたりもしたのですが、とても動きが激しい過渡期にあるので未来を見渡すのが面白いし、それがまた必須にもなってくるよね、という感想です。ただ証明書の話にせよ、 Signed HTTP Exchange の話にせよ、常に Google の影がチラついていて、基本的にはコンテンツホルダーである企業がウェブの実装やら仕様やらの話にまで極めて大きい力を持っている現状はどうなんだろうな、ということは強く思います。悪い方向になっている、と言い切るわけではないし改善がもちろん進んではいるんだけど、それを駆動しているのが Google って形は正しいのかなとか。あとこのセッションで出た話だと、 TLS 1.4 以降はどうなるという話の中で、<a href="https://t.co/Qx0c8L3zhi">Post-quantum cryptography</a> 、要は量子コンピュータ実用化後における暗号の危殆化の話に言及があったのが「めっちゃ次世代やん」って感じで知的好奇心をくすぐられました。</p>
<p>今回のイベントでは15セッションが設けられていて、一応 Web の末端で働いている自分にとっても埒外なフロントエンドの話とかそういうのもあって、一口に Web と言っても切り口は無数にあるし、学ぶことまだまだ多いなと感じた1日でした。SRE 方面に自分も向かうことになる気がするので、そちらの技術力高めるのと、あんまり仕様とか読んでないので HTTP/3 や TLS 1.3 について少し掘ってみよう、などと思っています。</p>
<p>以下、当日のメモを特に編集せず貼りますカオスです。</p>
<h3>10:00 SRE</h3>
<pre><code>ソフトウェアエンジニア的なことしてる比率
    プロアクティブ : リアクティブ = 50:50 が目標（Mercari）
        タスクのラベルで管理
        Site Reliability Engineering 記載の「Toil 50%」
        https://twitter.com/tagomoris/status/1084256565446627328
        直ちに割合調整するというより、クォーター末の時点で振り返り、次期クォーターのコントロールに活かす
    タスク量（Toil）の可視化
        本来やりたいこと（ロードマップ）が進んでいるか否か
            ベロシティが落ちたら割り込みとみなす
オンコール、インシデント対応、ポストモーテム
    週次でオンコールの振り返り、大きいインシデントについてはポストモーテム（Cookpad）
    平日毎日振り返り、ポストモーテムは全エンジニア書く、SLO侵害以外でも重大なバグなども（はてな）
    モノリス時代と Microservices 時代で異なる（Mercari）
        モノリスは SRE が受ける、インシデントレポートをコール受けた人が書く、slack でインシデント共有
    長期的な問題管理は「リアクティブ」？
        長らく解決されてない問題はロードマップに組み込む = プロアクティブ扱い（はてな）
Error Budget
    Microservices ではサービスごとに SLI, SLO マストにしている（Mercari）
        現状だとエンジニアが決めててよくない（本来はCTOとかプロダクトオーナーが持たないと妥当性が持てない）
        モノによっては 99% とかでもいいと思っていて、それを決められる議論の場がなければいけない
            SLO 向上とタスク数のトレードオフの意識、特にビジネス側への理解を進めるが大事
    Error Budget ははてな、Mercariともに使ってない
    アラートの設定は？
        開発者がしている、Datadog + slack or  PagerDuty（Mercari）
            Microservices はオンコールも開発者宛
        Zabbix → Prometheus （Cookpad）
オペレーションのセルフサービス化
    マージまで開発者ができる、DBのスキーマ変更まで含めて （Cookpad）
    AWSを勧めてセルフ化させたりしていた、それだけじゃないので一方で開発も（はてな）
    Microservices 化が進むと中央集権的なデプロイチームはボトルネックになるので、開発からデプロイ、運用全部各チームに渡してる（Mercari）
        GCP（マネージド） + Terraform を使ってインフラが作れる、 kubectl も渡してる
        SRE （プラットフォームチーム）はデプロイのための基盤を提供する役割
セルフサービス化が進むと SRE は集中的なものではなくなる？
    開発者にできること増えて「溶け込んで」いく
    99.9% 以上は開発者だけだと厳しい、専門としての SRE は要るかなと言う感覚（Mercari）
運用→SRE ≒ 技芸（ウェブオペレーション）→科学（計測可能）
生存戦略
    システムを理解したソフトウェアエンジニア、科学的なアプローチにトライできる人（Cookpad）
    ソフトウェア書けるのは当たり前として、マネージドサービスとの勝負（仕事が奪われる）中でどれだけ創造性が発揮できるか（はてな）
    SRE、SLOというのは技芸ではなく組織の話として広がるといい（mercari）
</code></pre>
<h3>11:10 Security</h3>
<pre><code>最近のセキュリティインシデント事例
    CDN のおもらしの話（Mercari, LINE）
        CDNでキャッシュをしない設定にしていたけど0秒間キャッシュがされていて、同時にリクエストすると他人のレスポンスが表示される
    Wordpress
    EC-CUBE
        簡単につかえてしまうが故に、「ちゃんと使ってなくて」という事例が多い
        Wordpress はプラグインを「完全に信頼」しているのでそこに脆弱性が入り込む
パッケージバージョン管理
    バージョン固定すれば変なのが入り込まない、固定しちゃうとアプデがめんどい
CVE 全部読む（バグの傾向が掴めたりとかある）
ブラウザの脆弱性
    ブラウザ側が気にするべき問題なのにアプリで気にするのは嫌
    「脆弱性のあるブラウザを使ってるやつが悪い」
cookie は未来永劫カチッとしない
    サードパーティ Cookie の問題
    Double Submit Cookie
X-FRAME-OPTIONS によるクリックジャッキング対策( https://www.jpcert.or.jp/tips/2010/wr103601.html )
    脆弱性対策でこういうヘッダが増えてきた
    意味がわからなくて付けてると外されたり
        DNS の TXT レコードも似た感じで便利に使われてる
    こういうヘッダ、対策全部入りみたいなのほしい
CSP
    コンテンツセキュリティポリシー (CSP) | MDN( https://developer.mozilla.org/ja/docs/Web/HTTP/CSP )
    開発、実装時に面倒、不便
    CSP レポートに拡張機能のものなどノイズが出る問題
GDPR
    Opera には勝手に同意する機能があるらしい
    Machine Readable にして、ブラウザに許可／不許可を設定しとくと勝手にやってくれたりしたらいい
        Coinhive の件も header でマイニング許可／不許可宣言してみたいなすれば解決するんでは
        JavaScript の実行に同意を求める世界も（あの判決によっては）来るんでは
        「一般ユーザーに認知されてる」ってどの範囲の話？
AdTech
    広告関連のカンファレンスでセキュリティとプライバシーの話があんまりない
    例
        ターゲティング広告が JSONP で配信されていて個人の情報が無関係なサイトに配信されてる
    プライバシーについては被害の金銭的な計量がしづらい
    どうすれば意識高められる？
        被害の定量性がないので放置されがち
QUIC とか新しいプロトコル、あるいは独自のプロトコルになるとキャプチャしづらく検証もしづらくなっている
    難読化する自由 vs エンドユーザーが検証、確認できる自由
</code></pre>
<h3>13:30 Microservices</h3>
<pre><code>分散トレーシング
    全部トレースしてるとレコード1回の write が単純倍になったりする
    リクエスト時に統一のIDを付けて、各サービスのログにID吐いておくことで必要時は grep
        各サービスでのログの粒度がまちまちになる問題
Chaos Engineering
    「お客さんにバレなければいい」
        Netflix がやっているのはクリティカルじゃない部分だったり
        ビッグプレイヤーがやっているからって猿真似すればいいわけではない（前提条件が違ったり）
Service Mesh
    Kubernetes とかで入れるの面倒じゃなくなっていくなら入れるの当たり前になったらいいんでは
gRPC
言語選択
    使いたいプロトコルへのライブラリの対応
    対抗側の言語が読めない場合の問題
    レガシーな言語やマイナーな言語をやっていると人が採れない問題
人数が増えると Microservices 化するのが自然では？
    1つの大きなチーム、となるとマネージが大変、分かれざるを得ない
        ピザ2枚ルール
</code></pre>
<h3>14:40 HTTPS</h3>
<pre><code>PKI, CA 周り
    Symantec の話
        当時シェア3割あったらしい、が、それでも distrust できてしまうという前例になった
        CA Browser Forum に違反した証明書を発行してしまっていた
        それに対してなかなか対応できていなかった
        Chrome による BAN
    日本の GPKI
        適切な証明書運用ができていなかったことの Mozilla からの指摘
    Certificate Transparency によって衆人環視ができるようになってしまったために、魔女狩り的に CA が受難していないか
    CA の責務が重すぎる？選択肢が減ってしまう？
        (chroju) ブラウザ側の実装（ていうか chrome ）がインターネット全体を振り回している感はある
        ルート認証局は増えてるが、DV でいいなら EV の必要性ってなくなるのか？みたいな話とか、需要は減ってる？
            増えてはいるが、増え方が歪、ブラウザベンダー（ Google ）がルートCAに参入している、という掟破り
    TLS の認証と信頼は別
        HTTPS for Everywhere の浸透によって
        証明書は FQDN を「認証」しているだけ
        EV が信頼されなくなってきた
            EV証明書を使用して既知の企業になりすませる可能性が指摘される | スラド セキュリティ( https://security.srad.jp/story/17/12/15/2110233/ )
            Identity Verified という証明書、イギリス？ iOS で悪用するケース？
            Stripe と同じ名前の証明書を別の州で取られる事例があった
TLS 周り
    TLS 1.3 正式化
        後方互換性配慮が大きいために、そこまでドラスティックじゃないように思える
    Qualys SSL Labs - SSL Pulse( https://www.ssllabs.com/ssl-pulse/ )
    SSL Pulse Trends( https://kjur.github.io/www/sslpulsetrend/index.html )
    TLS 1.0, 1.1 の廃止は大変
        ブラウザはいいとして、 wget やらライブラリやらが結構ハマる
    TLS 1.2 は残って TLS 1.3 が 4,5 に上がっていける
        変なミドルボックスにも1個1個対応するようなアップデートの実績が採れたので、今後はそれを続ければいい
        なので取りあえず1.2, 1.3 に上げてもらう
    1.4 以降
        Post Quantum の暗号危殆化への対応が必要になるはず
            RSA 、素因数分解に依存しているやつがマズい
            SHA とかは bit 数上げれば大丈夫なはず
HTTPS
    HTTPS を守るための機能があまりうまくいってないんではないか（ Strict HTTPS, Public Key Pinning, HSTS ）
    セキュリティによろしくなくなった場合の Alternative が必要では
    土管のセキュリティに特化しすぎた、土管が崩れるとすべての通信が崩れる
        HTTPS 対応したフィッシングサイト
    Signed Exchange
        WebPackaging の Signed HTTP Exchanges | blog.jxck.io( https://blog.jxck.io/entries/2018-12-01/signed-http-exchanges.html )
        amp で Google の URL 出すんじゃなくてコンテンツに署名されてればオリジンの URL 出せる
            土管ではなく土管の中の信頼性の担保
            URL で信頼性を保つことの限界
            コンテンツの信頼性が担保されるのであれば、それが amp, CDN で来たのかオリジンからなのかは意識する必要がなくなる
        自分でデプロイするのは難しく、 CDN が全部やってくれるとかになるんじゃないか
</code></pre>
<h3>16:10 HTTP/3</h3>
<pre><code>Transport Protocol TCP → QUIC
HTTP なのに TCP じゃないんだ？？？
    アッパーの部分、セマンティクスは変わらず下のほうが変わっているって点では 1.1 → 2 と変わらんのでは
HTTP over QUIC じゃないんだ？？？
    Google と IETF それぞれに QUIC の実装があって区別ができない（後者は QUIC2 と呼ぶことにはしたが）
    HTTP のバージョンを上げないと HTTP over QUIC と HTTP2 をログ上識別できない
TCP の限界 → UDP
    平文なので外部からの攻撃に弱い
    レイテンシー上のボトルネックになりつつあった
TCP → QUIC (UDP) になって実際に通信が可能か
    ミドルボックスの対応の問題
        TCP の特定のパケットを見ているやつがいたりするので暗号化したりして見られないようにしたり
    NAT のタイムアウト値
    UDP 443 通るのか
コネクションID
    コネクションの確立にはコネクションIDが使われる
    ロードバランシングでもコネクションIDを見て振り分けを行う
HTTP/3 の恩恵
    回線品質が高い日本でも恩恵はある？
        モバイルについてはパケロスが多く、輻輳制御が効いてくる可能性
QUIC が向かない例
    データセンター内の通信
        アプリケーションレイヤーのプロトコルなので、End-to-End が近すぎると kernel - アプリケーション間の通信ボトルネックの割合が大きくなってしまう
        パケロスも少ないので恩恵が薄い
標準化にもっとみんな関わってみよう
</code></pre>
]]></description>
            <link>https://chroju.dev/blog/next_web_conf_2019</link>
            <guid isPermaLink="false">next_web_conf_2019</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 13 Jan 2019 09:37:41 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[2018年総括]]></title>
            <description><![CDATA[<p>総括エントリーは2015年から書いていて、毎年「なんもしてないんじゃね」という悲観的な感情に支配されてしまう。が、実際1年間かけて何もやってないというわけもないので、<a href="https://chroju.github.io/blog/2015/12/31/looking-back-2015/">2015年</a>のときみたいな定量評価のほうがいいんだろうなとそっちで今回はやってみる。</p>
<h2>技術</h2>
<ul>
<li>Kubernetes
<ul>
<li><a href="https://chroju.github.io/blog/2018/08/19/entry_kubernetes/">GKE を使った k8s 環境の構築</a></li>
<li>kubeadm を使った k8s 環境の構築</li>
</ul>
</li>
<li>Golang
<ul>
<li><a href="https://chroju.github.io/blog/2018/07/10/contributed_to_terraform_provider_aws/">terraform-provider-aws への commit</a></li>
<li><a href="https://chroju.github.io/blog/2018/11/03/nature_remo_cli/">nature-remo-cli の作成</a></li>
<li><a href="https://chroju.github.io/blog/2018/05/05/release_tfdoc/">tfdoc の作成</a></li>
</ul>
</li>
<li>環境
<ul>
<li><a href="https://chroju.github.io/blog/2018/07/01/update_dotfiles_with_ansible/">VSCode への移行</a></li>
</ul>
</li>
</ul>
<h2>書籍</h2>
<ul>
<li>Real World HTTP</li>
<li>みんなのGo言語</li>
<li>エンジニアリング組織論への招待</li>
<li>Effective DevOps</li>
<li>プログラミング言語Go</li>
<li>エンジニアの知的生産術</li>
<li>オブジェクト指向設計実践ガイド</li>
<li>Site Reliability Engineering</li>
</ul>
<h2>活動</h2>
<ul>
<li><a href="https://chroju.github.io/blog/2018/11/18/write_code_every_day_with_competitive_programming/">Write Code Every Day の開始</a></li>
<li><a href="https://chroju.github.io/blog/2018/12/05/cncf_serverless_wg/">Advent Calendar への初参加</a></li>
<li><a href="https://chroju.github.io/blog/2018/04/28/lt_continuous_update_ansible_role/">Ansible Night での LT</a></li>
</ul>
<p>技術的にやったのがプライベートで触ったものがほとんどで、仕事であんまり新しいことに挑戦できなくなってしまったことに危機感を覚えている。プライベートでも別に新しいことって感じでもないけど。昨年も停滞って言っててなんか、まぁ、ヤバいかなという感じはありますね。うーん。</p>
<p>ただ、新しいことやればいいかって言うとまぁ別にそういうわけでもなくて、昨今『プロフェッショナルSSL/TLS』が話題になったり、技術書典でDNS入門本が売れていたり、基礎技術をきちんと学び直すみたいなのも一方では重要なのだろうなと。今年は競技プログラミングを始めたりもしたし、どちらかと言うとそちらの意識のほうが強いかもしれない。基礎的な技術知識をきちんと固めることと、最新の動向を追っていくこと、その両輪を上手く回していくことが難しい。</p>
<p>方向性としては k8s と Go に手を出している通り、 SRE チックな方向に向かいたい、というより向かわないといけなさそうだなーという思いが強まってはいるものの、明確にそれだけが自分の技術的に取り得る選択肢、という気もしていなくて、というか何か技術的に進みたい方向性が定まっているわけではなくて、今やれることを取りあえずやろうとしている、というのが自分の勉強パターンなので、技術的にどっちへ行きたい、みたいなのは相変わらず迷子という感じがあります。</p>
<p>まぁでも、競技プログラミングを始めてみてアルゴリズムやデータ構造に対する学びを得つつあるのはとても役に立っているし、一応は OSS を2つほど書けたのは悪い話ではないかなとは思う。去年は「自分で手を動かす、何かを書くということができなかった」という振り返りをしていたので、その点に関して言えば「書く」ことに比較的注力できた年になった。</p>
<h2>来年について</h2>
<p>来年はまず始めたいことが2つほどあって、3月ぐらいまではそのあたりの準備で忙しくなりそうだし、4月からはそれらが始まっていく、はずである。時期が来たらブログにもまとめます。</p>
<p>技術的なところで来年どうしようかなというのは、それ以外のところではまだあんまり固められていないんだけど、むちゃくちゃ抽象的なところで「プレゼンスを上げたい」というのを考えている。先にも書いた通り方向性を定めずに今やりたい、今やるべきと思われる技術分野を遅延評価学習法な感じでつまんできた人生ではあったけど、30代になってくると自分の「売り」というものをもっと意識してアピールしていかないとお給料上げにくいんじゃないかなという気がしてきていて、自分が何をやりたくって何の領域で食っていくか決めて、その領域でのプレゼンスを上げる、みたいなことをしていきたいなと。今年作った OSS 的なやつ、あんまり宣伝もしてないし Star もほぼ付いていないけど、そういうのももっとちゃんと広報するとか。 LT 、結局今年も1回しかやってなくて、あれはネタがあるときに、たまたまそのネタを披露できそうなイベントを見つけたから行く、じゃなくて、自分が何かしら喋れそうなイベントを見つけたら取りあえず参加にしてしまって、ネタは後から考える、という締切駆動型で参加しないと無理ですね、と思う。</p>
<p>あとはインプットとアウトプットのサイクルを早めたい。今年、サマータイムの話が話題になったときに、 Linux の tzdata とかそういうのちゃんと調べ直してまとめようとか思ったんだけど、まだそのタスクは Todoist に眠ったままなんですよ。まぁそうじゃなくて、やろうと思ったら2週間ぐらいのうちにはやってブログにまとめるとかね。時期を逃さずちゃんと上げればアクセスも狙えるしね。そういうの。いろいろ学んではいるけれど、キャッチアップ遅いよなあ、早い人めっちゃ早いよなあというのが気にかかりつつあるので、なんとかしたいです。なんで遅いのかというと他のこといろいろやってて時間取ってないからとか時間の使い方が悪いとかかなという気がするので、まずは時間の使い方見直したい。『エンジニアの知的生産術』が勉強の方法論とかでもすごくいいこと書いていたので取り入れるのを進めていきたいです。</p>
]]></description>
            <link>https://chroju.dev/blog/looking_back_2018</link>
            <guid isPermaLink="false">looking_back_2018</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 30 Dec 2018 23:57:32 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Subscriptions 2018]]></title>
            <description><![CDATA[<p>2018年末現在契約しているサブスクリプションの一覧。昨年やっている方を見かけて、自分も知らないうちに積み重なっている気がしたのでやってみる。括弧内は日本円での価格です。</p>
<h2>仕事周り</h2>
<h3>Todoist (3,500 / year)</h3>
<p>タスク管理はもう2年ぐらい Todoist にまかせている。もともと GTD に沿ったタスク管理をしていて、その点で一番やりやすかったのが Todoist だった、という理由。ほかだと Todledoo や Trello などいろいろ使ってみたことがあるけれど、前者はタスク1個に対して設定できることが多すぎて嫌になって、後者はスマホで見ると全体を見られないのがつらくてやめた。シンプルなのが一番いいみたい。</p>
<h3>GitHub (700 / month)</h3>
<p>こんぴゅーたえんじにゃーなので。プライベートレポジトリを作る以外の用途で使っていない気がするので、やめてもいいのかもしれない。</p>
<h3>esa.io (500 / month)</h3>
<p>残念ながらちょうど今月解約した。 markdown を突っ込んでおく場所として便利だし、 UI が可愛くて好きだったので使っていたけれど、メモ置き場としては Scrapbox が優秀過ぎたのでそっちに移ってしまった。ブログの下書きみたいな一時的な markdown 置き場としてはひとり slack が使えるし、 markdown にパーマリンク生やして共有したい場合には Dropbox paper があるので、 esa.io は要らなくなってしまった。</p>
<p>とてもいいサービスだと思うし、おそらくは個人よりチーム利用で効果を発揮するのだと思う。 WIP の機能とか、 Wiki とブログの区分けとかコンセプトが好きだった。</p>
<h2>生活周り</h2>
<h3>Day One (2,800 / year)</h3>
<p>中学生ぐらいからわりとマメに日記を書いていて、書く媒体は時期によって違うのだけど、今年の半ばぐらいから Day One を使い始めた。写真をコピペで簡単に貼り付けられたり、カレンダービューで任意の日付を簡単に選択できたり、日記アプリとしての使い勝手がダントツによかったので。x年前の同じ日の日記をピックアップしてくれる機能があって面白かったので、過去に Evernote で付けていた日記も全部インポートした。先日 Qiita に<a href="https://qiita.com/chroju/items/a00c46ec3fcc83c2b0b3">Evernote がエクスポートする xml ファイルをプレーンテキストに変換する - Qiita</a> というエントリーを書いたのは、このときの副産物。手書きの日記も写真撮って入れようかなと思ってるけど、面倒すぎてやってない。</p>
<p>別料金を払えば製本して送ってくれるサービスもやっているとのことなので、今年の分を〆たらやってみる予定。海外発送も受け付けているみたいだけど、日本語圏でこのサービスを使ったという話を探っても出てこないので、文字化けとかしないかは若干不安。</p>
<h3>Money Forward (500 / month)</h3>
<p>1年ぐらい課金している。昔は Zaim を使っていたけど、いろいろとこっちのほうが各口座の情報を勝手にかき集めてくれたりとかが便利で戻れなくなった。お金の管理のためにお金を支払っていることに若干矛盾を感じなくもないが、便利なので仕方ない。</p>
<h2>Entertainment</h2>
<h3>Amazon Prime (3,900 / year)</h3>
<p>もともと Amazon Dash ボタンを使ってみたいという動機で契約したのだが、その後 Prime Video が始まり、主にその目的で使っている。お急ぎ便はあんまり使ってないし、 Prime Music もいまいち好みに合わなくて使ってない。 Prime Reading は何冊か読んだ。 Amazon Echo も、スキル名をいちいち呼び出さなくちゃいけないという仕様が Google Home より煩わしくて使わなくなった。最近改善されつつあるみたいだけど。</p>
<p>どう考えても安すぎるので値上げしてくれてもいいと思う。むしろデリバリープロバイダとかサービスの劣化が激しくなってきてるので、値段上げてほしい。通販はヨドバシあたりにして、映像配信は Netflix に鞍替えするのもありかなと少し思っている。</p>
<h3>Spotify (980 / month)</h3>
<p>音楽配信サービスは Spotify を使っている。 UI とレコメンドが優秀だと感じるのと、ブラウザで聴けるというのが大きい。仕組みがわかっていないけど VOCALOID 関連の同人 CD も結構入ってて面白い。</p>
<h3>Nintendo Switch Online (300 / month)</h3>
<p>これも安すぎると思う。。。目下スプラトゥーン用。最近スマブラも買ったけど、プレイするのが 64 以来なので怖くてオンライン対戦はまだやってない。</p>
<h3>シネマシティ (1000 / year)</h3>
<p><a href="https://cinemacity.co.jp/citizen/">シネマシティズン | シネマシティ</a></p>
<p>東京都立川市にある、爆音上映などで話題を集める 映画館シネマシティの有料会員。サブスクリプションとは厳密には違うけど。これも安すぎると思うんだけど、年間1000円払えばいつでも映画が1300円（平日は1100円）で見られるので、2回行くだけで元が取れてしまう。それでいて音響はいいし、スタッフがめっちゃ映画好きなんだろうなー映画のこと考えてくれてるなーっていうイベントも多いし、ラインナップも好きだし、最高の映画館だなーとずっと思っている。大学の頃から通っているのでもう10年近くになるけれど、今後転居する場合にも「シネマシティへ片道1時間以内で通うことができる」ことが絶対条件になるぐらいには好き。</p>
<p>以上、合計すると約3913円/月でした（esa.io解約後は3413円）。案外そんなものか、という感じ。</p>
]]></description>
            <link>https://chroju.dev/blog/subscriptions_2018</link>
            <guid isPermaLink="false">subscriptions_2018</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 17 Dec 2018 11:31:56 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[GitHub Actions - Dockerfile を突っ込んで自動化するという考え方]]></title>
            <description><![CDATA[<p><a href="https://blog.github.com/jp/2018-10-24-action-demos/">GitHub Actions</a> が Limited Public Beta で使えるようになっていたので触ってみた。<a href="https://developer.github.com/actions/">マニュアルはすでにパブリックに公開されている</a> ので、使い方的なことは書かずに、触ってみた印象感想中心で少し書きます。</p>
<p>現状では private レポジトリだけで、このように「Actions」タブが現れるようになっている。ここを開くとビジュアルエディターで Actions を設定できるし、テキストエディタで <code>.github/main.workflow</code> ファイルを手動で作成しても使える。</p>
<p><a href="https://gyazo.com/c0edc7d6f195f09b00582021835662de"><img src="https://i.gyazo.com/c0edc7d6f195f09b00582021835662de.png" alt="Image from Gyazo" width="608"/></a></p>
<h2>docker run を組み合わせてワークフローをつくる</h2>
<p>とはいえ CI ツールは Jenkins と CircleCI しか使ったことがないので、自ずとそれらとの比較になってしまうが、あえて挙げれば  CircleCI 2.0 と近いところが多い。CircleCI 2.0 では自動で実行する一連のプロセスを <code>Job</code> という単位に分割し、各 Job では指定した Docker コンテナの中でコマンドを実行していく形を取るが、 GitHub Actions も同様に Job に相当する <code>Action</code> で分割され、個々の Action に Docker コンテナを紐付ける。</p>
<p>ただし大きく異なる点として、CircleCI における Docker コンテナがあくまでコマンドの実行環境としての扱いであるのに対し、 GitHub Actions では <code>docker run</code> の実行 = コマンドの実行、という感覚になる。どういうことかと言うと、各 Action では実行するコマンドを <code>runs</code> と <code>args</code> という項目で設定できるのだが、これらは <code>runs</code> が Docker の <code>ENTRYPOINT</code> を、 <code>args</code> が <code>CMD</code> を override するものとして設定されているものであって、 Docker コンテナ内で実行させるというものではないから。</p>
<p><a href="https://gyazo.com/5acf3940d83bf721d1d025cd31833861"><img src="https://i.gyazo.com/5acf3940d83bf721d1d025cd31833861.png" alt="Image from Gyazo" width="361"/></a></p>
<p>つまり、各 Action は <code>docker run</code> コマンドを一発実行するだけのものと捉えてよく、コンテナ起動後にその中で何かを実行する、という形を取らない。これは単純に考えれば各 Job で1回しかコマンドの実行機会が与えられないということであり、実行したいコマンドの数だけ Job を作る必要が出てきてしまう。それはさすがにちょっと冗長ではという気もするが、 https://github.com/actions にいくつか公開済みのサンプルを見てもわりとそういう組み方をしている。以下は Dockerfile から image を build して、 AWS の EKS へデプロイするサンプルだが、 Action 数は計10個に及んでいる。</p>
<p><a href="https://github.com/actions/example-aws/blob/master/.github/main.workflow">example-aws/main.workflow at master · actions/example-aws</a></p>
<p>まだユースケースが少ないので、どういう Action の組み方がベストなのかはわからないが、仮に1つの Action で複数のコマンドを実行させたい場合には、スクリプトを作って <code>ENTRYPOINT</code> に渡す形になるかと思う。 Action で起動する Docker コンテナは、レポジトリ内の Dockerfile から build させることができる（ちなみに実行の度に逐一 build するので実行時間は速くない。キャッシュしたい）ので、任意のコマンドを複数実行する Dockerfile を作るのは手かもしれない。ただ、個人的にはそういうやり方は求められていなくて、あくまで Docker コンテナの、というべきか、 <code>docker run</code> の、というべきか、その組み合わせでワークフローを組むものだと考えている。先に挙げた https://github.com/actions には GitHub Actions で使うための Dockerfile がいくつか GitHub から提供されている。現状は <code>AWS CLI</code> を実行できるもの、 <code>docker</code> コマンドを扱えるものなど数が限られるが、これが今後増えていき、またユーザーが作成する Dockerfile も集まってくれば、それらを組み合わせて様々なワークフローが作れるはず。</p>
<h2>Trigger できるイベントはかなり豊富</h2>
<p>GitHub と連携させて使う CI ツールは多くの場合 <code>git push</code> で triggered されるが、 GitHub Actions は GitHub 組み込みなだけあって、 <a href="https://developer.github.com/actions/creating-workflows/workflow-configuration-options/#events-supported-in-workflow-files">trigger として扱えるイベント</a>が非常に多い。 star を付けられたときにも trigger することができる。</p>
<p>star を付けられたタイミングで test や build を回したいというユースケースもあんまりないと思うし、これは CI ツールよりもっと広く、 GitHub レポジトリで何かしらのイベントが発生したときに、自動実行したいこと全般を管理するための広範なツールとして捉えるべきなんだろうと思う。今までであれば IFTTT や何かしらの bot を使って、例えば star やプルリクが発生したときに slack へ通知させたりしていた人も多いと思うが、これを GitHub Actions を使う形にしてしまえば、外部のツールを使わずにレポジトリ内だけで外部連携関係の管理が完結する。</p>
<blockquote>
<p>継続的インテグレーションと継続的デリバリー（CI/CD）はActionsのユースケースのほんの一部だ。たしかにその面で役立つが、Actionsはそれ以上のものだ。これはDevOps全体に革命を起こすものだとと思う。なぜならActionsを用いることでこの種のものとして最高のアプリケーション、フレームワークのデプロイメントのサイクルを構築できるからだ。</p>
</blockquote>
<p><a href="https://jp.techcrunch.com/2018/10/17/2018-10-16-github-launches-actions-its-workflow-automation-tool/">GitHubからワークフロー自動化ツール、Actions登場――独自サービス提供の第一弾 | TechCrunch Japan</a></p>
<p>slack などに通知するときに必要となる API キーも <code>secrets</code> として暗号化した変数で渡すことができる。ただ現状は各レポジトリ間で <code>secrets</code> を共有することができないので、レポジトリを切るたびにいちいち設定が必要になり逆に管理が面倒とも言えるかもしれない（bot で通知を制御する場合、bot 内で一括管理ができるはずなので）。他にもまだまだ不足している要素は多く感じる。例えば golang の build を実装しようと思ったとき、 Docker の <code>WORKSPACE</code> が現状だと <code>/github/workspace</code> というディレクトリに固定されてしまっているので、 <code>$GOPATH</code> 内で実行する必要のある <code>dep ensure</code> が上手く実行できなくてだいぶ苦労したりした。</p>
<p>ただそういった細かな点さえ解消すれば、結構魅力的なツールになりそうだと感じる。GitHub レポジトリを中心として仕事をする中で自動化したいことがあれば、全部 Dockerfile を書いてレポジトリの中に放り込めばいい、ということになるわけだから。</p>
]]></description>
            <link>https://chroju.dev/blog/github_actions_first_impression</link>
            <guid isPermaLink="false">github_actions_first_impression</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 15 Dec 2018 03:26:04 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Terraform で AWS assume role が使用できない場合がある]]></title>
            <description><![CDATA[<p><a href="https://gyazo.com/3e9d184df4735785cec8ee0f04355c6c"><img src="https://i.gyazo.com/3e9d184df4735785cec8ee0f04355c6c.png" alt="Terraform"></a></p>
<p>AWS では <a href="https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_use_switch-role-console.html">assume role</a> と呼ばれる機能を使うことにより、 IAM ユーザーで AWS アカウントへログイン後、他の AWS アカウントの IAM Role へ権限の切り替えを行うことができる。これを使うと、複数の AWS アカウントを保有している会社でも、管理者としては各アカウントにいちいち IAM ユーザーを作らず、中央集権的な管理が可能になるし、利用者としてもユーザー/パスワードを1組だけ覚えればいいとか良いことがたくさんあるので、2018年末の今日においては多くの人が使っていると思う。しかし、これを Terraform で利用する場合に躓きがあった。</p>
<h2>~/.aws/config の活用</h2>
<p>Terraform を使う際に AWS 認証を通すにはいくつか方式がある。というか、 AWS CLI と同じ認証方式が基本的に使える。最も簡単なのは <code>~/.aws/config</code> を活用する方式。</p>
<pre><code>[profile switch]
region = ap-northeast-1
source_profile = source
role_arn = arn:aws:iam::SQITCH_ACCOUNT_ID:role/switch
mfa_serial = arn:aws:iam::SOURCE_ACCOUNT_ID:mfa/source
</code></pre>
<p><code>source_profile</code> に switch 元になるプロファイルの名前を、 <code>role_arn</code> に switch 先になる IAM Role 名を書き、あとは MFA のシリアルも書いておけば、上記の場合 <code>--profile switch</code> という引数を付けて AWS CLI を実行することにより、 MFA の token を入力して switch ができる。</p>
<p>これを Terraform の provider - profile に指定すれば使えそうなものなのだが、</p>
<pre><code>provider "aws" {
  region  = "eu-west-1"
  profile = "test"
}
</code></pre>
<p>残念ながら動作せず、 <code>assume role with MFA enabled, but AssumeRoleTokenProvider session option not set.</code> というエラーになってしまう。</p>
<p>また別の認証方式として、 <code>~/.aws</code> を活用せず、 Terraform の tffile 内に <code>provider</code> 設定として直接 assume role の情報を書き入れるという手段もあるが、この場合も同様に動作しない。</p>
<pre><code>provider "aws" {
  region = "ap-northeast-1"
  assume_role {
    role_arn = "arn:aws:iam::SQITCH_ACCOUNT_ID:role/switch"
    session_name = "switch"
  }
}
</code></pre>
<p>エラーメッセージから察するに MFA token 周りで問題があると見られる。 AWS CLI でこの認証方式を使った場合、コマンドを実行したときに対話式に token を尋ねられるのだが、この部分の実装が terraform-provider-aws には現状無く、 MFA token が入力できないので認証も通らなくなっている。</p>
<p>本件については、すでに以下のように issue が上がっている。 Contributor からも MFA token に関する実装がない点について回答がついていて、「Terraform は対話式のコマンド実行を排除し、中央集権的な環境で自動実行することを目指しているから」「重大な変更が生じるので技術的に困難だから」と理由も述べられている（が、down vote がめっちゃ入ってる）。</p>
<p><a href="https://github.com/terraform-providers/terraform-provider-aws/issues/2420">Doesn't ask MFA token code when using assume_role with MFA required · Issue #2420 · terraform-providers/terraform-provider-aws</a></p>
<p>従って現状は、MFAが有効な assume role で Terraform の認証を通すことは不可能であり、また今後の対応予定も今のところ無いと判断して良さそうである。この問題、どうも結構根深い上に、長らく GitHub 上では議論が続いているようで、すでに close されたもの（ほとんどは Terraform への機能追加ではなく、ワークアラウンドを提示して close という形）と open のもの含めて複数の issue が立っていたりする。</p>
<ul>
<li><a href="https://github.com/terraform-providers/terraform-provider-aws/issues/472#issuecomment-380931474">AWS assume role not working · Issue #472 · terraform-providers/terraform-provider-aws</a></li>
<li><a href="https://github.com/terraform-providers/terraform-provider-aws/issues/5078">AWS Assume Role Doesn't work with MFA Enforced Roles · Issue #5078 · terraform-providers/terraform-provider-aws</a></li>
<li><a href="https://github.com/hashicorp/terraform/issues/11270">AWS assume role not working · Issue #11270 · hashicorp/terraform</a></li>
</ul>
<h2>回避策</h2>
<h3>MFA 無効化</h3>
<p>試してはいないが、おそらく MFA token 無しで switch 可能な IAM Role であれば、この方式でも上手くいくのだろうという気はしなくもない（※ <a href="https://github.com/hashicorp/terraform/issues/11270#issuecomment-298224055">MFA 無効化してもダメだったという報告もある。手元で試してないのでわからない</a>）。</p>
<p>が、少なくとも人間に対して払い出す IAM ユーザーにおいて、 MFA を無効化した運用は考えられないので、 MFA を無効化するというのは回避策としては妥当ではない。先に引いたコメントにあるように、中央集権的な環境で Terraform の実行をすべて自動化しているのであれば話は違うとは思うが。</p>
<h3>aws sts assume-role コマンドと環境変数の利用</h3>
<p>AWS CLI で assume role を使う別の方式として、 <code>aws sts assume-role</code> コマンドを使う方式がある。このコマンドを実行すると、当該の Role へ Switch するのに必要な一時的な API キーが以下のように吐き出される（<a href="https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html#tutorial_cross-account-with-roles-3">チュートリアル: AWS アカウント間の IAM ロールを使用したアクセスの委任 - AWS Identity and Access Management</a>から抜粋）。</p>
<pre><code>{
    "Credentials": {
        "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
        "SessionToken": "AQoDYXdzEGcaEXAMPLE2gsYULo+Im5ZEXAMPLEeYjs1M2FUIgIJx9tQqNMBEXAMPLE
CvSRyh0FW7jEXAMPLEW+vE/7s1HRpXviG7b+qYf4nD00EXAMPLEmj4wxS04L/uZEXAMPLECihzFB5lTYLto9dyBgSDy
EXAMPLE9/g7QRUhZp4bqbEXAMPLENwGPyOj59pFA4lNKCIkVgkREXAMPLEjlzxQ7y52gekeVEXAMPLEDiB9ST3Uuysg
sKdEXAMPLE1TVastU1A0SKFEXAMPLEiywCC/Cs8EXAMPLEpZgOs+6hz4AP4KEXAMPLERbASP+4eZScEXAMPLEsnf87e
NhyDHq6ikBQ==",
        "Expiration": "2014-12-11T23:08:07Z",
        "AccessKeyId": "AKIAIOSFODNN7EXAMPLE"
    }
}
</code></pre>
<p>この API キーを環境変数に set すれば、 Terraform は環境変数での認証を最優先に実行するので、 assume role の利用が可能になる。 MFA token の入力も <code>aws sts assume-role</code> コマンドの実行時点で終わるので問題ない。</p>
<p>ただ注意点としては、環境変数に AWS API キーを設定しまうと、 Terraform はそれ以外の認証情報を一切無視してしまうということ。例えば複数の AWS アカウントをまたいでセットアップを行うような Terraform のレポジトリを使おうとするとき、通常は tffile に複数の <code>profile</code> を書いて切り替えようとすると思うが、これらは環境変数の認証情報で上書きされて使えなくなる。あとは率直に、 Terraform を実行するたびにキーを発行して環境変数にセットするのは面倒という話もある。</p>
<h3>aws sts assume-role コマンドと ~/.aws の利用</h3>
<p>一時的な API キーを環境変数に set してしまうと問題なのであれば、 <code>~/.aws/credentials</code> に書き込んで一時的に profile を作ってしまえばいいんではという案。スクリプトを書けば <code>aws sts assume-role</code> コマンドを実行して credentials に書き込むところまで自動化も出来る。これが比較的マシと言えばマシな手段。</p>
<p>この手のツールはすでに作成されていて、見たところ aws-mfa というのが使いやすそうだった。</p>
<p><a href="https://github.com/broamski/aws-mfa">broamski/aws-mfa: Manage AWS MFA Security Credentials</a></p>
<h2>Conclusion</h2>
<p>いろいろ検討はしてみたものの、結局のところ「Terraform は MFA を必要とするような手動運用で実行するべきではない」という話になってくるのかなとは思う。先の HashiConf '18 で、 <code>terraform plan</code> や <code>apply</code> を実行するための基盤となるクラウド環境を <a href="https://www.hashicorp.com/blog/terraform-collaboration-for-everyone">HashiCorpが提供する</a> という話が出たことと、先述の issue 内でのやり取りを鑑みても、 HashiCorp としては手動での対応が必須になってしまう、対話的な terraform の実行はバッドプラクティスという方向に進めつつあるように見える。</p>
<p>なのでここに挙げたようなワークアラウンドで一旦は回避しつつも、手動 terraform 実行を一掃することを目指さなくてはならないのかな、というのが今回の結論。</p>
]]></description>
            <link>https://chroju.dev/blog/terraform_with_aws_assume_role</link>
            <guid isPermaLink="false">terraform_with_aws_assume_role</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 10 Dec 2018 12:08:16 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[CNCF の活動から Serverless の今を追う]]></title>
            <description><![CDATA[<p>この記事は <a href="https://qiita.com/advent-calendar/2018/serverless">Serverless Advent Calendar 2018 - Qiita</a> の5日目です。最初に断りですが、すみません具体的実装などの話は用意できませんでした。</p>
<p>AWS Lambda あたりを発火点として広がってきたサーバーレスの動きも、近年では他のクラウドサービスは当然として、特定クラウドにロックインされない OpenFaaS のようなプロダクトが出てきたりなど、多岐に渡ってきた印象があります。それに伴って全体像と言えるようなものがなかなか捉えづらくなってきて、何か良い追い方はないかと探していたところ、見つけたのが CNCF の Serverless WG (Working Group) でした。</p>
<p><a href="https://github.com/cncf/wg-serverless">cncf/wg-serverless: CNCF Serverless WG</a></p>
<p>CNCF ではクラウドネイティブな特定技術分野に関するワーキンググループをいくつか設けており、そのうちの1つが Serverless WG です。これまでの成果は上記の GitHub レポジトリで公開されていますが、主なところでは以下の2点が挙げられています。</p>
<h2>A Serverless Overview Whitepaper</h2>
<p><a href="https://github.com/cncf/wg-serverless/blob/master/whitepapers/serverless-overview/cncf_serverless_whitepaper_v1.0.pdf">wg-serverless/cncf_serverless_whitepaper_v1.0.pdf at master · cncf/wg-serverless</a></p>
<p>2018年2月に公開された、Serverless を取り巻く当時の状況や、ユースケースなどについて解説したホワイトペーパーです。非常に内容が多いですが、すでに @IT などで翻訳や解説も公開されており、読み進める上でとても助かりました。</p>
<ul>
<li><a href="http://www.atmarkit.co.jp/ait/articles/1802/28/news027.html">サーバレスコンピューティングとは何か、その典型的ユースケースとは (1/4)：【完訳】CNCF Serverless Whitepaper v1.0（1） - ＠IT</a></li>
<li><a href="http://gs2.hatenablog.com/entry/2018/02/16/114739">CNCF Serverless Whitepaper v1.0 の重要部分の抜粋と雑感 - GS2 Blog</a></li>
</ul>
<h2>Landscape</h2>
<p><a href="https://landscape.cncf.io/grouping=landscape&#x26;landscape=serverless">CNCF Cloud Native Interactive Landscape</a></p>
<p>個人的に最近よく参照しているのがこちらの Landscape です。主な Serverless 技術を「Hosted Platform」「Installable Platform」「Framework」「Tools」「Security」の5種類に区分してマッピングしたもので、 Serverless の現況をざっと概観するのにちょうどいい資料になっています。なお補足しておくと、これは Cloud Native Landscape というさらに広い Landscape の一部という扱いになっています。</p>
<p>実際に資料を見ると、あまり国内では耳にしないサービス、プロダクトも数多くあります。例えば「Platform」には AWS Lambda, Azure Function, netlify といったお馴染みのクラウドサービスや、 "Installable" な OpenFaaS や Kubeless などが並んでいますが、ここに連なっている Huawei Function Stage にはなかなかピンと来なかったりします。知らないものをたまに拾っては少し触ったり調べたりしてます。</p>
<h3>example: Dashbird</h3>
<p>一例として、最近ここで見つけて使ってみたサービスに <a href="https://dashbird.io/">Dashbird</a> があります。 AWS X-Ray や CloudWatch と連携して、 Lambda や API Gateway の見やすいダッシュボードを作ってくれるシンプルなサービスです。</p>
<p><a href="https://gyazo.com/c20fabd4ac3f332c32b8d3732a80ec37"><img src="https://i.gyazo.com/c20fabd4ac3f332c32b8d3732a80ec37.png" alt="Image from Gyazo" width="2856"/></a></p>
<p>Lambda Function の一覧画面にはリージョンを問わずすべての Function が掲載され、24時間以内の実行状態が確認できます。</p>
<p><a href="https://gyazo.com/a1f00d750221985c552d870baaf1adc5"><img src="https://i.gyazo.com/a1f00d750221985c552d870baaf1adc5.png" alt="Image from Gyazo" width="1513"/></a></p>
<p>個々の Lambda Function の詳細では実行時間やメモリ使用率のグラフ、また直近実行履歴において、それが cold start だったかどうかといった点まで一覧できて、結構使い勝手が良さそうだと感じています。ほかにも特定の Function を指定して、 tail コマンドのようにリアルタイムで実行ログを追う機能があったり、 slack へのアラート機能もあったり、およそダッシュボードに求められる機能はそれなりに揃っている印象です。カスタマイズ性は高くないものの、 Lambda を駆使して作った環境をサクッと監視したいときに使うにはアリかなと思っています。</p>
<h2>仕様の検討</h2>
<p>サーバーレスコンピューティングにベンダーロックインという問題は付き物のように思われていますが、 Serverless WG ではこれを解消する一助となる、共通仕様の検討も行われています。現状形になってきているものとしては、サーバーレスなりソースがやり取りする「イベント」の記述形式を共通化する CloudEvents が上げられます。</p>
<p><a href="https://github.com/cloudevents/spec">cloudevents/spec: CloudEvents Specification</a></p>
<p>他にも <a href="https://github.com/cncf/wg-serverless/blob/master/proposals/README.md">Proposals</a> によれば、 Wokrflows や Event Orchestration といった、いくつかのテーマが審議対象として挙げられているようです。</p>
<p>個人的には、ベンダーロックインを必ずしも忌避すべきものとしては捉えていません。というのも、特に AWS Lambda を使っていて感じていることですが、あれは単なるミニマムなコード片の実行サービスとして重宝されているわけではなく、AWS 内に様々存在するマネージドサービス間を相互に繋ぐ簡易かつ信頼性の高い手段として価値があると認識していて、いわば「ロックインされていることに意味がある」からです。DynamoDB と API Gateway と Cognito と連携してバリバリ動いている Lambda Function に、ベンダーレスな可搬性が必要かと言うと、あんまり要らないんじゃないかなと思っています。</p>
<p>とはいえマルチクラウドに対応する機会も多くなってきましたし、群雄割拠状態のサーバーレスコンピューティングに、ベンダー間共通の仕様が出来ることは、開発スピードを上げる意味でも、アーキテクチャの可能性を広げる意味でも意義があることだと思います。ぶっちゃけ CloudEvents の定義に沿って記述されたイベントを webhook で投げ合うぐらいがシンプルで使いやすいよなとも思ったりはしてます。CNCF が今後どのような Specification を策定していくのか、またそれが具体的にどう実装されていくかは注目したいところです。</p>
<h2>Conclusion</h2>
<p>以上、ざっくり見てみましたが CNCF Serverless WG が公開している情報から、特定のクラウドサービスに依存せず、広くサーバーレスコンピューティングの在り方を追っていけるのではないかなと考えています。今後も継続的に追いかけていく予定です。</p>
]]></description>
            <link>https://chroju.dev/blog/cncf_serverless_wg</link>
            <guid isPermaLink="false">cncf_serverless_wg</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 04 Dec 2018 15:10:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[競技プログラミングで Write Code Every Day を2か月続けてみて]]></title>
            <description><![CDATA[<p><a href="https://gyazo.com/31e59ad19ef31d2cf70eefff1313ddcf"><img src="https://i.gyazo.com/31e59ad19ef31d2cf70eefff1313ddcf.png" alt="Image from Gyazo" width="600"/></a></p>
<p>「<a href="https://chroju.github.io/blog/2018/10/03/competitive_programming/">競技プログラミングを始めてみた</a>」というエントリーを10月頭に書いて、だいたい2か月ぐらい毎日草を生やしてきたので、ここらで少し振り返ってみる。草は一部 <a href="https://github.com/chroju/nature-remo-cli">nature-remo-cli</a> などで生やしたものもあるが、ほぼ「<a href="https://onlinejudge.u-aizu.ac.jp/home">Aizu Online Judge</a>」で生やしている状況。</p>
<h2>Pros</h2>
<h3>スムーズにプログラムが書けるようにはなってきた</h3>
<p>始めたときのエントリーで書いた通り、自分は現在の職務だとプログラミングやスクリプティングをしない日もよくあるので、下手すれば1週間とか2週間とかプログラミングというものに触れず、いつまで経っても覚えが悪い、なんてこともあったのだが、さすがに毎日書いていると覚えが早いし忘れることもない。よく使う文法や関数はすぐ覚えるし、プログラミングに要する時間自体が徐々に短くなってきたように思う。</p>
<h3>アルゴリズムやデータ構造に関する学習にもなっている</h3>
<p>アルゴリズムやデータ構造をまともに体系的に学ぶ機会を設けてこなかったのだが、「Aizu Online Judge』には各種ソートアルゴリズムや基本的なデータ構造、ユークリッドの互除法などの数学的アルゴリズムを使う問題が豊富にあるので、それらを学ぶ機会に恵まれることとなった。さすがに主要なソートアルゴリズムぐらいは IPA の試験などを通じて知ってはいたけれども、全部が全部実装経験があるわけでもないので、この機会に学び直せてとても楽しい。</p>
<h2>Cons</h2>
<h3>模範解答がない</h3>
<p>「Aizu Online Judge」特有の話ではあるが、模範解答が存在してはいない。他のユーザーの回答がパブリックになっていればそれを見ることはできるが、模範的なものになっているとは限らないのでヒントにしかならない。各種主要なアルゴリズムを実装するにあたって、「ぼくが考えた最強のあるごりずむ」で解いてもおそらく意味はなくて、代表的な実装を把握はしておきたいところなので、副読本として『アルゴリズム・クイックリファレンス』を購入した。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117852/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/51gNHECLgTL._SL160_.jpg" alt="アルゴリズムクイックリファレンス 第2版" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117852/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">アルゴリズムクイックリファレンス 第2版</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 18.11.18</div></div><div class="amazlet-detail">George T. Heineman Gary Pollice Stanley Selkow <br />オライリージャパン <br />売り上げランキング: 160,999<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117852/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>ちなみに「Aizu Online Judge」公式の解説本も売っているらしいのだけど、目的はこの競技プログラミングを解くことというよりは、それを通じてアルゴリズムを学ぶことであるので、汎用的っぽいオライリーのほうを買った。</p>
<h3>ものを調べたり本を読んだりする時間が減った</h3>
<p>Write Code Every Day が第一優先になった結果、 commit を伴わない作業の優先度が相対的に下がった。1日1commitするのに、少なくとも 30分/day は費やしている。すると平日はなかなか他のことに時間を割くのも難しかったりして、 commit に繋がらない何かを調べる作業とか、本を読んだりする時間がめっきり減ってしまった。</p>
<p>Write Code Every Day は、ことプログラミングの習慣化をするにはとても良いプラクティスだと思う。何より成果が可視化されるのでわかりやすいし、草が続いていくと、これを絶やさないようにしたいというモチベーションがどんどんと湧いてくる。ただ「草を生やす」ことで可視化をしてしまうと、成果の出し方が「コードを書いて commit して GitHub に push する」という手段に縛られてしまうのは良くも悪くもだなと感じている。ITに携わる人間として、日々力をつけるのに必要な研鑽はそれだけに限らない。なので、例えば自分の場合はこのブログの元になっている markdown も GitHub で管理しているが、そこに commit することも成果として OK ということにすることにした。あるいは何かを調べる作業にしても、その調べた結果を単に「ふむふむ」と頭の中に留めるのではなくて、実際に簡単なコードで実装する習慣を作れば commit に繋げられるかもしれない。</p>
<h3>競技プログラミングだけで満足していていいのか</h3>
<p>もともと Write Code Every Day のネタとして競技プログラミングを始めたのは、他にネタを持っていない日が多かったからなのだけど、現状競技プログラミングがメインになりすぎてしまっている。競技プログラミングはどうしても問題を書くためのコード、つまりは手続き型で書けばOKな場合がほとんどなので、 Go で何かツールを作るときにはどういうプラクティスに則ればいいのかとか、そういったより実践的な知識を学ぶ機会がない。なにか題材になるような OSS を育てるとか、他の OSS に対して Pull Request を飛ばすとか、そういうことも週に1〜2日でも構わないので組み入れられるように切り替えたい。そしてそのためには、書くネタを探すという別の習慣付けが必要だなと感じている。</p>
<hr>
<p>ざっとこんな感じで、習慣的にプログラミングする時間を設けることができるようになったのはいいんだけど、そればかりしているわけにもいかないからどうしようかなというところ。日頃からネタを探す習慣をつけたくて、年内はインプットの方法を見直すことを進めていこうと思っている。</p>
]]></description>
            <link>https://chroju.dev/blog/write_code_every_day_with_competitive_programming</link>
            <guid isPermaLink="false">write_code_every_day_with_competitive_programming</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 18 Nov 2018 06:22:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Nature Remo の CLI ツールをつくった]]></title>
            <description><![CDATA[<p><a href="https://nature.global/">Nature Remo</a> を導入してから半年ぐらい経って、非常に便利に使っているのだけど、「リモコンを探さなくてもスマホか Google Home に話しかけるかすればいい」というのも作業中などはちょっと面倒に思えてきて、ITエンジニアなのだし、ターミナルから操作できたら一番いいよねという結論に至り、作ってみた。以前、 <a href="https://chroju.github.io/blog/2018/06/11/play_with_nature_remo/">Nature Remo API で遊んだ</a> というエントリーを書いたが、当時は Get 系の API を叩くのみで、実際にシグナルを送ることはしておらず、今回初めて挑戦した。</p>
<ul>
<li><a href="https://github.com/chroju/nature-remo-cli">chroju/nature-remo-cli: Unofficial command line Interface for Nature Remo</a></li>
</ul>
<h2>使い方</h2>
<p>https://home.nature.global/ から自分の Nature Remo のアクセストークンを発行すれば、それを使って誰でも扱えるようなものにしている。インストールは <code>go get</code> か、先の GitHub レポジトリの「Releases」からバイナリを落とすかの2パターンを用意している。コマンドを使えるようになったら、まず <code>remo init</code> コマンドを叩いて、アクセストークンを読み込ませる。</p>
<pre><code class="language-sh">$ remo init
Nature Remo OAuth Token:
&#x3C;Input your token>
Initializing ...
Successfully initialized.
</code></pre>
<p>正しいトークンを与えれば、このように初期化処理が成功して、あとは自由に使えるようになる。シグナルを遅らせるときは家電 (appliance) とシグナルの名前を指定する必要があるのだけど、使用できる家電名とシグナル名は <code>remo list</code> コマンドで一覧できる。うちの場合はこんな感じ。</p>
<pre><code class="language-sh">$ remo list
ライト オフ
ライト オン
ライト 暗い
ライト 明るい
ライト 白い
ライト 暖かい
ライト 全灯
tv オン
tv 入力切替
tv 1
tv 2
tv 3
tv 4
tv 5
tv 6
tv 7
tv 8
tv 9
tv 10
tv 11
tv 12
tv 音量上
tv 音量下
</code></pre>
<p>ここから任意のものを選んで、 <code>remo send</code> で実行する。</p>
<pre><code class="language-sh">$ remo send tv オン
Success.
</code></pre>
<h2>動作仕様</h2>
<p>Nature Remo のシグナル送信用 API は、当該の signal ID を与えて実行するようになっているのだけど、 signal ID は Nature Remo の内部的な値であって、例えばスマホ用のアプリでは表に出るものではない。取得するには API を叩く必要があるのだが、シグナルを飛ばすたびに signal ID を API で持ってくるのも非効率なので、 <code>remo init</code> を実行した時に、　<code>$HOME/.config/remo</code> に YAML 形式で書き出すようにしている。</p>
<pre><code class="language-yaml">credential:
  token: &#x3C;YOUR TOKEN>
appliances:
- name: ライト
  id: abcdefgh-1234-ijkl-5678-mnopqrstuvwx
  signals:
  - id: abcdefgh-1234-ijkl-5678-mnopqrstuvwx
    name: オン
    image: ico_foo
  - id: abcdefgh-1234-ijkl-5678-mnopqrstuvwx
    name: オフ
    image: ico_bar
</code></pre>
<p><code>remo list</code> はここから全家電とシグナルの <code>name</code> を読み込んで表示している仕組み。また <code>remo send</code> も同様に、このファイルから指定した家電名、シグナル名に該当する signal ID を探してきて、その ID で API を実行している。</p>
<p>つまりは <code>remo send</code> は実際 Nature Remo に設定している家電名、シグナル名を必要としているわけではなく、この YAML ファイル上に書かれた名前を必要としているので、 YAML の中身を自由に書き換えることで、 <code>remo send</code> に与える引数も変えることができる。家電名やシグナル名はスマホのアプリで設定するものなので、多くの人は日本語で名付けると思うのだけど、これをコマンドラインで実行するとなると、日本語というのは扱いづらい。なので YAML を書き換えて、例えば先の「ライト」「オン」を「light」「on」に書き換えて使うことができる。</p>
<p>元に戻したい場合や、新しい家電を Nature Remo に追加した場合は、 <code>remo sync</code> コマンドで Nature Remo の最新状態と YAML を同期できる。その際は日本語から英語に手動で書き換えた箇所も復元されてしまうわけだけど、将来的に解消できたらしたいと思っている。</p>
<h2>今後</h2>
<p>まだ実装していない機能としてエアコンの操作がある。</p>
<p>Nature Remo は「赤外線信号の送信を代替する IoT 機器」なわけだけど、エアコンとそれ以外の家電では内部での扱い方が異なる。多くの家電では、もともとのリモコンから学習した赤外線信号をシンプルに送るだけなのだが、エアコンの場合は温度、風量、風向といった設定セットを Nature Remo 側で作って、それを赤外線で送るような形になっている。なのでエアコン用シグナルの送信は API も個別に用意されていて、そちらはまだ実装ができていない。寒くなる前にはなんとかしたい。あとはセンサー情報を取得して、現在の気温や湿度を表示する機能も実装したい。</p>
<p>具体的な技術的背景とかは、また別のエントリーに書こうと思う。</p>
]]></description>
            <link>https://chroju.dev/blog/nature_remo_cli</link>
            <guid isPermaLink="false">nature_remo_cli</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 03 Nov 2018 12:32:37 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[HashiCorp が Terraform state 用 remote storage を出すらしい]]></title>
            <description><![CDATA[<p>先週 HashiCorp のイベント <a href="https://www.hashiconf.com/">HashiConf '18'</a> がサンフランシスコで開かれていて、そこで発表された内容をつらつら追っていたのだけど、2つほど気になったのでメモしておこうと思う。ちなみに HashiCorp ツールは Terraform をとてもよく使っていて、それ以外だと Vault と Packer を多少使っているぐらいという感じで、ほぼ Terraform のことにしか興味がない状態。</p>
<h2>Google Cloud Shell から実行可能になった</h2>
<p>可能になった、といっても自分が育てている任意の tf ファイルを持っていってどうこうするというわけではなくて、 HashiCorp が用意している example をボタンポチッとで Google Cloud Shell 内に持っていって、チュートリアル的に実行できるようになったという話。</p>
<p>とりあえず Terraform を試してみるにも、まずインストールして、ドキュメント見ながら tf ファイルを書いて、認証情報持ってきて、そこからようやく実行という感じで手数が多いと言えば多かったのかもしれなくて、それがブラウザからすぐお試し可能になった。すでに Terraform ドキュメントのいくつかにボタンが用意されていて、例えば <a href="https://www.terraform.io/docs/providers/google/r/compute_router.html">google_compute_router</a> に表示されていたりする。これをポチッとすると、 Google Cloud Shell が開いて、そのまま example を実行できる。試してみたけど、確かに最初の一歩を覚えるにはいいかもしれない。</p>
<p><a href="https://gyazo.com/fe7f226c0d8db7ee849b85cce85f02e8"><img src="https://i.gyazo.com/fe7f226c0d8db7ee849b85cce85f02e8.png" alt="Image from Gyazo" width="600"/></a></p>
<h2>Terraform state を保存する場所を HashiCorp が用意してくれる</h2>
<p>表題の件に移るが、 Terraform の state file はクラウド上に単一のものを保存して、実行者間で共有しましょうというのは自明だと思うけど、それをじゃあどこに置くのかというのはユーザーの裁量に任されていた。おそらく Amazon S3 など、管理対象クラウドサービスにあるストレージが選ばれている気がするけれど、これを HashiCorp が無料で用意してくれるらしい。しかも無料。</p>
<blockquote>
<ul>
<li>No limits on users</li>
<li>No limits on workspaces</li>
<li>Encryption provided by HashiCorp Vault</li>
<li>Per-operation locking</li>
</ul>
</blockquote>
<p>ちょっと上手い話すぎませんかねぇとも思うけど、 Docker が Docker Hub を提供しているようなものと考えると頷ける気もする。正直 S3 で事足りている感はあるし、 S3 で実現可能なバージョニングなどの機能が入るのかはわからないけれど、使い勝手によっては検討したい。今年中にベータ版がオープンするそうで、 <a href="https://app.terraform.io/signup">Wishlist</a> への登録受付がすでに始まっているので、興味がある人は登録してみるといいと思う。</p>
<p>関連して、これはすでに Terraform Enterprise で始まっているみたい（使ったこと無いのでよく知らない）けど、 plan や apply のコマンドを手元で実行するのではなく、 remote で実行するための環境を無料でも制限付きで開放するようだ。個人的な懸念として、手元のコンソールで terraform apply を実行するのは面倒に感じることは確かにあって、 tf ファイルが大きくなってくると数十分待たされることも少なくないし、実行結果を残すのが一手間いるし、実行者が複数いる場合には、個々の環境にインストールされている Terraform にバージョン差異が生まれてしまって上手く実行できない、なんてのもあり得る。解決策として CI を使って実行させたりもしているけれど、環境構築の手間はある。それを解決できる、シンプルに Terraform を実行するためだけのサービスがローンチされるのはわりと嬉しい気がする。</p>
<h2>Tool から Workflow へ</h2>
<p>HashiConf '18 のレポートの中で、 HashiCorp の Tao の中に "workflows, not technologies.”というのがあると触れられているけれど、今回の Terraform 周りのリリースはまさにそれで、従来は単に便利な OSS を配っている企業という印象が強かった HashiCorp が、その実行基盤まで用意してくれるようになってきた。クラウドリソースの定義さえ書いてもらえれば、その管理とか実行とかのワークフローはマネージドなサービスに全部任せられますよというのは良い流れだと思うし、 Ansible が GUI の管理ツールである Ansible Tower をプッシュしている流れにも似たものを感じる。自分は CircleCI とか使えば間に合うんじゃないかなと思ったりもするのだが、運用管理に特化したツール、サービスが充実してくると、そのあたりに厳しい大企業など、マスに広がりやすくなるように思う。 Terraform は好きなツールなので、裾野が広がりやすくなる動きは応援したい。</p>
<p>あと Terraform 0.12 と HCL2 もそろそろクルーーー？な感じで期待している。HCL は GitHub Actions でも採用が決まったので、なんか汎用的に使われていく未来もあるかもですね。その他 HashiCorp '18 の情報は以下のブログエントリーなど参照で。</p>
<ul>
<li><a href="https://www.hashicorp.com/blog/hashicorp-product-announcements-at-hashiconf-2018">HashiCorp Product Announcements at HashiConf 2018</a></li>
<li><a href="https://www.hashicorp.com/blog/terraform-collaboration-for-everyone">Terraform Collaboration for Everyone</a></li>
<li><a href="https://www.hashicorp.com/blog/kickstart-terraform-on-gcp-with-google-cloud-shell">Kickstart Terraform on GCP with Google Cloud Shell</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/hashiconf_2018</link>
            <guid isPermaLink="false">hashiconf_2018</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 29 Oct 2018 11:49:07 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[競技プログラミングを始めてみた]]></title>
            <description><![CDATA[<p>「<a href="https://johnresig.com/blog/write-code-every-day/">Write Code Every Day</a>」という有名なプラクティスに関して、なるほどそれは良さそうだなと思う一方、自分のメインとなる職掌がプログラミングというよりはインフラだったり Operation だったりする関係上、日々プライベートでやっていることは必ずしもプログラミングではなくて、本を読みたいときとかドキュメントを漁りたいときというのも少なくないので、どうも必ずしも「毎日コードを書く」というのは自分には合わないのではないかなという気がしていた。</p>
<p>それが最近になって意識が変わって、というのも、先に書いた通り現在の職掌がプログラミングメインではないため、状況によっては数週間ろくにプログラミングっぽいことをしない、ということがザラに発生するわけで、そうすると結構簡単に忘れてしまうというか、いつまで経っても手が慣れないなという感覚がでてきた。逆に言えば仕事でプログラミングを毎日している人は、さらに家でもプログラミング、ということをせずともプログラミングが日常になっているんだろうけど、プログラミングを仕事にしていないからこそ、余暇の時間に手を動かす、毎日コードを書くことを強制することは自分にとって必要なのではないかと思い直した（ただ本音で言えば、インフラと Ops を主戦場としつつももっとプログラミングできる環境に身を置きたい）。</p>
<p>で、問題になるのが「何を書くか」。</p>
<p>以前にも「Write Code Every Day」をしてみよう、と思ったことは無いではなくて、しかしそのときに壁となったのが「何を書くか」だった。 OSS を作るにも常にネタがあるわけじゃなかったりするし、まぁもっと日頃から OSS 触って PR 投げられるポイント見つけろとかそういう話なのかもしれないけど、そういう実践は実践でするとして、「現状書くものを見つけられていない」という課題への解決は別途しなければならない。</p>
<p>そこで競技プログラミングに手を出し始めた。といってもただパズルのように問題を解くだけなので、今のところコンテストに参加したり「競技」はしていない。手を動かす材料として、豊富に問題があるので使えるのではないかと思った。1問を解くのにも30分ぐらい用意すればなんとかなるので、平日時間がなくても頑張れば commit できるというメリットもある。</p>
<p>今登録しているのは以下の2つ。</p>
<ul>
<li><a href="https://atcoder.jp/?lang=ja">AtCoder</a></li>
<li><a href="http://judge.u-aizu.ac.jp/onlinejudge/index.jsp">AIZU ONLINE JUDGE</a></li>
</ul>
<p>おそらく AtCoder が国内最大手的な立ち位置？なのかなと思っているが、現在メインで書こうとしている Go に対応していなかったので、 AIZU ONLINE JUDGE を Go で解く、というのが今のところメインになっている。慣れてきたら Python で AtCoder の方にももっと参加してみたい。書いたコードを GitHub に commit することで草を生やしていっている。</p>
<p>自分は完全独学でプログラミングをしていて、しかも仕事で学ばせてもらった経験が一切ないのでプログラミングスキルは下の下というあまり嬉しくない自負があり、当然ながら主要なアルゴリズムの実装なんかも押さえてはいないのだが、 AIZU ONLINE JUDGE の問題を見るとそのへんのキャッチアップも多少出来そうな感じがあるので楽しみにしている。</p>
<p>あと、パズル的なプログラミングという点では、30分で解くような単純な問題では無さそうなんだけど、最近出た『問題解決のPythonプログラミング』も面白そうだなと思っている。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873118514/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/41--mqsprXL._SL160_.jpg" alt="問題解決のPythonプログラミング ―数学パズルで鍛えるアルゴリズム的思考" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873118514/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">問題解決のPythonプログラミング ―数学パズルで鍛えるアルゴリズム的思考</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 18.10.03</div></div><div class="amazlet-detail">Srini Devadas <br />オライリージャパン <br />売り上げランキング: 6,804<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873118514/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
]]></description>
            <link>https://chroju.dev/blog/competitive_programming</link>
            <guid isPermaLink="false">competitive_programming</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 03 Oct 2018 13:04:35 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[builderscon 2018 に行ってきた]]></title>
            <description><![CDATA[<p><a href="https://chroju.github.io/blog/2017/08/06/builderson_2017/">昨年も行きました</a>が今年も行ってきました。このカンファレンス、「知らなかった、を聞く」をテーマに掲げていて、ガチもネタも含めセッションの幅が広く、いろんな話に触れられて楽しめるのというのと、よくわからないけど参加者が楽しそうにしているのを目にすることが多いので良いなという感じでいいカンファレンスだなーと思っています。昨日、なんかまたプライベートの時間に勉強するべきかみたいな話をTLでちらほら見かけて、元エントリー読んではいないけど、我々が何かを学ぶ、知るのって楽しいからであって、するべきかとかそういう話じゃないよなと個人的には。</p>
<p>今回ちょいとしんどかったのは、昨年はなかったと思うけど各セッション「満席」という扱いが設けられていて、立ち見含めある程度の人数が埋まったら入場できなくなってしまうこと。人気セッションは結構椅子取りゲームの様相を呈していて、自分も望みのセッションに入れないことが1回ありました。セッションの終わり頃にはすでに次の回を待つ人たちが部屋の外に並びつつあるような形で、まともにセッションを最後まで聞くと次に入れないみたいな不安を抱くような形だったので、ちょっとうーん、、、という感じはしました。それだけ人が増えたんですねー。あと Twitter のハッシュタグで流れてきてるけど、今回ベストスピーカー投票で上位取った人がみなさん名のあるエンジニアだったようで、表彰式がわりと内輪な空気になってしまったのもうーん、でした。</p>
<p><a href="https://builderscon.io/tokyo/2018/session/476a4a30-2f94-424c-bbc2-f6cb14f1c4cd">「Web とは何か？」 - あるいは「Web を Web たらしめるものは何か？」 - builderscon tokyo 2018</a></p>
<p>今回特によかったのは Jxck さん？ Jack さん？ のこの話で、 Web に新しい機能が追加されていくたびに、それは Web に必要なのか、それは Web らしい機能なのかという議論が起きるけれど、我々は Web とは何であると捉えていて、これまでそれはどう発展してきて、今後どこに向かうのか、というような包括的な話。もともとはハイパーメディアシステムとして出発した Web が、 Ajax 登場以後はインタラクティブな Application Platform に変わり、さらに最近はスマートフォンとの結びつきが強まり、デバイス制御まで手を出す Operating System に近いものになってきている。でも後方互換性を失うことはこれまでやっていなくて、 Web として従来メリットとして考えられていた部分は変わることなく、機能的に可能であることは議論の上で取り込まれていくのだ、という。</p>
<p>自分も一応 Web に育てられて、現在は Web があるからごはんが食べられているわけだけど、その実　Web が今どのようなものとして存在するのか、それが今後どう変化していくのか、あるいはなぜ自分は Web と共にあるのかについて、それほど考えてはこなかったな、と。自分の技術習得はどちらかと言えば後追いで、世間的に今こういう方向になりつつある、だからそれをキャッチアップしていこうと考える場合が多くて、そもそもその方向性が望ましいのかとか、その方向へ舵を切ろうとしているのは誰なのか（ Web の場合、それは今 Google が強くて、セッション中では「対抗できるのは Mozilla だけ」という言及があったわけですが）という先端の部分をそれほど見ていなくて。自分が好きな、というか生きる礎になっている技術分野が、今後どうなっていくのか、それは本当に幸せな発展なのかということを、きちんと把握しておくという姿勢は見習わなくてはならないな、という感銘を受けました。</p>
<p>なんか、そういう全体感とか哲学とかって別にそれでそのままごはんが食べられる話ではないんだけど、別にごはんが食べたくてやってるのかって言ったら、我々そうじゃない部分は大きいはずなんですよね。最初に「楽しい」というキーワードを書きましたけど、本当にそれだなーというところで、もっと自分が生きる世界の動向に食らいつきたいなみたいなことを強く感じたのでした。こういう全体感の話ってLTだと短すぎて伝わらないし、質疑応答の中で今回についても話が深まる感じがあったので、こういうカンファレンスならではの話だったなと。</p>
<p>エンジニアとしての立ち位置を見直す良い機会になりました。</p>
]]></description>
            <link>https://chroju.dev/blog/builderscon_2018</link>
            <guid isPermaLink="false">builderscon_2018</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 09 Sep 2018 02:33:56 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『エンジニアの知的生産術』を読んだ]]></title>
            <description><![CDATA[<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774198765/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/510ppvAzSeL._SL160_.jpg" alt="エンジニアの知的生産術 ──効率的に学び、整理し、アウトプットする (WEB+DB PRESS plusシリーズ)" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774198765/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">エンジニアの知的生産術 ──効率的に学び、整理し、アウトプットする (WEB+DB PRESS plusシリーズ)</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 18.08.23</div></div><div class="amazlet-detail">西尾 泰和 <br />技術評論社 <br />売り上げランキング: 302<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774198765/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>西尾泰和『エンジニアの知的生産術』を読んだ。知的生産という分野については職業柄もともと興味があって、梅棹忠夫の『知的生産の技術』や安宅和人『イシューからはじめよ』などを読んではいたが、それを活用できているかと言うと、なかなか「具体的に何をするか」まで落とし込めていないことが多かった。本書でようやく実践を進められそうな気がしている。</p>
<p>本書が面白いのは、本の中で書かれていることを実践しながら著者が書き進めているという点だと思う。</p>
<p>例えば第7章『何を学ぶかを決めるには』では、「何を学ぶのが正しいのか」という質問を置く前に、「正しい」とはどういうことか考えてみましょうという形で始まり、科学と数学における「正しさ」の扱いを紐解くことから書かれている。これは本書第1章で言及されている、「ゴールは明確に」という方針に沿うものと解釈できる。</p>
<blockquote>
<p>あなたは、ゴールがどこにあるかわからない、何キロ走ればよいのかわからないマラソンを完走できますか？ やる気を維持できる人はまれでしょう。プログラミング言語の学習も同じことで、どこまで進んだら「マスターできた」という実感が得られるのか不明確です。これではやる気の維持が困難です。やる気を維持するためには、ゴールは明確なものにする必要があります。</p>
</blockquote>
<p>この箇所に限らず、本書には曖昧な記述を極力減らし、具体的な定義と事例、参考文献に基づいた論を進めようという節が読み取れる。その点において信頼ができ、また本書を読み進めるなかで「なるほど、知的にアウトプットを作り上げるとはこういう過程を言うのか」と納得することができる。</p>
<p>本書から学び、実践しようと取り入れ始めたことはいくつかあるが、特にインプットを増やすべきであるという姿勢は積極的に真似したいと思った。具体的には、よく知られる「知的生産術」であるKJ法を実践するにあたっては、まずは100枚材料となる付箋を作りましょう、と説く。少なくとも50枚に辿り着かないようでは、明らかにインプット不足であると。そして集めた付箋をグループ分けしていくわけだが、重複があったり、似ているものがあったりしても良いのだという。</p>
<blockquote>
<p>共通点は何か、違いは何か、と考えるきっかけになります。第2章でも説明したように、似ているが少し違うものの比較は、理解を組み立てる助けになります。</p>
</blockquote>
<p>本書で紹介されるメソッドには、KJ法をはじめGTDやYAGNI原則、ポモドーロ・テクニックなど、見知ったものも多く、読み飛ばしそうになったこともあった。でも、他の本の記述とまったく同じわけではない。そうであるならば、「共通点は何か、違いは何か」ということから、学べることはあるはずだ。まずはインプットをとにかく増やす。そして個々の材料をじっくり比べてみる。何が有用か、という判断は、それからで良いのである。インプットを増やし、またそれを頭の中だけでごちゃごちゃと考えるのではなくて、付箋なり Scrapbox なりにきちんと書き下して考えていくこと。そういった姿勢は自分には足りていないものだった。</p>
<p>ところで、著者の西尾氏は <a href="https://scrapbox.io/">Scrapbox</a> をパブリックで書いていて、本書が出る以前から参考にさせてもらっているのだが、そこに本書の公式ページなるものも開かれているので、読まれる際は是非こちらも参照することをオススメしたい。 Scrapbox について本書内での言及はなかったけれど、知を書き下して、関連させて、ボトムアップ式に知的生産を図るには打ってつけのツールだと思っている。</p>
<ul>
<li><a href="https://scrapbox.io/nishio/%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E7%9F%A5%E7%9A%84%E7%94%9F%E7%94%A3%E8%A1%93_%E8%91%97%E8%80%85%E5%85%AC%E5%BC%8F%E3%83%9A%E3%83%BC%E3%82%B8@Scrapbox">エンジニアの知的生産術 著者公式ページ@Scrapbox - 西尾泰和のScrapbox</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/engineers_intellectual_productivity</link>
            <guid isPermaLink="false">engineers_intellectual_productivity</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Thu, 23 Aug 2018 11:54:12 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Kubernetes に入門してからやってきたことのメモ]]></title>
            <description><![CDATA[<p>数か月前からちょこちょこと Kubernetes を触っているのだけど、まだエントリーには何も起こしていなかったので、これまでやってみたことをツラツラと書き留めてみる。</p>
<h2>なぜ Kubernetes か</h2>
<p>単純に言ってしまうと「流行っているから」が最初の動機で、 <a href="https://chroju.github.io/blog/2017/09/26/migrate_coreos_to_ecs/">CoreOSからECSへDockerを移行した · the world as code</a> に書いた ECS の環境から GKE へと移行した。</p>
<p>ただ、使い始めてからは少し印象が違ってきていて、これは単なる「流行り」ではなくて、 AWS が出てきて数年のうちに「 AWS は今後のインフラ環境の主流になる」という空気が醸成されたように、今後は Kubernetes がメインになっていく、まずは k8s に載らないかを検討するような形になっていくんだろうなという感覚になってきた。慣れてくるとわかるけれど、 k8s を運用する場面において物理的なインフラを意識することはほとんどなく、どのコンテナにどれぐらいのリソースを割かせ、どのコンテナとどのコンテナを接続して、計どれだけのコンテナを動かせばいいのか、というのを宣言すれば勝手にイイ感じにやってくれるので、インフラ管理という面でこの上なく楽。ただ、それは裏を返せばこれまでのインフラ概念と、まったく異なる概念の下で環境を運用しなくてはならないという意味でもあり、最初の学習コストは大きく感じる。</p>
<p>もう一点、 k8s が良いのは OSS であるという点で、つまりはクラウド隆盛以降にたびたび懸念されていたベンダーロックインが無い。今は最も簡単に k8s を扱える環境として GKE を使っているけれど、もし何か GKE に懸念が出てきたら Amazon EKS なり自前のオンプレ k8s なりに乗り換えるのも難しくない。なので学習コストは大きく感じると書いたけど、払ったあとの回収は今後数年長いスパンでできると思うし、払う甲斐はあると思う。 ECS よりはおそらく。</p>
<h2>学習用「貧者のGKE」もどき</h2>
<p>先に GKE を使っていると書いたが、具体的な環境としてはなるべく安価に済むように「貧者のGKE」にヒントを得ている。「貧者のGKE」は <a href="https://qiita.com/apstndb/items/788f705e71e7660967a6">貧者の GKE / 無料枠だけでクラスタを作ろう</a> から引用させてもらった。</p>
<blockquote>
<p>特に注目なのは US リージョンに限るが GCE f1-micro 1インスタンス, 30 GB の HDD が永続で無料なことだろう。GKE は5ノードまではマスタの課金はなく、ノードは GCE ノードとして課金されるので、この恩恵が受けられるはずだ。</p>
</blockquote>
<p>残念ながら自分が動かしたいのは <a href="https://docs.influxdata.com/influxdb/v1.6/">influxDB</a> で、こやつがそれなりにメモリを食うために f1-micro は使えず、次点の g1-small を使っている。これは無料ではないが、 us-central1 かつプリエンプティブであれば $5.11/month （2018-08-19 時点）で使えるのでまぁまぁ安い。プリエンプティブいいですね。個人用途なら十分だし、料金は通常の3分の1程度なので最高。</p>
<p>また他にも、 GKE を使うとデフォルトで作成される Google Cloud Load Balancing がそれなりに高いので、自前で nginx を使ってロードバランシングする、という節約術もあるらしい。自分の場合そこまではしていなくて、 g1-small プリエンプティブ2台構成で月額4000円程度になっている。もう少し下げたい、という気も確かにする。</p>
<ul>
<li><a href="https://blog.a-know.me/entry/2018/06/17/220222">安価なGKE（k8s）クラスタを作って趣味開発に活用する - えいのうにっき</a></li>
<li><a href="https://kter.jp/kubernetes/2018/03/01/GKE%E3%81%A7%E3%81%AA%E3%82%8B%E3%81%B9%E3%81%8F%E5%AE%89%E3%81%8FKubernetes%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%BF%E3%82%92%E4%BD%9C%E6%88%90%E3%81%97%E3%81%A6Prometheus-+-Grafana%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B-Part2-Ingress%E7%B7%A8.html">GKEでなるべく安くKubernetesクラスタを作成してPrometheus-+-Grafanaを使ってみる-Part2-Ingress編</a></li>
</ul>
<h2>kompose</h2>
<p>ECS からの移行には <a href="https://github.com/kubernetes/kompose">kompose</a> を用いた。 kompose は Docker compose の YAML を k8s のマニフェストファイルに変換してくれるツールで、しかも Kubernetes が提供しているという最高のやつ。自分は ECS の環境を Docker compose のファイルで動かしていたので、 kompose によって楽に移行ができた。</p>
<p>kompose は本当に簡単で、正直最初は生成されたファイルをただ <code>kubectl apply -f hoge.yml</code> するだけで何もわからぬままに環境構築ができてしまって、逆に戸惑ったぐらいだった。今動かしているマニフェストファイルは GKE クラスタ構築用の Terraform ファイルと合わせて GitHub に上げてあるけれど、 kompose で生成した時点から多少いじってはあるが、そこまで大きく変えてもいない。</p>
<ul>
<li><a href="https://github.com/chroju/gke_sandbox">chroju/gke_sandbox: private GKE sandbox manifest files and terraform files</a></li>
</ul>
<h2>学習リソース</h2>
<p>基本的には <a href="https://cloud.google.com/kubernetes-engine/docs/">Kubernetes Engine ドキュメント  |  Kubernetes Engine  |  Google Cloud</a> を見ているが、とりあえず1冊まとまっててザザッと概念的なものを見渡せるものが欲しかったので、オライリーが出している『入門 Kubernetes』をさっと読んだりもした。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873118409/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/41HRQrBzfOL._SL160_.jpg" alt="入門 Kubernetes" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873118409/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">入門 Kubernetes</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 18.08.19</div></div><div class="amazlet-detail">Kelsey Hightower Brendan Burns Joe Beda <br />オライリージャパン <br />売り上げランキング: 22,683<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873118409/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>この本は Pod, ReplicaSet, DaemonSet, Deployment といった、 Kubernetes をとりまく概念を1章ずつ割いて個別に解説してくれるので、各リソース概念がどのような働きをしているのか、またリソース同士がどういった関係性を持っているのかを整理するのにとても役立った。 Kubernetes はとにかく独自の概念が多い、というかほとんどが独自概念で構成されているツールなので、まずは個々の用語をきちんと抑えること、コンテナを動かすために何をどう設定すればよくて、その設定をデプロイしたときにどのリソースが生成されて、どのように動作しているのか、というところを早いうちに把握した方がいいと思う。これは AWS を触り始めた当初の感覚に近かった。 Kubernetes はかなりアップデートも速いので、いつまでこの本が有効性を持っていられるのかはわからないが、現時点では最初の一歩として通読しておくには良い本だと思う。</p>
<h2>現状と今後</h2>
<p>とりあえず Kubernetes 回りで触ったのはこんなところ。現状は g1-small 2台のクラスタ上で、 influxDB と Grafana のコンテナを1つずつ動かしているだけの状態。今後やってみたい、やろうと思っていることとしては以下の通り。</p>
<ul>
<li>監視をする
<ul>
<li>Prometheus はさすがに大げさ過ぎる気がするが、リソースをそれほど食わないならやってみたい</li>
<li>難しければ Mackerel あたりでなんとかする</li>
</ul>
</li>
<li>Tasks を使ってジョブを動かしてみる</li>
<li>AWS Lambda で動かしているものを k8s へ持ってきて、運用上のメリデメなど比較している</li>
</ul>
<p>個人的には今のとこ AWS で頑張って Serverless するより k8s 環境上で常駐プロセスもイベントドリブンなジョブも動かせるようにした方が管理しやすいんじゃないかなぁという感覚を持っているけど、一概に言える話でもないと思うので、どういうときにどれを使うのがベターかもっと掘り下げていきたい。無論、 VM やベアメタルにもまだ出番はあると思っている。</p>
]]></description>
            <link>https://chroju.dev/blog/entry_kubernetes</link>
            <guid isPermaLink="false">entry_kubernetes</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 19 Aug 2018 05:46:59 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[fluentd 1.0 でログの欠損を防ぐ]]></title>
            <description><![CDATA[<p>ようやく fluentd v1.0 を最近触り始めている。極力ログを欠損させない形の設定がしたくて、 v0.12 の頃だと <a href="http://blog.livedoor.jp/sonots/archives/44690980.html">fluentdでログが欠損する可能性を考える - sonots:blog</a> を参考にさせてもらっていたのだが、 v1.0 だとパラメーターが変更されている部分が多く、改めてどう設定するべきかを考えてみた。</p>
<h2>前提 : 考慮するべきログ欠損ポイント</h2>
<p>まず前提として、 fluentd を使っていてログの欠損が発生し得るポイントを並べておく。以下、ログの送出元を forwarder 、集約先を aggregator と呼ぶ。</p>
<p>先の sonots 氏のエントリーを元に整理すると、基本的には aggregator 自身、もしくは forwarder - aggregator 間のネットワークに何らかのトラブルがあり、 fluentd が正常にログを送れなかった場合への対処が必要となる。 aggregator との通信に問題が起きると、 forwarder は aggregator への通信を自動的にリトライしつつ、その間徐々に buffer が蓄積されることになり、これが欠損に繋がり得る。</p>
<ul>
<li>aggregator への通信が中途で途絶する</li>
<li>aggregator への送信リトライ回数が上限に達する</li>
<li>buffer が増えすぎてファイルディスクリプタの上限に達する</li>
<li>buffer の保存量が上限に達する</li>
</ul>
<p>また buffer type が memory の場合は、サーバートラブル時に欠損する可能性が高いため、 file buffer を用いることは前提とする。</p>
<h2>具体的対処</h2>
<h3>aggregator への通信途絶への対処</h3>
<ul>
<li>変更なし ( require_ack_response true )</li>
</ul>
<p>v0.12 から存在する <code>require_ack_response</code> が v1.0 でも使用できる。これを設定すると、 aggregator が input plugin の処理を完了してから ack を返してくれるようになり、 forwarder での buffer 削除はその後で行われるようになるため、通信や処理が途絶してもログは失われない（ forwarder に残る）。</p>
<h3>リトライ回数の上限</h3>
<ul>
<li>v0.12 : disable_retry_limit true</li>
<li>v1.0 : retry_forever true</li>
</ul>
<p>設定値の名前が変更になった。また従来は <code>&#x3C;match></code> directive に書いていたが、 v1.0 では <code>&#x3C;buffer></code> directive に書く必要がある。</p>
<h3>ファイルディスクリプタの上限</h3>
<p>これは fluentd の機能ではなく、 OS側の <code>ulimit</code> の設定の話にはなるが、 65535 まで引き上げておくことは v1.0 でも推奨されている。</p>
<ul>
<li><a href="https://docs.fluentd.org/v1.0/articles/before-install">Before Installing Fluentd | Fluentd</a></li>
</ul>
<p>ただし、 fluentd を systemd 下で動作させる場合は、 unit ファイルに ulimit の設定がデフォルトで入っているため、別途OSの設定を変える必要はなくなった。</p>
<p>なおファイルディスクリプタに関しては、 <code>flush_interval</code> が過度に短く設定されている場合、 queued chunk が増えすぎてファイルディスクリプタを使いすぎる可能性があるため、 <code>queued_chunks_limit_size</code> という設定も用意されている。ただ、そこまで <code>flush_interval</code> を短くしすぎない方が、サーバー負荷の観点からも良いのではないかなとは思うし、個人的にはこの観点は気にしていない。</p>
<h3>buffer の保存量の上限</h3>
<ul>
<li>v0.12 : buffer_chunk_limit * buffer_queue_limit</li>
<li>v1.0 : total_limit_size</li>
</ul>
<p>v0.12 では chunk 1つあたりの最大サイズを示す <code>buffer_chunk_limit</code> と、 chunk の最大保存数を示す <code>buffer_queue_limit</code> を掛け合わせた値が buffer の上限だったが、 v1.0 ではこれをまとめて <code>total_limit_size</code> で設定できるようになった。書き込み中のバッファのサイズまで考慮されているらしい（参考 : <a href="http://smallpalace.hatenablog.com/entry/2016/06/02/123724">fluentdmeetup2016summerにいってきた - smallpalace's blog</a>）。そしてファイルバッファの場合、このデフォルト値が64GBに設定されているので、多くの場合は十分かと思う。</p>
<p>と、いう感じでイケそうな気がしているが、何かおかしい部分があったらツッコミが欲しいです。 v1.0 は buffer 周りの設定が <code>&#x3C;buffer></code> に切り出せるようになったので、そのあたりスッキリ見やすくなっていいですね。</p>
]]></description>
            <link>https://chroju.dev/blog/fluent_1_0_no_logs_would_be_missing</link>
            <guid isPermaLink="false">fluent_1_0_no_logs_would_be_missing</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 13 Aug 2018 13:29:26 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[July Tech Festa 2018 に行って打ちのめされた]]></title>
            <description><![CDATA[<p>初めて <a href="https://2018.techfesta.jp/">July Tech Festa</a> に行ってきた。「インフラエンジニアの夏の祭典」ということで、この手の終日、複数日カンファレンスだと、だいたいどこかしらでいつも「あまりわかりそうな話が無いなぁ」という時間枠が出来てしまうのだけど、今回は常に聴きたい話がいくつもあって、なんだか珍しい気分になれた。</p>
<p>聴いたのは以下のセッション。隅田川花火大会に行くというリア充めいた予定があったので、最後のメルカリさん招待講演を聴かずに切り上げている。</p>
<ul>
<li>ビッグデータと機械学習の狭間で　〜データエンジニアに求められる役割〜</li>
<li>強いインフラが組織を創る</li>
<li>【仕事は楽しい、ですよね？】経験談から語る、「一歩先を行く」ITエンジニアの競争戦略</li>
<li>運用におけるシェルの役割とそのあり方を考える</li>
<li>サーバーやNW機器の構成・設定管理に困ってませんか？簡単に最新状況が把握できるインベントリ収集ツールの紹介</li>
<li>"自律的運用に向けた第一歩" ～運用現場にあふれる情報をデータ化し機械的に学習できる状態に～</li>
<li>AzureのLogAnalyticsでKubernetesを監視してみた</li>
</ul>
<h2>インフラエンジニアという言葉の拡散</h2>
<p>今挙げたセッションの名前を見てもわりと明らかだと思うけど、インフラエンジニアの祭典というとこう、自宅でYAMAHAルーターで云々とか、ラズパイで云々とか、Linuxカーネルハックでどうのみたいのが浮かぶところ、そういうセッションはあまりなかった（ゼロではない）。クラウドファースト、SREの隆盛を受けてと言うべきか、もっと上のレイヤーや運用の話、プログラマブルなインフラ管理の話が多い。</p>
<p>別に2018年なので今更な話ではあるけど、なんというか「インフラエンジニア」という括りがあんまり機能しなくなってきたなという気がする。「インフラやってます」と言っていても、ある人は Go でインフラ管理のツールバリバリ書いていますだったり、ある人は Kubernetes めっちゃやってて ssh とか最近してないッスだったり、ある人は計算リソースめっちゃ必要なので、 Ansible と Serverspec で数千台のサーバーを毎日管理してますだったり、人によってやってること全然違ってきたなというのがある。 <a href="https://speakerdeck.com/onunu/bitugudetatoji-jie-xue-xi-falsexia-jian-de-detaenzinianiqiu-merareruyi-ge">『ビッグデータと機械学習の狭間で』</a> では、機械学習で解析するための DWH やデータパイプラインの管理については、インフラエンジニアに任せるより専門のデータエンジニアを設けるべきだというような話が展開されて、そういうある分野に特化したインフラ担当というのも需要が出てきている。</p>
<p>自分も長らく「インフラエンジニア」を名乗ってはいたのだけど、最近は新卒の頃にやっていたような物理機器に触るような仕事や、DCに入るようなことも無くなってきていて、 VSCode やブラウザ上に開いた GUI コンソールで何かやっていることの方が多く、ちょうど最近 Twitter の bio も「Web Operation Engineer」に肩書を変えた（オライリーの『ウェブオペレーション』から拝借した）。インフラエンジニアです、ではなくて、その中で自分が抱えている問題のポイントは、注力ポイントはどこなのか、もう少しミクロに定義する必要性を感じる。</p>
<h2>自分が実現できなかった理想との対面</h2>
<script async class="speakerdeck-embed" data-id="8fbe8aca7d0d4240b47c6dca9f83f9a7" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>
<p>この『最高のITエンジニアリングを支える守りと攻めの「設計技術」と「SRE」』というセッションは当日聴きたかったけれど別のセッションを聴いていて聴けなくて、今日資料を読んだところ、昨日聴いたどの話よりも打ちのめされた。SRE として日頃何をやってますとか、 1 -> 100 の話は多いけれど、 0 -> 1 のフェーズの話がないのでします、というコンセプトだったらしく、つまりはあまり綺麗ではない状態から、綺麗な状態へどう持っていこうとしたのかが具体的に泥臭く書かれていて、とても良い資料だと思った。あと話の進め方がすごく上手いですね、これ。</p>
<p>実際のところ、ここで言及されているドキュメンテーション、監視基盤の再確立、自動化、インフラのコード化といったあたりは、自分がここ2年ぐらい業務で進めていた内容とわりと符合していて、ただ一方でこの資料に書かれているレベルにまでは到達できていなかったりというところも多く、自分の振る舞いを批判的に見る契機となる資料だった。問題だらけの運用環境をどう改善していくか考えるにあたり、そもそも問題解決とは何かから考えて <a href="https://chroju.github.io/blog/2016/12/17/engineering_problem_solving/">エンジニアの問題解決力とは何か · the world as code</a> というエントリーをまとめたこともあったが、この資料でも「問題とは何か」という点に言及されているなど、とても頷ける場所が多い。そして共感できるからこそ、なぜその帰結が自分とこの方とでこうも違うのかな、というのを自ずと考えさせられて、打ちのめされた。要するにこれは、自分が実現したかった理想そのものとの対面に近かった。</p>
<p>なぜ理想を実現できなかったのか、その原因にここで言及してしまうとちょっと業務に寄りすぎてしまうので、今は避けるけれど、少なくとも「技術力が足りない」みたいな答えではないことは確かで、理想や知識や技術だけで組織や人や仕事を変えていけるわけじゃないですよね、というのはとてもよくわかった。今回、インフラエンジニアという括りのカンファレンスに足を運び、数多のセッションを目にすることでこの話に行き着けたのだと思うので、今回行って本当によかったなと思うし、似た思考の人を探す、見つける、議論するというのもすごく重要だなというのが身に沁みた。</p>
<h2>今後について</h2>
<p>勉強することもいろいろ思い至ったけれど、それ以上にインフラを土壌として戦っている人たちともっと触れ合うべきだなと思ったので、そういうの苦手なんだけどもう少しだけ積極的になってみようと思います。いつかこの場に登壇できたらいいですね。。</p>
]]></description>
            <link>https://chroju.dev/blog/july_tech_festa_2018</link>
            <guid isPermaLink="false">july_tech_festa_2018</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 30 Jul 2018 12:58:46 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[buildersconを契機にOSS活動始めてterraform-provider-awsにcontributeできた]]></title>
            <description><![CDATA[<p>やったぜ。</p>
<p><a href="https://gyazo.com/e7f876b113acd42992052cc2c1fafa5f"><img src="https://i.gyazo.com/e7f876b113acd42992052cc2c1fafa5f.png" alt="Image from Gyazo" width="849"/></a></p>
<p><a href="https://github.com/terraform-providers/terraform-provider-aws/pull/5043">Fix the difference between aws_waf_byte_match_set and aws_wafregional_byte_match_set by chroju · Pull Request #5043 · terraform-providers/terraform-provider-aws</a></p>
<p>Terraform は最近、その本体と各APIを叩く Provider でレポジトリが分離されているんだけど、そのうちの AWS のやつに Contribute した。別にそこまで大した内容の commit でも無いんだけど、なんか嬉しいのでここに至るまでをエントリ起こしておく。</p>
<h2>builderscon tokyo 2017 が契機</h2>
<p>そもそも自分は専門領域インフラなので、プログラミングは本業というわけではなく、まぁそういう言い訳でガッツリプログラミングするような機会からは逃げてたと言えば逃げてきてたし、 OSS 活動はやってみたい思いはあったけどなんか無理だろうなって感じでやらずにいた。 GitHub はもっぱら自分のコードのバックアップ用途というか。</p>
<p>そんな意識を替えた、小さくてもいいからなんか Contribute できないか頑張ってみよっかと思ったのは昨年の <a href="https://builderscon.io/tokyo/2017">builderscon tokyo 2017</a> で聴いたこの発表だった。</p>
<iframe src="//www.slideshare.net/slideshow/embed_code/key/lQIyp731TQqOoF" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/shigemk2/oss-78585757" title="Oss貢献超入門" target="_blank">Oss貢献超入門</a> </strong> from <strong><a href="https://www.slideshare.net/shigemk2" target="_blank">Michihito Shigemura</a></strong> </div>
<p>コード読まずに GitHub に近づかずに OSS 貢献ができるかって言ったらできないわけで、わかんなくてもいいから取りあえず読むとか、ドキュメントの修正だって貢献は貢献だって話だとか、何かしらやれることからやれたらええやんけの始めの一歩をものすごい勢いで押してくれたスライド。わかんないからとか実力がないからという理由で遠ざけてたら一生かかってもできるわきゃないので、じゃあ取りあえず、もう少し GitHub と仲良くするか、とこの頃から思うようになった。昨今はインフラエンジニアだからコード書きませんってのも無いよねって流れだし、どうにかしたかった。</p>
<h2>GitHub と仲良くする</h2>
<p>手始めに始めたのはこのあたりのこと。</p>
<ul>
<li>GitHub で気になったレポジトリにはスターをつけたり Watch したりして動向を追ってみる</li>
<li>GitHub で気になったエンジニアをフォローしてみる（いまだに誰をフォローしたらいいかよくわかってなくてあんまり出来てはない）</li>
<li>フォローと Watch による通知はひとり slack に流して継続的に追う</li>
<li>OSS を使ってて疑問に思う挙動があったら、ググるんじゃなくて docs とソースを読む</li>
<li>GitHub トレンドを見に行く、メールでのトレンド通知も有効化する</li>
</ul>
<p>GitHub に触る機会、レポジトリを見に行く機会をとにかく増やしたのと、気になる挙動を自分でソースを追いかけてみることを心がけた。前者については、世の中本当にいろんなもの公開している人がいるなと知るきっかけになって良かったし、知れると自分でも何か作れないかとか考えるようになった。 GitHub トレンドは案外なんと言うのか、 markdown で書かれたドキュメントだけのレポジトリとかが上位に入っていることも多くて、そんなに頻繁には見なくなってしまったけど。とはいえ自分が初めて Pull Request 出してマージしてもらったのも、ドキュメント系のレポジトリではあった。</p>
<p><a href="https://github.com/zeeshanu/learn-regex/pull/91">Update README-ja.md by chroju · Pull Request #91 · zeeshanu/learn-regex</a></p>
<p>正規表現について簡潔に学べるドキュメントで、日本語訳が一部こなれてなかったのと、英語原本の更新に追いついていなかったので更新した、というだけの PR 。コード書いてねーじゃんという感じだが、そういうのにこだわらず、取りあえずまずは GitHub と仲良くしたかったので、ハードルの低いことからやってみた。</p>
<p>コードを書いて Contribute したのは、 terraforming が初めてだと思う。</p>
<p><a href="https://github.com/dtan4/terraforming/pull/357">Add failover attributes to Route53 record. by chroju · Pull Request #357 · dtan4/terraforming</a></p>
<p>Terraform はよく使っているので、既存リソースの terraform 化ができる terraforming もよく使うのだが、このときは Terraform の方の更新に追いついてない部分に使っていて気付いたので PR した。以前なら誰かが更新してくれるのを待つか諦めるかしていたと思うが、 terraforming であれば数多の AWS リソースそれぞれに対して似たようなコードが存在しているようなツールなので、他のリソース向けに書かれたコードを参考にすれば書けそうだなと思い、手をつけた。コード書いてマージしてもらうのは初めてでめちゃくちゃビビってたのだが、あっさり "LGTM" もらえてびっくりした記憶がある。</p>
<h2>terraform-provider-aws への Contribute</h2>
<p>で、その後もいくつか PR 送ったり、それが難しくてもコードに原因がありそうだなという当たりがついたら issue を投げたりしてきた。 influxDB のバグを直してもらえたのが結構嬉しかった。</p>
<p>冒頭に挙げた今回のマージは Terraform の実質本体みたいなところへのマージで、これまでで一番「やったぜ」という感覚があった。 AWS WAF という文字通りマネージドな WAF サービスがあって、これはリージョンを意識しないグローバルな設定とリージョン別の設定に分かれているんだけど、 API もこれに合わせて AWS WAF, AWS WAFRegional の2種類がある。ただ双方で用意されているメソッドやパラメーターはほぼ同じになっているんだけど、 Terraform では一方のパラメーターは複数形の名前で、もう一方が単数形という微妙な差異が一部で見られる状態になっていた。元の API にはそういう差異はなく、混乱の元になりそうだったので PR した。</p>
<p>最初はパラメーターの名前替えるだけなのでそれほど難しくはなかろうと思い、単数形と複数形の差異全部直すで〜という雑な内容を取りあえず WIP の状態で PR を投げたのだが、すぐにレビューで「パラメーターの名前を替える場合は、古い方のパラメーターも Deprecated で残しておかなくてはならない」とか「君はこれ単数形に統一してくれたけど、複数形の方がよくない？」とか言われて、「うわ深く考えずに PR 投げてもーた……レビュー反映して差異全部直したらとんでもない修正量になるやんけ。。。やっぱまずは1箇所だけ直す形に改めるわ申し訳ねぇ🙏💦」という返信をめっちゃ冷や汗かきながら送ることになった。これを温かく受け止めてもらえたので、なんとかマージまで漕ぎつけられた。</p>
<p>そもそも Terraform が書かれている Go を学び始めたのも今年の春先ぐらいだったので、それがまぁパラメーター名の変更という内容ではあれ、この1,2年頻繁に使っていたツールに貢献する形まで辿り着いたのはガッツポーズものであった。</p>
<h2>やってみるとなんとかなる</h2>
<p>去年の8月から、OSS活動と胸を張って言えるほどではないとはいえそこそこ続けてきて、思うのは案外なんとかなるなということであり、去年見たあのスライドの内容はマジで正しかったなということだ。</p>
<p>いまだに英語については自信がないけど、これまで「お前何言ってんだかわからんのだが？？」とは言われたことがないので、なんとか通じているっぽい。 Google 翻訳様様である。 Contribute するにあたり、膨大なソースコードを全行読む必要はなくて、「これを直したいな」というきっかけからまず当たりを付けてソースを読み、その周辺から徐々に全体へ読んでいくことで、動きは掴める。あと Terraform のような大規模な OSS だと Developer Guide が充実しているので、そちらも併せて読むことでだいぶ理解が捗るし、普段使っているツールがどう動いているのかを知る機会にもなるので一石三鳥ぐらいメリットがあった。あと他の PR とか読めば、どんな感じで書けばいいかとか、どんなコミットメッセージがいいかはわかる。</p>
<p>何かやってみたいけど何したらわかんないなというとき、まずは近付いてみるというのがいいんだと思う。近づき、情報を得て考えることを習慣にしていくうちに、だんだんとリズムが掴めてくる。あとは変に自分でハードル作らずに、小さくてもしょっぱくてもいいから PR 出してみれば、思ったよりもすんなりとマージしてもらえたりする。んで Contributor のマークが付くと、それが転職アッピルになりますぜとかそういうの抜きにして純粋に嬉しい。</p>
<p>builderscon は名前の通り「 builder 」のイベントなわけで、そこに行った甲斐あって builder っぽいことをほそぼそとではあるが始められた。<a href="https://builderscon.io/">今年</a>もめっちゃ楽しみにしてる。</p>
]]></description>
            <link>https://chroju.dev/blog/contributed_to_terraform_provider_aws</link>
            <guid isPermaLink="false">contributed_to_terraform_provider_aws</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 10 Jul 2018 12:02:20 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[開発環境を見直し、dotfilesを更新して、VimからVSCodeへ移行した]]></title>
            <description><![CDATA[<p>開発環境を最近ちょっといろいろ替えたので、軽くまとめてみる。</p>
<h2>dotfiles</h2>
<p><a href="https://github.com/chroju/dotfile">dotfiles</a> を久しぶりにガラッとアップデートした。従来は本当に dotfile を置くことにほぼ特化させていたんだけど、ある程度の開発環境構築も一緒にやれた方が便利だなと前々から思っていたので、構築系のタスク含めて自動化させた。`</p>
<p>どうでもいいけど、 http://dotfiles.github.io/ なんてページがあるのね。いろいろサンプルが載ってて参考になるけど、読みすぎると無駄に最強の dotfiles を求めようとして死ぬやつだこれ。ロゴはオシャレでいい感じ。</p>
<h3>Ansible の採用</h3>
<p>自動化には Ansible を使うことにした。別にシェルスクリプトや makefile でもいいんじゃないかとは思うのだけど、単純なコマンド実行だとやはり冪等性の問題があったりというところで、 Ansible 使ってみても良いのかなと。現在自分自身、 Ansible でごはんを食べているようなところもあるので、普段から使っている方がいいでしょうという理由もある。</p>
<p>任せているのはだいたいが dotfile を配置するタスクで、それ以外だと bash や zsh の git-completion 用のシェルスクリプトを落としてきたり、よく使っている Python や Golang の環境を作るところもやらせている。</p>
<h3>Ansible の macOS 関係モジュール</h3>
<p>Ansible には macOS の構築に使えるモジュールもいくつか用意されているのだが、今回はいずれも使っていない。</p>
<p>1つは <a href="https://docs.ansible.com/ansible/latest/modules/homebrew_module.html">homebrew</a> で、そのものズバリ Homebrew のパッケージインストールなどを行える。しかし、 <code>brew install</code> を行いたいとき常に Ansible Playbook を実行するかと言うとそうではないだろうという気がしていて、それであるならば Playbook 内ではなく Brewfile で必要パッケージを管理した方が良いなと思い、 Ansible からは <code>brew bundle</code> を実行させるにとどめている。</p>
<p>もう1つは <a href="https://docs.ansible.com/ansible/latest/modules/osx_defaults_module.html">osx_defaults</a> と言うもの。macOS には <code>defaults</code> という各種設定を触れるコマンドがあって、これを叩いてくれる。まぁ使って悪いことはないと思うのだが、 defaults 自体あんまり使ったことがなくて、改めて学習したところでそこまで便利とも思えないので使わず仕舞いになっている。なので各種設定の変更はあくまで GUI から実行している。</p>
<h2>Visual Studio Code</h2>
<p>これまでは何を書くにも Vim を使っていたんだけど、 最近 Visual Studio Code を使い始めていて、スクリプトやコードを書くときはこちらをメインに替えている。</p>
<p>別に Vim が嫌いになったとかでは全然なくて、メモ用途やちょっとしたファイルの編集には引き続き Vim を使っているし、今このブログを書いているのも Vim である。が、 dotfiles を整理したタイミングでちょっと vimrc のカスタマイズを始めてみたところ、なかなかこれを最新最高の状態に維持するコストってしんどいものがあるなと今更ながら気付いてきて、特に Go を書くようになって、 IDE 的な機能が欲しくなったときになんだかんだ Vim で全部頑張らなくてもいいんじゃないかなと思うようになってきた。要は快適に文章やコードを書ける環境がほしいわけであって、それを実現するのが Vim であろうと VSCode であろうと、手段は問わない。Vim キーバインドは大好きだけど、別にツールの信者ではないので。</p>
<p>信者ではないのでと言った手前ではあるが、実際のところはかなり Vim の使用感に近づけて VSCode を使っている。<a href="https://github.com/VSCodeVim/Vim">VSCodeVim</a> は当たり前のように使っているとして、もともと <a href="https://github.com/itchyny/lightline.vim">lightline.vim</a> を使っていたので、VSCode のステータスバーも lightline と同じ色で変わるようにカスタマイズしてみている。意味があるかと言えば、たぶんあんまりない。気分の問題。</p>
<p><a href="https://gyazo.com/af0b63cfb02f42f4021cf17d4bee9a25"><img src="https://i.gyazo.com/af0b63cfb02f42f4021cf17d4bee9a25.png" alt="https://gyazo.com/af0b63cfb02f42f4021cf17d4bee9a25" width="400"/></a></p>
<p>あとキーバインドもいくつか vimrc と同じものを採用していて、これら設定も全部 dotfiles に入れてある。</p>
<p>VSCode 、 TL で便利便利と聞いてはいたけれど、特に git やターミナルとの連携がとても便利で、 Vim でもプラグインを使って同じことができるとはいえ、ほぼ何もしなくても完成度の高い状態で使えるという体験は本当に素晴らしい。必要なプラグインも勝手に「インストールしません？」ってサジェストしてくれるし。</p>
<h2>開発環境としての macOS</h2>
<p>ところで最近、 macOS のバグが多発してたり開発状況が微妙だったりで、 macOS を捨てて Thinkpad あたりでデスクトップ Linux を使うのがにわかに流行っている気がする。デスクトップ Linux は今でも GPD Pocket を Ubuntu で動かしているし、ちょっと前まで Arch Linux を使っていたりもしたんだけど、まぁやっぱりメンテナンスコストはある程度必要で、ただ、それが楽しいのでやれてたという記憶はある。今は macOS をメインに据えてるし、これを Linux に変えるつもりはあんまりないんだけど、その理由としては主に2つある。</p>
<p>1つは開発用PCと普段遣いのPCを分けるのがあんまり好きではないということ。開発者としてよろしいことではない気がするんだけど、音楽をリッピングするためにPCを立ち上げて、その間にまた別のPCを立ち上げて開発をするとか、そういうのがあんまり好きじゃない。Linuxでもエンターテイメント系のソフトウェアはそれなりに揃ってはいると思うのだが、 macOS から完全に移行できるかというと厳しいかなという思いがある。</p>
<p>もう1つは、よくある「Linux開発者ならUNIXベースであるmacOSではなくちゃんとLinuxを使うべきでは」という話の反論っぽいところで、Linux 使いたければ Vagrant で EC2 や VPS を上げてしまうので、あんまりローカル環境の OS が Linux であることにこだわりがないということ。手元では UNIXコマンドがそれなりに使えればいいし、自分はだいたい RHEL系のOSをよく使うので、 デスクトップLinuxとして Ubuntu を手元で使ったところであまり意味がない（Fedora使えばいいのかもしれんが、クライアントOSとしてはそんなに好きじゃない）。</p>
<p>ので、特に現状 macOS で致命的には困っておらず、まぁいいかみたいになっている。とはいえ今後どうなるかはわからないので、何年か後には Thinkpad 使っているかもしれないけど。 Arch Linux とタイル型ウィンドウマネージャーの使い勝手は好きなので、使ってみたい思いはあるし。</p>
]]></description>
            <link>https://chroju.dev/blog/update_dotfiles_with_ansible</link>
            <guid isPermaLink="false">update_dotfiles_with_ansible</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 01 Jul 2018 07:06:10 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Nature Remo API で遊んだ]]></title>
            <description><![CDATA[<p>Amazon Echo dotに続いてGoogle Home miniも安売りに釣られて買ったので、せっかくだしVUI (Voice User Interface) の醍醐味であるはずの家電操作もやってみたくなって <a href="https://nature.global/">Nature Remo</a> を買った。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B06XCQFP96/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/31MkeLD6o3L._SL160_.jpg" alt="Nature Remo" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B06XCQFP96/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Nature Remo</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 18.06.11</div></div><div class="amazlet-detail">Nature, Inc. <br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B06XCQFP96/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>ちなみにこれ書いてるときに気付いたけど、廉価版の mini ってのも近々出るらしいです。</p>
<h2>Nature Remo</h2>
<p>赤外線信号を学習させて使えるスマートリモコン。Wi-Fiに繋げてインターネット経由でAPIを叩く形で操作する。専用のスマートフォンアプリからリモコン感覚でも使えるし、IFTTT Channel化されているので、他サービスと連携させていろいろやったりもできる。あとGoogle HomeやAlexaとも直接連携できるようになっている。</p>
<p>最近この手のIoT家電系製品は他にもあると思うけど、正直あまり比較して買ってはいないので、比較優位があるかはわからない。どうもIRKitの後継のようだったので、実績を鑑みてある程度信頼は置けそうだというのと、TLでちらほら買っているソフトウェアエンジニアを見かけたという、ただそれだけの理由で選んだ。</p>
<h2>API開放がよい</h2>
<p>なので他製品での状況はわからないが、Nature RemoはAPIが開放されているのがすごくいい。API仕様はSwaggerで公開されているのもポイントが高い。</p>
<p>http://swagger.nature.global/</p>
<p>やろうと思えば実質なんでもできる。手始めにslackからスラッシュコマンドでエアコンを点けられるようにしてみた。OFFにするコマンドをまだ実装していないので、滅多矢鱈と打てないんだけどイイ感じ。</p>
<p><a href="https://gyazo.com/ada116f88ba891fa63ecf9e42258143e"><img src="https://i.gyazo.com/ada116f88ba891fa63ecf9e42258143e.png" alt="https://gyazo.com/ada116f88ba891fa63ecf9e42258143e" width="601"/></a></p>
<p>あとこれは買ってから気付いたのだが、Nature Remoにはセンサーが内蔵されていて、温度・湿度のデータもAPI経由で取得できる。機器の設置場所によっても変動する値だし、全幅の信頼を置いていいデータではないかもしれないが、自室の温度・湿度の状態をモニタリングするのは興味があったので、influxDBへ突っ込んでGrafanaでグラフにしてみている。家に帰って窓を開けて、お茶飲みながらグラフ眺めてると結構如実に気温が下がっていったりして面白い。</p>
<p><a href="https://gyazo.com/cdead523411083bb6481e577cb1ebe98"><img src="https://i.gyazo.com/cdead523411083bb6481e577cb1ebe98.png" alt="https://gyazo.com/cdead523411083bb6481e577cb1ebe98" width="1088"/></a></p>
<p>APIでセンサー情報をGETすると、返ってくるjsonはこんな感じで、Swaggerには書かれていない "il" という項目があるんだけど、照度センサーも内蔵しているらしいのでおそらくは "illuminance" かな？と思っている。ちなみに今のところ照度の取得はアプリからもIFTTTからも出来ないので、今後拡張されるのかもしれない。ついでに人感センサーもあるらしいので、そちらの情報も取得できるようになると嬉しい。</p>
<pre><code>[
  {
    "name": "Remo",
    "id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "created_at": "2018-04-28T12:12:33Z",
    "updated_at": "2018-06-11T13:18:55Z",
    "firmware_version": "Remo/1.0.62-gabbf5bd",
    "temperature_offset": 0,
    "humidity_offset": 0,
    "users": [
      {
        "id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        "nickname": "chroju",
        "superuser": true
      }
    ],
    "newest_events": {
      "hu": {
        "val": 60,
        "created_at": "2018-06-11T12:43:29Z"
      },
      "il": {
        "val": 13.8,
        "created_at": "2018-06-11T13:19:09Z"
      },
      "te": {
        "val": 25.39,
        "created_at": "2018-06-11T07:41:56Z"
      }
    }
  }
]
</code></pre>
<p>やろうと思えばMackerelで気温を監視して、一定の値になったらWebhookからエアコン起動みたいなこともできると思うけど、大惨事になりそうな予感（閾値近辺で値が行ったり来たりしてON/OFFしまくるとか）があってやってはいない。まぁ自室だから別に大惨事でもいいか。やったら面白そう。</p>
<p>ちなみにAPIを叩くのはGoでやりたかったので、ライブラリ作ろうかなと思ったら既にあったのでありがたく使わせていただいている。何か気付いたことがあればIssueなりPRなり送れたら送りたい。</p>
<p><a href="https://github.com/papix/go-nature-remo">papix/go-nature-remo: API Client for Nature Remo (Golang)</a></p>
<p>とにかく「家電にAPIが生える」という感覚は想像以上に楽しかったので、いろいろ便利にしていきたいです。こうなると逆に、遠隔操作にBluetoothを使うPS4が、本来赤外線操作より便利だったはずなのに、不便に思えてくるのが面白い。</p>
]]></description>
            <link>https://chroju.dev/blog/play_with_nature_remo</link>
            <guid isPermaLink="false">play_with_nature_remo</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 11 Jun 2018 13:08:35 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[AWS Summit 2018と大規模企業Confの回り方について]]></title>
            <description><![CDATA[<p><a href="https://www.awssummit.tokyo/tokyo/">AWS Summit Tokyo 2018</a> に行ってきた。2年ぶり2回目になるけど、前回行ったときより格段に人が増えたように思う。というか、セッションに申し込む段階から早々に満席のセッションが続出していて、椅子取りゲームっぷりがハンパないことになっていた。さすがにそろそろ新高輪プリンスでやるのはキャパ的に限界じゃないかなと思う。</p>
<p>内容的な話はちょっと脇に置いておいて、そんな椅子取りゲームをクリアして、ギュウギュウに人が詰め込まれた会場に行ってまで、大規模な企業カンファレンスに行く意味はなんだろうとふと考える。大規模な企業カンファレンスというのは、AWS Summitのように1つの企業が自社製品、自社サービスに関するカンファレンスイベントを、複数日とは言わずとも、セッションやブーススペースを大量に設けて開催するようなイベントを指す。国内だと自分が行ったことあるのはVMwareのvForumぐらいなんだけど、まぁ国内の大手ITベンダーなどもやっているんではなかろうか。有料だけどde:codeもその枠には入る。</p>
<p>この手のイベントは自社製品の広告という意味を当然帯びているので、対象もデベロッパーだけではなく、ユーザー側も含まれている。AWS Summitも参加者の半数以上はスーツの方だったように思う。なのでセッションもきちんと選ばないとユーザー向けの他社導入実績紹介や、抽象的なクラウドの有効性、AWSサービスの紹介にとどまってしまう場合が少なくなく、サービスを使う側として身のあるセッションを選ぶのが案外難しい。今回だとデベロッパー向けセッションでは任天堂のプッシュ通知実装のセッションがだいぶ盛り上がったらしい。こういうのをきちんと押さえられるようなセッションの選び方が求められる。</p>
<p><a href="https://twitter.com/i/moments/1001726261884944384">「Nintendo Switch （TM） 向けプッシュ通知システム『NPNS』」</a></p>
<p>セッションの選び方に失敗すると、下手すればあんまり実入りがないまま終わったりもする。またデベロッパー向けのイベントと違って、いわゆるネットワーキングのための時間などもあんまり設けられていないことが多い（今回はAWS認定資格者限定でボウリングやってたらしいけど。なんでボウリングなのかは謎）ので、リアルイベントで重視される、横のつながりを広げるようなこともあまり期待はできない。ただ、だからといって得られる情報の価値が薄いと言ってしまうと言い過ぎで、企業主催のイベントなので、その企業が今何を推そうとしているのか、戦略を窺い知るには非常に有意義な機会だと思っている。</p>
<p>一昨年に参加したときだとAWS Lambdaのローンチから間もなかったこともあり、サーバーレスに関するセッションが多いという印象を受けた。今回に関してはECSのセッションが少し多くて、また基調講演の中でも、サーバー管理不要なコンテナサービスであるFargateの東京リージョン対応がアナウンスされるなど、世情も踏まえてかコンテナに軸足を置くような印象があった。自社のサービスが、ある企業の恩恵を多大に受けた構成になっている場合、その企業の主催イベントに行って、中の人が考えていることに直に接しに行くことは、デベロッパー向けのイベントとはまた違う意味がある。通常の技術者イベントが参加者同士の交流に重きを置かれる一方、こちらは主催側とのコミュニケーションと捉えた方がいいんじゃないかなと。ただ、とはいえそんなに話せる機会があるでもないんだけど。セッション後の質問タイムか、ブースエリアでつかまえるぐらいかな。</p>
<p>こういったことを踏まえて、AWS Summit 2回目の出席にして得たまわり方のコツとしてはこんなところか。</p>
<ul>
<li>基調講演は聴いておいた方がいいが、人が多すぎるしユーザー向けの話も多いので、ライブビューイングでも十分。</li>
<li>セッションはなるべくデベロッパー向けのものを押さえる。</li>
<li>個々のセッションで情報を得つつ、全体的な潮流のようなものを押さえる。</li>
<li>可能であれば主催側の「中の人」をつかまえて話を聴く。</li>
</ul>
<p>しかしそれにしても人が多すぎて効率はよろしくないというのは確かなので、もうちょい人の捌き方が改善されないのであれば、来年行くかどうかは微妙だなぁと思う次第。</p>
]]></description>
            <link>https://chroju.dev/blog/aws_summit_tokyo_2018</link>
            <guid isPermaLink="false">aws_summit_tokyo_2018</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 04 Jun 2018 12:19:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『Effective DevOps』と『エンジニアリング組織論への招待』を読んだ]]></title>
            <description><![CDATA[<p>ITエンジニア組織における組織論について書かれた本が同時期に2冊出ていたので、それぞれ読んでみた。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774196053/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/51zMvVL4MeL._SL160_.jpg" alt="エンジニアリング組織論への招待 ~不確実性に向き合う思考と組織のリファクタリング" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774196053/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">エンジニアリング組織論への招待 ~不確実性に向き合う思考と組織のリファクタリング</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 18.05.13</div></div><div class="amazlet-detail">広木 大地 <br />技術評論社 <br />売り上げランキング: 1,031<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774196053/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873118352/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/51hSE7AENQL._SL160_.jpg" alt="Effective DevOps ―4本柱による持続可能な組織文化の育て方" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873118352/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Effective DevOps ―4本柱による持続可能な組織文化の育て方</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 18.05.13</div></div><div class="amazlet-detail">Jennifer Davis Ryn Daniels <br />オライリージャパン <br />売り上げランキング: 8,495<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873118352/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<h2>エンジニアと社会学</h2>
<p>頻繁に引用されるトム・デマルコの言葉に、以下のものがある。</p>
<blockquote>
<p>実際のところ、ソフトウェア開発上の問題の多くは、技術的というより社会学的なものである。（トム・デマルコ, ティモシー・リスター『ピープルウェア』）</p>
</blockquote>
<p>実際コンピュータの世界にそこそこの年数身を置いていると、この言葉に対して徐々に実感が伴ってくる。技術的な解というのは、この情報過多の時代、すでに誰かがどこかへ書き記してくれていることが少なくないし、単純に技術的な妥当性だけを突き詰めれば、理想的なシステムの形は自ずと定まってくる。でもその解が実際に適用できるとは限らない場合が多い。それは予算的な都合であったり、社内の開発プロセス的に困難があったり、社内に反対勢力がいたり、もっとシンプルに技術者のレベルが追いついていないということもあり得る。技術的に楽しいことをただやっていればよかった若い時代を抜けて、徐々に自分のやりたいことをやろうとして、壁にぶつかるようになり、人はマネジメントという路線を意識せざるを得なくなるのだろうな、などと最近よく思う。</p>
<p>とても脱線した話をすると、自称理系による安直な「文系批判」というのが自分は非常に苦手だ。上記のようなことを考えたとき、自然科学的な課題を解決するにあたっても、社会科学的なアプローチが必要とされる場面は多いからだ。理系文系というのは二項対立ではないし、どちらか一方だけに特化することが、必ずしも高い生産性につながるわけではない。この2冊の書籍が出るあたりからして、昨今は社会科学の必要性というのも強く意識されるようになってきているのだとは思うが。</p>
<h2>Effective DevOps</h2>
<p>DevOpsとは何か？と言われると、それは特定のツールではなくて、開発と運用、引いてはそれ以外のチームも含めたスムーズな連携によるシステム運営文化を指す、というのはわかるのだが、正直バクっとしてとらえどころのない言葉だなとは長年思っている。</p>
<p>その点この本がすごいのは、そのとらえどころのない「文化」面に着目して、具体的実践を300ページ以上もの分量で書いていること。「ツール」の章もあるにはあるが、技術的な話ではなくツールの選定方法や、ツールが文化に対して与える影響について書かれている。もちろんこの本に書かれたことが唯一無二の正解ではない、というのは文中でも断られているが、DevOpsとはどうあるべきか、という疑問への最適解に近いものが集まっているように感じた。とにかくボリューミー。</p>
<p>本書は先の「ツール」の他に、主に「コラボレーション」「アフィニティ」「スケーリング」という計4つの章に分かれている。コラボレーションは複数人の協力の方法について、アフィニティはチーム間の関係構築について、スケーリングは組織の成長や縮小の観点について述べており、これはそのまま組織の成熟プロセスに該当しそうなので、各々の組織の状態に合わせて参照していけばよさそう。</p>
<h2>エンジニアリング組織論への招待</h2>
<p>こちらの本はDevOpsよりもう一歩手前というか、そもそも会社組織においてエンジニアリングを行うにあたり、何が問題として存在していて、それを如何にして解決すればよいのかという、そもそも論に焦点が当たっている。 <a href="http://blog.shibayu36.org/entry/2018/03/27/193000">「エンジニアリング組織論への招待」はいろんな立場の人に読んで欲しい - $shibayu36->blog;</a> という書評記事も読ませてもらったが、IT組織内の「いろんな立場」を超えて、IT以外の現場ですら役立ちそうに思える。</p>
<p>本書は副題通り、エンジニアリングの目的を不確実性＝定まっていないこと、わからないこと、乱雑な状態を効率よく解消していくことにあると定める。この定義がすごくしっくりきて、例えば本書の中でも触れられているアジャイル開発などは、不確実性を反復して徐々に徐々に削減していくプロセスと捉えられる。</p>
<p>この「不確実性の解消」という言葉で全体をまとめたことで、とても見通しの良い1冊になっているし、エンジニアリングに従事するにあたり、我々は一体何をしているのか？という日々の迷いにも指針を与えられた気分になる。そして不確実性へ向き合うにあたり、自分が最も感銘を受けたのは以下の一文。</p>
<blockquote>
<p>難しいのは、問題を正しく認知することです。(p.33)</p>
</blockquote>
<p>そう、まさにそれである。問題解決のための技術導入をしたところで、その技術が解決するべき問題を解決してくれなくては意味がない。本書では「問題の正しい認知」のために、認知バイアスの解消などが解説され、そして具体的な組織における不確実性を、通信（コミュニケーション）、方法（スケジュールの見積）などいくつかの側面から紹介している。</p>
<h2>正しい問題解決のための組織をつくる</h2>
<p>組織的な課題にぶつかったとき、2冊は補完的に使えるように思う。『エンジニアリング組織論への招待』は、組織の問題をまず正しく認知することに活用できる。『Effective DevOps』はその問題を実際解決するにあたり、DevOpsという観点から、組織をどういう方向へ変えていけばいいかを示してくれる。</p>
<p>自分はまだ実際にマネジメントの立場にいるわけではないので、まずは自らの認知をリファクタリングし、問題発見と解決のスキルを上げることから始めていきたい。</p>
]]></description>
            <link>https://chroju.dev/blog/engineering_organization_theory_and_effective_devops</link>
            <guid isPermaLink="false">engineering_organization_theory_and_effective_devops</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 13 May 2018 10:35:05 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[TerraformドキュメントをCLIで読むtfdoc v0.1.0をリリースした]]></title>
            <description><![CDATA[<p>先々月 <a href="https://chroju.github.io/blog/2018/03/25/create_terraform_helper_tool_with_go/">Terraformドキュメントをコマンドで見るツールをGoで作る · the world as code</a> で書いたツールがようやく形になったのでリリース扱いにした。</p>
<p><a href="https://github.com/chroju/tfdoc">chroju/tfdoc</a></p>
<p>指定したTerraformリソースについて、ドキュメントとスニペットをコマンドライン上で確認できるようになっている。そもそもリソース名がわからないという場合もあると思うので、 <code>--list</code> オプションでリソース名の一覧を出せるようにもした。まだまだ改善の余地はあるんだけど、取りあえず一通りやりたかったことはできるようになった。</p>
<h2>OSSをちゃんとリリースする</h2>
<p>OSSを「ちゃんと」リリースしたことがなかったので、ちゃんとした体裁を整えようとしてみた。</p>
<p>具体的には、今回初めてCoverallsを使ってテストカバレッジをREADME.mdへ表示している。自分は本職インフラで、プログラミングは必要にかられないとやることはないし、そもそも業務で誰かからプログラミングを習った経験もない。それを言い訳にするつもりはないのだけど、ソフトウェア開発の基本的なプラクティスを多分ちゃんとわかっていない。そのうちの一つとして「テストを書くのが苦手」というのがあり、これを解消したいと常々思っている。</p>
<p>幸いGoはテストを書くための機能が最初から内包されていて、これまで経験した言語の中ではとてもテストが書きやすく感じている。まだまだカバレッジは低いのだけど、今後100％へ近づけるためにテストを増やして、追加機能をリリースするときはTDD的な開発ができるようにするつもり。あと正直Coverallsの使い方もちゃんと理解してはいなくて、 <a href="https://docs.coveralls.io/go">Go | Coveralls Docs</a> を読んで書いたとおりにやっただけという感じなので、そこも学び直したい。</p>
<p>もう一つ、GitHub Releasesもちゃんと使ったことがなかったので、今回初めて使ってみた。 <code>git tag</code> の理解すら怪しいぐらいだったんだけど、こちらはそんなに難しい話でもないので、ちゃんと使えていると思う。</p>
<h2>活躍したパッケージ</h2>
<p>tfdocを作るにあたり、Goのパッケージを様々使っている。ロジック的にはスクレイピングが中心になっているので、goqueryが肝になっているけれど、どちらかと言えば補助的な部分で感謝したいものが多い。</p>
<h3>gox</h3>
<p><a href="https://github.com/mitchellh/gox">mitchellh/gox: A dead simple, no frills Go cross compile tool</a></p>
<p>素でググると仮想通貨関連の話しか出てこない名前。Goにおけるクロスコンパイルをコマンド一発で一度に実行してくれるのですごくビルドが楽になる。開発しているのは、Goで様々なOSSを生み出しているHashiCorpのmitchellh氏ということで、なるほど頷ける。使い方もすごくシンプルで素晴らしい。</p>
<h3>ghr</h3>
<p><a href="https://deeeet.com/ghr/">ghr - Easy to ship your project on Github to your user</a></p>
<p>GitHub Releasesへのファイルアップロードをコマンド一発で実行するツール。これもGoによるソフトウェア開発にあたり、クロスコンパイルした複数のバイナリをアップロードするために作られたもののようで、goxとの相性がよくて最高。</p>
<p>tfdocではCircleCIでテストとビルド、デプロイを任せることにしているので、goxとghrはCircleCIの中で自動実行させている。便利。</p>
<ul>
<li><a href="https://moznion.hatenadiary.com/entry/2016/11/16/234139">golangで書いたツールをCircleCI上でビルドしてその成果物をGitHub Releasesにリリースする - その手の平は尻もつかめるさ</a></li>
</ul>
<h2>今後の予定</h2>
<p>まだ完成とは思っていなくて、先のテストを書くというのもそうだし、いろいろ改善はしたい。</p>
<p>わかっていないことの一つに、コマンドのオプションの中に「あるオプションと一緒に使わなければ有効にならない」ものがあって、これをどうしようか考えあぐねている。現状はその条件を満たさず使った場合、そのオプションは無視するようにしているのだけど、できれば内部の制御として「このオプションはこのオプションと一緒に使う必要がある」というのを実装しておきたい。今回コマンドラインオプションには <a href="https://godoc.org/github.com/spf13/pflag">pflag</a> を使っていて、これはGo標準のflagパッケージとほぼ同様の動作をするので、以下の記事あたりが参考になるかもとは思っている。</p>
<p><a href="https://blog.rapid7.com/2016/08/04/build-a-simple-cli-tool-with-golang/">Building a Simple CLI Tool with Golang</a></p>
<p>あとは色付けたり、太字を使ったり、出力をもう少し工夫して見やすくしたい。自分で見てても現状のドキュメントは正直見づらい。スニペットの方も <code>terraform fmt</code> 実行時と同様のフォーマットになるよう整形したい。このツールを足掛かりに、Goの知識、ソフトウェア開発の知識をもっと深めていこうと思う。</p>
]]></description>
            <link>https://chroju.dev/blog/release_tfdoc</link>
            <guid isPermaLink="false">release_tfdoc</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 05 May 2018 04:33:36 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Ansible Roleの継続的自動UpdateについてLTした]]></title>
            <description><![CDATA[<p><a href="https://gyazo.com/510241fc62c4497af3a35142fe5ca5ed"><img src="https://i.gyazo.com/510241fc62c4497af3a35142fe5ca5ed.png" alt="https://gyazo.com/510241fc62c4497af3a35142fe5ca5ed" width="600"/></a></p>
<p>5分間のLTしてこんなクールなタンブラーが貰えるなんて、RedHat社は素晴らしい会社だと思います。ちょっとびっくりした。</p>
<p><a href="https://ansible-users.connpass.com/event/84907/">Ansible Night in Tokyo 2018.04</a>でLTをしてきた。なんだか最近inputもoutputもパッとしてない感じがしたので、「そうだ！　LTしよう！！！」とほぼ思いつきで。自身3回目なんだけど、RedHatでAnsibleの話をするってのはちょっと日和った。TL見る限りだと好評っぽかったのでありがたい限りでした。</p>
<script async class="speakerdeck-embed" data-id="911e623710df4b10bd00ef7509d53574" data-ratio="1.37081659973226" src="//speakerdeck.com/assets/embed.js"></script>
<p>テーマはAnsible Roleの継続的自動更新。Ansibleにはプログラムのパッケージ（RubyGemsとかpipとか）みたいな感じで、Ansible Roleという単位にコードをまとめて再利用する仕組みがある。自分もよく使うのだけど、このRoleに更新をかけたとき、それをimportしている各Playbook上で、バージョンの追随をするのが結構面倒で、みんなどうしてんだろうという思いもあり話してみた。</p>
<p>この手の話はRuby界隈でも「定期的なbundle updateをいかに実行するか」という話がよく聞かれたり、ソフトウェア開発分野でもポピュラーな課題っぽかったので、そちらをいろいろ参考にした。結果としてCIで回しましょうという、まぁそうだよねという結論に至っている。</p>
<p>難題は実装部分で、RubyGemsであれば <code>bundle outdated</code> という最新ではないgemを出力するコマンドがあったりするんだけど、Ansible Roleを管理する <code>ansible-galaxy</code> コマンドには「更新を確認する」ための機能はない。なので少し変則的なのだが、</p>
<pre><code class="language-yaml:requirements.lock.yml">- src: hoge.fuga
  version: 1.0.0
</code></pre>
<p>という、入れたいバージョンをロックしたrequirements.lock.ymlと、</p>
<pre><code class="language-yaml:requirements.yml">- src: hoge.fuga
</code></pre>
<p>というバージョンを記述していないrequirements.ymlを用意することにした。 <code>ansible-galaxy install</code> はバージョン指定無しで実行すると最新を引っ張ってくるので、前者と後者で入るRoleのバージョンに差異があれば「更新あり」と判断できるようになる、という話。明らかにワークアラウンド、という感じなので、他にもっとスマートなやり方をしている人がいれば教えてほしいところ。これに限らずなのだが、Infrastructure as Codeにソフトウェア開発のプラクティスを適用できる、というのはその通りなのだけど、それが実際どう実装するべきなのだという情報をもっと知りたい。</p>
<p>ちなみにLTは1年以上ぶりだったし経験ほとんどないので、上のスライド見て分かる通り明らかに詰め込みすぎで、思いっきり時間オーバーするしアレでした。しかしフィードバックも貰いやすいし、他の人のLTも参考になるし、もっとやっていきたいですね。</p>
]]></description>
            <link>https://chroju.dev/blog/lt_continuous_update_ansible_role</link>
            <guid isPermaLink="false">lt_continuous_update_ansible_role</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 28 Apr 2018 01:32:32 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[都内の図書館でコンピュータ書を読む]]></title>
            <description><![CDATA[<p>たまたま見かけたのだけど、</p>
<blockquote>
<p>ぼくは公立の図書館にずっと通ってたけど、情報系の本は充実してなくて、エクセル入門みたいな感じだった。情報系の学部がある大学に入ったところ、大学の図書館は10万冊くらいだけど、情報系の本が充実しててよかった。
<a href="http://blog.sushi.money/entry/2015/06/14/092519">本 - hitode909の日記</a></p>
</blockquote>
<p>確かに公立図書館で情報系、コンピュータ書を見かける機会は少ない。コンピュータ書は結構お値段がする場合も多く、また未知の分野に挑むときは大量の書籍をザッピングしたいこともあるので、一時期自分もコンピュータ書が多く置かれた図書館を探した時期があった。結果は実際それほど芳しくはなかったのだけど、いくつか良い場所もあったので紹介してみようと思う。</p>
<h2>東京都立中央図書館</h2>
<p>広尾の有栖川宮記念公園に併設された大きめの図書館。自分が探した中では、ここが抜きん出て充実していて、古い本から新しい本まで結構広い範囲のコンピュータ書が並べられている。最近の本で具体例を出すと、『みんなのGo言語』『SRE サイトリライアビリティエンジニアリング』『テスト駆動開発』『大熱血！アセンブラ入門』なんかもある。古いところだと、閉架にはなるが『それがぼくには楽しかったから』のような名著も置かれている。</p>
<p>また、ここは個人貸出を行なっていない＝館内での閲覧のみOKという関係上、閲覧席が充実しているのもポイントが高い。コンセント付きの座席もそこそこ数があるし、館内には東京都が提供する無料のWi-Fiがあって、インターネットも快適に使える。図書館は当然では在るが本を読むのが主目的なので、騒音を嫌ってPCを使えないような場所もあるが、ここはガッツリ勉強目的で使えるのが助かる。実際、自然科学のフロアに行くと、本を山積みにして勉強目的で来ているっぽい人も少なくない。自分も最近は、予定のない週末は結構高い確率でここにいる。</p>
<p>あと余談っぽくなるけど、食堂のごはんが結構おいしい。以前まではいわゆるお役所のごはんという感じで、取り立てて食べたいってこともなかったが、半年ぐらい前に新しい業者が入って一新された。</p>
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-permalink="https://www.instagram.com/p/BeevyiJh-Wj/" data-instgrm-version="8" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:48.98148148148148% 0; text-align:center; width:100%;"> <div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAMUExURczMzPf399fX1+bm5mzY9AMAAADiSURBVDjLvZXbEsMgCES5/P8/t9FuRVCRmU73JWlzosgSIIZURCjo/ad+EQJJB4Hv8BFt+IDpQoCx1wjOSBFhh2XssxEIYn3ulI/6MNReE07UIWJEv8UEOWDS88LY97kqyTliJKKtuYBbruAyVh5wOHiXmpi5we58Ek028czwyuQdLKPG1Bkb4NnM+VeAnfHqn1k4+GPT6uGQcvu2h2OVuIf/gWUFyy8OWEpdyZSa3aVCqpVoVvzZZ2VTnn2wU8qzVjDDetO90GSy9mVLqtgYSy231MxrY6I2gGqjrTY0L8fxCxfCBbhWrsYYAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div> <p style=" margin:8px 0 0 0; padding:0 4px;"> <a href="https://www.instagram.com/p/BeevyiJh-Wj/" style=" color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;" target="_blank">都立中央図書館の食堂、とてもおいしくなった。今日は青森県十和田市のバラ焼きをいただいたが、しかし肉量すごくないか。</a></p> <p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">@<a href="https://www.instagram.com/chroju/" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px;" target="_blank"> chroju</a>がシェアした投稿 - <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2018-01-28T04:52:53+00:00"> 1月 27, 2018 at 8:52午後 PST</time></p></div></blockquote> <script async defer src="//www.instagram.com/embed.js"></script>
<p>これはいつぞやの週替りメニュー、十和田のバラ焼き定食。定食は1000円近くするのでお高めではあるが、野菜もほどほどに取れて嬉しい（そして肉はめっちゃ多い）。これを食べてから、カップ自販機に入っている<a href="https://www.apex-co.co.jp/wp/?news=%E3%81%AA%E3%81%AA%E3%82%84%E3%81%AE%E6%8A%B9%E8%8C%B6%E3%83%A9%E3%83%86%E3%81%8C%E9%A3%B2%E3%82%81%E3%82%8B%E5%A0%B4%E6%89%80%E3%81%AF%E3%81%93%E3%81%93%EF%BC%81">ななや監修の抹茶ラテ</a>を飲んで午後の気合を入れるのがお気に入り。</p>
<h2>千代田区立日比谷図書文化館</h2>
<p>日比谷公園のなか、日比谷公会堂の隣にある図書館。ここは都立中央には劣るものの、オライリー専用の棚が置かれていて、オライリーに限定すると非常に品揃えがいい。もう絶版になっているような本でも普通に開架に置かれていたりもする。『ウェブオペレーション』という本がとても好きなのだけど、ここで初めて出会って惚れて、後から絶版と知って都内を探し回って頑張って入手した経緯がある。</p>
<p>こちらは都立中央と違って、個人貸出も行っている。そして、特に千代田区に住んでいたり、働いている必要はなくて、誰でも貸出カードを作れる。税金？？？って感じで、この恩恵を自分は何を対価に得ているのかわからないんだけど、分厚いオライリーを借り出してじっくり1週間読めるのはすごく助かる。</p>
<p>こちらもサービス面の充実はあって、地下にPRONTOがある。PRONTOに本を持ち込んでもいいし、ちょっと怖くて自分はやったことがないが、PRONTOのコーヒーを閲覧エリアに持ち込んでもいいらしい。あとは言わずもがな日比谷公園なので、ロケーションとしては最高。野外音楽堂でライブやってると、めっちゃ音が入ってくるのが玉に瑕ではある。</p>
<h2>本を買う場合</h2>
<p>ついでなので、都内でコンピュータ書を買う場合だけど、自分は以下をよく使う。</p>
<ul>
<li>丸善本店</li>
<li>ジュンク堂書店池袋本店</li>
<li>書泉ブックタワー</li>
</ul>
<p>特にジュンク堂書店池袋本店の品揃えは本当に素晴らしい。先日はてブでも話題になっていたけれども。</p>
<p>関連 : <a href="https://geek-out.jp/column/entry/2018/02/22/110000">ジュンク堂書店池袋本店の長田さん！ いま、どんなコンピュータ書が売れているんですか？ - GeekOut</a></p>
<p>丸善本店は洋書の技術書が多めで、海外のもので気になるのがあるとき、眺めに行ける貴重な場所だったりする。</p>
]]></description>
            <link>https://chroju.dev/blog/libraries_in_tokyo_which_have_computer_books</link>
            <guid isPermaLink="false">libraries_in_tokyo_which_have_computer_books</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 31 Mar 2018 05:41:26 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Terraformドキュメントをコマンドで見るツールをGoで作る]]></title>
            <description><![CDATA[<p>クラウドサービスのリソース管理をコード化できるTerraform、とても便利に使っているけれど、リソースの種類によって当然ながら書くべき内容が異なりなかなかスムーズに書くことができない。</p>
<p><a href="https://www.terraform.io/docs/providers/aws/index.html">Provider: AWS - Terraform by HashiCorp</a></p>
<p>例えば自分がよく使うAWSだけでも、このリンク先に書かれているだけのリソースの種類、書き方がある。そして機能やサービスが増えるごとに、リソースの書き方もどんどん多様化していく。今はこれをいちいちウェブ上で書き方を確認しながらTerraformを書いているんだけど、ちょっと手間が多いなという気がしてきた。</p>
<p>同様にInfrastructure as CodeのツールであるAnsibleには、ansible-docというコマンドがあって、ドキュメントをコマンドライン上で見ることができるようになっている。</p>
<pre><code>$ ansible-doc file
> FILE    (/usr/local/Cellar/ansible/2.5.0/libexec/lib/python2.7/site-packages/ansible/modules/files/file.py)

        Sets attributes of files, symlinks, and directories, or removes files/symlinks/directories. Many other modules support the same options as the `file'
        module - including [copy], [template], and [assemble]. For Windows targets, use the [win_file] module instead.

OPTIONS (= is mandatory):

- attributes
        Attributes the file or directory should have. To get supported flags look at the man page for `chattr' on the target system. This string should contain
        the attributes in the same order as the one displayed by `lsattr'.
        (Aliases: attr)[Default: None]
        version_added: 2.3

- follow
        This flag indicates that filesystem links, if they exist, should be followed.
        Previous to Ansible 2.5, this was `no' by default.
        [Default: yes]
        type: bool
        version_added: 1.8
...
</code></pre>
<p>これに類似したものがTerraformにあれば、ブラウザとターミナルを行き来する必要がなくなる。でも探した限りそういうツールはなさそうだったので、自分で作ることにした。</p>
<h2>tfdoc</h2>
<p><a href="https://github.com/chroju/tfdoc">chroju/tfdoc</a></p>
<p>まだ全然作り始めたばかりだけど、とりあえずリソース名を指定して実行すると、スニペットを吐き出すところまでは出来た。こんな感じで出力される。</p>
<pre><code>$ tfdoc aws_iam_user
resource "aws_iam_user" "sample" {

  // (Required) The user's name. The name must consist of upper and lowercase alphanumeric characters with no spaces. You can also include any of the following characters: =,.@-_.. User names are not distinguished by case. For example, you cannot create users named both "TESTUSER" and "testuser".
  name = ""

  // (Optional, default "/") Path in which to create the user.
  path = ""

  // (Optional, default false) When destroying this user, destroy even if ithas non-Terraform-managed IAM access keys, login profile or MFA devices. Without force_destroya user with non-Terraform-managed access keys and login profile will fail to be destroyed.
  force_destroy = ""
}
</code></pre>
<p>Terraformのドキュメントはウェブで公開されているHTML以外の形式がなさそうだったので、そこからスクレイピングして整形して吐くだけの簡単な実装になっている。とはいえ案外こういうきちんとしたサイトでも、書式が揃っていないところがあったりして、やっぱりスクレイピングはしんどいなぁという感じではあったのだけど。。</p>
<p>出力はスニペットだけじゃなくて、先に挙げたansible-docと同様にドキュメントの体裁でも行いたいので、そういう機能も少しばかり付けられたらなと思う。</p>
<h2>Go</h2>
<p>tfdocを作るにあたっては、初めてGoを使った。まだ勉強中なのでちゃんと使えると言える段階には無い（ソース見ればわかると思うが）けど、tfdocを作る中で習得していきたい感じ。</p>
<p>Goを選んだのにはいくつか理由があるけれど、クロスコンパイルが出来て様々な環境に合わせたバイナリが生成出来たり、それでいて文法的な難易度が高くはない（という評判を聴いている）のが大きかった。</p>
<ul>
<li><a href="http://blog.yuuk.io/entry/go-cli-unix">Go言語によるCLIツール開発とUNIX哲学について - ゆううきブログ</a></li>
<li><a href="https://deeeet.com/writing/2014/05/19/gox/">複数プラットフォームにGoアプリケーションを配布する | SOTA</a></li>
</ul>
<p>今は仕事だと主にPythonでツールを書くことが多いのだけど、古いサーバーだとPython2が入っていたりpipが無かったり、環境依存が大きくて困ることが多い。バイナリを置けばインストールが終わるというのは非常に助かる。</p>
<p>難易度の話は、ほぼLLしか経験のない自分にとってはポインタが少しハードルにはなったりして、サクッとすぐ書けるようになるというわけにはいかなかった。元々『Goならわかるシステムプログラミング』でGoの習得を考えていたものの、その点で一旦停まってしまっている。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4908686033/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/515xkIcDgXL._SL160_.jpg" alt="Goならわかるシステムプログラミング" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4908686033/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Goならわかるシステムプログラミング</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 18.03.25</div></div><div class="amazlet-detail">渋川よしき <br />Lambda Note <br />売り上げランキング: 32,638<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4908686033/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>その後に <a href="http://kakakakakku.hatenablog.com/entry/2017/10/16/081755">Treasure 2017 の研修資料は Go を学ぶのに最高だった - kakakakakku blog</a> で言及されている、 VOYAGE GROUPが公開している <a href="https://go-talks.appspot.com/github.com/voyagegroup/talks/2017/treasure-go/intro.slide#1">Go入門</a> をやってみて、改めて入口に立った。</p>
<p>レファレンスは <a href="https://godoc.org/">GoDoc</a> があれば十分という話もあるが、1冊本で手元に置きたい気持ちもあったので、『プログラミング言語Go』を買ってみている。海外だと「Blue book」と呼ばれて、これがバイブル扱いされているっぽい。ただ、実際紐解くと本職インフラエンジニアのなんちゃってプログラマーには少しむずかしい。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4621300253/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/41BaAiMmrnL._SL160_.jpg" alt="プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4621300253/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 18.03.25</div></div><div class="amazlet-detail">Alan A.A. Donovan Brian W. Kernighan <br />丸善出版 <br />売り上げランキング: 19,223<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4621300253/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>長らくブログもちゃんと更新できていなかったけど、何かを作りたいというモチベーションがあると勉強も進みやすいとわかってきたので、来月いっぱいぐらいはtfdocを形にすることを目指していきたい。TDDがやりやすい仕組みになっていたり、gofmtがコーディングを助けてくれたり、Goにはプログラミングの習得速度を加速してくれる機能が多い。これを進めることで得られるものが多そう。</p>
]]></description>
            <link>https://chroju.dev/blog/create_terraform_helper_tool_with_go</link>
            <guid isPermaLink="false">create_terraform_helper_tool_with_go</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 25 Mar 2018 13:56:51 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[裁量労働制の恩恵、個々の裁量で働くということ]]></title>
            <description><![CDATA[<p>別に法律とか労働法とか詳しくないのでそういう話はしないけど、昨今の裁量労働制の話において、「恩恵を受けている人を見たことがない」みたいな話も聞こえてきているので、恩恵を受けていると考える立場から取りあえず書いておこうと思って筆を執る。</p>
<h2>自分と裁量労働制</h2>
<p>今の会社に入ってから2年半ぐらい、裁量労働制の下で働いている。それ以前の会社はいわゆる時給制の会社で、残業代もきちんと出るようなところだったが、今のほうが働きやすいと感じている。ざっくり、今の状況を箇条書きしてみる。</p>
<ul>
<li>出退勤時刻の規定がない。
<ul>
<li>時給制社員もいるので、正確には一応出退勤時刻が存在するが、裁量労働制社員は縛られない。</li>
<li>多いのは子持ちの男性社員が、子どもの送迎などで早く帰る／遅く来る場合。</li>
<li>そうでない人も来る時間はバラバラ。一部IT系でいるような、夜だけ来るみたいな極端な人はいない。</li>
<li>雪の日に出社を遅らせるのももちろん自由。</li>
<li>極端な話、1時間でも働けばその日は出勤扱いになる（有給がなかなか減らない）。</li>
</ul>
</li>
<li>給与は半年ごとに改定され、向こう6か月の月給が固定される。
<ul>
<li>毎月の収入額が固定されているので、支出や貯金、投資の見通しが立てやすくて楽。</li>
<li>基本的に、効率化して労働時間を減らすことをモチベとする職種なので、「労働時間が減るほど収入が減る」時給制があまり好みではない。
<ul>
<li>時給制の頃は収入を減らし過ぎたくないので、暇な時期でもXX時間はコンスタントに残業するとかしていた。</li>
</ul>
</li>
</ul>
</li>
<li>指揮命令系統がほぼ無く、個々人の裁量で働くことができる。
<ul>
<li>従って一部で言われている「仕事量に裁量がなくて、実情は残業時間過多」という状況は少ない。</li>
<li>「少ない」と書いたのは、例えばトラブルシュートなどで必然と労働時間が増えてしまう場合はあるため。
<ul>
<li>みなしの労働時間を超過して働いている場合は追加支払いがあるらしいが、該当したことがないのでわからない。</li>
</ul>
</li>
<li>上下関係はあるにはあるが、上の人間という立場は責任を取るために存在しているような形で、直接的な指示を受ける機会は少ない。上の人間もプログラミングしているし、同列に働いている。
<ul>
<li>それ故、入社当初しばらくは「何をしていいかわからない」状態になったりもした。</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>総合すると、余計なことを考える必要が無くなり、精神に余裕ができた、というのが恩恵として大きい。朝、ちょっとおなかが痛くなって電車を降りたり、そういう状況でも時間を気にしなくていいとか、今月残業少なくて給料減りそうだから、来週は少し残業増やそう、みたいなアホなことしなくていいとか。時給制の頃、残業時間の関係により、月給が前月比10万円マイナスみたいなこともあって、あれは本当に心臓によろしくなかった。</p>
<p>ITの、特にベンチャーと言われるような界隈では裁量労働制は少なくないと思う。先にも触れたが、我々の仕事は効率化することに重きが置かれるし、優秀なプログラマーだと何倍も速く仕事を仕上げられるみたいな法則もあるからだと思うし、あとは自分と同じく自由な働き方を好む人が多いってことだとも思う。観測はしていないが、中には違法な運用をしている会社も当然あるのだろうけど。</p>
<h2>論点を切り分けずに一蹴するべきではない</h2>
<p>一連の議論というか、裁量労働制に関して最近いろいろ言われるなかで、「裁量があるのは労働の開始終了時刻だけ」という話を見かけたけど、事実のようで事実ではないと思う。厚労省の<a href="http://www.mhlw.go.jp/general/seido/roudou/senmon/index.html">専門業務型裁量労働制</a>の解説ページを見ると、</p>
<blockquote>
<p>業務遂行の手段や方法、時間配分等を大幅に労働者の裁量にゆだねる必要がある業務</p>
</blockquote>
<p>が対象になるとあり、つまり時間だけではなくて、仕事のやり方についても裁量が存在する。この「業務遂行の手段や方法」が「業務量」まで含むのかは判断しかねるが、少なくとも仕事についてこうしろああしろと指示を受ける状態は、裁量労働制の適切な運用ではない、ということになると理解している。</p>
<p>ただ世の中を見渡すと、どうも「裁量があるのは労働の開始終了時刻だけ」という形で運用されている裁量労働制が多いらしい。でも「裁量労働制はメリットの大きい制度か」ということと、「裁量労働制は適切に運用されているか」は別の論点だ。</p>
<ul>
<li>裁量労働制という制度は、そもそもメリットがあるのか。</li>
<li>裁量労働制は現状、実際にはどのように運用されているのか。</li>
<li>適法に運用されていない状態が蔓延している場合、その理由は何か。また、それに対応する方法はあるか。</li>
<li>適法に運用した場合、裁量労働制のメリットは拡大するか。</li>
<li>それらを踏まえた上で、安倍政権による今回の裁量労働制拡大は是か否か。</li>
<li>否である場合、どういった形で裁量労働制を活かせるか。あるいは裁量労働制自体廃止すべきか。</li>
</ul>
<p>こういった話に切り分けが出来るはずなんだけど、それをせずに「定額働かせ放題」のような雑なレッテルを貼って一蹴するのは、なんというか勿体無いなと、恩恵を受けている立場からは思う。</p>
<h2>「働き方改革」に「裁量」は必要になってくる</h2>
<p>先日関東で大雪が降ったとき、こういう日に出社時間を遅らせたり、休みにしない会社はブラックだ、みたいな話が挙がっていた。でもすごくザックリ言ってしまうと、休みたかったら休めばいいんじゃないの？と自分は思っていた。もちろん、個々の事情で出社しなければならない人もいるだろうけど、なんで全部会社のせいなんだろう、という気はしていた。</p>
<p>プレミアムフライデーの話も似ていて、あれに「帰れるわけないでしょ」と反応すると、そこで話は停まるわけだけど、「月末金曜は早く帰っていいらしい！じゃあ、それを実現するためにどうしよう？」とか「金曜は無理だけど、月初に帰ろうか」とか、話を発展させることはできる。まあ、そうは言ってもやっぱり現実問題、会社や上司に唯々諾々と従うのではなくて、自分なりに考えてやることをやる、ってのは難しいんだろうけど。</p>
<p>とはいえ自由な働き方を取り入れていきたいのであれば、裁量労働制ではないとしても、ある程度社員個々人が「裁量」を持つことが必要になると思う。本当かウソかは知らないが、よく海外の人は仕事が残っていても定時にサッサと帰ってしまうみたいな話があるけど、あれが出来るのは、その人が自らの裁量で動いている故なわけで。早く帰りたいけど自分にその裁量はなくて、上が何とかしてくれるのを待つしか無いです、自分にできることは何もないです、という態度が正解なのかはわからない。</p>
<p>裁量労働制、個々人が裁量で動いて成果出して、さっさと好きな時間に帰りましょうねってのが本懐だと思うので、それが一面に反対一色となるのは、まぁなんだかなと思う。どうしたら好きな働き方をみんな出来るようになるだろうね、って方向に早く議論が進んでほしい。</p>
]]></description>
            <link>https://chroju.dev/blog/flexible_work_or_not</link>
            <guid isPermaLink="false">flexible_work_or_not</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 28 Feb 2018 14:03:59 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[2017年総括 - 計算機科学と向き合う]]></title>
            <description><![CDATA[<h2>停滞</h2>
<p>今年は停滞していたというか、新しいことにあまり手を出さなかったように思う。</p>
<p>仕事を振り返ると、昨年末から今年の初め頃にだいぶテンション下がる出来事があって、しかもその後その状況を尻拭いしなくてはならなくなったりして、上半期はかなり長いことメンタルがアレだった。その頃やっていたのは、状況改善のために様々なOSSを導入したり、業務フローを改善するためのツールを書いたりすることで、生産的は生産的だったのかもしれないけど、なんだか不本意だなという思いがずっと強かった。扱ってたのはこのあたり。</p>
<ul>
<li>Amazon ECS (ECS CLI)</li>
<li>Terraform</li>
<li>influxDB</li>
<li>Grafana</li>
<li>Apex</li>
</ul>
<p>なんだかツールを使う、取り入れるというところに注力してしまって、あんまり自分で手を動かして何か書くとか、自分自身が持っている技術に依存した仕事ができなかったなという気持ちが強い。メンタルがアレになった時期が長かったことで、インプットが停滞した感じもあって、どうもよろしくなかった。</p>
<h2>計算機科学と向き合う</h2>
<p>でも別に本当に何もしてなかったかというと、実際には何かしらはもちろんやっていた。あるPython製のCLIツールを社内用に作る機会があり、結構規模が大きかったので、これを期にと思い『オブジェクト指向設計実践ガイド』を読み、オブジェクト指向で書くとはどういうことなのか学び直したりもした。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/477418361X/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/51-TCt0H4UL._SL160_.jpg" alt="オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/477418361X/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 17.12.29</div></div><div class="amazlet-detail">Sandi Metz <br />技術評論社 <br />売り上げランキング: 10,225<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/477418361X/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>自分はコンピュータ・サイエンスの学位を持っていなくて、独学と仕事での知識が中心になっているので、体系だった計算機科学の知識を持たないことはずっと気にかかっている。プログラムをどう書くと上手い感じになるのか、という点についてもそうで、特にこの点に関しては、プログラマーではない（職歴はインフラエンジニアとops方面のみ）故に弱いなと感じていた。オブジェクト指向の概念は知っていたが、この本を読んで初めて具体的な設計に落とし込めるようになった気がする。この本は本当に読んでよかった。</p>
<p>他にも、これはたまたまなのか、今年渋川よしきさんの著書で『<a href="https://www.amazon.co.jp/dp/4908686033/">Goならわかるシステムプログラミング</a>』と『<a href="https://www.amazon.co.jp/dp/4873118042/">Real World HTTP</a>』を買った。いずれもCSの基礎に近い内容を丁寧に追えるよな内容になっていて、まだ読み切れてはいないけど、しっかり力を付けたいと思う。</p>
<p>あと、友人が30歳近くになって大学院に進み、アカデミックの方向を目指し始めたというのにも影響されて、やっぱり学位はどこかで取っておきたい気持ちが強くなった。今年が「ツールを使う」年だった中で、そうじゃなくて作る側、技術を持った側に深く進みたいなと思い始めた。</p>
<h2>GitHubと仲良くする</h2>
<p>これは今度別のエントリーで詳しく書くつもりだけど、今年は少しGitHubとも仲良くできた。具体的には、OSSへプルリクを送ってマージしてもらう経験を初めてした。</p>
<p>対象は業務でも使っていたOSSなんだけど、会社では自分のGitHubアカウントを使ったりはできないので、プライベートの時間を使って開発した。なので社内の誰も知らないけど、自分が書いたコードが今社内の業務に使われていることになっていて、それはシンプルに嬉しい経験だった。</p>
<p>でもなかなかプルリク、出せるものでもなかったりして、来年はもっと仲良くしたい。やっぱりこれは別エントリーで書く。</p>
<h2>インフラエンジニアは死ななかった</h2>
<p>今年は『<a href="https://www.amazon.co.jp/dp/4873117917/">SRE サイトリライアビリティエンジニアリング</a>』や『<a href="https://www.amazon.co.jp/dp/4873117968/">Infrastructure as Code</a>』の刊行があって、インフラエンジニアが今後どうすべきかというロールモデルが示されたように感じている。</p>
<p>結果としてインフラエンジニアは死ななかった。というか、求められるのがコードを書いて環境全体をオーケストレートしたり、モニタリングやオペレーションを円滑化するミドルウェアを作ったりというところに変化してきていて、低レイヤーに対するより深い知識が求められるようになった。</p>
<p>DockerやAnsibleといった最近のインフラ周りのツール、あるいはこのエントリーの冒頭に挙げたようなツールは、使おうと思えば誰でも使える。でも、それをより効果的に使うためには、AnsibleにしたってDRYに書く必要があるとか、そういうソフトウェア開発のノウハウが必要になってくる。今年は「使う」年になってしまったけど、来年はより深く「知る」「作る」年にしたい。インプットとアウトプットのスピードを高めるのと、もうとにかくなんでもいいからコードを書いていく。数が大事。</p>
]]></description>
            <link>https://chroju.dev/blog/looking_back_2017</link>
            <guid isPermaLink="false">looking_back_2017</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 29 Dec 2017 12:43:07 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Terraform moduleは何が嬉しいのか]]></title>
            <description><![CDATA[<p>Terraformの「<a href="https://www.terraform.io/intro/getting-started/modules.html">module</a>」を最近使うようになった。moduleは複数のクラウドリソースをまとめてテンプレート化して、呼び出すときに必要な引数だけ与えてあげれば発動可能になるというもので、要するにリソースの抽象化に使われる。Ansibleで言うところのRoleに近い。</p>
<p>Terraform自体は1年ぐらい前から使っていたので、結構長いことmoduleには触れていなかったんだけど、理由としては結構複雑化しそうというのがあった。今回改めて触れてみて、メリットは確かに感じられるがやっぱり複雑だなという気持ちが強くて、一旦まとめてみる。</p>
<h2>宣言地獄</h2>
<p>moduleはクラウドリソースの枠を作り、各種設定値は変数として空けておいて、呼び出されるときに変数を埋めてもらう、という形を取るので、変数宣言をそこここに書くことになる。これがあまりDRYではないというか、何度も同じものを書く必要があったりする。</p>
<p>簡単に書いてしまうとmoduleはこうなる。</p>
<pre><code class="language-hcl:main.tf">variable "name" {}
variable "instnace_type" { default = "t2.micro" }

resource "aws_ec2_instance" "hoge" {
  name          = "${var.name}"
  instance_type = "${var.type}"
}
</code></pre>
<p>resourceの中に変数のプレースホルダを置き、さらにその変数名を
<code>variable</code> 句で宣言する。ここでは簡略化してresourceと同じファイル内に変数宣言も置いたが、推奨のプラクティスとしては <code>variable.tf</code> という別ファイルに変数宣言だけ切り出すことが多い。</p>
<p>このmoduleを呼び出すときは、以下のように変数に値を埋めてやる。</p>
<pre><code class="language-hcl:main.tf">variable "name" {
  value = "hoge"
}

variable "type" {
  value = "c4.xlarge"
}

module {
  source = "./hoge"

  name   = "${var.name}"
  type   = "${var.type}"
}
</code></pre>
<p>若干大げさに書いた。ここで <code>module</code> 内にもプレースホルダを置いて、さらに <code>variable</code> を宣言する必要はなくて、プレースホルダの箇所に直接値を書けばそれで済む。ただ、可変値とそれ以外は分けて記述した方がわかりやすいという人もいるので、そこは好みかなと。</p>
<p>というわけで結構何回も同じ変数名を書くことになる。少なくともmodule内のプレースホルダで1回、その変数宣言で1回、呼び出すときに1回の計3回必要。</p>
<p>これさすがに冗長だなぁという気がしていて、例えば特定のmoduleを使うときに、入力が必要な変数を全部tfファイルに書き出すツールとかあったらいいんではと思ってる。Terraform本体にも <code>validate</code> サブコマンドはあるけど、あれは文法的なエラーしか確認してくれないので。来月作れたら作りたい。</p>
<h2>moduleはどの単位で切るべきか</h2>
<p>moduleは何のために使うのかと言えば、繰り返し使うような部分を隠蔽して、DRYに書くことを実現するためなので、再利用性のある単位でresourceをまとめるのが効率がよいということになる。</p>
<p>これは各位のAWSの使い方に依存するので、唯一解はない。例えばEC2を立ち上げるときに必ずIAM Roleも個別に用意して付与するような使い方をしているなら、EC2とIAM Role双方を作れるようなmoduleでパッケージするのが効率いいはず。</p>
<p>ただ、再利用性を高めたmoduleを書くのが結構難しい。例えば以下のリンクは <a href="https://registry.terraform.io/">Terraform module registry</a> にあるAWSセキュリティグループのmoduleだが、ちょっと見てみてほしい。</p>
<p><a href="https://github.com/terraform-aws-modules/terraform-aws-security-group/tree/master/modules">terraform-aws-security-group/modules at master · terraform-aws-modules/terraform-aws-security-group</a></p>
<p>セキュリティグループはかなり書き方の幅が広くて、自力で書こうともしてみたけど、様々な利用ケースを想定して書くのは相当難しかった。なので先のレポジトリではある程度割り切って、元から代表的なポート番号を開けるためのmoduleを用意して使わせる形になっている。おそらくこっちの方が現実的。</p>
<p>そしてここまでのものを自前で用意したところで、そんなに再利用するかな？って話になるので、moduleが複雑化しそうであれば、無理して作らずにmodule registryから持ってくるか、逐一resourceを普通に書いた方が省エネだったりもする。一方でIAM Userとか設定がシンプルなものはmoduleに任せるとかなり楽。</p>
<p>module registry、少し使ってみたけど楽なのは確かで、例えばすぐにリソース立ち上げたいからTerraform書くのめんどくせーや手動起動→結局そのリソース長期で使うハメになりブラックボックス化、とかよくあるけど、module registryから引っ張ってきて取りあえず使えば雑にコード化は可能になったりする。</p>
<h2>Best Practice</h2>
<p>今回は断片的にmoduleに触れただけなので、どこかでもう少し包括的な視点からベストプラクティスっぽいのまとめたいなと思う。</p>
<p>実のところ <a href="https://github.com/hashicorp/best-practices/">hashicorp/best-practices</a> というのが公開されてはいるのだけど、残念ながら「Deprecated」になっていて、現状HashiCorp公開のベストプラクティスは存在していない（多分）（知らないだけでどこかにあるなら教えてほしい）。最近Terraformもいろいろ機能追加があってプラクティス変わってきてるので、どこかのタイミングで再度ベストプラクティスを公開してほしいとは思う。</p>
<p>Qiitaにあったこちらはかなり参考にさせていただいた。文中では触れられていないが、「immutable」と「not_immutable（mutable？）」でtfファイルを分けるというのはとても同意したい。Desired Instancesを手動、自動で変化させ得るAutoScalingグループのようなmutableなオブジェクトは、Terraformだけで変更をかけ得るオブジェクトとは別で管理した方がいい。</p>
<p><a href="https://qiita.com/shogomuranushi/items/e2f3ff3cfdcacdd17f99">Terraform Best Practices in 2017 - Qiita</a></p>
<p>表題に対する現時点の結論としては、</p>
<ul>
<li>シンプルな設定のリソースについては、再利用性の高いmoduleを書くとDRYなtfファイルになって嬉しい。</li>
<li>先日公開されたTerraform module registryから引っ張ってくれば、すぐリソース作りたいときにも少ない手間でコード化ができて嬉しい。</li>
<li>変数宣言の多さと、複雑化した場合の管理コストの多さは嬉しくない。</li>
</ul>
<p>というところ。なので3点目を解消する方向へ頑張りたい。</p>
]]></description>
            <link>https://chroju.dev/blog/how_to_use_terraform_modules</link>
            <guid isPermaLink="false">how_to_use_terraform_modules</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 27 Dec 2017 13:09:25 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[CircleCI 2.0でhugoのブログ生成を自動化する]]></title>
            <description><![CDATA[<p>このブログは <a href="https://gohugo.io/">hugo</a> で生成している。生成過程を自動化したくて、<a href="https://circleci.com/">CircleCI</a>へ任せることにしようと思ったところ、そういえばCircleCI 2.0をまだ触っていないことに気付いたので、2.0で自動化した。</p>
<h2>設定の書き方</h2>
<p>1.0における<code>circle.yml</code>のように、設定ファイルを書いてそれに基づいた処理が行われるという点は変わらないものの、設定の書き方はガラッと変わって後方互換性は一切なくなっていた。</p>
<p>一応マイグレーションガイドがあるので、<code>circle.yml</code>からステップ踏んで移行できるようにはなってる。</p>
<ul>
<li><a href="https://circleci.com/docs/2.0/migrating-from-1-2/">Migrating from 1.0 to 2.0 - CircleCI</a></li>
</ul>
<h3>実行タスク</h3>
<p>1.0ではCircleCIがリポジトリの言語から実行タスクを自動判定していたので、設定の書き方は基本的に「デフォルトの実行内容と異なることをやりたければ <code>override</code> する」という形だった。2.0ではデフォルトタスクがなくなり、すべて自前で書く形になった。</p>
<p>正直、デフォルトのタスクをそのまま使うことはほとんどなかったので、すべて自前で書ける方が何も考えずに済んで楽になった。</p>
<h3>ジョブとワークフローという概念</h3>
<p>タスクは1つの環境上で一気通貫に実行される形ではなくなり、実行したい内容を <code>Job</code> としてステップで分けて定義する形になった。 <code>Job</code> ごとに環境も分離されていて、それぞれDocker imageを定義して起動する。各言語で必要なimageは <a href="https://circleci.com/docs/2.0/circleci-images/">CircleCIが用意している</a> が、それ以外のimageでももちろんよい。</p>
<p><code>Job</code> をどの順番で実行するかは <code>Workflow</code> として定義する。テストのジョブが成功した場合のみデプロイのジョブを実行するなど、 <code>Job</code> 間の依存関係を定義することもできる。</p>
<h3>キャッシュの使い所</h3>
<p><code>Job</code> ごとにDockerコンテナが起動する都合上、コンテナ間で同じファイルを共有したい場合や、実行の度に同じファイルを使うようなときにはキャッシュを利用する。前者としては、 <code>git clone</code> したソースコードをどの <code>Job</code> でも使いまわすようなとき、後者としては、依存するライブラリのダウンロードなどが考えられる。</p>
<p>キャッシュはコンテナ内のどのディレクトリを、何という名前でキャッシュするか、という形で定義する。すでに同名のキャッシュが存在する場合は、それを上書きすることはないので、このあたりが設計上肝になる。</p>
<p>キャッシュ名には <a href="https://circleci.com/docs/2.0/caching/#using-keys-and-templates">変数 (Template)</a> が使えて、この使い方で「いつキャッシュするか」をコントロールできる。<code>{{ checksum }}</code> を使うと特定ファイルのチェックサムがキャッシュ名に入るので、Gemfileなどを指定すれば、これに変更があったときだけキャッシュを上書き＝ライブラリの再ダウンロードが促せる。 <code>{{ epoch }}</code>を使えば実行時刻に応じたキャッシュ名となり、またキャッシュリストア時は最新の <code>epoch</code> が入ったキャッシュが選ばれるので、毎回ダウンロードし直すことになるソースコードのキャッシュに使える。</p>
<h2>実装</h2>
<p>実装を以下に置く。hugoなのでいわゆるソフトウェアのテストは回しておらず、 <a href="https://github.com/textlint/textlint">textlint</a> で文章校正だけ行い、OKであれば build と deploy が走るようになっている。</p>
<p>textlintは当初全記事にかける形にしていたが、今までの記事ほとんどでNGが出てしまったので、「ブランチ名と一致するファイル名のmarkdown」にだけ実行する形にした。それでもデフォルトで使っていると結構厳しく感じるので、設定は改めたい。。</p>
<pre><code class="language-yaml">version: 2

jobs:
  checkout_code:
    docker:
      - image: circleci/golang:1.8
    working_directory: ~/hugo
    steps:
      - checkout
      - save_cache:
          key: hugo-cache-{{ epoch }}
          paths:
            - ~/hugo

  textlint:
    docker:
      - image: circleci/node:9.2.0
    working_directory: ~/hugo/.circleci
    steps:
      - restore_cache:
          keys:
            - hugo-cache
            - hugo-nodemodules-{{ checksum "package.json" }}
      - run:
          command: |
            npm install
            npm run textlint "../content/blog/${CIRCLE_BRANCH}.md"
      - save_cache:
          key: hugo-nodemodules-{{ checksum "package.json" }}
          paths:
            - ~/hugo/.circleci/node_modules

  build:
    docker:
      - image: circleci/golang:1.8
    working_directory: ~/hugo
    steps:
      - restore_cache:
          key: hugo-cache
      - run:
          command: |
            git submodule sync
            git submodule update --init
            go get github.com/gohugoio/hugo
            git clone https://github.com/chroju/chroju.github.io public
            rm -rf public/*
            sudo cp /usr/share/zoneinfo/Japan /etc/localtime
            hugo
      - save_cache:
          key: hugo-cache-public-{{ epoch }}
          paths:
            - ~/hugo/public

  deploy:
    machine:
      enabled: true
    working_directory: ~/hugo/public
    steps:
      - restore_cache:
          key: hugo-cache-public
      - run:
          command: |
            git config --global user.name chroju
            git config --global user.email chor.chroju@gmail.com
            git add --all
            git commit -m "${CIRCLE_BRANCH} (Circle CI)"
            git push git@github.com:chroju/chroju.github.io

workflows:
  version: 2
  build_and_deploy:
    jobs:
      - checkout_code
      - textlint:
          filters:
            branches:
              ignore: master
          requires:
            - checkout_code
      - build:
          requires:
            - checkout_code
      - deploy:
          filters:
            branches:
              only: master
          requires:
            - textlint
            - build
</code></pre>
<h2>hugo theme の変更</h2>
<p>余談にはなるけど、今回のCircleCI実装に合わせて、 hugo のテーマもcocoaというものに変更した。</p>
<p><a href="https://github.com/nishanths/cocoa-hugo-theme">nishanths/cocoa-hugo-theme: Configurable, responsive blogging theme for Hugo</a></p>
<p>hugo のテーマ変更は初めてなのだけど、configの書き方がテーマによって少し違いがあり、そのまま移植という形にはできなかったのでちょっと時間がかかった。</p>
]]></description>
            <link>https://chroju.dev/blog/circleci_2_0_with_hugo</link>
            <guid isPermaLink="false">circleci_2_0_with_hugo</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 18 Dec 2017 01:15:06 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[AlexaにAWSの請求額を教えてもらう]]></title>
            <description><![CDATA[<p>Amazon Echo Dotを書いたのでさっそくオリジナルスキルを作ったのだけど、アイディアに乏しいマンなので、「自分が使っているAWSアカウントの請求額を教えてもらう」という、あんまり夢のないスキルが出来上がった。想定される発話の一覧を作っているとき、「請求額を教えて」とか「支払いを確認して」とかいっぱい書いてて、若干つらい気持ちになったのだけど、取りあえず作るのが目的だったのでそこは気にしない。</p>
<p>ライバルであり、先に国内発売していたGoogle Homeは買っていないので、比較はできていないのだけど、Alexaの強みはLambdaを直接叩けることだと思う。API Gatewayを準備してHTTPSのエンドポイントを渡す、とかではなくて、LambdaのARNを指定して直接連携ができるのでとてもシンプル。既知の技術を活かせることもあって、開発の難易度は高くない。面倒なのはデバッグで、声に出して全機能試してみるというのはわりとまどろっこしくてだるい。</p>
<p>チャットボットフレームワークであるAmazon Lexや、音声変換技術であるAmazon Pollyが公開された時点で意図がわかってはいたけど、Alexaの開発にはバックエンドにAWSを存分に使ってくれということなんだろう。Google Homeの強みが、Google Assistantという高機能AIにあるとしたら、Amazonの方の強みは長年培ってきたクラウドサービスノウハウとのシームレスな連携にあるような気がしている。</p>
<h2>Alexaの開発</h2>
<p>Alexa開発はデモをしても音声なので、動画か音声ファイルを貼る必要があるのがちょっとつらい。一応アプリにも会話の記録が残るので、今回はそれを貼ることにする。こんな感じで、サービスごとの請求金額や、請求金額の合計を教えてくれる。</p>
<p><a href="https://gyazo.com/a42658b0b61e3b2b237a8298672a98ce"><img src="https://i.gyazo.com/a42658b0b61e3b2b237a8298672a98ce.png" alt="https://gyazo.com/a42658b0b61e3b2b237a8298672a98ce" width="540"/></a></p>
<p>開発にまつわる技術的な話もしようと思っていたのだけど、Alexa Skill開発入門みたいなことは、書いたら長くなってしまったのでQiitaに投稿しておいた。そちら参照。</p>
<ul>
<li><a href="https://qiita.com/chroju/items/3f30fe424df36e4b4d80">Amazon Echo (Alexa) の開発に必要な概念について - Qiita</a></li>
</ul>
<p>ここにはLambdaのコードとIntent Schemaだけ貼っておく。Lambdaの方はblueprintで用意されている「alexa-skills-kit-color-expert-python」を少しいじっただけなので、そんな大したものではないというのと、Python2.7のままですというのを断っておく。逆に言えば、用意するものはこんなもんだけでAlexaのSkillは作れてしまう。</p>
<script src="https://gist.github.com/chroju/97201c49a888533f3413a081013ea706.js"></script>
<h2>like a hubot ?</h2>
<p>ところで人間的な応答を返す会話インターフェースとなると、hubotを始めとするチャットボットを彷彿とさせる。hubotの登場後は、単純な雜談や情報連携から、CIとの連携、監視との連携、さらにはbotを使ったdeployなどもチャットで行われるようになった。ではAlexaはどうなのか。開発の現場でも似たように使えるんじゃないか。</p>
<p>Lambdaと連携できるということは、自社のAWSアカウントのAPIを叩かせることもできるわけで、例えば「Alexa, サーバー台数を100台に増やして」みたいな「ボイスオペレーション」も可能ではある。突然Yahoo!砲のような大量のリクエストが来てワタワタとオペレーションしているときに、片手間で呼びかけるだけで操作を肩代わりしてもらえるなら、ちょっと便利かもしれない。</p>
<p>ただ冷静に考えるとやっぱり無理かなという思いがある。ひとつは文字が使えないこと。チャットボットは文字で指示する、要はCLIの派生みたいなものだったので、記号的なidだとか、固有名だとかでも違えず引数として与えることができた。対してAlexaは音声を解釈するので固有名詞や記号的文字列はどうしても苦手であり、「AutoScalingグループのhogefugaを」などと指示しても、たぶん読み取ってはくれない。</p>
<p>もうひとつは権限の問題。強力なオペレーション機能を持ったhubotは、専用のchannelだけに置いたり、特定のユーザーだけに反応するように組むことで、「権限」の制約ができたのだけど、Alexaは声紋認証するわけでもないので、anonymousに命令を受け付ける。なのでさっき書いたような「起動サーバー台数を増やす」機能を持ったAlexaなど、オフィスに置いたら危なっかしくて仕方ない。てわけで、ボイスオーバーオペレーションはちょっとだけ夢見たのだけど、今のとこ無理そうかなという気がしている。小規模ベンチャーとかで限定的に導入したらテンション上がるかもだけど。</p>
<h2>Alexaブーム来てほしい</h2>
<p>繰り返しになってしまうけど、開発プラットフォームがAWSという既知の領域に開放されたことは結構大きいと思っていて、ぶっちゃけた話企業によるスキルの公開を待たなくても、巷のAPIと連携する形で必要なものはどんどん作れてしまう（もちろん、企業側とバッティングすれば審査で弾かれるんだろうけど）。スマートスピーカー、いざ使ってみると案外手の届かないことが多くてそのうち使わなくなる、みたいなことを想定したりもしていたのだけど、自分の好きなようにスキルが作れるなら、いくらでも使いようがあるなという気がしている。個人的にはAlexaスキル作成ブームが来ることをちょっと期待したい。お前も書けって話だと思うので、機会があればまた書きたいとも思う。</p>
]]></description>
            <link>https://chroju.dev/blog/hello_alexa</link>
            <guid isPermaLink="false">hello_alexa</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 18 Nov 2017 14:23:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Scrapbox.ioで思考を気持ちよく繋げる]]></title>
            <description><![CDATA[<p><a href="https://scrapbox.io/">Scrapbox.io</a>を最近使っていますが本当にいいのでいいという話をします。</p>
<p>そもそもScrapboxって何かという話から言えば、いわゆるオンラインでメモが取れる、ノートが書ける、スニペットが保存できるという類のサービスです。Gyazoを運営しているNOTA Incによる開発です。</p>
<p>何がいいかと言えば、これは記録するためのメモツールというより、思考のためのメモツールだと言うことです。NOTAのshokai氏のエントリーでも以下のようなものがあります。</p>
<p><a href="https://scrapbox.io/shokai/%E6%80%9D%E8%80%83%E3%82%92%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%81%99%E3%82%8B%E8%A6%81%E7%B4%A0%E3%82%92%E6%B8%9B%E3%82%89%E3%81%97%E3%81%9F%E3%81%84">思考をブロックする要素を減らしたい - 橋本商会 - Scrapbox</a></p>
<p>Scrapboxが「思考のためのツール」たる特徴はいくつかあるのですが、Wikiで良くあるシステムのように、本文中にブラケットで囲んだ単語を入れると、それがリンクとなる機能があります。それだけだとまぁ普通なんですけど、ノートを書いているときにこのリンクを作ると、リアルタイムにその単語に対してリンクしたページがバババッとページの下に羅列されるのがとても気に入っています。</p>
<p><a href="https://gyazo.com/8e952b04252c9c641be4de163a5e59b2"><img src="https://i.gyazo.com/8e952b04252c9c641be4de163a5e59b2.gif" alt="Scrapboxサンプル"></a></p>
<p>こんな感じ。面白いのはリンク先のページのみならず、リンク先にリンクしたページ、つまり2ホップ先まで表示される点です。Christpher Nolanについて書こうとしたら、過去に彼の監督作で『ダンケルク』と『インターステラー』についても書いていたんだなぁってのが自動的に想起され、今回何かを書くにあたり、過去に何書いてたんだっけというのを見ながら編集ができたりとか、そういう「過去の自分との連想」ができる。</p>
<p>自分の場合は固有名詞はとにかく端からリンクにしてるんですが、そうすると自分でも忘れていた、過去に同じテーマに関して書いたメモがどんどんピックアップされてつながっていくんですよね。この手の「発想を繋げる」方法論、従来では情報カードを使い、机上でカードを広げてやる方式が梅棹忠夫氏の『知的生産の技術』に載っていたりして有名ですが、まぁ手間はかかるし、確実ではない。得てして脳の「想起」の機能はランダムなものだし、カードでそれを補強しても完全ではない。Scrapboxは自動で漏れなくそれを実現してくれるのがとてもいい。</p>
<p>メモの整理で「タグを付ける」という方法論自体も古くからあるものですけど、メタ情報として付けるのではなく、単に文章を書きながら目についた固有名詞を囲んでいけばいいだけなので、思考を阻害されることなくタギング出来るってのもだいぶ気に入っています。</p>
<p>自分はそれほどスペックのいい脳味噌を持ってないんで、思考と記憶が外部化されて、さらにそれらが「勝手に繋がる」のが気持ちいい。気持ちいいので現状プログラミング以外のことでもとにかくぶち込んで繋げて遊んでます。オススメです。</p>
]]></description>
            <link>https://chroju.dev/blog/i_love_scrapbox</link>
            <guid isPermaLink="false">i_love_scrapbox</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 08 Oct 2017 13:31:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[CoreOSからECSへDockerを移行した]]></title>
            <description><![CDATA[<p>CoreOS（現状Container Linuxですけど、キャッチーじゃないのであえて）上でプライベートのDockerコンテナを動かしていたのですが、それをAmazon ECS上へ移行した話です。</p>
<h2>従来の環境</h2>
<p>従来は以下のような環境を使っていました。</p>
<ul>
<li>さくらクラウドでCoreOSを起動（イメージがデフォルトで用意されていて嬉しい）</li>
<li>コンテナは個人的なログ用influxDB、Grafana、個人slack用hubotの3つ。</li>
<li>オーケストレーションツールは使っていない（docker composeで管理、systemdで自動起動）</li>
<li>それ以外に運用っぽいことも特にしてない。</li>
</ul>
<p>プライベートかつ、とりあえずDocker触って動かしたいという理由だけで作った環境だったので、正直扱いは雑でして、たまにコンテナ落ちてて、hubotに呼びかけてから気付くみたいなこともままありました。</p>
<p>それが地味にストレスだったのと、せっかくDocker使うならもうちょいオーケストレーションとかちゃんとしたいってことで移行を決断しました。</p>
<h2>移行先の検討</h2>
<p>CoreOSは従来であれば<a href="https://coreos.com/fleet/docs/latest/launching-containers-fleet.html">fleet</a>という独自のオーケストレーションツールを持っていましたが（今も正確には現役ですが）、このリンク先にもある通り、現状はk8s使えってことになってます。</p>
<p>なのでさくらクラウド続投してk8sで頑張るというのも手ではあったのですが、仕事ではAWS使うことが多いというのと、個人的にここ最近聴いたDockerのproduction利用の話がだいたいECSだったのとで、管理も楽そうだしECSでいいかなという感じでした。</p>
<p>ただ、k8sであればオンプレやら何やらといった環境を問わずに運用が可能だし、クラウドに載せたければGKEでそのノウハウ活かせるしという利点があり、長期視点で汎用性の高い技術選択、という視点だとk8sの方がいいのではと思ったりしてます。</p>
<h2>ECSの概念</h2>
<p>簡単に触れておきます。</p>
<h3>cluster</h3>
<p>コンテナをホストするEC2インスタンス群。</p>
<h3>task definition</h3>
<p>cluster上でコンテナをどう配置するかという定義。</p>
<h3>task</h3>
<p>task definitionに基いて稼働するコンテナ群。</p>
<h3>service</h3>
<p>taskを永続的なプロセスとして稼働させるECSの機能。</p>
<p>taskは「service」として動かすことで、コンテナが落ちても勝手に上げ直してくれるようなイイ感じのやつになります。serviceの定義の中でAuto Scalingの設定したりとかもできるらしいですが、今回そこまでやってないです。要らないし。</p>
<h2>移行作業</h2>
<p>ぶっちゃけ、すごく簡単でそんなにやったことはないです。</p>
<p>はじめはTerraformで環境作るかとか思ってたんですが、~~tfファイルをゼロから書くのがだるくなったので~~他にも手段があるんじゃないかと調べていたところ、<a href="http://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ECS_CLI.html">ECS CLI</a>というAWS提供のコマンドツールがありました。</p>
<p>で、これがtask definitionとしてdocker-compose.ymlがだいたいそのまま使えるんですね。。なのでdocker-compose.ymlからTerraformへ定義を書き写すような面倒はかけず、移行が出来てしまうわけです。実行したコマンドはこれだけです。</p>
<pre><code class="language-bash"># clusterを起動
$ ecs-cli up --keypair hoge --size 1 --instance-type t2.micro --capability-iam --port 8080 3000 8086
# docker-compose.ymlからserviceを起動
$ ecs-cli compose --file docker-compose.yml service up
</code></pre>
<p>これだけでもう、コンテナはほぼ永続的に稼働します。便利ですね。今回は個人用なのでt2.microを1台しか上げてないですが、複数台インスタンスを上げればコンテナはイイ感じに分散してくれるみたいです。</p>
<p>ただ、<code>ecs-cli up</code>で賄えるのはあくまでEC2の範囲なので、ALBを使いたいですとか、EFSで各インスタンス間のデータを共有したいですとか、そういう要望がある場合にはマネジメントコンソールなりTerraformを使う必要があります。あくまで「とりあえずコンテナを動かす環境が何かあればいい」ぐらいの目的で使うものかなと。</p>
<p>まぁ自分の場合はプライベート用途で複雑な要件もなかったので、ECS CLIで十分です。構成管理という面でも、先のコマンドを書いたシェルスクリプトとdocker-compose.ymlさえあれば環境再現はすぐできるので、拍子抜けするほど楽でした。</p>
<h2>運用</h2>
<p>当初の動機が「コンテナがバンバン落ちる不健全な環境を抜け出したい」でもあったので、多少なり運用も組み立てています。</p>
<h3>監視</h3>
<p>自分がproduction環境でのDocker運用経験がほとんどないこともあり、正直ベストな監視の仕方がよくわかっていません。例えば最低10台以上のコンテナを動かしてガリガリ処理させたいような環境を動かしたいとして、稼働台数10台を下回ったらアラート上げたいと個人的には思うんですが、そういう運用でいいんですかね。それともオーケストレーションでコンテナ数確保されるから監視しなくてよい、のかどうなのか。</p>
<p>と言うのも、意外というかなんというか、Amazon CloudWatchではコンテナの稼働状態に関するメトリクスはほとんど取れません。CPUとメモリの使用率だけです。稼働台数ぐらいありそうなものなんですけどね。ECSの監視はどうしてんだろうみなさんというのは改めて調べておきたいところ。</p>
<p>結局のところ、自分は2方面で監視してます。</p>
<p>1つはCloudWatch Eventsで、serviceの稼動状態に変化が起きたことをトリガーとしてLambdaなどを発火できる機能があります。これを使ってコンテナが落ちたりしたときにはslackに通知されるようにしました（鏡音リンちゃんが教えてくれます）。ただ、先述の通り「落ちてもすぐ自動で上がる」ようにはなってるので、なんか頻繁に落ちてるなとか、落ちたまま上がらないなとかを気付くためだけの用途です。</p>
<p><a href="https://gyazo.com/589d57ff847e6d90239b9f2856a25620"><img src="https://i.gyazo.com/589d57ff847e6d90239b9f2856a25620.png" alt="https://gyazo.com/589d57ff847e6d90239b9f2856a25620"></a></p>
<p>2つ目はMackerelのDockerプラグイン。</p>
<p><a href="https://mackerel.io/ja/docs/entry/advanced/docker">Dockerをモニタリングする - Mackerel ヘルプ</a></p>
<p>これも1インスタンス上で動いているコンテナごとのメトリクスをグラフ表示するだけなので、コンテナ個別の死活などは取れないです。あくまでメトリクスグラフの描画のために使ってます。</p>
<p>聴くところだとDataDogはコンテナの稼働台数とか取れるみたいですね？</p>
<h3>バックアップ</h3>
<p>ECSのインスタンスを落としたらそのままデータ死ぬという状況はさすがに怖いのでバックアップ。これも悩みましたけど、ズボラにCloudWatch Eventsで日に1回EBSスナップショット取らせてます。</p>
<h2>罠っぽいところ</h2>
<p>最後にハマリポイントをいくつか。</p>
<h3>docker-compose.ymlが必ずしも直接使えない</h3>
<p>docker-compose.ymlがほぼそのまま使えるのは使えるのですが、具体的にはmemlimitを各コンテナで設定しておかないと、メモリ足りないと言って落ちたりします。CoreOSだとリソースなど見ずに上げろと言えば上げてくれるんですが、ECSはそのあたりシビアに見てます。</p>
<h3>ecs-cli service upが無限ループする</h3>
<p>コンテナのserviceを起動する<code>ecs-cli service up</code>コマンドですが、どうも一度起動命令を送った後、全コンテナがRUNNING状態になるのをひたすら待っているようで。</p>
<p>何かタスク定義に不備（先のメモリ不足とか）があるとserviceは一度落ち、そしてserviceは永続稼働前提なので再度コンテナを起動し、そしてまた落ちるという無限ループに陥るのですが、ECS CLIはそれを拾ってくれないです。なのでupしてからしばらく応答がなければ、無限ループに陥ったと判断し、コマンドキャンセルしてGUIからログとか見に行った方がいいです。</p>
<h3>Docker Hub Privateとの連携が面倒</h3>
<p>ECS上でDocker Hubのプライベートレジストリに置いたイメージを動かしたい場合、cluster上のインスタンスに一旦ログインして、設定ファイルにログイン情報を書き込む必要があります。ちょっと面倒だし、手段としてもあんまりイケていない感じがするので、もう少しなんとかならないかなと。まぁECR使ってくれってことなんでしょうけど。</p>
<h2>まとめ</h2>
<p>単純に「コンテナを動かす」だけであれば非常にシンプルに出来ており、docker-compose.ymlという既存の資産も使えるので、ECSが使われる理由はちょっとわかった気がします。特にECS CLIがあることで、Dockerイメージを更新したときなど、CIで自動的にデプロイをトリガーできたりするのはいいですね。</p>
<p>機会があればk8sも使ってみて、使い勝手とか比較したいところ。</p>
]]></description>
            <link>https://chroju.dev/blog/migrate_coreos_to_ecs</link>
            <guid isPermaLink="false">migrate_coreos_to_ecs</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 25 Sep 2017 23:36:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[AWS Certified Sysops Administratorを取得した]]></title>
            <description><![CDATA[<p><a href="https://aws.amazon.com/jp/certification/certified-sysops-admin-associate/">AWS認定Sysopsアドミニストレータ</a>という資格を取得しました。AWSには5種類の認定資格がありまして、レベル的には「アソシエイト」と「プロフェッショナル」の2段階に分かれるのですが、これは下位にあたる「アソシエイト」のものです。本当は「プロフェッショナル」にあたるDevOpsアドミニストレータがほしいなと思ったんですけど、受験資格としてSysopsが必要だったのでまずは、という感じで取りました。</p>
<h2>準備したこと</h2>
<p>試験要項には「モニタリングとメトリクス」とか「ネットワークの基本的な知識」といった抽象的な試験範囲は書かれているんですが、具体的にどのAWSサービスが出題されるかは書かれていないので正直勉強しづらかったです。ウェブで漁ればある程度受験記を書かれている方がいるので読んどいた方がいいのと、実際の問題に慣れる意味でサンプル問題は確認しておくこと、あと模試が2000円ぐらいで受けられるので受けとくのは必須です。サンプル問題も模試も先のリンク先から飛べます。</p>
<p>実際受けたところだと、Sysopsで出題されるサービスは以下あたりという感触。</p>
<ul>
<li>EC2</li>
<li>VPC</li>
<li>RDS</li>
<li>S3</li>
<li>Route53</li>
<li>ELB(Classic, ALBいずれも)</li>
<li>Auto Scaling</li>
<li>EBS</li>
<li>Elastic Beanstalk</li>
<li>ElastiCache</li>
<li>Opsworks</li>
<li>CloudWatch</li>
<li>CloudFormation</li>
</ul>
<p>ここに並べた各サービスについて、<a href="https://aws.amazon.com/jp/aws-jp-introduction/">AWS クラウドサービス活用資料集 | AWS</a>に存在するBlackBeltの資料を読み、その上でざざっと公式のドキュメントを眺めました。たまによく読まないと解けない引っ掛けはありますが、重箱の隅をつつくような変な問題はないので、きちんとサービスの仕様とプラクティスを押さえれば得点はできます。準備期間は1か月ぐらい？</p>
<p>ただ、自分の場合はこの大半のサービスを実際に使った経験があるので、それにより得点できた感は否めないです。逆に触ったことがないElastiCacheあたりは弱かったりしたので、触っとくか、それが難しい方ならAmazonが開催しているトレーニングを受講した方がたぶん無難です。</p>
<h2>問題の傾向</h2>
<p>実際に出る問題はユースケースを想定したものが多く、丸暗記でどうにかなる感じではないです。</p>
<ul>
<li>構成に関する情報が記載され、そこからシングルポイントを見つける問題
<ul>
<li>IGWやVGWやNGWとか、AWSマネージドの範囲がどう冗長化されてるか答えられないといけない</li>
</ul>
</li>
<li>RDSやEC2のインスタンス障害時の想定動作</li>
<li>欲しいメトリクスをAWSサービスを使って取得、通知する方法の考案</li>
<li>ネットワークの疎通ができない際や、CPU等がサチってるときの対処方法を考えさせる問題</li>
<li>クライアントが保存するデータの高セキュリティな保管、読み出し方法を考えさせる問題</li>
<li>負荷上昇を見据えて、可用性と金銭的コストを踏まえた適切なスケーリング設計の作成</li>
<li>既存のオンプレミスデータセンターと連携した上で、高可用なシステムを組む問題</li>
</ul>
<p>こんな感じですかね。漫然とAWSを使っているとわからないけど、EBSの種類をちゃんと吟味してるかとか、SPOFが無いかどうかつぶさにチェックしているかとか、そういう点で差がつく気がします。</p>
<h2>今後</h2>
<p>冒頭にも書いたとおりDevOpsも受けようと思います。が、この手の資格にはつきものの2年ごとの更新が面倒だなぁという気もしたりしてどうも。AWSは必要なサービスを必要なだけ使えればそれでいいものだとは思いますが、網羅的に仕様を押さえてどっぷりAWSを使いこなしたいという場合には、体系的な知識獲得に悪くない資格だと感じてます。</p>
]]></description>
            <link>https://chroju.dev/blog/aws_sysops_administrator</link>
            <guid isPermaLink="false">aws_sysops_administrator</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 26 Aug 2017 03:04:57 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[builderson2017に行ってきた]]></title>
            <description><![CDATA[<p><a href="https://builderscon.io/tokyo/2017">builderscon Tokyo 2017</a>に行ってきた。最初会場をSFCと勘違いしてましたが、慶應の日吉の方でした。日吉駅周辺、大学を前提に作られている放射状の道が美しいですね。</p>
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3246.0166435539!2d139.64466915084074!3d35.55329114448822!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x60185f76e18c9d4d%3A0xc4a6f4b87d35fcb0!2z5pel5ZCJ6aeF!5e0!3m2!1sja!2sjp!4v1501994501383" width="600" height="450" frameborder="0" style="border:0" allowfullscreen></iframe>
<p>会場になっていた<a href="http://www.kcc.keio.ac.jp">協生館</a>は大学施設というよりは少し街に開かれているのか、コンビニがあるのはもちろん、驚いたことにHUB（スイッチングじゃなくて酒飲めるアレ）があったり、ホールには全席電源とLANポートが完備されていたり、IT系カンファレンスには最適の場所じゃないかという声をTwitterで見かけたりしました。とてもいいとこでした。</p>
<p>ビルコン初めてでしたけど、名前通りにと言うのか、まさに何かを「build」しましたという発表が多かったり、テーマでもある「知らなかったを聞く」機会に多く恵まれてよかったです。自分はOps側の人間なので、それほどbuildするという機会が多くはないんですけど、あんまりそこにハードル高く考えず、なんかやってみたいなと思ったら稚拙でもいいから作ればいいんだなという感覚が強くなった気がします。</p>
<p>あと完全に私事ですが元同僚と遭遇したりして、前職と今とで全然やってること違うのにこういう機会があるってこと、ジャンルの壁を設けない横断的なカンファレンスってやっぱいいなと思いましたね。会社という枠が良い意味でそれほど強い意味を持たない、というのはこの業界の好きなとこです。</p>
<p>今回は以下のセッションを聴きました。いずれもbuildersconのページからスライド資料に飛べるはずです。</p>
<ul>
<li>横山三国志に「うむ」は何コマある？〜マンガ全文検索システムの構築
<ul>
<li>この週末だいぶバズったアレです。</li>
<li>コマの切り取り、OCR、全文検索、ウェブページのフロント、それぞれにOSSを的確に使っていて、発表自体もすごく参考になりました。</li>
<li>個人利用できて楽しいことできるAPIとか結構あるんやんと思った。APIに自分でも触ってみたくなるセッション。</li>
</ul>
</li>
<li>Anatomy of DDoS
<ul>
<li>CloudFlareの中の人によるゲストセッション。</li>
<li>DDoSと一口に言ってもOSI7層それぞれに手法と対応があるとか、IoTでデバイスばらまかれるとそれだけセキュリティの穴も増えるよねみたいな基礎から丁寧な話。</li>
</ul>
</li>
<li>RDBアンチパターンリファクタリング
<ul>
<li>今回のベストトーク賞。</li>
<li>RDBに限らずリファクタリング全般に言えるYAGNIの話、技術的負債のうちどれを優先して返済するのかみたいな視点が参考になった。</li>
</ul>
</li>
<li>LT
<ul>
<li>QRコードは分割できるという話がマニアックながら何かに使えそう。</li>
<li>もうマジで何でもいいから作ればいいじゃんという感を覚えた。作るは正義。</li>
</ul>
</li>
<li>サーバーサイドKotlin
<ul>
<li>Kotlinのnullable型がよいという話。</li>
</ul>
</li>
<li>OSSで始めるセキュリティログ収集
<ul>
<li>osqueryの話</li>
<li>OSからログ、メトリクス情報を吸い出す手段って対象ごとにバラけてて面倒だなと思ってたんだけど、それに対する1つの回答になりそう。</li>
</ul>
</li>
<li>OSS貢献超入門
<ul>
<li>がんばりましょう。。。時間つくりましょう。。。</li>
</ul>
</li>
<li>Serverless Server Side Swift
<ul>
<li>Swiftはバイナリで動いてランタイム要らないのでAWS Lambdaで使えるって話。</li>
<li>Lambdaのランタイム制約しんどいって話はよく聞くけど、正直バイナリそのまま突っ込んでまで別言語使いたいという気持ちはいまいちわからない。</li>
</ul>
</li>
<li>ここが辛いよサーバーレス。だが私は乗り越えた
<ul>
<li>サーバーレス実運用した上でのノウハウの話。</li>
<li>フェイルオーバーの実装とか、テストのときの環境エミュレートとか。つらいのとてもわかる。</li>
</ul>
</li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/builderson_2017</link>
            <guid isPermaLink="false">builderson_2017</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 06 Aug 2017 12:25:43 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Toilの地獄から抜け出す術を知りたい]]></title>
            <description><![CDATA[<p>最近とても停滞感があってよろしくないので一度ブログに吐き出すなどします。</p>
<h2>Toilが多すぎる</h2>
<p>現状、自分はオペレーションエンジニア（決まった手順しかやらないオペレーターではなくて、問題解決や運用体制の構築とかやる感じの）という位置付けで働いていて、日々のシステム運用に関するタスクをもろもろ片付ける他に、長年澱のように蓄積された技術的負債とか、暗黙的な運用を改善していくことも任務だったりします。Googleが名付けたところで言えば前者がToilってやつですね、いわゆる。自動でできるはずなのにマニュアルで行われていて、サービスの増加に比例してどんどん業務を圧迫していくような類の仕事。</p>
<p>で、<a href="https://landing.google.com/sre/book/chapters/eliminating-toil.html">SRE本</a>ではToilを日常の仕事の5割以下に収めろと言ってるんですが、全然自分の場合収まっていない。TodoistやTogglで最近はToilが1日に占める割合を計測しているのだけど、いずれもほぼ8〜9割。実感としても将来的な投資に費やせている時間ってのがほとんどないです。</p>
<p>実際のところ何がToilとして積み重なっているのかというと、手動でコマンドを打つような作業がほとんど。弊社では基本的に本番稼働中のシステムでオペレーションする人間を限定しているので、デプロイや設定の確認（ドキュメントがなかったりバージョン管理してなかったりするので、実機確認が必要になる機会が多々ある）等々自分らがやらねばならんのですが。しかし手動でやることがあまりに多い。数年に渡ってエンジニアのUNIXコマンドスキルに依存していた運用のツケが回ってきている。ある程度自動化すればいちいち手を動かさなくてよかったり、サーバーの状態、設定を確認するような作業であれば適切な可視化をすれば済む話であったり、解決策は見えているのだけど、手を打つ方に時間を回せていない状態。それなりに「どうすればいいか」がわかってはいるので、その分余計に「改善に時間が回せない」ことへの歯がゆさが強くてメンタルに優しくなかったりしている。</p>
<h2>改善に必要なスキルは多方面に渡る</h2>
<p>DevOpsなんて言葉はもう枯れていて、SREという職種も珍しくなくなってきた昨今、先に挙げたようなありがちな技術的負債に対する汎用的な解決策は世の中に溢れていて、自分も見知ってはいる。でも、それを実際にどう現場へ適用していくかが本当の課題。</p>
<p>そもそもの時間が取れないってのはどしたらいいんですかね。『<a href="https://www.amazon.co.jp/dp/B00QQKCV6E">エッセンシャル思考</a>』よろしく、本当に必要な依頼以外は「断る」というのは1つの選択かもしれない。うまいことやらないと怒られそうだけど。個人的な思いとしてはある程度残業時間増やしてでも時間確保するしかねーなってのと、あとは改善を進める効率を上げることなのかなと。例えばチームで使っているツールのAPIを叩くラッパースクリプトを書いたりとかよくしてるんですが、自分はお世辞にもプログラムを書くのが速い方ではないので、最近は1年ぐらいプログラマーとして働いてスキル上げたいなと思うぐらい。</p>
<p>時間が取れたとして、どうするか。改善は大きなことをいきなりやろうとしてもうまくいかないので「小さく始める」というのはよく言われることですが、小さく始めるにしても自分の業務だけが楽になるんじゃ意味がないから、自ずと他の人を何かしらは巻き込む形になる。なのでコミュニケーションスキル、と言わずともプレゼンテーションスキルは少なくとも必要。そう、技術的な解決策をいくら知っていてもそれだけではダメで、やはり組織でやっていく以上、当たり前の話として対人的なスキルは不可欠になるんですよね。自分が楽になるから、確実性が上がるから、ではなくて、双方ハッピーになれるという話をしなくてはならない。これが結構難しくて。単に設定をバージョン管理して可視化します、という話であっても、元々その設定を確認して開発に活用していた人たちの業務プロセスには変化が生まれる。それをメリットとして受け入れてもらえるか。改善を進めるというのを自分は十字軍にはしたくないと思っていて、そのへんのバランスには常々気を遣っていたり。</p>
<p>あとは自分の現場のように多方面に様々な課題が山積していると、その中のどの課題をまず解決するか、どのように解決するかという取捨選択も重要。局所最適にならず、なるべく全体最適で、さらにレバレッジを効かせられるようなことからどんどんやっていくべきで、些末なことに囚われるべきではない。どうしても課題をパラパラ並べていくと、手を付けやすそうなこととか、技術的に面白そうなことからやりたくなっちゃうんだけど、そこをグッと我慢しなければならない。</p>
<p>つわけで改善、と一言で言っても、求められるのは純粋なコンピュータに関する技術、だけではなくて、社会学や人文学がやっぱり必要になってくるなぁというのを実感する日々です。そしてそのどれもが自分には足りていないような気がして、強く閉塞感を覚えてしまっているのも事実であり。課題は一度バラして並べてあるので、それがなかなか崩れていかないのがとてももどかしくてしんどい。</p>
<h2>あらゆる情報の流れを制御したい</h2>
<p>まぁしんどい話ばかりしていても仕方ないので具体的にやっていることも書きます。。だいたいは散逸してしまっている運用を統制していこうという向きが強い。</p>
<ul>
<li>時系列データベース（主にinfluxDB）を用いたメトリクスデータの集約。</li>
<li>あらゆるもののバージョン管理、コマンドによるオペレーションの推進、必要に応じてAPIをラップしたCLIツールの作成。
<ul>
<li>
<p>Ansibleやfabricでの構成管理、デプロイの統一。</p>
<ul>
<li>言語はだいたいPythonを使っているけど、クロスコンパイルしてバイナリ配布できるGoに興味がある感じ。</li>
<li><a href="https://chroju.github.io/blog/2017/05/05/infrastructure_as_code_book/">Infrastructure as Code</a>記載の構成レジストリ（サーバー情報を集約したデータベース）やKVSによる設定情報の統制管理。</li>
<li>あとは人間のオペレーションをどうコントロールできるか、という視点から認知科学やデザインを少しかじったり。</li>
</ul>
<p>とにかく暗黙知に頼った運用が多すぎて、結果として「運用でカバー」せざるを得なくなってToilがかさむ、という本当にしんどい循環をしてしまっているので、様々な情報の集約、可視化、管理をしたい感じ。たぶん自分が興味あるのは情報の流れをつくる、それに乗せることで人間の仕事を最適化していくということっぽいんですよね。それができるのはとても楽しくはあるけど、つらくもあり。結果技術というよりプロセスの話を最近多く学んでいるのでブログも書けてなかったり。そういや暗黙知つながりでポランニーの『暗黙知の次元』読んだりもしてるのだが、もはや自分が何屋かわからんな。</p>
<p>ちょっと正解が何なのかよくわからなくなってきたので、一旦立ち止まって冷静にならないとダメそう。</p>
</li>
</ul>
</li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/very_exhausted_because_of_toil</link>
            <guid isPermaLink="false">very_exhausted_because_of_toil</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 12 Jun 2017 14:35:55 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[O'Reilly『Infrastructure as Code』読了]]></title>
            <description><![CDATA[<p><a href="https://www.oreilly.co.jp/books/9784873117966/">O'Reillyの『Infrastructure as Code』</a>を読んだ。従来Ansibleの本、Chefの本といった各ツールの使い方にフォーカスした本はいくらか出ていたけれど、おそらく「Infrastructure as Code」の考え方や、システム運用への採用方法を包括してまとめた本は初めてということになるのかな。</p>
<h2>ツールとプロセス</h2>
<p>端的に内容を説明してしまうと、Infrastructure as Codeで使用するツールを</p>
<ul>
<li>ダイナミックインフラストラクチャプラットフォーム（AWS等パブリック、プライベート問わずプログラマブルな操作が可能なインフラプラットフォーム）</li>
<li>インフラストラクチャ定義ツール（Terraformのような、構築するインフラ環境を定義するツール）</li>
<li>サーバー構成ツール（Ansible、Chef等のサーバー内部の設定を定義するツール）</li>
<li>インフラストラクチャサービス（モニタリング、サービスディスカバリ等の環境管理用のツール）</li>
</ul>
<p>の4つに大きく分類して、</p>
<ul>
<li>インフラのプロビジョニング</li>
<li>サーバーテンプレートの管理</li>
<li>サーバーのアップデート、更新</li>
<li>サーバーの破棄</li>
</ul>
<p>といったライフサイクルを、各ツールを使ってどう管理するかを説いた本。後半で第10章をまるごと「インフラストラクチャのためのソフトウェア工学プラクティス」の説明に充てて、継続的インテグレーションやVCSの方法論を書いていたりして、DevOpsの名のもとにソフトウェア管理に対して導入されてきた手法を、インフラへも適用していくための本になっている。なのでサーバーを構築したらそれでおしまいではなくて、ダイナミックにサーバーが生成／廃棄される環境であれば、自動的にログは退避できるようにしておく必要があるだとか、システムマネジメント全体に焦点が当てられている。</p>
<p>ツールの使い方自体はドキュメントを読むなり、Qiitaを探るなりすればだいたいわかるんだけど、それをどう運用すれば効率的になるのか、より効果が得られるかという、プラクティスを知りたい思いが強かったので、大いに参考になった。</p>
<h2>徹底的な自動化アプローチ</h2>
<p>例えばプロビジョニングは「インフラストラクチャ定義ツール」でサーバーを構築し、その内部を「サーバー構成ツール」で設定するわけだけど、2つのツールを個別に手動実行するのではなくて、前者から後者へどう情報を受け渡して、自動的にプロビジョニングを済ませるかが肝になる。</p>
<p>Terraformであれば、EC2を立てた後に自動的にAnsibleを呼ぶようなことも機能でできるらしいけど、そういった連携の仕組みがツール自体に存在しなければ、構築したサーバーのIPアドレスやユーザーの情報を「サーバー構成ツール」へ渡す必要がある。1例として挙がっていたのが「構成レジストリ」と呼ばれる、サーバー情報を中央集権的に管理するツール。インフラストラクチャ定義ツールは立てたサーバーの情報をここに登録し、サーバー構成ツールが情報を引き出して、サーバー設定のデプロイを行う。具体的に「構成レジストリ」として使えるツールについてはそれほど言及がなかったけど、CygamesだとElasticsearchを使ってサーバー情報を管理しているという話を聞いたことがあって、実装としてはこれに近いのだと思う。</p>
<script async class="speakerdeck-embed" data-slide="46" data-id="c6f07c336b90417f9a1361c9afb5eb07" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script>
<p>あるいはAnsibleなどを導入したときによく聞かれるのが、結局手動でサーバー構成を変更してしまって、Playbookと実情に乖離が出てしまうという問題（本書ではこれによる構成差異の発生を「構成ドリフト」と呼んでいる）。これに対してはイミュータブルなサーバー管理をするのが最も良いとされる。なぜなら構成ドリフトを起こしても、定期的にイチから生成したサーバーに置き換えられていれば、そのたびに構成ドリフトもリセットされるから。</p>
<p>この本全体で貫かれているのは、とかく徹底的な自動化と、ワークフローのパイプライン化を行なって、各タスクからシステム管理者の手動オペレーションをなくすということ。これによりシステム管理者はインフラ構築、変更の「門番」としての役割から解放され、問題への対応といったより生産的なタスクへ移ることができるし、システムの変更によりサービスに対して発生する影響も低減できるとしている。</p>
<blockquote>
<p>自律的なオートメーションこそ、Infrastructure as Codeが確実に機能する秘訣である。チームがセキュリティを向上させる新しいウェブサーバーの設定オプションを見つけたら、それをオートメーションツールのなかに組み込む。チームは、もう1度そのことについて考えようとしなくても、現在及び将来のすべての関連サーバーにそれが適用されることを知っている。 (p.254)</p>
</blockquote>
<h2>共通言語として利用したい</h2>
<p>先述した「構成ドリフト」のように、本書ではいくつかあまり聞き慣れない用語（構成ドリフトを起こしたサーバー群を「スノーフレークサーバー」と呼んだり、イミュータブルに何度も破棄されては生成されるサーバーを「フェニックスサーバー」と呼んだり）が使われているのだけど、アンチパターンやグッドプラクティスを共有認識にする上では、名前がついているほうが話が通じやすいので、この本の用語が共通言語になっていくとうれしいなと思ったり。そういえば、プラクティスに名前を付ける手法は<a href="https://www.amazon.co.jp/dp/462108786X">『Fearless Change』</a>でも使われていた。</p>
<p>で、結論としてとても良い本だとは思うのだけど、これを全部導入するとなるとなかなかにパワーが必要になる。特に、すでに手動でのサーバー管理を絶賛実施中の環境に対して導入する場合には、インフラに対する考え方自体を、秘伝のタレのように継ぎ足して使うものから、外部で管理している設定と常に同期して使うもの、すぐに破棄と生成のサイクルを回せるものへと変えていかなくてはならないので、組織的な協力が必要になってくる。しかも必要なのは一部ワークフローの自動化ではなく、徹底的な自動化、インフラ環境の自律的な動作。</p>
<p>まぁ、とはいえインフラパイプライン全体をいきなり用意して導入するのも難しいのは確かなので、まずは頻繁に変更が入る設定など、Infrastructure as Codeの恩恵が大きそうなところから始めてみるべきかと思う。少しずつでも確実にこれは実現していきたいなと思える本だった。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117968/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/51YYyQ6-t6L._SL160_.jpg" alt="Infrastructure as Code ―クラウドにおけるサーバ管理の原則とプラクティス" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117968/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Infrastructure as Code ―クラウドにおけるサーバ管理の原則とプラクティス</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 17.05.05</div></div><div class="amazlet-detail">Kief Morris <br />オライリージャパン <br />売り上げランキング: 25,983<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117968/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
]]></description>
            <link>https://chroju.dev/blog/infrastructure_as_code_book</link>
            <guid isPermaLink="false">infrastructure_as_code_book</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 05 May 2017 08:53:22 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[VimperatorからVivaldi + Vimiumへ乗り換える]]></title>
            <description><![CDATA[<p>Firefox 51から、Vimperatorの一部機能が使用できなくなる状態が発生した。これについてはGitHub上でFixが進んでいるが、2017-02-15現在だとまだ修正版の公開までには至っていない。</p>
<ul>
<li><a href="https://github.com/vimperator/vimperator-labs/issues?utf8=%E2%9C%93&#x26;q=is%3Aissue%20FF51">Issues · vimperator/vimperator-labs</a></li>
</ul>
<p>もう数年間vimpを使っている身として、一時は修正版を待とうかとも思ったのだが、<a href="http://internet.watch.impress.co.jp/docs/news/1031773.html">今年11月からWebExtentionに移行する</a>際にも同様の混乱が様々ありそうだし、代替策の模索を始めた。</p>
<h2>Why Vivaldi ?</h2>
<p>とはいえ、今の時代に代替となるブラウザはほぼChrome一択になってしまう。ChromeにもVimライクなKey configを実現する<a href="http://internet.watch.impress.co.jp/docs/news/1031773.html">Vimium</a>があり、触れたこともあるのだが、自分はどうもChromeが苦手で移れずにいた。</p>
<p>一番大きいのがUIをカスタマイズする余地がないこと。例えばFirefoxだと多段タブをTab Mix Plusで実現しているのだが、Chromeだとこういったことはできず、大量のタブを開くとファビコンのみの表示に縮小されてしまう。またアドレスバーが上部で固定されているのも、個人的には邪魔くさい。</p>
<p>そこで<a href="https://vivaldi.com/">Vivaldi</a>を採用しようと考えた。VivaldiはChromeエクステンションが互換動作するのでVimiumも使える上、UIがかなりフレキシブルにカスタマイズできる。</p>
<p><a data-flickr-embed="true"  href="https://www.flickr.com/gp/chroju/3ZEy43" title="vivaldi"><img src="https://c1.staticflickr.com/1/298/32875812446_92ae4222dc_z.jpg" width="640" height="452" alt="vivaldi"></a><script async src="//embedr.flickr.com/assets/client-code.js" charset="utf-8"></script></p>
<p>多段タブこそできないものの、タブバーを上部ではなく横に表示することで、ファビコンだけに縮小されることは免れた。アドレスバーも要らないと言えば要らないのだが、SSLの確認用途もあるので下部表示へ変更している。</p>
<h2>Vimperator to Vimium</h2>
<p>まずそもそもなのだが、VimiumではVimperatorの完全な代替には成り得ない。Vimperatorの真髄はjavascriptを介してOSの挙動を骨の髄までコマンド操作に置き換えるところにあったわけだけど、Vimiumでコマンド操作可能なのは、あくまでエクステンション内部で定義されているものに限られる。Vimperatorのような好き勝手はできない。</p>
<p>なのでVimperatorで自分にとってのキラーとなっていた機能だけでも移植を検討した。</p>
<h3>Key mapping</h3>
<p>key mappingは自由に替えられるので、自分の<code>.vimperatorrc</code>に合わせる形で変更した。</p>
<p>なおctrlキーを交えたマッピングを行う場合、ブラウザデフォルトのショートカットと衝突する恐れがあるが、Vivaldiはショートカット定義を自由に替えられるため、キーバインドを解除すれば衝突しなくなる。</p>
<pre><code>unmap d
map d removeTab
unmap T
map b Vomnibar.activateTabSelection
map ;t LinkHints.activateModeToOpenInNewForegroundTab
unmap X
map u restoreTab
map @ togglePinTab
map O Vomnibar.activateEditUrl
map l nextTab
map h previousTab
unmap &#x3C;c-h>
map &#x3C;c-h> moveTabLeft
map &#x3C;c-l> moveTabRight
</code></pre>
<h3>quick marks</h3>
<p>Vimのmarkっぽい機能として、VimperatorではURLにmarkを設定できるquickmarks (qmark) という機能があって重宝していた。例えば<code>q</code>にQiitaを設定しておくと、<code>goq</code>でカレントタブ、<code>gnq</code>で新しいタブにQiitaが開く。</p>
<p>Vimiumでは再現できなかったので、現状Vomnibar（ブックマーク、履歴等からインクリメンタルサーチするランチャー）からブックマークを呼ぶ形で対応している。どうもREADMEを読む限りでは<code>map X createTab http://www.bbc.com/news</code>といったキーバインドが可能らしいのだが、なぜか上手くいっていない。</p>
<h3>copy.js</h3>
<p><a href="https://github.com/vimpr/vimperator-plugins/blob/master/copy.js">vimperator-plugins/copy.js at master · vimpr/vimperator-plugins</a></p>
<p>Pluginになるが、URLやページタイトルを加工して好きな形でクリップボードへ取り込むコマンドを設定できる、copy.jsというものがあった。</p>
<p>こちらも再現はできなさそうなのだが、ブログ等を書くときにMarkdown形式でのURLコピーがどうしてもほしかったので、Vomnibarからbookmarkletを呼ぶ形で対応している。</p>
<h3>commandBookmarklet.js</h3>
<p><a href="https://github.com/vimpr/vimperator-plugins/blob/master/commandBookmarklet.js">vimperator-plugins/commandBookmarklet.js at master · vimpr/vimperator-plugins</a></p>
<p>ブックマークレットをコマンドで呼べるPlugin。そもそもVimiumにはコマンドモードがないので土台無理なわけで、Vomnibarから呼ぶという手段に頼るしか無くなっている。</p>
<p>良くも悪くも、以前コマンドモードでやっていたことは、ブックマークレットで再現してVomnibarからどうにかして呼ぶ、という形でだいたいは回避している。</p>
<p>また一方でVivaldiには「クイックコマンド」という機能があって、デフォルトだとF2を押すとVomnibarにも似たランチャーが起動する。ここからブックマーク、履歴、オープンなタブ、設定項目等をインクリメントに呼び出せるので、Vimiumが無くてもある程度キーボードで操作ができたりする。まぁ、インクリメンタルサーチするより、Vimiumの割り当てコマンドの方がタイプ数は少なくて済むので、あまり使ってはいない。</p>
<h2>frustrated</h2>
<p>以上の設定でなんとなく使えてはいるのだが、不満の話も。</p>
<ul>
<li>マスターパスワード設定がないので、あまりパスワードを記憶させたくない。</li>
<li>Firefox Syncのようなブックマーク、エクステンションの同期機能がない。</li>
<li>http/https以外のプロトコルで開いているタブ上では、Vimiumが効かない。</li>
<li>Vimiumは<code>.vimperatorrc</code>のような設定の外出しが出来ない。</li>
</ul>
<p>そもそもにして、Firefoxの先を儚んでいるときに、先が不透明な更なるマイナーブラウザに移るという選択もどうかと思ったが、Vivaldiの開発が終わってしまった暁には大人しくChromeに移ろうと思う。</p>
]]></description>
            <link>https://chroju.dev/blog/vimperator_to_vivaldi</link>
            <guid isPermaLink="false">vimperator_to_vivaldi</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 15 Feb 2017 14:30:43 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[サーバーレスっぽいインフラをどう管理していくか]]></title>
            <description><![CDATA[<h2>きっかけ</h2>
<ul>
<li>VPSで設置していたプロフィールサイト（静的HTML）をサーバーレスで動かした方がコストダウンになるのではないかと考えた。</li>
<li>とはいえ完全に静的なサイトだとS3だけで事が済んでしまい面白くない（）ので、自分のブログの最新エントリーを動的に書き加えるような処理を与え、動的に生成されるページをLambdaで作ることにした。</li>
<li>サーバーレスの時代にいくつかデプロイフレームワークが出てきていたので、それを使えればと思った。</li>
</ul>
<p>……という感じでサーバーレスっぽい何かを作った。いや作ろうとしたってレベルか……。</p>
<p>実は個人で使っているクラウド上のサーバーが、今年1月の時点で3台ありまして。1台はプライベート用途のContainer Linux @さくらクラウド。1台は先に書いたパブリック用途のウェブサーバー @さくらVPS。んで踏み台として、必要なときだけ起動するEC2を1台。ああ、もう1台Herokuもhubot用に使ってたか。これはDockerにしちゃって消しましたが。</p>
<p>まぁさすがにちょっと無駄に多いから整理したいなという思いがきっかけとなった。VPS、数年前だとエンジニアは1人1台持ってnginxとMySQL運用しろみたいな気風もあったけど、なんだかそんな時代も去った感もあり。どちらかと言えばどこかのPaaSでなんか作る方が今風なのかも。</p>
<p>詳細な設計は<a href="http://qiita.com/chroju/items/827dbb9e820f41820e14">Qiitaに上げました</a>ので、そちらをご参照ください。</p>
<h2>使用したツール</h2>
<h3>サーバーレスなデプロイツール</h3>
<p>これらのフレームワーク群をまとめてどう呼べばよいものか。。。「サーバーレスフレームワーク」がしっくり来るんだけど、これはすでに使ってしまっているプロダクトがあるから使えない……あの名前、汎用的過ぎてちょっとどうかと思うんだけど。</p>
<p>今回せっかくなので、フレームワークを使ってみることにしました。試したのは以下3種類。</p>
<p>| 名称 | カバー範囲 | 感想 |
| --- | --- | --- |
| <a href="https://github.com/serverless/serverless">Serverless Framework</a> | 中でCloud  Formationを使っているのでわりとなんでも。 | 多機能で何でもできる印象。CFn直接使うのと学習コストを比べたい感じがする。 |
| <a href="https://github.com/awslabs/chalice">chalice</a> | API Gateway, Lambda | レスポンスがjsonに限定されるなどまだ機能は少ないが、その分簡単なAPIならサクッと作れて楽。何よりIAMポリシーを自動生成してくれるのが最高。 |
| <a href="https://github.com/apex/apex">Apex</a> | Lambda | Lambdaを手作業でzipしてデプロイするのが面倒なときに使いたいツール。GolangでLambdaを書けたりする機能もある。 |</p>
<p>試用の結果、今回の目的はHTMLの返却だったのでchaliceは一旦諦めて、Serverless Frameworkでもよかったんだけど、ちょっと今回払う学習コストとしては見合わなさそうな印象があったので、Apexを使うことにした。</p>
<p>触った印象としてはApexも非常に学習コストが少なくて良いのだが、今後に期待したいのはChalice。awslabsが作っているので、というのもあるけれど、おそらくサーバーレスアーキテクチャーとして多い用途の1つであろう、API GatewayとLambdaを使ってREST APIを返す、という使い方においては必要十分な機能が満たされているように思います。</p>
<h3>HTML5 UP!</h3>
<p>以前は自分でせこせこHTMLやCSS書いてたんですが、カッコよいデザインがいいので今回は<a href="https://html5up.net/">HTML5 UP!</a>を使いました。やりたいことに注力して、専門外の部分は外から力借りるってとても大切だし、今はあらゆる側面でそれができる時代になりました。以下の記事のおかげです。ありがとう。</p>
<ul>
<li><a href="http://qiita.com/mhimuro/items/405590746e67971aac47?utm_content=buffer86566&#x26;utm_medium=social&#x26;utm_source=twitter.com&#x26;utm_campaign=buffer">「プログラマでしょ？ホームページ作ってよ！」を1日で対応する - Qiita</a></li>
</ul>
<h2>サーバーレスの管理問題</h2>
<p>冒頭に挙げたQiitaの記事に書きましたが、だいーぶ四苦八苦しました。かれこれ2週間ぐらい？かかった？</p>
<p>例えばRDSやEC2ならオンプレで使っていたLinuxなりMySQLなりを単に置き換えたものとして扱えるわけですけど、API Gatewayなどは抽象化されたインフラなので、どんな機能を持っているのかは全部AWSの采配次第なわけです。従って当然ながらできることとできないことがあり、それをきちんと把握した上で、低コストでアーキテクチャーを設計するというのはなかなかにサービス仕様への理解が必要になります。AWSを持ち上げすぎることは、ベンダーロックインとどう違うのかという意見もありますが、まさにそれです。</p>
<p>使えるようになると確かにとても楽ではありますが、一方でこれに依存し切るのもどうなんだろうな、という思いがあるのも事実で。要所要所でLambda + API Gatewayを限定的に使うならまだしも、3つ4つのサービスを繋がるピタゴラスイッチになってきたら管理コストの方が高くなる可能性が強そうです。先に挙げたApexやChaliceが非常にシンプルなデプロイツールになっているのは、構成自体もシンプルに仕上げるためだと思います。Serverless Frameworkのように守備範囲の広いツールは一見便利ですが、その分カオスにもなりやすい。</p>
<p>サーバーレスとかマイクロサービスやりたいなら、Lambda中心に組み上げるのもいいけど、Dockerやコンテナ指向になった方が幸せになれるんじゃないかなぁ、とぼんやり考えています。いや、わかんない。今後ひょっとしたらサーバーレスを管理するための画期的ツールが現れるのかもしれないが、現時点では「使いすぎる」ことは避けたいなという思いです。構築コスト、運用コスト、さらには更改コストとはきちんと天秤にかけたいところです。</p>
]]></description>
            <link>https://chroju.dev/blog/try_on_serverless_architecture</link>
            <guid isPermaLink="false">try_on_serverless_architecture</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 07 Feb 2017 06:37:51 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Baroccoで分割キーボードデビューした]]></title>
            <description><![CDATA[<p><a data-flickr-embed="true"  href="https://www.flickr.com/gp/chroju/hY667o" title="Baroccoとどいた"><img src="https://c1.staticflickr.com/1/579/31813875193_36398a3d15.jpg" width="500" height="500" alt="Baroccoとどいた"></a><script async src="//embedr.flickr.com/assets/client-code.js" charset="utf-8"></script></p>
<p>20代がまもなく終わってしまうということもあり、今年はある程度健康維持、環境維持というところに注力して、快適かつ健全な肉体と精神を保とうと一応考えてます。んでその一環として1日の半分近くを費やすキーボード入力の身体への負担を改善すべく、 <a href="https://www.mistelkeyboard.com/keyboards">Barocco</a> を買いました。</p>
<p>昨年10月に国内で販売開始、その後さまざまなレビューは出ているので、懸念点は織り込み済みで、半ば流行り始めである分割キーボードの将来に投資する意味合いを込めて購入に至った感覚です。まぁErgoDoxに投資するほどガチでは今のところないかなとか、あまりに通常のキーボードからかけ離れると他のキーボード使いづらくなりそうとか考えた結果、Baroccoが妥当ではという判断に落ち着きました。よく聞かれる不満としてHHKBとの配列や機能的差異があったんですが、幸い？にもHHKB未経験なのでその点は問題なく。</p>
<h2>Impression</h2>
<p>使い始めてまだ1週間も経っていないので、慣れが必要ではあるし、判断には時期尚早ではあるけど、今のところ悪くないなという感じです。</p>
<h3>キー配列</h3>
<p>キー配列はHHKBとの比較、というのはわからないものの、確かに少ししんどいところがあって、例えばバッククォートがFn + ESCという変則仕様でだいぶつらい。</p>
<p>また自分はアローキーをよく使うんですが、これもFn + j, k, l, iで少々微妙。キー配列を替えているのは今のところ以下。</p>
<ul>
<li>アローキーはデフォルトの機能で「右下Shift , Fn, Pn, Ctrlをアローキーに変更できる」というものがあったので、これを使用。</li>
<li>アローキーに変更して埋もれたFnは、右Altに担わせる。</li>
<li>Aの隣のCapsLockをCtrlに変更（ただし、これは元から使っていたソフトウェア側の機能）。</li>
</ul>
<h3>タイプ感</h3>
<p>あんまりメカニカルを使ったことがないし、キーボードマニアでもないんですけど、打ちやすいし不満はないです。CHERRY MXなので期待を裏切ることはないかと。メカニカルは黒軸と青軸しか経験ないんですが、今回も黒軸にしました。赤軸がオーソドックスな気がするんですけど、店頭で試しに触ってみてもどうもあの軽さに馴染めなくて。</p>
<h3>分割キーボード</h3>
<p>肝心の「分割」という点ですけど、真ん中に位置するYやBは両手どちらも使って打っていたので、たまに空振ったりしてます。でもそれを除いてはそれほど問題なく打てています。</p>
<p>変わったのは姿勢ですね。弊社はアーロンチェアが支給されていて、この椅子って基本的に深く腰掛けるのがベストな座り方だと思うんですけど、これまではついつい前かがみになってしまい、いまいち活かしきれてなかったんです。Barocco導入後は深く腰掛けて、胸を開き、両手を軽く開いた場所にキーボードを配置できるので、アーロンチェアに合った座り方ができるようになった気がしてます。両手のポジションを自由に決めてタイピングができるというのは思っていたより快適でした。いいんじゃないでしょうか、分割キーボード。</p>
<h2>結果</h2>
<p>よい買い物だったと思います。ただメカニカル、ちょっとやっぱり音がするなぁという感じで、購入するときに店頭物色してて触った静音のキーボードも気になってしまったりして、キーボード沼にはまらないかだけ不安です。HHKBやRealForceの分割も出て、分割キーボードの選択肢が増えるといいんですけど。</p>
<p>Barocco現在は品薄のようで、Amazonで2万円近くになったりしてますが、割高なので時期を待った方が良さそうです。私が買ったのはツクモのネットショップですが、黒軸と青軸だけが17000円ぐらいで残ってました。あとは新宿西口のヨドに赤軸18000円を見かけましたが、まだあるかどうか。</p>
]]></description>
            <link>https://chroju.dev/blog/barocco_review</link>
            <guid isPermaLink="false">barocco_review</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 05 Feb 2017 14:34:24 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[2016年総括 - 技術者って何なのかやっと理解した]]></title>
            <description><![CDATA[<p>2016年も終わるので振り返ります。ポエムです。今年はなんというか、技術者として自分が何をすべきなんだろっていうのがやっとなんとなくわかってきたかなという年でした。</p>
<p>元々SEとして4年間、小規模なシステムのおもりをしてExcelと格闘する日々を過ごしていた自分なので、技術的な部分でだいぶコンプレックスがあったし、とにかく勉強しなきゃみたいな焦りをずっと抱いていたんですけど、転職して1年半ぐらい経過してようやくそういう焦りが落ち着いた気がします。今年は業務上必要なことを遅延評価で学習することが多く、あまり自分のやりたいものを作ったりなんだりっていうクリエイティブっぽい感じにはなれなかったんですけど、いわゆるシステム運用ってなんなんだ、エンジニアってどこまで知識や技術を広げるべきなんだっていう全容がやっと見渡せて、自分の位置づけがわかってきたように思う年でした。</p>
<p>とか言ってしまうとだいぶ抽象的ですけど、具体的にやったのはMySQL中心にRDBMSの理解、Linuxでよく使われるBINDやsquidのようなOSSの習熟、AWSの利用とホワイトペーパーからのベストプラクティス習熟、Infrastructure as Code等DevOps周りの導入検討といったところでした。6年目でやることかこれみたいのも入ってますけど、Windowsだけの世界でずっと生きていたというのもありますし、遅かったかもしれないけどなんとかこう、スタートラインには立てたのかなと。学習はほぼほぼ本を読む、ブログを読むというところに特化していて、図書館もよく使いました。都内だと広尾の都立中央図書館がすごい技術書の蔵書量ですね。オライリーに限れば日比谷図書文化館にも結構ありますが。あとは勉強会を必要に応じて月に1回ぐらいのペースで。手を動かすより読む場面の方が多かったかもな、というのは若干反省点。基礎的な内容だろうと恥ずかしがらず、習得したらアウトプットしたいものです。</p>
<p>でー、基礎的、具体的な技術の土台ができてくるとメタな視点を持てるようになるもので、先の見通しがクリアになってきたかなと。『情熱プログラマー』の「1つのテクノロジーに投資するな。ベンダー中心にキャリアを考えるな」という記述にだいぶ影響受けまして、これまでは「技術学習」となるとプロダクトと相対する形がほとんどだったわけですけど、技術は手段に過ぎない、何のためにその技術を選ぶのか、みたいなことをやっと考えられるようになってきました。ミッション的には自分はビジネス的価値を直接生み出す、いわゆるコーディングをする人間というよりは、ビジネス的価値を産んでくれるコードをつつがなく動かす、運用効率を最適化するというところにフォーカスしたいという思いが強くなってきていて、そのためにどんな技術を選べばいいのかなというのをよく考えます。よく言うDevOpsとか、今年流行ったSREに思いとしては一番近いでしょうか。まだまだ未熟なので、そういう方面でバキバキバリュー発揮したいですね。特にDevOpsとかは文化的、コミュニケーション的な側面が強く、純粋に技術極めりゃいいってより組織論とか社会科学的なアプローチが必要だったりするし、そのへんもっと頑張りたいなと。。</p>
<p>あとあと、これまでは技術をインプットするという方向性が強かったんですけど、技術者という枠組みの中にいるのであれば「提供する」側にはそれなりに寄与したいなとも思うようになってきました。なんか今まではLTをする（そういえば今年やっと初LTしました）、GitHubでプルリクを出すみたいなのは自分の価値向上のためだとばかり思ってたんですけど、見方を変えれば技術者コミュニティというもっと広い場所に対する価値向上の意味もあるわけだよなと。特にOSSへのプルリクやらコミットというのは、誰かがそれをしてくれなくてはこれだけ便利な世の中は現状存在していなかったはずというわけで、これまで受けてきた恩恵を少しでも返す努力したいなと。そのためにはコードを読めて書けなくてはならない、もっと手を速くしたい。会社への寄与、自分の価値向上だけではなくて、業界全体に対して自分がやれることというのを意識したいなと思う。</p>
<p>はい、というわけで技術者として冷静になれたというのが今年だろうと思います。自分が何のために技術者やってんだってのをやっと考えられるようになった。ウェブを見てると新しいことやらなきゃいけない、かっこいいことやらなきゃいけないみたいに焦りますが、そうじゃなくて自分ができること、求められていることを的確に提供できるようになりたい、そのために必要な知識や技術を、的確な速度でキャッチアップしているエンジニアになりたいですね。来年はもっとコードを書く、それも汎用的に使える、きちんと公開して他の人の役にも立つようなものを書く、それが技術者としての責任でもあるかなと思います。</p>
]]></description>
            <link>https://chroju.dev/blog/looking_back_2016</link>
            <guid isPermaLink="false">looking_back_2016</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 28 Dec 2016 09:05:19 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[esa.ioを個人利用している話]]></title>
            <description><![CDATA[<p>3か月ぐらい前から<a href="https://esa.io/">esa.io</a>を個人利用している。</p>
<h2>esa.ioにした理由</h2>
<p>何分調べること、考えることが多い職業ということで、メモをする環境というのは常に欲しいもの。家でも仕事でもその姿勢はシームレスだったりするので、可能であれば場所を選ばずメモが出来て、メモを参照できる環境がいい。</p>
<p>従来はDropboxにmarkdownを保存して、<a href="https://github.com/glidenote/memolist.vim">GitHub - glidenote/memolist.vim: simple memo plugin for Vim.</a>を使ったりしていたのだけど、職場でDropbox同期をするのは気が引けたのと、古いメモが死蔵される率が高かったために断念。以前は古いメモも「grepできればOK」と考えていたが、そもそもgrepする単語を思いつかなければ古いメモは参照されないままになってしまうので、もう少し一覧性の高い仕組みが欲しくなった。</p>
<p>手を出したのがesa.io。課金は毎月500円/ユーザー数なので、個人であれば月々500円で使用できる。esa.ioを使っているのは、どこでも使えるという点もそうだし、もういろいろな人が言っていることだけど、「使っていて気持ちがいい」という点が大きい。</p>
<ul>
<li>Markdownで書くことが前提になっていて、例えば箇条書きを「* 」を使って書いていると、改行したときに自動で「* 」が入力されるなどの入力補助がある。</li>
<li>Markdownプレビューがシンプルで見やすい。</li>
<li>整理が簡単で、タイトルを「hoge/fuga/memo」とスラッシュで区切るとその構造でフォルダが作成され、「#」を含めるとタグが付与される。ドラッグ＆ドロップでノート整理をするような苦痛がない。</li>
<li>テンプレート機能がある。週報や読書メモのような、決まったフォーマットで書きたいメモを作りやすい。</li>
<li>各フォルダにREADME.mdを作成しておくと、フォルダのトップを表示したときにREADMEの内容がプレビュー表示される。そのフォルダ内の使い方を記したりするのに使える。</li>
<li>デザインかわいい。</li>
</ul>
<h2>esa.ioの用途</h2>
<p>もっぱら使う目的は長文用途が強い。日常の中で長文を書く、一つのテーマについてとにかく書き留めていくという機会は多い。技術書を読めば概要などのメモはしておきたいし、勉強会に参加したときも、資料が後から公開されるにしても、手元にメモを残している。何か新しい技術を学んだり、課題を検討したりするときも、なるべく徒手空拳ではなくて思考のログを残したい。<a href="http://d.hatena.ne.jp/naoya/20131107/1383792634">「書く」のは特別な道具 - naoyaのはてなダイアリー</a>というエントリーでも触れられているけれど、インプットされた情報そのものではなく、それを自分の中でどう咀嚼したか、どう考えたかをロギングするツールというのが必要で、その点でesa.ioを活用している。というわけで、用途を並べるとこんなところか。</p>
<ul>
<li>読書メモ</li>
<li>勉強会、イベントメモ</li>
<li>何か1つのテーマを掘り下げるときのノート取り</li>
<li>個人週報</li>
</ul>
<p>特に読書メモや週報あたりは特定の書式（KPTだとか、感想と不明点と次に読む本だとか）に則って書きたいという気持ちが強かったので、テンプレート機能のあるesa.ioがすごくマッチしている。</p>
<p>また自分が今注力している分野、短期的な目標等を見失わないため、一番トップのREADME.mdにはそれらを書き記している。いわゆるタスク管理ツールは短期的な行動指針にしかならないので、そのさらに先の方向性を定めるイメージ。『SOFT SKILLS』でも「目標をたてよう！」と言っていたし。</p>
<h2>エンジニアと「書く」ということ</h2>
<p>それにしても自分はメモ環境を悩みすぎている嫌いがあって、今年の初めにも「Personal Knowledge Base」という括りでエントリーを2つ上げている。</p>
<ul>
<li><a href="http://chroju.github.io/blog/2016/01/24/personal-knowledge-base/">Personal Knowledge Base · the world as code</a></li>
<li><a href="http://chroju.github.io/blog/2016/03/17/personal-knowledge-base-2/">Personal Knowledge Base 2 · the world as code</a></li>
</ul>
<p>どうにも「どこかに書き留めることなく、頭の中だけでつらつらと思考を巡らせてしまう」癖のようなものがあって、1つのことを深く考えたり調べていったり、逆に様々な思いつきを将来役立てるために記録しておくことが得意じゃない。</p>
<p>なのでメモ術、整理術みたいなものはいくつも読んでいて、自分が影響を受けたものにはこんなところがある。</p>
<ul>
<li><a href="https://www.amazon.co.jp/dp/4480020470">外山滋比古『思考の整理術』</a>。ド定番だけど、一度考えたことを「寝かせて」おいて、しばらくしてから「メタノート」に拾い上げる、考え直すみたいな方法は気に入っている。</li>
<li><a href="http://pileofindexcards.org/wiki/index.php">PoIC</a>。要は情報カードの使い方なのだが、発見、参照、記録、GTDの4種類にカードを分類するだけで、大掛かりな整理はしないシンプルな方法論。こちらも「メタノート」のように、何かを考えるにあたっては関連するカードを束ねた「タスクフォース」を作り、メモの掘り返しを行う。</li>
<li>GTD。言ってしまえば頭の中のことをすぐにメモをして、その内容はすぐ何かやるべきか、後でやるか、特に行動が要らないか分類して、頭の中を空っぽにしようという話。</li>
</ul>
<p>これらに共通するのは、結局のところ思考を外部に記録することで、脳内のリソース効率を高めることと、蓄積された情報を後から見返すことで、新たな意味を発見できる可能性があるという二点になる。PoICの中で、情報の蓄積による「エントロピーの増大」という表現をしていたが、頭の中で考えているだけの段階だと見通しが悪くてあまり価値のある情報にはならないのだが、書き溜めていくことで自分が何を考えているのか、どういう方針を持っているのかが明確化されるという副作用がある。過去の自分に囚われたいわけではないが、自分がどういった方向性で進んできていて、それとブレていないかを定期的に確認する手段としてメモなりブログなりは作用している。</p>
<p>技術系の仕事をしていても同じことで、あるソフトウェアに関するエラーを調査していたはずなのに、徐々に重箱の隅を突き始めて、目的から逸れたことを調べていたりすることはそこそこある。「体系立てて考える」というのは簡単なように見えて案外難しくて、「外部脳」に頼ることはやっぱり必要だなと思う。それこそ研究者の文献管理方法とか参考にしてみたらいいのかもしれないと思ってもいて、一度togetterにまとめられているのを読んだのだが、案外というか、京大式カードとか使うものなんだな実際と思ったり。</p>
<ul>
<li>参考：<a href="https://togetter.com/li/939197">文献読書中のメモの管理方法 - Togetterまとめ</a></li>
</ul>
<p>こういう「メモをする」「ノートを取る」重要性は理解しているし、それに沿った方法論や道具も持っているはずなのに実行できていないというのは、まぁちょっとアプローチを考える必要があるんだろうなと思う。強制的かつ自動的にメモを取る、脳内ではなく「脳の外で思考する」ために「書く」という手段を使えたらなと思いながら、まだ絶賛模索中。</p>
]]></description>
            <link>https://chroju.dev/blog/esa_io_personal_use</link>
            <guid isPermaLink="false">esa_io_personal_use</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 26 Dec 2016 15:46:39 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[エンジニアの問題解決力とは何か]]></title>
            <description><![CDATA[<p>今年度、特に下半期からいわゆる技術的負債の返済、特にDevOps方面におけるプロセス改善に深く携わるようになった。これまで依頼ベースの対応や、プロジェクトベースの仕事をすることが多く、要は「何をやるか」がある程度決まっていたわけだけど、改善系の業務は問題を見つけ、解決策、しかも場当たり的なものではなくてボトルネックを閉めるような策を講じていく必要があるということで、これまでと違う視点で仕事をする必要が出てきた。そこで何冊か「問題解決」にフォーカスした本を読んだ結果をまとめてみる。</p>
<h2>問題とはなにか</h2>
<p>そもそも「問題」って何なのか。<a href="https://www.amazon.co.jp/dp/4492557415">細谷功『問題解決のジレンマ』</a>によれば、問題とは「事実と解釈の乖離」だという。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4492557415/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51HZRQOWU6L._SL160_.jpg" alt="問題解決のジレンマ: イグノランスマネジメント:無知の力" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4492557415/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">問題解決のジレンマ: イグノランスマネジメント:無知の力</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 16.12.17</div></div><div class="amazlet-detail">細谷 功 <br />東洋経済新報社 <br />売り上げランキング: 112,865<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4492557415/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>客観的な「事実」があり、その関係性や論理構造を規定する「解釈」がある。事実というのは客観的なものなので変化することは少ないが、解釈は時代や文化によって在り方を変える。つまりは古くなってくるわけで、それによって事実と解釈が乖離を起こすことにより、問題が発生する。</p>
<p>システム運用という自身の立場で考えれば、例えばベンチャー企業においては「小規模なシステム」かつ「少人数の精鋭社員」という「事実」下では、「スピードが重要でドキュメントを書かずとも運用は可能」という「解釈」が成り立ちうる。これが年数が経過して「大規模なシステム」かつ「新卒等も含めばらつきのある社員」という事実に変わってくると、先の解釈通りにドキュメントなしでは運用が難しくなったりするわけで、事実と解釈の乖離が起きた状態が発生していることになる。</p>
<h2>問題を見つけるために</h2>
<p>人は日常的には己の「解釈」の枠組みの中で生きている。知識が増えるほど、自分の知る範囲内での最適化＝問題解決を図ろうとするようになるが、根本的な問題解決をするには、そもそもその「解釈」の範囲の外に問題がある、つまり自分の「解釈」がすでに形骸化している、ということを見つける必要がある。『問題解決のジレンマ』では、これをラムズフェルドがかつて言及した<a href="https://ja.wikipedia.org/wiki/%E7%9F%A5%E3%82%89%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%81%A8%E7%9F%A5%E3%82%89%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E3%81%82%E3%82%8B">Unknown unknowns（未知の未知）</a>という言葉で説明している。</p>
<p>とはいえそれは容易な話ではない。たいていの人間は自身の知識、先入観を抽象化して物事を考えるということを、簡単には実践できていないように思う。</p>
<p>自分がそもそも「わかっていない」ということを「わかっていない」ことに気付くには、安直に言ってしまえば視野を広げていくしかない。『問題解決のジレンマ』で挙げているのは「フレームワークの導入」で、物事を一般的なフレームワークに当てはめて考えれば、どの分野に対して視点が足りていないのかを探る手がかりになる。</p>
<p>また「知識がある」という状態がそもそもの「未知の未知」を見つける足枷になるわけだから、知識をリセットする、知識をフローとして扱って、不要になったら捨てていくようなプロセスがいいのではという。これは外山滋比古も「忘却の力」という形で扱っている概念だ。エンジニアは技術職だが、一つの技術領域にこだわりすぎると時代の潮目についていけなくなったりするので、この点は一理ある。</p>
<p>あるいは『SOFT SKILLS』の「学習」の項において、学習すべき事項を見つけるために勧めていたのが、「わからないことをメモしておく」ことだった。学習すべき事項というのは要は「問題」なわけで、これも問題発見には応用できるのだと思う。まぁ地道で「そりゃそうだろ」という話ではあるのだが、日頃見つかる小さな問題をスルーせずに、都度確実に書き留めておくことは必要と思う。そして個別の問題それぞれに対応するのではなく、ある程度蓄積された複数の小さな問題を並べて「ボトルネックは何か？」と考えていくことで、対応すべき大きな問題が見つかるのではないか。</p>
<h2>問題を解決していく過程</h2>
<p>見つけた問題を解決する過程については<a href="https://www.amazon.co.jp/dp/4862760856">安宅和人『イシューからはじめよ』</a>に詳しいが、内容としては要するにデカルトの『方法序説』に近い、一般的な科学的方法論だ。問題を見つけたら、それを解決可能な小さな単位に分解し、単純かつ具体的な観測から抽象へと認識を進め、全体の論理が沿うように再構成していく。GTDにおいても、目的と求めるべき結果を最初に定めて、その間に必要なタスクをブレインストーミングしていく「ナチュラルプランニング」という方法論があるが、どこか似通っている。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4862760856/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41Xo9o1l0sL._SL160_.jpg" alt="イシューからはじめよ―知的生産の「シンプルな本質」" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4862760856/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">イシューからはじめよ―知的生産の「シンプルな本質」</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 16.12.17</div></div><div class="amazlet-detail">安宅和人 <br />英治出版 <br />売り上げランキング: 1,168<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4862760856/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>ある問題を端緒として改善活動を始めたとして、どうもエンジニアとしての性なのか、当初の目的からズレて技術的な面白さを求めてしまったりすることはよくある。サーバーのデプロイスピードが遅いことを発端として改善を始め、じゃあクラウドを使って改善しようという話になったが、どのクラウドサービスを使えばいいのかと言った別の問題で時間をかけてしまったり、結局手作業でEC2インスタンスを作っているのでオンプレのときとスピードが変わらない、みたいな話はありがちだ。問題から解決策への筋道が論理的な整合性を保っているかは、常に確認が必要になる。</p>
<p>この点は自分が特に出来ていないところで、プライベートで何か勉強を始めたはいいが、何を求めて始めたのかを忘れてしまって、細かいつまずきポイントでずっとハマったままになったりしていることが少なくない。</p>
<h2>具体的実践</h2>
<p>以上のような検討から、具体的にいろいろと実践してみようと思う。</p>
<ul>
<li>「わからないことメモ」をすすめる。よく使っている小さめのメモ帳があるので、それに1ページ1項目で「わからないこと」を記述して、週末に見直してみる。</li>
<li>何か勉強を始めたり、問題解決にあたるときは、個人契約しているesa.ioでノートを1つ作る。
<ul>
<li>まず問題を1文で書き表す。それを出発点として、ぶれないことを心がける。</li>
<li>調査の過程、問題解決を図るプロセスもすべて記録していく。常に全体の整合性が取れていることを確認しながらすすめる。</li>
<li>最終的に「解決」まで至ったノートは、ブログやQiitaに投稿して公開する。
<ul>
<li>実はこのエントリーもその方法に則ってesa.io上で昇華させた。</li>
</ul>
</li>
</ul>
</li>
<li>あまり特定の「技術」にこだわらない。
<ul>
<li>そもそも問題解決やビジネス的な成功という「目的」があり、それを達成するための手段が「技術」なのであって、それが何を採用するかこだわるのは本質ではない。</li>
<li>技術への固執は「未知の未知」を見えにくくする。多様な技術に対して寛容な理解を心がけることで、常に必要な技術へキャッチアップできるような気がする。</li>
<li>一方で低レイヤーの知識や、コンピュータ史への造詣は深める。先に挙げた「フレームワーク」にあたるのがこのような基礎分野だと思うので、基礎を固めることで現在の技術潮流をメタに判断できるようになる。</li>
</ul>
</li>
</ul>
<p>特に最後の「特定の技術にこだわらない」は重要だと思っていて、自分はどうしてもクールな技術、なんだかカッコよさそうなものがあると簡単に心惹かれてしまい、技術が目的になってしまう。もちろん、使っていて気持ちのいい技術を選択するのも大事なのだが、結局はどの技術もツールに過ぎないわけで、自社の「問題解決」に適切なハンマーなのかという点は念頭におきたいし、またその目的に適うならどんな技術だってクールと思うべきなんだろうと思う。</p>
<p>自分は謙遜せずに言えば頭の回転が速い方なので、どうしても考えすぎてしまう、頭の中でぐるぐる物事を捏ね繰り回してしまう傾向にあり、それを解消する意味でも「きちんとesa.io上で論理展開する」というのは良いだろうと思っている。『考えない練習』という本も、考え過ぎを抑制する助けになりそうなので読んでみたい。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4094087001/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51y1EO0eUOL._SL160_.jpg" alt="考えない練習 (小学館文庫)" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4094087001/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">考えない練習 (小学館文庫)</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 16.12.17</div></div><div class="amazlet-detail">小池 龍之介 <br />小学館 (2012-03-06)<br />売り上げランキング: 5,008<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4094087001/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>また、ここまでは個人的な実践の話が多かったが、実際に職務上の問題解決を行うにはチームを巻き込む必要がある。人を動かす、チームの中で振る舞っていく方法論については、また別の課題としていきたい。</p>
]]></description>
            <link>https://chroju.dev/blog/engineering_problem_solving</link>
            <guid isPermaLink="false">engineering_problem_solving</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 17 Dec 2016 03:43:17 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[多義化するOpsのミッションについて]]></title>
            <description><![CDATA[<p>今年度から運用の担当になったんですけど、最近消化不良を起こしつつあります。立場としては言われたことだけやるオペレーターという形じゃなくて、いわゆるインフラエンジニアっぽい感じだけど構築はやりませんよって感じです。日々のオペレーションや障害対応をやりつつ、一方でDevOpsの整備とかに注力している感じ。でも自分のミッションはそこまで社内で明確化されているわけではなくて、どうもそのあたりに消化不良の原因がある。</p>
<h2>Opsの担うミッションの変化</h2>
<p>そもそもにしてDevとOpsの境界ってどこなんだろうという定義はわりと曖昧な気もしますが、おそらくは「リリース」が境なんでしょう。基本的にはリリースまでを担当するのが「開発」で、リリース後のシステム稼働の面倒を見るのが運用、保守というイメージでいるのだけど、「運用」が担うミッションって最近かなり広がっているような気がするんですよね。</p>
<p>一番難易度の低い運用といえば、いわゆる手順書に沿った業務しかやらないオペレーター作業になるわけですが、そういう運用と開発の業務内容、職掌をガッツリと分けた状態って最近は主流ではなくて、いわゆるDevOps的に開発フェーズからデプロイされて本番運用へと移っていく過程がシームレスになっていくのが常識化しつつある。あと運用というのも、システムを単に放っておいてトラブルが起きたら対応、という受動的なものではなくて、能動的にメトリクスやログを解析して、SREのようにソースコードにまで手を入れて、安定運用のための方策を講じていくスタンスが生まれつつあります。</p>
<p>少し前だと、いわゆるインフラエンジニアが運用も担っているようなケースは特にWeb系だと多く見られていたし、Infrastructure as Codeの黎明期には「インフラエンジニアもコードを書けるべき」ということが盛んに言われていましたが、もはや時代は「運用の中でソフトウェアのコードを編集する」というところまで来ていて、だいぶ時代が移り変わったように見える。</p>
<h2>Ops先鋭化へのジレンマ</h2>
<p>もともとインフラエンジニアが運用を担っていたパターンにおいて、SREのような業務を来月からやりましょうってのはまず無理だと思っています。スキルの畑があまりに違うので。やるのであれば人員の配置換えをするか、インフラエンジニアにかなりの学習コストを払わせることが必要になる。ので、ちょっとSREの話は先鋭的すぎるとして置いておくとしても、いわゆる「インフラエンジニアもコードを書けるべき」は求められる場面が多くなってきたように思う。</p>
<p>そもそも旧来の運用業務にしたところで、一切コードを書けない人間が担えたとは思えないんですよね。まぁ「手順書運用」は一切スキル不要なので別として、何か処理を自動化して効率化しましょうとなればスクリプトぐらいは書ける必要があるし、OSSの監視ツールを使いましょうとなれば、ソースを読む機会ぐらいはある。ただ、実際に運用業務に携わっていて思うのは、それを出来る人間というのは現実として限られてもいる。インフラエンジニアが運用を兼ねるようなケースであれば尚更です。</p>
<p>堅牢性を求めて保守的なシステム運用をしようとすれば、運用は「決められたことだけをやる」「引き継いだことだけをやる」という方向にシフトしがちなわけで、そうなってくるとコードを読み書きするスキルが必要とされる場面は当然ながら減ります。その場合のスキルはインフラ周りに重点が置かれて、コードの修正はソフトウェアエンジニアに任せることになる。手作業のオペレーションが煩雑であるならば、ソフトウェアエンジニアへ自動化を依頼するかもしれない。</p>
<p>どちらが良い、どちらが悪いという話ではなく、スキルと職掌による問題なんだろうと思っています。同じシステムを運用していても、コーディングスキルがあるエンジニアであれば自ら自動化をしよう、ソースコードを確認してみようという手の動かし方になるし、コードに携わるのは自分の職務ではないと認識していて、スキルも持ち合わせていないエンジニアであれば、誰かに任せればいいという思考になる。</p>
<p>（運用も担っていた）インフラエンジニアの役割が変わってきた、というよりは、スキルやマインド、スタンスの面で、コーディングスキルのあるOpsエンジニアが別の方向へ進み始めたというように思えます（繰り返しになりますが、どちらが良し悪しということではなく、決められた手順だけを実施させることで運用のコストを下げる、というのも一つの考え方だとは思っています）。</p>
<h2>圧倒的技術力の必要性</h2>
<p>ところで、DevOpsはさておき「システム運用」全体を網羅したような本ってあんまりないです。最近は少し出るようになっていて『インフラエンジニアの教科書』などはそれに近いですが、（サーバー）構築の話も入ってくるので、純粋な運用というとオライリーの『ウェブオペレーション』が一番ハマっているかなと。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4863541333/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51WvFGuX5iL._SL160_.jpg" alt="インフラエンジニアの教科書" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4863541333/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">インフラエンジニアの教科書</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 16.10.23</div></div><div class="amazlet-detail">佐野 裕 <br />シーアンドアール研究所 <br />売り上げランキング: 29,314<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4863541333/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873114934/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51-ThZ6FRfL._SL160_.jpg" alt="ウェブオペレーション ―サイト運用管理の実践テクニック (THEORY/IN/PRACTICE)" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873114934/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">ウェブオペレーション ―サイト運用管理の実践テクニック (THEORY/IN/PRACTICE)</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 16.10.23</div></div><div class="amazlet-detail"><br />オライリージャパン <br />売り上げランキング: 371,961<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873114934/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>Amazonに在庫ないっぽいので絶版かもしれないですがいい本でした。監視の考え方から継続的デプロイ、障害対応に関してまで載ってる。技術書というよりはエッセイっぽいですが、運用ってどんなことやるんだというのがわかる本。</p>
<p><a href="http://kakakakakku.hatenablog.com/entry/2015/07/12/194716">圧倒的な技術力が求められる職種だ /「ウェブオペレーション」を読んだ - kakakakakku blog</a></p>
<p>レビューを上げているブログを貼りましたが、このタイトルにもある通り、この本を読むと「圧倒的な技術力が求められるわ……」と呆然とします。2011年の本なので、SREのような先鋭化したスタイルに言及があるわけではないですけど、そもそも障害への対応にしたって、原因を切り分けるにはコンピュータアーキテクチャーのレイヤーから、OS、ミドルウェア、ソフトウェア、ネットワークと様々な視点を考慮する必要があるわけです。原因追求をせず、手順書通りに再起動や再実行をして「とりあえず」復旧したからOKとするのも運用と言えば運用ですけど、システムの安定性を保つためにどちらが望まれるかとなれば、大きな違いが出てくる。また運用や障害対応は組織で行うのが基本なので、うまいこと人員が動いて有機的に連携していくには、時に心理学や社会学の知識も役に立ったりします。</p>
<p>思うのは、Opsという領域が二分されてきているんじゃないかということです。運用を標準化して、決まったことをやることでコストを抑えた方式と、SREへ辿り着くような、漸進的にシステム改善を図りながら安定稼働を目指す方式。なんとなく、前者のエンジニアが後者へ移り変わっていくようなイメージを持っていましたが、そもそもスタンスとして前者を是とする人と、後者を是とする人の2種類に分かれてきているように思う。B to BのサービスでSLAを握っているのなら、多少システムリソースの使用率が逼迫していても、SLAの範疇で運用されていれば問題がないわけだし、そこでパフォーマンスチューニングをしてもお金が取れるわけではないので得策ではない。となればSREは必要ないかもしれない。といった具合に、スタンスの違いでミッションも変わってくる。</p>
<p>自分の場合は後者のスタンスを欲しています。SREのような高いスキルは現状持ちあわせていないけど、システムの安定した稼働、高効率な稼働に寄与して、エンジニアの対応コストを抑えていくというのをミッションにしたいなという思いが強くなってきている。が、それも会社が目指すOpsの方向性と噛み合っていないと無意味です。「運用」という言葉で括れる範囲は極めて広く、多義的になってきている昨今で、先に示したように「これ1冊！」という本を読めばOKというものでもないです。なので、まずはリリース後のシステムをどうしようか、というOpsのミッションをブレずに定義することが求められているのかなというのが最近の実感でした。</p>
<p>ちなみに自分が思うOpsの職掌としては、クックパッドさんのインフラエンジニアの職掌範囲がとてもしっくりきていますね。</p>
<p><a href="http://techlife.cookpad.com/entry/2015/10/07/181340">インフラエンジニアの責任範囲と評価 - クックパッド開発者ブログ</a></p>
]]></description>
            <link>https://chroju.dev/blog/what_is_ops</link>
            <guid isPermaLink="false">what_is_ops</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 24 Oct 2016 15:20:02 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[ServerlessConfとエンジニアの職掌に関して]]></title>
            <description><![CDATA[<p><a href="http://tokyo.serverlessconf.io/">ServerlessConf Tokyo</a></p>
<p>10月1日に開かれたServerlessConf Tokyoに行ってきました。会場で一度「サーバーエンジニアの方ってどれぐらいいますか？」という質問がありましたけど、そのときの挙手によればサーバー、インフラ寄りのエンジニアはだいぶ少数派だったみたいですね。まぁサーバーなくなっちゃってんだからそりゃそうだろって感じなんだけど、自分としてはインフラエンジニアの立場から見て「サーバーがない！」という状況はどう映るのか、どう向き合えばいいのかというのがだいぶ気にかかってました。それでなくてもクラウドの登場、特にAWSが当たり前のものとなってからはインフラエンジニア不要論が常に囁かれてはきたわけで。</p>
<p><a href="http://chroju.github.io/blog/2015/10/20/eudaemonics-of-infrastructure-engineer/">インフラエンジニアの幸福論 · the world as code</a></p>
<p>改めてサーバーレスとはなんだろうと。いや、サーバーがないはずはないじゃんというのはよく聞く反論で、仰る通りAWS Lambdaといえど裏側では当然Amazon Linuxが、物理的なサーバーが動作しており、サーバーレスって言葉はあまりよろしくないんではみたいな話もあります。とはいえ運用するエンジニアの視点からすると、サーバーというスコープはごっそり消失しているような状態ではあるので、個人的にはあながち的を外しているとも思ってはいないです。しかしそうすると今度は、従来のherokuやAWSマネージドサービスだってサーバーレスだったことになるじゃん？というのが自分の疑問としてはあったのですけど、この点はだいぶ思い違いをしていたなと今回認識を改めました。</p>
<script async class="speakerdeck-embed" data-slide="1" data-id="8808b232125a4fbda7155ea8128e99cc" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>
<p>端的にサーバーレスで受けられる恩恵をまとめたものとしては、このスライドが非常にわかりやすくてピンときました。これまでビジネスロジックはサーバーというモノシリックなエンティティの中に組み込まれ、サーバーを基本単位として扱われることが主だったわけだったですけど、サーバーレス、いわゆるFaaSの世界ではビジネスロジックが単一の機能＝関数を単位としたマイクロサービスへ分割されます。そして実行媒体は常時稼動が前提であったサーバーやデーモンから、immutableなライフサイクルを持ったコンテナへ移されるため、自ずとステートレスな状態が保たれる。FaaSの実行はイベントドリブンで必要なときのみに絞られるので、リソースの効率性も従来とは考え方がまったく変わってくる。サーバーレスというのは、こういったソフトウェアアーキテクチャーの全体的な転換点として捉えなければならないんだなというのがやっと掴めました。</p>
<p>確かに実行媒体であるはずのコンテナすらも隠蔽され、コードを書いて渡してしまえばそれだけで実行されるサーバーレスな世界というのは、インフラエンジニアという旧来の職種が入る余地はなさそうには見えます。でも自分の立場から見て、こういったサーバーレスの世界でやること皆無になるか？というとそうは思えなくて、ハードウェアリソースを如何に効率的に使うかだとか、リソース部分をすべて別の事業者に委ねてしまった状態で、可用性やパフォーマンスをどう担保していくかだとか、インフラエンジニアの視点から出来ることっていろいろあると思うんですよね。まぁそりゃ今までみたいにLinuxにSSHして云々だとか、ネットワーク機器の設定をどうのってのをやる機会はほぼ無いのかもしれないけれど、「インフラエンジニア」の定義を技術領域からミッションに変えることで、見えていく先はあるんじゃないかなと。</p>
<p>またイベント内でこれも何度も聴いたんですけど、当然ながらサーバーレスは銀の弾丸ではないです。ステートフルであることが相応しいソフトウェアもあるし、デーモンを常駐させる必要性も現在皆無になったわけではない。サーバーレスを至上として、ソフトウェアをどうすればサーバーレスに出来るか？と考えるよりは、ソフトウェアをより望ましい状態にするために、アーキテクチャーとしてサーバーレスを選択することが適切か？という考え方をするべきなのではないかなと感じました。</p>
<p>エンジニアの職掌は従来だと技術領域のレイヤーで隔てられることが多かったですが、技術分野の変容もさることながら、アーキテクチャーすら10年待たずにガラガラと形を変えていく時代においては、技術レイヤーへのフォーカスだけで職種を定義すると痛い目を見そうな気がしてきました。まずはミッション先にありきであって、そのための手段として技術やアーキテクチャーを選択する。そういう発想でいくと、「インフラエンジニア」と呼ばれる職種にも未来はある気がします。あるいは最近それがSREといった呼び方に変わったりしているのも、その証左であるんじゃないかなと。</p>
]]></description>
            <link>https://chroju.dev/blog/serverless-conf-tokyo</link>
            <guid isPermaLink="false">serverless-conf-tokyo</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 03 Oct 2016 14:52:14 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『SOFT SKILLS』と「やっていく気持ち」]]></title>
            <description><![CDATA[<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B01GDS0994/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51xVQQcUloL._SL160_.jpg" alt="SOFT SKILLS　ソフトウェア開発者の人生マニュアル" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B01GDS0994/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">SOFT SKILLS　ソフトウェア開発者の人生マニュアル</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 16.08.01</div></div><div class="amazlet-detail">日経BP社 (2016-06-02)<br />売り上げランキング: 223<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B01GDS0994/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>『SOFT SKILLS』読みました。印象としてはいわゆるライフハックな内容をエンジニア向けに落とし込んで解説している本、とういう感じ。ただ、単にテクニックだけを載せたペラペラした内容ではなくて、成功するためにはハードワークを避けるべきではない（第47章）ということもまた語っていたり、実情に即した書き方である点が好感が持てる。というか全体的にマッチョ寄り。</p>
<p>この手の「ソフトスキル」、つまりエンジニアやギークが「よく生きる」ための本というのがこれまで皆無だったわけではなくて、例えば『<a href="https://www.oreilly.co.jp/books/4873113075/">エンジニアのための時間管理術</a>』や、『<a href="https://www.oreilly.co.jp/books/9784873117287/">ヘルシープログラマー</a>』に書いてあることと一部の記載は似通っている。本書のポイントとしては、プロダクティビティ、精神、肉体、金銭といった横断的なソフトスキルを幅広くまとめ、またそれらを「エンジニアとしてより良く生きるために、直接的なエンジニアリング以外の領域をどうすべきか？」という視点でまとめた本はあまりなかったのだと思う。自分はライフハックがわりと好きでかじりまくった時期があったので、ちょっと目新しさに劣る部分はあったのだけど、そういう分野を敬遠してきたエンジニアにとっては新鮮な話が多いはず。</p>
<h2>行き先を定めてから、走るスピードを上げる</h2>
<p>個人的にライフハックに対して感じていることがあって、タスクをどう処理するか？とかライフログがなんちゃらみたいな「目の前のことに対応する方法」は多いのだけど、それをすることで何を得るの？っていうのがあんまりなくて。早く帰れますとか生産性が上がりますでもまぁいいんだけど、それって本来「手段」となるべき部分で、生産性を上げて何を成したいのかというのが重要だよなとずっと思っている。</p>
<p>本書の構成はその点で言えば第1部が「キャリアを築こう」で行き先を定める部分にあたり、第2部「自分を売り込め！」でそのために最も必要なことを語り、第3部以降でいわゆるライフハック的な、プロダクティビティや肉体精神の維持といった話に入っていく。順序としてはやっぱりこれが正しくて、行き先を定めておかないと、何のために走力を上げたいのかという目的を見失ってしまう。</p>
<h2>日常での実践</h2>
<p>本書の内容で自分がいま実践できていることって、実際のところあまりなかった。目標を持とう、と言われてそういえばあまり具体的な目標ないなと気付いたし、そこまで自己アピールして「売り込み」ができてもいないし、投資はちょっと前ちょろちょろETFを買ってみたっきりだし、肉体と精神に関しては自信がない。</p>
<p>生産性に関しては少し前にrebuild.fmで取り扱っていたこともあり、自分は今ポモドーロを使っている。本書で紹介されているKanbanFlowは使っていないけれど、Trelloでざっくりした自分のプロジェクトの状況をダッシュボード的に管理して、細かい「やるべきこと」はTodoistに入れて、Chrome ExtentionのToggl Buttonでポモドーロタイマーを使っている。ポモドーロは25分間集中させることに意味があるように語られがちだけど、実際は1日の消化ポモドーロ数を見て自分の生産性を測るのに適していると書いてあって、そうそうそれだよ！という感じだった。タスクの消化数だと、タスクごとに工数が異なるのでなかなか生産性とイコールにはならないのだが、ポモドーロだとそれができる。あるいはアジャイルにおけるPivotal Trackerの考え方が生産性の計測には良いのかなと思っている。</p>
<p>その他の部分は取りあえずやれることから手をつけたいかなと。ただ冒頭にも書いた通りわりとマッチョ寄りな内容が多くて、例えば自分は精神力に本当に自信がないのだが、その改善策として「理想的な自己イメージを想像することだ」と言われてもなかなか難しい（文中でも「難しい」とは書かれているけど）。あるいはこういう記述。</p>
<blockquote>
<p>その上で聞きたいのは、あなたは負けるつもりなのかということだ。単純に自分は仕事に集中することができないと諦めるのか、それとも抵抗に立ち向かい、障害を乗り越えようとするのか。それはあなただけができる選択だ。単にしなければならない仕事をすると決心すればいいだけだ。</p>
</blockquote>
<p>いや厳しい。。。とはいえ言っていることもごもっともなので、「やるしかねえ」と腹くくるかなぁという感じです。いい刺激になりました。以下、やること取りあえずでメモ。</p>
<ul>
<li>ポモドーロでの生産性計測を継続する。</li>
<li>キャリア上の目標を定めてみる。</li>
<li>どっかでLTする。年内中を目標に。</li>
<li>瞑想を取り入れる。余裕あったら筋トレする。ランニングは見送る。</li>
<li>ハードワークを避けない。難しい課題、つまらない課題でも挑む姿勢。</li>
<li>何かを学ぶときは漫然と行わず、本書の10ステップに取りあえず従ってみる。</li>
<li>メモの頻度を上げる。自分の内面の状態管理に使う。</li>
<li>脂肪ではなくタンパク質の摂取。フルーツの摂取を心がける。</li>
<li>自己イメージを持つという話は納得できてないので、本書で紹介されてる『自分を動かす』読んでおく。</li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/soft_skills_and_our_productivity</link>
            <guid isPermaLink="false">soft_skills_and_our_productivity</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 01 Aug 2016 13:30:41 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[YAPC経験ないけどパチモンの方に行った]]></title>
            <description><![CDATA[<p>イベントレポートに見せかけたポエムです。</p>
<p>技術ブログとかQiitaとかやってると、更新してない間はあんまり成果出てないってことでバロメーターになっていいですね。先月はあんまり具体的な成果に繋がることは仕事でもプライベートでもしていない。。。何をやっていたかというと、</p>
<ul>
<li>AWS運用見直しのためにホワイトペーパーやユースケース読み漁り</li>
<li>EFK(Elasticsearch + Fluentd + Kibana)スタックをDockerでやろうとしてまだ途中</li>
<li>セキュリティ知識つけるために『暗号技術入門』と「徳丸本」を読破。</li>
</ul>
<p>あたり？ というわけでなんだか煮詰まった状態で久しぶりの勉強会というかイベントになったのが<a href="http://yapcasia8oji-2016mid.hachiojipm.org/">YAP (achimon) C::Asia Hachioji 2016 mid in Shinagawa</a>でした。昨年まで開催されていたYAPC::Asiaの「続き」として開かれたカンファレンス。</p>
<h2>本物は経験ない</h2>
<p>タイトルにも書いたけど本物のYAPCは一度も行ってないです。昨年転職するまではOfficeを主戦場としたSEだったのでアンテナ低かったし、タイトルにPerlって入ってるけど自分Perlエンジニアじゃないし、Perlを冠しながらあんなイベントだとは知らなかったし？ 結局内実をきちんと知ったのは昨年の開催中だったので時はめちゃめちゃ遅すぎた感じであった。RubyKaigiとかAWS Summitのような大きめのカンファレンスは経験あるにはあるけど、ビッグサイトで開催されていたという規模はちょっと想像できないですね。もったいないことをした。</p>
<h2>技術スタックを掘り下げたい</h2>
<p>今回いろいろとトークを聞いていて思ったのだけど、技術スタックをもっと掘り下げていきたいなという思いがした。こういう場で話される内容って、そのエンジニアの得意領域だったり経験だったりが活きるもので、ちょっとググって資料つくりましたとか、大して思い入れはないけどやってみたので喋りますとかそういうのじゃないんですよね。掘り下げがあるから話が面白くなる。実体験だから身にしみてわかる。そういうものだよなと。先月はAWS Summitにも行ったのだけど、今日の方が面白かった。それは企業がお膳立てした話じゃなくて、エンジニアがボトムアップに立ち上げたイベントだからだろうなと思う。</p>
<p>転職してちゃんとエンジニアっぽいこと仕事でできてるなーと感じ始めてから、自分はだいたい1年ぐらいなのだけど、この1年は業務についていくためと時代についていくため、とにかく広くいろいろ調べてやってみるというばかりで、あんま掘り下げってしてないんですよね。「インフラエンジニア」って肩書はよくあるものだけど、その守備範囲ってすさまじく広いので、DBなのか、AWSなのか、ネットワークなのか、セキュリティなのかみたいな、自分を位置づける技術スタックは持っておきたいなと思った。よくT字型とか言われるけど、広く浅い知識はもった上で、一部分で深掘りを進めていかないと、自分が何をすべきか見失いそう、というか見失ってるな最近と。</p>
<h2>エントロピーの増大期間</h2>
<p>突然話は変わるけど、自分はPoICという方法論がわりと好きで。要は情報カードに発見や記録をメモしていきましょうみたいな知的生産の話なのだけど、この中で面白いなと思っている話として、<a href="http://pileofindexcards.org/wiki/index.php?title=PoIC_%E3%82%92%E9%80%9A%E3%81%98%E3%81%A6%E8%A6%8B%E3%81%88%E3%81%9F%E3%81%93%E3%81%A8#.E6.83.85.E5.A0.B1.E3.81.A8.E3.82.A8.E3.83.B3.E3.83.88.E3.83.AD.E3.83.94.E3.83.BC.E3.81.AB.E3.81.A4.E3.81.84.E3.81.A6">エントロピーに絡めた話</a>がある。頭の中の乱雑な情報をカードに書いて書き溜めておくことで、そのストックの中でエントロピーを高めて生産性を生み出すという考え方。</p>
<p>これって外山滋比古のいう「メタノート」とか、あるいはジョブズのスタンフォードでのスピーチにあった「Connecting the dots」と話は似ていて、要はある程度蓄積されてこないと情報や知識って意味を成さなかったりするもんなんですよね。学習曲線も正比例のグラフを描かないことは有名だけど、何かを学んだり取り入れたりすることがすぐに成果を生むわけではなくて、ある程度価値となるまでには時間がかかる。</p>
<p>冒頭に書いたように、先月ぐらいって自分はあんまり成果出せなかったなっていうのがあって、停滞感にもやもやしていたんだけど、エントロピーの増大期間という考え方をすると、まぁそんな焦る必要もないのかなと。きちんと日頃から必要な知識に向き合って習得していくことで、徐々に掘り下げってできてくるのかなと思う。</p>
<p>で、エモい話だけしてイベントレポート終わるわけにもいかないので具体的な話も書きますが、今回MySQLの話4回ぐらい聞いていて、改めてDB弱いなと思った次第。</p>
<iframe src="//www.slideshare.net/slideshow/embed_code/key/F89iwACdqldnT" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/yoku0825/ss-63664674" title="とあるイルカの近況報告" target="_blank">とあるイルカの近況報告</a> </strong> from <strong><a href="//www.slideshare.net/yoku0825" target="_blank">yoku0825</a></strong> </div>
<p>弊社もMySQLがメインで使っているので、いい加減真面目に追いかけておきたい。正規形の話も数年前に受けた応用情報の復習みたいで勉強できた。</p>
<iframe src="//www.slideshare.net/slideshow/embed_code/key/6yzSDaOxaTOWN" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/yoku0825/mysql-63658697" title="MySQLと正規形のはなし" target="_blank">MySQLと正規形のはなし</a> </strong> from <strong><a href="//www.slideshare.net/yoku0825" target="_blank">yoku0825</a></strong> </div>
<p>これは現地で聴いてなくて後から読んだスライドだけど、esa.ioの姿勢はとてもいいなと思う。頑張り過ぎないのあたりとかすごい大切だと思っていて、最初からベストなやり方するより、とりあえず導入した方がいいってことは多い。あと移行日記。移行じゃなくても技術的な日記書きたい。一つの技術を長期間追ってると徐々に目的見失ったり、そうだアレもやらなきゃみたいに脇道逸れたりしやすいんだけど、これぐらい砕けて感情的に書くと、それがなくなりそう。</p>
<script async class="speakerdeck-embed" data-id="7aa606badc2d4782a14eeba7c2755309" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script>
<p>あと個人的にはHashicorp Vaultがとても気になりました（資料はちらとググったけど、まだ上がってない？）。クレデンシャル情報、どうしてもLDAPやIAMのような集中管理に載り切らないものが出てきてしまうけど、これなら集約的に管理できて、しかもAPIあるから取り回しも楽そう。</p>
<p>いろいろ考えることの多い1日でした。自分がどこに向いて進むのか、もっかい考えようと思う。</p>
]]></description>
            <link>https://chroju.dev/blog/yapc8oji_2016</link>
            <guid isPermaLink="false">yapc8oji_2016</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 02 Jul 2016 13:11:59 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Serverlessの時代とas code]]></title>
            <description><![CDATA[<p>先週<a href="http://ansible-users.connpass.com/event/31222/">Ansible Meetup in Tokyo 2016.06</a>と、<a href="http://www.awssummit.tokyo/">AWS Summit Tokyo 2016</a>に行ってきたので軽めのレポートにします。</p>
<h2>AWS Summit</h2>
<p>AWS Summitは初参加でしたが、会場を見渡したときのスーツ率の高さからいわゆるEnterprise系のイベントに近いのかと思いきや、DevConの方を中心にテクニカルな話題も多めで楽しめました。とはいえAWSサービス紹介にとどまるセッションや、タイトル通りの内容ではなく、各企業の内部事情を抽象的に話すだけで終わるようなセッションも少なくなく、セッションの選択はそれなりにコツがいるなとも思ったのですが。。</p>
<p>自分が受けたセッションで特に多く話されていたのは、Serverlessの話とDevOps、具体的にはCI/CDの話。いずれも要はこれまで複雑に運用していたシステムが、AWSのマネージドサービスを使うことで簡単に実現できるという話なのですが、特にServerlessに力を入れてる感じがしました。Lambdaの話がすごく多い。先日Serverless confで「サーバーを叩き割る」というパフォーマンスで話題になった、AWSのTim Wagnerも来てましたしね。</p>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">This is how you go <a href="https://twitter.com/hashtag/serverless?src=hash">#serverless</a> – @timalleneagner <a href="https://t.co/SpllWVz76u">pic.twitter.com/SpllWVz76u</a></p>&mdash; Lars Trieloff (@trieloff) <a href="https://twitter.com/trieloff/status/735839549729996800">2016年5月26日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>Lambda、簡単なジョブや解析処理であればEC2立てずとも実行が可能になるわけで、いわゆるアプリケーションが担っていた仕事、これまでサーバーを立てなければならなかった部分がごっそり持っていかれることになる。Lambda自体は発表が2014年なのでそれなりに経っているけれど、Pythonに対応したあたりから実用される動きが大きくなってきたような感触があります。とはいえLambdaだけですべて済むというわけでもなく、例えばそのエンドポイントとしてAPI Gatewayが使えたり、SNSと連携してメッセージのプッシュを行ったりと、これまで連綿と作られてきたAWS各サービスがあって、それらを繋げる部分に位置することで真価を発揮している。そう考えるとLambdaが単体ですごいというより、AWS全体を見回したときに足りなかった1ピースを埋めてくれたような印象がある。</p>
<h2>Ansible</h2>
<p>そこに来てAnsible、というのはどういう位置付けになるのか。Ansibleの役割はServerlessとは対極、基本的にはサーバーの設定管理というところになります。仮にシステムをServerlessに置き換えていくのだとしたら、ひょっとしたら徐々に要らなくなってくるツールなのかもと思ったり。無論、AnsibleにもAWSモジュールがあるけれど、端々まで対応しているというわけではなく、AWSの設定を管理するのであればCloudFormationやTerraformを使う方が現実的かなという気がします（AWS Summit内で、CloudFormationにLambdaや周辺サービスの設定を書いて、サーバーレスのマイクロサービスをパッケージングする手法が紹介されてました。Lambdaのコードもそのjsonの中に含むので「つらそう」という声は多かったですが）</p>
<p><a href="http://docs.ansible.com/ansible/list_of_cloud_modules.html">Cloud Modules — Ansible Documentation</a>v</p>
<p>まぁ、とはいえ現状を鑑みてサーバーが一切なくなるというのはまずないとも思います。AWS Summitでの趣旨も別にサーバー全廃しろよと言ってるわけではなくて、Lambdaに肩代わりさせることでコストダウンしたり効率化が図れる部分が大きいよという点。だからポイントとしてはAWSのマネージドサービスを上手く使えないかというのが設計上第一に来て、困難な部分はEC2（やオンプレのサーバー）を使用するという発想の転換にあるのかと。</p>
<p>そしていずれにせよas codeであることが求められる。AWS上のマネージドサービスはもはや「インフラ」という言葉で括るにはふさわしくないように思いますが、システムおあらゆるレイヤーをcodeで管理し、アプリケーションと同じCI/CDのサイクルに載せてDevOpsで回していくことはもはや必須になる。そこで使うツールには選択の余地があって、Ansibleでもある程度AWSレイヤーをまかなえたりするし、一方でマネージドサービスはTerraformなどを使う方法もある。そのあたりの匙加減が難しい。</p>
<p>さらに言えば、まだツールが充実しきったとも言えない気がするんですよね。GitHubへのcommitをトリガーとしてサーバーの設定変更まで行うような、インフラCIの手法はまだ確立しきったとは言い難い（そういえばCodePipelineにOpsWorksが対応しましたね）し、Serverspecのようなインフラテストツールもより広がる必要がある。インフラの考え方はここ数年どんどん変化してますけど、まだまだ本格的な動きはこれからなんじゃないかという気がしています。</p>
]]></description>
            <link>https://chroju.dev/blog/aws_summit_ansible_meetup_2016</link>
            <guid isPermaLink="false">aws_summit_ansible_meetup_2016</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 05 Jun 2016 14:46:12 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[インフラエンジニアなので第5回ペパボテックカンファレンス行ってきた]]></title>
            <description><![CDATA[<p><a href="http://pepabo.connpass.com/event/30348/">第5回ペパボテックカンファレンス〜インフラエンジニア大特集〜 - connpass</a></p>
<p>そもそもインフラ向けのイベントって相対的にはやっぱ少ない気がするし、かのペパボさん主催のイベントだし行く以外の選択肢はなかった。アプリ系のイベントだとだいたいが「Pythonエンジニア」みたいに言語ごとだったり、フレームワークまでテーマが絞られたりするなか、「インフラエンジニア」ってよくよく考えたらめっちゃ広いよねって感じだけど、実際の職務もまぁそんな感じだし、今回の話もだいぶ話題としては多岐に渡っていました。</p>
<p>自分の最近の関心事としては社内にAnsible導入させたいなと思いながら格闘しているのと、もっとインフラの低レイヤーの知識深めたいなと思っているのとがあるのだけど、その両面について話が聞けてとてもよかったです。</p>
<h2>インフラのコード管理</h2>
<script async class="speakerdeck-embed" data-id="c2be628f92684309baceb739c9d688a8" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script>
<script async class="speakerdeck-embed" data-id="a54d0ad6100a405497f88b93385c2e3d" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>
<p>前者はdrone.io上にdocker-on-dockerでインフラCI環境を作っているという話。どうもdrone.ioだとベースイメージのバージョンが切り替えられないらしい。自分は過去にAnsibleとServerspecによるCIをCircleCIで走らせる構成を作ったことがあるのだけど、これを社内で導入するなら確かにこうなるんだろうなぁという感じだった。</p>
<p><a href="http://chroju.github.io/blog/2015/11/18/ansible-serverspec-circle-ci/">Ansible + Serverspec + Docker + circle ci によるインフラCI · the world as code</a></p>
<p>後者はあるある、というかAnsible導入検討のなかで自分としても浮かんでいた課題で、コード管理しててもそれを更新する「人手」が必ずしもパーフェクトではないので、コードと実機状態の乖離が出る問題。解決策としてはPuppet、Serverspecと実機の照合を毎日夜間に回して、差異にすぐ気づけるようにするというものでした。わかる。すげーわかる。懇親会でも話していたのだけど、sshして作業しちゃいたいのグッと我慢してPuppetちゃんと書き換えるの大事。個人的にはPuppetとServerspec両方回すのもなかなかしんどそうなので、Serverspec単体を構成変更監視みたいに使うのでもいいかなと思う。</p>
<p>他に印象的だったのは開発側もPuppetを触る、つまり自らインフラの設定変更に手を出せるという話。現状弊社だと、フォルダ1つ掘るのでも、ファイルのコピーでも開発から依頼を受けて運用でsshするみたいなテンション上がらない運用なので、開発にコードでそれを書いてもらえるのはとても効率的に思える。インフラをコード化する一番の意味って、開発と運用という垣根を超えて、インフラを語る共通言語を技術者全体にもたらせることなのだろうなと。まさにDevOps。</p>
<p>あとそういえば「Infrastructure as Code」って言葉を聞かなかった。単語として長いなぁとは思ってたから自分も今度から「インフラのコード化」って言います。</p>
<h2>低レイヤー</h2>
<p>スライドまだ出ていないみたいだけど、ext4からxfsへの移行検討にあたって、結構ガッツリとベンチマークテストやったというLTがありました。クラウド全盛な今日このごろでも足回りは結局物理なんですよというのはまさにその通りで、自分は全然このへんの知識がないのだけどちゃんとやらなきゃなと。。。反省。。。</p>
<p>そして何よりペパボのプライベートクラウド"Nyah"の話ですねー。</p>
<script async class="speakerdeck-embed" data-id="5786d472901a4758a005deeb670746e2" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>
<p>いやもうすげーわー。あこがれるわー。OpenStack使うにあたり社内別グループ会社に経験者がいたので知見を聴けたとか、一気に5バージョン飛ばして最新バージョンへ追随させるとか、技術に対する姿勢が会社も個人もとても前向きで素敵な話だった。真似しようとして簡単に真似できる話ではないけれど、姿勢や方針については本当に参考になった。</p>
<h2>懇親会</h2>
<p>インド人完全無視カレーおいしかった。トムヤムクン入れてるのか。なるほど。</p>
<p><a href="http://calamel.jp/curry">インド人完全無視カレー | インド人のアドバイスを完全無視！－カラメル</a></p>
<p>ペパボの方と実際に話せてよかったです。なんか新しいもの社内に導入したり、広げていったりとなると「結局コミュニケーションだよね」という結論に至ったのでそこは頑張るしかないのかなぁ超ニガテ。あとKPIちゃんと出して比較しないと響かなかったりするってのは確かになという感じなので、自分も腐らず頑張らなきゃなと思い新たにしました。スーパーエンジニアすげーすげーと言っても始まらんし、やりたいならちゃんと自分でやらなきゃなーと。いやー行った甲斐がありました。ありがとうございました。</p>
]]></description>
            <link>https://chroju.dev/blog/pbtech_infra_engineers</link>
            <guid isPermaLink="false">pbtech_infra_engineers</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 14 May 2016 12:58:32 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[#qpstudy 響け！アラートコール！行ってきた]]></title>
            <description><![CDATA[<p><a href="http://www.zusaar.com/event/12327003">#qpstudy 2016.04 響け！アラートコール！　本編 一般枠 on Zusaar</a></p>
<p>こちら参加してきました。アラートコール、というか監視運用をテーマとした勉強会。qpstudyことキューピー3分インフラクッキングについては、数少ないインフラ系の継続的勉強会ということで、気になってはいましたが初参加できました。</p>
<p>以前にも障害対応をテーマとした勉強会に行ったことがありますが、この界隈は闇が深い。。以前のそのイベントも今回のイベントも、いずれも参加者が互いの経験を話し合う場があったわけですが、やっぱりそういうのが一番効果あるかもなぁという気がしました。特に監視運用についてはイベント内でも触れられた通りノウハウや勘に頼っている部分も大きく、他社がどういうノウハウに頼っているのか？というのはとても気になるところ。例えばサービス運用全般のガイドラインとしてITILがあるように、客観的な基準があればいいわけなんですが。</p>
<p>で、監視の基準。これは確かにもう少し考え直した方がいいのかもなと思った次第。例えばメトリック監視ってよくありますけど、仮にCPUが90%使用率達したとして、それがすぐに何か異常に繋がるわけではないのですよね。だから「障害」として扱うべきは単純な閾値超過やエラーではなくて、システム的な動作不全であるはず。それと障害予兆にあたるようなワーニングメッセージは別で扱うべきであって、何が本当に必要な監視、アラートなのかというのは、どの会社でも洗い直すと結構ボロが出てきそうな気がしました。イベントではMakerelのような監視系のSaaSがフレームワークを提供してほしいという声もあったり。あとはAIによる判別。確かにメトリックやログの状態を機械学習させれば、障害予兆をAIで判断させることもできそうな気がします。</p>
<p>今年度に入ってからの自分の社内ミッションは、わりと自動化に重きが置かれているのですけど、イベントでは「自動化は目的ではなく手段」という話もあり。確かに自動化自体が楽しい作業なのでついついなんでも手を出すけど、何のために、またどういった効果があると考えられるから自動化するのか、あるいは自動化の手段には何を用いるのかというところはもうちょっと考えたい。「SaaSを使わない理由って何？」って話もあったけど、そういえばそうだなと。まぁ外部にメトリックやIP持たせるのが嫌、という理由で弊社の場合は通らないかもなぁという気もしますけど、SaaSの導入だって要は監視システムをDIYするプロセスを自動化しているわけで。一考には値するはず。</p>
<p>今回の勉強会はなにか結論をバーン！と提示してくれるものではなく、考えるきっかけを与えてくれるような形式だったので、明日以降ちゃんと社内に持って帰って再検討しようと思います。qpstudy、楽しいので次回もぜひ行きたいところ。</p>
<script async class="speakerdeck-embed" data-id="3aaec6a7751c4245a2951a688eaa5543" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>
<iframe src="//www.slideshare.net/slideshow/embed_code/key/CI5WFlfnIN2Pyf" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/zembutsu/is-it-wront-to-try-to-automate" title="Re: 運用に自動化を求めるのは間違っているだろうか" target="_blank">Re: 運用に自動化を求めるのは間違っているだろうか</a> </strong> from <strong><a href="//www.slideshare.net/zembutsu" target="_blank">Masahito Zembutsu</a></strong> </div>
]]></description>
            <link>https://chroju.dev/blog/qpstudy_alert_call</link>
            <guid isPermaLink="false">qpstudy_alert_call</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 24 Apr 2016 13:28:32 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Pythonに入門している]]></title>
            <description><![CDATA[<h2>Pythonを学び始める</h2>
<p>今年の <a href="http://chroju.github.io/blog/2016/01/03/manifesto-2016/">行動規範</a> でも書いた通り、Pythonに入門している。きっかけはAWS LambdaがPython対応しており、またAnsibleもPythonで書かれているということで、Pythonの読み書きが出来た方が今後良さそうだなと思うに至った。これまでRubyをよく書いていたけど、Linuxにデフォルトで入っているのはPythonやPerlという現実的な問題もある。</p>
<p>今までにやったこととしては取りあえず本を2冊読んだのと、一昨日は <a href="http://python-nyumon.connpass.com/event/26257/">入門者向けのPythonハンズオン</a> に行ったりしてみた。基礎文法はだいたいさらって、requestsのようなポピュラーなライブラリは試してみた程度。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117534/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51SI%2BAszQwL._SL160_.jpg" alt="Pythonチュートリアル 第3版" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117534/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Pythonチュートリアル 第3版</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 16.03.28</div></div><div class="amazlet-detail">Guido van Rossum <br />オライリージャパン <br />売り上げランキング: 24,079<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117534/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00ZR7WZOU/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51moRIhvzhL._SL160_.jpg" alt="Pythonエンジニア養成読本［いまどきの開発ノウハウ満載！］" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00ZR7WZOU/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Pythonエンジニア養成読本［いまどきの開発ノウハウ満載！］</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 16.03.28</div></div><div class="amazlet-detail">技術評論社 (2015-06-16)<br />売り上げランキング: 42,458<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00ZR7WZOU/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>なおPythonチュートリアルはつい先日改版が出たのでそっちをリンクしてます。自分が買ったのは先月です（白目）</p>
<h2>Pythonに対する小並感</h2>
<p>自分はアプリ屋ではないので言語に対する知見は広くないのだけど、なんとなく感じているのはこんなところ。</p>
<ul>
<li>PerlのTMTOWTDIに対して<a href="http://qiita.com/IshitaTakeshi/items/e4145921c8dbf7ba57ef#there-should-be-one---and-preferably-only-one---obvious-way-to-do-it">"There should be one"</a>という考え方が明確で好き。</li>
<li>難読な記法というのが今のところあまりない。発想した通りに書いてだいたい動く気がする。</li>
<li>インデントでブロック形成するのはcoding styleの戦争が起きなくていい。
<ul>
<li>ただし自分はインデント＝スペース2つ派だった。Pythonは4つの方が確かに見やすいけど。</li>
</ul>
</li>
<li>バージョン2.x vs 3.xの話、外から聞いてはいたけどなにこれ面倒。</li>
<li>新参としては3.x学びたいけど、AWS Lambdaが2.7対応だし両方押さえようとしている。</li>
<li><code>pyvenv</code>の環境の隔離の仕方がシンプルで好き。<code>pyenv</code>というのもあって紛らわしいが。</li>
<li>というか全体的にシンプルなコンセプトで作られている印象。</li>
</ul>
<p>2.xと3.xの両輪を回さなくてはならないことを除いては、全体的にはシンプルだし書きやすくてよいなという感じがする。インフラ自動化便利ツールもそろそろなにか書いてみたい。</p>
<h2>新しい言語の学習方法</h2>
<p>あと言語学習ではいままで「とりあえず書く」というのを手法にしていたけど、複数言語を学んでみて徐々にわかってきた勘所が2点ある。</p>
<h3>文法で押さえるべきポイントは決まっている</h3>
<p>例えば<code>elif</code>か<code>elsif</code>か<code>else if</code>かとか、false判定されるのはnullなのか<code>0</code>なのか<code>""</code>なのかとか、複数言語を並行して遣うときに迷うポイントはわりと決まっているので、そこさえ押さえればとりあえず書ける、というのがある気がした。</p>
<p>チートシートを自分用に作るのも漫然と端から文法を並べ立てるのではなく、こういうポイントに限ったものにすると効率がよさそう。</p>
<h3>読むのも勉強</h3>
<p>書くのではなく読むのも勉強。よく言われることではあるけれど、これまであまり意識していなかった。冒頭に挙げた通り、PythonではLambdaとAnsibleという明確にきっかけとなったツールが存在しているので、これらのコードをしばらく読んでものにしてみたいと思う。</p>
<p>あと個人的には最近インフラ界隈でもわりとgolangが話題で気になっているけど、それはまたおいおい（実はgo製OSSを修正して使いたくて、ちょっとだけかじってはいる）。</p>
]]></description>
            <link>https://chroju.dev/blog/entry-python</link>
            <guid isPermaLink="false">entry-python</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 28 Mar 2016 13:29:39 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Personal Knowledge Base 2]]></title>
            <description><![CDATA[<p>年初に<a href="http://chroju.github.io/blog/2016/01/24/personal-knowledge-base/">Personal Knowledge Base · the world as code</a>という記事を上げて、メモや知識の管理をする環境作りを進めていたのだけど、最近ようやく固まってきた。結論としては <strong><a href="https://trello.com/">Trello</a></strong> と <strong><a href="https://github.com/gollum/gollum">gollum</a></strong> を使っている。</p>
<h2>Trello</h2>
<p>近年よく名前を訊く、Kanban形式でのビジュアライズされたタスク管理を可能とするツール。タスク管理向けなので当初は目を向けてなかったのだけど、よくよく冷静に考えてみるとメモ管理にかなり適してそうだったので採用。</p>
<p>結果として、タスクに限らず、数多の情報を整理するツールとしてとても使いやすい。ポイントはいくつか。</p>
<ul>
<li>メモがカードの形で表示されて、パラパラと繰って一覧できる。</li>
<li>メモにラベルを付けると色で表示されるので視認しやすい。</li>
<li>全文検索が可能。</li>
<li>エクスポート機能あり（json）。</li>
<li>descriptionをMarkdownで書くことができる。</li>
<li>Android、iOSいずれもアプリあり。IFTTTも対応。</li>
</ul>
<p>単なるテキストメモを保存する用途であればEvernoteの上位互換だと感じる。何よりも画面全体にメモを並べることができる一覧性の高さがいい。</p>
<p>今の自分は<a href="http://pileofindexcards.org/wiki/index.php?title=%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8">PoIC</a>のような使い方をしていて、とにかくメモを書き溜めては記録、発見、参照の3つのリストに取りあえず分けて、暇なときにつらつら眺めたりしている。分類の仕方はまだ模索中なので、今後変わるかもしれない。とにかく柔軟に使えるのがいい。</p>
<ul>
<li><a href="http://d.hatena.ne.jp/choiyaki/20140920/1411170874">「Trello」というアプリがおもしろい - iPhoneと本と数学となんやかんやと</a></li>
<li><a href="http://victorsavkin.com/post/94468744151/using-trello-for-your-personal-productivity-system">Using Trello for Your Personal Productivity System | Victor Savkin</a></li>
</ul>
<p>GTDは「高度」の管理用といわゆるToDoの管理用に2つボードを設けて使ってみている。プライベートのタスクだけなのでそれほど厳密な期限管理などは必要ないし、これで十分。</p>
<h2>gollum</h2>
<p>散発的な思いつきをTrelloに入れる一方、体系的な知識管理はgollumを使う。GitHub Wikiの機能だけが単独でオープンソース化されているもので、さくらクラウドの2万円クーポンがあったのでとりあえずサーバー1台立ててホストしている。</p>
<p>技術的なメモ書き、読書メモ、あとは趣味で行く美術展の記録などはすべてここに溜めている。Wikiだと散逸的にページを作ってしまいがちなので、トップから最大2階層までの作成と定め、1階層目は各技術ジャンルのページ、2階層目に詳細記事として配置した。こうして体系立てたメモ環境を作ってみると、自分のスキルマップが出来上がっていくようで面白い。</p>
<p>gollumを建てるのに、技術的に難しいことはほとんどない。中身はSinatraとgitなのでカスタマイズもしやすく、とりあえず安易な認証機能ぐらいは追加してみた。作成した記事は個別にMarkdownファイルになってgollumのディレクトリ直下に直置きされるのだが、これはディレクトリを切って<code>git submodule</code>としてGitHub上に上げ、個別管理したいかなと思っている。</p>
<h2>ナレッジ管理の必要性</h2>
<p>ナレッジ管理が必要である、という潮流は昨今高まっているような気はしていて、Qiitaやesa.ioの登場あたりから特にそういう話はよく聞く気がする。</p>
<iframe src="//www.slideshare.net/slideshow/embed_code/key/2R3Nk0tCAKPUnY" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/takoratta/ss-59111661" title="情報共有から始めるチーム開発とキャリア戦略" target="_blank">情報共有から始めるチーム開発とキャリア戦略</a> </strong> from <strong><a target="_blank" href="//www.slideshare.net/takoratta">Takuya Oikawa</a></strong> </div>
<p>個人であれ組織であれ、我々の仕事は（まぁ他の職種も同じだとは思うが）ナレッジを溜めて活用していくことにあるので、こういう取り組みは何がしか進めるべきだろうと思う。上記スライドにもあるように、暗黙知を形式化していくことで自分内でも、社内やコミュニティ内でも知識を記憶、伝達してさらに深めることが可能になる。</p>
<p>とはいえ昨今はツールの乱立はあって、ブログとQiitaの使い分けだったり、個人的なメモをどうするかだったり、やっぱり迷うことも多い。そこはある程度自分なりの使い方を定めておかないと、後々散逸したメモの山に途方に暮れたりはしそう。あと、単純に良いツールがあったとしても、メモする習慣をつけておかないと意味がないし、どちらかといえばそっちが大事なんではという気もする。些細なことでも漫然と調べず、記録するクセをこの2ツールで付けていこうと思う。</p>
<p>以下、他に比較検討したツール群を載せておく。</p>
<h3><a href="https://faqt.co/">FAQT</a></h3>
<ul>
<li>比較した中ではだいぶ惹かれた。一時はこれにしようかと思った。</li>
<li>明確にKnowledge baseを唄ったサービス。Markdownで書いたメモがカード形式で表示できる。</li>
<li>Markdownプレビューが結構好みだし、外観はとてもよかった。</li>
<li>まだ立ち上がったばかりで、将来性はちょっと不安。</li>
<li>全文検索の不在が決め手になり不採用。</li>
</ul>
<h3>Simplenote</h3>
<ul>
<li>定番メモサービス。</li>
<li>Markdown対応がほぼ皆無なので不採用。</li>
</ul>
<h3><a href="http://happenapps.com/#quiver">Quiver</a></h3>
<ul>
<li>最近少し話題になったMac用ノートアプリ。</li>
<li>タグとノートブックで分類するEvernoteっぽいMarkdownノート。</li>
<li>データファイルをDropboxに置いてクラウド同期が可能。</li>
<li>外観がクールだし、結構使い勝手はよかった。</li>
<li>とはいえMacでしか使えないので断念（持ち歩きPCがLinuxなので）</li>
</ul>
<h2>参考</h2>
<ul>
<li><a href="https://medium.com/the-personal-knowledge-management-saga/the-personal-knowledge-management-saga-part-1-ae9bdc575ded#.9xvxjvkkz">The Personal Knowledge Management Saga: #1 — The Personal Knowledge Management Saga — Medium</a></li>
<li><a href="https://news.ycombinator.com/item?id=7697050">Ask HN: What do you use to organize your knowledge? | Hacker News</a></li>
<li><a href="https://news.ycombinator.com/item?id=8806950">Ask HN: How do you manage/organize information and knowledge in your life? | Hacker News</a></li>
<li><a href="http://marcusvorwaller.com/blog/2015/12/14/personal-knowledgebases/">The Sad State of Personal Knowledgebases</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/personal-knowledge-base-2</link>
            <guid isPermaLink="false">personal-knowledge-base-2</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Thu, 17 Mar 2016 13:09:45 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[JAWS DAYS 2016に行ってきた]]></title>
            <description><![CDATA[<p>昨年に続き。</p>
<p><a href="http://chroju.github.io/blog/2015/03/22/jaws-days-2015/">JAWS DAYS 2015でAWS童貞捨ててきた · the world as code</a></p>
<p>昨年JAWS DAYSのハンズオンでAWSアカウント作ったので、これでAWS歴丸1年。それにしては自分の力がしょっぱすぎて嫌になる。もっと活用したい。ただ今回「わからない」というセッションはなかったので（技術メインじゃないセッションをいくつか入れてたのは置いておいて）、それなりに知識はついているのかなぁという実感はできた。</p>
<p>サーバーレスアーキテクチャ、クラウドネイティブという言葉が極めて一般的になったなというのが今回の感想。事例を聞いていてもEC2並べてなんかやりますというのは当然ながらほとんどなくて、だいたいがLambda、Kinesis、API GatewayといったAWSリソースを繋ぎ合わせることでアーキテクチャを作り出している。もう従来的な言葉で言う「インフラ」というものは存在しなくなってしまった。VMwareやXenの時代というのか、あくまでサーバーという実体は変わらず、それの扱い方が変わるというだけの変化だったが、AWSがもたらしているのはサーバーそのものの消失。システムのアーキテクチャ自体の転換。何度かブログ内でも繰り返しているが、この全く新しい領域で勝負するにあたっては、アプリエンジニアもインフラエンジニアも関係ない。こういった状況下で自分が勝負できるとしたら、Opsになるのかなと思う。これまでインフラ屋が担ってきたOpsのスキルを、AWSへ適用していく。もちろん、コードをもっと書けるようにならなくてはならないといった、本来的な問題もあるが。</p>
<p>また今回全体を通して「コミュニティへの参画」というのが強調されていたようにも思う。最初のJAWS-UG代表である今春氏のセッションでも、Increments及川氏のセッションでも、社外のコミュニティに参加することの意義が説かれた。自分はお世辞にも積極参加ができているとは言いがたい状態なので、とても耳が痛い。</p>
<h2>参加セッション</h2>
<h3>JAWS-UGこれまでとこれから（キーノート）</h3>
<ul>
<li>先述した今春氏のキーノート。</li>
<li>京セラドームでもイベントを開いたことがあるというのはちょっと驚き。思い切ってますなぁ。</li>
<li>会場に出来る会社様募集中らしい。企業が無償で場所提供してくれる業界状況というのも非常に恵まれている。というか、そういう文化圏にいて良かったと思う。</li>
</ul>
<h3>AMIMOTO × サーバーレスアーキテクチャ</h3>
<ul>
<li>デジタルキューブ堀家氏。</li>
<li>先述の通り。サービスを疎結合にする。No EC2。</li>
<li>モバイル開発者じゃないからスルーしてたけど、mobile hub面白そう。</li>
<li><a href="https://github.com/serverless/serverless">Serverless Framework</a>気になる。
説明のあった「Lambdaをローカルからinvokeできる」ぐらいならAWS CLIでいいんだけど、他にも活用できそう。</li>
</ul>
<h3>外よりも中からの攻撃・事故がヤバイ、今やるべきクラウドセキュリティ対策</h3>
<ul>
<li>cloudpackのアイレット齊藤氏。今回一番ためになった。</li>
<li>セキュリティに終わりはない、完璧はない、だからきちんと監査して透明性を確保して、リスクを受け入れる。</li>
<li>監査は目的ではない。むしろ時代に追いつけてない監査基準もあったり。</li>
<li>パスワードは脆弱だからSAMLとKerberosでAD連携してSSOとかカッコイイ。</li>
<li>cloudpackでやっていることは公開されているらしいので後でチェック。</li>
</ul>
<h3>[Deep Dive] AWS IoT</h3>
<ul>
<li>mobile hubと同じく敬遠してたIoTだけどなんかやれそうな気になった。</li>
<li>とりあえずラズパイ入手かな。あとPython頑張る。</li>
</ul>
<h3>金融クラウド＆FINTECH最新動向　～AWSで金融のイノベーション！</h3>
<ul>
<li>AWS、MUFG、ウェルスナビの共同セッション。</li>
<li>MUFGがハッカソンとかやってるんだというのは全然知らなかったし意外オブ意外。
時代の潮目が確実に変わってきてるのかなと。</li>
<li>銀行システム、基幹系は今まで通り守らなくてはならない。フロントはスピードを速める必要があると。
その意味でSIerは失くならないと個人的には思っている。少なくとも金融系は。</li>
<li>ウェルスナビ、これまで米富裕層に提供していたような投資診断をモバイル向けで一般にも提供すると。</li>
<li>ITの役割が単なる自動化や効率化じゃなくて、新たな価値、市場を創造することにある。そういう仕事したい。</li>
</ul>
<h3>エンジニアのキャリアとアウトプットを意識した成長戦略</h3>
<ul>
<li>Increments及川氏。</li>
<li>話題になったIncrements入社の理由が「誰もやりそうにないから、差別化戦略として」ってのカッコよすぎた。</li>
<li>及川氏の最初のキャリアであるDECという会社、不勉強につき初耳。紆余曲折の末に現在はhpの一部か。。。</li>
<li>Googleの社是？ "Share everything you can"</li>
<li>Qiitaにもっと投稿しようと思いました（こなみかん）</li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/jaws_days_2016</link>
            <guid isPermaLink="false">jaws_days_2016</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 13 Mar 2016 02:03:24 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[ブログをHugoに移行した]]></title>
            <description><![CDATA[<p>すでに流行りは一巡しているような気もするが、Hugoを導入してみた。もともと自宅iMacにOctopressを置いてブログ作業はしていたのだが、外でもブログ更新ぐらいできた方がいいなぁと考え、クラウド上の開発用端末にレポジトリ移しちゃおうということになり、じゃあついでだからと移行してみた。Go自体は最近使っているオープンソースがそれであったという試しがあり、すでに導入は終えていた（ただし書けない）。</p>
<p>随所で語られているように移行自体は大したものではなく、Markdownでいずれも互換性があるし、Front MatterもYAML形式であれば同一。Hugoレポジトリの<code>content/post</code>配下に記事ファイルを突っ込めば移行としてはおしまい。多少の差異については以下の記事が詳しい。</p>
<p><a href="http://deeeet.com/writing/2014/12/25/hugo/">OctopressからHugoへ移行した | SOTA</a></p>
<p>ただ自分の場合はパーマリンクを前ブログから保てていない。というのも、Octopressで使っていた記事ファイル名が<code>YYYY-MM-DD-foobar.markdown</code>の形だったのに対し、今回は記事のパーマリンクを<code>config.toml</code>で以下のように設定してしまっている。</p>
<pre><code class="language-toml">[permalinks]
    post = "/blog/:year/:month/:day/:filename/"
</code></pre>
<p>従って<code>/blog/YYYY/MM/DD/YYYY-MM-DD-foobar/</code>という歪なパーマリンクになってしまっている記事がいくつかある。ほとんどの記事は<code>foobar.markdown</code>に直したのだが、はてなブログ時代から移植した記事は<code>YYYY-MM-DD-post.markdown</code>という適当なパーマリンクにしていたので、一括して直すことができなかった。時間を見てこれらも意味のあるURLに直すつもり。</p>
<p>記事を公開する流れは以下のようになる。</p>
<pre><code class="language-bash"># 記事作成
$ hugo new post/title.md
$ vi content/post/title.md
# ビルド
$ hugo
# commit
$ cd public
$ git add .
$ git commit -m "new post"
$ git push origin master
</code></pre>
<p><code>hugo</code>コマンドでビルドすると<code>public</code>フォルダにサイト構成全体が吐かれるので、それをそのまま<code>git push</code>して終わり。ただ実際にバージョン管理したいのは<code>public</code>というより、設定ファイルや元のMarkdownが詰まったHugoのレポジトリ全体ではないかという気もするので、後々以下の記事のようにレポジトリ全体で<code>git push</code>してCIでビルドさせる形に変えたいと思う。</p>
<p><a href="http://hori-ryota.com/blog/create-blog-with-hugo-and-circleci/">HugoとCircleCIでGitHub PagesにBlogを公開してみた - Hori Blog</a></p>
<p>なおテーマはとても悩みどころで、しばらくコロコロ変わるかもしれない。というか自分でカスタマイズしたいけどCSSなんて今更書けるのか。。。</p>
<h2>（追記 2016-02-22 23:50）</h2>
<p>フィードのファイルパスがデフォルトだと<code>index.xml</code>になってしまうので、Octopressから変更がないよう<code>atom.xml</code>に直した。<code>config.toml</code>で指定ができる。</p>
<pre><code class="language-toml">rssuri = "atom.xml"
</code></pre>
<p>参考：<a href="https://discuss.gohugo.io/t/what-is-rsslink-exactly/1195/2">What is {{ .RSSlink }}, exactly? - support - Hugo Discussion</a></p>
<h2>その他参考記事</h2>
<ul>
<li><a href="http://qiita.com/syui/items/869538099551f24acbbf">HUGOを使ってサイトを立ち上げる方法 - Qiita</a></li>
<li><a href="https://gohugo.io/tutorials/github-pages-blog/">Hugo - Hosting on GitHub Pages</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/convert-to-hugo</link>
            <guid isPermaLink="false">convert-to-hugo</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Thu, 18 Feb 2016 11:51:20 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Ops JAWS#3に行ってきた]]></title>
            <description><![CDATA[<p>その名の通り運用管理系の話題を中心としたAWSユーザーグループです。ハンズオンもあるということで行ってきた。</p>
<p>メインとなったのはconfig rulesのハンズオン。</p>
<iframe src="//www.slideshare.net/slideshow/embed_code/key/g0o2kIUtI0yKmw" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/okochang/opsjaws-20160128" title="OpsJAWS 20160128" target="_blank">OpsJAWS 20160128</a> </strong> from <strong><a href="//www.slideshare.net/okochang" target="_blank">hideaki yanase</a></strong> </div>
<p>AWSリソース、使っているうちに無秩序になっていき、ルールの統一がはかれなくなったり、全体像が見えづらくなったりということはありがちですが、config rulesを使ってもうシステム的に制御しちゃいましょうというテーマ。例えばCloudTrailが有効化されていない場合にアラートを上げる、とか。監視結果が変化すると、それをトリガーにLambdaをinvokeしたりもできるので、それこそなんでもできる感じ。</p>
<p>やってみて気付いたけど、やっぱり自分は運用が好きなのかもしれない。システムによって、本来不確かであったり信用性に劣っていたりするはずの人間の動作を制御する、というのが好きなんだろうなと。SEやってた頃は運用の制御はExcel資料が元になることが多くて、それ自体は特に楽しくなかったのだけど、システム的に作りこんでいくのはわくわくする。これはいい気付きだったし、次回も是非参加してみたい。</p>
<p>問題としてはやはり、Lambda Functionを書くのにpythonかnode.jsを使う必要がある（いまさらJavaってのもなぁ）ので、次回参加するのであればそれまでにpythonをある程度やっておかねばなぁというところ。</p>
<p>その他、昨年とてもおもしろく読ませていただいたSDの特集『なぜ「運用でカバー」がダメなのか』を書かれた運用設計ラボの波多野氏がいらっしゃっていたりして、個人的にはテンション上がったりもしました。「運用でカバー」をググるとトップに出てくる、なんだか好評を得てしまった拙記事はこちら（あえて移行前ブログを貼るアレ）。</p>
<p><a href="http://chroju89.hatenablog.jp/entry/2015/02/11/164926">Software Design 2015年2月号『なぜ「運用でカバー」がダメなのか』読了 - そのねこが学ぶとき</a></p>
]]></description>
            <link>https://chroju.dev/blog/ops-jaws-3</link>
            <guid isPermaLink="false">ops-jaws-3</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 29 Jan 2016 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Personal Knowledge Base]]></title>
            <description><![CDATA[<p>昨年は転職のゴタゴタがあったりしてメモを取る習慣というものがどこかに消え失せてしまっていたので、年始にあたり生涯幾度目かわからないがメモ環境について再考している。本当に何度目だよ、と思うのだが、これはもう生涯模索しながらいくしかないし、最適解なんてのは時と場合によって変わるものだとは思う。</p>
<p>しかしオライリーから『エンジニアのための時間管理術』は出ているのに、『情報整理術』が出ていないのはなぜなのか。むしろそっちが職種的に重要じゃないのか。ブログやQiitaでもあまり見かけない。</p>
<h2>Evernoteの呪縛</h2>
<p>現代においてメモ、ノートというと真っ先に挙がってくるのがEvernoteであり、自分も確かに使ってはいる。使ってはいるが、正直に言って愛憎は入り混じっている。基本的には使いたくない。でも使わずにはいられなくて、ついついいろいろとぶち込んでしまう。</p>
<p>Evernoteの肝は、ありとあらゆるフォーマットの資料を何でも入れることができて、それがsearchableになることにあると思っている。昨日読んだブログのエントリー。1年前に契約したサービスの証明書。3ヶ月前に読んだ本の感想。そういったものをすべて並列に保存することができ、検索すればすぐに出てくる。放っておけば消えて無くなるような情報が「死蔵」されなくなる。だから取りあえず「いいな」と思ったものがあればEvernoteに入れてしまう。特に開発終了が発表されたClearlyが自分にとってはクリーンヒットで、良いなと思った文章があれば迷わずClearlyを使っていた。ググればまた出ると言われればその通りだが、同じ検索キーワードをまた思い出せるとも限らないし、ページが消滅することだってままある。</p>
<p>しかし実際に突っ込んだ情報をもう一度掘り出せるのかどうか。文字情報であれば確かに検索できるのだが、画像はどうか。音声は。またpdfは。それを防ぐためか、ノートブックやタグ付けという能動的な整理手法も用意されているわけだが、次々と投げ込んだ資料を1つずつ分類していくのは骨が折れるし、メールクライアントにあるようなオートフィルタリングはいまだにできない（サードパーティーのアプリならあるけど）。また実際に検索をかけたときも、ノートの読み込み速度はそれほど速いものではなく、特にモバイルアプリに関してはどうにもストレスフルだ。</p>
<p>結果的に何でも入れられるがサルベージが難しいゴミ箱、あれば安心感があるので離れられないけど、積極的に何か活用していこうとは思えない存在と化してきている。</p>
<h2>何をメモするのか</h2>
<p>そもそも何をそんなに悩むほどメモしたいのか。改めて考えるとよくわからないなぁで思考が停まりそうになったが、いくつか挙げてみる。</p>
<ul>
<li>Tech関連でも日常の中の疑問でもそうだが、ググるのは簡単だがその知識はすぐ忘れてしまう。どこからどんな情報を得て、どんな結論に至ったのかは書き留めておきたい。</li>
<li>スニペットやチートシート。頭悪いのでコマンドや文法をすぐ参照できるようにしておきたい。</li>
<li>読書メモ。簡単な本の概要、感想、それを受けて何を実践するのか。</li>
<li>ポエム。客観的な事実や資料より感情より、主観よりのもの。課題に関する考えとか哲学とか。</li>
<li>チェックリスト。日常の指針になるような。定例作業の手順もそうだし、持ち物リスト、忘れがちなポリシー的なものとか。</li>
</ul>
<p>こうして挙げてみると参照頻度、パブリックorプライベートといった軸で分類できそうな気がしてくる。またそれによって選ぶべきツールも変わりそうだ。例えばEvernoteは先に書いた通り遅い、分類が面倒という特徴を自分は見出しているが、逆にそれほど素早く引き出す必要のないもの、つまり参照頻度が低い「もしものためのメモ」などであればEvernoteでも構わないことになる。</p>
<p>スニペットやチートシートは本当に秒で出てきて欲しいし、シンタックスハイライトが効いてないと辛いみたいなところがあったりもするので、Evernoteには向かないことになる。この目的だと自分の中ではGistやKobitoが最近のヒットではある。</p>
<p>思うに、Evernoteや梅棹忠夫先生が掲げるような「すべてのメモを一箇所に集める」というのはちょっと厳しいのではないか。目的の違うメモであれば、適切なフォーマットも自ずと変わってくる。もちろん分散していろんなところにメモがある状況というのはわかりにくくはあるが、目的がはっきり定まっていればツールの選択に迷うことはない。自分はEvernoteにスニペットを格納したことはないし、日常生活で使うチェックリストをGistのPublicで保存したこともない。</p>
<h2>Personal Knowledge Base</h2>
<p>ここでようやくタイトル回収するのだけど、海外ではこの手のツールをPersonal Knowledge Base(PKB)と呼ぶらしい。<a href="https://en.wikipedia.org/wiki/Personal_knowledge_base">Wikipediaの記述</a>の細かさを見ると、国内よりはだいぶホットな話題っぽく思われる。いろいろこのワードでググッてみたのだが、今のところうなずけたのは以下のあたり。</p>
<ul>
<li><a href="http://www.acuriousmix.com/2014/09/03/designing-a-personal-knowledgebase/">Designing a Personal Knowledgebase – A Curious Mix</a></li>
<li><a href="https://news.ycombinator.com/item?id=8270759">Designing a Personal Knowledgebase | Hacker News</a></li>
<li><a href="http://programmers.stackexchange.com/questions/729/how-do-you-manage-your-knowledge-base">How do you manage your knowledge base? - Programmers Stack Exchange</a></li>
</ul>
<p>特に一番上の記事はだいぶ熱い。俺の理想とするPKBはこんなのだ！！！ってめっちゃ細かく書いているが、わりと同意できる内容ではあった。下2つのフォーラム系の記事を見ると、案外多いのが個人Wikiを使っている人。確かにフレキシブルな編集が可能という点では、2016年現在に至ってもWikiの優位性はかなり高い気がする。でもさすがに今更感あるなーということで手を出す気にはなれない。あるいはorg-modeが結構評判よくて、Vimmerじゃなければ手を出していたようには思う。</p>
<p>PKBの定義に関してはWikipediaの記事にあるが、情報の一次ソースそのものではなくて、そこから得られた知識をまとめるものということ。</p>
<blockquote>
<p>Its purpose is not simply to aggregate all the information sources one has seen, but to preserve the knowledge that one has learned from those sources.</p>
</blockquote>
<p>これについては深く同意するところで、情報そのものなら別に本自体とかウェブページを直接見たりとかすればいいんだけど、それら複数の資料から自分なりに導いた知識、学習結果というものをまとめておきたいのだ。そう考えてみると、Qiitaに特にそういう内容は多く書いているし、一次ソースに関してはウェブクリップなり、本のページを撮影したものなりをEvernoteに入れているので、やっぱりツールの棲み分けになってくるのかなぁと思えてくる。ちなみに一次ソースにあたる情報をまとめたものはPIM(Personal Information Management)と言うらしい。</p>
<h2>結論？</h2>
<p>書いていけば結論見えるかなと思ってここまで書いてみたが、なかなか見えてこない。結局のところ自分の中ではGistが一番近くはある。Gistboxを使えばタグ分類ができるし、<a href="https://github.com/lambdalisue/vim-gista">vim-gista</a>を使うことでVimキーバインドでの編集もできる。コードハイライトもMarkdownのプレビューも出来て至れり尽くせり。引っかかるのは非techなメモを入れるのがGitHubである故に心理的に憚られるなぁというのと、モバイル端末からの閲覧にあまりいいツールがないこと。</p>
<p>んで一方で公開したい情報はこうやってブログにまとめたり、Qiitaにまとめたりもしているので、そこの分断も若干もどかしい。さっきツールは分けるしかないかもと言っておいてアレだが。ちなみにブログはこういう文章過多な場合、いわばポエムだとかツール、技術に関する考察をまとめる場、Qiitaはよりtechそのものに寄ったものを書く場と使い分けている。こういったところで公開共有するほどでもねーやってものはGistかなと。あんまりにも初歩的な内容とかQiitaに流すの憚られるじゃないですか。タグで追ってる人には必ず見られるわけだから。</p>
<p>Evernoteに関しては、結局一次ソースにあたる情報を端からブチ込んで安心感を得るツールとしては今後も使い続けそう。しかしClearlyがなくなるのが本当につらい。Web Clipperのあの鈍重な動きは「何も考えずとりあえずクリップ」するにはちょっと抵抗ある。仕方ないか。しかしウェブクリップというのもどこまで意味のあるものやら。。その後情報が更新されても追えなくなるわけだし。</p>
<p>何はともあれ、とりあえず「記録残せ」から始めなくてはと思う。悩んで結論出ないから記録しないみたいな状態が続くのが一番よろしくない。悩みながらも進めていくしかないんだろうな。</p>
]]></description>
            <link>https://chroju.dev/blog/personal-knowledge-base</link>
            <guid isPermaLink="false">personal-knowledge-base</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 23 Jan 2016 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[東京Node学園付属小学校1限目に行ってきた]]></title>
            <description><![CDATA[<p><a href="http://connpass.com/event/23463/">【増枠！】東京Node学園付属小学校 1時限目 - connpass</a></p>
<p>東京node学園というNode.jsのユーザーコミュニティがありますが、その入門者向けバージョンが立ち上がったので行ってきました。</p>
<p>自分がNode.jsを扱った経験はAWS Lambdaとhubotで遊ぶために既存のスクリプトを少し触ったぐらいで、おそらくは小学校というより幼稚園レベルだったと思いますが、それ以前にやはりフロントエンドの集まりにインフラのエンジニアが行くというのはちょっと自分でも場違い感を覚えずにはいられず、さすがに提供できる話もないやろなってことで懇親会は出ずに帰ってしまいました（）。しかし刺激になったのは確かというか、フロントエンドの世界にちょっとだけ触れられる良い機会ではあったかなと。</p>
<p>そもそもにして自分にとって「言語」は最近手足になってきていて、Ansible使いたいからPythonやっておこうとか、Docker理解したいからgolangかなとかそういう選択ばかりするようになっていたのだが、フロントエンドにとって新しい言語というのは可能性の広がりなのだなーと当たり前のようなことに気付いた。例えば最近Kobitoの実装などで話題のElectronはNode.jsなわけで、サーバーサイドスクリプトであるNode.jsを学ぶことで、デスクトップアプリケーションを従前よりは容易に構築できる可能性になる。作れるものの幅が増える、やれることが膨らんでいくことはエンジニアにとってとても楽しい。</p>
<p>くっだらないものでもなんでも構わんから、とりあえず手を動かして「作る」ことが楽しいって経験をもっとしてもいいのかもなと思った。インフラのデリバリー、運用の効率化、そういうのも大切ではあるけれど、我々がそもそもビジネスとして提供しているサービス、システムとはなんぞやって部分をもう一度見返してみたい気がした。言語は単なるツール、ではないはず。だからこういう勉強会もいいけど、ハンズオンとかもっと行ってみるべきかなと。具体的に今回の勉強会で見かけた中ではMEANスタックが気になるのでやっておきたい。ちょうどMongoに手を付けたかったし。</p>
<p>以上、取り留めのない感想でした。</p>
]]></description>
            <link>https://chroju.dev/blog/node-js-elementary-school-1</link>
            <guid isPermaLink="false">node-js-elementary-school-1</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 19 Jan 2016 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[2016年の行動規範]]></title>
            <description><![CDATA[<p>うまいことまとまらないのでつらつら。</p>
<h2>問題意識</h2>
<ul>
<li>時間、お金の使い方がいまだに下手。
<ul>
<li>きちんと考えず浪費している機会が多い。</li>
<li>時間ならタスクシュート、お金ならZaimを使ったりした経験はあるが結局とまったりしている。</li>
<li>昨年は10年以上続いていた日記すらもとめてしまった。</li>
<li>何か忙しい課題が仕事なりプライベートなりに鎮座すると、他に回す手が一切なくなったりしてバランス悪い。</li>
</ul>
</li>
<li>メモ環境の再考。
<ul>
<li>インプットが「ググって終わり」の場合が多く、次にその情報が必要になったときも結局ググってる。</li>
<li>読んだ本が本当に身になっている気がしない。</li>
<li>Evernoteがメモの死蔵場になっている。</li>
<li>デジタルメモはVimと<a href="https://github.com/glidenote/memolist.vim">memolist.vim</a>を基本にしているけど、書き散らして終わってる感。</li>
</ul>
</li>
<li>技術探求の不足
<ul>
<li>やってるけどやりきれてないというか。</li>
<li>Qiitaで話題になっているのを見て、ザッと読んでなんとなく無理そうと思うと閉じちゃったり。</li>
<li>いつか使うかな？と思ってPocketにつっこんでそのまんまの積読があまりに多い。</li>
<li>流行ってる→やろうとか、こういうツールほしい→作ろうの瞬発力上げたい。</li>
<li>本読みたい。というか去年文化資本にあまりに触らなすぎた。</li>
</ul>
</li>
<li>仲間がほしい
<ul>
<li>懇親会とか行ってもその場限りの話しかできなかったりでエンジニア仲間社外にあんまいない。</li>
<li>社内の技術課題解決するのに社外で話すってのも大切そう。</li>
<li>ていうかエンジニアとしてもうちょい知名度上げてみたい。</li>
</ul>
</li>
</ul>
<h2>解消していくために</h2>
<ul>
<li>時間とお金の定量評価
<ul>
<li>お金は娯楽費にx万までみたいな予算持ってるので、時間も定量評価したい。コード書く時間を週に必ずx時間とか。</li>
<li>タイムロギングしたいけどTogglとか使うの面倒。とりあえずやってみるか。難しけりゃ1日の最後にノートに記憶から書き出すんでもいいかなと。</li>
<li>週ごとのノートにしたい。PDCA回すのにちょうど良いスパンだと思う。今週ダメなら来週帳尻合わせるとか出来るわけで。
<ul>
<li>そういう用途だと紙ノートよりEvernoteの方が良さそう。1ノートに対して1週間という形が取れるので。</li>
<li>じゃあ日記もここに載ってくる形でいっか。</li>
</ul>
</li>
</ul>
</li>
<li>メモをもっかいちゃんとする
<ul>
<li>技術テーマごとにちゃんとノート取る。ブログに上げるといった方がいいか。</li>
<li>ブログ記事にならないレベルのものはQiita。二番煎じ三番煎じでQiitaレベルに値しないものはGist。
<ul>
<li>でもGistあんまり使いやすくない……。</li>
</ul>
</li>
<li>メモを見返す時間をちゃんと作る。週次レビュー的なあれ。金曜夜が第一候補。無理なら土曜。
<ul>
<li>というかそれぐらいの時間は取れるようなスケジューリングをする。去年はそれすら難しいぐらいアホほど予定入れてた。</li>
<li>頭のなかちゃんと棚卸するの大事。</li>
</ul>
</li>
<li>手元のモレスキンはタイムライン的なリアルタイムメモ用にする。アナログは見返すの無理。ざざっと時系列で追う目的でしか使えない。</li>
</ul>
</li>
<li>散逸的な勉強をしない
<ul>
<li>とりあえずおもしろそうなもの、役に立つはずのものに片っ端から手をつけるのやめる。</li>
<li>Pocketに記事を置いとくのはいいけど、1週間ぐらい経ったら躊躇なく消す（自動化できないかな）。</li>
<li>上述の通りブログに上げることを目的としてノートを取っていく。参照する記事はノート上で繰り回す。</li>
<li>スーパーマンになろうとしない（選択と集中、less is more）</li>
</ul>
</li>
<li>技術的な瞬発力の向上
<ul>
<li>手足のように使える言語がほしい。Rubyかじったんだからちゃんとやり切る。</li>
<li>もう1個。デフォルトで入ってる言語だと楽なんだが。Pythonかなー。
<ul>
<li><a href="http://orangain.hatenablog.com/entry/python3-as-default">LinuxディストリビューションにおけるPython 3デフォルト化の流れ - orangain flavor</a></li>
</ul>
</li>
<li>実際の開発経験を積む。API叩くとかやる。動かす。</li>
<li>原則としてCLIで操作する。GUIに頼らない。コマンドでなんとかならないかとまず考える。</li>
</ul>
</li>
<li>文化資本に触れたい
<ul>
<li>1クール3本のアニメ</li>
<li>1か月2冊の小説</li>
<li>1か月2本の映画</li>
</ul>
</li>
<li>エンジニアとしての活動
<ul>
<li>なんかユーザーグループ入ってみたい。職種的に考えるとJAWS-UG？</li>
<li>これだけはという技術分野ほしい。Ansibleが今自分の中でキテるのでもっと。</li>
<li>GitHubをソーシャルにちゃんと使う。横断的な検索とかフォローとかプルリク出してみるとか。</li>
</ul>
</li>
</ul>
<h2>挑むべき技術分野</h2>
<ul>
<li>上述の通り武器言語としてのRuby、Python。</li>
<li>hubotいじる上でnode.jsを少しだけ。</li>
<li>DB経験がさらっさらと言っていいほどないのでMySQL（Mariaでいいか）とRedis。</li>
<li>インフラ関連技術は継続。Ansible、Serverspec、AWS。</li>
<li>最近流行ってるOSSツール類。Elasticsearch、HashiCorp周り、Docker、Sensu、Rundeck、</li>
<li>総合するとこれやってみるといいかも→ <a href="http://syou6162.hatenablog.com/entry/2015/12/21/000843">今年よかった習慣: ライフログ収集および可視化 - syou6162's blog</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/manifesto-2016</link>
            <guid isPermaLink="false">manifesto-2016</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 02 Jan 2016 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Serverspecファーストインプレッション]]></title>
            <description><![CDATA[<p>秋ぐらいから個人開発で試してみて、最近業務でも使えないかとServerspecで試行錯誤している。はじめに言っておくと使用感もコンセプトもとてもしっくりきていて満足している一方で、技術的なハードルはAnsible等より上かもなと思っている。</p>
<h2>サーバー構成の「仕様書」代わりとして</h2>
<p>自分は当初Ansibleで構築したサーバーのあくまでテストツールとして使っていて、「こういう設定にしたい」という頭の中の設計書をAnsible playbooksとServerspecに同時に落とし込み、テストが通ることを確認していた。が、実際にじゃあこれを業務内でどう使おうかとワークフローを考えてみると、仕様書的な使い方がメインになりそうな気がしている。</p>
<p>Serverspecによるテストを実行するのはどういったタイミングか。構築完了時点での確認に用いるのは然り。その後サーバー設定を変更したときには、その内容をServerspecにも反映して再度テストを行うはず。つまりサーバーの仕様、設定の変更にServerspecは追従していく。逆に言えば任意のタイミングで仕掛けたServerspecがエラーを吐くことで、不意のサーバー設定変更を検知できる。サーバーの「正」とされる状態を管理する仕様書の代替として、Serverspecが活用できる気がしている。</p>
<p>中には<a href="http://blog.kenjiskywalker.org/blog/2013/09/20/serverspec-with-cron/">cronで監視チックに実行させている例</a>もあるようだが、それもアリかなと思う。</p>
<h2>導入は簡単だが探求にはRubyスキル必須</h2>
<p>Ansibleが実質的にはYAMLを書くだけで使えてしまい、内部実装に用いられているPythonの知識をほとんど必要としないのに対し、Serverspecは徐ろにRubyスキルを必要とする。</p>
<p>例えば私が初めて書いた<code>spec_helper.rb</code>はこんな感じで、公式のtipsを反映したものとはいえ、デフォルト通りでは使っていない。</p>
<pre><code class="language-ruby">require 'serverspec'
require 'yaml'

properties = YAML.load_file('properties.yml')

host = ENV['TARGET_HOST']
set_property properties[host]

set :backend, :exec
</code></pre>
<p>実際のテスト用のタスクを生成するのもRakefileである。もちろんデフォルトのままでも使えるには使えるのだが、ちょっと凝ったことをしようと思うとRubyが読み書きできていなくては難しい。これは「Rubyにより実装されたインフラテストツール」と理解するより、「RSpecをインフラテストに使えるよう拡張したもの」と捉えた方が正しいように思う。</p>
<p>自分は元々Rubyがある程度書けるものの、RSpecが理解しきれていないので、もう少し勉強しなくてはならなさそう。</p>
<h2>国産OSSであるアドバンテージ</h2>
<p>Serverspecの何より大きなアドバンテージはここではないのか。開発者も国内にいらっしゃるので、Rebuild.fmで直接声が聴けるし、解説本もいち早くO'Reilly Japanから発行されている。特にオライリー本発刊時のRebuild.fmは本自体の補完にもなる内容で、開発コンセプトなどがよく理解できるので聴いておきたい。</p>
<p><a href="http://rebuild.fm/75/">Rebuild: 75: Book Driven Development (gosukenator)</a></p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117097/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51P6qVOPALL._SL160_.jpg" alt="Serverspec" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117097/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Serverspec</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.12.31</div></div><div class="amazlet-detail">宮下 剛輔 <br />オライリージャパン <br />売り上げランキング: 213,793<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117097/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>結論として先述のようにRSpecの拡張的な位置付けであり、その他Infra as Code関連のツールと比べても実装が薄いことから、取り回しがしやすく、今後も継続して使いやすいのではないかと思う。<a href="https://github.com/ryotarai/infrataster">Infrataster</a>とも組み合わせられれば、よりテストの質は増しそう。</p>
]]></description>
            <link>https://chroju.dev/blog/serverspec-first-impression</link>
            <guid isPermaLink="false">serverspec-first-impression</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 30 Dec 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[2015年総括]]></title>
            <description><![CDATA[<p>いろいろとチャレンジングに動いてみただけに、難しい年だった。</p>
<p>今年初めの<a href="http://chroju.github.io/blog/2015/01/12/post/">「行動規範」</a>で書いた通り、就職は、した。大手SIerからいわゆるベンチャー気質な企業に転職して、働き方はだいぶ変わった。毎日Excelとにらめっこしていた生活ではなく、業務上初めてsshを実行し、いまでは毎日実行するような生活になった。</p>
<p>承認と判子と指示が行動の軸だった状態から、個々人のスキルと瞬発力と経験が物を言うような状態になり、率直に言ってついていけてない感はある。どこまでを許可無くやっちゃっていいのかわからない（いわゆるDon’t ask for permission, beg for forgiveness的文化）し、技術検証に手をつけ始めると基礎スキルが低いのでやたら時間を食ってしまい、その間に他の人にタスクを取られたりする。</p>
<p>でもまったく手応えがないわけではなくて、個人開発で使っていたスキルで食い込んでいけるところも大きいし、自分に足りない、学ぶべきことは山のように社内に転がっているので、ひたすら旺盛に吸収していきたいと思う。というかそうしない限り、エンジニアとして生きる道がない。</p>
<p>興味領域としてはDevOps方面にかなりアンテナが伸びてきている。大企業でわりとカッチリ運用設計を認めていた自分が、創業からそれなりの年数が経ち、技術的負債の増えてきたベンチャーに入ったことによる必然とも言えるのだろうが、運用上の穴や非効率な部分がとても目についていて、ルールで縛るのではなく、システム的に運用の統括を図ろうというのが目下の課題となっている。それこそInfrastructure as Codeを使うなりDockerを使うなり、もっと低レイヤーにシェルスクリプトをガリガリ書くなり。だから技術的に磨いて実践していくことが本当に多いのだけど、一方で運用方法の改変ということは社内への浸透が必要になり、政治的な問題にもなってくるので、コミュニケーション力結局必要やんけってところで非コミュな自分は悩んでいる。社内政治ほんとやだ。</p>
<p>まぁ、総じて言えば楽しく仕事はできている。だけど大きな変化は副作用的に予期しない変化を別のところでもたらしたりするものでもあって、そのバランスを取ることがなんとも難しい。貪欲であることと、単に我欲を押し通すこととはまた違うわけで、もう少しコントールが必要だと思っている。リスクテイクしたのだからその分の負担の大きさを覚悟してはいたが、わりと想定以上なところはあってストレスは大きい。年齢も年齢なので、自分が「何をすべきか」という論調よりも、周囲、世の中にとって自分は「何であるのか」という視点で動いた方が良いのかもなという気がしてきた。もう少し、置かれた場所というものも大事にしたい。</p>
<p>抽象論についつい流れてしまったけど、具体的な技術的成果はQiitaを中心に流していこうと思っているので、ブログはポエミーにこんな感じで締めてみる。また来年。</p>
<h2>おまけ：2015年定量評価</h2>
<h3>技術</h3>
<ul>
<li>Linuxのサーバー運用に従事開始。初歩的なコマンドからさらい直せてる。</li>
<li>CentOS7の業務利用開始。</li>
<li>AWSの利用を個人でも業務でも開始。ただしほぼEC2。</li>
<li>Ansible利用開始。</li>
<li>Serverspec検証開始。</li>
<li>Docker検証開始。</li>
</ul>
<h3>イベント</h3>
<ul>
<li>JAWS DAYS 2015</li>
<li>JAWS UG 初心者支部</li>
<li>デブサミ2015</li>
<li>Ansible入門イベント</li>
<li>他社の障害対応気にならNight</li>
<li>手羽の会（ハンズラボ）</li>
<li>Serverworks Sonic!</li>
<li>OSC東京 2015秋</li>
<li>Rakuten Tech 2015</li>
<li>RubyKaigi 2015</li>
<li>他</li>
</ul>
<h3>書籍</h3>
<ul>
<li>リーダブルコード</li>
<li>プログラマが知るべき97のこと</li>
<li>それがぼくには楽しかったから</li>
<li>ハッカーと画家</li>
<li>UNIXという考え方</li>
<li>インターネットのカタチ</li>
<li>Amazon Web Services パターン別構築・運用ガイド</li>
<li>シェルプログラミング実用テクニック</li>
<li>はじめてUNIXで仕事をする人が読む本</li>
<li>大規模サービス技術入門</li>
<li>Serverspec</li>
<li>CentOS7実践ガイド</li>
<li>Team Geak</li>
<li>オペレーティングシステムの基礎</li>
<li>たのしいインフラの歩き方</li>
<li>他</li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/looking-back-2015</link>
            <guid isPermaLink="false">looking-back-2015</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 30 Dec 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『Team Geek』読了]]></title>
            <description><![CDATA[<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873116309/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41SlY0zvpKL._SL160_.jpg" alt="Team Geek ―Googleのギークたちはいかにしてチームを作るのか" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873116309/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Team Geek ―Googleのギークたちはいかにしてチームを作るのか</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.12.14</div></div><div class="amazlet-detail">Brian W. Fitzpatrick Ben Collins-Sussman <br />オライリージャパン <br />売り上げランキング: 18,890<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873116309/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>ひたすら技術ドリブンに仕事できるのであればそれはそれで良いような気はするが、現実にはちゃんとコミュニケーション取る必要はあって、何かやりたいことがあればいわゆる政治的な課題に悩まされることになったりもする。本を読むときはつい技術系のものや個人のハッカーマインドに関するものを読みがちだけど、歳も歳だし組織論もかじろうかということで読んだ。元々読むつもりはあったが、紀伊國屋書店新宿本店でオライリーカレンダーのプレゼントやってたので背中押された。</p>
<p>とても元も子もないまとめ方をしてしまうと、<a href="http://blog.glidenote.com/blog/2015/08/17/move-to-akamai/">KAIZEN Platform, Inc. のエンジニア行動指針</a>がだいぶ本書に影響を受けたと思われるものになっていて、これに全社員がコミットできている状態というのは理想的なのだろうなと思ったりした。本書の内容にはとても賛同できるのだが、「組織論」である以上は自分だけが納得していても仕方なくて、社内でこの内容を文化として定着させなくてはならない。そこのハードルがなかなかに高い。</p>
<p>本書でもそのあたりの話には「組織的操作の技法」として第5章をまるまる当てて触れられていて、例えば「道がないなら道を作る」＝草の根からツールの導入などを始めていく、「許可を求めるより寛容を求めるほうが簡単」、「安全なポジションまで昇進する」といったことが書かれている。結局はできることからやっていく、しかなくなってしまうのかもしれない。</p>
<p>個人のマインドに関する話は大変参考になって、HRT（謙虚、尊敬、信頼）を軸として、「コードの価値を自分の価値と同一視するな」というあたりもだいぶクるものがあった。技術職としては技術的価値の優劣が極めて大きな価値をもっていて、ともすれば「モヒカン」だとか「マサカリ」といった言葉が表すような事態になりかねないのだが、チームが円滑に動くためにはそういったものは障壁となりかねない。技術的に未熟であるメンバーについても、謙虚に対応していくべきだし、また自分の技術は粛々と磨いていくことが必要なんだろうなと。</p>
<p>こういう本は一人で読んでもやっぱり仕方がないところがあるので、チームで買ってシェアしたりもアリかもしれません。</p>
]]></description>
            <link>https://chroju.dev/blog/review-team-geek</link>
            <guid isPermaLink="false">review-team-geek</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 13 Dec 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Dockerファーストインプレッション]]></title>
            <description><![CDATA[<p>前回上げたインフラCIを試みた際、CircleCIを利用する中で初めてDockerに触れたので、今更ながらのファーストインプレッション。</p>
<h2>「仮想マシン」と考えるとDockerは理解しづらい</h2>
<p>Dockerを「仮想マシン」と称する文章も随所で見かけていたが、これを仮想マシンとして捉えると理解からは遠のく。自分自身、Dockerの概念的な理解にはかなり手こずっていて、OSがないのにどうやって「マシン」が動くのかわからなかったし、 <code>chroot</code> のようにファイルシステム上に仮想的なディレクトリツリーを設けるものなのかと思っていた。</p>
<p>Dockerは隔絶された名前空間上で展開されるプロセスに過ぎない。確かにコンテナはOSのような振る舞いを見せるが、そこにいわゆるVMwareやXenのような仮想「マシン」はない。あくまでホストOSの一部リソースを切り出して、仮想的に扱う技術に過ぎない。</p>
<h2>Vagrantの代替？</h2>
<p>一度理解して、 <code>docker run</code> を叩けるようになると利便性は即座に理解できる。OSをブートさせるわけではないのでコンテナの起動は従来の「仮想マシン」と比べて格段に速く、CircleCIで使われている用途同様、テスト用にまっさらな環境が即席で欲しいときには大変重宝する。こういう用途にはもともとVagrantが適していたのだと思うが、本当にすぐ使い捨ててしまいたいようなOS環境であれば、Dockerを使ったほうが遥かに手軽に起動も破棄もこなせる。</p>
<p>ただあまりに簡単に起動、破棄ができるものの、作成したコンテナのイメージはコンテナ終了後も基本的に残存するので、調子に乗っているうちにいつの間にかディスクがかなり消費されていることが何度かあった。コンテナライフサイクルの把握と運用整備はマスト。</p>
<h2>ポータブルなインフラストラクチャー</h2>
<p>Dockerを実用できる一例として、先日Traildashを採用する機会があった。</p>
<p><a href="https://github.com/AppliedTrust/traildash">AppliedTrust/traildash</a></p>
<p>CloudTrailという、AWS APIへのアクセスログをjsonで吐いてくれるAWSサービスがあるのだが、それをElasticsearchで集計してKibanaでブラウザ表示してくれるツール。このツールはDockerイメージで配布されていて、自分のサーバー上にpullしてきて、AWS APIへアクセスするための環境変数をいくつか設定するだけで使えるようになる。自分はElasticsearchの運用経験はないのだが、実質的に <code>docker run</code> コマンド一発だけでそれが使えてしまう。（そのことの是非は置いておくとして）Dockerがアプリケーションサイドで実現することってこういうことなんだろうと。herokuが出たとき、ローカルからインターネットへのサービスのポータビリティが劇的に向上したわけだが、Dockerは稼働先を問わないわけで、ポータビリティはさらに拡大する。</p>
<p>これはインフラ側としても嬉しいところで、今までnginxやらDBやらというミドル的な部分はアプリとしての要求もあり、インフラとしての要求もあり、双方の要件がガッシリ絡んでしまっていて、設定を後から見返すと「これなにゆえにこうなったんだっけ？」ってことが少なくなかったり、構築分担が面倒だったりというのがあって。コンテナとしてアプリをデプロイするとなると、サーバーとコンテナが明確に分離される。疎結合になる。ミドルの調整はコンテナ内だけを気にして行えばよいので、サーバーはとりあえずDocker動いてくれればいいやみたいな状態になる。雑だけど楽だろうなという気がぼんやりしている。</p>
<h2>Dockerの運用</h2>
<p>とりあえず前述のTraildashはDockerによる本番運用（外に出すものではないので本番といえるか微妙ではあるが）の発端にはなりそうなものの、いわゆるアプリ、サービスを本番稼働させるのがどんなもんなのかってところは自分自身見えてない。これをきちんと本番で扱うには可用性やら信頼性やらを担保しなくてはならないわけで、クラスタ構成に用いる<a href="https://docs.docker.com/swarm/">Docker Swarm</a>を導入するだとか、いわゆるインフラとしてのお仕事はやっぱり必要になる。そのへんどこかで試せればなぁとは思うので、ひとまずは自分の http;//chroju.net をDocker化しようかなどと。この前OSCでさくらのクラウド2万円クーポンもらったし、Dockerによる個人PaaS的なものでも作ってみようか。</p>
<p>テストとしての利用には申し分のないところで、先日記事で上げたが<a href="http://chroju.github.io/blog/2015/11/18/ansible-serverspec-circle-ci/">AnsibleとServerspecのテスト</a>に使えるまっさらなOS環境としてDockerは重宝している。Infra as Codeと大変相性がよくて、よくこのタイミングで出てきてくれたなという感じがする。時代の要請なのだろうか。</p>
]]></description>
            <link>https://chroju.dev/blog/docker-first-impression</link>
            <guid isPermaLink="false">docker-first-impression</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Thu, 03 Dec 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Ansible + Serverspec + Docker + circle ci によるインフラCI]]></title>
            <description><![CDATA[<p><a href="http://blog.kenjiskywalker.org/blog/2014/11/13/circleci-docker-ansible-serverspec/">CircleCIでDockerコンテナに対してansibleを実行しserverspecでテストをする - さよならインターネット</a></p>
<p>この記事に書かれている内容を実際にやってみた。Ansibleを一旦は触ってみたところから、Circle.CIどころかCI経験が一切ない、ServerspecとDockerも使ったことがないという出発点だったので、得られるものはだいぶ大きい経験だった。完了したレポジトリは以下。</p>
<p><a href="https://github.com/chroju/ansible-ruby-devs">chroju/ansible-ruby-devs</a></p>
<h1>Ansibleにテストは必要か？</h1>
<p>AnsibleはPlaybookに書かれた設定通りにサーバーをセッティングしてくれるツールなのだから、傍証としてのテストは必要ないし、そもそもそれはAnsibleに対する信頼の問題だという話がある。（かのオライリーのServerspec本でも「Serverspecの必要性」を状況に応じて説明した章がある）が、自分は以下の理由からAnsible実行後のテストは必要と考えている。</p>
<ol>
<li>Playbookの書き方が間違っている</li>
</ol>
<hr>
<p>確かにPlaybookに書いた内容通りにサーバーは組まれるのだが、そもそもPlaybookの書き方がおかしくて、想定通りの実行結果にならない可能性はある。そのレベルであればコードレビューで気付くべきではないかという話もあるが、こういう趣味の個人開発では難しかったり、レビューで漏れがあったりというのも有り得るわけで、自動テストに任せられるならその方が確かかとは思う。</p>
<ol start="2">
<li>冪等性の問題</li>
</ol>
<hr>
<p>特にshellモジュールを用いたときなどは冪等性が維持されない可能性があり、複数回の実行で想定外のサーバー状態になる可能性はある。</p>
<h1>テストツールの選定</h1>
<p>普通にServerspec。Ansibleで定義したインベントリファイルやrolesをServerspecと共有してくれる<a href="http://qiita.com/volanja/items/5e97432d6b231dbb31c1">ansible_spec</a>というツールもあり、当初はこちらを使おうとしていた。が、前述した「Ansibleの書き方自体が間違っている可能性」をテストするとなると、できるだけAnsibleとテストツールは疎結合とするべきと考え、ファイルや設定は一切共有しない形でServerspecを使っている。</p>
<h1>Circle CIの利用</h1>
<p>繰り返しになるが初である。インフラエンジニアがCIをすることはまぁない（なかった）。そんな頻繁に設定を変えるわけでもなし。インフラCIが可能かつ必要となったのは、Infrastructure as Codeの台頭と、クラウドネイティブ化によりImmutableかつ極めて速いライフサイクルでサーバーインフラが更新されるようになったことによるもの。</p>
<p>で、Circle CIでググってもそんなに使い方みたいな初歩的な記事は出ない。どうもCIツールの使い方なんてのはJenkins登場の頃に身につけてて当然だろって感じの扱いっぽい。実際使いながら自分なりに理解したのは「レポジトリをpushすると、それを使って自動的にテストやデプロイを回してくれる」ツールということで、Circle CIについてはこんな感じに認識してるんだがあってんのかなぁ。</p>
<ul>
<li>レポジトリの使用言語やファイル構成を見て良きに計らって勝手にテストしてくれる。</li>
<li>もちろん自分でテストコマンドを書いてもOKで、Circle CIにやってほしいことは <code>circle.yml</code> というYAMLファイルに書いてレポジトリの第一階層に置いておく。</li>
<li>GitHub連携を前提としており、連携したレポジトリの <code>push</code> をトリガーとして動作する。</li>
<li>動作としてはCircle CI上でDockerコンテナ（ubuntuベース）を起動→レポジトリを <code>git clone</code> →circle.ymlを読んで実行</li>
</ul>
<h1>実装</h1>
<p>実際のcircle.ymlはこうなった（といってもほぼ丸のまま冒頭記事のものを使っているが）。Dockerイメージのキャッシュには以下の記事も参考にした。</p>
<p><a href="http://stormcat.hatenablog.com/entry/2015/02/04/004227">CircleCIでDockerイメージをキャッシュするのに、実はちょっとした工夫が必要な件 - tehepero note(・ω&#x3C;)</a></p>
<pre><code class="language-yaml">machine:
  timezone:
    Asia/Tokyo
  services:
    - docker

dependencies:
  pre:
    - if [[ -e ~/docker/docker_ansible_image.tar ]]; then docker load --input ~/docker/docker_ansible_image.tar ; else docker build -t centos_ansible ~/ansible-ruby-devs/ ; mkdir -p ~/docker ; docker save -o ~/docker/docker_ansible_image.tar centos_ansible ; fi

  cache_directories:
    - "~/docker"

test:
  override:
    - docker run -v `pwd`/ansible:/ansible centos_ansible /bin/sh -c 'ansible-playbook /ansible/ci_site.yml -i /ansible/ci_hosts -c local &#x26;&#x26; cd /ansible/spec &#x26;&#x26; /home/develop/.rbenv/bin/rbenv exec bundle install &#x26;&#x26; /home/develop/.rbenv/bin/rbenv exec bundle exec rake spec'
</code></pre>
<p>この方法の肝はAnsibleとServerspecのフォルダを<code>docker run</code>の<code>-v</code>オプションでコンテナにマウントさせてしまって、ローカルでいずれも実行させている点だと思う。Dockerコンテナに対してSSHで外から処理を行うことももちろん可能ではあるが、ちょこちょこと小細工は必要だし、CI上の処理であればミニマムに済ませたいところ。</p>
<p>テストにおいてはインベントリファイルも<code>site.yml</code>もテスト用の設定値となるので、CI用のファイルを置いている。ただ、これらはレポジトリにとっては余分なファイルでしかないので、本来であれば取り除きたいような気もする。妙案は浮かばない。Dockerコンテナは2回目以降の実行だと<code>load</code>するだけで済むし、AnsibleとServerspecはローカル実行なので、処理時間はだいぶ速い。</p>
<p>実行結果はslackの個人チャンネルに流している。GtiHubに上げるだけで勝手にテストして結果も自動通知されるというのはとても楽しい。やれることの自由度が広すぎて夢が広がる。</p>
<h1>つまずいた点</h1>
<ul>
<li>Dockerfile初挑戦につき、結構戸惑った。Ansibleでsshd_configを編集させていたのだが、コンテナにそもそもsshが入ってなくてコケたりした。</li>
<li>Circle CIでのカレントディレクトリの扱いがわからず、しばらく <code>circle.yml</code> で指定するファイルパスに悩まされた。クローンしたレポジトリの中にいる状態で始まるっぽい？</li>
<li><code>docker run</code> に <code>&#x26;&#x26;</code> 付きでコマンド渡すときに <code>/bin/sh -c</code> が必要だとしばらく気付かなかった。</li>
<li>Dockerコンテナを <code>save</code> して <code>load</code> してるので、Dockerfile書き換えたら当然ながらCircle CIを「without cache」で実行しないとダメです。</li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/ansible-serverspec-circle-ci</link>
            <guid isPermaLink="false">ansible-serverspec-circle-ci</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 17 Nov 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[オープンソースカンファレンス2015 Tokyo/Fall行ってきた]]></title>
            <description><![CDATA[<p><a data-flickr-embed="true"  href="https://www.flickr.com/photos/chroju/22273557670/in/dateposted-public/" title="このはちゃんかわいい"><img src="https://farm1.staticflickr.com/630/22273557670_c7c51c391b_z.jpg" width="640" height="640" alt="このはちゃんかわいい"></a><script async src="//embedr.flickr.com/assets/client-code.js" charset="utf-8"></script></p>
<p>戦利品、ConoHaちゃんかわええ。</p>
<p>オープンソースカンファレンスに初めて行ってみた。2015 Tokyo/Fallです。だいぶ奥地の方でやってるなぁという印象があってなかなか行きづらかったのだが、実際行ってみると自然に囲まれて静かで建物綺麗で過ごしやすそうないい大学ですね。ちょっぴり休憩でもくもくしたりしてみたけどだいぶ捗ったし、もう少し近所なら作業環境に使いたい感じが（）</p>
<p>ぼっち参戦かつ初参戦かつコミュ障な故、ブースがんがん回ってがんがん自分から話しかけるみたいな度胸はなく、だいたいセッション聴いてました。ので、セッションごとにちょっとまとめる。</p>
<h1>はじめてのオープンソース・ライセンス</h1>
<p>オープンソース自体の考え方だとかは知ってはいたのだが、ライセンスがMITとかApacheとかそういういろいろがあるのがよくわかってなかったので。話の中で教えていただいた<a href="http://www.catch.jp/oss-license/2013/09/10/github/">Githubによる、オープンソースライセンスの選び方 | オープンソース・ライセンスの談話室</a>というページが確かに詳しそうなので後で読まなければなと思った。ギッハブ使ってるのに全然これ理解してなかった。</p>
<h1>実録！Hinemos導入経験者が語る、実運用でのあるある話</h1>
<p>最近実務でHinemosを使っているもので。監視設定をグループ（スコープ）単位で作ってしまうと静観するときに設定変更がしんどいだとかっていう本当にあるあるな話と、<a href="http://www.hinemos.info/option/utility">Hinemos Utility</a>が便利だという話など。Hinemos Utility、設定のインポートエクスポートがあるので、GUIポチポチの面倒臭さから救われそうな気はした。あるある話の方は他の監視ツールでもわりと似たところあるので、結局アーキテクチャーってどんなツールでも大して変わらんのかなぁ、そのへんどうにかしたツールないかなぁとか思った。</p>
<p>そういえばセッションはTISの主催だったのだが、同社といえば<a href="http://thinkit.co.jp/author/3519">Zabbixの池田氏</a>の印象が強いので、Zabbixと比較して同社としてどう考えてるのかってあたりも聞きたかった。</p>
<h1>[飲食OK]（発表者募集中！）1日目-ライトニングトーク（by OSCスポンサー）</h1>
<p>なかなかカオスにライトニングトーク。飲食OKでしたけど学食せっかくなので使いたかったので無飲食で。言及してるとキリがないので割愛。</p>
<h1>Ubuntuの最新情報</h1>
<p>Ubuntu使ってない。てかDebian系ほとんど触った経験ないんで触らなきゃなと思いました。</p>
<h1>ZabbixでDockerも監視してみよう</h1>
<p>最後の質疑で出た話で、新陳代謝の高いコンテナの監視に既存ツールの分単位での監視感覚が役に立つのか？っていうのがあったのだけど、わりとそれに同意した。自分はコンテナを実サービスで運用した経験がないのでアレなのだが、その性質からして既存サーバーより速いスピードで起動停止を繰り返すことは有り得ると思うし、むしろアーキテクチャーの考え方がスピーディーなものに変わるためには監視ツールの在り方も変わんなきゃならないんじゃないかなぁと思った。答えは出てないけど。</p>
<h1>コンテナ(Docker)時代のインフラ技術・運用管理に迫る！</h1>
<p>Docker最新事情という感じで、Dockerの概要もそこそこに周辺ツールや開発状況をいろいろ舐めていく感じのセッション。Docker触り始めたばかりの自分にはとてもありがたかった。Docker machine、Docker Swarm、docker-composeだとかなかなかにワクワクする話。</p>
<h1>aozorahackの今までとこれから ～インターネット電子図書館「青空文庫」をエンジニアリングで支える～</h1>
<p>ここから2日目。春に<a href="https://atnd.org/events/66230">青空文庫アイディアソン</a>が開かれて話題になりましたが、そのときから興味があったので話を聞いてみた。青空文庫の誕生が1997年、オープンソースという言葉が生まれたのが1998年ということで、オープンソースより古い歴史を持つ青空文庫がOSSライクな発想をしていたはずもない！という出発点だったようなのだが、それを変えていこうという試み。もともとサードパーティ的にビューアやコンバータを作る動きは周辺にあったわけで、それをまとめて今風の開発をしていくとなると面白そうだなと思う。自分は業務エンジニア＋趣味エンジニアでしかないけど、こういうボランティアというか、自らの意志で参画していくエンジニアリング活動というのがOSSの在り方なんだとここで初めて腑に落ちた気がした。</p>
<h1>Solaris ZoneとPuppet、Serverspecでインフラ CI</h1>
<p>Solarisわからないけどインフラ周りの知識手広くしたいなということで行ってはみたがやっぱりわからなかった。知識って広くて浅いか狭くて深いかの二択だと勝手に思ってたけど、実際それなりに出来るエンジニアってそこそこ手広く平均点取れる人が多い気がしていて、例えばこのセッションであればUNIX（Solaris）の知識にコンテナ（Zone）の知識、んでPuppetはRubyだし、ServerspecもRubyというかRSpecなんですよね。エンジニアとしての幅、ちょっと見直したいなと思わされたセッション。</p>
<h1>【パネルディスカッション】今こそ語るエンジニアの幸せな未来 ～OSC東京編～</h1>
<p>春に行ったJAWS DAYSでも同様のパネディスを聴いてはいたので実質第二回というか。こういう話題が定期的に持ち上がるようになったのって、さくらインターネットが15周年迎えたこともあるようにエンジニアの高齢化（家庭環境の変化）があるような気はする。働き方はライフステージによっても、世の中の技術動向やビジネス動向によっても変わるので、結局時間と金銭的余裕のあるうちに勉強して、常に自分が働きやすい場所にいられるようバリューを磨いておくしかないのだろうなと思う。そういう話でした。</p>
<p>以上、9セッション。知識のザッピングとしてこういうセッション形式のイベントはやはり良いなと。いわゆる勉強会だとだいたいが自分の興味関心のあることだけに集中してしまうのだが、こういう機会だとせっかくなのでってことで脇道に逸れたりしやすいので、知識の幅増やす機会にはなりやすいですね。OSS、TISのようにビジネスとして取り扱っている人たちもいれば、aozorahackのような草の根の動きもあったり、有り様はいろいろであって、んでGitHubで取りあえずソース読むところからいつでも手を付けられる時代にあるので、何かしらやってみると面白いのかもしれない。尻込みしてるのではなく。</p>
<blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr">テロ <a href="https://twitter.com/hashtag/osc15tk?src=hash">#osc15tk</a> <a href="https://t.co/OEa2JYMezY">pic.twitter.com/OEa2JYMezY</a></p>&mdash; T.Kabu (@disco_v8) <a href="https://twitter.com/disco_v8/status/657855359357337600">2015, 10月 24</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>懇親会、<a href="https://twitter.com/chroju/status/657852424502276096">TRIGGER ANIMATION EXPO</a>に行けるチャンスがここしかなかったのと、200人という大所帯にぼっち参戦する勇気がないのと（あと、さすがに薄い話しかできなさそうであまり意味はないかなと思った）で行かなかったんだけど、生ハム原木はうらやましかった。</p>
]]></description>
            <link>https://chroju.dev/blog/osc-2015-tokyo-fall</link>
            <guid isPermaLink="false">osc-2015-tokyo-fall</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 24 Oct 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[インフラエンジニアの幸福論]]></title>
            <description><![CDATA[<p>1年前、<a href="http://yapcasia.org/2014/talk/show/df196eac-fb65-11e3-b7e8-e4a96aeab6a4">インフラエンジニアは死んだ</a>。</p>
<p>遅れにも遅れをとって今年からAWSに触れているけど、これは触れれば触れるほどインフラエンジニアとしての自分の価値に疑問を抱かせてくれるサービスで、インフラエンジニアとして今後自分はどのように幸せになれるのかなんて考えたくなってくる。</p>
<p>どうもLambdaが出たあたりから<a href="http://blog.takuros.net/entry/2015/10/19/081349">サーバーレスアーキテクチャ</a>という言葉が取り沙汰されてきているようで、アプリやDBを動かすための基盤としてサーバーが必要だという前提はすでに崩れている。AWSを触れる前はVPSを触っていたので、どうもAWS＝EC2というイメージから抜け出せずにいたが、実際には<a href="http://i-think-it.net/how-to-aws">「EC2を使ったら負け」</a>なんて言葉も目にする時代にある。ここ最近Circle CIを触ってみていても、テストの実行基盤となるサーバーなんて考え方をする必要はなくて、テスト用の環境はyamlで書けてしまうし、別のインスタンスが欲しければDockerで済ませられる。まぁherokuあたりからすでにそういう風潮だったよなという気もするが、単純にアプリをデプロイしてしまって実行基盤は全部お任せという状態から、LambdaとS3とCognitoを組み合わせて云々みたいな柔軟なアーキテクチャを採用できる状態にまで変化してきている。</p>
<p>AWSを管理する人間が旧来のインフラエンジニアである必要性を当人としてはあまり感じていないし、実際に昨今のWeb企業あたりだとアプリエンジニアがAWSエンジニアを兼ねている場合も少なくないとは思う。規模が大きくなれば構成設計にインフラエンジニアの視点が必要になったりもするのかもしれないが、そこで必要とされるスキルは必ずしも旧来のインフラスキルとは直結していない。1000万円のLBとCiscoのスイッチとDELLのサーバーを買ってきて配線して起動して設定していくスキルと、ブラウザ上でELBやEC2のセキュリティグループを設定するスキルは明らかに異なるもので、故に2015年におけるインフラ＝AWSの領域においては、旧来のインフラエンジニアと非インフラエンジニアが同じ土俵で戦えなくもなかったりする（さすがに言い過ぎ感あるか）。これまで培ってきたインフラスキルというものは、必ずしも2015年に戦える武器にはなっていない。</p>
<p>もちろん一方でEC2もオンプレの環境もまだ健在ではあるし、これが10年後に撤廃されるかというと、現状のMFのように残り続けるとは思う。特に金融のような特殊領域ではどうしてもクラウド移行が難しいということもある。だから旧来のインフラエンジニアが死に絶えることはないのだろうが、それでもパイが小さくなることは事実だし、物理環境の障害だとか5年ごとのリプレースだとか、テンションの上がらない類の仕事に携わり続けることを余儀なくされる。</p>
<p>テンションの上がる仕事がしたいと言うと軽薄になってしまうが、誰だって夜中にタクシーでデータセンターに駆け付ける機会は極力少なくしたいと思うわけで、これまで注力していたいわゆる「オープン系」の需要が狭まる中で、インフラエンジニアの「幸福論」のようなものは求められつつある気がする。より少なくなる、かつ結構しんどい椅子に座り続けるのは個人的に嫌なので、Docker、ServerSpec、Ansibleあたりの領域でガッツリ存在感を示せるようになるか、あるいはそれらを生み出す側、より下のレイヤーで技術的に研ぎ澄まされていくかの二択なのかなと最近は思いつつある。とはいえ後者はどう考えても狭き門であり、現実的には前者を日常的な業務としつつ、要はRubyエンジニアがgem書くような感覚でツール作ったりOSSにイッチョカミしたりもたまにやれるぐらいの力があるといいのだろうなと思う。</p>
<p>何はともあれやはり「勉強する」以外に道がないことは今も昔も変わってないし、ある意味で過渡期にある技術として、いまインフラは面白いところにあるとは思っている。これについていけるかついていけないかっていうシンプルな問いでもあって、自分の希望としてはついていきたい。今からアプリに鞍替えする気はなく、カーネル書けるかって言えば書けないだろうし、かといって今のまま障害対応で夜に起こされるのを続けるわけにもいかない。だったら2015年におけるインフラというものを学んでいくしかないわけで、幸いなことに、学べば「物理ハードウェアからの開放」というある程度の報酬が待ち受けていることは確実になっている。どれだけ頑張ってもサーバーのファームウェアのバグで泣かされるような時代ではなく、ある意味でインフラエンジニアが「インフラを学び直す」ことは美味しい選択肢ではある。また場合によっては、インフラエンジニアとしてより良い環境へ適時シフトしていく（惰性でずっとオンプレ使う方針の会社との喧嘩は早々に諦める）こともまた必要になるのだと思っている。</p>
<p>とかなんとか書きながら考えていたら、<a href="http://blog.hifumi.info/2015/02/23/wakateinfra/">若手インフラエンジニア現状確認会</a>とやらで似たような話が上がっていた。個人的な実感としてはITエンジニア100人の企業であれば5～9人ぐらいがインフラかなと思うので、若手インフラが少ないというよりは全体的にインフラエンジニアが少ないのだと思っているが、その分情報交換とか大切にしなきゃなと思う。エンジニア仲間増やしたい。</p>
]]></description>
            <link>https://chroju.dev/blog/eudaemonics-of-infrastructure-engineer</link>
            <guid isPermaLink="false">eudaemonics-of-infrastructure-engineer</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 19 Oct 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[個人開発環境にGithub Flowを適用する]]></title>
            <description><![CDATA[<p>Github、<a href="https://github.com/chroju">joinしたのは2013年</a>で作ったものは軒並みちゃんと突っ込んではいるんだけど、単に一区切りついたらadd => commit => pushしているだけでちゃんと使っていなかったので、個人開発ではあるがGithub Flowを取り入れてみた。</p>
<h1>What is Github flow ?</h1>
<p>Githubを用いた開発作業を進めるにあたっての指針みたいなものです。基本的にはmasterブランチ上では作業せず、作業工程ごとにブランチ作って、終わったらプルリクしてmasterにマージしてもらうことでデプロイとしましょうね、というものだと理解している。至ってシンプルではあるけど、これを取り入れるだけで従来やっちゃってた「masterで作業してるのでデプロイしても動かないレポジトリがGithub上にある」みたいな状態が防げて良さそうだと思った。</p>
<p>ちなみにGit-flowというのもあるようだけど、こちらは全然別個のツールらしく理解していない。Git-flowの問題解決としてGithub Flowが提唱されたようだが、そもそも開発工程の制御のためだけにツールを追加したくはないなと思ったのでGithub Flowを採用した。</p>
<p>Github Flowの理解にはこの文章が良さそう。なお、dotfilesのような大した更新のないレポジトリにはさすがに適用していない。</p>
<p><a href="https://gist.github.com/Gab-km/3705015">GitHub Flow (Japanese translation)</a></p>
<h1>実際の開発工程</h1>
<p>あくまでGithub Flowに沿う形という程度なので、そのままそっくり適用できてはないとは思うが。</p>
<h2>開発開始</h2>
<p>ブランチを切る。ブランチ名は機能追加等の開発要件であれば<code>dev_hoge</code>、バグフィックスであれば<code>hotfix_hoge</code>とする。</p>
<pre><code class="language-bash">$ git checkout -b dev_hoge
</code></pre>
<h2>開発中</h2>
<p>普通であればレビューを依頼するタイミングなど、開発の切りがついたところで<code>push</code>していくのだろうが、分散して開発しているわけではないので、1日の開発が終わる段階で<code>push</code>している。そもそも開発に使っている環境が複数あるので、Github上のdevelopブランチも常に最新化していつどこでも<code>fetch</code>可能にしたいなという思いがある。従来はDropboxで各環境間の同期を取っていたが、プラグインの有無やbundleなどで度々不具合もあったので改めた。</p>
<pre><code class="language-bash">$ git add -A
$ git commit -m "
...
$ git push origin dev_hoge
</code></pre>
<p><code>git add .</code>ではなく<code>-A</code>なのは、そちらじゃないと<code>git rm</code>したファイル等が含まれないと<a href="http://qiita.com/otukutun/items/9feb513c596418e94fc6">こちらの記事</a>に書いてあったゆえ。</p>
<h2>開発終了</h2>
<p>開発が終わり、masterへのマージを必要とする段階に来たらプルリクを出す。プルリクって別のコミッターからしか不可なのかと思っていたが、自分のレポジトリに自分で出すことも可能だったのでそうしている。本来であればテストツール等走らせるべきではあるのだろうが、今のところはプルリクに対して特にレビュー等なく（自分のコードだし）そのままマージしている。</p>
<p>後述するがバグや開発課題の管理にはGithub issueを用いているので、マージの際はissueのナンバーをコメントに入れている。これでGithub上のリンクとして働いてくれるので便利。</p>
<p><a data-flickr-embed="true"  href="https://www.flickr.com/photos/chroju/21903884486/" title="スクリーンショット 2015-10-04 14.19.25"><img src="https://farm1.staticflickr.com/735/21903884486_cae2057f70_z.jpg" width="640" height="576" alt="スクリーンショット 2015-10-04 14.19.25"></a><script async src="//embedr.flickr.com/assets/client-code.js" charset="utf-8"></script></p>
<p>参考：<a href="http://rochefort.hatenablog.com/entry/2015/09/05/090000">Gitコミットメッセージの7大原則 - rochefort's blog</a></p>
<h2>マージ後</h2>
<p>作業ブランチを消して、ローカルのmasterを最新化する。</p>
<p>マージには<code>git merge</code>を使用し、<code>git rebase</code>は使わないことにしている。そもそも<code>rebase</code>完全に理解してないというのもあるが、要するに歴史改変にあたるような操作があまり好めないというのが強い。個人の開発においては作業ブランチの変更中にmasterに更新が入ることは少ないので、このやり方でおそらく不都合はしないと思っている。</p>
<pre><code class="language-bash">$ git checkout master
$ git branch -a
$ git branch -d dev_hoge
$ git push --delete origin dev_hoge
$ git fetch
$ git marge origin/master
</code></pre>
<p>参考
<a href="http://dev.classmethod.jp/tool/git/development-flow-with-branch-and-rebase-by-git/">GitのRebaseによるBranchの運用 ｜ Developers.IO</a>
<a href="http://kray.jp/blog/git-pull-rebase/">git pull と git pull –rebase の違いって？図を交えて説明します！ | KRAY Inc</a></p>
<h2>コンフリクトした場合</h2>
<p><code>git ls-files -u</code>でコンフリクトしたファイルが一覧化されるとのことなので、確認の上で開いて直す。もしローカルかリモートのいずれかを全面採用するのであれば、<code>git checkout</code>の<code>--ours</code>と<code>--theirs</code>オプションを使う。</p>
<pre><code>git ls-files -u
git checkout --ours hoge
git checkout --theris hoge
</code></pre>
<p>参考：<a href="http://d.hatena.ne.jp/sinsoku/20110831/1314720280">Gitでコンフリクトした時のための備忘録 - アジャイルSEを目指すブログ</a></p>
<h2>リモートのmasterがローカルより先に行っている場合</h2>
<p>ローカル環境が複数あるので、このような場合は多々ありえる。そういうときは基本的にはmergeすればいいだけではあるが。masterはリモートレポジトリの最新化が原則となるので、コンフリクトした場合は99%リモートを優先させる。</p>
<pre><code>git show-branch --all --color
git fetch origin
git diff origin/master
git merge origin/master
</code></pre>
<p>参考：<a href="http://qiita.com/yuyuchu3333/items/a30387bdd6a0afc1185c">gitのリモートリポジトリの更新を確認する - Qiita</a></p>
<h2>バグ、開発課題の発生</h2>
<p>先に少し触れたが、開発すべきTODOはすべてGithub issueで管理することにした。今までどうしていたかというと特に管理はしておらず、思いつくままに開発してしまっていたのだが、これでGithubに開発に必要なものはすべて集約できるのではないかと思う。個人でのGithub issue運営には下記の記事を参考にさせてもらっているが、特に難しいことはせず、タスク管理ツールのような形で使っている。</p>
<p>参考：<a href="http://azu.github.io/slide/udonjs/github-issue.html#3">一人で使えるGithub Issue</a></p>
<h1>覚えられない</h1>
<p>Github Flowは便利なのだが、Gitのコマンド体系がどうにも覚えづらくて仕方がない。どうにもならんのでaliasを駆使してなるべく覚える内容を少なくしようと努めているが、あとは慣れるしかないのかなぁと。Githubのコマンドは本当に多い。体系自体を学ぶのであれば<a href="https://progit-ja.github.io/">Pro Git</a>がわかりやすく、epubの配布もあるのでKindleでいつでも読めて最高なのだが、数多あるコマンドを網羅しようとか思うとこれだけではつらい。Qiitaでまとめ記事が上がるたびに覗いてみて、今の自分のキャパで使えそうなのをつまみ食いしていく形で覚えればいいのかなと思っている。</p>
<p>今のalias設定はこんなの。</p>
<pre><code>[alias]
  a  = add
  aa = add --all
  br = branch
  bra = branch -a
  brd = branch -d
  co = checkout
  cob = checkout -b
  coo = checkout --ours
  cot = checkout --theirs
  cl = clone
  clr = clone --recursive
  cm = commit
  cmm = commit -m
  d  = diff
  f  = fetch
  lg = log
  lga = log --graph --decorate --online
  lgp = log -p
  mg = merge
  mgn = merge --no-ff
  ps = push
  psd = push --delete origin
  pso = push origin
  psm = push origin master
  pl = pull
  s  = status -s
  sb = status -s --branch
  ss = status
  sh = show
  sba = show-branch --all
</code></pre>
<h1>今後</h1>
<p>やりたいこととしてはCI。Circle CIとかと連動させて自動テストしたりというところまで組み込めたら、個人開発としてだいぶ理想的な状態かなと思う。そのままデプロイまで自動化できれば最高か。またGitの理解がやはりどうにも覚束ない部分があり、まだまだ使いこなせているとは言いがたいので、aliasをカンペ代わりに育てつつ、ガンガン覚えていきたい。特にミスったときの<code>reset</code>系コマンドがあまりに多くてなぁ……。</p>
<h1>その他参考記事</h1>
<ul>
<li><a href="http://keijinsonyaban.blogspot.jp/2011/05/git.html?m=1">見えないチカラ: 【翻訳】Gitをボトムアップから理解する</a></li>
<li><a href="http://postd.cc/git-command-line-shortcuts/">Gitコマンドラインショートカット | プログラミング | POSTD</a></li>
<li><a href="http://yuroyoro.hatenablog.com/entry/20101008/1286531851">.gitconfigに設定してるaliasなどのまとめ - ( ꒪⌓꒪) ゆるよろ日記</a></li>
<li><a href="http://d.hatena.ne.jp/sinsoku/20111025/1319497900">図で分かるgit-mergeの--ff, --no-ff, --squashの違い - アジャイルSEを目指すブログ</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/individual-github-flow</link>
            <guid isPermaLink="false">individual-github-flow</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 03 Oct 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[開発環境のためのansibleを出来るだけベストプラクティスでまとめた]]></title>
            <description><![CDATA[<p>自分は今まで開発に使うマシンとして家では据え置きのiMac Mid 2010（古い）を、出先ではVAIO Proに入れたArch Linuxを使っていて、レポジトリの同期にはあろうことかDropboxを使っていたのだが、インストールされているツールが微妙に違っていたり、Dropboxで<code>bundle</code>とかまで同期してしまうのはあまりよろしくなさそうだなというのもあったりして、EC2上に開発環境を置いて各端末からはSSHでつなぐことにしてみた。で、せっかくなのでと思いansbileで環境構築を行っている。</p>
<h2>なぜEC2？</h2>
<p>少し前に<a href="http://chroju.github.io/blog/2015/07/20/ansible-digitalocean-vps-dev-env/">開発環境としてDigitalOceanを使うことを勧める記事</a>を書いたことがあったが、仮想マシンを停止しても課金が発生してしまうのが少々つらいのと、リージョンがすべて国外で、開発に使うにはさすがにレイテンシーが厳しいので断念した。EC2であれば停止中は課金されないので、常時起動が必要ない開発環境として使う分には課金額は少なくなりそうかなと考えている。今は自分のアカウントだとまだ無料期間にあたるので、t2.microを無料で使える状態にあり、実際の課金額がどうなるかは確かめていない。</p>
<h2>ベストプラクティス構成の意識</h2>
<p>出来上がったplaybooks（という言い方でいいのか？）はGitHubに上げてある。</p>
<p><a href="https://github.com/chroju/ansible">chroju/ansible</a></p>
<p>あらゆるサーバーで共通の<code>common</code>というロールと、開発環境用の<code>develop</code>というロールを用意している。現状、開発言語がRubyでシェルにはzshを使っているので、完全に自分仕様のplaybookにはなっている。dotfilesも自分のレポジトリから<code>git clone</code>しているし。</p>
<p>ansibleには公式ドキュメントに<a href="http://docs.ansible.com/ansible/playbooks_best_practices.html">ディレクトリ構成のベストプラクティス</a>が上がっていて、なるべくこれに沿うようには作っている。が、完全に当てはめてしまうには開発環境1サーバーだけのためのansibleには荷が重すぎるので、あくまで部分適用ではある。自分の解釈ではベストプラクティスの考え方はこんなところかと。</p>
<ul>
<li>playbooksは同時に実行すべきtaskをroleとして分割する</li>
<li>ansibleの適用対象サーバーはWeb、DB等の役割ごとにグループで分割する</li>
<li>グループごとに実行するroleと変数（group_vars）を紐つける</li>
</ul>
<p>taskはroleに分割され、それらroleをwebservers.ymlやdbservers.ymlがincludeし、さらにsite.ymlがすべての*servers.ymlをincludeするというのが公式の勧めです。確かにこれなら全体に適用したい場合は<code>ansible-playbook site.yml</code>でよいし、一部グループだけに適用したいなら<code>ansible-playbook *servers.yml</code>とすれば良いのだから合理的。さらにインベントリファイルもstagingとproductionに分けて、それぞれにwebserversとdbserversのグループを作っているのだから、stagingとproductonで別々に適用することも可能になると。またtagをtaskにつけておけば特定のtask群だけ実行することも容易になる。。。とまぁ、とにかくいろんな手段を使って分割実行できるようにしているわけですな。</p>
<p>なのでそこまで大規模な構成管理をしないのであれば、このあたりどこまで取り入れるのは自由ではないかと。自分の場合はサーバー1台が今のところは相手ということもあり、*servers.ymlにあたるインベントリファイルは作っていないし、tagも個々のtaskに対しては設定していない。今後さらに範囲を広げるようであれば、後付で設定していけばよいかと思っている。</p>
<p>ただ、少なくともroleに関しては分けておくべきと個人的には推しておきたい。普通にアプリケーション用のコード書くときにも関数やメソッドは分割しますよね？ってことで、全体の見通しを良くする意味でもroleへの分割は必須と思う。</p>
<p>ansible、ファーストインプレッションはとにかく<a href="http://chroju.github.io/blog/2015/06/25/hika-labo-ansible/">「楽そう」</a>だったんだけど、複雑なことをやろうとすればするほどドツボにはまっていきそうな気もする。ある程度早い段階でベストプラクティスに目を通したうえで、自分が使うときにはどういったディレクトリ構成が最も有効であるかを模索した方がよい。自分も理解できるまでは少し苦労したけど、一度やり方をハメてしまうと今後長く使えそうで満足感がある。</p>
<h2>このレポジトリでやっていること</h2>
<p>ソース読んでもらえればわかる話ではありますが。</p>
<ul>
<li>common
<ul>
<li>hostname設定</li>
<li>localeとtimezone設定</li>
<li>sshd_config設定</li>
<li>authorized keys設定</li>
<li>/etc/aliasesの設定</li>
<li>DenyHostsインストール</li>
<li>logwatchインストール</li>
<li>iptables設定</li>
</ul>
</li>
<li>develop
<ul>
<li>development tools、zsh、git、vim、jqのインストール</li>
<li>dotfilesの配置</li>
<li>デフォルトシェルをzshに変更</li>
<li>rbenvの設定</li>
</ul>
</li>
</ul>
<p>もっとも苦労したのはrbenv周りで、<code>git clone</code>直後はpathが通ってない<code>~/.rbenv/bin</code>配下のコマンドをどう実行すべきかとか、それなりに悩んだ。当初インベントリファイルで<code>sudo: yes</code>としてしまっていたので、rbenv関連のタスクも全部root権限で実行されて、軒並みフォルダやファイルがrootの所有になってしまうという事故があったのだが、<code>sudo:</code>ないし<code>become:</code>の設定はタスク単位で考えたほうが良いと思う。また本来であれば<code>~/.bash_profile</code>あたりにrbenvのpath追加等の設定を書き込むところまでタスク化すべきかと思うが、自分の場合はdotfilesにすでに設定が入っているので、そのタスクは作っていない。</p>
<p>もうひとつの悩みとしては、いずれのroleもsudo権限のある開発用ユーザーでの実行を前提に考えているのだが、EC2の場合は<code>ec2_user</code>、その他VPSの場合は<code>root</code>がデフォルトのユーザーなので、デフォルトユーザーで一度入って開発用のユーザーを作るところもタスク化すべきかなと言うこと。その場合はそのroleだけ別ユーザーで実行する形になるわけで、そういった構成がそもそも可能なのか？というところからわかってないのだけど。</p>
<h2>その他技術的な話</h2>
<p>細かい技術的なtipsは後ほどQiitaに上げるつもり。現状の疑問中心に一旦取りまとめます。</p>
<ul>
<li>変数名の命名規約。代入は<code>group_vars</code>で行うことになるが、ここに一挙に集めたときにどれがどこで使われているのかわかりにくいので、roleに紐ついた名前とすべきであろうか。。</li>
<li>ntp.confの設定。templatesでいい気はするのだが、どんなサーバーでも共通の設定で問題ないのか勉強不足でわかっていない。</li>
<li>EC2には開発ツールがないので<code>Development tools</code>でまとめてインストールしてしまったが、本当は個々に切り出したい。</li>
<li>ファイルの一部上書きではなく、追記に良い方法がないものか。下手にやると何度も追記してしまって冪等性がなくなる（現状は一度grepかけて、その内容でtaskの実施要否を分岐してるが汎用性がない）。</li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/ansible-in-nearly-best-practice</link>
            <guid isPermaLink="false">ansible-in-nearly-best-practice</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 23 Sep 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[ハッカーマインドと3冊のエッセイ]]></title>
            <description><![CDATA[<p>ハッカー3大エッセイとは自分が勝手に呼んでいるだけなのだが、『ハッカーと画家』『UNIXという考え方』『それが僕には楽しかったから』の3冊のことである。しかし『それがぼくには』は重要な一冊だと思うんだけど、なんでまた絶版なんですかね。そんな古い本でもないのに。仕方なく図書館で借りたけど。</p>
<p>いわゆるハッカーマインドを描いた本としていずれも似たような印象を抱きがちだが、実際に読んでみるとスタンスはだいぶ異なる。『ハッカーと画家』はコンピュータについてあまり詳しくない人に対して、ハッカーというのはこういう人種なのだと切々と説いた本であり、故にそれほど挑発的な印象は受けず、すらすらと読み進めていくことができる。もっともこれがハッカー以外に理解できるかというとかなり疑問ではあるが、ハッカーが比較的客観的に自らを解き明かした本として参考にはなる。著者のポール・グレアムのエッセイは<a href="http://practical-scheme.net/wiliki/wiliki.cgi?naoya_t:%E3%83%9D%E3%83%BC%E3%83%AB%E3%83%BB%E3%82%B0%E3%83%AC%E3%82%A2%E3%83%A0%E3%81%AE%E3%82%A8%E3%83%83%E3%82%BB%E3%82%A4%E3%81%A8%E5%92%8C%E8%A8%B3%E4%B8%80%E8%A6%A7">naoya_t氏による和訳</a>がいくらか読めるので、これを読んで興味をそそられたら読んでみるのでもいいかもしれない。あと、Lispめっちゃ推してる。</p>
<p>『UNIXという考え方』は、ハッカー向けにハッカーマインド、というかUNIX哲学を説く本なので、これは3冊の中では最も「読むべき」本だと思った。プログラムの移植性が重要であることだとか、ソフトウェアのレバレッジを効かせて効率性を最大限に高めていくべきだとか、我々がコードを書いたりシステムを作る上で重視すべきことがいくつも盛り込まれている。</p>
<p>『それがぼくには楽しかったから』はまさにエッセイ、リーナス・トーヴァルズの半生を描いたもので、ハッカーマインド云々というよりはだいぶ読み物チック。終盤で著作権やOSSといった概念に対するリーナスの考え方が少し語られるが、ほとんどはLinuxがいかにして生まれたのか？を描いた物語と言っていい。自分はリーナスというハッカーをこれまで詳しくは知らなかったのだが、案外柔軟な人物であるという印象を受けた。OSSの考え方自体は肯定しながらも、それは押し付けるべきではない、具体的に名前を挙げてリチャード・ストールマンのやり方は強引に過ぎるとしていたり、自分は聖人君子ではなく、大金が舞い込んだときには当然喜んでしまったこともあるよなんて語っていたり、彼の人間性がとても良く出ている。まぁとはいえ、自分が否とみなしたものに対しては、それなりに厳しい批判を飛ばす人物ではあると思うが。</p>
<p>こうした本に書かれた「ハッカーマインド」なるものは、我々が仕事をする上で必須のものではないと思うし、行き過ぎるとリーナスが言うような宗教戦争チックにもなりかねない。また技術に傾倒しすぎた単なるオタクが仕事の上でも重要な人物足りえるかというと、そういうわけでもない。リーナス・トーヴァルズは偉大なハッカーの1人であろうが、彼は同時にLinux開発者という立場での活動を行うにあたり、社会性を身につけたりもしてきたわけで。単にGeekであること自体が良いこととも自分は思えない。</p>
<p>とはいえ、まだ生成されてまもなく、業界標準なんてものがあるんだかないのだかもわからない、進化の速いこの業界で仕事をしていくには、多少なりともハッカー的なマインドは必要だとも思うのだ。というか、じゃないと仕事が面白くならないんでは？　惰性で同じ技術をずっと使い続けたり、効率の悪い方法を繰り返したりしていてもお金は入るのだろうけど、それが必ずしも収入に結びつかないとしても、なんかカッコイイことやってみたいとか、楽しそうな新技術にトライしてみたいだとか、そういう感覚がないとエンジニアをやっている意味がないなと思う。エンジニアが会社を選ぶにあたって重要なのは、案外このポイントなのではなかろうか。</p>
<p>残念ながら求人票からハッカーマインドは透けてこないし、転職面接の数分でそれを読み解くことも難しいだろう（自分は以前、面接でArch Linuxの話でたまたま意気投合する機会があったりして、そういう面接が出来たら話が別なのだろうけど）。その点、最近GitHubやQiitaでエンジニアたちが企業名を出して活動していることがあるが、あれは求人票やウェブサイトでは見えにくいその会社のハッカーマインドを、外部に知らしめていく良い手段だと感じる。ビジネス的に何を成して、社会をどう変えたいのかというよりも、エンジニアとしてどういったカタチで技術にコミットしていくかの方が自分には重要だ。そういう視点で仕事をしていけたらどんなにか幸せだろうし、またそれは茨の道でもあるのだろうなと思っている。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4274065979/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/511SV9NXW2L._SL160_.jpg" alt="ハッカーと画家 コンピュータ時代の創造者たち" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4274065979/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">ハッカーと画家 コンピュータ時代の創造者たち</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.08.16</div></div><div class="amazlet-detail">ポール グレアム <br />オーム社 <br />売り上げランキング: 6,887<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4274065979/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4274064069/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/518ME653H3L._SL160_.jpg" alt="UNIXという考え方―その設計思想と哲学" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4274064069/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">UNIXという考え方―その設計思想と哲学</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.08.16</div></div><div class="amazlet-detail">Mike Gancarz <br />オーム社 <br />売り上げランキング: 44,838<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4274064069/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4796880011/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51WZM2W6ZBL._SL160_.jpg" alt="それがぼくには楽しかったから (小プロ・ブックス)" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4796880011/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">それがぼくには楽しかったから (小プロ・ブックス)</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.08.16</div></div><div class="amazlet-detail">リーナス トーバルズ デビッド ダイヤモンド <br />小学館プロダクション <br />売り上げランキング: 71,563<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4796880011/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
]]></description>
            <link>https://chroju.dev/blog/hackers-mind-and-their-essay</link>
            <guid isPermaLink="false">hackers-mind-and-their-essay</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 15 Aug 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Qiitaを使うということの意義]]></title>
            <description><![CDATA[<p><a href="http://qiita.com/chroju/">Qiitaにいくつか記事を上げてみて</a>思ったことを。</p>
<h1>承認欲求が満たしやすい</h1>
<p>ブログのような個人の場ではないのに承認欲求がってのもどうなんだという話はあるが、反応を得やすい。Qiitaでは各エントリーに必ずタグを設定することになり、ユーザーは興味のあるタグを登録して新着記事をチェックするわけだが、記事が上がってくるスピードは1日に数えられる程ではあるので、上げればほぼ必ず誰かしらの目には留まる状態にある。なので自分が上げたのは基礎的な記事ばかりだという思いはあるのだが、それでもすべて漏れなくストックされていた。</p>
<p>もちろん、100ストックなどを目指すとハードルはぐっと上がってくるわけだが、こういった個人ブログで誰が見てくれているかわからない状態と比べて、記事投稿へのモチベーションは保ちやすいように感じた。なお、はてなでも同様のエコシステムは働いていて、例えばこのブログもはてな時代はそこそこブクマされていたわけだが、github.io化した後のブクマは見事にゼロである。</p>
<h1>誤り修正と議論の活性化</h1>
<p>ほぼすべての記事が誰かしらの目に触れるということで、（自分は未経験だが）コメントにより間違いの修正が入ることも多い。特に特定のタグに関してはその道の有名な方がだいぶ監視しているっぽいなぁという場合もあり、ちょこちょこコメントが付いている。</p>
<p>またコメントで長々と議論が続くのもよく見かける。単なるハウツーよりは何らかの設計思想を書いた記事に多いように思うが、派生した内容として興味深く追えることも多い。</p>
<h1>技術のコモディティ化</h1>
<p>で、ここからが本題なのだが、QiitaによってIT技術者の知識というのはある程度コモディティ化されそうだなぁと思う。</p>
<p>Qiita以前ははてななどがエンジニアのアウトプットがよくストックされる場所ではあったが、Qiitaほど体系だってまとめられていたわけではない。Qiitaでは「タグ」を追うことで、その分野の新しい話題も古い話題も、基礎も応用も知っていくことができる。逆に言えば、Qiitaに書いてあることぐらいは誰だってすぐ追って身につけられる状態にある。</p>
<p>技術書のような網羅性の高い知識パッケージとはさすがに性質を異にはするが、先に上げたコメントなどによって適宜内容が改訂され、より正しい状態に近づいていき、また必要な情報、新たな情報が次々と追加されるという意味では、動的な知識パッケージとして果たす役割は大きいのではないか。
まぁ要はブログやSNSの黎明期に言われたようなことが、Qiitaという専門性の高い1サービス内で圧縮的に再現されているというだけの話ではあるのだが、「Qiitaをやっている」というレッテルが、ある一定の知識レベルを有することと同義になる日も来そうだなという思いがする。問題点としてはQiita外と同様、やはりWeb系、OSS系の知識に内容が偏っていて、有償製品等のノウハウはそれほど多くないことだろうか。これはQiitaの問題ではないのだけど。</p>
]]></description>
            <link>https://chroju.dev/blog/qiita-commoditization-of-engineer</link>
            <guid isPermaLink="false">qiita-commoditization-of-engineer</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 08 Aug 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Kaminariの実装をしてみた]]></title>
            <description><![CDATA[<p>久しぶりに稼働させている<a href="http://chroju.net/exhibi">ExhiBi</a>というサービスの機能を少し更新した。といってもそれほど大した話ではないですが、一応書き留め。</p>
<h1>kaminari</h1>
<p>ページネーションでデファクトスタンダード状態であるkaminariを使ってみました。</p>
<iframe class="bookmarklet hatena-embed" src="http://hatenablog.com/embed?url=http%3A%2F%2Fgithub.com%2Famatsuda%2Fkaminari" title="amatsuda/kaminari" style="border:none;display:block;margin:0 0 1.7rem;overflow:hidden;height:155px;width:100%;max-width:100%;"><a href="https://github.com/amatsuda/kaminari" target="_blank">amatsuda/kaminari</a></iframe>
<p>bundlerでインストールすればほぼ設定とかなくても使えます。最初のローンチのときに入れなかったので、viewを結構いじらなくちゃいけなくて大変かなーと思っていたのだけど、そんなことはなかった。主に変更は2点で、まずは<code>controller</code>で<code>#index</code>のようなリソースを拾ってくるアクションに<code>.page</code>をかましてやるようにします。</p>
<pre><code class="language-ruby"># もともとはExhibition.all.order...
def index
  @exhibitions = Exhibition.page(params[:page]).order("start_date DESC")
end
</code></pre>
<p>あとは<code>view</code>でページネーションを表示するためのヘルパーを1行追加すれば終わり。以下はslimの場合。</p>
<pre><code class="language-slim">= paginate @exhibitions
</code></pre>
<p>なお、実装当初は<code>undefined method 'deep_symbolize_keys'</code>などというちょっと関係ねーだろこれって感じのエラーが出たりして焦ったのは秘密です。原因は<code>config/locales/ja.yml</code>が一切インデントされてなかったことなんですけど、そんなのがここに波及するんですね。。。てかyamlの書き方よくわかってねーわ。</p>
<p>もちろん、1ページあたりの表示数とかページャーの表示の仕方だとか、いろいろ細かく設定はできますが、とりあえずこれだけでページャーは実装されます。あーこりゃデファクトスタンダードになるわなという簡単さ。早く入れればよかった。なお、本当にまだ入れただけなのでCSSとかぜんぜん調整してないです。</p>
<h1>id以外の要素でmodle#showにアクセスする</h1>
<p>例えばExhiBiの場合は美術館ごとのページにアクセスするには、これまでmuseums/2みたいなURLになっていたわけですが、カッコ悪いし使い勝手も悪いのでmuseums/motなど、英名でアクセスできるよう変えました。参考にしたのは以下ページ。</p>
<iframe class="bookmarklet hatena-embed" src="http://hatenablog.com/embed?url=http%3A%2F%2Fqiita.com%2Fawakia%2Fitems%2Fc2c790dc51e5b084af10" title="Railsで、URLにIDでなく名前を入力して、アクセスする方法 - Qiita" style="border:none;display:block;margin:0 0 1.7rem;overflow:hidden;height:155px;width:100%;max-width:100%;"><a href="http://qiita.com/awakia/items/c2c790dc51e5b084af10" target="_blank">Railsで、URLにIDでなく名前を入力して、アクセスする方法 - Qiita</a></iframe>
<p>やってることはなんともシンプルで、<code>Museum.find(n)</code>で呼んでいたところを<code>Museum.find_by_name_en_or_id(hoge)</code>と出来るようにしただけですね。<code>#to_param</code>でサービス内のリンクもすべて英名表記URLに変更できています。こういう柔軟さはRailsやっぱりいいですね。</p>
<p>ただ自分の場合ちょっと問題があったのは、これまでテーブルに英名表記のカラムを入れてなかったので、新たに追加する必要がありました。まぁ普通に<code>bundle exec rake g migration</code>してから<code>rake db:migrate</code>するだけなんですけど、ローカルで開発しているときに何故かこれが通らず、一旦<code>rake db:migrate:reset</code>してから改めて打つハメになったりした。このへんの話は以下記事がちょっと詳しかったり。</p>
<iframe class="bookmarklet hatena-embed" src="http://hatenablog.com/embed?url=http%3A%2F%2Feasyramble.com%2Fdifference-bettween-rake-db-migrate-reset.html" title="rake db:reset と rake db:migrate:reset の違い | EasyRamble" style="border:none;display:block;margin:0 0 1.7rem;overflow:hidden;height:155px;width:100%;max-width:100%;"><a href="http://easyramble.com/difference-bettween-rake-db-migrate-reset.html" target="_blank">rake db:reset と rake db:migrate:reset の違い | EasyRamble</a></iframe>
<p>自分はインフラエンジニアなので、Railsを実務で使うってことはほとんどこの先皆無だとは思うんですけど、自己表現手段としてやっぱりRailsぐらい使えておくと良さそうだなと改めて思います。例えばインフラの勉強でサーバー運用してみようとなっても、上で何か動いてないとあんまり勉強にならなかったり。自分がどんなことをしているのか？を外にアッピルする意味では、こういうの1つぐらい持っとくといいのだろうなと思います。yamlの勉強しなきゃとか、今回そういう派生効果もありましたので。近々作れたらもう1個サービス作ってみようと思ってます。</p>
]]></description>
            <link>https://chroju.dev/blog/exhibi-update</link>
            <guid isPermaLink="false">exhibi-update</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 07 Aug 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Qiitaはじめました]]></title>
            <description><![CDATA[<iframe class="bookmarklet hatena-embed" src="http://hatenablog.com/embed?url=http%3A%2F%2Fqiita.com%2Fchroju" title="chroju - Qiita" style="border:none;display:block;margin:0 0 1.7rem;overflow:hidden;height:155px;width:100%;max-width:100%;"><a href="http://qiita.com/chroju" target="_blank">chroju - Qiita</a></iframe>
<p>気分でQiitaはじめてみた。Kobitoをちらちら使って簡単なメモを残していたりしたのだけど、そこから一発で上げられるのはやっぱ楽かなと思って。あと先日の<a href="http://chroju.github.io/blog/2015/07/20/encryption-hash-at-first/">暗号化に関する記事</a>みたいなまとめ記事、tips系はやはりQiitaの方がフットワーク軽くて使いやすいような気がする。更新した場合にも履歴が残るし。</p>
<p>ブログとの使い分けが難しそうな気はするが、いわゆる勉強メモみたいな頻繁に見返すものをQiitaに上げて、ブログの方はもっとガッチリとした長文、たとえば勉強会の記録だとか技術に対する考え、あるいは何かを作った系の記事などを上げたらいいのではと思っている。まぁこのへんはあまり縛られず、あくまで中心に据えているのは自分用メモとしての役割なので、自分が使いやすいようなやり方でやれればいいかなと思っている。</p>
<p>ブログは多くとも週2回程度の更新だったが、Qiitaはもっと高い頻度でいろいろ貯めこんでいきたいし、そうできるような仕事をしていきたい所存。</p>
]]></description>
            <link>https://chroju.dev/blog/start-qiita</link>
            <guid isPermaLink="false">start-qiita</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 24 Jul 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[暗号化とハッシュ化に関する基本的な事柄まとめ]]></title>
            <description><![CDATA[<p>セキュリティスペシャリスト持ってるはずなのに曖昧な理解で誤魔化してたので自分用まとめ。また書き足すかも。なんか書き足し書き足ししていくようなノートの整理には、編集履歴が見られるQiitaの方が便利なのかなとか思うけど。</p>
<ul>
<li>暗号化とハッシュ化は違う。暗号化はデータの秘匿を目的としており、適切な鍵を用いることで復号が可能。ハッシュ化はデータの置換がそもそもの目的であり、ハッシュ関数により一定のフォーマットへ不可逆の変換を行う。</li>
<li>ただし、衝突耐性を持つことなどにより、セキュリティ用途に適する「暗号学的ハッシュ関数」というものもあるらしい。デジタル署名やメッセージ認証符号への使用を目的とされており、逆にチェックサム等に使用するには計算が「重い」。</li>
</ul>
<h1>暗号</h1>
<p>主なアルゴリズムをざっと。</p>
<h2>RSA</h2>
<ul>
<li>公開鍵暗号。素因数分解の計算難度を根拠としたもの。サマウォで解いてたアレもたぶん素因数分解暗号だが、暗算で解かれたらたまったものではない。</li>
<li>SSHログイン時の鍵認証やSSL認証など、広く使われる。</li>
<li>秘密鍵生成コマンドとして<code>openssl genrsa</code>がある。SSH鍵認証では<code>ssh-keygen</code>を用いる。</li>
</ul>
<h2>DES</h2>
<ul>
<li>共通鍵暗号。鍵長54bitのブロック暗号。</li>
<li>鍵長が短すぎるため、現在では安全ではないとされるが、暗号化復号化処理を3回実行するトリプルDESという形で主に実用されている。</li>
<li><code>openssl genrsa</code>での秘密鍵生成時に、パスフレーズによるトリプルDESでの暗号化を施すため、<code>-des3</code>オプションが用いられる。</li>
</ul>
<h2>AES</h2>
<ul>
<li>共通鍵暗号。DESの安全性低下に伴い開発された、鍵長128bit超のブロック暗号。</li>
</ul>
<h1>ハッシュ</h1>
<h2>ソルト</h2>
<p>ハッシュ化前に対象文字列に付加するランダムな文字列。同一文字列のハッシュ化時に衝突が防げる、レインボーテーブルによる探索に対する妨害になる、といった利点がある。</p>
<h2>フィンガープリント</h2>
<p>SSH初回ログインで表示されるやつ。公開鍵のハッシュ値。<code>~/.ssh/known_hosts</code>に記述され、次回以降のログインで公開鍵の変更有無の確認に使われる。変更があると、サーバーなりすましの危険性もあるため警告が表示される。<code>ssh-keygen -lf</code>でも表示可能。</p>
<h2>md5</h2>
<ul>
<li>出力128bitのハッシュアルゴリズム。ファイル配布時のチェックサムなどに用いられる。</li>
<li>安全性は高くないことが判明しているため、日米ともにSHAの使用が推奨されている。</li>
<li>コマンドは<code>md5sum</code>あるいは<code>openssl md5</code>を使用する。</li>
<li>なおパスワードハッシュ化でよく用いられる<code>openssl passwd</code>はmd5による実装。</li>
</ul>
<h2>sha</h2>
<ul>
<li>Secure Hash Algorithm。暗号学的ハッシュ関数の一つ。</li>
<li>SSL、SSH等で用いられる暗号化アルゴリズム。</li>
<li>SHA-0,1,2,3が存在しており、SHA-1には脆弱性が存在するため、SSL証明書はSHA-2への全面移行が進められている。すでにGoogle ChromeではSHA-1による証明書に対して警告が表示される。</li>
<li>SHA-2は鍵長によりSHA-224、SHA-256、SHA-384、SHA-512といったバリエーションが存在する。</li>
<li>上述の通り<code>openssl passwd</code>はSHA非対応だが、<code>grub-crypt</code>がSHA-2によるハッシュ化に使える模様。
参考: <a href="http://heroween.hateblo.jp/entry/2014/07/28/133713">CentOS6.5でランダムSalt付きSHA-512のシャドウパスワードを生成する - ひろうぃんの雑記</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/encryption-hash-at-first</link>
            <guid isPermaLink="false">encryption-hash-at-first</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 19 Jul 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[AnsibleとDigitalOceanでどこでも使える開発環境を作る]]></title>
            <description><![CDATA[<p>個人開発環境としては自宅にiMac 2010Mid、モバイルでVAIO Pro 11に入れたArch Linuxを使っているのだが、メインとしてはiMacの方を利用していて、デプロイしたりなんだりは自宅からしか出来ない状態にある。じゃあVAIOに移せばいいやんとも思うのだが、こちらも会社PC（なぜかこちらもVAIO Pro 11）と二重になってしまうので始終持ち歩きたくはなく、平日フラフラしてるときにサッとbash入りたいなみたいのが出来ずにいた。</p>
<p>結論としてVPSを開発環境として扱い、最悪iPad miniからいつでもSSH接続してbash叩けるだけでも幸せかなというところに至った。これまで<a href="http://chroju.net">http://chroju.net</a>をさくらVPSで運営していたので、特に考えずさくらをもう1台追加したりもしたのだが、ちょっと調べてみると<a href="https://www.digitalocean.com/">DigitalOcean</a>が最近流行りつつあるようだったので、他社サービスも使ってみると面白そうだってことで新規契約してみた。</p>
<h2>DigitalOcean</h2>
<p>すでに他所で言われてはいるが、利点としてはこんなところかと思う。</p>
<ul>
<li>月額課金ではなく時間課金なので、使いたいだけ払えばOK</li>
<li>安い</li>
<li>アプリケーションやSSH鍵が最初から組み込まれたイメージを作れる</li>
<li>REST APIでだいたいのVPS操作ができる</li>
</ul>
<p>要するに使いたいときに使いたい環境をバチコンと作れちゃうというのが一番のメリットなので、今回のような永続的に使う開発環境より、一時的なテストなんかに使った方が良いのだと思う。とはいえ時間課金上限が月あたりで定められており、現状最安プランだと月5ドルが上限になっていたりもするので、永続的にマシンを上げておく分にも安いのは確か。なお、課金はイメージを作った時点で開始されるので、不要なマシンはhaltではなくdestroyしておく必要がある。まぁ無料のスナップショット機能もあるから、リカバリできると思えばdestroyしてしまうこともそこまで難しくはないかなと。</p>
<p>REST API提供ということで、CLIから落としたり上げたり壊したりなんだりも全部できるのだが、だったらひょっとして誰かがアプリとか作ってんじゃねーかなと思ったら、やっぱりすでにあった。</p>
<div class="bookmarklet bookmarklet-gp" itemscope itemtype="http://schema.org/MobileApplication" style="clear:both;min-height:165px;width:100%;max-width:468px;overflow:hidden;padding:12px;border:1px solid;border-color:#eaeaea #ddd #d0d0d0;-moz-box-sizing:border-box;box-sizing:border-box;border-radius:5px;"><dl class="bookmarklet-gp-info" style="margin:0;"><dt class="bookmarklet-gp-title" style="border-bottom:1px solid;border-color:#eaeaea #ddd #d0d0d0;font-weight:bold;margin:0 0 .5em 0;padding:0 0 .5em 0;"><img alt="Google play" class="favicon" style="vertical-align:middle;border:0;" src="//ssl.gstatic.com/android/market_images/web/favicon.ico" /> <span itemprop="name">DigitalOcean Swimmer Android</span></dt><dd class="bookmarklet-gp-desc" style="font-size:.9em;margin:0;"><div class="bookmarklet-gp-thumb" style="float:left;"><img src="https://lh3.ggpht.com/HXBZyHdspPh5MFgaC-rOXAZIZc8D9uM4KrQsL-gqoB1_9ZuBhthaWYLRoYJYNUY9Ytg=w300" alt="DigitalOcean Swimmer Android" itemprop="image" style="height:120px;width:120px;max-width:100%;vertical-align:middle;border:0;margin:0 1em 0 0;"></div><div class="supplier" itemscope itemtype="http://schema.org/Organization">制作: <span itemprop="name">Hannoun Yassir</span></div><div class="review" itemtype="http://schema.org/AggregateRating" itemscope itemprop="aggregateRating">評価: <span itemprop="ratingValue">4.4</span> / 5段階中</div><div class="price" itemtype="http://schema.org/Offer" itemscope itemprop="offers">価格: <meta itemprop="price" content="0">無料<small> (2015/7/11 時点)</small><br /></div><a href="https://play.google.com/store/apps/details?id=com.yassirh.digitalocean&hl=ja" target="_blank" title="DigitalOcean Swimmer Android" itemprop="url" style="float:right;"><img src="//dl.dropboxusercontent.com/u/540358/ja_generic_rgb_wo_45.png" alt="ダウンロード" style="border:0;display:inline-block;height:auto;vertical-align: middle;"/></a><small>posted by: <a target="_blank" href="http://hayashikejinan.com/?p=818">AndroidHTML v3.1</a></small></dd></dl></div>
<p>このアプリさえあればGUI操作はほぼ全部できる。</p>
<p>ちなみにこんなことでハマる人はほとんどいないだろうと思うが、自分がハマったポイントとして<code>authorized_keys</code>の件がある。Digital OceanではあらかじめWeb GUIで公開鍵を上げておき、VPSをcreateするときに最初から任意の鍵を入れておくことができるのだが、当初は<code>root</code>以外のユーザーがいないため、当然ながら<code>authorized_keys</code>のパスも<code>/root/.ssh/</code>配下となる。構築用には別のユーザーを設けることになると思うが、その際には<code>authorized_keys</code>を<code>/home/user</code>配下へ持ってきて、アクセス権の適切な設定などもしなくてはssh接続できないので注意。</p>
<h2>Ansibleによる初期構築</h2>
<p>巷ではVagrantと連携して、<code>vagrant up</code>でDigitalOceanにマシンを上げるのが流行ってるらしい。</p>
<ul>
<li><a href="http://qiita.com/msykiino/items/d45cab7f520a3288862a">vagrantではじめるクラウド開発環境（DigitalOcean編） - Qiita</a></li>
<li><a href="http://blog.glidenote.com/blog/2013/12/05/digital-ocean-with-vagrant/">VagrantとSSDなVPS(Digital Ocean)で1時間1円の使い捨て高速サーバ環境を構築する - Glide Note - グライドノート</a></li>
</ul>
<p>とはいえ自分は冒頭に書いた通り、最悪iPad miniでもいいので外から繋ぐという運用をしたかったので、Vagrantからの起動は使えない。なので初期構築には最近学び始めたAnsibleを使ってみた。</p>
<p>インフラ管理系のツール、使ったことがあるのはChefぐらいで、Puppetは概念だけ知ってはいるが、Ansibleの特色はやはりハードルの低さ、学習コストの低さだと思う。エージェントレス、<code>knife</code>のような特殊なコマンドもほとんど覚える必要がなく、<code>ansible-playbook</code>コマンドさえ覚えておけばとりあえずなんとかなってしまう。</p>
<ul>
<li>エージェントレスなのでpipで手元のマシンにansibleを入れればすぐ使える。</li>
<li>設定はyamlによるplaybookに書き出すので、文法も比較的容易。</li>
<li>1個1個のタスクは定められたモジュールを用いて書くことになるが、やりたいことを公式Docsの<a href="http://docs.ansible.com/modules_by_category.html">Module Index</a>で探ればわりとなんとかなる。</li>
<li>ディレクトリ掘ったり<code>knife</code>みたいなコマンドいっぱい覚えなくても、とりあえずyaml1つとコマンド1つあれば始められる。</li>
</ul>
<p>pip経由でのインストールが必要なので非pythonista的には若干戸惑いもありましたが、学習コストの低さはハンパないのでインストールから1時間もあれば一旦サーバー建てられました。ノウハウもQiitaはじめ随所に落ちてはいるけれど、正直公式ドキュメントがかなり充実していて、<a href="http://docs.ansible.com/YAMLSyntax.html">YAMLのシンタックスガイド</a>まで付いていたりするので、下手にググってやるよりもドキュメントちゃんと読んだ方がいいと思う。まぁ、Ansibleにかぎらずなんだってそうではあるが。ただ、複数台管理だとかアプリのデプロイだとかをやろうとすると当然ディレクトリ構成も複雑になって、既存のプラクティスが必要になってくるので、あくまで「導入の学習コストが低い」という感じだが。</p>
<p>書いたPlaybookはとりあえずGitHubに上げた。<a href="http://akiyoko.hatenablog.jp/entry/2013/12/16/020529">こちら</a>を参考に、いわゆるVPS作るときの初期設定だけまとめている。ただしわりと俺用（dotfiles引っ張ってきたりとか）。Ansibleについてはまた別の記事でまとめようと思う。</p>
<p><a href="https://github.com/chroju/ansible">chroju/ansible</a></p>
<h2>iPadからのSSH接続</h2>
<p>クライアントソフトがいろいろあるのは知っていたが、ここまでのレベルと思わんかったなーというのが<a href="https://panic.com/jp/prompt/">Prompt2</a>。</p>
<p><a data-flickr-embed="true" href="https://www.flickr.com/photos/chroju/19822940536" title="prompt_with_digitalocean"><img src="https://farm1.staticflickr.com/541/19822940536_5f6201ca53_z.jpg" width="640" height="480" alt="prompt_with_digitalocean"></a><script async src="//embedr.flickr.com/assets/client-code.js" charset="utf-8"></script></p>
<p>vim-lightlineもきちんと表示してくれるし日本語も可だし、外付けキーボードの煩わしささえ考慮しなければかなり快適である。当然ながら鍵認証も使えるし、ぶっちゃけWindowsのラップトップ持ち歩くぐらいならこっちの方がSSHはストレスないんじゃないかというぐらい。つないでちょこちょこっと使えればいいかなぐらいの思いだったが、嬉しい誤算だった。さすがに有料ではあるけど。</p>
<p>おかげさまで場所を選ばず開発環境につながるようになったので、ちょっと試したいツールがTLに上がってきたりしたらおもむろにiPadを取り出して試したりとかできる。すぐ復元したいのであれば、先のAndroidアプリで予めスナップショットを取ったりもできるし、楽すぎて笑える。</p>
]]></description>
            <link>https://chroju.dev/blog/ansible-digitalocean-vps-dev-env</link>
            <guid isPermaLink="false">ansible-digitalocean-vps-dev-env</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 19 Jul 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Windows開発環境を整える話と、メモアプリとして最強であるwasaviの話]]></title>
            <description><![CDATA[<p>職場のWindows PC、いろいろと開発用に整備を進めてはいるが、やはりWindowsだとツラミある。</p>
<h2>Chocolatey</h2>
<p>Windowsでのパッケージ管理。不可欠かというとそうでもないとは思うのだが、アップデート含め一括管理が可能なので、精神衛生上良さそうだという意味で使ってみている。どうでもいいが名前がかわいい。</p>
<p>インストール自体はPowershellからワンライナーを叩くだけなので難しくはないのだが、よくわからないエラーで止まることが多くて、現状使い切れてない。Proxyの設定はしたし、powershellの権限も<code>RemoteSigned</code>にしたのだけど、何がいけないのか。。。</p>
<pre><code> Unable to index into an object of type System.IO.FileInfo.
 発生場所 C:\ProgramData\chocolatey\helpers\functions\Write-ChocolateyFailure.ps
 1:24 文字:8
 +   throw &#x3C;&#x3C;&#x3C;&#x3C;  "$failureMessage"
     + CategoryInfo          : OperationStopped: (Unable to index...em.IO.FileI
    nfo.:String) []、RuntimeException
     + FullyQualifiedErrorId : Unable to index into an object of type System.IO
    .FileInfo.
The install of clover was NOT successful.
Error while running 'C:\ProgramData\chocolatey\lib\Clover\tools\chocolateyInstall.ps1'.
 See log for details.
</code></pre>
<h3>参考</h3>
<p><a href="http://qiita.com/himinato/items/11f4dc9a23afebbc242c">windowsの開発環境は一瞬で整うwith chocolatey - Qiita</a></p>
<h2>コンソール</h2>
<p>cmdだと貧弱貧弱ゥ！なので、とか、bashコマンド試し打ちしたい場合が多いとか、そういう理由でコンソールは入れ直す。</p>
<p>Gitを入れると自動的にGit bashが入るので、コマンド環境としてはこれを使っている。ターミナルアプリは最近ちょっと話題になっていたのでConEmuを入れてみた。もちろんChocolateyで。</p>
<ul>
<li>Font charsetを「Shiftjis」に設定</li>
<li>フォントは<a href="http://github.com/yascentur/RictyDiminished">Ricty Diminished</a>を利用</li>
<li>lsで日本語が化けるので<code>~/.bashrc</code>に<code>alias ls='ls --show-control-chars --colors'</code>を設定</li>
</ul>
<h3>参考</h3>
<p><a href="http://astra.digi2.jp/a/e/setup-conemu-as-japanese-cmd.html">ConEmuの初期設定(日本語表示環境を構築) - Diary on wind @astra.dat</a>
<a href="http://qiita.com/ironsand/items/ec0675644a55a69855d6">Ruby - 【無理】WindowsのコンソールでUnicodeを使いたい - Qiita</a></p>
<p>Windowsで開発する場合の最大のネックは、CLIの貧弱さ以上にcp932にあると思うの。</p>
<h2>AutoHotkey</h2>
<p>キーバインド変えたいことが多いので愛用。とりあえず<code>&#x3C;ESC></code>と間違えて隣の<code>F1</code>押してヘルプ出てしまうことが多いので、<code>F1</code>は潰している。</p>
<pre><code class="language-autohotkey">F1::Return
</code></pre>
<p>あとOutlookの使い勝手があまり好きではないので、配布されていたGmailライクなキーバインドを実現する設定を使わせていただいている。しかしOutlook2013、差出人名の表示がやたらでかかったり、フォルダのツリー表示が文字だけ（アイコンとかツリーを表す罫線がない）になっていて見づらかったり、UI面で難がありすぎる。。。</p>
<h3>参考</h3>
<p><a href="http://www.autohotkey.com/board/topic/102227-gmailkeys-for-outlook-2013/">GmailKeys for Outlook 2013 - Scripts and Functions - AutoHotkey Community</a></p>
<h2>メモアプリ</h2>
<p>技術的なことをやってるとどうしてもメモを取る必要性が出てくるのだが、いろんなところに書き散らしていると後から見返せないのでそれなりの整理はしておきたいと常々思う。</p>
<p>元々は自宅だとDropbox + QFixHowm(Vim)、会社だと（あまり技術的な話が多くなかったので＆クラウド系アプリは使えなかったので）別個の環境で同様にQFixHowmを使っていたのだが、比較的技術的なノウハウをとりためることも増えたので、可能なら自宅からも参照できるメモ環境を会社でも作りたいなと思い直している。</p>
<p>個人的に理想としているのはこんな感じ。</p>
<ul>
<li>クラウド同期が取れる、可能ならDropboxがいい</li>
<li>全文検索ができる</li>
<li>（可能なら）vimキーバインドが使える</li>
<li>（可能なら）Markdownプレビューができる</li>
</ul>
<p>いろいろ検証はしてみたが、どれもしっくり来ていない。なんかないものか。</p>
<h3>Kobito</h3>
<ul>
<li>Markdownエディタとしては優秀。ハイライトも綺麗。</li>
<li>vimモードがあってそこそこ快適。若干表示がズレることがあるが、設定いじれば修正は可能かも。</li>
<li>クラウド同期はできない。あとファイル実体見れないのがなんとなく気持ち悪い。</li>
</ul>
<h3>Evernote</h3>
<ul>
<li>Markdownエディタとしては論外。</li>
<li>アカウントは持っているが、すでにプライベートメモがどっさり入ってるので会社で開きにくい。</li>
</ul>
<h3>GistBox</h3>
<ul>
<li>Markdownエディタではないし、フォーム入力なので編集は貧弱。</li>
<li>GitHub経由で同期取れる点は魅力。</li>
<li>Gistはスニペット置き場のイメージが強く、文章の保存はしっくりこない。</li>
</ul>
<h3>Wri.pe</h3>
<ul>
<li>今のところ最良と思われる。</li>
<li>フォーム入力型の編集にはなってしまうが、<a href="https://github.com/akahuku/wasavi">Wasavi</a>使うことでVimっぽくできる。</li>
<li>ログインすれば自宅からでもメモは見られるので一応同期可能。</li>
<li>Dropbox連携はあるが、あくまでバックアップをzipでストックさせるだけなので、家ではVimで編集します、とかはスムーズにできなくて微妙。</li>
</ul>
<h3>Cirrus Editor</h3>
<ul>
<li>Dropbox内のtxtファイルをブラウザで直接編集できるのは今のところこれぐらいしか見つからない。</li>
<li>新規ファイルの追加ができないので、メモ環境としては使えない。</li>
</ul>
<p>ひとまずWri.pe使ってますけどだいぶ辛さあります。今日日はやっぱりKobito使ってるエンジニアが多いんだろうか。あるいはメモなんていらない？ うーん。。。</p>
<p><strong>……と思ってたらWasaviがDropbox連携機能もってた！！！</strong></p>
<iframe class="bookmarklet hatena-embed" src="http://hatenablog.com/embed?url=http%3A%2F%2Fappsweets.net%2Fwasavi%2F" title="wasavi - appsweets akahuku labs." style="border:none;display:block;margin:0 0 1.7rem;overflow:hidden;height:155px;width:100%;max-width:100%;"><a href="http://appsweets.net/wasavi/" target="_blank">wasavi - appsweets akahuku labs.</a></iframe>
<ul>
<li>連携すると<code>:write</code>や<code>:edit</code>がWasavi上で使えるようになる。
<ul>
<li>つまりWri.peをWasaviで編集していて、Dropboxにツッコみたくなったら<code>:write hoge.txt</code>すればよい。</li>
<li>逆にDropboxのテキストをWri.peに持ってきたければ<code>:edit fuga.txt</code>とすればよい。</li>
</ul>
</li>
<li>さらに<code>http://qasavi.appsweets.net</code>につなぐと単独でWasaviをブラウザエディタとして使える。Dropboxのオンラインエディタになる。</li>
</ul>
<p>ヤバイだろうこれ。。。highlightはさすがに無理とか、Dropbox使えると言っても<code>ls</code>は使えないのでファイラとしては微妙とか、そういうのはもろもろあるとは言え、Dropboxのファイルを直接ブラウザ上でVimライクな編集できるってのは恐ろしく便利。単なるVimのエミュレートに留まらず、ブラウザとDropboxのシームレスな連携ができるという点が肝だと思う。Dropboxで書きためていたブログの下書きを、はてなブログの編集画面上で直接呼び出すこともできるわけだ。ちなみにGoogle DriveとOne Note連携もあるので、そちらがお好みであればそちらでも。</p>
<p>これまでぜんぜん見たこともないソフトだったけど、これだいぶいいものなのでは？？？</p>
<h2>その他アプリケーション</h2>
<ul>
<li><a href="http://www.forest.impress.co.jp/library/software/clover/">Clover</a> エクスプローラーのタブ化</li>
<li>chrome全盛になりつつある気はするが、Vimp使いたくてFirefox</li>
<li>VirtualBoxにVagrantはもはや定番</li>
<li>Outlookの予定表使いづらすぎて辛いんだけど、Exchangeと同期できるアプリでなんか良い代替ないッスか。。。</li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/development-environment-for-windows</link>
            <guid isPermaLink="false">development-environment-for-windows</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 03 Jul 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[すべての障害対応を、生まれる前に消し去りたい！ #障害対応きにならNight]]></title>
            <description><![CDATA[<p><a href="http://www.zusaar.com/event/6147005">エンジニア交流会〜他社の障害対応きにならNight!〜 on Zusaar</a></p>
<p>改めて見るとすげー名前のイベント……行ってきた。</p>
<p>障害対応は嫌いです。ていうか好きな人がいるならお目にかかってみたいもんですが、しかしシステムを動かす以上障害は避けられないし、それならばなるべく負担を軽減したいというのが人の、いやエンジニアの性。つわけでよりよいソリューションを探す目的で行ってきたイベントだったんですが、結局のところ <strong>より深い闇を知るだけの結果に終わった。</strong></p>
<p>世の中闇だらけですわ。闇しかないですわ。自分なんかぜんぜん甘いなっていうか闇とすら呼べないんじゃないかっていう。詳しくは書けませんけど世の中運用者って苦労してんなって認識新たにしました。まぁだからって闇を甘受していいわけじゃなくて、だからこそやることあるんだけどさ。</p>
<p>得た知見をザクっとまとめちゃいますけど、</p>
<ul>
<li>明文化と記録は何事も大事。顧客との契約にせよ、手順や構成にせよ、障害記録にせよ。</li>
<li>ただ記録するんじゃなくて探しやすいようにとか考えないと意味ない(Wikiに書き散らしても役には立たない)</li>
<li>日頃からの点検などによる障害の抑止も重要。障害訓練とか。</li>
<li>スーパーエンジニアだから治せるって状態は脱したいのでスキルの底上げは必要。</li>
<li>電話かかってくるのウザいけど必要。確実に対応しなきゃならない障害なら絶対電話。別にTwilioとかでいいので。</li>
</ul>
<p>障害対応って辛くないはずはないのだが、だったらより辛くない方法を探さねばなと思う。アラートの対象は極力絞ったり、自動復旧でイケる事象はスクリプト組んでおいたり。</p>
<p>あと自分はもともと金融系SEで、運用に用いてたのもJP1やTivoliみたいな商用製品が多かった故、会場で交聞いたnagiosやらcactiやらCloudWatchやらを学ばねばというところ。顧客とビジネスモデルが変わっただけで、見える技術領域もほんとに変わるものだと思う。</p>
<p>こういうopsやインフラに絞ったイベント、なかなかない気がするので良いですね。</p>
]]></description>
            <link>https://chroju.dev/blog/how-about-your-troubleshooting</link>
            <guid isPermaLink="false">how-about-your-troubleshooting</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Thu, 02 Jul 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[SIerからサービス系の会社に転職して1か月]]></title>
            <description><![CDATA[<p>SIerからサービス提供型の会社に転職して1か月ぐらい経ったので、感想とか今後のこととかまとめておく。立ち位置としてはインフラエンジニア、まぁ要は運用担当者になるのだが、BtoB、BtoCで動いている提供サービスすべてと、社内インフラまでひっくるめたありとあらゆるインフラの運用管理を受け持っている。なのでそれこそ雑用めいた仕事から構築にイッチョカミしてサーバー立てたりAWSいじったりみたいなところまで、見渡すべき範囲はアホほど広い感じ。</p>
<h2>日常のストレスは減った</h2>
<p>とはいえストレスは減った。だいーぶ減った。受託開発だと当然ながら顧客側のシステムポリシーだとか会社方針が第一にあり、それが要件になって、マネージャー同士での合意、契約に流れ、そこから上司の指示のもとで設計構築というように自分の動き方を規定するピラミッドがでっかくそびえるのだが、これがごっそりなくなった。インフラ関連で必要な設定作業や修正があれば誰かがRedmineにチケット上げるので、それを期日の早いものからパカパカと片付けていく感じ。もちろん粒度のデカすぎるチケットなんかは上位者が分割して割り振りをするわけだが、制約がんじがらめの中で仕事をこなしている状態からはだいぶ脱している。</p>
<p>とはいえ当然ながら責任とのトレードオフではあるわけで、チケット内の課題解決のためにスクリプト組んで実装するのか、ワークアラウンドでどうにかしちゃうのかはエンジニアの技量次第になったりするし（もちろん後者だと後から追及される可能性があるが）、そもそもスキル範囲外の話はチケット拾えなくて仕事できないとかご迷惑な場合も多々あり、なんとかせねばなという感じがある。</p>
<h2>綺麗な運用ってどこに落ちてるんだろう</h2>
<p>10年程度存続している企業なので、まぁ必要悪と言っていいのか、属人化してたりブラックボックス化してたり暗黙知化していたりなんて部分は様々見られ、アカンやろなと思うし、またそういう意識がチーム全体の根底にも流れてはいる。前職でもこの辺の課題はあったのだが、逆に綺麗で整った運用ってどんな会社がしているのか興味ある。というかそういう会社の話を聞いてみたいなと。</p>
<p>暗黙知化しているものについては手順化したりスクリプト化したりしていきたい。私は「すべての手作業を生まれる前に消し去りたい」と「人間は信頼性の面でコンピュータに劣る」をモットーとして掲げている人間なので、じゃかじゃかコンピュータ殿が勝手にやってくれる運用に切り替えていこうかなと思う。何年この会社にいるかなんて正直わからないけど、いなくなるまでにそれができれば本望かなと。</p>
<p>ただインフラエンジニアが運用エンジニアになっていく現状に対して疑問をもたなくもない。Infrastructure as Codeなんざの流れもあり、インフラ構築も含めたDevはすべてアプリ開発者が担えるようになりつつあり、一方でOpsはインフラエンジニアが担うというような流れにあるが、本当にOps以外にやることないんですかねえ？っていう。DevOpsはバズワードとして聞き流していた節があるので、昨今の潮流とかきちんと押さえて反映しようと思う。</p>
<h2>エンジニアの就労環境って</h2>
<p>旧来のIT企業と新進気鋭のところとで何が一番違うか？ってこれだと思うんだけど、弊社の場合もよくある事例ではあるがアーロンチェアが支給されていたり、開発運用に必要な物品はそれなりに気前よく買ってもらえたり、お菓子や飲み物が豊富に用意されていたり、オフィスがなんかシャレオツだったりみたいな感じである。旧来のSIerなんかでこういうの導入している会社はほとんどないのではないかと思うのだが、エンジニアを大事にしているか否かってことになるのだろうか。正直とても助かるし、転職の条件としては今後ちゃんと考えるようにしたい。</p>
<p>あと晴れて例の関東IT健保に入れたので、どっかで寿司食いには行きたいと思う。</p>
<h2>やろうと思えば仕事は多いけど思わないとない</h2>
<p>利益をあげる方法って売上増やすかコスト下げるかだと思うんだが、運用エンジニアの仕事って基本的に後者である。ただ当然ながらサービスとして稼いでいる前者の仕事がそもそも必要なので、後者、要するに効率化だとか運用改善の部分に上手いこと手が回らず、効率の悪い運用をいつまでも続けている、なんてことには陥りやすい。</p>
<p>前者、売上を上げるべき仕事というのは黙ってても降ってくるので、仕事はある。でもエンジニアとしてそれでいいんですか？というと、やっぱり良くないよねというか、エンジニアリングしてこそだよねと思うので、売上増やすためのタスクはさっさと終わらせて、改善や効率化にじゃんじゃん時間割きたい。そのために試行錯誤している時間ってそんなにはないので、手持ちの武器を増やす方向で進めていければと思う。取り急ぎシェルスクリプトとAWSかなぁと。</p>
]]></description>
            <link>https://chroju.dev/blog/one-month-from-job-changing</link>
            <guid isPermaLink="false">one-month-from-job-changing</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 27 Jun 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Ansibleの入門イベント聞いてきた話]]></title>
            <description><![CDATA[<p><a href="https://atnd.org/events/66419">これ</a>行ってきた。ざくっと感想を箇条書きで。</p>
<ul>
<li>ChefやPuppetに相当するインフラの設定管理ツールだと勝手に思い込んでいたが、対象範囲はそれらより広い。要はCapistranoがやるようなことまでまかなえる。</li>
<li>それどころかHomebrewの管理あたりも可。一時期brewfileとか流行ってたけど、冪等性とか考えるとAnsible管理の方がいいかも。
<ul>
<li>最近そんな記事がちょうど上がってた。→ <a href="http://dev.classmethod.jp/tool/osxc-ansible-configuration-for-mac/">【要するに】osxcでMacの環境の構成を記述管理する【MacでAnsible】 ｜ Developers.IO</a></li>
</ul>
</li>
<li>一番のポイントはエージェントレス、だと個人的にも思う。導入ハードルが低い。個人のVPSとかならChef-Zeroとかよりも気楽で良い。</li>
<li>yamlだからインフラ担当者でも読みやすいって点はそれほど惹かれないというか、Rubyぐらいインフラ屋でも昨今は読み書きできるべきではって気がする。
<ul>
<li>あとRubyの方がぶっちゃけ処理ベタ書きしちゃえるって点で安心感はある。Ansibleで細かいとこに手が届かないとき、どういうワークアラウンドがあるかはわかってないが。</li>
</ul>
</li>
<li>しかし、とはいえやっぱ楽そう。Vagrantと組み合わせて開発環境立てるみたいな小さなことからやってみて、イケると思ったら本番展開ってのもアリかもしれない。かも。</li>
<li>この手のツールが出たときに「こんなこともできる！すごい！」ってなりがちなんだけど、実は再発明された車輪で成り立ってる部分もあって、それshでできるよ？ってなることは結構ある（brewfileがわりとその気配あった）ので、その点に関してはきちんと見極めがしたい。</li>
<li>あとやっぱり構成管理ツールはインフラエンジニアから完全にdevを奪いにかかるツールではあるので、インフラ屋はスケーリングとかネットワークとか（そういえばネットワーク周りのas codeなかなか流行りませんね）障害対策とか、本気でops特化が求められるのかもなとか思った。</li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/hika-labo-ansible</link>
            <guid isPermaLink="false">hika-labo-ansible</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 24 Jun 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[ファッション無職になった]]></title>
            <description><![CDATA[<p>退職エントリーに対して「で、誰？」っていうレスが付くのがもはや定番化しているような気もするけど、ブログなんてだいたいはチラ裏なんだから「誰？」なんて退職エントリーに限らずなんだってそうやんけ、と思ったりはしてます。誰だかわかんない人の文章読むのがネットの醍醐味なんだから、あえて煽らなくてもいいじゃんねー？というネタにマジレス。</p>
<p>というわけで退職、自体は実際にはまだなのだが、すでに現職はフェードアウトしてファッション無職期間に入っていたりする。半月以上の休暇なんて大学以来だからちょっとワクワクしてるし、大学4年の春休みに「こんなに休めることはもうないんやで」とか言われたのは嘘だったんだなーとも思ってる。んで、インフラ系SEを辞めて、来月からSaaS事業者でインフラエンジニアをすることになる。転職にあたってそもそも何がきっかけになったのか、忘れないよう書き留めておく。</p>
<ul>
<li>自分は技術的な素養がまだ乏しいと感じているのに、会社側はマネジメントラインへ自分を進ませようとしており、方針の違いが大きくなってきていた。 => もっと技術畑でやっていきたい。</li>
<li>下請け、外注、アプリとインフラでの分割受注等により、システム全体像が見えないことが多く、システム設計や運用設計の上で歯がゆいことが多かった。 => 自社開発を重視したい。</li>
<li>怠惰に流れやすい。リスク回避の意味で「変わらない」ことが是とされることが多い。 => もっと革新的な方針の会社で働きたい。</li>
<li>趣味的に追っている技術動向のスピードと、自分が業務で携わる技術変化のスピードの乖離が激しすぎる。 => 世の動向をきちんとキャッチアップできるエンジニアでありたい。</li>
<li>というか率直に言ってインフラエンジニアとしての武器を増やしたい。</li>
</ul>
<p>こんなところか。一言で言えば「焦り」である。就職から4年経ってなお、自分がインフラエンジニアとして技術的に成長できてない、と思う焦り。それを社内でやりくりしてどうにかすることも多分できたと思うし、それを上司に掛け合わないわけではなかったのだが、異動のタイミングは半年に一度しかなかったし、それを4回近く却下されたりしてきたので、じゃあもう自分で動いてしまった方がいいかなと思うに至った。年齢的には27歳で、まだ自由が効くと言えるところでもあったし。</p>
<p>と、いうわけで、今後は今まで以上にインフラ寄りにお勉強を深めていきたい所存。先日のJAWS-UGへの参加なんかも是非とも続けていきたいところでござんす。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4840144265/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41aEGDjXwAL._SL160_.jpg" alt="34歳無職さん 1 (MFコミックス フラッパーシリーズ)" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4840144265/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">34歳無職さん 1 (MFコミックス フラッパーシリーズ)</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.05.16</div></div><div class="amazlet-detail">いけだ たかし <br />メディアファクトリー (2012-02-23)<br />売り上げランキング: 15,860<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4840144265/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
]]></description>
            <link>https://chroju.dev/blog/i-am-neet-now</link>
            <guid isPermaLink="false">i-am-neet-now</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 15 May 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[JAWS-UG初心者支部の立ち上げに行ってきた #jawsug_bgnr]]></title>
            <description><![CDATA[<p><a href="https://jawsug-beginner.doorkeeper.jp/events/22161">JAWS-UG初心者支部【第1回】2015年5月14日(木) - JAWS-UG初心者支部 | Doorkeeper</a></p>
<p>AWS初心者具合がどれぐらいかと言うと、先日のJAWS DAYS 2015のハンズオンセッションでアカウント作り、それっきり一度もログインしていないぐらいの初心者なんですが、今回JAWS-UGの初心者支部というのが出来ると聞いたので飛び込むにはちょうどいいと思い行ってきました。しかし会場の内田洋行さん、初めて行ったけど大変ナウいオフィスでびっくりした。横に長い会場だったけど、6面スクリーン同時投影でどの席でも見やすいとかハンパない。</p>
<h2>AWSは入口が山のようにある</h2>
<p>初心者と口で言うのは簡単ですが、それを脱する手段も実は山のようにあるのがAWSで。そもそもがマウスでポチポチやればサーバー立ち上がっちゃうっていうサービス自体の簡易性を反映してなのかなんなのか知りませんが、入口といえる部分は非常に多いです。今回の勉強会では「入口」の紹介に非常に時間を割いていたなという印象。</p>
<p>自分が特に印象深かったのは<a href="http://aws.amazon.com/jp/training/self-paced-labs/">セルフペースラボ</a>と<a href="http://aws.amazon.com/jp/webinar-flow/">Webiner</a>。前者はウェブ上で無料で（有料コースもあり）使える実践的なラボ空間で、自学自習でAWSの使い方が学べるとのこと。自分はVMwareを今専門としているのだが、VMwareでも同様の<a href="http://labs.hol.vmware.com/HOL/catalogs/">Hands on Labs</a>があったりして、使えるもん使わなきゃ損だなと。後者はオンライン・セミナーで、毎週開催されているそうです。火曜日18:00からが初心者向け、水曜日18:00からがBlack Belt Tech、すなわち「黒帯」ですので中級者向けのセミナー。</p>
<p>他にも技術書の読み方や推薦があったり、ちょっと上級者向けな気はしたけどRe:Inventの紹介があったり（まーこういうのは早いうちから知っておいて、アンテナ高めといた方が良いのだろう）。とにかく勉強しようと思ったらいくらでもAWSを知るための入口はあるし、しかもかなり敷居の低いところから始めることもできるので、やらないで指くわえてたらどんどん置いていかれてしまうだけだなと。</p>
<h2>人と会うこと</h2>
<p>勉強会界隈ではよく言われる話で、本番は懇親会ってのがあります。まぁこの集まり自体が「Users Group」であることからもわかる通り、エンジニア同士の会社の枠を超えたつながりってすごく重視されていて、今日のなかでも何度も話に出ました。というか「隣の人と話してみましょう」なワークセッションが設けられていたぐらいの。これはあれですね。勉強会自体の初心者が多いことも見越してのことだったんでしょうね。</p>
<p>自分はもうとにかくコミュ障というか人と話さず済むならそれが一番って感じの人間なんですけど、ここまで言われると話さないわけにもいかないんじゃないかなと思いつつあるし、てか勉強会参加の第一の目的が「コミュ障脱却」になってくるのではないかという話も。。</p>
<p>これまでの勉強会で他の参加者と話したことは皆無ではなくて、んでやっぱり社外のエンジニアだと技術との向き合い方だとか、会社環境における技術選択の方式だとかが全然違うことが多くて、そういうの聞いてるだけで確かに楽しいのは知ってるんですよね。んでユーザーグループとなるとそのつながりがずっと続いていくわけで、絶えず情報交換しながら自分の会社に持ち帰って試してみて、また勉強会に課題を持ってくるみたいなサイクルが出来てくるわけじゃないですか。会社内だとなかなか解決できないことを外に出すこともできるわけで、閉塞感を打破する矛先を持っておくことってすごい重要なんじゃないかって気がします。近所にもJAWSの支部あるっぽいんで、そっちにも顔出してみたい……ですね、なんとか。あー、初心者向けならコミュ障のための勉強会参加法も教えてほしいなぁ。</p>
<h2>初心者の中での隔絶</h2>
<p>セッションを聞きながらTwitterでハッシュタグ追っていたのですが、結構レベル高くないか？難しいよ？みたいな声もちょこちょこ聞こえていて、「初心者」とひとえに言ってもレベルの差があるのだと気付いた次第。</p>
<p>それを言ってしまうと多分自分は「なんちゃって初心者」です。オンプレミスのインフラエンジニアとしては数年の業務経験がありますし、VPS使ってるしAWSもアカウントは持ってるしで、完全な初心者かと言うとそうではない。一方で本当に「AWSってよく聞くけどなんなの？ 導入したらおいしいの？」ぐらいの人もいるのだし、敷居をどこまで下げていくかって案外むずかしい話なのかもしれないなと。初心者向けを謳っているのに「いやいや難しいでしょ」で人が離れてしまったら悲しいし、そこへのフォローってどうしたらいいのかなとか。</p>
<p>あと「わからないことを取りあえずスルーする力」ってのも必要な気がした。今日のセッションって結構具体的なAWSのサービス名も出たりして、自分も全然わからない言葉は少なくなかったんですけど、一つ一つの単語や一部の話はわからなくとも、全体として何を言っているのか掴めれば取りあえずOKってことも多いし、わからない部分にこだわりすぎず、ある程度スルーする力って必要だと思うのです。でもこれって日々「わからないこと」と向き合っているエンジニアならではの特性っていう部分もあると思うので、そうじゃない人も入ってくる可能性のあるこの初心者支部では課題になりそうとも思った。</p>
<p>やろうと思えばいくらでもやることあるし、やらないと置いて行かれるだけだってのが理解できたので、できることからガツガツやっていきたい所存。とはいえ「目的のない勉強」は行き詰まりやすいので、AWSで何ができるのか、自分は何をしたいのかをちょっと考えてみようかなと。とりあえず「紫本」買ってみるか。。。</p>
]]></description>
            <link>https://chroju.dev/blog/jaws-ug-for-beginners-at-first</link>
            <guid isPermaLink="false">jaws-ug-for-beginners-at-first</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Thu, 14 May 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Hash与えるとGoogleスプレッドシートに入力してくれるRubyスクリプト]]></title>
            <description><![CDATA[<script src="https://gist.github.com/chroju/7b9d422732f1a0ddd45e.js"></script>
<p>つくった。動きとしては、項目名と入力値からなるハッシュを引数で与えてやることで、該当スプレッドシートの2列目に符合するキーがある場合、その値を一番右側の列に入力してくれる。符合するキーがない場合は、メッセージを吐いた上で最下行に新しい項目として追加する。</p>
<p>用途としては非常に個人的なもので、各種オンラインバンクの残高をスクレイピングしてハッシュで返してくれるスクリプトをいくつか作ってあったので、その戻り値を使ってオートで家計簿作れたらいいなーという思いによるものです。ハッシュのキーをそのままスプレッドシート内の項目名として使っているので、シンボルではなく文字列をキーとして使ってしまっているのがあまりよろしくないのかなぁとは思うのだが、いつか改善するってーことで、とりあえず動くものを作ることを優先させた。んで、これって結構汎用的に使えそうなスクリプトかもなと思って公開した次第。</p>
<p>Googleスプレッドシートをいじるのには<code>google-drive-ruby</code>というGemを使ってます。Githubは<a href="https://github.com/gimite/google-drive-ruby">ここ</a>。<code>def initialize</code>内の処理は、このGemの初期設定によるものなので、Gemの方のReadme読んでもらえればよいかと。単純な話、GoogleのOAuth API使っているだけの話です。ただ、このコードだと叩くたびにブラウザからAPI使用許可を与えてやって、success codeをコピーしてコマンドラインで入力してやらなくちゃならないっていう手間があって、そこまで省く方法なにかありそうだけどまだ調べてない。あと気になっている点としては、このGemでセルの値を取ると、表示値しか取れないこと。式を入れているセルについては、式を取るか表示値を取るか選べるといいなぁと思ったんだけど、そこまではできないらしい。しかしまぁ、とにかくGoogleスプレッドシートという、APIで叩けるクラウドの表計算ソフトがあるというのは本当に便利なことですね、って感じ。</p>
<h2>参考</h2>
<ul>
<li><a href="http://qiita.com/inokappa/items/2566b21f4b1deac6f95b">RubyからGoogle SpreadSheet をいじるメモ - Qiita</a></li>
<li><a href="http://qiita.com/yumiyon/items/d7c370b3b8582431a3de">Google DriveのスプレッドシートにRubyでアクセスする方法 - Qiita</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/google-spread-sheet-update-via-ruby</link>
            <guid isPermaLink="false">google-spread-sheet-update-via-ruby</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 02 May 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[GTD環境 2015年春版（Workflowy最強説）]]></title>
            <description><![CDATA[<p>GTDという言葉もなんだか多義的に使われているような気がするが、自分の場合は「今あるタスクを『高度』の概念から見直して、きちんと前に進むことができているか確認すること」と、「やるべきことが全部可視化されていること」に重点を置いている。</p>
<p>前回GTD関連をきちんとまとめ直したのはどうも<a href="http://chroju.github.io/blog/2013/11/10/post/">この記事</a>のようなのだが、さすがに古くてここからだいぶ変わっている。とかく面倒であるということが中心にあって、使うツールは少なければ少ない方がよいし、完全に管理しようとするよりもある程度割り切ってしまった方が上手く回る。現時点で使っているのはほとんどGoogle Calendarと<a href="https://workflowy.com/">Workflowy</a>だけだ。特にWorkflowyにはだいぶ助けられている感がある。</p>
<h2>Workflowy</h2>
<p>オンラインのアウトライナーツールである。そんなのVimでいいんじゃねーかと思ったこともあったが、わりと使い勝手が良くて使い続けている。ポイントとしてはショートカットがかなり豊富で、TabやShift + Tabでインデント／アウトデントできるなんてのはもちろん、Ctrl + Enterで取り消し線引けたり、階層の折りたたみもできたりと、キーボードだけでほとんどの操作が完結できる点にある。あと貧相ではあるがiPadアプリとAndroidアプリがあるのでモバイル環境でも使えるし、@hogeとか#fugaって形式でタグを生成して絞込かけたりもできる。タグで絞り込んだ状態や一部階層だけを表示した状態にはそれぞれパーマリンクが与えられるから、アクセスも楽でよい。</p>
<p><a href="https://www.flickr.com/photos/chroju/17114714740" title="2015-04-29blog by chroju, on Flickr"><img src="https://farm8.staticflickr.com/7700/17114714740_7849a4f7cc.jpg" width="424" height="500" alt="2015-04-29blog"></a></p>
<p>自分がこれを何に使っているかと言えば、ほぼGTDの全部と言っていい。各高度の可視化、PJ（高度1000mにあたる）ごとの手順、細切れのタスク、などなど。GTDというのは単なるタスク管理の手法ではなく、高度のような文章化される内容まで管理しなくてはならなかったり、あるいは単純にタスクだけを目にするのではなくて、マイルールとか目標といったものも一度に管理したいなという思いもあったので、結果的にいわゆるタスク管理系のソフトを捨ててWorkflowyに辿り着いた。アウトライナーなのでフォーマットは自由だが、階層化できるので高度ごと、ジャンルごとなどでまとまった意味単位を作りやすいし、取り消し線機能を使えばタスク管理っぽいこともできる。フットワーク軽く使えるという点でこれはだいぶ重宝する。</p>
<p>あとWorkflowyでは1日の更新差分をメールで転送してくれる機能があって、これ使ってEvernoteに差分を貯めこんでいる。週次レビューでその週にやったことを見直すときに便利。</p>
<h2>Google Calendar</h2>
<p>いわずもがなのカレンダー。これ以外にクラウドのカレンダーツールって選択肢あんのかもわからないぐらいのデファクトスタンダード。ただWeb版の使い勝手はあまり良いとは思えていなくて、代わりに<a href="https://calendar.sunrise.am/">Sunrise Calendar</a>を使っている。予定を追加するとき、Google Calendarみたいに別画面へ遷移することなく、バルーン上ですべての項目を登録できるあたりがお気に入り。あと全体的に使われている色の彩度が低めで見やすい。</p>
<p><a href="https://www.flickr.com/photos/chroju/17094816017" title="2015-04-29blog2 by chroju, on Flickr"><img src="https://farm9.staticflickr.com/8703/17094816017_e1bb19b134.jpg" width="474" height="500" alt="2015-04-29blog2"></a></p>
<p>時間の決まったタスクだとか、繰り返しやることなんかはすべてGoogle Calendar行きである。あとWorkflowy上で記録しているタスクでも、今日やれそうだ、明日やれるかなと思ったらGoogle Calendarにツッコんでリマインダーかけている。スマホだと予定確認には<a href="https://play.google.com/store/apps/details?id=com.anydo.cal&#x26;hl=ja">Cal</a>を使っているので、リマインダーについてもピックアップしてくれて忘れにくい。ちなみにCalを使っている理由は、スマホでカレンダー見るときは先々の予定を考えるときより、その日の予定とタスクを確認するときの方が多かったから、CalのUIがしっくり来たってことです。というかスマホの小さい画面だと月間予定とか見るのはしんどい。</p>
<h2>回し方</h2>
<p>基本的にはこれらのツールを使って週単位でタスクを回している。1週間終えた金曜日の夜に週次レビュータイムを設けていて、さっき書いたWorkflowyの差分やらモレスキンやDropboxに溜め込んだメモを下に、KPTで週を振り返る。で、終わったタスクはWorkflowyから消して、予定見ながら空いている時間を確認しつつ、次週やることをNext Actionとしてピックアップする。長期間進んでいないプロジェクトなどがあれば要チェック。塩漬けのタスクがあれば「やる必要があるのか」再検討。週の行動目標をタスクとは別に何かしら定めてWorkflowyに記入。まぁ、そんな感じです。</p>
<p>問題点として、だいたい毎週進歩がないというか似たようなProblemが出てきちゃってるなぁというのが最近あるので、Tryにあたる内容はちゃんとタスクに落としこむことと、無理なくスモールスタートにできる範囲にしといた方がいいってことです。GTDは確かにやること、頭の中を可視化はしてくれるけど、結局それを進めていくのは自分だってことを忘れちゃいけないので。というか、そこがGTDで一番キモだし難しいところなんじゃないかなと思っている。</p>
]]></description>
            <link>https://chroju.dev/blog/gtd-2015-workflowy</link>
            <guid isPermaLink="false">gtd-2015-workflowy</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 28 Apr 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Ruby基礎学習(10) Mix-in]]></title>
            <description><![CDATA[<p>Mix-inの話と、それに似たもろもろ。他に詳しい記事があるので、これを読んでおけばいいような気はした。</p>
<h2>参考</h2>
<ul>
<li><a href="http://faultier.blog.jp/archives/1220074.html">requireとincludeとextendとmodule_function(1) : As Sloth As Possible</a></li>
<li><a href="http://faultier.blog.jp/archives/1220088.html">requireとincludeとextendとmodule_function(2) : As Sloth As Possible</a></li>
</ul>
<h2>require</h2>
<ul>
<li>Kernelモジュールのモジュール関数。</li>
<li>引数に与えたRubyライブラリを1回ロード、というか実行する。</li>
<li>使う場面としてはgemだとか自作のライブラリ（クラス）を読み込むときに指定する。</li>
<li>指定した引数は$LOAD_PATHに探しに行き、カレントディレクトリは含まれないため、パスの指定には少し注意が必要。</li>
<li>同じファイルを複数回requireしようとしても、1回しか読み込まない。</li>
</ul>
<h2>load</h2>
<ul>
<li>Kernelモジュールのモジュール関数。</li>
<li>requireと同様に外部ライブラリを実行するが、同じファイルを何度でも読み込める。</li>
<li>requireは拡張子の自動補完を行うが、loadは行わない。</li>
</ul>
<h2>include</h2>
<ul>
<li>Moduleクラスのインスタンスメソッド。</li>
<li>Moduleを引数に取り、メソッドや定数といった対象Moduleの性質を取り込む。</li>
<li>ArrayやHashがEnumerableの性質を持っているのはincludeしていることによるもの。</li>
<li>継承とは異なるが、メソッドの探索対象としてはスーパークラスよりincludeされたModuleの方が先になる。</li>
<li>同じモジュールを複数回読み込もうとしても、2回目以降は無視される。</li>
<li>Rubyは多重継承を認めていないが、その代わりの機能を果たすという位置付けらしい。</li>
</ul>
<h2>extend</h2>
<ul>
<li>Objectクラスのインスタンスメソッド。</li>
<li>引数に取ったModuleのメソッドを特異メソッドとして取り込める。</li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/ruby-study-mix-in</link>
            <guid isPermaLink="false">ruby-study-mix-in</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Thu, 23 Apr 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Ruby基礎復習(9) Dirクラス]]></title>
            <description><![CDATA[<p>『パーフェクトRuby』p.208より。</p>
<p>Dirクラスは基本としてカレントディレクトリ情報を持っていて、それを元としてディレクトリ操作ができる。従って多くの操作を特異メソッドで行うことができる。</p>
<pre><code class="language-ruby">Dir.pwd # => "/Users/chroju"
Dir.chdir("/tmp")
Dir.pwd # => "/tmp"
Dir.home # => "/Users/chroju"
</code></pre>
<p>ディレクトリに含まれるファイルは<code>Dir.entries</code>で配列として返り、<code>Dir.foreach</code>でEnumerableとして返る。また<code>Dir.glob</code>により、パターンにマッチするファイルパスを配列で返すこともできる。<code>Dir.glob</code>は<code>Dir[]</code>と同義である。引数のディレクトリが存在するか確認する場合は<code>Dir.exists?</code>を用いる。</p>
<pre><code class="language-ruby">Dir.entries('.') # => [".", "..", "bar", "foo", "baz"]
Dir.foreach('.') {|d|
  p d
} # => ".", "..", "bar", "foo", "baz"
Dir.glob('ba*') # => ["bar", "baz"]
Dir['ba*'] # => ["bar", "baz"]
Dir.exists?("hoo") # => false
</code></pre>
<p>ディレクトリの削除、生成等も特異メソッドにて。</p>
<pre><code class="language-ruby">Dir.mkdir 'foo', 0755 # パーミッション0755でfooディレクトリを生成
Dir.rmdir 'foo' # fooディレクトリを削除するが、対象ディレクトリは空である必要がある
Dir.delete 'foo' # Dir.rmdirと同義
Dir.unlink 'foo' # Dir.rmdirと同義
</code></pre>
<p><code>Dir.open</code>すると、Dirオブジェクトを取得することができ、インスタンスメソッドによる操作が可能になる。Dirオブジェクトは読み込み位置を持っていて、ディレクトリ内のファイル名を1つずつ読み込ませることができる。</p>
<pre><code class="language-ruby">dir = Dir.open('.')
dir.path # => "/temp" （現在のファイルパス）
dir.pos # => 0 （現在の読み込み位置）
dir.pos = 1 # 読み込み位置を移動
dir.read # => ".."
dir.rewind # 読み込み位置を先頭に戻す
dir.read # => "."
dir.each {|f| p f} # => ".", "..", "bar", "baz", "foo"
</code></pre>
]]></description>
            <link>https://chroju.dev/blog/study-ruby-dir</link>
            <guid isPermaLink="false">study-ruby-dir</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 13 Apr 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Ruby基礎復習(8) Fileクラス]]></title>
            <description><![CDATA[<p>『パーフェクトRuby』p.196より。わりと苦手な分野。</p>
<p>まずはファイルをひらく。<code>#open</code>して変数に格納してもいいし、ブロックを引き渡して処理させることもできる。後者の場合は処理が終わると自動でクローズしてくれるので、こっちの方が楽っぽい。<code>#read</code>はファイルの内容全体を読み込む一方、<code>#gets</code>を使うと1行ずつ読み込むことができる。あるいは<code>#each_line</code>や<code>#each_char</code>といったメソッドも。</p>
<pre><code class="language-ruby">file = File.open('example.txt')
p file.read # example.txtの内容を表示
file.close

File.open 'example.txt' do |file|
  p file.read
end

File.read('example.txt')

File.open 'example.txt' do |file|
  while line = file.gets
    p line
  end
end

File.open 'example.txt' do |file|
  f.each_line do |line|
    p line
  end
end
</code></pre>
<p>書き込むときは<code>#open</code>の第二引数にファイルを開くモードを指定する。デフォルトは<code>'r'</code>、すなわち読み込みモードで、他は以下の通り。基本は<code>r</code>が読み込み、<code>w</code>が書き込み、<code>a</code>が追記で、<code>+</code>を付けると読み書き両用モードになる。また<code>b</code>を後置するとバイナリモードで開かれる。</p>
<p>| r  | 読み込みモード         |
| r+ | 読み書き両用モード（読み書き位置は先頭から）       |
| w  | 上書き書き込みモード   |
| w+ | 新規作成して読み書き両用モード |
| a  | 追記書き込みモード       |
| a+ | 追記読み書き両用モード（読み込み位置は先頭から、書き込みは追記形式）  |</p>
<pre><code class="language-ruby">File.open 'example.txt', 'w' do |f|
  f.write 'hoge'
end
</code></pre>
<p>もっと単純に<code>#write</code>メソッドだけでも書き込み可能。</p>
<pre><code class="language-ruby">File.write 'example.txt', 'fuga'
</code></pre>
<p>先のファイルを開くモードの話の中で「読み込み位置は先頭から」という表現があったが、IOオブジェクトではファイル内の今どこを読み／書きしているかというアクセス位置が存在する。<code>#gets</code>では1行ずつ読み込みを行ったように、読み／書きを行うことでアクセス位置は進んでいく。先頭まで戻りたい場合は<code>#rewind</code>を使う。また<code>#seek</code>メソッドは第二引数に定数で指定した基準位置より、第一引数の整数分アクセス位置を移動させることができる。<code>#pos</code>は絶対的にアクセス位置を指定して動かせる。</p>
<pre><code class="language-ruby">File.open 'example.txt' do |f|
  f.puts
  f.rewind # 先頭位置まで戻る

  f.seek 10 # 先頭から10進む
  f.seek -10, IO::SEEK_END # 末尾（SEEK_END）から10戻った位置に移動

  f.pos = 25 # 先頭から25バイト目に移動
  f.pos # => 25
end
</code></pre>
<p>文字のエンコーディングについては、「外部」と「内部」という概念を持つ。外部はファイルのエンコーディング情報であり、内部はRuby上で処理する際のエンコーディング情報。例えばEUC-JPのファイルをutf-8で変換して取り扱い、書き込みはEUC-JPで、といったことができる。エンコーディングの設定には<code>#set_encoding</code>メソッドを使う。引数を1つだけ取る場合は外部エンコーディングを設定し、2つ取る場合は第一引数が外部、第二引数が内部を設定する。あるいは<code>File#open</code>するときに、読み書きモードと一緒にエンコーディングも指定することができる。</p>
<pre><code class="language-ruby">File.open 'example.txt' do |f|
  f.set_encoding('utf-8') # 外部エンコーディングをutf-8に設定

  f.set_encoding('utf-8', 'EUC-JP') # 外部エンコーディングをutf-8、内部エンコーディングをEUC-JPに設定
  f.set_encoding('utf-8:EUC-JP') # 外部エンコーディングをutf-8、内部エンコーディングをEUC-JPに設定
end

File.open 'example.txt', 'r:utf-8:EUC-JP' do |f|
  p f.external_encoding # => "utf-8"
  p f.internal_encoding # => "EUC-JP"
end
</code></pre>
<p>ファイルのロックには<code>#flock</code>メソッドを利用する。ロックのモードは<a href="http://docs.ruby-lang.org/ja/1.9.3/method/File/i/flock.html">ここに記載の定数</a>を使って指定するのだが、主に<code>File::LOCK_EX</code>が排他ロックであることを覚えとけばいいような気も。</p>
<pre><code class="language-ruby">File.open 'example.txt', 'w' do |f|
  f.flock File::LOCK_EX
end
</code></pre>
<p>その他、ファイル情報取得系のメソッドをつらつらと。これらはファイルオブジェクトから取得するだけではなく、<code>File.atime(filename)</code>の形で<code>File</code>クラスのクラスメソッドでも呼び出すことができる。</p>
<pre><code class="language-ruby">File.open 'example.txt' do |f|
  f.atime # 最終アクセス日時
  f.ctime # 最終変更日時
  f.mtime # 最終更新日時

  f.size # ファイルサイズ

  f.ftype # ファイルタイプ 以下真偽判定メソッドも有り
  f.file?
  f.directory?
  f.symlink?

  f.writable? # => false
  f.readable? # => true
  f.executable? # => false

  f.owned? # => false (自身がファイル所有者か？)
  f.gid # ファイル所有者のGID
  f.uid # ファイル所有者のUID
end
</code></pre>
<p>ファイル操作系。</p>
<pre><code class="language-ruby"># ファイル名変更、ファイル移動
File.rename 'hoge', 'fuga'
File.rename 'hoge', 'dir/hoge'

# ファイル削除
File.unlink 'hoge'

# シンボリックリンク作成
File.symlink 'target', 'link'

# ハードリンク作成
File.link 'target', 'link'

# ファイルモード変更
File.chmod 0600, 'filename'

# 所有者、グループの変更
File.chown 100, 100, 'filename'
</code></pre>
<p>ファイルパスに関するもろもろ。</p>
<pre><code class="language-ruby"># ファイルのあるディレクトリパスの取得
File.dirname("etc/sample.txt") # => "/etc"

# 第一引数に与えたファイルパスに対する、ファイル名の取得。第二引数でsuffix指定。
File.basename("etc/sample.txt") # => "sample.txt"
File.basename("etc/sample.txt", ".txt") # => "sample"

# 拡張子の取得
File.extname("etc/sample.txt") # => ".txt"

# ファイルパスの連結（引数は可変長）
File.join("/usr/local", "bin/ruby") # => "/usr/local/bin/ruby"

# ファイルパスからdirnameとbasenameを取得し配列生成
File.split("/usr/local/bin/ruby") # => ["/usr/local/bin", "ruby"]

# 絶対パスの展開
File.expand_path("~") # => "/home/chroju"
File.expand_path("filename", "~") # => "/home/chroju/filename"

# absolute_pathでは~を展開しない
File.absolute_path("~") # => "/home/chroju/~"
</code></pre>
<p>Dirクラスも触れたいのだが、長くなるので一旦ここまで。</p>
]]></description>
            <link>https://chroju.dev/blog/study-ruby-file-i-o</link>
            <guid isPermaLink="false">study-ruby-file-i-o</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Thu, 09 Apr 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Ruby基礎復習(7) Timeクラス]]></title>
            <description><![CDATA[<p>『パーフェクトRuby』p.190より。</p>
<p><code>Time#now</code>か<code>Time#new</code>で現在時刻が取得可能。</p>
<pre><code class="language-ruby">now = Time.now # => 2015-03-16 23:25:32 +0900
new = Time.new # => 2015-03-16 23:25:32 +0900

now.zone # => "JST"
now.getutc # => 2015-03-16 14:25:32 UTC
now.utc
now.zone # => "UTC"
</code></pre>
<p>現在時刻以外のTimeオブジェクトを生成するには<code>Time#at</code>でUNIX秒を引数に指定するか、<code>Time#utc</code>か<code>Time#local</code>で直接時刻を指定する。</p>
<pre><code class="language-ruby">Time.at(0) # => 1970-01-01 09:00:00 +0900
Time.utc(2015, 1, 1, 2, 30, 40, 100) # => 2015-01-01 02:30:40 UTC (最後の100はマイクロ秒)
Time.local(2015, 1, 1, 2, 30, 40, 100) # => 2015-01-01 02:30:40 +0900
</code></pre>
<p><code>#to_i</code>、<code>#to_f</code>、<code>#to_r</code>の戻り値はUNIX秒。<code>#to_s</code>で文字列表現が返る。<code>#to_a</code>は秒、分、時、日、月、年、曜日、その年の通算日数、夏時間の真偽判定、タイムゾーンの配列を返す。なお、この配列フォーマットを展開して<code>Time#utc</code>や<code>Time#local</code>の引数として与えることもできる。</p>
<pre><code class="language-ruby">now.to_i # => 1426515932
now.to_f # => 1426515932.978824
now.to_r # => (178314491622353/125000)
now.to_s # => "2015-03-16 23:25:32 +0900"
now.to_a # => [32, 25, 23, 16, 3, 2015, 1, 75, false, "JST"]
</code></pre>
<p><code>#to_s</code>の戻り値は上記フォーマットの固定だが、任意のフォーマットで文字列表現を得たい場合は<code>#strftime</code>を使う。使えるフォーマット文字列は<a href="http://docs.ruby-lang.org/ja/1.9.3/class/Time.html">公式ドキュメント</a>参照で。</p>
<pre><code class="language-ruby">now.strftime("今日は%Y年%m月%d日、今は%H時%M分を%S秒過ぎたところです。") # => "今日は2015年3月16日、今は23時25分を32秒過ぎたところです。"
</code></pre>
<p>逆に文字列表現からTimeオブジェクトを得たい場合は<code>#strptime</code>が使える。</p>
<h2>参照</h2>
<ul>
<li><a href="http://qiita.com/riocampos/items/de59263ac4e991a98f49">Ruby - 日本語表記の日時をTimeオブジェクトに変換（Time.strptimeメソッド） - Qiita</a></li>
</ul>
<p>その他もろもろの出力。</p>
<pre><code class="language-ruby">now.year # => 2015
now.month # => 3
now.day # => 16
now.hour # => 23
now.min # => 25
now.sec # => 32
now.nsec # => 978824000 (ナノ秒)
now.wday # => 1 (曜日は日曜を0としてカウント)
now.yday # => 75 (年初からの日数)
</code></pre>
<p>曜日やサマータイム(DST)については疑問符のメソッドで真偽判定できる。</p>
<pre><code class="language-ruby">now.dst? # => false
now.sunday? # => false
now.monday? # => true
</code></pre>
<p>Timeオブジェクト同士の比較についてはナノ秒まで判定されるので、そのあたりに注意とのこと。以下のようなことがあり得る。</p>
<pre><code class="language-ruby">now = Time.now # => 2015-03-16 23:25:32 +0900
new = Time.new # => 2015-03-16 23:25:32 +0900

now == new # => false
</code></pre>
<p>整数を与えることによる加算減算は秒として取り扱われる。Timeオブジェクト同士の減算も可能。その場合は差分の秒数が浮動小数点数で返る。</p>
<pre><code class="language-ruby">now = Time.now # => 2015-03-16 23:25:32 +0900

now + 1 # => 2015-03-16 23:25:33 +0900
now - 1 # => 2015-03-16 23:25:31 +0900
</code></pre>
<p>なお時間や日時を扱うクラスには他に<code>Date</code>や<code>DateTime</code>もあるが、組み込みのライブラリはこの<code>Time</code>だけ。どれを使えばええんや？ってのは、探してみたら大変詳しいQiitaを見つけたんでそっちに譲ります。</p>
<h2>参考</h2>
<ul>
<li><a href="http://qiita.com/jnchito/items/cae89ee43c30f5d6fa2c">RubyとRailsにおけるTime, Date, DateTime, TimeWithZoneの違い - Qiita</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/study-ruby-time</link>
            <guid isPermaLink="false">study-ruby-time</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 05 Apr 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Ruby基礎復習(6) Hash]]></title>
            <description><![CDATA[<p>『パーフェクトRuby』p.179より。</p>
<p>まず基本的なとこで。</p>
<pre><code class="language-ruby">hash = {hoge: 1, fuga: 2}

hash.each do |key, val|
  p "#{key}: #{val}"
end # => "hoge: 1", "fuga: 2"

hash.each_key do |key|
  p key
end # => "hoge", "fuga"

hash.each_value do |val|
  p val
end # => "1", "2"

hash[:hoge] = 3
p hash # => {hoge: 3, fuga: 2}
hash[:piyo] = 4
p hash # => {hoge: 3, fuga: 2, piyo: 4}

hash.delete(:piyo)
hash # => {hoge: 3, fuga: 2}

hash.empty? # => false
hash.length # => 2
</code></pre>
<p>ハッシュの生成は<code>Hash[]</code>により偶数個の引数から行うこともできる。</p>
<pre><code class="language-ruby">ary = ["hoge", 1, "fuga", 2]
Hash[*ary] # => {hoge: 1, fuga: 2}

ary = [["hoge", 1], ["fuga", 2]]
Hash[ary] # => {hoge: 1, fuga: 2}
</code></pre>
<p>Arrayクラスと同様の<code>#select</code>、<code>#reject</code>、<code>#keep_if</code>、<code>#delete_if</code>操作が可能。</p>
<pre><code class="language-ruby">hash = {hoge: 1, fuga: 2, piyo: 3}

hash.select {|key, val| val.even? } # => {fuga: 2}
p hash # => {hoge: 1, fuga: 2, piyo: 3}
hash.select! {|key, val| val.even? } # => {fuga: 2}
p hash # => {fuga: 2}

hash = {hoge: 1, fuga: 2, piyo: 3}

hash.reject {|key, val| val.even? } # => {hoge: 1, piyo: 3}
p hash # => {hoge: 1, fuga: 2, piyo: 3}
hash.reject! {|key, val| val.even? } # => {hoge: 1, piyo: 3}
p hash # => {hoge: 1, piyo: 3}

hash.select! {|key, val| val.even? } # => nil
hash.keep_if {|key, val| val.even? } # => {hoge: 1, piyo: 3}
hash.reject! {|key, val| val.even? } # => nil
hash.delete_if {|key, val| val.even? } # => {hoge: 1, piyo: 3}
</code></pre>
<p>Hashの統合は<code>Hash#merge</code>を用いる。キーが重複する場合は、引数で渡されたハッシュの値で上書きされる。ブロックを引き渡している場合は、キー重複時の処理をブロックの中で定義できる。破壊的操作である<code>Hash#merge!</code>は<code>Hash#update</code>とも書くことが出来る。</p>
<pre><code class="language-ruby">a = {hoge: 1, fuga: 2}
b = {hoge: 3, piyo: 4}
a.merge(b) # => {hoge: 3, fuga: 2, piyo: 4}
p a # => {hoge: 1, fuga: 2}

a.merge!(b) {|key, a_val, b_val|
  a_val + b_val
} # => {hoge: 4, fuga: 2, piyo: 4}
p a # => {hoge: 4, fuga: 2, piyo: 4}
</code></pre>
<p>キーと値の取得に関して。特に特定キーの存在確認については、<code>Hash#has_key?</code>を用いる。通常の<code>Hash[]</code>による呼び出しだと、値が存在しない場合でもnilが返ってきてしまい、値がnilなのか、それとも存在していないのか区別がつかないため。あるいは<code>Hash#fetch</code>を用いれば、値が存在しない場合の返り値を指定できる。</p>
<pre><code class="language-ruby">hash = {hoge: 1, fuga: 2, piyo: 3, hogehoge: nil}

hash.keys # => [:hoge, :fuga, :piyo]
hash.key(2) # => :fuga

hash.values # => [1, 2, 3]
hash.values_at(:fuga) # => [2]
hash.values_at(:fuga, :piyo) # => [2, 3]

hash[:hogehoge] # => nil
hash[:foo] # => nil
hash.has_key?(:foo) # => false
# 以下すべてhas_key?と同義
hash.member?(:foo)
hash.include?(:foo)
hash.key?(:foo)

hash.fetch(:foo) # => nil
hash.fetch(:foo, "error") # => "error"
hash.fetch(:foo){|key| "#{key} not exists"} # => "foo not exists"

hash.has_value?(3) # => true
hash.value?(3) # => true
</code></pre>
<p>Hashにはデフォルト値の概念があり、<code>Hash#new</code>の引数に与えた値が、存在しないキーを参照したときの返り値となる（デフォルトはnil）。ここで指定した値はすべて同一オブジェクトであり、破壊的操作をする場合などは注意が必要。また<code>Hash#default=</code>や<code>Hash#default_proc=</code>により、既存のHashオブジェクトに対してもデフォルト値の変更が可能。</p>
<pre><code class="language-ruby">hash = Hash.new("null")
hash[:foo] # => "null"

hash.default = "undefined"
hash[:foo] # => "undefined"
default = hash.default
default.reverse!
hash[:foo] # => "denifednu"

hash.default_proc = ->(hash, key) {"Key: #{key} not exists"}
hash[:foo] # => "Key: foo not exists"
</code></pre>
<p>ハッシュ変換系のメソッド。</p>
<pre><code class="language-ruby">hash = {hoge: 1, fuga: 2}

hash.invert # => {1: hoge, 2: fuga}
hash.to_a # => [[:hoge, 1], [:fuga, 2]]
hash.sort # => [[:fuga, 2], [:hoge, 1]]
</code></pre>
]]></description>
            <link>https://chroju.dev/blog/study-ruby-hash</link>
            <guid isPermaLink="false">study-ruby-hash</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 04 Apr 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[the world as code]]></title>
            <description><![CDATA[<p>世界を構成するのはテクストである、という考え方が好きだ。より正確な言い方をするならば記号論やミーム的な考え方になるのだと思うが、記述されたもの、意味を成して認識されたものだけが実在足りうる、というような世界観をなんとなく抱いている。『ニルヤの島』では個人の生が物語へと還元され、データとして外部記憶装置へ保存されるようになった。『from the nothing, with love』では、ジェームズが自らを「生起しつつあるテクスト」であると述懐する。あるいはヘプタポッドの言語は、未来をも決定論的に「記述」する。</p>
<p>特にことインターネットの隆盛により、世界はテクストの、ミームの満ちるものへと変容しつつあるように思う。インターネット上に存在する「個人」とは、すなわちミームに他ならない。インターネットへのアクセスをしていても、能動的にテクストを紡がない個人は存在しないに等しい。この世界では個人は、あるいはあらゆる事象はデータへと還元され、そして半永久的にミームの海を彷徨っていく。</p>
<p>上述したように、最近頓に多い「言葉」に関するSFのなかで、最も好きなのは『屍者の帝国』なのだけど、ここでは人間の魂自体が「言葉」によるものと解されており、そして屍者は「言葉」によってフランケンシュタインと化す。言葉は物質化する。書物がそうであるように。歴史上の人物がそうであるように。これが自らもまた「物質化した言葉」であるはずのヴァン・ヘルシングの言葉であるというのは皮肉でもあるのだと思うが、生きとし生けるものが言葉によりもたらされるというハッキリとした記述と、それに基づいて構成された世界観は実に興味深い。</p>
<p>Infrastructure as Code、物理的な世界の技術であったはずのITインフラが、近年言語により記述され、管理、構築されるフェーズへと転換したように。Internet of Things、家電や家具といった非電子的であったはずの「モノ」たちが、APIを提供して「言語」による働きかけを許すようになったように。我々エンジニアの一つの使命は、万物の情報化であると思う。言語が支配する世界にすべてを置き換え、言語を介した制御を可能とすること。それがエンジニアとしてやるべきことなのだと。</p>
<p>私はなぜ書くのか？という問いに対する答えはあまりに簡単で、それは生きるに等しい行為だからだ。語らぬ者は存在しないのならば、語る以外に選択肢はない。世界と関わりたいのならば、言語によって働きかけていくしかない。紡いだ言葉がミームの海を流れていき、対岸でやがて物語として物質化する日を夢見る。言葉が世界を構成し、言葉が万物を紡ぎ上げて、やがて物語と化していく。</p>
<p>the world as code.</p>
<p>世界は言葉で成り立っている。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4150114587/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51191C0153L._SL160_.jpg" alt="あなたの人生の物語 (ハヤカワ文庫SF)" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4150114587/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">あなたの人生の物語 (ハヤカワ文庫SF)</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.04.03</div></div><div class="amazlet-detail">テッド・チャン <br />早川書房 <br />売り上げランキング: 10,379<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4150114587/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
]]></description>
            <link>https://chroju.dev/blog/the-world-as-code</link>
            <guid isPermaLink="false">the-world-as-code</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 03 Apr 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[JAWS DAYS 2015でAWS童貞捨ててきた]]></title>
            <description><![CDATA[<p><a href="https://www.flickr.com/photos/chroju/16701892109" title="#jawsdays 初心者ハンズオンなう by chroju, on Flickr"><img src="https://farm9.staticflickr.com/8687/16701892109_b35dd45f3a_n.jpg" width="320" height="320" alt="#jawsdays 初心者ハンズオンなう"></a></p>
<p><a href="http://jawsdays2015.jaws-ug.jp/">JAWS DAYS</a>、前々からやってるのは知ってたんですけど、自分はAWS経験ないし行ってもわかんねーかなと思ってなんとなく行かずにいたんですが、今回タイムテーブル覗いてみたら初心者向けハンズオンもあったので意を決して行ってきました。</p>
<p>ハンズオンでAWSアカウント作り、とりあえずEC2のインスタンスを1つばちこんと立てて、もう1こ簡単なREST API使ったサービスをばちこんと立てたので、無事にAWS童貞捨てることができました。クリック1つでサーバーが立つってのは知ってはいたけど、実際やってみるとほんと楽だなと。ていうかこれがあるならインフラエンジニアって何のためにいんの？ってやっぱり思うのですよね。もちろん大規模に組むならどこにどのサービス使ってスケーリングの設定はどうでみたいのがいるし、サーバーとストレージとLB立てるってだけがエンジニアではないと思うけど、サーバー1つ立てんのにいちいち申請上げて手順書き出して何人日もかけてやってる自分と比べると、デプロイのスピードも容易性も、おまけに確実性も段違いなわけで。わかってる、わかってるつもりだったけど、こりゃもう無理だなというか、クラウドファーストってよりAWSファーストが前提にあって、オンプレミスはなにか制限がある場合の最終手段にしかならんよなということを改めて実感してしまった気がします。</p>
<p>セッションは結果としてわりとミーハーに聞いてしまって、ソニックガーデン倉貫さんの話だとかハンズラボ長谷川社長の話だとか、さくらインターネット田中社長がモデレーターをつとめるパネディスとかに参加してました。特に倉貫さんの「納品のない受託開発」の話、これまできちんと聞いたことなかったのですんごい興味を惹かれました。「受託開発」と言ってますけど、実質的には顧客との関係は受託開発よりも強固なもので。要するにビジネスモデルはあるけどエンジニアがいないようなスタートアップに対し、技術顧問を務めるような形で開発と運用を請け負うのですね。それはシステムを作って収めるというよりは、顧客の課題解決を一緒になってシステム開発によって実現していくこと。エンジニアの働き方の概念自体が変化する話。これをソニックガーデン社外の人間がすぐ真似できんのかと言ったらそうではないかもしれませんけど、現状の特に死に体になってる受託開発界隈に対して一石を投じるには十分過ぎる話だと思いました。</p>
<iframe src="//www.slideshare.net/slideshow/embed_code/46130528" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/kuranuki/ss-46130528" title="「納品のない受託開発」の先にある「エンジニアの働きかたの未来」" target="_blank">「納品のない受託開発」の先にある「エンジニアの働きかたの未来」</a> </strong> from <strong><a href="//www.slideshare.net/kuranuki" target="_blank">Yoshihito Kuranuki</a></strong> </div>
<p>あとハンズラボの話に関してはこのツイートの内容に尽きる気がします。正直、羨ましいというか、今でこそ先駆的な一例に過ぎないけど、たぶんこういう例は徐々に増えていく、その一端なのだろうなと思っている。</p>
<blockquote class="twitter-tweet" lang="ja"><p>ハンズやあきんどスシローのすごいところは、それまでtech companyっぽくない印象だった業態が、じつは <a href="https://twitter.com/hashtag/jawsdays?src=hash">#jawsdays</a> で先進的な事例として講演できるようなことをやってのけたところだと思う。 クラウドだからできた。</p>&mdash; Haruka Iwao (@Yuryu) <a href="https://twitter.com/Yuryu/status/579523731719995392">2015, 3月 22</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>AWSのポイントはやっぱり、やろうと思えばすぐなんでもやれるって点だと思うんですよね。サービスやシステムを構築するにあたり、インフラをデリバリーするスピードがAWSによって格段に上がった。今まで何人日、何人月という工数をかけて、それでもヒューマンエラーで障害起こしてたようなインフラが意味を成さなくなった。じゃあその時代にインフラエンジニアは何をしなければならないのか？ってのは、ほんとちゃんと考えなきゃ死ぬな―これ。</p>
]]></description>
            <link>https://chroju.dev/blog/jaws-days-2015</link>
            <guid isPermaLink="false">jaws-days-2015</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 21 Mar 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Ruby基礎復習(5) 配列(Array)]]></title>
            <description><![CDATA[<p>『パーフェクトRuby』p.171より。</p>
<p>まずは配列の生成をいくつか。<code>#new(a,b)</code>で生成したとき、各要素は同じオブジェクトとなるので注意。またブロックで受け取ると、インデックスを引数としてブロック内の処理を実行した結果が値となる。</p>
<pre><code class="language-ruby">a1 = Array.new(3,1) # => [1, 1, 1]
a2 = Array.new(3, "hoge") # => ["hoge", "hoge", "hoge"]
a3 = ["hoge", "fuga", "piyo"] # => ["hoge", "fuga", "piyo"]
a4 = Array.new(3) {|i| i * 5} # => [0, 5, 10]

a2[0] &#x3C;&#x3C; "fuga"
p a2 # => ["hogefuga", "hogefuga", "hogefuga"]
</code></pre>
<p>基本的な操作系メソッド。演算子メソッドは直感的でほんといいなーと思う。なお、<code>#&#x3C;&#x3C;</code>は<code>#concat</code>と同義。<code>#==</code>と<code>#eql?</code>も同義。</p>
<pre><code class="language-ruby">array = ["hoge", "fuga", "piyo"]

array.length # => 3
array.size # => 3
array.empty? # => false
array.include?("fuga") # => true

p array * 3 # => ["hoge", "fuga", "piyo", "hoge", "fuga", "piyo", "hoge", "fuga", "piyo"]
p array + [1, 2] # => ["hoge", "fuga", "piyo", 1, 2]
p array - ["hoge", "piyo"] # => ["fuga"]
p array &#x26; ["piyo"] # => ["piyo"]
array &#x3C;&#x3C; "hogehoge" # => ["hoge", "fuga", "piyo", "hogehoge"]
array2 = ["hoge", "fuga", "piyo"]
array3 = ["hoge", "fuga", "piyo", "hogehoge"]
array == array2 # => false
array == array3 # => true
</code></pre>
<p>要素の取り出し。<code>#[a, b]</code>が添字aから長さbの配列を取り出すのに対し、<code>#values_at(a, b)</code>が添字a, bの要素を取り出して配列を作る、という点が異なるのが注意かも。</p>
<p>また範囲外の添字を指定したときの振る舞いだが、<code>#[]</code>がnilを返すのに対し、第一引数のみの<code>#fetch</code>はIndexErrorを返す。<code>#fetch</code>に第二引数を指定すると、範囲外を呼び出したときに第二引数を返すようになる。</p>
<p><code>#sample</code>はランダム抽出。</p>
<pre><code class="language-ruby">array = (1..5).to_a

array[1] # => 2
array[-1] # => 5
array[1, 3] # => [2, 3, 4]
array[2..4] # => [3, 4, 5]

array.values_at(3) # => 4
array.values_at(0, 3, 4) # => [1, 4, 5]

array.fetch(5) # => IndexError
array[5] # => nil
array.fetch(5, "error") # => "error"

array.first # => 1
array.last # => 5
array.last(2) # => [4, 5]

array.sample # => 3
</code></pre>
<p>要素の追加削除。添字を使って普通に要素の入れ替えはできるのだが、面白いのはレンジにない添字を指定してもOutOfBounds扱いにはならず、足りない箇所はnilを埋めて補完してくれること。<code>#insert</code>は第一引数をインデックスとする要素の直前に、第二引数以降の要素を挿入する。あと<code>#fill</code>は全要素を同じオブジェクトで埋め込む。</p>
<pre><code class="language-ruby">array = (1..5).to_a

array[1] = 0 # => [1, 0, 3, 4, 5]
array[8] = 10 # => [1, 0, 3, 4, 5, nil, nil, nil, 10]

array.push(3) # => [1, 0, 3, 4, 5, nil, nil, nil, 10, 3]
array.pop # => 3
p array # => [1, 0, 3, 4, 5, nil, nil, nil, 10]

array.shift # => [0, 3, 4, 5, nil, nil, nil, 10]
array.unshift(1) # => [1, 0, 3, 4, 5, nil, nil, nil, 10]

array.insert(2, "a", "b") # => [1, 0, "a", "b", 3, 4, 5, nil, nil, nil, 10]

array.fill(0) # => [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
array.clear # => []
p array # => []
</code></pre>
<p>要素の選択周り。ブロック内の処理でtrueとなった要素について、<code>#select</code>では抽出、<code>#reject</code>では削除を行う。いずれも破壊的／非破壊的の別があり。<code>#keep_if</code>は<code>#select!</code>と同様の動作をするが、削除する要素がなかった場合に<code>#select!</code>がnilを返す一方で、<code>#keep_if</code>がレシーバをそのまま返すという違いがある。<code>#delete_if</code>についても同様。ブロック内での評価ではなく、単純に特定の値と等しい要素を削除したい場合は<code>#delete</code>が使える。これは破壊的。<code>#delete_at</code>は添字による指定で削除する。</p>
<pre><code class="language-ruby">array = (1..5).to_a
array.select {|i| i.even? } # => [2, 4]
p array # => [1, 2, 3, 4, 5]
array.select! {|i| i.even? } # => [2, 4]
p array # => [2, 4]

array = (1..5).to_a
array.reject {|i| i.even? } # => [1, 3, 5]
p array # => [1, 2, 3, 4, 5]
array.reject! {|i| i.even? } # => [1, 3, 5]
p array # => [1, 3, 5]

array = [2, 4, 6]
array.select! {|i| i.even? } # => nil
array.keep_if {|i| i.even? } # => [2, 4, 6]
array.reject! {|i| i.odd? } # => nil
array.delete_if {|i| i.odd? } # => [2, 4, 6]

array.delete 4 # => [2, 6]
array.delete_at 1 # => [2]
</code></pre>
<p>同様に要素の切り出しでは<code>#slice</code>というメソッドもあるが、引数の与え方で動作が変わってくる。Integerの引数1つを与えると、そのインデックスにある要素を返す。範囲外の場合はnilが返る。Integerの引数2つでは、第一引数のインデックスより、第二引数の個数分要素を切り出して返す。Rangeを引数とすると、その範囲のインデックスにあたる要素を返す。</p>
<p>またいずれの場合でも<code>!</code>による破壊的メソッドがあるが、ここでは戻り値となる要素が配列より削除される。</p>
<pre><code class="language-ruby">a = [2, 4, 6, 9]
a.slice(1) # => 4
a.slice(1, 4) # => [4, 6, 9]
a.slice(1..2) # => [4, 6]

a.slice(2) # => 6
p a # => [2, 4, 9]
a.slice(0..1) # => [2, 4]
p a # => [9]
</code></pre>
<p>整形。<code>#compact</code>はnilを要素から除外する。<code>#uniq</code>は重複した要素を除外。<code>#reverse</code>は要素の順序を逆にする。<code>#flatten</code>は多次元配列を1次元に変換する。いずれも<code>!</code>を付けることで破壊的になる。また<code>#sort!</code>や<code>#map!</code>といった破壊的要素を使うことで、実行結果により自身を更新できる。</p>
<pre><code class="language-ruby">a = [5, 3, nil, 3, nil, 9, 1, [4, 3]]
a.compact! # => [5, 3, 3, 9, 1, [4, 3]]
a.uniq! # => [5, 3, 9, 1, [4, 3]]
a.reverse! # => [[4, 3], 1, 9, 3, 5]
a.flatten! # => [4, 3, 1, 9, 3, 5]
a.sort! # => [1, 3, 3, 4, 5, 7, 9]
a.map! {|i| i * 2 } # => [2, 6, 6, 8, 10, 14, 18]
</code></pre>
<p>複製。<code>#dup</code>は内容のみを複製する（浅いコピー）のに対し、<code>#clone</code>はfrozen等の情報も複製する。</p>
<pre><code class="language-ruby">a = [1, 2, 3].freeze
a[0] = 5 # => RuntimeError

b = a.dup
b[0] = 5 # => [5, 2, 3]

c = a.clone
c[0] = 5 # => RuntimeError
</code></pre>
<p>若干変わったものを最後にいくつか。<code>#transpose</code>は多次元配列を行列とみなして、行と列の入れ替えを行う。破壊的メソッドはない。<code>#bsearch</code>はソートされている配列に対して使用し、二分探索で最初に見つかった要素を返す。<code>#join</code>は各要素を連結した値を返す。引数にセパレータを渡すことも可。<code>#shuffle</code>は配列をランダムにシャッフルする。</p>
<pre><code class="language-ruby">a = [[1, 2], [3, 4]]
a.transpose # => [[1, 3], [2, 4]]

a = [0, 3, 5, 7, 9]
a.bsearch {|i| i > 2 } # => 3

a.join # => "03579"
a.join("-") # => "0-3-5-7-9"

a.shuffle!
p a # => [5, 9, 0, 3, 7]
</code></pre>
]]></description>
            <link>https://chroju.dev/blog/study-ruby-array</link>
            <guid isPermaLink="false">study-ruby-array</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 17 Mar 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Ruby基礎復習(4) EnumerableとComparable]]></title>
            <description><![CDATA[<p>『パーフェクトRuby』p.164より。</p>
<p>一部組み込みクラスは、EnumerableやComparableというモジュールがincludeされている。前者は聞き慣れない英単語だが、"can be counted"の意味らしく、HashやArrayといった一定の集合を表すクラスにincludeされていて、繰り返し処理や要素抽出に関するメソッドを実装する。Comparableはその名の通り比較演算、具体的には<code>#&#x3C;=></code>の実装であり、NumericやStringにincludeされているらしい。</p>
<p>特に実装されるメソッド数が多いので、Enumerableについてじっくり見てみたい。</p>
<h2>Enumerable</h2>
<p>まず繰り返し系。これだけでもかなり。。<code>#each_cons</code>のconsって何の意味ですかね。他はだいたい字義からイメージできる動作をしてくれる。あと<code>#each_with_object</code>がいまいち飲み込めてない。</p>
<pre><code class="language-ruby">(1..4).each_cons 2 do |a,b|
  p [a,b]
end # => [1,2] [2,3] [3,4]

(1..4).each_slice 2 do |a,b|
  p [a,b]
end # => [1,2] [3,4]

%(hoge fuga piyo).each_with_index do |value, index|
  p "#{index}: #{value}"
end # => 0: hoge 1: fuga 2: piyo

(1..4).each_with_object([]) {|i, result| result &#x3C;&#x3C; i*2} # => [2,4,6,8]

(1..4).reverse_each do |i|
  p i
end # => 4,3,2,1

(1..4).cycle {|i| p i} # => 1,2,3,4,1,2... 以下、無限ループ
</code></pre>
<p>各要素の評価には<code>#map</code>と<code>#collect</code>。いずれも同じ動作。</p>
<pre><code class="language-ruby">(1..4).map {|i| i * 3} # => [3, 6, 9, 12]
(1..4).collect {|i| i * 3} # => [3, 6, 9, 12]
</code></pre>
<p>判定系。<code>#member?</code>と<code>include?</code>は同義。</p>
<pre><code class="language-ruby">[1,2,3].all? {|i| i > 1} # => false
[1,2,3].any? {|i| i > 1} # => true
[1,2,3].none? {|i| i > 3} # => true
[1,2,3].one? {|i| i > 1} # => false

%w(hoge fuga piyo).member? "fuga" # => true
%w(hoge fuga piyo).include? "fuga" # => true
</code></pre>
<p>抽出系。覚えやすいことにgrepがある。<code>#detect</code>は条件に当てはまる最初の要素だけ、<code>#select</code>はすべてを抽出する。<code>#find_all</code>は<code>#select</code>と同義。<code>#reject</code>は<code>#select</code>といわば「逆」の動きをする。<code>#take</code>と<code>#drop</code>は要素数を指定して先頭から要素抽出orスキップする。あとは語義通りのメソッドがいくつか。</p>
<pre><code class="language-ruby">%w(hoge fuga piyo).grep(/o/i) # => "hoge", "piyo"
[1,2,"hoge"].grep(String) # => "hoge"

[1,2,3,4].detect {|i| i.even?} # => 2
[1,2,3,4].select {|i| i.even?} # => 2, 4
[1,2,3,4].find_all {|i| i.even?} # => 2, 4
[1,2,3,4].reject {|i| i.even?} # => 1, 3
[1,2,3,4].find_index {|i| i.even?} # => 1

(1..10).take 3 # => [1,2,3]
(1..10).drop 3 # => [4,5,6,7,8,9,10]

(1..10).take_while {|i| i &#x3C; 3} # => [1,2]
(1..10).drop_while {|i| i &#x3C; 3} # => [3,4,5,6,7,8,9,10]

(1..10).max # => 10
%(aaa bbbb ccccc).max_by {|s| s.length} # => "ccccc"
(1..10).min # => 1
%(aaa bbbb ccccc).min_by {|s| s.length} # => "aaa"
(1..10).minmax # => [1,10]
%(aaa bbbb ccccc).minmax_by {|s| s.length} # => ["aaa", "ccccc"]

(1..10).first # => 1
(1..10).count # => 10
(1..10).count(2) # => 1
</code></pre>
<p><code>#inject</code>を使うと全要素を総計するような処理ができる。これを「畳み込み演算」と呼ぶらしい。引数2つを必要とするブロックを受け取り、第一引数が直前のループでの演算結果を持ち、第二引数がその回のループでの要素を取る。あるいはブロックを取らず、<code>#inject</code>の引数にシンボルでメソッド名を渡すことで、全要素に対してそのメソッドを適用した結果を得られる。</p>
<pre><code class="language-ruby">(1..5).inject {|result, i| result + i} # => 15
(1..5).inject(10) {|result, i| result + i} # => 25
(1..5).inject(:+) # => 15
(1..5).inject(:*) # => 120
</code></pre>
<p>グルーピング。<code>#group_by</code>はブロックで評価した戻り値をキーとしたハッシュに要素をグルーピングしてくれる。<code>#partition</code>はブロックで評価した真偽値を元に配列でグルーピング。後者の方が使い勝手は良さそうではある。</p>
<pre><code class="language-ruby">(1..6).group_by {|i| i % 3 } # => {0=>[3,6], 1=>[1,4], 2=>[2,5]}
(1..6).partition {|i| i.even?} # => [[1,3,5], [2,4,6]]
</code></pre>
<p>一番意味がわからない<code>#zip</code>。selfと引数の配列で、同じ添字にあたる要素を使って新しい配列を生成する。どう使うんだろうこれ。。</p>
<pre><code class="language-ruby">(1..3).zip([4,5,6], [7,8,9]) # => [1,4,7], [2,5,8], [3,6,9]
</code></pre>
<h2>Comparableとソート</h2>
<p>個人的に苦手なのがこの宇宙船演算子とソート周り。まず大前提として、宇宙船演算子はレシーバと引数を比較し、レシーバが大きければ1、小さければ-1、同値であれば0を返す。</p>
<pre><code class="language-ruby">1 &#x3C;=> 2 # => -1
1 &#x3C;=> 0 # => 1
1 &#x3C;=> 1 # => 0
</code></pre>
<p>Comparableモジュールをincludeしたクラスで<code>#&#x3C;=></code>を定義すると、各種演算子による比較のルールを定めることができる。</p>
<pre><code class="language-ruby">class Person
  include Comparable
  attr_accessor :age

  def initialize(age)
    self.age = age
  end

  def &#x3C;=>(other)
    age &#x3C;=> other.age
  end
end

taro = Person.new(21)
hanako = Person.new(32)

taro > hanako # => true
taro == hanako # => false
</code></pre>
<p>で、Enumerableの<code>#sort</code>は要素を宇宙船演算子で比較して結果が正になるよう並び替えていく。要は昇順がデフォルト。ブロックに引き渡すこともでき、ここで任意の比較方法を定義してソートすることもできる。<code>#sort_by</code>を使えば宇宙船演算子を使わず、指定のメソッドを使って昇順に並び替えてくれる。メソッド呼び出し回数が<code>#sort_by</code>だと1回で済むので、実行速度の面で差が出る可能性がある。</p>
<pre><code class="language-ruby">takeshi = Person.new(25)
people = [hanako, taro, takeshi]
people.sort # => [taro, takeshi, hanako]
people.sort {|a,b| b &#x3C;=> a} # => [hanako, takeshi, taro]
people.sort_by {|person| person.age} # => [taro, takeshi, hanako]
</code></pre>
<hr>
<p>なお、意図的に飛ばしてしまったのだが、あと触れてないEnumerableのメソッドとして<code>#chunk</code>周りがある。ちょっと飲み込みきれてないのでまた次回。</p>
<h2>参考</h2>
<p><a href="http://jutememo.blogspot.jp/2008/03/ruby-2-enumerable.html">Ruby のイテレータ (2) – Enumerable と Comparable モジュール | すぐに忘れる脳みそのためのメモ</a></p>
]]></description>
            <link>https://chroju.dev/blog/study-ruby-enumerable-comparable</link>
            <guid isPermaLink="false">study-ruby-enumerable-comparable</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 16 Mar 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Ruby基礎復習(3) Numericクラス]]></title>
            <description><![CDATA[<p>パーフェクトRuby p.144より。</p>
<p>判定系メソッド、<code>#nonzero</code>が<code>#zero</code>の真逆の動きではなくてちょっと混乱しそう。あと<code>#integer?</code>はあるけど<code>#float?</code>はないとか。</p>
<pre><code class="language-ruby">0.zero? # => true
3.zero? # => false
0.nonzero? # => nil
1.nonzero? # => 1

1.integer? # => true
1.real? # => true
</code></pre>
<p>演算子系の話は割愛するが、宇宙船演算子だけ注意しとく。右辺（引数）の方が大きければ負。左辺（レシーバ）が大きければ正。<code>#sort</code>ではブロック内の戻り値が負の場合は2要素をそのまま、正の場合は逆順にして返してくる。宇宙船演算子を利用して昇順or降順に並べ替えることができる。</p>
<pre><code class="language-ruby">1 &#x3C;=> 2 # => -1
2 &#x3C;=> 1 # => 1
1 &#x3C;=> 1 # => 0

%w(aaaa aa aaa).sort { |a,b|
  a.length &#x3C;=> b.length
} # => ["aa", "aaa", "aaaa"]
</code></pre>
<p>丸め。<code>#round</code>が四捨五入。<code>#ceil</code>で切り上げ。<code>#floor</code>で切り捨て。馴染みのない英単語で覚えにくい。</p>
<pre><code class="language-ruby">1.4.round # => 1
1.4.ceil # => 2
1.4.floor # => 1
</code></pre>
<p><code>#step</code>で、第一引数に与えられた上限数値に達するまで、レシーバに第二引数の数値を足し合わせていく繰り返し処理がつくれる。第二引数のデフォルトは1。整数であれば<code>#upto</code>と<code>#downto</code>で1ずつ加算、減算させていくことも可能。</p>
<pre><code class="language-ruby">2.step 4 do |i|
  puts i
end # "2","3","4"

2.step 3, 0.3 do |num|
  puts num
end # "2.0","2.3","2.6","2.9"

2.upto 5 do |i|
  puts i
end # 2,3,4,5

4.downto 2 do |i|
  puts i
end # 4,3,2
</code></pre>
<h2>整数</h2>
<p>Integerクラスは絶対値の大きさによりFixnumサブクラスとBignumサブクラスに振り分けられる。メモリ領域との関係で境界が定められるみたいだが、自動判定されるのであまり気にしなくても良い気がする。整数ならではのメソッドは以下のあたり。oddとevenは「オッドアイ」の意味を考えると連想できることに気付いた。</p>
<pre><code class="language-ruby">1.odd? # => true
1.even? # => false

1.next # => 2
2.succ # => 3
3.pred # => 2

56.chr # => "8" 文字コードで対応する文字列を返す

"123".to_i # => 123
</code></pre>
<h2>浮動小数点数</h2>
<p>Floatクラス。あまり意識せずに使っても勝手にFloatクラス扱いしてくれたりするので楽。</p>
<pre><code class="language-ruby">num = 2.0 / 2
num.class # => Float
</code></pre>
<h2>有理数無理数</h2>
<p>Rationalが有理数クラスなわけだが、プログラミングにおいて無理数有理数の別が必要になる場面が想定できない数学オンチなのでよくわからん。Ruby Silverにも出なかった気がするし割愛でいっかな。。。なお複素数は文字通りComplexクラス。</p>
]]></description>
            <link>https://chroju.dev/blog/study-ruby-numeric</link>
            <guid isPermaLink="false">study-ruby-numeric</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 15 Mar 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Ruby基礎復習(2) Stringクラス]]></title>
            <description><![CDATA[<p>パーフェクトRuby p.148から学習。文字列ことStringクラス。</p>
<p>まずは基本操作系。</p>
<pre><code class="language-ruby">s = "hoge"
s.empty? # => false
s.length # => 4
s.size # => 4
s.bitesize # => 8
s.include?("og") => true
</code></pre>
<p>演算子での操作。</p>
<pre><code class="language-ruby">'hoge' + 'fuga' # => 'hogefuga'
'hoge' * 3 => 'hogehogehoge'
</code></pre>
<p>破壊的な文字列の追加。</p>
<pre><code class="language-ruby">s = "hoge"
s &#x3C;&#x3C; "fuga" # => "hogefuga"
s.concat("piyo") # => "hogefugapiyo"
</code></pre>
<p>切り出し。</p>
<pre><code class="language-ruby">s = "hogefuga"
s.slice(3) # => "e"
s.slice(2,5) # => "gefu"
s.slice(-4,2) # => "fu"
s.slice(2..5) # => "gefu"
</code></pre>
<p><code>#slice</code>を使わず、以下記法でも同等。</p>
<pre><code class="language-ruby">s = "hogefuga"
s[3] # => "e"
s[2,5] # => "gefu"
s[-4,2] # => "fu"
s[2..5] # => "gefu"
s[//]
</code></pre>
<p>文字列の整形に関するメソッドいろいろ。特に<code>#chop</code>と<code>#chomp</code>とか紛らわしいとよく言われる。英単語の意味するところとしてchop＝刻むってことで1文字削除されるのはわかるが、そこにmが足されると改行コードの削除になるのはなぜなんだろう。。。あと<code>#squeeze</code>なんかは使う場面がいまいち想像できない。</p>
<p>なお、ここにあるメソッドはすべて非破壊的。末尾に<code>!</code>を付けることで破壊的操作になる。</p>
<pre><code class="language-ruby">s = " aaa "
s.strip # => "aaa"
s.rstrip # => " aaa"
s.lstrip # => "aaa "

s = "aaa\n\n"
s.chomp # => "aaa\n"
s = "abcd"
s.chop # => "abc"

s = "aaaabbbbcccc"
s.squeeze # => "abc"
s.squeeze('ab') # => "abccc"

"ABC".downcase # => "abc"
"def".upcase # => "DEF"
"Abc".swapcase # => "aBC"
"tITle".capitalize # => "Title"

"abc".reverse # => "cba"
</code></pre>
<p>置換。第一引数で検索を行い、ヒットした箇所を第二引数で置換するか、あるいはブロックに引き渡して操作、という建て付けのよう。<code>#sub</code>だと最初に一致したもののみ、<code>#gsub</code>だとヒットしたすべての箇所が置換される。これも破壊的、非破壊的の2種類あり。</p>
<pre><code class="language-ruby">"aaaa".sub("a","b") # => "baaa"
"24-1-365".gsub(/[0-9]+/) {|str| str.to_i.succ} # => 25-2-366
</code></pre>
<p>配列への変換。<code>#split</code>で第一引数に指定した文字をセパレータとした分割が可能。第二引数には分割最大数が指定できる。また1文字ずつ操作したい場合は<code>#each_char</code>が使える。ブロックへの引き渡しも可能。似たところで<code>#each_byte</code>もある。</p>
<pre><code class="language-ruby">str = "Alice, Bob, Charlie"

str.split(",") # => ["Alice", "Bob", "Charlie"]
"Alice".each_char.to_a # => ["A","l","i","c","e"]
</code></pre>
]]></description>
            <link>https://chroju.dev/blog/study-ruby-string</link>
            <guid isPermaLink="false">study-ruby-string</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 14 Mar 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Ruby基礎復習(1) 基礎文法]]></title>
            <description><![CDATA[<p>去年末から今年のはじめにかけてRuby Silver/Goldの再受験無料キャンペーンってのやってて、おーこりゃちょうどいいわーと思って取りあえず受けたら見事に落ちたんですけど、その後再受験申し込み期間あるの忘れてて棒に振るとかよくわからんことやりました。そのままなんとなーくやる気なくなってたけど、さすがにSilverクラスの知識はきちんと押さえるべきだろってことで、しばらく手元の『パーフェクトRuby』使って自分用チートシートっぽくまとめてみます。超基礎なので退屈な記事が続く予定。</p>
<p>今回は文法面で自分がつまずいたポイントまとめる。</p>
<h2>変数のスコープ</h2>
<p>ローカル変数、グローバル変数、インスタンス変数、グローバル変数がまず基本にある。それぞれ文字通りではあり、ローカル変数は最も局所的なスコープ、グローバルはどこからでも参照可能（あまり使わない？）、インスタンス変数は個々のインスタンスに属する変数、クラス変数はクラス間で共有される変数。</p>
<pre><code class="language-ruby">def display_local
  puts hoge
end

def display_global
  puts $hoge
end

$hoge = "Hello, world!"

display_local # => NameError: undefined local variable or method `hoge' for main:Object
display_global # => "Hello, world!"
</code></pre>
<pre><code class="language-ruby">class Hoge
  @@class_var = "Hello, world from class!"
  
  def display_class_var
    puts @@class_var
  end

  attr_accessor :ins_var
end

i = Hoge.new
j = Hoge.new

i.display_class_var # => "Hello, world from class!"
j.display_class_var # => "Hello, world from class!"
i.ins_var = 1
j.ins_var = 2
i.ins_var # => 1
</code></pre>
<p>しかし改めてattr_accessorというのは便利ですね。</p>
<p>問題はローカル変数とブロック、メソッドとの関係で、わりと理解できてなかった。やりがちだけど、メソッドの中からメソッド外のローカル変数は参照できない。一方でブロックの中からブロック外のローカル変数は**参照できる。**一方でブロック内のみで宣言されている変数は、ブロックローカル変数扱いになり外から参照できない。</p>
<pre><code class="language-ruby">hoge = "hoge"

def hello_hoge
  puts hoge
end

hello_hoge # => NameError: undefined local variable or method `hoge' for main:Object
</code></pre>
<pre><code class="language-ruby">i = 1

3.times do |j|
  i = i + j
  block_local = 'in block'
end

puts i # => 4
puts block_local # => NameError
</code></pre>
<h2>Rangeクラス</h2>
<p>Ruby Silver受けるまで、恥ずかしながら1..10みたいのがクラスだということを知りませんでした。Rangeクラスってのがあるのね。。</p>
<pre><code class="language-ruby">range1 = 1..4
range2 = 1...4
range1.class # => Range

range1.each do |i|
  puts i
end # => 1,2,3,4

range1.include?(4) # => true
range2.include?(4) # => false
</code></pre>
<h2>三項演算子</h2>
<p>苦手。ついでに後置if/unlessもよく使うので頭に置いとく。</p>
<pre><code class="language-ruby">0.zero? ? '0です' : '0じゃないです' # => '0です'
puts '0です' if 0.zero? # => '0です'
</code></pre>
<h2>rescue</h2>
<p>rescue節を複数書いた場合、最初に該当したrescue節で捕捉され、その後のrescue節は捨象される。</p>
<pre><code class="language-ruby">begin
  raise 'StandardError'
rescue LoadError => e
  puts 'これはloaderrorです'
rescue StandardError => e
  puts 'これはstandarderrorです'
rescue Exception => e
  puts 'これはなにかエラーです'
end # => 'これはstandarderrorです'
</code></pre>
<h2>今後のtodo</h2>
<ul>
<li>Hashの扱い（というかEnumerable）</li>
<li>Time/Date関連の扱い</li>
<li>Fileの扱い</li>
<li>組み込みクラスの言語仕様再確認（特に破壊的非破壊的のあたり）</li>
</ul>
<p>まーぶっっちゃけ全部だな。。。。</p>
]]></description>
            <link>https://chroju.dev/blog/study-ruby-grammer</link>
            <guid isPermaLink="false">study-ruby-grammer</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 07 Mar 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『エンジニアのための時間管理術』読了]]></title>
            <description><![CDATA[<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873113075/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51jWtxU0sAL._SL160_.jpg" alt="エンジニアのための時間管理術" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873113075/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">エンジニアのための時間管理術</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.03.07</div></div><div class="amazlet-detail">Thomas A. Limoncelli <br />オライリー・ジャパン <br />売り上げランキング: 12,858<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873113075/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>先日のデブサミでオライリーの書籍販売があったわけですけど、5000円以上購入でトートバッグプレゼントというのに釣られて買った1冊です。本当は2冊で5000円届くはずだったんだけど、そのときはディスカウントがあったばかりに5000円に届かず3冊という、得したんだか買いすぎちゃったんだかよくわからない感じでした。まぁ、前々から気になって立ち読みしまくってた1冊なので、買うきっかけくれたことには感謝。</p>
<p>内容はGTDとか散々やってきてる自分にとってそれほど新鮮味のあるものではありませんでした。煩わしいタイムマネジメントに関することは全部頭の中から放り出して、その日のタスク、スケジュール、目標なんかはひとつの場所にまとめておこうねっていうのが全体の趣旨です。あとはエンジニアならではなのかな？と思えることとして、手順の文書化の話だったり、スクリプトによる雑事の自動化周りの話がちょっぴり載ってたりはします。</p>
<p>本書内ではタイムマネジメントに使う媒体（デジタルでもアナログでもなんでもいいけど、とりあえず何かしら「1か所」にまとめる）のことをオーガナイザーと読んでいるのですが、そこに書くことは大きく3つあり、1つは365日のタスク。GTDをはじめ、よく聞かれるタスク管理法だと「やるべきこと」は全部1つのリストにドバっと書き出していることが多いわけだけど、本書ではそういう「永遠に終わらないリスト」は「破滅のリスト」と呼んで回避するよう告げている。タスクリストを1日分でクローズドにすることで、その日にやったことを明示的にリスト内で「潰せる」ようにし、達成感を味わえるようにした方がよいと。2つ目はカレンダー。日時の決まった予定だとか、繰り返しのルーチンはカレンダーに書いちゃった方が早い。3つ目が長期的な目標。月単位や年単位の長いスパンで何を実現したいのか？を書き出しておく。その手順は細かく分割した上で、365日のタスクリストや、カレンダー上に載ることになる。そして目標リストは定期的に見直して、更新していく。</p>
<p>自分が今やってることとこれ、わりとよく似ていて。自分の場合、スケジュールがGoogle Calendarで、タスクリストはAny.do。以前todo.txtを使っているという記事を書いたこともあるのだけど、最近乗り換えてしまった。なぜかと言うとスマホアプリのCalを使うと、1日のGCal上の予定とAny.doのタスクがまとめて見られてすんごい楽だから。</p>
<div id="appreach-box" style="text-align:left;">
    <img id="appreach-image" src="http://a512.phobos.apple.com/us/r30/Purple6/v4/78/bb/1d/78bb1d61-0262-76c4-2edb-f421111365d4/mzl.fxvayqgf.png" alt="Cal – Calendar for iCloud, Google &amp;amp; Exchange" style="float:left; margin:10px; width:25%; max-width:120px; border-radius:10%;" pagespeed_url_hash="248610482">
    <div class="appreach-info" style="margin: 10px;">
      <div id="appreach-appname">Cal – Calendar for iCloud, Google &amp; Exchange</div>
      <div id="appreach-developer" style="font-size:80%; display:inline-block; _display:inline;">
        開発元:<a id="appreach-developerurl" href="https://itunes.apple.com/jp/artist/halo-inc./id499497834?uo=4" target="_blank" rel="nofollow">Any.DO</a>
      </div>
      <div id="appreach-price" style="font-size:80%; display:inline-block; _display:inline;">無料</div>
      <div class="appreach-powered" style="font-size:80%; display:inline-block; _display:inline;">
        posted with <a href="http://appreach.t-tu.com/" title="アプリーチ" target="_blank" rel="nofollow">アプリーチ</a>
      </div>
      <br>
      <div class="appreach-links" style="float:left;">
        <div id="appreach-itunes-link" style="display: inline-block; _display: inline;">
          <a id="appreach-itunes" href="https://itunes.apple.com/jp/app/cal-calendar-for-icloud-google/id648287824?mt=8&amp;uo=4&amp;at=11lHd9" target="_blank" rel="nofollow">
           <img src="http://appreach.t-tu.com/img/itune_en.png.pagespeed.ce.8asOsm0ta-.png" style="height:40px;" pagespeed_url_hash="1074815294">
          </a>
        </div>
        <div id="appreach-gplay-link" style="display:inline-block; _display:inline;">
          <a id="appreach-gplay" href="https://play.google.com/store/apps/details?id=com.anydo.cal" target="_blank" rel="nofollow">
           <img src="http://appreach.t-tu.com/img/gplay_en.png.pagespeed.ce.1AAXzseXga.png" style="height:40px;" pagespeed_url_hash="45329112">
           </a>
        </div>
      </div>
    </div>
    <div class="appreach-footer" style="margin-bottom:10px; clear: left;"></div>
  </div>
<p>GTDが唄うような「すべてのタスクが網羅されたリスト」ってのはあまりに雑多で自分も嫌いで、なのでAny.doの中身は週に一度見直して、その週にやることを「TODAY」として扱うようにしている。日次リストが本当は理想なのだろうけど、残業も少なくない中で日次でできるタスクなんざたかが知れているので週次がちょうどいい。今日できなくても明日やればいい、みたいな調整もわりと楽に出来るし。</p>
<p>長期的なやりたいこととか取り組んでいることはプレーンテキストで残している。タスク管理アプリのカテゴリー機能などを使う人も多いようだけど、長期的な取り組みはだいたいがその途上で疑問が湧いてきたり、参考URLなぞを書きたくなるもので。だから柔軟なフォーマットで記録しておきたいなという思いが強く、今はプレーンテキストを使っている。</p>
<p>だいたいこれで上手く回ってるかなーと思ってはいるのだが、気にかかっていることが2つだけある。1つはルーチンの扱い。そのほとんどが家事ではあるのだが、定期的にやらなきゃならんことって案外多くて、Google calendarに全部記録するとなかなかにとんでもない量になって嫌気が差す。かといって他のリストを使うというのもあまり効率的には思えないので、現状は「日次タスク」というような大きな予定枠を取っておき、メモ欄にその内容を細かに書く、といった運用になっている。もうちょっとスマートにならぬものか。あとルーチンって定期的に決まったタイミングでやるもののみならず、普段はやらないけどたまに思い出さなくちゃならないよね！みたいなものもあって、そういうのまで「決まった日時に繰り返す」としてカレンダーに入れちゃうとちょっとしんどいなぁと思える。でも、そうした方が忘れずに済むのだろうなぁとも思うから、なるたけ割り切るようにしている。</p>
<p>もう1つ気にかかっているのは、クローズしたタスクや、長期的な取り組みの進捗はきちんと記録を残したいなということ。例えるなら<a href="http://shigotano.info/mbr/taskchute2/paypal.php">TaskChute</a>。自分はこれを仕事で使っているのだが、完了したタスクは取り消し線を引いた上できちんと残るようになってて、今週どのPJに多くの時間を割いたのかとか、そういやあのタスクいつやったっけ、みたいなのを後から振り返れるようになっている。これをAny.doや、プレーンテキストによる長期タスク管理の中でも回したい。進んでいる感覚を持ちたい。暫定的には週次レビューでタスクの棚卸しをするとき、その週のやったことリストを残すことで運用している。自分が何かをやったんだ、前に進んでいるんだという実感を持つことはすごく大事。なんとなく頭の中がもやっとしてるときに、達成記録を読むとちょっとホッとするし、逆に最近取り組んでいない領域があると、ああやらなきゃなって思える。</p>
<p>んで、書評じゃなくて自分のタスク管理の話になってしまったが、毎日のライフサイクルをエンジニアリングするという思想は今後も重視していきたいなと思う。もうずっと迷いながら、やり方を模索しながらなのでときに嫌になったりはするのだけど、エンジニアリングすること自体が楽しくもあるし、それが「システム」である限りは常に保守運用は必要だよなとも思っている。とりあえず中心に置いている考え方は、「ルーチンを確実に回し、タスクを効率的に処理して、やりたいことをやる時間を増やす」こと。ここだけブレなければ大丈夫かなと思っている。</p>
]]></description>
            <link>https://chroju.dev/blog/book-review-time-management-for-engineer</link>
            <guid isPermaLink="false">book-review-time-management-for-engineer</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 06 Mar 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[はてなブログからの記事移行を完了した]]></title>
            <description><![CDATA[<p><a href="http://chroju89.hatenablog.jp/">旧ブログ</a>から全記事移行完了しました。ちょっとだけ疲れた。</p>
<p>もともとはてなブログで記事を書いてたわけですが、こちらは記事のエクスポート形式がMovableType形式にしか対応してないので、そこからMarkdownに変換し直したりだとか、はてなキーワードリンクを削除したりとか、地道にいろいろやらねばならず。たぶんスクリプトでガチャーンと一発でやれるんでしょうけど、力が足りないのでvimでファイル開いて変換ポイント確認してはポチポチコマンドで置換してやりました。</p>
<h2>エクスポートファイルの分割</h2>
<p>はてなブログからエクスポートすると、最初は全記事が1ファイルに連なった状態で吐かれます。自分はMT使った経験ないんでわかりませんが、これは「そういうもの」と考えていいんですかね。一方のoctopressはエントリーごとに分割されているので、まずはこのエクスポートファイルを1記事ずつ分割してやらなくてはならない。あとヘッダの形式も微妙に両者で異なるので、ここの変換も必要。</p>
<p>なんか変換ツール落ちてないかなと堕落した感じで探しまわってたら、一応ありました。</p>
<script src="https://gist.github.com/railsbros-dirk/2351046.js"></script>
<p>名前がMT to Markdownなので完全にMarkdownへ変換してくれるものかと期待したのだけど、実際やってくれるのは先ほど挙げた「分割」と「ヘッダの書き換え」程度です。中身はHTMLタグのまま。一方で自分の環境だと<code>&#x3C;</code>が<code>&#x26;lt;</code>に変わってしまうといった副作用もあり。あと元のヘッダにあったBASENAMEだとかCONVERT BREAKSといった文字列がそのまま本文内に残ってたり。。。ちょっと謎。ただ、変換が楽になるのは確か。</p>
<h2>vimによる置換</h2>
<p>スクリプト力弱いので、あとはvimによる力技です。今回初めて複数ファイルを一挙にvimで扱うってやったけど、便利ですね。</p>
<p>vimではバッファリストがあるのは知っていたけど、一方で引数リストっていうのもあって、<code>:args hoge.txt fuga.txt</code>とかでファイルリストを作れます。元々は名前の通り、vimを起動するときに与えた引数が入ってるリストらしいのだけど、任意に書き換えができるのであまり「引数」リストという感じはしない。バッファ内の全ファイルへのコマンド実行は<code>:bufdo</code>で出来るし、引数リストについても似た感じで<code>:argdo</code>が使える。このあたりを上手く活用すれば、今回のような複数ファイルを一挙に処理するのはたやすい。</p>
<p>例えば先の<code>&#x26;lt;</code>を<code>&#x3C;</code>に全置換したり。他にも置換コマンドはh1タグを<code>#</code>に変換するだとか、いろいろな形で使いました。</p>
<pre><code class="language-vim">:argdo %s/&#x26;lt;/&#x3C;/g
</code></pre>
<p>CONVERT BREAKSと書かれた行を全部消したり。</p>
<pre><code class="language-vim">:argdo g/CONVERT BREAKS/d
</code></pre>
<p>自分が今回初めて身に付けた知識でもっとも有効だったのは、検索でマッチした文字列を置換後の文字列内で指定する方法ですかね。検索パターンの括弧でくくった部分（vimなのでエスケープして<code>\(</code>と<code>\)</code>で囲った部分、ということになりますが）を、置換パターンから<code>\1</code>で指定できる。これははてなキーワードのリンクを一掃するのに役立ちました。</p>
<pre><code class="language-vim">:argdo %s/&#x3C;a class="keyword"\(.\{-}\)&#x3C;\/a>/\1/g
</code></pre>
<p>あー、あとこのコマンドで重要なのは<code>{-}</code>の部分ですかね。これで最短マッチになるらしい。他、細かなとこだと改行コードを入力するには<code>&#x3C;C-v>&#x3C;C-m></code>と打つとか、<code>&#x3C;C-r>/</code>で直前の検索パターンをコマンドラインに入力できるとか、いろいろこの機会に調べられてタメになりました。</p>
<h3>参考</h3>
<ul>
<li><a href="http://scriptogr.am/error1009/post/201211151634">Vimで最短マッチと検索してから置換 - // Nice Catch! :)</a></li>
<li><a href="http://lesguillemets.github.io/blog/2014/08/05/vim-reuse-last-search-for-replace.html">Vim で直前の検索パターンを部分的に再利用する - Xeebi</a></li>
<li><a href="http://www.eightsee.net/?m=pc&#x26;a=noticeinfodetail&#x26;notice_no=31">改行コード変換 vi で改行コード一括置換　-eightsee.net</a></li>
</ul>
<h2>ファイルのリネーム</h2>
<p>また先のコードで分割したMarkdownファイルは自動的にファイル名も振ってくれるんですけど、日本語の場合は漢字をなんとなく頑張って読んでローマ字に変換してくれた、気持ちはありがたいけど残念な感じのものになっちゃいます。なのでこれも一括変換。</p>
<p>ファイル名一括変換だと<code>rename</code>コマンドってのがあるのですね。Linuxだと標準で入ってるけどUNIX系にはないだとか。なのでMacにも入ってなかったので、Homebrewでインストール。</p>
<pre><code>$ brew install rename
</code></pre>
<p>使い方としては<code>rename 's/hoge/fuga/' *.markdown</code>形式が使える、要はvimの置換コマンドっぽく書けるので、vimmerならこれが便利ではないかと。正規表現も当然使えます。ただし、vimで必要なあの面倒くさいエスケープの数々が要らなくなっていたり、先ほど書いた<code>\1</code>によるマッチ文字列の流用が<code>$1</code>に変わっていたり、若干の使用感の違いはあります。でも便利。</p>
<h3>参考</h3>
<ul>
<li><a href="http://qiita.com/yahihi/items/dd8b3cc7c7041c3f03b9">Linuxでrenameコマンドを使おう - Qiita</a></li>
</ul>
<p>そんなこんなで記事の変換が終わったら、あとはoctopressのレポジトリで<code>/source/_posts</code>の中に全ファイルブチ込んで<code>rake generate</code>かければ生成されます。最初はちょっと戸惑いもありましたが、やれてしまうと案外簡単に移行できるなという感じです。</p>
]]></description>
            <link>https://chroju.dev/blog/move-from-hatena-blog-to-octopress</link>
            <guid isPermaLink="false">move-from-hatena-blog-to-octopress</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 28 Feb 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Developers Summit 2015に行ってきた]]></title>
            <description><![CDATA[<p>Developers Summit 2015の2日目に行ってきました。うちの会社とは少し毛色が違うイベントということもあり、これまで業務時間を利用して行くということはなかなかできなかったんですが、今年はたまたま休みが入ったので行けました。</p>
<p>マネジメント的な話から、かなり技術よりの話まで、幅広く聞くことができたのは面白かったです。一方でそれほどベンダーロックインされた話もなく、自分の業務に何かしらのフィードバックを持ち込みやすそうな構成になっているのだなという点もよくわかりました。人は多くてちょい疲れますけど。。あと会場の目黒雅叙園、IT系のイベントやってるとは思えないぐらい綺麗な場所ですね。。まぁ元は結婚式場などなどなわけだけど。渡風亭とか、屋内に茅葺きの一軒家があるもんでびっくりした。</p>
<p>以下、参加セッション別に簡潔に。</p>
<h2>進化する！インテル RealSense テクノロジー</h2>
<p>インテルが売り出している、Kinectのような3Dカメラのデモを交えた紹介。990ドルで買えて、SDKキットは無料で落とせるらしいので、こういうのも試してみると面白いのかも。自宅での趣味開発ってこれまでコード書いてるだけに結局は終始してしまっていたのだけど、昨今の流行りに乗ってラズパイでなんかやってみたりっていうIoTっぽいのも楽しそうだし、Unityみたいな簡単に本格的なアプリケーションを作れるフレームワークもいいのかなと。RealSenseもUnityに対応しているみたいです。</p>
<h3>関連</h3>
<ul>
<li><a href="http://japanese.engadget.com/2014/06/30/engadget-fes-realsense-3d/">Engadget Fes：インテル「RealSense 3Dカメラ」をタッチ＆トライ。表情も認識 #egfes - Engadget Japanese</a></li>
</ul>
<h2>クラウドを活かす組織運営 ～クラウドガバナンス入門</h2>
<p>すでにSlideShareが上がってますね。</p>
<iframe src="//www.slideshare.net/slideshow/embed_code/44913374" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/yuya_lush/2015-44913374" title="デブサミ2015 クラウドを活かす組織運営 ガバナンス入門" target="_blank">デブサミ2015 クラウドを活かす組織運営 ガバナンス入門</a> </strong> from <strong><a href="//www.slideshare.net/yuya_lush" target="_blank">Yuya Yoshida</a></strong> </div>
<p>様々なケーススタディを元にした、組織内でクラウドを導入する場合のガバナンスノウハウの紹介。クラウドの導入とは単なる技術的な変革にとどまらず、リソース調達のタイムスパンが飛躍的に短くなったり、管理手法としてスパイラルが適していたりと、ビジネスの枠組み自体が変化することを意識して、ガバナンスルールを変えなくてはならないという点が印象的でした。またスキルセットの話（属人化とか能力評価の方法）はクラウド運営にとどまらず、いろいろと応用できそうな話でした。</p>
<h2>おさえておきたいモダンなチーム開発を支えるツール連携</h2>
<p>こちらもSliedeShareあり。</p>
<iframe src="//www.slideshare.net/slideshow/embed_code/44917265" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/tomohn/20b4-devsumi-devsumib" title="おさえておきたいモダンなチーム開発を支えるツール連携【20-B-4】 #devsumi #devsumiB" target="_blank">おさえておきたいモダンなチーム開発を支えるツール連携【20-B-4】 #devsumi #devsumiB</a> </strong> from <strong><a href="//www.slideshare.net/tomohn" target="_blank">Tomoharu Nagasawa</a></strong> </div>
<p>システム企画にConfluence、BTSにJIRA、開発にGitHubといった形でそれぞれ個別のツールを使って管理しているところを、Atlassian社のツールを使って連携させていきましょうというような話。こういったツールとまったくもって無縁の仕事をしているので若干ぼんやり聞いてしまいましたけど、やっぱツールで仕事回せるのは間違いが少なくて良さそうだな、と。上がどうにもしてくれないなら、自分でなんとかせねばなぁ。</p>
<h2>実践！Infrastructure as a Codeの取り組みと改善</h2>
<p>サイバード社の実例に基づいたInfrastructure as a Codeの現場レベルでのお話。正直言って途中から用語についていけなくなってしまったのだけど、オンプレミスでVMware上に仮想マシン立ててばかりいる自分とは隔世の感があることだけはよくわかりました。Chefはともかく、AWSには早いとこ業務で関わりを持たなくてはまずそう。AMI？ ChefとAWSの連携？ オートスケーリングの制御？</p>
<h2>情報革命時代における新しい多様性の共存と、これからのエンジニアのキャリア、評価制度について</h2>
<p>ビズリーチCTOの竹内氏によるお話。「多様性」とは内向型人間（イントロバート）と外向型人間（エクストロバート）のことであり、エンジニアには前者が多い一方で、営業には後者が多く、両者が相互理解していくこと、また近代資本主義下ではエクストロバート偏重文化があることを指摘した上で、イントロバートに対する配慮をどのように進めるべきかという内容でした。自分もイントロバートではあると思うので、結構興味深い内容。</p>
<p>外向型の振る舞い方を内向型に対して強要すること、またその逆はハラスメントに相当すると考え、双方の立場を理解して付き合っていかなくてはならないと。またイントロバートはビジネススキル、マネジメントスキルがなかなか理解できない側面もあるので、そういったスキルはきちんと理論的に分解して説き、「インストール」していくべきである。確かに自分も「なるべく社交的に振る舞わなくてはならない」という強迫観念のようなものがあるんですけど、一方で外向型の人が内向型に合わせてくれても良いはずなんですよね、多少は。</p>
<p>このあたりのお話はスーザン・ケイン氏の主張が下地になっているとのことなので、後で調べてみたいところ。</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/ScNIhIe6_5Y" frameborder="0" allowfullscreen></iframe>
<h2>変革のSIer～挑戦者たち～</h2>
<p>NRIと日立ソリューションズのSEによるパネディス形式でのセッション。ごめんなさい、本日寝不足につき正直半分寝てました。。</p>
<p>お話としては大きく二本立てで、保守的なSIerの内部で新しいものを導入していくにはどうすればいいのか？という話と、SIerが持つ技術をOSS化した事例の紹介。前者についてはリスク（悪い面の話だけではなく、将来予測が難しいことをリスクと呼ぶ）を可視化して検討を重ねていくことが大切であり、後者についてはオープン化の時代に対応していくために、OSSとして自社技術を公表することによる外部へのアピールの重要性と、またそれを実践するにあたっての困難が話の主軸でした。</p>
<p>大きなことをやる必要はない、世の中には解決すべき問題は多いので、小さなことからでも変えていくべきだという話がセッションの中でありましたが、自分としてはドラスティックな変革が必要だよなーという思いもあってちょっともにょもにょ。結局小さなことしかゲリラ戦を仕掛けていくしかないとしたら、なかなかに気の遠くなる話です。</p>
]]></description>
            <link>https://chroju.dev/blog/developer-summit-2015</link>
            <guid isPermaLink="false">developer-summit-2015</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 20 Feb 2015 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[美術展検索サービスExhiBiを見切り発車しました]]></title>
            <description><![CDATA[<p><a href="http://www.chroju.net/exhibi">ExhiBi</a></p>
<p>初めてウェブサービスをローンチしました。ネタとしてはすでにゴマンとある美術展の検索サービスです。既存のものがあんまりしっくりこなかったので、自分向けに対象を絞って、掲載情報も絞ったものを作ろうかと。ただし現時点だと<s>絞りすぎて</s>まだ出来てなくてMOTとMOMATしか範囲に入ってないッス。タイトル通り超見切り発車。なおExhiBiと書いてエキシビと読みます。</p>
<p>技術的な面では自分が「コードを書けないエンジニア（GUIによる設定ばかりに従事しているインフラエンジニア）」なので、何かしら書けるようになりたいよねということで、汎用性も高そうで文法的にもしっくりきたRubyを選びました（細々した理由は他にもいろいろとありますが……）。フレームワークには当然のごとくRails、中身のデータはMechanizeで美術館サイトから取ってきてます。あとはInfrastructure as Codeを意識したかったので、ChefとCapistranoを軸に構築してます。若干手作業が残ってしまったのが気掛かりなので、後々なんとかしたいところ。</p>
<p>しっかしRailsのデプロイ、めっちゃめちゃハマりポイント多かったんですがなんなんですかね……。開発自体は半月で終わったけどデプロイで1か月以上苦しんでました。自分が単に知見がないってだけの話なのか、元々そういうものなのか。<a href="http://www.oreilly.co.jp/books/9784873114002/">オライリーもRailsのデプロイだけで1冊出してる</a>ぐらいなので、結構難しいものなのやも。</p>
<p>今後やりたいことは取りあえずこんな感じ。</p>
<ul>
<li>対象美術館を増やす</li>
<li>気になる展覧会をクリップしとく機能</li>
<li>気になる美術館を同上</li>
<li>レスポンシブ、とかデザイン面をもうちょっと</li>
<li>コードきたねーので整える</li>
<li>はてなブログのembed記法に対応させる（冒頭のリンクだとなんかダサい）</li>
</ul>
<p>コードは一応<a href="https://github.com/chroju/exhibi/">GitHubに上げてます</a>が、場当たり的に直しちゃったところもあるんで汚いです。ていうか仕事でコード書いたことないからもう少し作法とか身につけたい。</p>
<p>なんとか年内にあげようと思ってたんで、間に合ってホッとしました。技術的な話はおいおい少しずつブログにまとめていきます。</p>
]]></description>
            <link>https://chroju.dev/blog/2014-12-29-post</link>
            <guid isPermaLink="false">2014-12-29-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 28 Dec 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『インフラ/ネットワークエンジニアのためのネットワーク技術&amp;amp;設計入門』読了]]></title>
            <description><![CDATA[<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4797373512/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51PKnkIrvrL._SL160_.jpg" alt="インフラ/ネットワークエンジニアのためのネットワーク技術&設計入門" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4797373512/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">インフラ/ネットワークエンジニアのためのネットワーク技術&設計入門</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.03.01</div></div><div class="amazlet-detail">みやた ひろし <br />SBクリエイティブ <br />売り上げランキング: 8,231<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4797373512/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>去年の末ぐらいに話題になってた本だと思うけど、読み終えた。よかった。</p>
<p>自分はネットワークスペシャリストを持っているんだけど、IPAの資格って基礎を満遍なくさらっておくには良いんだが、じゃあその知識の中で今現場で必要なのどれよ？ってのがなかなかわかりにくい面がある。この本はその「現場で実際どうネットワークは組まれるのか？」という部分に大きく焦点が当たっていて、知識を実践的なものに洗練できる。L3をコアスイッチにして構成していくのが主流ですみたいな話から、ケーブルにタグ付けてこういう情報書いておきましょうなんていう細かいことまで載っていて隙がない。</p>
<p>こういうことができる／できないという知識があったところで、じゃあそれがネットワークを組む上でどう活きるかというのはまた別の話であって、そこを弁えてないと車輪の再発明に手を煩わせてしまったり、組んだ構成が主流から外れてたりということはままある。自分がまさにそういう状態で、ベストプラクティスをきちんと押さえていないことがずっと気がかりだったので、今ネットワークを触る上でベターなやり方、注意点を体系的に学べたのはとても良かった。知識レベルとしては応用情報技術者があれば読めるレベルだと思う。1〜2年目ぐらいでネットワークに携わり始めたぐらいの社員が読むには本当に優れた1冊です。</p>
]]></description>
            <link>https://chroju.dev/blog/2014-12-01-post</link>
            <guid isPermaLink="false">2014-12-01-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 30 Nov 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[ブログ書けてない不安]]></title>
            <description><![CDATA[<p>インプットに対してアウトプットの量が少ないなと前から思っている。ブログを書いてるとアウトプットの履歴が残るから「アウトプットしてない」時期が明確にわかり、それを見て不安になったりもするんだけど、結局書けてない、ということが続く。</p>
<p>何かコーディングするときや構築するとき、わからないことがあるとついついググって探して実装して、そのままにしてしまうことが多いんだけど、これだと一過性で終わってしまって、結局記憶に残らず終わったりする。せめてはてブしたりEvernoteにクリッピングしたり、ぐらいはするときもあるのだが、これはこれでクリップしたまま記憶の底に埋もれていくので、やっぱり身になった気がしない。きちんと知識の定着を図るなら、何度も繰り返し試してみるか、インプットした内容を頭の中で咀嚼して、その経緯を自分なりにアウトプットし直すのが一番いい。</p>
<p>なんで書けないのか？というと怠惰という理由が最も強いように思う。特に壁にぶつかったときは山のようにググって比較検討して答えを見つけようとしてしまうから、結局どのページを見て正答に至ったのかが曖昧になったりしやすい。まずは公式ドキュメントにあたるだとか、試行錯誤した結果でさえ一つ一つ丁寧にログを残すだとか、そういうことをできていない。</p>
<p>ちなみにメモツールとしてはアナログだとモレスキンのラージ、デジタルだとVimプラギンのQfixHowmを主に使っている。QfixHowmを使っているのは正確にはプライベーとのPC上だけで、要はDropboxにプレーンテキストでメモを書き溜めている形になる。アナログについては、先月までは常に1日1ページ手帳のEDITを携えてメモ代わりに使っていたんだけど、ページが足りなくなることも多かったし、そもそもスケジュール管理はGoogle Calendarに全部移行していたので、もう手帳を持つ意味もないなと思い、自由度の高いモレスキンに変えた。職場の関係でDropboxは使えないし、ノートPCを叩きながら打ち合わせに臨むのも好ましいとされていないので、アナログのメモはどうしても捨てられずにいる。あと思考を巡らせるときなんかには自由度の高いフォーマットの方が好ましくて、iPad miniにタッチペンとか使うよりも広めのノートの方が脳と手が直結しやすくて楽。</p>
<p>基本的にはこれらに「なんでも書く」方針でいるのだが、散漫な思いつきなどは書けていても、本を読んだり勉強しながら書く習慣がない。tmux開いてコーディングして、ウィンドウを切り替えてメモしてという手順を踏めばいいはずなんだけど、ついつい怠ってしまう。プログラマーの三大美徳に「怠惰」が含まれてはいるが、究極の怠惰は生産性を持たないものだと思う。</p>
<p>書くためにどうしたらいいのか？という問いに対する答えは自分でもまだ見出だせていない。こういうのはもう性格レベルの問題なので、「意識する」とかそういう類の対策じゃなんの意味もなくて、もっと根本的にメモせざるを得ない状況を生み出すしかないのだと思う。あるいはメモの効用をより強く自覚すること。怠惰とはいえ、本当に必要だと思っていることはそれなりにこなせてはいるので、メモを書いてないことで痛い目見るような経験がもっと増えれば変わるような気はする。</p>
]]></description>
            <link>https://chroju.dev/blog/2014-11-10-post</link>
            <guid isPermaLink="false">2014-11-10-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 09 Nov 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Rakuten Technology Conference 2014に行ってきた]]></title>
            <description><![CDATA[<p>イベント終了から1週間後にレポートとか遅すぎますね。これの前の週のオープンソースカンファレンスがせっかく土日開催だし行こうかなと思っていたんだけど、土曜に徹夜仕事があったんでさすがにしんどくて行けなくて、じゃあこっち行こうかな、と行ってみた具合。</p>
<p>中嶋聡氏→三木谷氏→OpenStackの話→Matz氏→Chefの中の人という大変ミーハーなタイムテーブルで回ったけど、著名なハッカーの話を聞く機会というのは何度か設けておくべきなんだろうと思う。当然ながらウェブや雑誌で何度も著名な人の話は読んでいるわけだけど、実際目の前で話してもらうと記憶への残り方とか、影響の受け方とかやっぱし違ってくる。</p>
<h1>エンジニアとしての哲学</h1>
<p>特にMatz氏の話を聞いていて思ったのが、エンジニアとして哲学というか思想というか、そういうのはきちんと持っておきたいなということ。</p>
<p>エンジニアというのは知的生産、クリエイティブワーカーだという人もいるが、意識によっては単なる流れ作業の駒になりかねない。実際、自分の今の仕事というのはそちらに近くて、顧客からの要件をいかに盛り込むか、いかに期日までにリリースして検収をもらうか、というところにばかり目がいってしまっていて、全体のデザインが出来ていないことはままある。短期的に売りを上げるだけであれば別にそれでいいのだが、思想のないシステムは運用上のトラブルが多いだとか、更改や拡張に対する思慮に欠けているだとか、長期的には利を失うことにつながりやすい。</p>
<p>キャリアデザインとしても、思想がないエンジニアはブレる。というか、単に売り上げて金回すサラリーマンエンジニアになりたいのか、それともいわゆるハッカーとしてやっていきたいかの境界線の一つがそこなんじゃないかなと。どちらが良し悪しではないし、どちらでも人生で「やっていく」上では困りはしないとは思うのだが、どちらが自分にとって楽しいかが問題だ。自分は結構収入面って後回しに考えていて、自分が思うような価値を生み出せる人間になれればいいと思うし、その対価として金が得られればそれでいいのかなと思う。</p>
<h1>リクルーティングとしてのイベント</h1>
<p>いろいろと縁があって、ビジネス的なつながりがない企業の中では楽天がおそらく一番多く訪問してるんだけど、今回はだいぶ中の方まで入り込めて、ちょっとだけ実態が理解できたように思う。噂の楽天ランチは大変楽しみにしてたのだが、思ってたより薄めの味付けで社員の健康を考えている会社って素晴らしいなぁと感心してしまった。でもその後、カフェテリアで開かれる午後のセッションに行ったら無料でピザやらポテトやら唐揚げやらコーラやら配られてたんで、「あかん、これ罠や」と思いました。</p>
<p>あと周知の通り社内は英語公用語化していて、イベント自体も英語が基本なんだけど、実態としては会場内の案内は日本語遣うスタッフもいたし、本当に英語しか喋らない外人スタッフもいるし、日本語喋る外人スタッフもいるしでわりと脳味噌混乱した。参加者側も外国籍の人が半分ぐらいいたんじゃないかという感じ。</p>
<p>こういうあたり、単純にエンジニアイベントというよりは、楽天という会社の在り方をアピールする機会として本当にうまく活かしていたなと思う。夜のBeer Bashの裏でHiring Partyも開かれているのはちょっとびっくりしたけど。</p>
]]></description>
            <link>https://chroju.dev/blog/2014-11-02-post</link>
            <guid isPermaLink="false">2014-11-02-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 01 Nov 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『実践Vim』でVimの思想を身につける]]></title>
            <description><![CDATA[<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4048916599/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51xLKL7w92L._SL160_.jpg" alt="実践Vim 思考のスピードで編集しよう!" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4048916599/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">実践Vim 思考のスピードで編集しよう!</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.03.01</div></div><div class="amazlet-detail">Drew Neil <br />アスキー・メディアワークス <br />売り上げランキング: 15,673<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4048916599/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>何ヶ月か前にKindleでアスキー本のセールをやっていたことがあって、そのときに買ったのをやっと読み終えた。技術書を電子書籍で読むというのは、感覚の問題なんだけどどうも身が入らない。ドッグイヤー付けたりとか書き込んでみたりとか出来なかったり、あるいは満員電車の中とかでも手軽に読めすぎてしまって、腰を据えて勉強する感覚がなくなるからなのかなぁという気がしている。なお、これまでKindle読むのにはXPERIA Z1fを使っていたが、さすがにしんどくてiPad miniを買った模様。もちろん、他にも理由はあったけど。</p>
<p>自分はVimを使い始めて1年ちょいというところで、これまでVim本をきちんと読んだことはなかったのだが、読んでよかったと思う。</p>
<p>Vimの情報はネットにありふれすぎていて、素のVimから触り始める人ってあんまりいないような気がする。自分も最初からKaoriya版を使っていたし、使い始めてまもなくGitHubやQiitaから他人のvimrcを拝借してきて、NeoBundleでプラギン入れて使っていた。特にプラギンまわりが楽しすぎて、ほうほうVimはこんなことができるのかー！とｗｋｔｋしながら1か月ぐらいはvimrc触りまくってたように思う。自分の<a href="https://github.com/chroju/dotfiles/commits/master/.vimrc">GitHub</a>見るとまーよくわかる。</p>
<p>でもこの本にも書いてある通り、まずは素の状態で試してみるべきなのだ、本来。Vimは最初からできることが豊富にある。テキストを扱う上で必要な操作がいくらでも揃っているので、まずはそれらを味わってみて、足りなければvimrcで味付けしていけばいい。そうじゃないとVimの設計思想というか、Vimによってテキストをどう扱うべきなのかという原則論が見えてこない。</p>
<p>本書はプラギンの話は皆無で、Vimが最初から備えている機能を中心に解説されている。<code>.</code>を始めとした繰り返し操作を多用する考え方だとか、テキスト対Vimというありがちな考え方だけではなく、ファイル対Vimという考え方もしなくてはならないとか、学べることは本当に多かった。あまりに分量が多いので一気にすべてのことを実践できるわけではないが、これはと思ったとこから取り入れていきたい。おそらくVimはツールではなくて思想なのだ。親指シフトやHHKBなんかと同じように、最速でテキストを編集するための思想。もちろんここでいう「Vim」には「Emacs」も当てはまってくるのだろうけど。あと正規表現ちゃんと覚えなあかんなと思った。後半の検索、置換のあたりは当然ながら正規表現を使える前提の話が多くて、きちんと使えてない自分には少ししんどかった。</p>
]]></description>
            <link>https://chroju.dev/blog/2014-10-02-post</link>
            <guid isPermaLink="false">2014-10-02-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 01 Oct 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[awesomeウィンドウマネージャーの見栄えを良くする]]></title>
            <description><![CDATA[<p>Arch Linuxで使っているデスクトップマネージャ、awesomeのテーマに若干手を入れてみたので備忘録。あんまり日本語ドキュメントないので、このあたりのカスタマイズしんどかったです。</p>
<h1>テーマファイルの構成</h1>
<p>awesomeの設定はいくつかのLuaファイルを使って書き換えていく。基本的には全体設定を司る<code>~/.config/awesome/rc.lua</code>と、外観やテーマを司るライブラリである、Beautifulの設定ファイル<code>~/.config/awesome/themes/default/theme.lua</code>の2つを覚えておけばいいのかなと。いずれも初期状態では配置されてないので、デフォルトファイルをコピーしてきて使う。</p>
<pre><code># cp /etc/xdg/awesome/rc.lua ~/.config/awesome/rc.lua
# cp -r /usr/share/awesome/themes/default ~/.config/awesome/themes/default
</code></pre>
<p>Beautifulについてはrc.luaの中で設定ファイルのパスが指定できるので、<code>default</code>という名前が嫌だったら任意で変えてもOK。あとは正直<a href="http://awesome.naquadah.org/wiki/Awesome_3_configuration">awesomeのWiki</a>見るのが手っ取り早いとは思うのだが、設定したところだけ書いておく。ちなみに<a href="http://chroju89.hatenablog.jp/entry/2014/09/23/190304">前回記事</a>で書いたが、awesomeのデフォルトターミナルの設定も<code>rc.lua</code>を使うので、外観変える必要なくても<code>rc.lua</code>だけは確実に要ると思う。</p>
<h1>タグリストの書き換え</h1>
<p>awesomeでは仮想デスクトップを"tag"と呼んで扱っていて、デフォルトの状態だと左上に1から8まで（だったかな？）の数字がタグの番号として並んでいる。あまりわかりやすいものではないし、そんなに多くタグも使わないので書き換える。</p>
<pre><code class="language-lua">tags: &#x3C;span class="synType">{}&#x3C;/span>
&#x3C;span class="synStatement">for&#x3C;/span> s = &#x3C;span class="synConstant">1&#x3C;/span>, screen.count() &#x3C;span class="synStatement">do&#x3C;/span>
    &#x3C;span class="synComment">-- Each screen has its own tag table.&#x3C;/span>
    tags[s] = awful.tag(&#x3C;span class="synType">{&#x3C;/span> &#x3C;span class="synConstant">"Firefox"&#x3C;/span>, &#x3C;span class="synConstant">"Terminal"&#x3C;/span>, &#x3C;span class="synConstant">"Vim"&#x3C;/span>, &#x3C;span class="synConstant">"other"&#x3C;/span> &#x3C;span class="synType">}&#x3C;/span>, s, layouts[&#x3C;span class="synConstant">1&#x3C;/span>])
&#x3C;span class="synStatement">end&#x3C;/span>

</code></pre>
<p>あとウィンドウを開いているタグは小さな正方形が表示されたりしていて鬱陶しかったのと、あまり見栄えも良くなかったので、正方形を表示されないようにした上で、フォーカスしているタグは文字色を変えることにした。これはbeautifulの方で設定する。</p>
<pre><code class="language-lua">theme.taglist_fg_focus = &#x3C;span class="synConstant">"#f15c22"&#x3C;/span>
&#x3C;span class="synComment">-- theme.taglist_squares_sel   = "/usr/share/awesome/themes/default/taglist/squarefw.png"&#x3C;/span>
&#x3C;span class="synComment">-- theme.taglist_squares_unsel = "/usr/share/awesome/themes/default/taglist/squarew.png"&#x3C;/span>

</code></pre>
<p>1行目がフォーカスされているときのfg、フォアグラウンドカラーの設定。2、3行目はデフォルトで入ってる設定だったのでコメントアウトしておいた。</p>
<h1>ウィジェットの表示</h1>
<p>画面上の情報表示はウィジェットとして扱う。ウィジェットを管理するライブラリはいくつかあるみたいなんだが、取っつきやすそうなので自分は<code>vicious</code>を<code>rc.lua</code>の中で<code>require</code>して使っている。</p>
<pre><code>$ yaourt -S vicious
</code></pre>
<p>インストールした上で、</p>
<pre><code class="language-lua">&#x3C;span class="synStatement">local&#x3C;/span> vicious = &#x3C;span class="synIdentifier">require&#x3C;/span>(&#x3C;span class="synConstant">"vicious"&#x3C;/span>)

</code></pre>
<p>設定の順序としては、awesomeがもともと備えているウィジェット生成用のAPIである<code>wibox</code>を使ってウィジェットのの原型をセットし、これに<code>vicious</code>を使って表示させたい情報をセットする。ここではバッテリー状態と音量、Wi-Fiの状態を表示させる。どんな情報を表示させられるのか、詳細は<a href="http://git.sysphere.org/vicious/tree/README">ここ</a>。</p>
<pre><code class="language-lua">&#x3C;span class="synComment">--&#x3C;/span>
battxtwidget = wibox.widget.textbox()
vicious.register(battxtwidget, vicious.widgets.bat, &#x3C;span class="synConstant">" Battery: &#x3C;span color='#ffffff'>$2%&#x3C;/span> "&#x3C;/span>, &#x3C;span class="synConstant">60&#x3C;/span>, &#x3C;span class="synConstant">"BAT0"&#x3C;/span>)
&#x3C;span class="synComment">--&#x3C;/span>
soundwidget = wibox.widget.textbox()
vicious.register(soundwidget, vicious.widgets.volume, &#x3C;span class="synConstant">" Vol: &#x3C;span color='#ffffff'>$1&#x3C;/span> "&#x3C;/span>, &#x3C;span class="synConstant">2&#x3C;/span>, &#x3C;span class="synConstant">"Master"&#x3C;/span>)
&#x3C;span class="synComment">--&#x3C;/span>
wifiwidget = wibox.widget.textbox()
vicious.register(wifiwidget, vicious.widgets.wifi, &#x3C;span class="synConstant">" Wi-Fi: &#x3C;span color='#ffffff'>${ssid}&#x3C;/span> "&#x3C;/span>, &#x3C;span class="synConstant">60&#x3C;/span>, &#x3C;span class="synConstant">"wlp1s0"&#x3C;/span>)

</code></pre>
<p>ウィジェットを作ったら、画面上のレイアウトにウィジェットをセットする。</p>
<pre><code class="language-lua">&#x3C;span class="synComment">-- Widgets that are aligned to the right&#x3C;/span>
&#x3C;span class="synStatement">local&#x3C;/span> right_layout = wibox.layout.fixed.horizontal()
&#x3C;span class="synComment">-- if s == 1 then right_layout:add(wibox.widget.systray()) end&#x3C;/span>
right_layout:add(soundwidget)
right_layout:add(battxtwidget)
right_layout:add(wifiwidget)
right_layout:add(mytextclock)
right_layout:add(mylayoutbox[s])

</code></pre>
<p>自分がした設定はこの程度。あとはbeautifulで<code>theme.font = "sans 10"</code>の設定でフォントサイズを少し大きくしたぐらいだが、beautifulの設定ファイルを見ればわかる通り、かなり細かく色やら何やら設定ができる。このへんに凝り始めるとキリがないので自分はやめることにしたが、好きな人はやってみたらいいんじゃないですかね。1つ、GitHubですげーカッコイイテーマ配ってるの見つけたんで貼っときます。Samuraizuとか思い出すなー。</p>
<ul>
<li><a href="https://github.com/copycat-killer/awesome-copycats">copycat-killer/awesome-copycats · GitHub</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/2014-09-28-post</link>
            <guid isPermaLink="false">2014-09-28-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 27 Sep 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Arch Linux + awesome with Windows 8.1 in VAIO Pro]]></title>
            <description><![CDATA[<p><a href="https://www.flickr.com/photos/chroju/15143254940"><img src="https://farm4.staticflickr.com/3842/15143254940_70774bd603.jpg" width="500" height="281" alt="snapshot1_1"></a></p>
<p>先日<a href="http://chroju89.hatenablog.jp/entry/2014/09/07/232727">VirtualBoxでArch Linux入れてみた</a>ところでしたが、引き続いてVAIO Proへのインストールが完了したのでまとめます。なお、Window8.1とのデュアルブートです。上のスクリーンショットが完成形。</p>
<h1>事前準備</h1>
<p>まず起動前の状態でASSISキーを押してBIOS設定を呼び出し、Secure Bootを<code>disabled</code>にしておきます。Arch LinuxではSecure Bootをサポートしてないです。あとここではExternal MediaでのBootを許可したりとかしておくべきなんですけど、怠惰なんでASSISTメニューからUSBメモリでの起動を選ぶことでインストール作業を済ませてしまいました。Arch Wikiには「External MediaいじってUSBブートしろ」って書いてあるんで、そっちに従った方がいいと思います。</p>
<p>続いてWindows側での設定。</p>
<ul>
<li>コントロールパネル > 電源オプション > 電源ボタンの動作の選択 > 高速スタートアップを有効にする をオフ</li>
<li>スタートボタン右クリック > ディスクの管理 > パーティションを縮小</li>
</ul>
<p>既存パーティションを縮めることでLinuxインストール用の領域を作るのが通例ですけど、自分の場合これだ空き容量が小さすぎたので、回復パーティションを削除することにしました。そのために16GBのUSBメモリを買ってきて、回復ドライブを作ります。</p>
<blockquote>VAIO Care > その他の機能 > リカバリーメディアの作成</blockquote>
<p>作成が無事に終わったら、その後一度シャットダウンしてASSISTキー押して起動。以下の手順でリカバリーパーティションが消せます。</p>
<blockquote>トラブルシューティングを開始 > Microsoft IME > トラブルシューティング > VAIOのリカバリー機能 > Windows 8.1 > ツール > リカバリーパーティションを削除</blockquote>
<p>が、自分の場合これだとエラーが出て結局ダメだったんでdiskpartで削除しました。これもあまり褒められたやり方ではないと思うので推奨はしません。256GBモデルをケチらず買っときゃよかったなと初めて思った次第。</p>
<h1>インストール</h1>
<p>インストール用のUSB指して再度ASSISTキーを押し、USBメディアから起動。そこからは前回のエントリーを参考に、通常通りインストール進めていきます。ポイントは以下の点かなと。</p>
<ul>
<li>ディスクパーティション、ESPはWindowsのものを使うので新たな切り出し不要。自分は/mnt/boot(200MB)と/mnt(残り全部)だけ切りました。</li>
<li>実際にインストールしていく段階ではネット接続が必要だが、<code>wifi-menu</code>でWi-Fi接続できる。意外に簡単。</li>
<li>インストール後の設定作業でもwifi-menuを使えるようにするため、<code>pacstrap</code>するときにdialogとwpa_supplicantも入れておく。</li>
</ul>
<p>だいたいブートローダーの設定前までは特にハマるポイントはないはず。</p>
<h1>ブートローダーの設定</h1>
<p><code>grub-install</code>まで完了すると、/boot内は次のような感じになりました。</p>
<pre><code>/boot/efi/EFI/Microsoft/Boot/bootmgfw.efi
/boot/efi/EFI/grub/grubx64.efi
</code></pre>
<p>……efiがダブったパスになったのあれなんですけど、とりあえずここで言いたいのはもともとのWindowsのブートローダーとgrubがダブりますねという話で、勝手にgrubの方を上げてくれればいいんですけど、このPCの場合なのかWindows8の場合なのかわかりませんが、bootmgfw.efiの方がどうしても呼ばれてしまうので、パスを変える必要があります。</p>
<pre><code>$ cd /boot/efi/EFI/Microsoft/Boot/
$ mv bootmgfw.efi bootmgfw.efi.original  #あとで使うので必ず残すこと
$ cp /boot/efi/EFI/grub/grubx64.efi bootmgfw.efi
</code></pre>
<p>あとはGRUBのメニューエントリにWindows8のブートローダーを追加してやればよいのですが、この辺はArch Wikiに記述があるので<a href="https://wiki.archlinux.org/index.php/GRUB_(%E6%97%A5%E6%9C%AC%E8%AA%9E)#UEFI-GPT_.E3.83.A2.E3.83.BC.E3.83.89.E3.81.A7.E3.82.A4.E3.83.B3.E3.82.B9.E3.83.88.E3.83.BC.E3.83.AB.E3.81.95.E3.82.8C.E3.81.9F_Windows_.E3.81.AE.E3.83.A1.E3.83.8B.E3.83.A5.E3.83.BC.E3.82.A8.E3.83.B3.E3.83.88.E3.83.AA">そちら</a>を見ながらやった方が確実です。で、当然ながらここで<code>chainloader</code>で呼び出すのがさっき<code>.original</code>付けて退避した元のブートローダーってことになります。</p>
<p>なお、ここでbootmgfw.efiを上書きしてやっても、<a href="http://pankona.github.io/blog/2014/05/14/arch-windows-multiboot-tips/">Windows Updateをかけることで元に戻ってしまう</a>なんて話がありまして、自分も実際その現象には遭遇しました。面倒だけど遭遇したらもっかいUSBブートしてブートローダー移し替えてやるしかないです。</p>
<h1>起動後の各種設定</h1>
<p><code>reboot</code>をかければGRUBのメニューが起動して、Arch Linuxをブートできるはず。あとは<code>wifi-menu</code>につないで前回同様にslimとawesomeを導入、その他もろもろ設定します。まずは<code>yaourt</code>入れとくと何かと便利です。前エントリーに書いたのでやり方省略しますが、<code>yaourt -Syua</code>は最初にかけておくのが無難。具体的に言うとDropbox落としてみたらバージョン古くて使えなくてハマった。</p>
<p>ドライバ系の設定はだいたいArch Wikiに<a href="https://wiki.archlinux.org/index.php/Sony_Vaio_Pro_SVP-1x21_(%E6%97%A5%E6%9C%AC%E8%AA%9E)">VAIO Pro</a>の項があるので見ればOK。</p>
<ul>
<li>今回はVirtualBoxなので、当然ながらビデオドライバ（xf86-video-intel）が必要。</li>
<li>タッチパッドのドライバは<code>xf86-input-synaptics</code>を入れる。</li>
<li>音は<code>alsa-utils</code>入れたら普通に流れた。</li>
</ul>
<p>ラップトップだと折りたたんだときの電源の扱いがいろいろあるかと思いますが、デフォルトだとサスペンドになってるので、<code>/etc/systemd/logind.conf</code>を編集してハイバネートに変更しておきます。</p>
<pre><code>HandleLidSwitch=hibernate
</code></pre>
<p>Fn+Functionキーでの各種操作は当然ながらできなくなったので、<code>xbindkeys</code>を使って設定します。<code>xbindkeys -k</code>を打つと入力待ちの小窓が現れるので、そこで設定したいキーバインドを押すとキーコードが取れます。あとは取得したキーコードを使って、<code>~/.xbindkeysrc</code>にキーバインドを設定。</p>
<pre><code>"xbacklight -inc 10"
  m:0x0 + c:233
"xbacklight -dec 10"
  m:0x0 + c:232
"amixer set Master 3%+"
  m:0x0 + c:123
"amixer set Master 3%-"
  m:0x0 + c:122
</code></pre>
<p><code>alsamixer</code>でいちいち音量調節するのが面倒なので、音量の増減もキーバインドしときました。<code>~/.xbindkeysrc</code>を設けた状態で<code>xbindkeys</code>コマンド打てばキーバインドが設定されるので、<code>~/.xinitrc</code>に書き込んで自動起動するようにしておくと捗ります。</p>
<p>フォントは<code>ttf-ricty</code>と<code>otf-takao</code>ぶち込みました。ターミナルはRictyが好きだけどFirefoxとかGUIアプリで使うにはTakaoが見やすいので使い分け。パッチ当てたりとかは面倒なのでまだしてないけど、もうなんかいっかなって気がする。vim-airlineのためだけにパッチ当てるってのも手間かなと。フォント綺麗に表示するために<a href="http://archlinux-blogger.blogspot.jp/2013/08/arch-linux.html">ここ</a>の設定はしとくべきだと思います。</p>
<p>ターミナルは<code>terminator</code>です。機能豊富なのとノウハウ多くて安定してそうなので。設定は画面右クリック→設定で呼べます。一度何か設定を入れると<code>~/.config/terminator/config</code>が作られるので、これを編集しても設定可能になる。今こんなとこです。透過はやっぱ素敵。</p>
<pre><code>[global_config]
  title_transmit_bg_color = "#490001"
  inactive_color_offset = 0.4
[keybindings]
[profiles]
  [[default]]
    scrollbar_position = hidden
    background_image = None
    background_darkness = 0.66
    background_type = transparent
    use_system_font = False
    font = Ricty 14
  [[mysetting]]
    background_image = None
    background_type = transparent
    scrollbar_position = hidden
[layouts]
  [[default]]
    [[[child1]]]
      type = Terminal
      parent = window0
      profile = default
    [[[window0]]]
      type = Window
      parent = ""
[plugins]
</code></pre>
<p>ターミナル決めたら忘れずにデフォルトターミナルも変更します。<code>rc.lua</code>をコピーしてきて編集します。</p>
<pre><code>cp /etc/xdg/awesome/rc.lua ~/.config/awesome/rc.lua
</code></pre>
<p>ターミナルに関する記述の行を探して変更。</p>
<pre><code>terminal = "terminator"
</code></pre>
<p>あとは欲しいソフト適当に入れます。コードとブログ書くのに特化したマシンなので、大したのは入れてないです。</p>
<ul>
<li>Dropboxは開発中のコードやdotfilesやメモやタスク全部入りなので自分的には必須。容量の余裕そんなないのでテキスト関連だけ部分同期です。<code>yaourt</code>で入れて<code>dropboxd</code>叩けばGUIで楽々設定できます。あとは<code>~/.xinitrc</code>にも忘れず書き込むこと。</li>
<li>ブラウザはVimperatorに慣れてるのでFirefox。以降には昔FEBE使ったりしてた時期もありましたが、今時だとFirefox Sync使えばだいたいいい感じになる。</li>
<li>バッテリー状態見たいので<code>ACPI</code>入れる。本当はawesomeのウィジェットで常時表示させたいけどまだやってない。</li>
<li>エディタは前回記事でVim入れましたが、その後Wiki読んだらRuntimeもろもろ入ってるのがGVimだけだとわかったんでGVim入れ直しました。colorscheme適用するとターミナルの透過背景塗りつぶされるんで、背景設定の部分だけコメントアウトするとかアレなことしてます。対策求む。</li>
<li>開発用にrbenv。</li>
<li>スクリーンショットはKSnapshot使ってます。</li>
</ul>
<p>だいたいこんなとこですかねー。骨は折れましたがそこそこ快適に使えてます。まだやりたいことはあって、テーマ変えたりとかウィジェット置いたりとかそのへんが今後の課題です。</p>
<p>あー、あとそういえば<a href="http://exlight.net/linux/vaio_pro_13/index.html">libata.force=noncqを設定しないとSSDの場合は遅くなる</a>ていう話を見かけましたけど、今のとこうちの環境は普通に動けてます。一応やっといた方がいいのかね。</p>
<h1>参考</h1>
<ul>
<li><a href="http://ac-mopp.blogspot.jp/2014/04/2014-vaio-pro-svp1322a1j-arch-linux.html">もぷろぐ: 2014版 VAIO Pro (SVP1322A1J) で Arch Linux と Windows 8.1 を デュアルブートする</a></li>
<li><a href="https://wiki.archlinux.org/index.php/Windows_and_Arch_Dual_Boot_(%E6%97%A5%E6%9C%AC%E8%AA%9E)">Windows and Arch Dual Boot (日本語) - ArchWiki</a></li>
<li><a href="https://wiki.archlinux.org/index.php/Laptop_(%E6%97%A5%E6%9C%AC%E8%AA%9E)">Laptop (日本語) - ArchWiki</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/2014-09-23-post</link>
            <guid isPermaLink="false">2014-09-23-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 22 Sep 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[RubyHiroba 2014に（少しだけ）行ってきた]]></title>
            <description><![CDATA[<p>本当に少しだけというか2時間だけ居られました。LTほぼずっと聴いてて永和システムマネジメントさんの生活発表会を聴いて帰ってきました。</p>
<h2>アンテナの広さとか</h2>
<p>インフラエンジニアである自分がRubyに興味持ったのは、最近インフラ界隈でもRuby使う機会多いなと思っていて。ChefやCapistranoがそうだし、あとVagrantfileもRubyの文法で書かれてるし。あと何かしら言語も身につけるべきだよなと思った時、汎用性が高そうだよなとか日本製だからというのもあって選んでます。でもRubyで何ができるんだろ？っていまいちちゃんと定まってなくて、最近はWebスクレイピングを少しやってたりしたんだけど。</p>
<p>LT聴いてると話題の幅が広くて驚く。何がやれるんだろ？なんて悩んでるのがそもそもおかしくて、コンピュータ上で情報を扱うのであれば言ってしまえば何でもいいのであって。きちんとアンテナ広げて何やりたいのかとか、何がやれるのかとか探って書いてかないと嘘だよなと。何が一番印象に残った？となると<a href="http://sue445.hatenablog.com/entry/2013/12/16/000011">Rubicure</a>なんだけど、手のつけやすいとこからとにかく書くって重要だと思う。他だとロジバンとか言語学かじってた人間としては興味をひかれた。</p>
<h2>LTはきっかけ</h2>
<p>「勉強会」って言われるとその場でいろんなことめちゃくちゃ吸収して文字通り「勉強するんだ」と意気込むような感じするけど、ぶっちゃけ5分のLTで得られる情報量は「勉強」って程のものではない。あれはこんな界隈があるんだとか、あんなことやってるエンジニアがいるんだって知るきっかけで、そこから自分で興味持って更に調べるなり、発表者に聞くなりするきっかけにすべきもんなんだなって今回遅まきながら気づいた。一方で発表者の側にとっても自分を知ってもらったり、マイナーな領域を広めたりするチャンスでもあって、コミケじゃないけどあまり主客を分けた意識になってしまうのは危険だと思った。流動的に自分も「主」の側に回れるようにならなきゃいけない。</p>
<h2>みんなずっとコード書いてる。。。</h2>
<p>常にみなさんMBAなりMBPなり開いてコード書くかプレゼン資料修正するかしてた気がする。そもそもうちの会社だと自分用ノートPC持ってるとセレブ扱いされる（商売道具なんだから値段云々言ってる場合じゃねーだろと個人的には思うんだが）んだけど何なんだよこの違いとか思った。とはいえ自分もノートPC持ってるけどコードはあんま書いてないので書かなきゃなと思う。MBAやっぱり羨ましいけど、VAIO ProにArch Linux入れたんで頑張る。入れた経緯は今度書く。</p>
<p>とにもかくにも自分、視野狭いなーと思いました。視野の狭さ故に自分がやれることとか、今後の働き方の選択肢も勝手に狭めている気がして。情報集めてコードに落としこむことをもっと意識したい。とりあえずるびまはちゃんと読もう。</p>
]]></description>
            <link>https://chroju.dev/blog/2014-09-22-post</link>
            <guid isPermaLink="false">2014-09-22-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 21 Sep 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[VirtualBoxでArch Linuxのインストール練習]]></title>
            <description><![CDATA[<p>VAIO Proにcygwin入れたりして頑張っていたのだが、そろそろしんどくなってきたので、まともに開発に使える環境作るかーってことでデュアルブートを試みることに。デュアルじゃなくてOS丸ごと入れ替えたら？という話もありそうだが、仕事で使うのでWindowsを潰せない。かと言って仮想マシンだとこのPCのスペックでは心許ない。。ってことでデュアル。</p>
<p>ではディストリは何を使うか？だが、以前Ubuntuを使ったデュアルブートは構築した経験があるし、GUIでポチポチインストールするんじゃあんまり勉強にはならなさそうだなーということで、思い切ってArch Linuxを選んだ。ミニマルを是とするディストリだが、ミニマルどころか最初はsudoすら入っていないという徹底っぷり。使うものだけ入れろ！というポリシーは大変に共感できるものではあるが、それは当然難易度の高さと引き換えなわけで。。</p>
<p>さすがにぶっつけ本番は怖すぎるので、まずはiMac(OS X Marverics)上のVirtualboxでデスクトップ環境が立ち上がるとこまでやってみた。難易度が確かに高いOSではあるが、<a href="https://wiki.archlinux.org/">Wiki</a>が非常に充実しているので、案外迷うこともないとは思う。逆に言えば、ここのInstallation GuideとBeginner's Guideにきちんと目を通した上でやるべき。こんなブログ記事だけに頼らずに。</p>
<p>なお、えっらい長い記事になった模様。</p>
<h1>事前チェック</h1>
<p>VAIO ProがUEFI環境なんで、今回の練習でもUEFIを用いることにした。Virtualboxの場合は仮想マシンの設定から「UEFI」を有効化できる。他にも初期設定ではインストールメディアをつないだり、外部メディアからの起動準備を優先させたりして、準備完了。</p>
<p>起動するといきなりシェルが現れる。ここから全部自力でコマンド打って入れてけというストイックさ。ひとまずはUEFIで起動しているか確認するため、UEFI変数を表示。</p>
<pre><code># mount -t efivarfs efivarfs /sys/firmware/efi/efivars
# efivar -l
</code></pre>
<p>続いてキーボードマッピング変更。 jp106とかusとか適宜。やらなくてもインストールぐらいはなんとかなるかもしれんが、viでコロンの位置違ったりすると不便。地味に。</p>
<pre><code># loadkeys hoge
</code></pre>
<p>事前チェックはこれぐらい。</p>
<h1>パーティション</h1>
<p>続いてパーティション分割。まずは<code>fdisk -l</code>によりハードディスクのデバイス名を確認し、そのデバイス名に対して<code>cgdisk</code>コマンドを実行。今回はGPTを用いるので<code>cgdisk</code>だが、MBRなら<code>cfdisk</code>でよい。あるいは<code>gdisk</code>や<code>fdisk</code>もあるけど、やりづらいので自分はcを頭に付ける。</p>
<p>なおMBRとGPTの選択に関してはwiki内に記述がある。</p>
<blockquote>ブートローダに GRUB Legacy を使う場合、MBR を使うべきです。
古い BIOS を使う Windows (32ビット、64ビット両方) とのデュアルブートをするなら、MBR を使うべきです。
BIOS の代わりに UEFI を使う64ビットの Windows とデュアルブートをするなら、GPT を使うべきです。
[https://wiki.archlinux.org/index.php/Partitioning_(%E6%97%A5%E6%9C%AC%E8%AA%9E)](https://wiki.archlinux.org/index.php/Partitioning_(%E6%97%A5%E6%9C%AC%E8%AA%9E))</blockquote>
<p>分け方はわりと適当。swapはまぁ、なくてもいいかなと。</p>
<ul>
<li>
<p>ESP(EFI System Partition)用に512MB</p>
</li>
<li>
<p>タイプコードはef00</p>
</li>
<li>
<p>FAT32でフォーマットする
(<a href="https://wiki.archlinux.org/index.php/Unified_Extensible_Firmware_Interface_(%E6%97%A5%E6%9C%AC%E8%AA%9E)">https://wiki.archlinux.org/index.php/Unified_Extensible_Firmware_Interface_(%E6%97%A5%E6%9C%AC%E8%AA%9E))</a>)</p>
</li>
<li>
<p>デュアルブートの場合はすでにWindows側で作られているので要らないはず。</p>
</li>
<li>
<p>/bootに200MBぐらい</p>
</li>
<li>
<p>残り全部が/。</p>
</li>
</ul>
<h1>フォーマット、マウント</h1>
<p>切り分けが終わったらそれぞれ<code>mkfs</code>コマンド使ってフォーマットする。基本的にはext4でフォーマットするが、ESP用の領域はさっき書いた通りFAT32でフォーマットしておく必要がある。</p>
<ul>
<li><code>mkfs.ext4 /dev/sda1</code>でフォーマット</li>
<li>FAT32の場合は<code>mkfs.vfat -F32</code></li>
<li>-vオプションで詳細表示、-cで不良ブロックのチェック</li>
<li>Windowsデュアルブートの場合、WinのEPSがある領域を/bootに指定する</li>
</ul>
<p>そしてマウント。こんな感じで。</p>
<pre><code># mount /dev/sda1 /mnt
</code></pre>
<p>なお、<a href="https://wiki.archlinux.org/index.php/Unified_Extensible_Firmware_Interface_(%E6%97%A5%E6%9C%AC%E8%AA%9E)#EFI_System_Partition">EFISTUBの場合はESPと/mnt/bootを兼ねさせることも可能</a>らしいいのだが、EFISTUBってなに。。。？　とりあえずgrub使う場合にEFISTUBのことは考えなくていいらしいので一旦無視した。</p>
<p>マウントが終わったら<code>lsblk -f</code>でパーティションレイアウトの確認をしておく。念のため。</p>
<h1>インストール</h1>
<p>いよいよインストールである。本来ならその前にインターネット接続の設定が必要だが、Virtualboxの場合は特に何もせずつながってしまったので何もしていない。システムファイルのインストールでは、<code>/etc/pacman.d/mirrorlist</code>の上から優先的にミラーサイトが使われるので、好みのがあるなら予め編集して並び替えておく。基本的には日本（筑波大だが）を一番上にしとけば良いかと。</p>
<pre><code># pacstrap /mnt base base-devel
</code></pre>
<p>vimとかgrubとか必要なものがあれば、このコマンドの後にスペース空けて続けることで一緒に落とせる。この後の作業をある程度楽にできるかなということで、自分はvimとbashを、あとsudo（このディストリsudoすら入ってない！！）を落としておいた。</p>
<p>インストールがつつがなく終わったら、fstabを生成。</p>
<pre><code># genfstab -U -p /mnt >> /mnt/etc/fstab
</code></pre>
<p>そしてchroot。</p>
<pre><code># arch-chroot /mnt /bin/bash
</code></pre>
<h1>インストール後の処理</h1>
<p>ここからインストール後の諸設定をば。</p>
<h3>localeの変更</h3>
<pre><code># vim /etc/locale.gen
</code></pre>
<p>使う言語をコメント解除。基本はen_USとja_JPあたりでOKのはず。で、以下を打つ。</p>
<pre><code># locale-gen
</code></pre>
<pre><code># vim /etc/locale.conf`
</code></pre>
<p>さっきコメント解除した言語をLANG=で指定。LANG=ja_jp.UTF-8とか。ただしGUI環境入れずに日本語使おうとすると化けるので、この時点ではen_usが無難。</p>
<h3>Timezone</h3>
<p>/etc/localtimeを置き換える。</p>
<pre><code># ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
</code></pre>
<h3>デフォルトのコンソールフォントとキーマップ変更</h3>
<p>/etc/vconsole.confを編集して、デフォルトのキーマップとコンソールフォントを設定する。</p>
<pre><code># vim /etc/vconsole.conf
</code></pre>
<pre><code>KEYMAP=jp106
FONT=Lat2-Terminus16
</code></pre>
<h3>ハードウェアクロック</h3>
<p>自分はよく知らんかったのだが、ハードウェアクロックとシステムクロックってのがあるらしい。で、ハードウェアクロックにUTCを設定しておく。</p>
<pre><code># hwclock --systohc --utc
</code></pre>
<p>参考：<a href="http://www.atmarkit.co.jp/ait/articles/0812/26/news120.html">実践でも役立つLPICドリル（8）：Linux時刻管理の仕組みと設定 (1/4) - ＠IT</a></p>
<h3>hostname</h3>
<pre><code># echo hostname > /etc/hostname
</code></pre>
<h3>rootパスワード変更</h3>
<pre><code># passwd
</code></pre>
<h1>ブートローダー設定</h1>
<p>Gummibootとか使ってみようかなとも思ったけど、初めてだし一般的によく使われているであろう、GRUB2を使うことに。どうでもいいけどパッケージマネージャの名前が「pacman」って面白いでふね。オプションなしで打つとAAも出てくるけど、権利関係とかどうしてんだろ。。</p>
<pre><code># pacman -S grub efibootmgr
# mkdir -p /boot/efi/EFI
# grub-install --target=x86_64-efi --efi-directory=/boot/efi --boot-direcotory=/boot/efi/EFI --bootloader-id=grub --recheck
</code></pre>
<p>GRUB設定ファイルの自動生成。当たり前だがここで指定のディレクトリを誤ると立ち上がらない。自分は何度かハマったんだが、<code>grub-install</code>したときに<code>--boot-direcotory</code>オプションで指定した場所で良い、はず。</p>
<pre><code># grub-mkconfig -o /boot/efi/EFI/grub/grub.cfg
</code></pre>
<p>そして再起動！</p>
<pre><code># exit
# umount -R /mnt
# reboot
</code></pre>
<h1>デスクトップ環境</h1>
<p>ここからはデスクトップ環境を構築していく。要らないならすっ飛ばしでも。</p>
<p>まずは作業用のユーザーを作成。</p>
<pre><code># useradd -m hoge
# passwd hoge
# visudo  #sudo実行可能にしておく
</code></pre>
<p>続いてVirtualBox特有のものとして、ゲストユーティリティをpacmanを使って入れる。普通ならVirtualbox側のメニューから仮想CD-ROMをマウントさせるところだが、Arch Linuxの場合はこの方法だとインストールができない（エラーが表示される）。</p>
<pre><code>$ sudo pacman -S virtualbox-guest-utils
$ sudo vim /etc/modules-load.d/virtualbox.conf
</code></pre>
<p>virtualbox.confを開いたら、下記の通り書き入れておく。これでVirtualbox関連のモジュールが起動した時に自動でロードされるようになる。</p>
<pre><code>vboxguest
vboxsf
vboxvideo
</code></pre>
<p>そしてデスクトップ環境に必要なもろもろのインストール。これまでGNOMEぐらいしか使ったことがなくてよくわかってなかったのだが、LinuxのGUI環境を提供するツールは大きくこんな感じで分けられる、みたい。</p>
<ul>
<li>
<p>ディスプレイマネージャー</p>
</li>
<li>
<p>グラフィカルなログイン環境を提供する</p>
</li>
<li>
<p>Slim、GDM、KDMなど</p>
</li>
<li>
<p>ウィンドウマネージャー</p>
</li>
<li>
<p>ウィンドウ周りの機能を提供する</p>
</li>
<li>
<p>スタック型＝Windowsっぽいウィンドウを重ねるタイプ（Xfwmなど）</p>
</li>
<li>
<p>タイル型＝ウィンドウがオーバーラップしないタイプ（Bspwmなど）</p>
</li>
<li>
<p>動的＝どちらもいける（awesomeなど）</p>
</li>
<li>
<p>デスクトップ環境</p>
</li>
<li>
<p>様々なツールを一括提供するGUIキット</p>
</li>
<li>
<p>GNOME、KDE、Xfceなど</p>
</li>
</ul>
<p>したがってGNOMEあたりを入れてしまうのが一番簡単なようなのだが、ここまで来たらきちんとやっておきたいし、せっかく最小ディストリなのに重いツールを入れてしまうのももったいないので、Slimとawesomeを使うことにした。</p>
<pre><code>$ sudo pacman -S xorg-server xorg-server-utils xorg-xinit xterm
$ sudo pacman -S slim archlinux-themes-slim slim-themes
$ sudo pacman -S awesome
</code></pre>
<p>X Window Systemの起動には<code>startx</code>コマンドを打つことになるが、このときのシーケンスとしては、まずxorg-xinitやSLiMなどでXを起動 => .xinitrcを見てウィンドウマネージャー等を起動という順序になる。.xinitrcに対して、どのウィンドウマネージャーを使うのかを教えてやらなくてはならない。またVirtuarlBox関連のドライバを同時に読みこませておかないとうまく起動しない。</p>
<pre><code>$ cp /etc/skel/.xinitrc ~/
$ vim ~/.xinitrc
</code></pre>
<pre><code>/usr/bin/VBoxClient-all
exec awesome
</code></pre>
<p>そして<code>startx</code>を使えばawesomeが立ち上がるはず。OSを起動した時に自動でGUIを立ち上げるには、slim.confを編集した上で、<code>systemctl</code>コマンドを使って有効化しておく。</p>
<pre><code>$ sudo vim /etc/slim.conf
</code></pre>
<pre><code>daemon yes
current_theme archlinux-simplyblack
</code></pre>
<pre><code>$ systemctl enable slim.service
</code></pre>
<p>ためしに<code>reboot</code>してみて、ログイン画面が表示されればOK。</p>
<h1>日本語環境</h1>
<p>GUIを使えるようにしたら日本語環境も整えたい。で、まずまずは<code>/etc/locale.conf</code>を編集し、さっきやめておいた言語設定の変更を。。他にやることとしてはフォントの導入、IMEの導入、キーボードの設定。まずフォントからだが、pacmanではなくyaourtを使って入れることになる。</p>
<h3>yaourt導入</h3>
<p>pacmanにレポジトリを追加。</p>
<pre><code>$ vim /etc/pacman.conf
</code></pre>
<pre><code>[archlinuxfr]
SigLevel = Never
Server = http://repo.archlinux.fr/$arch
</code></pre>
<p>そしてyaourtを導入。</p>
<pre><code>$ pacman -Sy yaourt
</code></pre>
<h3>フォント導入</h3>
<p>フォントの導入。yaourtを使ってインストールすると、そのままデフォルトとして設定されるみたい。複数入れておいて選択したい時とかどーすんの？って思うけど調べてない。とりあえず無難にRictyを。。</p>
<pre><code>$ yaourt -S ttf-ricty
</code></pre>
<h3>IME導入</h3>
<p>ibus-mozcを使ってる例が多かったのでそうします。さっきと同じくpacman.confにレポジトリを追加した上でインストール。</p>
<pre><code>[pnsft-pur]
SigLevel = Optional TrustAll
Server = http://downloads.sourceforge.net/project/pnsft-aur/pur/$arch
</code></pre>
<pre><code>$ pacman -Sy mozc ibus-mozc
</code></pre>
<p>そしてibusをセットアップする。下記コマンドを実行するとグラフィカルな設定用ウィザードが表示されるので、ホットキーを使用可能とし、mozcをインプットメソッドとして指定する。</p>
<pre><code>$ ibus-setup
</code></pre>
<p>ibusを起動時に自動で上げるための設定を入れる。.xinitrcを立ち上げて、<code>exec awesome</code>よりも前に以下のように書き入れる。</p>
<pre><code>export GTK_IM_MODULE=ibus
export XMODIFIERS=@im=ibus
export QT_IM_MODULE=ibus
ibus-daemon -drx
</code></pre>
<p>今のところ設定したのはここまで。残ってる問題としてはキーマップの設定がおかしい。vconsole.confはコンソール上でのキーボード設定だから、たぶんawesome上では別の設定をしなくてはいけないはず。探さねば。</p>
<h1>参考</h1>
<ul>
<li><a href="http://qiita.com/co-me@github/items/12f21126c5117e07decd">Arch Linux インストールから awesome 導入まで - Qiita</a></li>
<li><a href="http://opamp.hatenablog.jp/entry/2013/10/30/233548">UEFIでArchLinuxをインストールする - opamp_sando's blog</a></li>
<li><a href="http://masawada.hatenablog.jp/entry/2013/06/10/225748">Arch Linux インストールメモ 3 - あんパン</a></li>
<li><a href="http://qiita.com/xorphitus/items/3711895eb5d9f946c782">Arch Linux快適デスクトップ環境の構築 - Qiita</a></li>
<li><a href="http://opamp.hatenablog.jp/entry/2013/08/13/201544">ArchLinuxでibus+mozcな環境を構築 - opamp_sando's blog</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/2014-09-07-post</link>
            <guid isPermaLink="false">2014-09-07-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 06 Sep 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Webスクレイピング手法は何かしら身に付けると便利そう]]></title>
            <description><![CDATA[<p>最近<a href="http://tokyoscrapper.connpass.com/event/7107/">Webスクレイピング勉強会</a>が開かれましたが、自分これは「補欠」になってしまった上に別の予定が入ってしまって行けなくなり、なので自分なりにスクレイピングやってみました。人気の勉強会ってすぐ満席になりますよね。。ホントは勉強会情報とかすくれーぴんぐして逃さずゲトできるようになりたい。まぁこの分野は先人が作ったサービス等いろいろありますが、push型の配信してくれるものってまだない気がするのよね（あったっけ？）</p>
<p>Ruby好きなので使ったのはMechanizeです。nokogiriではない。ネットバンクから毎月残高拾ってきて記録してって手でやってたんだけど、いい加減自動化できないかと思いまして。なのでログイン処理とかまで任せるためにMechanize。</p>
<script src="https://gist.github.com/6cfb9869b7733d362af3.js"> </script>
<p>で、使ってみた結果、これめちゃくちゃ便利というか、Web上に掲載されているあらゆるデータを抽出して使い回せるようになるので、やり方一つぐらい身に付けといて損はない気がしますね。</p>
<p>冒頭に挙げたWebスクレイピング勉強会の第2回で<a href="http://dev.classmethod.jp/study_meeting/web-scraping-tokyo-2nd/">kimonoの中の人がしゃべっていた</a>みたいですが、その中でも「セマンティックWebは失敗だった。だからkimonoが必要なんだ」という考え方にはわりと共感できるところがあります。Webってこれだけ情報に溢れたのに、そこから情報を抽出する手立てが限られているのは勿体ないですよね。</p>
<p>ただ、kimonoが最終解のままで良いとも思っていなくて、セマンティックWebは失敗したのかもしれないけど、それに代わるアーキテクチャは何かしら必要なんじゃないかと。Web標準への準拠という、フロントサイドの思想がだいぶ一般的になってきた今日、次に考えていくべきはアーキテクチャの標準化ではないかという気がします。</p>
]]></description>
            <link>https://chroju.dev/blog/2014-08-24-post</link>
            <guid isPermaLink="false">2014-08-24-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 23 Aug 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[何を勉強したらいいのかわからなくなってきた]]></title>
            <description><![CDATA[<p>このブログ始めて1年経ったけど、まー振り返ってみるとだいぶ話題の幅が広いっつーかまとまりがないっつーか、俺はいったい何エンジニアなんだって感じの内容になりつつある。絶賛迷走中、何を勉強してるのかよくわからない、感じに。</p>
<p>ここまでは完全に興味関心に頼ってそのときやりたいことを取りあえずやってみる、という感じの勉強をしてきてしまった。いや、正確に言えばそこまで何も考えていないわけでもない。自分はインフラ、それもWindows方面にかなり偏ったエンジニアなので、Linuxを触る機会を増やすだとか、アプリ寄りの技術も触れてみるだとか、そういうことは意識してきたつもりだ。とはいえ基礎から積み上げるような学習ではないし、そうやって身につけてきたことが実際の仕事で役立ったためしも、今のところない。実際のところ仕事で学べるところはOJTで学べばいいやと思っている節があったりして、趣味の勉強の目的が迷子になりつつあるように思う。</p>
<p>プログラミングとか学ぶことは趣味にもなり得るのだが、一応この業界にいる以上、勉強の目的は「金を生めること」であるのが健全だろうと思っている。言い方はよろしくないかもしれないけど、付加価値のない技術なんざ単なる雑学に過ぎないわけで。なのに実業務につながるような勉強ができていないあたり、自分のやっていることは自己満足に過ぎなかったのかもしれんなぁなどと最近考える。もちろんまったくの無駄と言うわけではないけれど、それを学んで今後どうしたいの？ということをあまり考えていなかったような。</p>
<p>今業務でやっていることに対してモチベーションが上がらないのであれば、自分がやりたいことをやるにはどうしたらいいのか考えるべきだし、今の業務の延長線上で食べていく気があるのであれば、もっと業務に結びつくことを学ぶべきだ。要するに、エンジニアとしての生き方を自分は考えきれていない。なんとなく不安だからとか、なんとなく面白そうだからとか、そういう理由でつまみ食いをしてきてしまったなと思う。たぶん、これでは生きていけない。</p>
<p>で、じゃあ何をやろうか？と。スキルマップみたいなものを描かなくてはならないのではないか。計画的に狡猾に、自分の人生がどこに向かっていて、そのために何が必要なのかを考えなくてはならんのではないか。</p>
<p>もっと社外のエンジニアに会ったりしないと、選択肢は狭まる一方だよなーと思う。実のところ、この3か月ぐらいはそこそこいろんな人に会う機会を設けてみたのだけど、ユーザーへのデリバリを考えずひたすら作りたいものがあるって人もいれば、何よりもお客様のためだみたいなことを話す人もいるし、1人保守のチームに投げ込まれて気付いたらアプリもインフラもやれるようになりましたみたいな人とか、まーホントいろいろいる。社内のキャリアパスにしたってあんまりルートは多くないように見えていたけど、知らないところでだいぶ自由なことをやれている人もいた。結局、やりたいことはやったもん勝ちだし、案外やりたいことをやれるようになるまでのハードルは高くないのだと思う。だから、まずは自分がやりたいことを、もちょっと見定めてみようと思う。</p>
]]></description>
            <link>https://chroju.dev/blog/2014-08-10-post</link>
            <guid isPermaLink="false">2014-08-10-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 09 Aug 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[tmuxをなんとなく使ってたのできちんと使うようにしてみた]]></title>
            <description><![CDATA[<p>tmux、なんとなく入れてなんとなく使ってたけど、改めてそれなりに形にしてみたのでメモ。</p>
<h2>tmuxとは</h2>
<p>たーみなるまるちぷれくさー。ターミナル操作が便利になる系の、まぁ今更自分が説明する必要はないですね。せいぜいVagrantとVPSいじりながらローカルでもVim開くみたいなことしかやってないので宝の持ち腐れ感はハンパねーですが、とりあえず知っといた方がいいやってのとなんとなくカッコいいっていう理由だけで使ってる。</p>
<p>なお、インストール自体はだいぶ前に実行したのでやり方忘れた。たしかHomebrewで入れられたと思う。</p>
<h2>.tmux.conf</h2>
<p>ルートディレクトリ上に生成される設定ファイル。tmuxに関する設定は基本的にここに書く。</p>
<script src="https://gist.github.com/705c90c240abe035a98e.js"> </script>
<p>自分の設定ファイルを張ってみたけど、よく見られる設定の寄せ集めだとは思う。tmuxはなんかESCキーの反応が悪いらしく、その調整用の設定。ペイン分割したときに各ペインごとでマウススクロールができるようにする設定。文字コードの設定。色の設定。これは上手くやればもうちょっと見やすくなるんだろうなとは思ってるけど、面倒なので半端なとこで終えている感がある。カラーパレット見て色名探してみたいのめんどいよぉ。</p>
<p>あとキーバインド。デフォルトのプレフィックスが<code>C-b</code>なんだけど、使いづらいので<code>C-z</code>に当て替えてる。他にやってるのは.tmux.confをすぐ読み込むための設定と、ペイン移動や分割のショートカット、あとはウィンドウやセッションのkill。</p>
<p>コピーモードについてはよくあるviライクなキーバインドが使えるってやつをそのまま使っている。コピーモードに入るときのデフォルトキーが<code>[</code>なのが気に食わんので、これも<code>y</code>に変更してある。でもよく考えたら<code>v</code>の方が相応しいなこれ。。。</p>
<h2>powerline</h2>
<p>残りはpowerlineに関しての設定。ステータスラインがカッコよくなります的なやつ。これも入れ方忘れたけど、<a href="https://github.com/erikw/tmux-powerline">公式のREADME</a>によれば<code>git clone</code>するみたい。</p>
<p>これ、入れたはいいけど天気とか上手いことでなくてしばらく放置していた。今回改めて先のREADME読んでみたところ、GNU grepが要るみたいで、インストールしてgrepコマンドを置き換えたら上手くいった。やっぱりREADMEはちゃんと読むべき。自戒。他にもCPUとメモリ使用状況のグラフィカルな表示のためには<a href="https://github.com/thewtex/tmux-mem-cpu-load">thewtex/tmux-mem-cpu-load</a>が必要だったりする。</p>
<p>設定は主に3ファイルを用いる。</p>
<ul>
<li>~/.tmux.conf</li>
<li>~/tmux-powerline/themes/default.sh</li>
<li>~/.tmux-powerlinerc</li>
</ul>
<p>まず.tmux.confにpowerlineを使うってことを宣言しなくては使えない。先の.tmux.confで言えば一番下の方の設定。上からステータスラインを表示する設定、更新インターバルの設定、UTF-8の使用設定、ウィンドウリストを左側に配置（これは好みによってcenterにする人もいるみたい）、ステータスラインの長さの設定。で、最後の2行で<code>powerline.sh</code>を読み込ませている。</p>
<p>実際にpowerlineに何を表示させるか、という設定は~/tmux-powerline/themes/default.shを変更して行う。</p>
<script src="https://gist.github.com/bd1d33a4cb73807e6f22.js"> </script>
<p>デフォルトで表示できるものについてはすでに入っているので、これをコメントアウトしたりして好きなものを表示できるよう変える。各.shの後ろについている数字は表示部分の文字色と背景色。<code>~/tmux-powerline/color_palette.sh</code>を実行すると、設定できる色と色名の一覧が表示できるので、これを使って設定する。まぁ、おこのみで。あと各表示部分の境界をカッコいい感じにするための設定が入ってたりするが、このへんはググれば出てくるので割愛（適当）。なお、default.shを直接触りたくない場合は、コピーして名前変えて使えばOK。</p>
<p>さらに、表示内容の細かな設定に.tmux-powerlinercを使う。このファイルは元々置かれていないので、<code>./tmux-powerline/generate_rc.sh</code>を実行して生成する。よくいじるのは天気の設定で表示する地域を入れたり、時間や日付の表記を好きに変えたりってところかと。これについてはコメントでどういじればいいのか書いてあるので、見ればわかると思う。</p>
<p>tmux-powerlineについては自作のshellを使って好きな内容を表示させたりもできるようだけど、現状そこまでの情熱は傾けていない。</p>
<h2>tmuxinator</h2>
<p>tmuxを立ち上げたあと、ペイン分割をいちいち手でやるのが手間なので、自動化しちゃいましょうというツール。単に分割するだけではなく、各ペインでコマンド実行させることもできるので、例えば最初からVim開いておいたりディレクトリ変えておいたり<code>git pull</code>させておいたりとか、いろいろできる。工夫次第。自分は今のところよく使っていたペイン分割を自動化させることしかしていない。以下のページが大変わかりやすかった。</p>
<p><a href="http://tactosh.com/2014/01/tmux-window-pane-tmuxinator/">tmuxのwindow, pane設定を一発で再現できるtmuxinatorが便利 | TACTOSH</a></p>
<p>以上、超適当かつ簡潔なまとめでした。まぁ、あまりにもこの分野は先駆者が多いので。。</p>
<p><strong>参考</strong></p>
<ul>
<li><a href="http://kanjuku-tomato.blogspot.jp/2014/02/tmux.html">tmuxを使い始めたので基本的な機能の使い方とかを整理してみた - 完熟トマト</a></li>
<li><a href="http://qiita.com/syui/items/dc509f208b464838b948">tmux-powerline - Qiita</a></li>
<li><a href="http://saku-na63.hatenablog.com/entry/2013/10/13/223010">tmux-powerlineを使う - memo63</a></li>
<li><a href="http://qiita.com/naoty_k/items/869b00fdde27c2225989">Ruby - tmuxinatorで一瞬で開発環境を起動する - Qiita</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/2014-07-20-post</link>
            <guid isPermaLink="false">2014-07-20-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 19 Jul 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[chroju.netを開設してみた]]></title>
            <description><![CDATA[<p><a href="http://chroju89.hatenablog.jp/entry/2014/05/30/212733">前回の記事</a>でchefでVPS構築したと書きましたが、そのサーバーに静的なHTML置いてドメインも取得してみました。</p>
<p>まだ何もないですけど、ここをハブにしていろいろやってみたい。</p>
<p><a href="http://www.chroju.net/">http://www.chroju.net/</a></p>
]]></description>
            <link>https://chroju.dev/blog/2014-06-05-post</link>
            <guid isPermaLink="false">2014-06-05-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 04 Jun 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[chefでさくらVPSの初期構築を全部自動化してみた]]></title>
            <description><![CDATA[<p>Chefでサーバー構築を全部自動化して、借りているさくらVPSに当ててみた。意地でも手作業はまったく入れない完全自動構築設定。これはよい。毎回手作業やらずに済むというのは、抜け漏れをなくすという点でも、構築時間を短縮するという面でも本当に楽。</p>
<h2>前提</h2>
<p>今回構築するサーバーの前提は次の通り。</p>
<ul>
<li>
<p>CentOS 6.4環境で試行</p>
</li>
<li>
<p>vagrantを使って試験後、さくらVPSに対して適用</p>
</li>
<li>
<p>基本の設定として以下を実施</p>
</li>
<li>
<p>構築用のユーザーを作成</p>
</li>
<li>
<p>構築用ユーザーにsudo権限を付与</p>
</li>
<li>
<p>構築用ユーザーを秘密鍵認証でsshログイン許可</p>
</li>
<li>
<p>rootによるsshログインを禁止</p>
</li>
<li>
<p>パスワード認証によるログインを禁止</p>
</li>
<li>
<p>sshのポート番号を変更</p>
</li>
<li>
<p>ssh, http以外のアクセスをiptablesでシャットアウト</p>
</li>
<li>
<p>nginxを導入</p>
</li>
<li>
<p>将来的にunicornを入れるための設定を準備</p>
</li>
<li>
<p>極力サードパーティクックブックは使わない（ブラックボックス化が嫌）</p>
</li>
</ul>
<h2>レシピ</h2>
<p>まず「どんなサーバーだろうとまず実行するだろうセキュリティ上の設定」はdefault_tasksというレシピにまとめた。</p>
<h3>default_tasks</h3>
<pre><code># sshdサービスの有効化
service "sshd" do
  supports :status => true, :restart => true, :reload => true
  action [ :enable, :start ]
end

# sshd_configの配置
template "sshd_config" do
  path "/etc/ssh/sshd_config"
  source "sshd_config.erb"
  owner "root"
  group "root"
  mode 0600
  notifies :restart, "service[sshd]"
end

# iptablesの設定
iptables_rule "iptables"
</code></pre>
<p>sshdの有効化と、templateを使ったsshd_configの配置、そしてiptablesの設定。このうちiptablesについてはサードパーティ・クックブックを使っている。</p>
<p><a href="https://github.com/opscode-cookbooks/iptables">opscode-cookbooks/iptables</a></p>
<p>iptablesに挿入したい内容をtemplateで用意し、<code>iptables_rule "template name"</code>の形でレシピ内に書き込んでおくと、templateの内容がそのままiptablesに追加されるというシンプルなレシピ。まぁ、これぐらいはサードパーティ使ってもよいかな、と。iptablesを丸ごとtemplate化してアップロードするという手もあるにはあるのだが。</p>
<p>sshd_configはCentOSから引っ張ってきたものをそのまま流用し、Attributesを使っていろいろと書き換えられるように仕込んだ。長いので割愛するけど、設定可能なAttributesはこんな感じ。</p>
<pre><code>  "sshd" : {
    "Port" : 22,
    "MaxStartups" : 10,
    "PermitRootLogin" : "yes",
    "RSAAuthentication" : "yes",
    "PubkeyAuthentication" : "yes",
    "AuthorizedKeysFile" : ".ssh/authorized_keys",
    "PasswordAuthentication" : "yes"
  },
</code></pre>
<p>よく編集する箇所を中心にAttributesとしてみた。他に設定したい項目が増えたら随時足していけば良いかなと。</p>
<h3>users</h3>
<p>ユーザーの作成は別のレシピに切り分け。</p>
<pre><code># wheelグループの作成
group "wheel" do
  gid 10
  action :create
end

# data bagsよりユーザーを作成
data_ids = data_bag('users')

data_ids.each do |id|
  # ユーザー作成
  u = data_bag_item('users', id)
  user u['username'] do
    password u['password']
    supports :manage_home => true, :non_unique => false
    group u['group']
    action [:create]
  end

  # ssh公開鍵配置用のディレクトリ作成
  directory "/home/#{id}/.ssh" do
    owner u["id"]
    group u["id"]
    mode 0700
    action :create
  end

  # ssh公開鍵の配置
  file "/home/#{id}/.ssh/authorized_keys" do
    owner u["id"]
    mode 0600
    content u["key"]
    action :create_if_missing
  end
end
</code></pre>
<p>sudoを許可するユーザーをwheelグループに入れるという定番設定。wheelを実際にsudo許可するのはまた別のレシピの仕事で、ここではグループとユーザーの作成のみ。</p>
<p>ユーザー作成にはdata_bagを使った。<a href="http://girigiribauer.com/archives/1066">こちら</a>を参考として作っている。ポイントとしては公開鍵まで登録させていること。fileリソースを使って実にシンプルな配置の仕方だけど、非常に楽ではある。</p>
<p>あまり詳しくは知らないのだが、data_bagについては暗号化する方法があるみたいなので、公開鍵を生でべろっと貼っとくのが気になる場合はそのへんも仕掛けておくと良さそう。</p>
<h3>nginx</h3>
<p>一番苦労した気がするし、あまり美しくない。。。</p>
<pre><code>
# nginxインストール
package "nginx" do
  action :install
end

# nginx有効化
service "nginx" do
  supports :status => true, :restart => true, :reload => true
  action [ :enable, :start ]
end

# templateからnginx.confを配置
template "nginx" do
  path "/etc/nginx/nginx.conf"
  source "nginx.conf.erb"
  owner "root"
  group "root"
  mode 0644
  notifies :reload, "service[nginx]"
end

# ディレクトリ作成
directories = ["/etc/nginx/sites-available","/etc/nginx/sites-enabled","/var/www","/var/www/#{node['nginx']['root']}","/var/www/#{node['unicorn']['root']}"]
directories.each do |directory_name|
  directory "#{directory_name}" do
    owner "root"
    group "root"
    mode 0644
    action :create
  end
end

# sites設定をtemplateごとに実行
node['nginx']['nginx_sites'].each do |site|
  # templateからsites-available配下に設定ファイルを配置
  template "nginx_sites_available" do
    path "/etc/nginx/sites-available/#{site}"
    source "nginx/#{site}.erb"
    owner "root"
    group "root"
    mode 0644
  end

  # sites-enabled配下へシンボリックリンクを配置
  link "/etc/nginx/sites-enabled/#{site}" do
    to "/etc/nginx/sites-available/#{site}"
    link_type :symbolic
    action :create
    notifies :reload, "service[nginx]"
  end

end
</code></pre>
<p>インストール、サービス有効化、templateからのnginx.confアップロードまでは良いとして。ディレクトリ作成がなんか。。。汚い。。。</p>
<p>/var/wwwを掘って、その中にウェブサイトのルートを置いたり、バーチャルホストの設定でsites-availableとかその辺を使っているもんで、ディレクトリ作成の量が多くなってしまった。いずれも設定は同じなので配列でやるのがベターだとは思うのだが、どうにも汚い。なんとかしたいとこではある。</p>
<p>あとはsites-availableにtemplateから設定ファイルを配置して、linkリソースでsites-enabledにシンボリックリンクを貼って終了。nginxの使い方はsites-availableを使うパターンだけではないので、もう少しスッキリさせることはできそう。</p>
<h2>サードパーティ・クックブック</h2>
<p>サードパーティとして導入したのはさっきのiptablesと、sudoの2つ。</p>
<p><a href="https://github.com/opscode-cookbooks/sudo">opscode-cookbooks/sudo</a></p>
<p>sudoはvisudoを<code>execute</code>で走らせるってのも怖いし、その後ファイル編集をどうやったらいいのかよくわからんなってのと、sudoresファイルをtemplateで上げるってのもちょっと怖いという感覚的な問題からサードパーティ採用とした。</p>
<p>使い方としては簡単なもので、変数でsudoを許可するユーザーやグループを指定して、passwordlessとするかどうかを設定するぐらいで終わり。</p>
<pre><code>  "authorization" : {
    "sudo" : {
      "groups" : ["wheel"],
      "passwordless" : "true"
    }
  },
</code></pre>
<p>冒頭でも書いた通り、なるべくサードパーティを使わない方針で行きたいんだけど、自力でレシピを書けないor書く自信がないところは已むなく実績のあるサードパーティを使ったという感じ。まぁサードパーティと言っても結局は人の手で書かれたレシピなので、自分でchef力上げれば相応なレシピは自力で書けるはず。このあたりは結局「どこまでchef力の向上に時間を割くか」という部分とトレードオフになるのかと。</p>
<h2>今後やりたいこと</h2>
<p>最終的にこのサーバーではRails動かしたいので、Rubyやpostgresqlのインストールを今後実装したい。あと「取りあえず動けばいいや」路線で一度作ってしまったので、もう少しメンテナンス性の高いもの、読みやすいレシピには育てたいところ。</p>
<p>汎用的に誰でもどんな用途でも使えるって感じではないと思うが、とりあえずGitHubには上げてみた。秘伝のタレのようにこれをじわじわ育てていくというのは良いなぁ。Linuxの勉強をするごとにきっと強靭なレシピとなっていくのだろう。まさに「レシピ」だな、これは。</p>
<p>まずは静的なページをってことで、近日中にプロフィールでも置いて公開する予定。</p>
<p><a href="https://github.com/chroju/chef_web_server">https://github.com/chroju/chef_web_server</a></p>
<h2>参考</h2>
<ul>
<li><a href="http://tsuchikazu.net/vps_chef_solo/">さくらVPSの初期設定をChef Soloでやってみた〜サードパーティcookbookの使い方〜 | tsuchikazu blog</a></li>
<li><a href="http://ch.nicovideo.jp/dwango-engineer/blomaga/ar334285">Chef Soloと Knife Soloでの ニコニコサーバー構築 (4) ～コツ編～:dwango エンジニア ブロマガ:ドワンゴ研究開発チャンネル(ドワンゴグループのエンジニア) - ニコニコチャンネル:生活</a></li>
<li><a href="http://d.hatena.ne.jp/ntaku/20130324/1364132658">入門Chef-Soloを片手にRailsアプリを動作させるところまでやってみた - プログラミングノート</a></li>
<li><a href="http://m-tkg.hatenadiary.jp/entry/2013/12/12/151254">単純な環境構築を知る -Chefでiptables書き換え- - 技術いろいろ勉強メモ</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/2014-05-30-post</link>
            <guid isPermaLink="false">2014-05-30-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Thu, 29 May 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[自分のことを「ペルソナ」から見返してみる]]></title>
            <description><![CDATA[<p>自分の状況を客観的に評価する（タスク、財務管理、スケジュール管理など）とき、「ペルソナ」を考え方として導入するとわりと捗ることに最近気付いた。</p>
<p>このご時世、人格が一面的という方はあまりいないのではないかと思う。要は家庭での顔、仕事での顔、趣味での顔とかそういうのだ。これを「ペルソナ」と呼んだのだが、自分にはどんなペルソナがあるのか把握した上で、各ペルソナごとに状況を振り返ってみると漏れが少なくなる。</p>
<p>使える場面としては、例えばGTDの週次レビュー。ToDoリストに漏れがないか考えるとき、各ペルソナごとに数分ずつ考えてみる。あるいは「高度」の概念を取り入れるとき、ペルソナごとの高度の視点を持ってみる。</p>
<p>あるいは家計簿。どのペルソナに対してどれだけお金を使っているかで出費のバランスを管理する。時間の使い方を振り返るときも、案外趣味の時間がすげー多いなとか気付けたりして有意義。</p>
<p>自分の場合は今のところ、生活、仕事、趣味、開発、家庭・友人、教養と6つのペルソナに分けてみている。なかなかMECEというわけにはいかないのだが、「生活」は自分自身の身の回りのこと（病気や健康、衣食住）であるのに対して「家庭・友人」は実家の事情やプライベートな友人関係の話という具合に分けていたり、仕事上必要な技術知識は「仕事」に振り分け、家で勉強している知識は「開発」に入れたりとか、そういうことをしている。</p>
<p>まぁ要するに、自分なりに状況整理できる手がかりがあれば良いのではないか、という話。</p>
]]></description>
            <link>https://chroju.dev/blog/2014-05-06-post</link>
            <guid isPermaLink="false">2014-05-06-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 05 May 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Chef soloはじめの一歩]]></title>
            <description><![CDATA[<p>Capistranoでいろいろやったので今度はChef、正確にはChef solo。サーバー立てて最初にやること（ユーザー作成、sshd_configの設定、もろもろインストールとか）はだいたい決まっていると思うので、Chefで全部コード化してしまえたらやっぱり楽だなぁという思い。なおChefとCapistranoの境界線については、システム全体をまかなうのがChefであり、Capistranoはあくまでアプリ単位のデプロイに使うイメージでいる。rbenvやRubyを入れるのはChef。/var/www/RailsApp/配下（仮）をごにょごにょするのがCapistrano。</p>
<p>参考としたのはお馴染みのアレです。ただ、すでに出版から1年近く経っているので若干事情が変わっている箇所もあったりした。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00BSPH158/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/31u6VLGX2kL._SL160_.jpg" alt="入門Chef Solo - Infrastructure as Code" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00BSPH158/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">入門Chef Solo - Infrastructure as Code</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.03.01</div></div><div class="amazlet-detail">伊藤直也 (2013-03-11)<br />売り上げランキング: 2,821<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00BSPH158/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<h2>基本構成</h2>
<p>chefの基本構成を取りあえず押さえる。</p>
<ul>
<li>chef: インフラ自動化のフレームワーク</li>
<li>chef solo: 本来クラサバ構成で扱うChefをスタンドアロンで使えるようにしたもの</li>
<li>knife-solo: リモートからchef soloの実行に必要なツール</li>
<li>Berkshelf: サードパーティクックブックの管理に使う</li>
</ul>
<h2>インストール</h2>
<p>上記のものを全部インストール。Gemfile書いてる場合はそっちに追加で。また最後に<code>rbenv rehash</code>を忘れずに。</p>
<pre><code>gem install chef -v 11.10 --no-ri --no-rdoc
gem install knife-solo --no-ri --no-rdoc
gem install berkshelf
rbenv rehash
</code></pre>
<p>ちなみにChefの最新はv11.12.xなんだけど、どうもバグがあるっぽく上手くいかなかったのでバージョン指定で古いの入れてる。</p>
<ul>
<li>参考：<a href="http://qiita.com/sakatuba@github/items/1548818b02735b2047ad">Chef 11.12.2のknife configureが失敗する - Qiita</a></li>
</ul>
<h2>セットアップ</h2>
<p>初期設定。</p>
<pre><code>knife configure # 対話は全部デフォでOK
knife solo init chef-repo # chef-repoフォルダがレポジトリとして作られる
cd chef-repo
</code></pre>
<p>chef soloを使うリモート側へもchefをインストール。</p>
<pre><code>$ knife solo prepare vagrant@192.168.1.1
</code></pre>
<h2>Berkshelf</h2>
<p>続いてBerkshelfの初期設定。</p>
<pre><code>$ berks init
</code></pre>
<p>しかし、ここでまさかのエラー。。。</p>
<pre><code>cannot load such file -- hitimes/hitimes (LoadError)
</code></pre>
<p><a href="https://github.com/copiousfreetime/hitimes/issues/17">ここ</a>によればgem updateしてからhitimesを再インストールすれば大丈夫だよ的な話。やってみる。</p>
<pre><code>$ gem update
$ gem -v
2.2.2
$ gem install hitimes
$ rbenv rehash
</code></pre>
<p>気を取り直して。</p>
<pre><code>$ berks init
The resource at '/Users/chroju/Dropbox/lab/chef/vagrant-repo/metadata.rb' does not appear to be a valid cookbook. Does it have a metadata.rb?
</code></pre>
<p>('A`)ｳﾞｧｰ</p>
<p>わけわからんし、<code>berks init</code>しなくてもBerkfile自前で作りゃイケるらしいので諦めることにする。Berksfileを<code>touch</code>してからvimで編集。</p>
<pre><code>site :opscode

cookbook 'sudo'
cookbook 'iptables`
</code></pre>
<p>Gemfileと似たような書き方で、<code>cookbook 'hoge'</code>と書くとそのクックブックが<a href="http://community.opscode.com/">Opscode</a>からインストールされる。Opscode以外のGitHubで公開されているクックブックを使う場合は、これもGemfileのように<code>cookbook 'fuga' git:"..."</code>の形でURL指定が可能。</p>
<p>そしていざインストール……だがまたしてもエラー。</p>
<pre><code>$ berks install --path cookbooks
DEPRECATED: `berks install --path [PATH}` has been replaced by `berks vendor`.
DEPRECATED: Re-run your command as `berks vendor [PATH]` or see `berks help vendor`.
</code></pre>
<p>そろそろこのあたりから笑えてきた。調べたところ、Berkshelf v3.xでは<code>berks install --path hoge</code>は使えないらしいス。<code>berks vendor hoge</code>が今どきらしい。</p>
<pre><code>$ berks vendor cookbooks
destination already exists /Users/chroju/Dropbox/lab/chef/vagrant-repo/cookbooks. Delete it and try again or use a different filepath.
</code></pre>
<p>えー。</p>
<pre><code>$ rm -rf cookbooks
$ berks vendor cookbooks

DEPRECATED: Your Berksfile contains a site location pointing to the Opscode Community Site (site :opscode). Site locations have been replaced by the source location. Change this to: 'source "http://api.berkshelf.com"' to remove this warning. For more information visit https://github.com/berkshelf/berkshelf/wiki/deprecated-locations
Resolving cookbook dependencies...
Using iptables (0.13.2)
Using sudo (2.5.2)
# 以下略
</code></pre>
<p>文句言いながらもやってくれました。冒頭の1行目の書き方は<code>site :opscode</code>というのが通例だったけど、v2.0から<code>source "https://api.berkshelf.com"</code>に変わった模様。ただ、コマンドは通るには通るんだけど。</p>
<p>最初に<code>berks vendor cookbooks</code>したときに出たエラー、要は「すでにあるフォルダにはインストールできねーよ」って話なのだが、だとしたらBerksfileを書き換えて追加インストールしたいときはどうしたらいいんだろう？というのは素朴な疑問。サードパーティのクックブックは直接編集しない（変数などは自分のレシピの方で代入する）のが基本らしいので、一度フォルダを消してから再度<code>berks vendro cookbooks</code>でも不都合はないと言えばないのだが、なんだか馬鹿らしい感じもする。</p>
<p>あと<code>berks install</code>コマンドもあるんだけど使い方わかってない。</p>
<h2>レシピ作成</h2>
<p>その前におさえる基本。</p>
<ul>
<li>nodes/hostname.json : 実行するレシピをrun_listとして記述</li>
<li>solo.rb : chefが利用する各種パスの設定ファイル（knife soloの場合は生成されない）</li>
<li>cookbooks/hoge/recipes/default.rb : レシピ本体</li>
<li>cookbooks/hoge/templates/default/* : テンプレートファイル</li>
<li>cookbooks/hoge/files/* : 静的ファイル</li>
<li>cookbooks/hoge/attributes/* : 変数の格納</li>
</ul>
<p>あとcookbooksフォルダはサードパーティ製のものを入れて、自家製のクックブックはsite-cookbooksフォルダに入れるっていうルールもある。名前がわかりにくいが。</p>
<p>このへん押さえつつ、次回はレシピ作成編です。</p>
]]></description>
            <link>https://chroju.dev/blog/2014-05-06-02-post</link>
            <guid isPermaLink="false">2014-05-06-02-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 05 May 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[エンジニアの転職において「技術」とは目的か手段か]]></title>
            <description><![CDATA[<p><a title="By 江戸村のとくぞう (投稿者自身による作品) [CC-BY-SA-3.0 (http://creativecommons.org/licenses/by-sa/3.0)], via Wikimedia Commons" href="http://commons.wikimedia.org/wiki/File%3A%E6%B8%8B%E8%B0%B7%E3%83%92%E3%82%AB%E3%83%AA%E3%82%A8%E3%83%BC%EF%BC%92.JPG"><img width="512" alt="渋谷ヒカリエー２" src="//upload.wikimedia.org/wikipedia/commons/thumb/7/76/%E6%B8%8B%E8%B0%B7%E3%83%92%E3%82%AB%E3%83%AA%E3%82%A8%E3%83%BC%EF%BC%92.JPG/512px-%E6%B8%8B%E8%B0%B7%E3%83%92%E3%82%AB%E3%83%AA%E3%82%A8%E3%83%BC%EF%BC%92.JPG"/></a></p>
<p>ヒカリエ綺麗すぎる。。。</p>
<p>えー。<a href="http://connpass.com/event/5766/">こちらのイベント</a>に参加してきました。こういう社外での勉強会チックなものに参加するって初めてですげービビってたけどわりと楽しめた。</p>
<p>登壇者の方はSIerを経てWeb系に行かれたということでしたけど、その理由が「コードを書けないことへの危機感」だとか「3.11を目の当たりにして、やりたいことやっとかないといつ死ぬかわからん」みたいな話だったのはだいぶ自分とも似ている点でした。というかSIerを脱出して別のIT系に転職する人って2パターンあって、1つがこのように「より技術的なスキルアップをしたい」という人、もう1つが「ユーザー企業の側に行ってみたい」という人。少なくとも自分の周囲を見回しているとそういう感じで、比較的安定的でよく狙われてるのは後者なのかなという印象を持っています。ただ、最近のトレンドとして手に職をつけるじゃないですけど、自分で出来ることの幅を増やしたいという人は多い気もしている。イベント後の懇親会で話していてもそんな感じでした。</p>
<p>自分としても技術的な危機感というのはあって、だからこそのこのブログなのだけど、最近より強く感じているのは「長期的な目的なしに転職したくない」ということ。</p>
<p>突然の話になりますが、自分は今のインターネットを巡るこの国の状況って実にダサいなと思ってます。光回線はだいぶ普及したし、ポケットに入るコンピュータを誰もが持ち歩いているし、Wi-Fiサービスだってそこここにある。確かにインフラ面では多大なる普及を終えているんだけど、じゃあそれを使ってみんな何をしてるの？というと、今ってソシャゲで金銭巻き上げられたりSNS疲れが社会問題化したり、あるいは歩きスマホしてて階段から落ちて死ぬみたいな感じじゃないかと。なんてーか、まだ十分に社会が、ソフトウェアの方がインフラの状況に追いついていないように思うのですよ。ネットを通じて社会を良くしよう！みたいな話がよくあるけど、その前にネット自体を何とかしないとヤバくね？ってのが自分の実感です。</p>
<p>だからキャリアプランとしては、そういう方面に進んでいきたい。ITと社会がうまく調和していくような、そういう動きを促せるような働きかけをしていきたいという思いが強くある。となると、自分の手で技術的なこと出来るか？ってのは二の次になるんですよね。手段と目的の違いです。もちろん、今挙げた「目的」を達するために技術力という「手段」を使えれば自分にとって最も望む結果だと思うし、その方向ってのは目指したいと思ってる。ただ、じゃあ実際どういう職種がその方向の先にあるんだろうってのがあまり具体化できてなくて。考えたのはUIデザインとかは少し近いなと思うんですけど、あまりしっくりはきていない。むしろ法整備したりだとか、あるいはMIAUのやっているようなことが自分の目的には近いのだけど、そうなると技術者じゃなくて良くなっちゃうなぁってのもあって悩ましい。</p>
<p>世の「技術やりたい！」というエンジニアのみなさんは、もうそれ自体が目的化しているのか、それとも技術を通して実現したい目的が別にあるのか、というのは大変に気になるところです。今日聞けばよかったかな。まあ、もうちょっといろいろ考えてみます。</p>
]]></description>
            <link>https://chroju.dev/blog/2014-05-01-post</link>
            <guid isPermaLink="false">2014-05-01-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 30 Apr 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Capistrano3を最後にもう一度だけ懇切丁寧にまとめてみる]]></title>
            <description><![CDATA[<p>いろいろエントリーを上げながら苦しんでいたCapistranoだが、ようやっとそこそこ落ち着いてきた気がするのでそろそろ完結編といく。Capistranoの基本とかはすでに<a href="http://chroju89.hatenablog.jp/entry/2014/02/20/000348">こちら</a>のエントリーで書いたので、今回は各設定ファイルの書き方とか、その他ハマったポイントを中心に。</p>
<h2>今回作成したファイル</h2>
<p>以下4ファイルを作成した。</p>
<ul>
<li>Capfile</li>
<li>config/deploy.rb</li>
<li>config/deploy/staging.rb</li>
<li>lib/capistrano/tasks/unicorn.cap</li>
</ul>
<p>基本的にCapistranoを使う場合「必須」なのは上2つのファイル。<code>deploy/hoge.rb</code>も確実に必要にはなるが、デプロイ先の環境が本番なのかステージングなのかでproduction.rbとstaging.rbを使い分けることになる。もちろん、ステージング環境を用意していない場合はstaging.rbは不要。また4つ目のファイルだが、自分の場合はunicornをデプロイ先で使っているので、デプロイ後にunicornを再起動する目的で独自タスクを作成している。説明が遅れたが、今回デプロイ先となる環境は大雑把に以下の通り。</p>
<ul>
<li>Vagrant 1.4.3</li>
<li>CentOS 6.4</li>
<li>Postgresql 9.1</li>
<li>Ruby 1.9.3(rbenv)</li>
<li>Nginx + unicorn</li>
<li>位置付けはステージング環境</li>
</ul>
<h2>Capfile</h2>
<script src="https://gist.github.com/10530780.js"></script>
<p>ここはだいたい環境を問わず同じになってくる箇所。まず<code>capistrano/setup</code>と<code>capistrano/deploy</code>は<code>require</code>が必須。RailsをCapistranoで扱う場合は、<code>capistrano/bundler</code>から<code>capistrano/rails/assets</code>までも必須となる。rbenvを使っている場合は<code>capistrano/rbenv</code>が必要。rbenvをどこにインストールしたのかにより、<code>set :rbenv_type</code>を指定する。あとはデプロイするアプリケーションで使うRubyのバージョンも指定してやる。rvmを使う場合も似たような<code>capistrano/rvm</code>を使うみたいだが、そちらはよくわからんので割愛。</p>
<p>で、ここまでがrequireということなので、デプロイ元サーバーにGemfile書いてインストールしておくことを忘れずに。</p>
<pre><code>group :development do
  gem 'capistrano', '~> 3.1.0', :require => false
  gem 'capistrano-rails', '~> 1.0.0', :require => false
    gem 'capistrano-rbenv', '~> 2.0', :require => false
  gem 'capistrano-bundler', '~> 1.1.2', :require => false
end
</code></pre>
<p>最終行は独自カスタムタスクを読み込むための行。デフォルトで入っているのでそのままにしておけばよい。先のunicorn.capのように、何か独自タスクを作った場合はこのパスに入れれば読み込むよーということでもある。</p>
<p>なお、以前書いたエントリーでは<code>capistrano3/unicorn</code>も<code>require</code>していたのだが、これは撤回した。詳細はunicorn.capについて説明するときに後述。</p>
<h2>staging.rb</h2>
<script src="https://gist.github.com/10530945.js"></script>
<p>ステージング環境、というかデプロイ先環境の設定を書く。vagrantを使う場合はだいたいこれと同じように書いておけば通るんじゃないかと思う。Vagrantはデフォルトではvagrantユーザーによるsshが可能になっているので、それをそのまま使わせてもらっている。何か他のユーザーで入りたい場合などは頑張るしかない。</p>
<p>一点だけ注意すべきは、<code>RAILS_ENV</code>がstagingに設定されるということ。Capistrano3では<code>cap install</code>を叩くとデフォルトでstaging.rbとproduction.rbが作られ、<code>RAILS_ENV</code>もこのファイル名に倣うことになるのだが、Railsの動作環境は通常test, development, productionの3種類であり、stagingは存在していない。従ってこのままデプロイを始めてもうまくはいかない。面倒であればstaging.rbは使わず、production.rbだけを使っていてもいいかもしれない。</p>
<p>staging.rbを使う場合は、Rails側で環境の準備が必要になる。やることは大きく3つ。</p>
<h3>1. database.ymlにstagingを作成する</h3>
<p><code>rake db:migrate</code>などのDB系のコマンドはi<code>RAILS_ENV</code>を指定して実行される。ここで指定された<code>RAILS_ENV</code>をdatabase.ymlに見に行くので、設定を入れておく必要がある。ステージング環境の本来の意味を考えると、production用の記述をそのままコピーするだけで良いはず。</p>
<h3>2. config/environments/staging.rbを作成する</h3>
<p>動作環境設定ファイルとして、デフォルトではproduction.rbとdevelopment.rbだけが用意されているので、これもproduction.rbをコピーしてstaging.rbを作る。</p>
<h3>3. Gemfileにgroup :stagingを作成する</h3>
<p>これは<code>RAILS_ENV</code>と直結するわけではないが、GemfileのグループもRails環境ごとに作られているのでstagingを設けてやった方が良さそう。これもここまでと同様の話で、<code>group :staging, :production do</code>としてやるだけで良い。</p>
<ul>
<li>参考：<a href="http://spring-mt.tumblr.com/post/33209507135/rails-staging">railsでstaging環境を作る - CubicLouve</a></li>
</ul>
<h2>deploy.rb</h2>
<script src="https://gist.github.com/10530987.js"></script>
<p>いよいよデプロイ用の設定。面倒なので説明は省くが、だいたいはコメント読めば設定できるはず。</p>
<p><code>linked_files</code>と<code>linked_dirs</code>は<a href="http://chroju89.hatenablog.jp/entry/2014/04/06/191336">前回のエントリー</a>で書いた通り、shared配下に置いているファイルやフォルダのうち、currentに必要となるものを指定することでシンボリックリンクを張ってくれるというものなのだが、ではshared配下にこれらファイルやフォルダはいつ作られるのか？というのがかねてから疑問だった。</p>
<p>結論を言えば、<code>linked_files</code>は勝手には作成されない。というより、ここに指定したファイルがshared下に存在しない場合、Capistranoはデプロイ時にエラーを吐いてくる。正確に言えば<code>deploy:check:linked_files</code>というタスクがあり、ここで存在確認を行っている（<a href="https://github.com/capistrano/capistrano/blob/master/lib/capistrano/tasks/deploy.rake">参照</a>）。したがってこのタスクが投げられる前にファイルは別でアップロードしなくてはならない。ここではdetabase.ymlを指定しているので、アップロードタスクを独自で組み込んでいる。詳細は後述。</p>
<p>一方の<code>linked_dirs</code>は、shared配下に存在しない場合は<code>deploy:check:make_linked_dirs</code>で空っぽのフォルダとして作成してくれる。逆に言えば、元々ファイルが入っているようなフォルダをここで指定することはあまりないということ。例えばbundleなり、logやtmpなり、アプリが動作する中で必要とされるフォルダ（従ってGitHubで静的に管理はしていないフォルダ）がここに来ている。なお、shared/bundleは<code>capistrano/bundle</code>が<code>bundle install --path</code>で指定するデフォルトのフォルダなんだそうだが、古いバージョンの<code>capistrano/bundle</code>ではshared/vendor/bundleにインストールするらしいので要確認。</p>
<p>後半では独自タスクを3つ追加している。</p>
<p>1つ目はdatabase.ymlをアップロードするタスク。デプロイ先にshared/configフォルダを作成した上で、ローカルのconfig/database.ymlをアップロードしている。2つ目は<code>bundle exec rake db:create</code>を発動するタスク。Capistranoやcapistrano/railsにはDB作成用のタスクは一切含まれていないので、自力であらかじめ作っておく必要がある。手動で作成したり、Chefなんかで仕込んでおく手もあるのだろうが、ここではCapistranoのタスクとして書いている。必要になるのはもちろん初回1回限りなので、デプロイのルーチンの中には組み込んでいない。</p>
<ul>
<li>参照：<a href="http://yss44.hatenablog.com/entry/2013/12/01/150215">Capistrano3で快適デプロイ生活!! - Less is Best</a></li>
</ul>
<p>3つ目はunicornを再起動するタスク。これはunicorn.capの中で作成した<code>unicorn:restart</code>というタスクを呼んでいる。</p>
<p>最後の2行は独自タスクのルーチンへの組み込み。database.ymlのアップロードは真っ先にやらなくてはならないので、<code>deploy:starting</code>というデフォルトで言えば最初のタスクのさらに前に組み入れている。一方のunicorn再起動は<code>deploy:publishing</code>の後、ほぼすべてのタスクが終わったタイミング。</p>
<h2>unicorn.cap</h2>
<script src="https://gist.github.com/10531064.js"></script>
<p>ほぼほぼ以下エントリーの中身をそのまま使わせてもらいました。</p>
<ul>
<li>参照：<a href="http://qiita.com/satococoa/items/9b0cc416ffc042680b9b">unicorn + rails 用 Capistrano 3 の設定ファイル - Qiita</a></li>
</ul>
<p>異なる箇所は<code>start_unicorn</code>の内部処理。元エントリーでは<code>bundle exec unicorn</code>を叩いているのだが、自分としては<code>bundle exec unicorn_rails</code>を叩く認識だったので書き換えている。ここの書き換えが必要なのかどうかはちょっと自信がない。またコマンドのオプションとして<code>--path hoge</code>を指定しているのだが、これはサブディレクトリでRailsアプリを動作させたいため。予定として<a href="http://www.chroju.net/">http://www.chroju.net/</a>は静的なサイト、www.chroju.net/hogeでアプリごとにフォルダ作って管理としたかったもので。まー、こういう要らんチューニングを最初からやろうとするから迷走するわけなのだが。はじめはマニュアル通りにまず写経すべきだと思います。はい。サブディレクトリ云々の件はまた別途エントリー書きます。</p>
<p>ちなみにパスの指定やら何やらやらないのであれば、<a href="https://github.com/tablexi/capistrano3-unicorn">capistrano3-unicorn</a>を使うのも手だと思う。</p>
<h2>その他トラブルなど</h2>
<p>以上、ここまでの設定にはそれなりに自信がある。とりあえず<code>bundle exec cap staging deploy</code>を叩いてエラーが出ないことも確認はした。が、現状アプリは動いてない。。。いや、正確に言うと一度動いたのだが、その後Vagrant落として、セキュリティアップデートのためにiMacも再起動してもう一度やってみたところ、ダメダメになってしまったのだ。何が原因なのやらさっぱりだ。。。トラブルは3つほど遭遇している。</p>
<h3>1. Gitが通らない</h3>
<p><code>git ls-remote</code>で<code>Permission denid(publickey)</code>のエラーが出るという事象が発生、その先に進めなくなった。これについてはドンピシャなエントリーを探し当てたので、そのまま解決策を適用したらなんとかなった。なぜこのエラーが起きたのかまではまだ深堀りできてない。</p>
<ul>
<li>参考：<a href="http://peteoliveira.com/deploying-with-capistrano-3-failing-permission-denied-publickey/">Deploying with Capistrano 3 failing – Permission denied (publickey) | Pete Oliveira</a></li>
</ul>
<h3>2. 404が返される</h3>
<p>Nginxは動いている。unicornもプロセスは上がっているのだが、アプリを配置したフォルダを見に行くとThe page you were looking for doesn't exist.というメッセージが返される状態。他の有りもしないフォルダを見に行こうとするとNginxがBad Gatewayを返してくるし、unicorn.stderr.rbにログが残っているのでアクセスはできているようなのだが、なぜ表示に至らないのかわからない。</p>
<p>ちなみにstaging.logにはActionController::RoutingErrorが出ている。？？？</p>
<h3>3. Assets周りが不具合起こしている模様</h3>
<p>Vagrantを落とす前はアプリ自体つながりはしたのだが、jsとcssが反映されていない状態だった。ソースから探ってjsとcssをブラウザ上で開いてみたのだが、真っ白になっていた。アセットコンパイルのエラーなのかと思い、サーバー上でもコンパイル後のファイルを開いたりしてみたが、こっちは中身がきちんと書かれていた。なんなんだ一体。</p>
<p>以上。だいたい整ったはずなのだが、まだまだ先が長そうでいい加減ゲンナリしている。自分、この手のこと向いてないのかもしれんと思い始めた。。。</p>
]]></description>
            <link>https://chroju.dev/blog/2014-04-12-post</link>
            <guid isPermaLink="false">2014-04-12-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 11 Apr 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Capistrano3がわからんので今一度イチから考えなおしてみる]]></title>
            <description><![CDATA[<p>前回Capistranoが上手くいかないというエントリーを上げてから1か月。いまだにハマってしまっている……。何が悪いの皆目検討もつかない、というほどではないのだが、なんというか、雲を掴んでいるような状態ではある。一旦Capistranoについて整理してみるべきなんだろう。</p>
<h2>Capistranoは何をしてくれるのか</h2>
<p>そもそもCapistranoとは何をしてくれるツールなのか？</p>
<p><a href="http://qiita.com/yuku_t/items/01c0ec4389db143e27f5">Capistrano3のデプロイフレームワークの使い方 - Qiita</a></p>
<p>Capistranoは2まではRailsのデプロイツールだったけど、3は汎用的なデプロイツールに変わっている。したがってデフォルトの状態ではRails用のデプロイタスクは特に含まれていない。このあたりが上の方のリンク先で語られている内容になる。</p>
<p>ではデフォルトでのデプロイタスクは何をするのかと言えば、およそサーバーへのデプロイとして一般的に行われるようなものが組み込まれている。<a href="https://github.com/capistrano/capistrano/tree/master/lib/capistrano/tasks">capistrano/lib/capistrano/tasks</a>あたりを探るとデフォルトタスクがよくわかる。</p>
<ul>
<li>releases、sharedなどディレクトリの作成</li>
<li>レポジトリからgit clone</li>
<li>linked_files、linked_dirsの存在確認とシンボリックリンク作成</li>
<li>currentディレクトリへのシンボリックリンク作成</li>
<li>最古世代の削除、クリーンナップ</li>
</ul>
<p>ざっくり見てしまうと、単純にサーバーへファイルを上げて自動的に世代管理をさせるだけであればこれだけでもなんとかなりそうなところではある。逆にこれらが煩わしいのであれば、<a href="http://labs.gree.jp/blog/2013/12/10084/">デフォルトタスクを無効化して使う手もある。</a>デフォルトタスクの内容がよくわからないのであれば、一旦無効化してすべて自分でタスクを書くというのも手だと思う。</p>
<p>Railsをデプロイする場合はこれだけでは足りないので、capistrano/railsやcapistrano/bundleを追加で読み込むことになる。</p>
<h2>Capistranoのディレクトリ構成</h2>
<p>Capistranoでデフォルトのデプロイを行った時、デプロイ先サーバーに作成されるディレクトリについてもよくわかってないのでまとめておく。deploy.rbのdeploy_toで指定したディレクトリ内に、次の3つのディレクトリが作られる。</p>
<ul>
<li>releases : デプロイした内容を世代管理する</li>
<li>shared : bundleとかdatabase.ymlとかGitで管理してないファイル置き場（多分）</li>
<li>current : releasesの最新世代とsharedのシンボリックリンクが置かれる</li>
</ul>
<p>基本的に「デプロイ」される先はreleasesだ。releases配下にはデプロイ時のタイムスタンプから生成された名前のフォルダが作られ、その中にごっそりデプロイしたファイルが入っている。タイムスタンプが付くということは当然世代管理されているわけだが、保持される世代数はdeploy.rbの<code>set :keep_releases</code>で好きに指定できる。で、最新世代についてはcurrent配下にシンボリックリンクが自動的に貼られる。</p>
<p>sharedは正直よくわからない。デプロイのたびに更新するわけではない、すなわちGitで管理をしていないファイルやディレクトリを置いておくみたいなのだが、では<strong>どうやって配置すれば良いのか？</strong>がわからない。配置したファイルのうち、必要なものについてはlinked_dirsとlinked_filesで指定すればcurrent配下にこれもまたシンボリックリンクが貼られる。しかし、<strong>どうやって配置すれば良いのかわからない。</strong></p>
<p>関連：<a href="http://qiita.com/shunsugai@github/items/a112182ff5c0bb49249a">[自分用メモ]Capistrano3のlinked_filesって自分でuploadしなきゃダメですか？ - Qiita</a></p>
<p>で、これを書いていて気付いたのだが、アプリの中身がcurrent配下に展開されるということは、ウェブサーバーの設定もdeploy_toではなくてcurrentに飛ばすようにしておかないといけないわけだ。俺だけかも知れんが、案外罠ではないかという気がする。</p>
<h2>capistrano/rails</h2>
<p>取りあえずsharedの話はほっといて、Railsをデプロイする話に戻る。冒頭でデフォルトタスクにはRailsに対するものは何もないと書いたが、それではRails用のデプロイタスクはどこで生成されているのか？ 答えから書けば、capistrano-railsを読み込むことによって初めて生成される。</p>
<p><a href="http://qiita.com/yuku_t/items/78f32d6e5d21aee4e745">Capistrano3におけるRailsのデプロイタスクの内部実装 - Qiita</a>
いわく、追加されるタスクは主に3つ。</p>
<ul>
<li>assets compile(deploy:compile_assets)</li>
<li>assetsのタイムスタンプ更新(deploy:normalize_assets)</li>
<li>db:migrate(deploy:migrate)</li>
</ul>
<p>逆に言えば、ここで追加される以外のタスクはデフォルトでは<strong>行われない</strong>ということになる。その点を配慮せずにただググって適当なdeploy.rbをコピーしたりしただけでは、思ったとおりのデプロイは出来ない。</p>
<p>一例として自分がハマったのが、<code>db:create</code>は行われないということ。schema.rbを使って初回デプロイのときに上手いこと云々なんてことは一切してくれないので、このあたりは自分で書くか、サーバーを作ったときに予めDBをこしらえておく必要がある。</p>
<h2>capistrano/bundle</h2>
<p>もうひとつ、RailsをCapistranoでデプロイする場合に必要なのがcapistrano/bundler。Rails使っててGemfileがないなんてことはないだろうし、というかcapistrano/railsの中で<a href="https://github.com/capistrano/rails/blob/master/lib/capistrano/rails.rb">明示的にrequireされている。</a>何をやっているのかと言えば、簡単な話しである。</p>
<pre><code>  before 'deploy:updated', 'bundler:install'
</code></pre>
<p>デフォルトではshared配下にbundleディレクトリを作ってbundle installをかけてくれる。パスについては<code>set :bundle_path</code>オプションで自由に指定ができる。</p>
<h2>capistrano/rbenv</h2>
<p>あとよく使われるものとして、capistrano/rbenvがある。デプロイ先のサーバーで、Rubyをrbenvを使って入れてる場合には必須になるもの。中身はよく知らないが、そこまで気にしなくても良いのではないかという感覚がある。入れたらdeploy.rbに<code>set :rbenv_ruby_version</code>で使うRubyのバージョンを指定すればOK。</p>
<p>同じ類のものとして、capistrano/rvmももちろんあります。</p>
<h2>ソースにあたることの必要性</h2>
<p>以上がCapistrano3でRailsをデプロイする場合の主なデフォルトタスクの内容になる。繰り返しになるが、これ以外に何をやりたいのならタスクは書く必要がある。よく言われるのがデプロイ後のウェブサーバーの再起動で、unicornを再起動するタスクを追加している例はよく見かける。ただ、これも<a href="https://github.com/tablexi/capistrano3-unicorn">capistrano3-unicorn</a>という便利なものがすでに作られていたりはする。</p>
<p>個人的な思いなのだが、<a href="http://capistranorb.com/">Capistrano公式</a>の「Getting Started」は説明が不十分な気がしてならない。デプロイに至るまでの設定ファイルの書き方やら何やらは確かにだいたい載っているのだが、ではCapistrano3の内部実装がどうなっているのかとか、タスクを自分で書くにはどうすればよいのかといったあたりの情報が足りない。自分はまだこのDSLを読み下せないのだが、rakeあたりを知っていると結構書けるものなんだろうか？　ひょっとしたら、自分のようなRubyやRails初心者が安易に手を出すものではないのかなぁとか思う。</p>
<p>ただ、GitHubにいずれもソースが上がっているので、根気よく読んでいけばCapistranoが何をしているのか、また何を求めているのかは理解できる。誰かの書いたノウハウに頼るより、ソースにあたるのが大切なのは基本だと思う。常に。</p>
]]></description>
            <link>https://chroju.dev/blog/2014-04-06-post</link>
            <guid isPermaLink="false">2014-04-06-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 05 Apr 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Rails環境構築（5）Capistranoによるデプロイ ※未完]]></title>
            <description><![CDATA[<p>だいぶ間が空いてしまった……。Rails環境構築シリーズ、あとサーバーにはDB（postgresql）、unicorn、Railsを入れれば終わりなのだが、いずれもアプリ側のGemfileを使ってローカルにインストールするつもりなので、まずはアプリのデプロイが必要となる。そしてRailsのデプロイといえばCapistranoだ！と、いきたいところだったのだが。</p>
<p>Capistrano 3.0を試しているのだが、どうにもハマっている。ハマっているというのはのめり込んで楽しくなっちゃった的な意味ではなく、上手くいかずにっちもさっちもいかない的な意味である。とりあえず頭からやり方おさらいしつつ、ハマった箇所をまとめてみたい。</p>
<p>3.0についてはまだ登場してから時間も経ってないためか、日本語で有益な記事は少ない。が、まずは<a href="http://capistranorb.com/">本家</a>をよく読むこと推奨。一応これに則れば出来るようになっているはずではある。他に個人の方がまとめたハウツーで参考になったのは以下の記事。すでに2.0を使っている人ならよりわかりやすいのだろうが、これがCapistrano初体験となる自分にはちょっとわかりにくかったりも、した。特に3番目の記事は完全に2.0からの移行組に向けて書かれた内容。</p>
<ul>
<li><a href="http://threetreeslight.com/post/68344998681/capistrano-3-x-rails">capistrano 3.x系を使ってrailsをデプロイ | iii ThreeTreesLight</a></li>
<li><a href="http://labs.gree.jp/blog/2013/12/10084/">入門 Capistrano 3 ~ 全ての手作業を生まれる前に消し去りたい | GREE Engineers' Blog</a></li>
<li><a href="http://takkkun.hatenablog.com/entry/2013/10/12/Capistrano_3%E3%81%B8%E3%81%AE%E6%89%8B%E5%BC%95%E3%81%8D">Capistrano 3への手引き - 今日のごはんは素麺です</a></li>
<li><a href="http://d.hatena.ne.jp/ria10/20130526/1369583203">capistranoでステージングとか本番環境とか使い分ける - リア充爆発日記</a></li>
<li><a href="http://kakakakakku.hatenablog.com/entry/2013/12/11/090204">Capistrano3 で Vagrant で構築したVMにデプロイする - kakakakakku blog</a></li>
</ul>
<h2>Capistranoとは？</h2>
<p>そもそも論。開発完了したアプリをサーバーにデプロイするときの手順をRubyで書いて自動化しておくためのもの。デプロイ先はステージング環境とか本番環境とか何種類か存在する場合もあるが、環境ごとにデプロイ手順は別々に設定したりできる。なお、Rails用のツールだと思われがちだが、3.0からRails以外でも使える汎用的なツールになったらしい。自分の場合はRailsで使っているのであしからず。あと、SCMはGitを使っている必要がある。</p>
<h2>インストール</h2>
<p>インストールはGemで行う。デプロイ予定のRailsアプリで、Gemfileに以下追記してbundle install。</p>
<pre><code>group :development do
  gem 'capistrano', '~> 3.1.0'
  gem 'capistrano-rails', '~> 1.0.0'
  gem 'capistrano-bundler', '~> 1.1.2'
end
</code></pre>
<p>capistranoが本体。先の本家によれば、Railsで使う場合はcapistrano-railsも必要になるとのこと。他にもいろいろ便利なプラギンがあったりするっぽいけど、わかんないので今はここまで。</p>
<h2>初期作業</h2>
<pre><code>$ bundle exec cap install
</code></pre>
<p>初期ファイルの生成。手元の本にはcapify .コマンドだと載っていたのだが、capistrano 3.0から変わったらしい。ほあ。これによりCapfileと、config配下にdeploy.rb、さらにconfig/deploy配下にproduction.rbとstaging.rbが作成される。それぞれの役割は次の通り。</p>
<ul>
<li>Capfile : 他のGem（capistrano-railsとか）の読み込みなどを記述</li>
<li>config/deploy.rb : デプロイタスクを記述</li>
<li>config/deploy/hoge.rb : 各サーバー情報を記述</li>
</ul>
<h2>Capfile編集</h2>
<p>capistrano-railsと同bundlerを読み込むため、Capfileを開いて以下追記。</p>
<pre><code>require 'capistrano/rails'
require 'capistrano/bundler'
</code></pre>
<h2>config/deploy.rb編集</h2>
<p>いろいろコメントアウトしてあってどれを使えばいいかよくわかんなかったりもするのだが、最低限以下は必要っぽい。</p>
<pre><code>set &#x3C;span class="synConstant">:application&#x3C;/span>, &#x3C;span class="synSpecial">'&#x3C;/span>&#x3C;span class="synConstant">hoge&#x3C;/span>&#x3C;span class="synSpecial">'&#x3C;/span>
set &#x3C;span class="synConstant">:repo_url&#x3C;/span>, &#x3C;span class="synSpecial">'&#x3C;/span>&#x3C;span class="synConstant">git@github.com:chroju/hoge&#x3C;/span>&#x3C;span class="synSpecial">'&#x3C;/span>
set &#x3C;span class="synConstant">:deploy_to&#x3C;/span>, &#x3C;span class="synSpecial">'&#x3C;/span>&#x3C;span class="synConstant">/var/www/hoge&#x3C;/span>&#x3C;span class="synSpecial">'&#x3C;/span>
set &#x3C;span class="synConstant">:scm&#x3C;/span>, &#x3C;span class="synConstant">:git&#x3C;/span>

</code></pre>
<p>上から。1行目はアプリケーション名。これはどこかで使われる設定ではないようなので、適当に入れておけばよさそう。2行目はGithubのリポジトリURL。3行目はデプロイ先となるサーバー上のディレクトリパス指定。ここではApacheの設定にならってみた。4行目は使用しているSCMの指定。とはいえ、現状Gitしか対応していないのでこれ以外の書き方は不可。</p>
<p>ファイル後半にはデプロイタスクのデフォルト設定が書かれている。一応、ここはそのままでも動くみたい。自分で何か特別なことをやらせたい場合は当然ながら編集する必要があるが、まだその域に至ってないです。</p>
<h2>config/deploy/hoge.rb編集</h2>
<p>ここではステージング環境としてvagrantを使うものと仮定。WebサーバーやDBサーバーを分けたりはせず、1台のサーバーですべてをまかなうこととする。よってstaging.rbを編集する。このファイルもデフォルトでいろいろ書かれてはいるのだが、とりあえず次の4行があればOK。</p>
<pre><code>server &#x3C;span class="synSpecial">'&#x3C;/span>&#x3C;span class="synConstant">127.0.0.1&#x3C;/span>&#x3C;span class="synSpecial">'&#x3C;/span>, port: &#x3C;span class="synConstant">2222&#x3C;/span>, user: &#x3C;span class="synSpecial">'&#x3C;/span>&#x3C;span class="synConstant">vagrant&#x3C;/span>&#x3C;span class="synSpecial">'&#x3C;/span>, roles: &#x3C;span class="synSpecial">%w{&#x3C;/span>&#x3C;span class="synConstant">web, app, db&#x3C;/span>&#x3C;span class="synSpecial">}&#x3C;/span>, ssh_options: {
  user: &#x3C;span class="synSpecial">'&#x3C;/span>&#x3C;span class="synConstant">vagrant&#x3C;/span>&#x3C;span class="synSpecial">'&#x3C;/span>,
  keys: &#x3C;span class="synSpecial">%w(&#x3C;/span>&#x3C;span class="synConstant">~/.vagrant.d/insecure_private_key&#x3C;/span>&#x3C;span class="synSpecial">)&#x3C;/span>,
  auth_methods: &#x3C;span class="synSpecial">%w(&#x3C;/span>&#x3C;span class="synConstant">publickey&#x3C;/span>&#x3C;span class="synSpecial">)&#x3C;/span>
}

</code></pre>
<p>server〜で1台のサーバーの設定を一括で書ける。言わずもがな、まず対象IP。portがポート番号、userがSSHログインするユーザー名。roleはこのサーバーの役割を書く。web、app、dbの中から当てはまるものを書けばいいようだが、allという指定もできるとかできないとか。ssh_options:でさらに詳しい内容を記述。userはさっきのと被ってるので不要な気がするのだが、他のサイトを見てたら書いている設定があったので取りあえず入れてる。keysは認証に使うキーのパス。auth_methods:で認証方法を指定しているが、通例publickey認証とする。
ここに書いた設定の大半はvagrant ssh-configコマンドで拾えるので、自分の環境に合った設定に書き換えて下さい。</p>
<h2>デプロイ実行</h2>
<p>で、あとはデプロイでいけちゃうみたいです。</p>
<pre><code>bundle exec staging deploy
</code></pre>
<p>stagingをproductionに換えればproduction.rbの設定に則ります。あと、末尾に:checkを付けるとコマンドが通るかコールドでチェックしてくれるので、まずは:checkをした方がいい。あと、cap -Tで実行可能なコマンドがずらずら出てくる。デプロイのロールバックしたり、rake db:migrateを走らせたり、結構いろんなことができるので一度見ておくと吉。</p>
<h2>ハマった点</h2>
<p>自分の場合は以上の手順で上手くいきませんでした。何点かハマったポイントをば。</p>
<h3>デプロイ先ディレクトリのパーミッション</h3>
<p>大変アホみたいな話だが最初これでmkdirが上手くいかなかった。公式ドキュメントの<a href="http://capistranorb.com/documentation/getting-started/authentication-and-authorisation/">ココ</a>に書いてあるけど、SSHユーザーはsudoなしでデプロイ先ディレクトリを操作できる権限がなきゃダメです。vagrantユーザーは~/var配下の操作権限なかったので弾かれた次第。。。</p>
<p>対応としてはさっきのリンク先に書いてある手順通り<a href="http://itpro.nikkeibp.co.jp/article/COLUMN/20080219/294154/">sgid</a>の設定とかしてあげたらなんとかなりました。あるいはパスワードなしでsudo実行可能にしてやっても動くみたいだけど、当然ながらサーバーセキュリティ的にはNGなので。まぁvagrantであればどうでもいいかもしんないけど。</p>
<h3>SQLiteのエラー</h3>
<p>deploy中にsqlite3.hが存在しないよというエラーが発生。<a href="http://www.guanxiaohua2k6.com/2012/07/sqlite3h-is-missing.html">このページ</a>に書いてあるのとまったく同じ症例だったので、同様の対策をしてあげて解決。これは俺のvagrant環境の準備に不備があったってことでいいんだろうか。根本原因がイマイチ謎。</p>
<h3>rake db:migrateのエラー</h3>
<p>そして現在進行形で未解決なのがこのエラー。デフォルトのデプロイタスクでは途中でデプロイ先サーバー上でRAILS_ENV=staging bundle exec rake db:migrateを叩くんだけど、これが次のエラーで停まってしまう。</p>
<pre><code>DEBUG [4be84d91]        rake aborted!
DEBUG [4be84d91]        database configuration does not specify adapter
</code></pre>
<p>いくつか思い当たった原因に取り組んではみたのだが、なおエラーが起きている。</p>
<ul>
<li>RAILS_ENV=hogeを追加した場合、Gemfileのgroup :hogeを見に行くのだが、stagingグループを用意していなかった（<a href="http://opentechnica.blogspot.jp/2012/01/railsenv.html">参考</a>）。</li>
<li>database.ymlにstagingの設定を用意していなかった。</li>
</ul>
<p>たぶんRAILS_ENV周りの設定が何かおかしいと思うのだが、わからないので取りあえず保留にしている。というか、これに行き当たるまでRAILS_ENVのことを全然知らなかった自分にも問題大有りなので、一度Railsの勉強に立ち返ってみている次第。知識がないと、連鎖的に他のこともできなくなってくるなぁというのを痛感している。</p>
]]></description>
            <link>https://chroju.dev/blog/2014-02-20-post</link>
            <guid isPermaLink="false">2014-02-20-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 19 Feb 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[突然だけどVimperatorrcを晒してみる]]></title>
            <description><![CDATA[<p>非常に唐突ではあるけどvimperatorrcを晒してみようと思う。2014年の今日、あんまりvimperator関連の日本語記事って見かけない気がしていて、少しでもそのへん貢献できればなぁという思い。</p>
<p>vimperator自体は何年か前から使っていたのだが、カスタマイズはあまりせずにデフォルトの状態で使っていた。が、操作によってはマウス使った方が便利だったり、ちょっと中途半端な状態にあったので、一念発起してちょこちょこいじってみた。まだいじれる余地はありそうなんだけど。</p>
<pre><code>" vim: set filetype=vim :
</code></pre>
<p>Vimで編集するとき、vimperatorrc用のハイライトがないので、似たところでfiletypeをvimとして認識させてます。</p>
<pre><code>"============================
" General
"============================

" 入力欄に自動フォーカスしない
set focuscontent
" ビジュアルベルを表示しない
set visualbell
highlight Bell display:none
" :oなどでの補完候補をサーチエンジン、履歴に限定
set complete=sl
" Hintモードでアルファベット使用
set hintchars=jfnvurhgytbkdmcielsxoe
" ツールバーはアドオンとタブのみ表示
set gui=addons,nobookmarks,nomenu,nonavigation,tas
" commandモードでIMEオフ
style! -name=commandline-ime chrome://* #liberator-commandline-command input {ime-mode: inactive;}
</code></pre>
<p>ここまでは基本、一般的な設定しかないかと。set complete=slは地味に効く。で、なぜか現状set hintcharsが動いてないれす。。。何がいけないのかわからん。</p>
<pre><code>"============================
" Key mapping
"============================

" google検索を手早くする
noremap s :open&#x3C;Space>google&#x3C;Space>
noremap ,s :tabopen&#x3C;Space>google&#x3C;Space>
</code></pre>
<p>ここからキーマッピング。:openで検索もURL開くのも両方いけるのはいけるんだが、vimperatorでの自動判別がうまいこといかない（例えば「twitter おすすめ」とかで:openすると、Twitter検索で「おすすめ」を探した結果が表示されるとか）ときがあるので、明示的に:open googleを一発で開けるようにしてます。</p>
<pre><code>" OS分岐
" dをブラウザ標準の「タブを閉じる」にマッピング
" vimperatorrcのリロード
js&#x3C;&#x3C;EOM
if(liberator.has("MacUnix")) {
  liberator.execute("map d &#x3C;M-w>");
  liberator.execute("map ,r :source&#x3C;Space>~/.vimperatorrc&#x3C;CR>");
} else {
  liberator.execute("map d &#x3C;C-w>");
  liberator.execute("map ,r :source&#x3C;Space>~/_vimperatorrc&#x3C;CR>");
}
EOM
</code></pre>
<p>dを打ったときに左隣のタブにフォーカスが移るのが気に入らないので、OSデフォルトの「タブを閉じる」ショートカットにdをリンクさせて、タブを閉じたときの挙動はTab Mix Plusで「直前のアクティブタブに移る」ように設定してる。このへん、vimperatorrcだけでなんとか設定できないものか。</p>
<p>あと、,rでvimperatorrcの再読み込みさせてます。この2つの設定はOSによって微妙に異なるので、分岐させますた。MacとWindowsでしか使ってないのでかなり適当な分岐。</p>
<pre><code>" 移動幅
noremap j 5j
noremap k 5k
" タブ移動
nnoremap h &#x3C;C-p>
nnoremap l &#x3C;C-n>
" タブの位置変更
map &#x3C;C-l> :tabmove! +1&#x3C;CR>
map &#x3C;C-h> :tabmove! -1&#x3C;CR>
" undo一覧から開く
nnoremap U :undo&#x3C;Space>
let g:hint_tombloo_key = 'r'
" ブラウザ再起動
nnoremap &#x3C;C-r> :restart&#x3C;CR>
</code></pre>
<p>わりと良くある感じのキーマッピング。</p>
<pre><code>" VisualモードでC-gで選択しているテキストでGoogle検索
vmap &#x3C;silent> &#x3C;C-g> y&#x3C;Esc>&#x3C;Esc>P
</code></pre>
<p>コメントの通り。Visualモードで文字列選択した状態でC-g押すと、選択文字列でGoogle検索します。URLの場合はそのまま開いてくれるはずだけど、やったことなし。</p>
<pre><code>" タブのピン止めを@でトグル
" http://qiita.com/t3kot3ko/items/1b032940dbb79e88323e
javascript &#x3C;&#x3C;EOM
liberator.modules.commands.addUserCommand(["togglepin"], "add pin to current tab",
function(){
    var currentTab = gBrowser.mCurrentTab
    if(currentTab.pinned){
        gBrowser.unpinTab(currentTab)
    }
    else{
        gBrowser.pinTab(currentTab)
    }
});
EOM
nnoremap @ :togglepin&#x3C;CR>
</code></pre>
<p>地味にピン止め使うのでキーマッピングしました。Firefoxのこの全部Javascriptでなんとかなる感じ好きよ。大好き。ちなみに以下エントリーから丸コピーしてます。</p>
<p><a href="http://qiita.com/t3kot3ko/items/1b032940dbb79e88323e">Vimperator - タブのピン留めをトグルする - Qiita</a></p>
<pre><code>"============================
" colorscheme
"============================
" デフォルトのヒント派手すぎ＞＜
hi Hint font-family: Arial; font-size: 21px; font-weight: bold; text-shadow: -1px -1px 2px black, 1px -1px 2px black, -1px 1px 2px black, 1px 1px 2px black; color: #33cccc;
hi HintElem color: gray; background-color: #a1e4e6;
hi HintActive color: black; background-color: #ff8700;

" デフォルトのエラー赤くてこわい＞＜
hi ErrorMsg color:white; background-color: #ec6aa1;
</code></pre>
<p>デフォルトのヒントモードが色彩的に大変ウザいので……。色はもうちょい改善の余地あるかなと思ってる。</p>
<p><a href="http://www.flickr.com/photos/chroju/12396935955/"> title="スクリーンショット 2014-02-09 10.09.25 by chroju, on Flickr"><img src="http://farm6.staticflickr.com/5548/12396935955_dae9869fd9.jpg" width="500" height="257" alt="スクリーンショット 2014-02-09 10.09.25"></a></p>
<pre><code>"============================
" qmarks
"============================
qmark m https://mail.google.com/
qmark b http://b.hatena.ne.jp/chroju
qmark t http://chroju.tumblr.com/
qmark f http://cloud.feedly.com/#latest
qmark p http://getpocket.com/a/queue
qmark B http://chroju.hatenablog.jp/
</code></pre>
<p>QuickMarks設定。これ入れておくと、例えばgomでアクティブタブにGmailが開きます。gnmで新規タブで開ける。あんまり使ってない。</p>
<pre><code>"============================
" plugin
"============================

" plugin_loader
let g:plugin_loader_roots = "~\vimperator\vimperator-plugins\ ~/.vimperator/vimperator-plugins/"
let g:plugin_loader_plugins = "_libly,direct_bookmark,sbmcommentsviewer,caret-hint,appendAnchor,stella,feedSomeKeys_3,commandBookmarklet,copy"
</code></pre>
<p>ここからプラグイン。プラグイン管理は<a href="https://github.com/vimpr/vimperator-plugins/blob/master/plugin_loader.js">plugin_loader</a>を使うとアホみたいに便利です。</p>
<p>普通、プラグインって~/.vimperator/plugin/フォルダに入れて（あるいはシンボリックリンク貼って）読み込ませると思うのだが、このplugin_loaderを~/.vimperator/pluginフォルダに入れれば、以下設定が適用可能に。</p>
<ul>
<li>let <a href="http://plugin.g.hatena.ne.jp/">g:plugin</a>_loader_roots => 読み込むプラグインが配置されたフォルダを指定（複数可）</li>
<li>let <a href="http://plugin.g.hatena.ne.jp/">g:plugin</a>_loader_plugins => 読み込むプラグイン名を指定（.jsは除外でOK）</li>
</ul>
<p>つまり<a href="https://github.com/vimpr/vimperator-plugins.git">https://github.com/vimpr/vimperator-plugins.git</a>をどっかにgit cloneしておいて、そのフォルダに対してg:plugin_loader_rootsを指定しておけばどのプラギンもシンボリックリンクとか貼らずに好きに使えるってわけです。便利過ぎ。</p>
<pre><code>" Evernote Clearly
nnoremap e :&#x3C;C-u>js __readable_by_evernote.__readable_by_evernote__launch(false)&#x3C;CR>
nnoremap E :&#x3C;C-u>js __readable_by_evernote.__readable_by_evernote__launch(true)&#x3C;CR>
</code></pre>
<p>プラグインじゃないけど。。。アドオンのEvernote Clearyの操作をeとEにマッピングさせてる。これもどっかで拾ったコードです。</p>
<pre><code>" direct_bookmark
let g:direct_sbm_use_services_by_tag = "h"
let g:direct_sbm_use_services_by_post = "h"
source! $HOME/.vimperatorrc.local
</code></pre>
<p>direct_bookmarkの設定。コマンドからdeliciousとかはてブとかソシアルブックマアクに投稿できるヤツです。はてブしか使ってないので、はてブだけで使えるように。</p>
<pre><code>" vのみではてブコメント表示
map v :viewSBMComments&#x3C;Space>-t&#x3C;Space>h&#x3C;Space>-f&#x3C;Space>id,comment&#x3C;CR>
</code></pre>
<p>sbmcommentsviewerの設定。ソシアルブックマアクのコメントがコマンドで見られるようになるヤツ。これもはてブだけに設定。</p>
<pre><code>" feedSomeKeys
command! -nargs=+ lazy autocmd VimperatorEnter .* &#x3C;args>
lazy fmaps -u='mail\.google\.com/mail' c / j k n p o u e x s r &#x3C;S-i>  a # [ ] ? gi gs gt gd ga gc
lazy fmaps -u='mail\.google\.com/mail/.*/[0-9a-f]+$' c / j,n k,p n,j p,k o u e x s r a # [ ] ? gi gs gt gd ga gc
lazy fmaps -u='feedly\.com' j k n p o v gm ga gg gl / r m x s t l f b
lazy fmaps -e=vkeydown -u='www\.tumblr\.com/' j k r t q p n L l&#x3C;CR>
lazy fmaps -u='www\.pixiv\.net/member_illust\.php\?mode=manga&#x26;amp;illust_id=[0-9]+' j k
</code></pre>
<p>feedSomeKeysの設定。特定URL下で特定キーを無効化するプラギン。:ignorekeysより細かく設定ができるから好き。ただ、いまいち設定方法が飲み込めてなかったりもする。現状はGmail、feedly、Tumblr、pixivの漫画モード（？）で設定させてる。Gmailの設定が被ってるとこなんとかしたい。。</p>
<pre><code>" copy.js
javascript &#x3C;&#x3C;EOM
(function () {
  liberator.globalVariables.copy_templates = [
    { label: 'titleAndURL',    value: '%TITLE%\n%URL%' },
    { label: 'markdown',       value: '[%TITLE%](%URL%)' },
    { label: 'title',          value: '%TITLE%' },
    { label: 'anchor',         value: '[%TITLE%](%URL%)' },
    { label: 'selanchor',      value: '[ title="%TITLE%">%SEL%](%URL%)' },

    { label: 'amazon',   value: 'copy clean amazon url from current page',
      custom: function() {
        var m = content.document.location.pathname.match(/dp\/(\d+)/);
        return m ? ('http://amazon.jp/dp/' + m[1]) : null;
      }
    },
  ];
})();
EOM

" 特によく使う機能をキーマッピング
map ,y :copy&#x3C;Space>titleAndURL&#x3C;CR>
map ,my :copy&#x3C;Space>markdown&#x3C;CR>
</code></pre>
<p>copy.jsの設定。いろいろと好きな形式でコピーが出来るようになる。{ label〜のとこの設定がそれに当たりまして、例えば:copy markdownコマンドでマークダウン記法用にタイトルとURLがコピーできる。ブログ書いてるとこれホント便利。</p>
<p>基本的には%TITLE%や%URL%といった変数を使って設定するんだけど、javascriptも欠けます。label: amazonではAmazonのURLを短い（アフィ用のパラメータとか除外した）状態でコピれるようjavascriptで書かれてる。詳しくは以下エントリー。</p>
<p><a href="http://qiita.com/hadashiA/items/83e2fef39bac531577e2">JavaScript - vimperatorプラグインcopy.jsで、いま開いてるamazonの本のページの短いURLをクリップボードにコピる。あと正規表現で好きなとこコピる - Qiita</a></p>
<pre><code>"============================
" about:config
"============================

set! network.dns.disableIPv6=true
set! network.http.pipelining=true
set! network.http.proxy.pipelining=true
set! network.http.pipelining.maxrequests=8
set! network.http.max-connections-per-server=32
set! security.dialog_enable_delay=0
set! browser.tabs.closeWindowWithLastTab=false
set! browser.cache.memory.capacity=16384
set! browser.sessionstore.interval=500000
set! dom.popup_maximum=50
set! browser.cache.disk.enable=false
set! browser.cache.memory.capacity=-1
set! layout.spellcheckDefault=0
set! javascript.options.mem.high_water_mark=32
</code></pre>
<p>Vimperatorはset!でabout:configの設定ができます！　便利！　これでabout:configの内容も共有できるよ！　設定内容はウン年前にやったままなので、具体的に何やってんのか覚えてないれす。メモリ周りの設定が主だったと思うので、最近の比較的軽くなったFxなら要らない設定もあるかも。</p>
<pre><code>"読み込み完了メッセージ
echo "vimperatorrc loaded."

" [EOF]
</code></pre>
<p>最後に、vimperatorrcが読み込まれたとき用のechoを入れる。これがないと,r押しても読み込まれたのかわかんないので。</p>
<p>vimperator、Vimmerじゃなくても便利なのでじゃんじゃん使いましょう晒しましょう。</p>
]]></description>
            <link>https://chroju.dev/blog/2014-02-09-post</link>
            <guid isPermaLink="false">2014-02-09-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 08 Feb 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Rails環境構築（4）nginx導入]]></title>
            <description><![CDATA[<p>nginxの導入はyumを使ってサクッと。まずリポジトリを登録して、その後yumを使ってインストール。</p>
<pre><code>$ sudo rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
</code></pre>
<p>リポジトリが正しく登録されているか確認。</p>
<pre><code>$ yum list nginx --disablerepo=* --enablerepo=nginx
（中略）
Installed Packages
nginx.x86_64                1.4.4-1.e16.ngx           @nginx
</code></pre>
<p>yum install</p>
<pre><code>$ sudo yum install nginx
</code></pre>
<p>インストールは以上。EPEL様々ですね。あとは仮想ホスト設定用にディレクトリを作っておくという作業を入れる。</p>
<pre><code>$ sudo mkdir /etc/nginx/sites-available
$ sudo mkdir /etc/nginx/sites-enabled
$ sudo rm -f conf.d/*.conf
</code></pre>
<p>nginx.confを開いて、sites-enabledを読み込ませるための設定を追加する。具体的には以下の1行。</p>
<pre><code>include /etc/nginx/sites-enabled/*;
</code></pre>
<p>以上、終わり。最後にサービスを立ち上げて、自動起動を設定。</p>
<pre><code>$ sudo service nginx start
$ sudo chkconfig nginx on
</code></pre>
]]></description>
            <link>https://chroju.dev/blog/2014-02-02-post</link>
            <guid isPermaLink="false">2014-02-02-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 01 Feb 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[$ vagrant sshで仮想マシンに入れなくなった場合の対処法]]></title>
            <description><![CDATA[<p>やらかしました。Rails環境構築シリーズ、次回でセキュリティ周りの設定をまとめようと思い、普段の要領でiptablesをいじったりsshのポート番号変えたりしてたんだけど、なんか設定しくじったっぽくてvagrant sshできなくなった。やべえ、仮想マシンだしこれもう詰んだんじゃねと思ったんだけど、なんとか元に戻せたので対処法まとめとく。</p>
<p>といっても簡単な話です。</p>
<ul>
<li>Virtual BoxをGUIで開く</li>
<li>該当仮想マシンがリストに入ってるので強制終了し、Virtual Box上で起動し直す</li>
<li>rootでログイン（パスワードはデフォルトでvagrant）</li>
<li>おかしい箇所を直す</li>
</ul>
<p>コマンド叩いて操作してるので忘れがちだけど、vagrantはVirtual Box上（有料版ならVMware上も有り得るが）に仮想マシンを立ててるので、普通にGUIから入ればいい話です。rootで入ってぐいぐいヤバそうなとこ直して、直したらターミナルからssh試してみてってのを交互に繰り返して直しませう。</p>
<p>rootで入り直す前に一度VM落とす手順を入れましたが、こうしないとGUIから入れないみたいです。僕の場合だとターミナルでiptablesとかいじって、よしじゃあsshログインできるか試してみようってことで一旦ログアウトしたら入れなくなった（アホだ）のでVMが立ち上がりっぱなしになっちゃったわけなんだけど、この状態で取りあえずVirtual Box開いてみたらコンソールを表示するボタンがグレーアウトされてました。なので一旦強制終了するしかないです。</p>
<h2>余談</h2>
<p>ちなみに今回何をやらかしたのかだけど、ポイントとしてはsshのポート番号を変えた（/.ssh/configをいじった）のと、iptablesをいじったのの二点。これを普通のVMの感覚でやっちゃったのがマズかったみたい。</p>
<p>まず、vagrant sshで使われているポート番号はデフォルトで22ではなく、2222なのです。これはホスト側で$ vagrant ssh-configコマンドを打ってみるとわかる。</p>
<pre><code>Host default
  Hostname 127.0.0.1
  User vagrant
  Port 2222
</code></pre>
<p>一方、ssh以外の各vagrantコマンドについても、いずれもsshを使っている模様。vagrant upもvagrant haltもssh経由で命令しているみたいです。ただ、こちらは通常通りPort 22を使っているのでややこしい。このあたりの事情を踏まえた上でポート番号あれこれしないと、必要なはずのポート塞いじゃってうああああああってなっちゃうっぽい。</p>
<p>まぁvagrantで作ったサーバーを表に公開することはあんまりないと思うんで、このへん触らないのが吉かも。練習でやりたいのであれば、vagrant以外でサーバー用意してやった方が良さそうな気がします。</p>
<p><strong>参考</strong></p>
<ul>
<li><a href="http://girigiribauer.com/archives/1127">Vagrant で SSH の接続ポート番号を変えると、けっこう複雑になるという話 | girigiribauer.com</a></li>
<li><a href="http://d.hatena.ne.jp/okinaka/20110805/1312474847">Vagrant のベースBOX作成手順 (Scientific Linux 6.1) - エンジニアきまぐれTips</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/2014-02-02-02-post</link>
            <guid isPermaLink="false">2014-02-02-02-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 01 Feb 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Rails環境構築（3）PostgreSQLインストール]]></title>
            <description><![CDATA[<p>ポスグレのインストール。yumで入るようなんだけど、聞くところによるとバージョンが古いらしい。念のため確認してみる。</p>
<pre><code>$ yum list | grep postgresql
（中略）
postgresql.i686                           8.4.18-1.el6_4                base
postgresql.x86_64                         8.4.18-1.el6_4                base
postgresql-contrib.x86_64                 8.4.18-1.el6_4                base
postgresql-devel.i686                     8.4.18-1.el6_4                base
postgresql-devel.x86_64                   8.4.18-1.el6_4                base
postgresql-docs.x86_64                    8.4.18-1.el6_4                base
postgresql-ip4r.x86_64                    1.05-1.el6                    epel
</code></pre>
<p>うん、確かに古い。この記事を書いている時点では9.3.2とか出てるけど、yumで用意されてるのは8.4である。最新を入れればいいというわけでもないが、さすがにちょっと古いような気が。（ところでyumに入ってるパッケージの調べ方、これであってんのかな？）</p>
<p>てわけで新しいバージョンをWebから持ってくる。<a href="http://yum.postgresql.org/repopackages.php">PostgreSQL RPM Repository (with Yum)</a>にいろいろあるので適切なリンクURLをコピー。1コ前のバージョンでPostgresql 9.2にしときましょか。自分のOSがなんだかわかんなくなったらunameコマンドで確認。</p>
<pre><code>$ uname -a
Linux xxx 2.6.32-358.23.2.el6.x86_64 #1 SMP Wed Oct 16 18:37:12 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
</code></pre>
<p>CentOS 6 x86_64であることがわかったので、wgetでダウンロード。</p>
<pre><code>$ wget -P /tmp http://yum.postgresql.org/9.2/redhat/rhel-6-x86_64/pgdg-centos92-9.2-6.noarch.rpm
</code></pre>
<p>続いてRPMにインストール。</p>
<pre><code>$ sudo rpm -ih /tmp/pgdg-centos92-9.2-6.noarch.rpm
warning: /temp/pgdg-centos92-9.2-6.noarch.rpm: Header V4 DSA/SHA1 Signature, key ID 442df0f8: NOKEY
########################################### [100%]
########################################### [100%]
</code></pre>
<p>rpmコマンドのオプションとして-iを付けるとパッケージのインストールが出来る。さらにhを付けると####で進捗が表示されるそうだ。必須オプションではないので、hについてはお好みで。</p>
<p>いよいよyumでインストール。</p>
<pre><code>$ yum -y install postgresql92-server.x86_64
</code></pre>
<p>……yum installって補完はできないんですかね入れたら初期化して起動て自動起動設定します。</p>
<pre><code>$ sudo service postgresql-9.2 initdb
$ sudo service postgresql-9.2 start
$ sudo chkconfig postgresql-9.2 on
</code></pre>
<p>ここまでで一旦インストールとしては終了。あとは基本的な設定をいくつか入れておく。</p>
<p>まずpg_hba.confを触る。これはDBに対するクライアントからのアクセスを制御するファイルで、さきほどinitdbしたときに作成されている。管理している内容としてはどのDBに対するどのユーザーのどこ（IP）からのアクセスを、どの認証方式で認証するか。必要に応じて書き入れてやる必要があるが、ひとまず参考書通りの設定をしておく。</p>
<pre><code>$ sudo vim /var/lib/pgsql/9.2/data
</code></pre>
<pre><code># TYPE  DATABASE     USER           ADDRESS                     METHOD

local  all           postgres                                   peer
local  all           all                                        md5
host   all           all            127.0.0.1/32                md5
host   all           all            ::1/128                     md5
</code></pre>
<p>終わったらPostgreSQLをリロード。</p>
<pre><code>$ sudo service postgresql-9.2 reload
</code></pre>
<p>今回はここまで。</p>
<h2>参考</h2>
<ul>
<li><a href="http://www.postgresql.jp/document/8.2/html/auth-pg-hba-conf.html">pg_hba.confファイル</a></li>
<li><a href="http://morizyun.github.io/blog/postgresql-mac-centos-rails/">Mac MountainLion/CentOS 6.4へのPostgreSQL 9.2の導入手順 - 酒と泪とRubyとRailsと</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/2014-01-26-post</link>
            <guid isPermaLink="false">2014-01-26-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 25 Jan 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Rails環境構築（2）Rubyのインストール + α]]></title>
            <description><![CDATA[<p>環境構築エントリーその2。まっさらなOSにRubyを入れていきます。</p>
<p>まずはいろいろパッケージのインストール。ぶっちゃけ参考書通りにやってるだけなので、どこまで必要なのかはよくわかってない。wgetとgitが必須であるのは言わずもがなだし、openssl-devel、make、postgresqlなんかもまぁ必要だろう。gccとかは要る……のか？</p>
<pre><code>$ sudo yum -y install gcc gcc-c++ make autoconf openssl-devel readline-devel libyaml-devel postgresql9.1-devel wget git
</code></pre>
<p>続いて意気揚々とRubyを入れたいとこだが、その前にrbenvを入れる。以前にエントリーで書いたこともあったけど、rbenvを使ってRubyをインストールすると、複数のバージョンのRubyを切り替えて使えるようになるので大変便利。インストールもwgetでダウンロードしてビルドしてなんてやり方をせず、rbenv installコマンドで簡単にできるようになる。</p>
<pre><code>$ git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
$ git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
</code></pre>
<p>rbenv自体のインストールもgithubからのクローンで済むのでスマートですね。ついでにもう1個git cloneしているのはruby-buildって奴で、これがないとrbenv install（rbenv使ってRubyをインストールするためのコマンド）が使えないらしい。で、入れたらPATHを通します。</p>
<pre><code>$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
</code></pre>
<p>PATHを通したらbash_profileを再読み込みして、それからtype rbenvコマンドを打ってインストールの正常完了を確認する。ちなみに自分は最初、bash_profileの再読み込み忘れて慌てました。</p>
<pre><code>$ source ~/.bash_profile
$ type rbenv # rbenv is a functionと表示されればOK
</code></pre>
<p>ここまでの手順はGitHubでrbenvのREADMEにも書かれてるから一読を推奨。</p>
<p>rbenvが入ったので、早速Rubyをインストール。</p>
<pre><code>$ rbenv install --list #インストール可能なバージョンが一覧表示される
$ rbenv install 1.9.3-p484 #入れるバージョンは任意で
</code></pre>
<p>もちろん複数バージョン入れてもOK。Rubyのインストールが完了したら、どのバージョンを使うか確定させる。使うコマンドはrbenv global。安易に想像できる話ではあるが、rbenv localもある。前者が文字通りシステム全体、どのシェルでも使われるバージョンであるのに対し、後者はローカル環境、すなわち今後入れるRailsのアプリケーションディレクトリとか、そういう環境でのRubyバージョンを指定するもの。今はローカル環境がないので、rbenv globalだけ指定すればいい。</p>
<pre><code>$ rbenv global 1.9.3-p484
$ ruby -v #確認
</code></pre>
<p>以上でRubyは入ったわけだけど、ついでに今後使うのでBundlerも入れておく。BundlerはRubyGemsを管理するためのツールであり、RubyGemsとはRubyのパッケージ管理システムのことである。GemはRailsでもめちゃめちゃ使うし、そもそものRailsもGemで入れることになるので、ここでBundlerを入れておく。</p>
<p>ちなみにGem自体はRubyと一緒にすでに入っている。が、バージョンが古い場合があるので更新してあげる必要がある。GemだけでももちろんRailsをインストールしたりはできるんだけど、その後の落とした各Gemの管理がマンドクセーってなるので、Bundlerが必要になる。まぁ詳しくは次回あたりで。</p>
<pre><code>$ gem update --system
$ gem -v #最新のバージョンになったことを確認
</code></pre>
<p>じゃあ喜び勇んでGemを使ってBundler入れましょう！と行きたいところだが、まだやることがある。デフォルトだとGemで何かをインストールしたとき、ずらずらーっとメッセージが出てくるのだが、それを消すためのおまじない。これで体感2倍ぐらいインストールが速くなるらしい。方法は簡単で、~/.gemrcファイルを新規で作成して、以下の内容を書き入れる。</p>
<pre><code>gem: --no-ri --no-rdoc
</code></pre>
<p>書き入れるって簡単にいうけどエディタは何使えばいいんだよ？って人はviあたり使っとけばいいと思う。もっといえば$ sudo yum install vimすればいいと思うんだが、そのあたりの話はまたおいおい。</p>
<p>はい、やっとこれで準備完了。Bundler入れます。</p>
<pre><code>$ rbenv exec gem install bundler
$ bundle -v
</code></pre>
<p>これで作業完了！のはずなんだが、なぜか自分はbundleにPATHが通ってなかったらしく、$ bundle -vできませんでした。なんでだろ？　仕方ないので<a href="http://qiita.com/hyshhryk/items/7e728ad57d963454b142">ココ</a>のやり方に従ってなんとかPATHは通ったんだけど、リンク先が何をやっていたのかはっきり言ってわかっておらず、不安。EXECUTABLE DIRECTORYってなんスか？</p>
<p>まーとりあえずRubyとBundlerは入ったので、次回はRailsのインストールといきますかね。</p>
<h2>参考</h2>
<ul>
<li><a href="http://blog.ruedap.com/2011/05/14/ruby-gem-install-no-ri-no-rdoc-gemrc">RubyGemsでgemのインストール時に--no-ri --no-rdocをデフォルトにする - アインシュタインの電話番号</a></li>
<li><a href="http://qiita.com/ongaeshi/items/b07beebca21ba7ed8e7f">rbenv &#x26; ruby-build の使い方メモ - Qiita [キータ]</a></li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/2014-01-23-post</link>
            <guid isPermaLink="false">2014-01-23-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 22 Jan 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Rails環境構築（1） Vagrantで仮想マシン構築]]></title>
            <description><![CDATA[<p>Vagrantで仮想サーバー構築してみたのでメモ。構築するだけなら、楽。大してコマンドも要らない。</p>
<h2>インストール</h2>
<p>まずはGemでインストールしてみたけど、バージョン古いっぽくてダメだった。なので、ふつうにウェブからダウンロードしてインストールします。URLは以下。ついでに「GET STARTED」からいろいろ読んどくといいと思う。公式のRead meに勝るものはないです。</p>
<p><a href="http://www.vagrantup.com/">http://www.vagrantup.com/</a></p>
<p>インストールしたらバージョン確認。</p>
<pre><code>$ vagrant -v
</code></pre>
<h2>boxの追加</h2>
<p>まずはboxと呼ばれる仮想マシンイメージをvagrantに追加する。</p>
<pre><code>$ vagrant box add hoge url
</code></pre>
<p>hogeは適当なイメージ名、urlはウェブで公開されているboxのurl。イメージは<a href="http://www.vagrantbox.es/">ココ</a>に大量にあるので、任意のサーバーのURLをコピってくればOK。ほとんどがLinux、ちょこっとだけBSD。</p>
<h2>vagrantの初期化</h2>
<pre><code>$ mkdir vagrant
$ cd vagrant
$ vagrant init hoge
</code></pre>
<p>vagrant initでカレントディレクトリをvagrant用に初期化する。なのでmkdirは好きなとこに好きなフォルダ作ればよい。そこに仮想マシンの設定ファイルが作られるので。vagrant initの引数にはさっきvagrant box addで追加した仮想マシンイメージの名前を渡してやる。渡さないとデフォルト値で設定ファイルが作られてしまう。これで最初ハマった。ちなみにどうハマるかというと、vagrant upしたときにこんなエラーが出る。</p>
<pre><code>There are errors in the configuration of this machine. Please fix
the following errors and try again:

vm:
* The box 'base' could not be found.
</code></pre>
<p>「base」という名前のboxがないというエラー。どうもデフォルトでbaseという名前が使われるらしいのだが、さっきbox addした名前と異なるので、そんなboxはないから立ち上げられませんよということ。もしこの状態になってしまった場合の対処としては、vagrantfileのconfig.vm.boxの値を該当の仮想マシンイメージ名に替えてやれば上がるようになる。</p>
<p>話が飛んでしまったが、Vagrantfileはvagrant initしたディレクトリの中に出力されている。で、仮想マシンを上げる前にちょっとコイツの編集が必要。</p>
<pre><code>  # Create a private network, which allows host-only access to the machine
  # using a specific IP.
  config.vm.network :private_network, ip: "192.168.xx.xx"
</code></pre>
<p>上のconfig〜行のコメントアウトを外してやって、IPを適当に設定する。が、自分の環境だとこれだけでは仮想マシンを起動した時にエラーが出てしまって、さらにprivate_networkをpublic_networkに替えてやらなくてはならなかった。ググってるとこの手順やってる人ほとんどいないんだけど、何が原因だろう。</p>
<h2>仮想マシンの起動</h2>
<p>で、ここまでやっていよいよVM起動。</p>
<pre><code>$ vagrant up
</code></pre>
<p>てっきりVirtual boxがGUIでも上がってくるのかと思ったが、仮想マシン上がりましたよ―というメッセージが表示されるだけでGUI上は何の変化もない。なのでOSが上がってるのかわかりにくいんだけど、SSHで入ると実際入れるのでどうも上がっているらしい（ちなみにGUIでVirtual box上げてももちろん起動状態はわかる。あとvagrant statusコマンドでもわかる）。</p>
<pre><code>$ vagrant ssh
</code></pre>
<p>bashのsshコマンド発行しなくても、vagrantの独自コマンドで入れる。楽。ちなみに入るときのユーザーは勝手にvagrantというユーザーが作られているんだとか。あとはもう好きにやっちゃってーというところ。他に使いそうなコマンドは以下の表あたりか。</p>
<table>
<thead>
<tr>
<th> コマンド         </th>
<th> 意味                    </th>
</tr>
</thead>
<tbody>
<tr>
<td> vagrant halt     </td>
<td> 仮想マシンの停止        </td>
</tr>
<tr>
<td> vagrant destroy  </td>
<td> 仮想マシンの削除        </td>
</tr>
<tr>
<td> vagrant box list </td>
<td> 仮想マシンイメージリストの表示 </td>
</tr>
<tr>
<td> vagrant status   </td>
<td> 仮想マシンの状態確認      </td>
</tr>
</tbody>
</table>
<p>vagrantが真価を発揮するのって多分chef-soloと組み合わせたときなので、今の段階だと「わざわざマウス使わずともターミナル上で仮想マシン上げられて便利〜」ぐらいの感想しか正直ないです。もっと勉強しよ。</p>
<h2>参考</h2>
<p><a href="http://www.happytrap.jp/blogs/2013/07/26/10602/">Vagrantで仮想サーバ構築 | HAPPY*TRAP</a></p>
<p><a href="http://qiita.com/nobu_blast/items/828cf7c002100a0fdeb2">vagrant + virtualbox 仮想サーバ構築 - Qiita [キータ]</a></p>
]]></description>
            <link>https://chroju.dev/blog/2014-01-19-post</link>
            <guid isPermaLink="false">2014-01-19-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 18 Jan 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Ruby on Rails環境構築はじめます]]></title>
            <description><![CDATA[<p>Ruby on Railsのアプリ構築の勉強もそこそこに進んできたので、そろそろ環境構築始めてみようかと。（あんまりブログで書けてないけど……）。てわけで、この本買いました。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4844333755/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51Mb377pxwL._SL160_.jpg" alt="Ruby on Rails環境構築ガイド" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4844333755/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Ruby on Rails環境構築ガイド</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.03.01</div></div><div class="amazlet-detail">黒田 努 <br />インプレスジャパン <br />売り上げランキング: 44,343<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4844333755/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>これまで環境としてはMax OS X 10.8にVMware FusionでCentOS浮かべて、その上でコード書いてWEBlick立ち上げてってやってたんだけど、考えてみればWEBlickでやるなら手元のMacで良かったわけで。いちいちコード書くのにSSHつなぐとかまぁ無駄なわけで。ということで、環境は次のように変えていく。</p>
<ul>
<li>
<p>開発環境：Mac OS X 10.8（物理）</p>
</li>
<li>
<p>Ruby 2.0.0</p>
</li>
<li>
<p>Rails 4.0</p>
</li>
<li>
<p>MySQL</p>
</li>
<li>
<p>ステージング：CentOS 6.4（Virtual Box）</p>
</li>
<li>
<p>Ruby 2.0.0</p>
</li>
<li>
<p>Rails 4.0</p>
</li>
<li>
<p>MySQL</p>
</li>
<li>
<p>nginx</p>
</li>
<li>
<p>unicorn</p>
</li>
<li>
<p>vagrant + chef soloで構築予定</p>
</li>
<li>
<p>本番環境：CentOS 6.4（VPS）</p>
</li>
<li>
<p>構成はステージングと同様</p>
</li>
</ul>
<p>Apacheは仕事でも使ったことがあるんで、流行りに乗ってnginx + unicornでやってみます。んでさらに流行りに乗ってvagrantとchef solo使おうかと。vagrantはちなみにもう試してみたけど、さっくり仮想マシンが立ってしまってビビる。あとでブログにまとめる予定。ただしchefはちょっとしっかりやんないと使えなさそう。</p>
<p>もともと自分はインフラをメインで飯食ってるんで、こころへんはあまり迷わずにいきたいところ。</p>
]]></description>
            <link>https://chroju.dev/blog/2014-01-18-post</link>
            <guid isPermaLink="false">2014-01-18-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 17 Jan 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[bundle installはどのパスに対してすべきなのか問題]]></title>
            <description><![CDATA[<p>今まであまり意識していなかったのだが、bundle installコマンドを打ったときにGemはどこにインストールされるのか？という問題がある。オプションなしにこのコマンドを実行した場合、Gemはシステム側（すなわちusr/lib/ruby/gems/云々）に入ってしまうわけだが、一つの環境で複数アプリを構築している場合はこれだと困るし、何より各アプリごとにGemfileを用意している意味が無い。というわけで、bundle installはパスを指定すべきである、ということ。</p>
<pre><code>% bundle install --path vendor/bundle
</code></pre>
<p>Railsの場合はvendor/bundleディレクトリがあるので、ここを明示的に指定してやれば良い。これでGemも含めてアプリ内で「閉じた」状態にすることができる。</p>
<p>まぁこのへんの話は今更自分が書くまでもなく、いくつか参考になるエントリーがあった。ただ、自分が使っていた有名な<a href="http://railstutorial.jp/">オンラインのRoRチュートリアル</a>にはこのことが書かれてなかったので、書き留めた次第。</p>
<ul>
<li><a href="http://qiita.com/emadurandal/items/a60886152a4c99ce1017">Rails開発環境の構築（rbenvでRuby導入からBundler、Rails導入まで） - Qiita [キータ]</a></li>
<li><a href="http://memo.yomukaku.net/entries/IpCSQmo">Bundler再履修: bundle execって何？ gemはどこに入るの？ - memo.yomukaku.net</a></li>
</ul>
</blockquote>
<p>で、<a href="http://chroju89.hatenablog.jp/entry/2014/01/09/235505">先日のエラー</a>についてもこれが原因ではないかと思ったのだが。。。そんなことはありませんでした。</p>
]]></description>
            <link>https://chroju.dev/blog/2014-01-14-post</link>
            <guid isPermaLink="false">2014-01-14-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 13 Jan 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[twitter-bootstrap-railsでundefined methodのエラーに嵌る]]></title>
            <description><![CDATA[<p>完全に嵌った。さっぱりわからん。</p>
<pre><code>undefined method `to_css' for nil:NilClass
</code></pre>
<p><a href="https://github.com/seyhunak/twitter-bootstrap-rails">twitter-bootstrap-rails</a>を試してみているのだが、インストールしていざブラウザからアクセスしてみると、undefined methodのエラーが出てしまう。どのページにアクセスしてもダメ。</p>
<p>エラーメッセージ読んでも、そもそも#to_cssメソッドがどこにあるのかもわからんのだが、名前からしてLESSのコンパイルでトチってそうだという想像をしている。でもそれ以上はわかんない。ググっても情報はほとんどないし。</p>
<p>試しにrails newから全部やり直してみたりしたのだが、それでも尚ダメだった。READMEの通りにやってるはずなんだけどなぁ……。使ったコマンドは以下のみ。</p>
<pre><code>rails new TestApp
(Gemfileを編集)
bundle install
rails g bootstrap:install less
rails g bootstrap:layout application fluid
rails g Scaffold User name:string mail:string
rake db:migrate
rails g bootstrap:themed Users
rails s
</code></pre>
<p>仕方ないので他のGem使おうかと。んー……なんなんだろ。</p>
]]></description>
            <link>https://chroju.dev/blog/2014-01-09-post</link>
            <guid isPermaLink="false">2014-01-09-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 08 Jan 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[今年はほぼ日からEDITに浮気しました]]></title>
            <description><![CDATA[<p><a href="http://www.flickr.com/photos/chroju/11754549826/"> title="ほぼ日→EDIT by chroju, on Flickr"><img src="http://farm4.staticflickr.com/3816/11754549826_38e5d312cd.jpg" width="500" height="500" alt="ほぼ日→EDIT"></a></p>
<p>浮気しました。</p>
<p>就職2年目から2年間ほぼ日手帳を使い続けたけど、今年はEDIT。ライバル側に浮気してしまいました。理由はいくつかある。ほぼ日手帳に愛想を尽かした点が多いかな。</p>
<ul>
<li>紙面サイズが小さい。EDITの方が書くスペースが多い。</li>
<li>「今日の一言」が邪魔。手帳を書くときに脇目を逸らしたくない。</li>
<li>価格が高い。一番安いタイプだと、ポリエステルカバーのザラザラした手触りが苦手。</li>
</ul>
<p>これはほぼ日が悪いというより、単に好みの問題だと思ってる。いわゆる「ほぼ日らしさ」が好きな人であれば多分たまらないんだろうし、俺も当初はそうだったんだけど、仕事で書くことが増えたり、もっといろんな用途で使いたくなってくると、徐々に物足りなくなってきた。よりシンプルで、スマートな印象があるEDITの方が魅力的に見えてしまった。</p>
<p>まだ使い始めて3日なのだが、EDITにも当然いまいちだなぁという点はある。</p>
<ul>
<li>ペンを挿すパーツがチープで心許ない。ほぼ日のバタフライストッパーは素敵。</li>
<li>紙質がすべっすべで気持ちいいんだけど、心持ちめくりにくい。</li>
<li>ほぼ日の月ごとにインク色が違うのは、パラパラめくるときにすごいわかりやすかった。</li>
</ul>
<p>このあたりはトレードオフなので、両方使ってみて「より良い方」を選べばいいだけの話。ただし、手帳は1年ものなので、なかなか「気に入らないから買い直そう」というのがすぐ出来ないのが痛いところ。本来あるべき姿としては、あまりツールが何であるかにこだわりすぎず、出来るやり方でやってみることこそが重要なんだろう。物理的なガジェットだけじゃなく、タスク管理サービスとかでもそうだと思う（Wunderlistがいいか、Google Tasksがいいかで1か月悩んだことへの自戒。。。）</p>
]]></description>
            <link>https://chroju.dev/blog/2014-01-05-post</link>
            <guid isPermaLink="false">2014-01-05-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 04 Jan 2014 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『Webを支える技術』読了]]></title>
            <description><![CDATA[<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774142042/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51qo6pgjaSL._SL160_.jpg" alt="Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774142042/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.03.01</div></div><div class="amazlet-detail">山本 陽平 <br />技術評論社 <br />売り上げランキング: 13,031<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774142042/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>言わずと知れた名著、なんですかね。元はと言えば山本陽平氏の<a href="http://yohei-y.blogspot.jp/2005/04/rest_23.html">REST解説記事</a>をWebで見かけて、えっらいわかりやすかったもんで著作にも手を出してみたという感じ。あとRails触り始めたというのもあって、一度は読んでおくべきかな、と。</p>
<p>全体の印象としてはかなり平易な言葉で書かれてて読みやすい。ただ、多少の前提知識は必要とされるので、ウェブサービスを初めてこれから作ってみようみたいな人が読んでも厳しいと思う。自分はRailsかじってたので、それになぞらえて読み進めることができた。というか、この本読むとRuby on Railsが本当にRESTfulに設計されているんだってことが追認できる。</p>
<p>目次</p>
<ul>
<li>
<p>第1部 Web概論</p>
</li>
<li>
<p>第1章 Webとはなにか</p>
</li>
<li>
<p>第2章 Webの歴史</p>
</li>
<li>
<p>第3章 REST ―― Webのアーキテクチャスタイル</p>
</li>
<li>
<p>第2部 URI</p>
</li>
<li>
<p>第4章 URIの仕様</p>
</li>
<li>
<p>第5章 URIの設計</p>
</li>
<li>
<p>第3部 URI</p>
</li>
<li>
<p>第6章 HTTPの基本</p>
</li>
<li>
<p>第7章 HTTPメソッド</p>
</li>
<li>
<p>第8章 ステータスコード</p>
</li>
<li>
<p>第9章 HTTPヘッダ</p>
</li>
<li>
<p>第4部 ハイパーメディアフォーマット</p>
</li>
<li>
<p>第10章 HTML</p>
</li>
<li>
<p>第11章 microformats</p>
</li>
<li>
<p>第12章 Atom</p>
</li>
<li>
<p>第13章 Atom Publishing Protocol</p>
</li>
<li>
<p>第14章 JSON</p>
</li>
<li>
<p>第5部 Webサービスの設計</p>
</li>
<li>
<p>第15章 読み取り専用のWebサービスの設計</p>
</li>
<li>
<p>第16章 書き込み可能なWebサービスの設計</p>
</li>
<li>
<p>第17章 リソースの設計</p>
</li>
</ul>
</blockquote>
<p>ポイントピックアップ</p>
<ul>
<li>
<p>POSTとPUTの使い分け。前者は作成したリソースURIをサーバーが規定し、後者はクライアント（というかリクエスト）で規定できる。</p>
</li>
<li>
<p>HTTPメソッドには「冪等性」と「安全性」の性質がある。冪等性は「ある操作を何度行っても結果が同じこと」。DELETEメソッドは何度発行しようと同じ結果になる。安全性は「操作対象のリソースの状態を変化させないこと」。GETを発行してもリソースは変化しない。POSTは冪等でも安全でもない。</p>
</li>
<li>
<p>セマンティックWeb、ウェブの意味論。リソースの意味をどのようにプログラムから処理するか？</p>
</li>
<li>
<p>RESTfulなウェブサービスの性質はアドレス可能性、接続性、統一インタフェース、ステートレス性の4つ。</p>
</li>
<li>
<p>アドレス可能性 ＝ URIで一意にリソースを指し示せる性質。</p>
</li>
<li>
<p>接続性 ＝ リソースをリンクで接続する性質。</p>
</li>
<li>
<p>統一インタフェース ＝ GET/POST/PUT/DELETEということ（でOK？）。</p>
</li>
<li>
<p>ステートレス性 ＝ HTTPはステートレス。但しCookieによるセッション管理が現実には行われる。</p>
</li>
<li>
<p>Webサービス設計において重要なことはシンプルに保つこと、リソースを基準として考えること、POSTでだいたいなんでもできること（え？）</p>
</li>
<li>
<p>リソースはそれ自身ですべての情報を表せた方が通信が効率的になるため、あえて正規化を行わない（このへん、DB設計と同一視してたわ）</p>
</li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/2013-12-28-post</link>
            <guid isPermaLink="false">2013-12-28-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 27 Dec 2013 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Windows 8(VAIO Pro)買って最初にやったことと注意点]]></title>
            <description><![CDATA[<p>本家ブログの方に書いたけど<a href="http://chroju.hatenablog.jp/entry/20131211/vaio_pro_11_so_cool_mobile_pc">VAIO Pro買った</a>。1週間ちょいほど、主に仕事で使ってるが、やっぱ軽いは正義。持ち歩いてもあんまり負担にならない。スペック的にも申し分ないし。不満点といえば、マットな触感のボディが案外傷つきやすいことぐらい。これタッチパネル有りのモデルだと質感違うんだっけ。そっちのが良かったりするのかも。</p>
<p>で、Windows8はこれまでMac上に載せた仮想マシンで遊んでただけで、今回初めてきちんと初期設定とかしたので、いろいろまとめてみる。Win8が使いづらいってのは、要するにタブレット用のMetro UIを何も考えずデスクトップ用UIに統合させちゃったからで、この点上手く付き合えばそこまで悪くないOSかなとは思う。動きは軽い印象。</p>
<h1>インストール</h1>
<p>インストールは対話型に順序良く進めれば別に迷うこととかはないんだけど、一点だけ注意すべき点がある。ユーザーアカウント作るときにMicrosoftアカウントがあるなら入れてくれと確か言われるんだが、これ、入れない方がいい。というのも、入れるとMSアカウントに登録している名前がそのまま勝手にユーザーネームとして採用されるからだ。当然ながらユーザーディレクトリ名もMSアカウントの「名」部分が使われる。すなわちMSアカに「山田太郎」と登録していると、C:\Users\太郎フォルダと永劫付き合っていくことになる。これは頭抱える。</p>
<p>はっきり言って糞仕様というか、こういうアカウントの「意味」が範囲を広げてしまうような昨今の風潮が自分は好きじゃない。例えばGoogleアカウントはもともとGmail目的で、つまりプライベートで使うものとして7年ぐらい前に取得したんだけど、いまや「ソーシャル」サービスであるGoogle+と勝手に結び付けられてしまって、当初こちらが意図していた「意味」を逸脱してしまっている。俺の持ってるMSアカウントも元を正せばSkypeアカウントだったんだが、それがまさかMSに買収され、さらにはOSのユーザーアカウントにまで流用されるとは思ってなかった。まぁアカウントの統合はわかりやすくて良いことかもしれないが、個人的には大変気持ち悪い。</p>
<p>MSアカウントを使うのが気持ち悪い人や、ユーザーディレクトリに2バイト文字使いたくない人はローカルでアカウント作りましょう。MSアカウントには後からでも紐付けられるんで。</p>
<h1>アップデート</h1>
<p>インストールしたら早速8.1に上げた。上げていいこともあんまなかったけど、悪いこともそんなない気がする。スタートボタン復活が8.1の目玉らしいけど、あれ押しても例のタイル型UIのスタート画面が出てくるだけで、何の意味もないです。強いて言えば右クリックしてみると真価を発揮する、かも。</p>
<p><a href="http://www.flickr.com/photos/chroju/11491905623/"> title="スクリーンショット_2013-12-11_18_55_36 by chroju, on Flickr"><img src="http://farm6.staticflickr.com/5483/11491905623_ced037d32a.jpg" width="396" height="500" alt="スクリーンショット_2013-12-11_18_55_36"></a></p>
<p>見たまえ、このよく使うはずなのにどこ行ったかわからん機能をとりあえず寄せ集めました感。美しくない。</p>
<p>ちなみにアップデートはWindowsストアからです。Windows Updateじゃないです。いまだにWindows Updateがどこにあるかわかんないんだけど、どこにあんの？ MS公式のヘルプ見たら「検索から探せ」とか酷い答え返ってくるんだけど。。。</p>
<p>あとハードウェアによっては独自のドライバアップデートツールとかあるんでそのへんも忘れずに。VAIOならVAIO Updateね。</p>
<h1>設定変更</h1>
<p>適当にコンパネとか。</p>
<ul>
<li>フォルダオプションで不可視ファイルの表示と拡張子の表示。必須。</li>
<li>タスクバーとナビゲーションの設定でサインイン時にデスクトップを表示させる。</li>
<li>マウスの速さ適切化。あとCtrl押下でマウス位置表示させる。すぐいなくなるので。</li>
<li>電源オプションで無操作スリープ時間の変更と、休止状態の有効化。</li>
</ul>
<h1>ソフトウェアインストール</h1>
<p>ここまできてやっとソフト入れます。Win8アプリは普通にPCとして使う場合は不便そうなので入れてない。</p>
<ul>
<li>Google IME</li>
<li>Firefox</li>
<li>Evernote</li>
<li>Dropbox</li>
<li>Kaoriya版Vim(GVim)</li>
<li>Avast!</li>
<li>Janetter</li>
<li>Keepass</li>
</ul>
<p>ウイルスソフトとTwitterクライアントは今何が流行りなんですかね。よくわかんないので取りあえずAvast!とJanetter。もうリーマンやってんだからウイルスソフトぐらい買えって話だけど。</p>
<p>テキストエディタは迷ったけどMacと同じくKaoriya版Vim入れました。慣れるともうVimから離れられんね。OS選ばず同じ使い方できて楽だし。ちなみにGVimとしてしか使ってないです。コマンドプロンプトからVim開くのはなんかテンション上がんなくて。</p>
<p>ここまでやったらEvernoteとDropboxの同期でしばし待ち。</p>
<h1>ソフト設定移行</h1>
<p>ソフトの設定連携。というか、Dropboxの中に設定はほぼエクスポートしてるんで、DBの同期が終わった時点で半分移行は済んでいる。</p>
<h2>Firefox</h2>
<p>FEBEっていうアドオンが便利なので良いです。アドオン、ブックマーク、設定とかそのへんまとめて自動的に吐いてくれる。さすがにGreasemonkeyは無理っぽいけど。</p>
<p><a href="https://addons.mozilla.org/ja/firefox/addon/febe/">FEBE</a></p>
<h2>dotfiles</h2>
<p>vimrcとvimperatorrcはdotfilesとしてDropboxにまとめているので自動同期。あとはシンボリックリンク貼っちゃえば終わりです。</p>
<pre><code>mklink _vimrc Dropbox/dotfiles/.vimrc
mklink _vimperatorrc Dropbox/dotfiles/.vimperatorrc
</code></pre>
<h2>vimrc</h2>
<p>だいたいはMacで使えてたvimrcそのままでイケるんだけど、一部設定変更が必要だったり。例えばファイルパス指定しているような箇所はOSによって当然異なるので、if has("Win64")で分岐させる。あとGVimだとcolorschemeの設定がgvimrc優先になるとかそのへん注意。</p>
<h2>vimperator</h2>
<p>vimperatorrcの同期は上に書いたDropboxでいいとして、pluginの同期まんどくせって思ってたんだけど、<a href="https://github.com/vimpr/vimperator-plugins/blob/master/plugin_loader.js">plugin_loader.js</a>で解決した。これ便利すぎてヤバイ。</p>
<pre><code>let g:plugin_loader_roots="~/.vimperator/vimperator-plugins/ ~/vimperator/vimperator-plugins/"
let g:plugin_loader_plugins="_libly,direct_bookmark,sbmcommentsviewer,caret-hint,appendAnchor,evernote-clearly-vimp,stella,feedSomeKeys_3,commandBookmarklet,copy"
</code></pre>
<p>g:plugin_loader_rootsにプラグインが入れてあるフォルダのパスを指定し、g:plugin_loader_pluginsに読み込むプラグイン名を列挙するだけでプラグインを読み込んでくれる。シンボリックリンクなんて不要。プラグインについてはたいていのvimperator遣いはvimpr/vimperator-pluginsをクローンしてると思うんで、組み合わせれば最強に近い。他から持ってきたプラグインについては別途パスを指定してやればいいだけだし。</p>
<p>だいたいこんなとこ。最近はDropboxとか使うとすんげー簡単に環境同期できちゃうので楽なことこの上ないッスね。</p>
]]></description>
            <link>https://chroju.dev/blog/2013-12-22-post</link>
            <guid isPermaLink="false">2013-12-22-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 21 Dec 2013 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[SSHでサーバーリモートログインする際のあれこれまとめ]]></title>
            <description><![CDATA[<p>うちのには仮想開発環境としてCent OSが立っているんだけど、この前コイツの中で作っているプロジェクトをGithubに突っ込もうと思ったらGithubで登録してるRSA認証のキーフレーズ忘れてて軽く詰んだ。で、仕方ないのでもっかい鍵作ってやり直そうと思ったら、SSHの鍵認証のやり方とかそのへんも全部吹っ飛んでたので改めてまとめ直しとくことにする。やったことまとめないのダメ、絶対。</p>
<h2>環境</h2>
<p>今回はいわゆる「リモートのサーバーにSSHを使ってログインする」場合と「GithubにSSHでpushする」場合を想定する。使用するクライアントはMac OS X、サーバーはCent OS。ちなみにシェルはbash。</p>
<h2>そもそもSSHってなんぞや</h2>
<p>セキュアなリモート通信用プロトコル。セキュアな、と言っているのはTelnetあたりが平文でパスワード贈っちゃうのに対して、SSHが暗号化に対応している点を指す。で、暗号化には今多くの場合RSA（公開鍵暗号方式）を用いているらしい。だから秘密鍵と公開鍵を作ってローカルとリモートにそれぞれ配置して云々という設定が必要になる。あとGitHubもリモートレポジトリにつなぐ時にSSHが使える。</p>
<h2>リモートサーバー接続手順</h2>
<p>まずリモートサーバーにSSHでつなぐときの手順。</p>
<h3>1. 認証鍵の生成</h3>
<p>Linuxには鍵生成のコマンドがあるので、それを使う。</p>
<blockquote>ssh-keygen -t rsa</blockquote>
<p>-tが鍵のタイプを示すオプション。ここではrsaを使うのでそのまま。あとは促されるままに保存先ディレクトリとパスフレーズを入力してやれば鍵が生成される。パスフレーズは忘れるとどうにもならんので絶対控える。<strong>絶対控える。</strong></p>
<p>作成された鍵はデフォルトだと~/.ssh/配下に置かれる。id_rsaが秘密鍵でid_rsa.pubが公開鍵。</p>
<h3>2. 公開鍵の転送</h3>
<p>鍵が出来上がったので、早速だが公開鍵をリモートサーバーに転送してやる。転送の方法はいろいろ考えられる（一番アレな手段だと中身コピペしちゃえばいいだけだったりする。単なるテキストだし）けど、scp使うのが個人的には楽かな、と。まぁscpもSSH利用したファイル転送なので、SSH使うためにSSH使っているという矛盾っぽいところはあるんだが。細かいことは置いといて。</p>
<blockquote>scp ~/.ssh/id_rsa.pub hoge@fuga.com:~/.ssh/</blockquote>
<p>SCPコマンドの第一引数が送るファイル、第二引数が転送先のユーザー名@ホスト名:ファイルパス。通信するときに指定したユーザー名のパスワードを聞かれるので答えてやる。SSHの認証の方式はいくつかあって、デフォルトではパスワード認証の設定になっているので、こういうログインの仕方になる。今このエントリの作業でやっているのは、パスワード認証から公開鍵認証に変えるための手順。</p>
<p>ちなみにホスト名は当然ながら名前解決出来なきゃアウトなので、ローカルの開発環境とかだったらhostsに入れとくとかなんとか忘れずに。あと俺みたいにSSH1回設定したんだけどいろいろ忘れちゃったんでもっかい鍵作ってまーす(<em>ﾉω・</em>)ﾃﾍ)みたいな人（あんまいないだろうが）はすでにリモート側のsshd_configが書き換わってたりするので注意。ていうか俺が少しやられた。</p>
<p>例えばセキュリティ面の配慮でポート番号を22から変えてると当然ながら通信できない。-Pオプションでポート番号を明示的に指定する。あるいはすでにSSHをパスワード認証で使うのをNGにしてる場合もある。これについては後述。</p>
<h3>3. 公開鍵の登録</h3>
<p>今度はリモートサーバー側に入って、送られた公開鍵のファイル名を替えてやる。</p>
<blockquote>mv ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys</blockquote>
<p>authorized_keysが公開鍵登録用ファイルの名前。複数の公開鍵を登録することもできる。その場合は改行挟んで追記でいいのかな。アクセス元を制限してやったりとかできる記法もあるらしいが、ここでは割愛。</p>
<p>あとアクセス権も変える。</p>
<blockquote>chmod 600 ~/.ssh/authorized_keys</blockquote>
<h3>4. sshd_configの設定</h3>
<p>リモートホスト側の/etc/ssh/sshd_configファイルがSSHの設定ファイルになっているので、公開鍵認証が出来るよう、設定を書き換える。</p>
<blockquote>RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys</blockquote>
<p>読めば字の如くだが、上からRSA認証許可、公開鍵認証許可、公開鍵ファイルパスの指定。デフォルトでは全部コメントアウトされていると思うので、#を外して設定を有効化する。おそらく一番下のオプション書き換えでauthorized_keysファイル以外のファイルも公開鍵に指定できるんだと思うけど、やったことないのでわからん。</p>
<p>逆にパスワード認証（SCPでさっき使ったヤツ）はこれで要らなくなるので無効化する。</p>
<blockquote>PasswordAuthentication no
ChallengeResponseAuthentication no</blockquote>
<p>上がパスワード認証の不許可。下はチャレンジレスポンス認証の不許可。こちらもnoにしとかないとパスワード認証が完全にオフにならないとどっかで聞いた。うろ覚え。。。</p>
<p>あと気になるようであれば、port行を変えればポート番号も変えられる。22はウェルノウンポートなので、変えておいた方が無差別な攻撃は防げるはず。</p>
<p>書き換えたらsshサービスを再起動してフィニッシュ。</p>
<blockquote>/etc/init.d/sshd restart</blockquote>
<p>これでローカル側からsshコマンド打ってやればつながる。パスワードを聞かれたら、公開鍵作る時に入れたパスフレーズを答えればOK。</p>
<h3>5. Githubにつなぐ場合</h3>
<p>Githubにつなぐときは公開鍵の中身を全部コピーして、GithubのAccount Settings > SSH Keysにベタッと貼り付けてやればそれでOK。はじめはリモートホストにつなぐときと別の鍵を生成してやった方がよいのかな？とか思ってしまったが、公開鍵認証の意味を考えてみると、別の鍵を作ってやる必要はなかったので特にこれで問題はない。ちなみに俺の話をすると、これまで.ssh配下にcentosとかgithubとかフォルダ作ってそれぞれの鍵ファイルを管理してた。うん、無駄だったんやね……。</p>
<p>リモート側のサーバーで環境共有したい場合はgit cloneで持ってくる。</p>
]]></description>
            <link>https://chroju.dev/blog/2013-12-08-post</link>
            <guid isPermaLink="false">2013-12-08-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 07 Dec 2013 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Bundle execサボってエライ目にあった]]></title>
            <description><![CDATA[<p>今までよくわからなくてほっといたけどこれ使わなきゃダメだったわ……</p>
<blockquote>bundle exec rails g devise:install</blockquote>
<p>Railsのログイン機構作るためにDevise入れてみてたんだけど、本来上のコマンドを入れるべきところでふつーにrails g devise:installとしてしまった。そしてrails g devise User ゴニョゴニョ。すると何が起きたか。</p>
<p><a href="http://www.flickr.com/photos/chroju/11270239633/"> title="スクリーンショット_2013-12-08_22.57.54-3 by chroju, on Flickr"><img src="http://farm4.staticflickr.com/3751/11270239633_8cc563c384.jpg" width="500" height="404" alt="スクリーンショット_2013-12-08_22.57.54-3"></a></p>
<p>い……いねぇ……。確かにgenerateしたはずなのにurbはあるけどコントローラーもヘルパーもねぇ……。でもね、この状態でブラウザ開くとなんかログインできるんだよ。動くんだよ。幽霊かと。お前ソースはどこにあんのかと。んで探ってみたらあった。</p>
<p><a href="http://www.flickr.com/photos/chroju/11270148454/"> title="スクリーンショット 2013-12-08 22.57.19 by chroju, on Flickr"><img src="http://farm4.staticflickr.com/3754/11270148454_9e29b9f724.jpg" width="500" height="291" alt="スクリーンショット 2013-12-08 22.57.19"></a></p>
<p>なんかすげえとこにあった！！！！</p>
<p>あー、要はこれがbundle execの有無による違いね。bundle execプレフィックスを付けると今の環境のGemfileからインストールしてくれるけど、付けない場合はシステム側のRubyにdeviseをインストールしてしまう。だからこんなとこにいろいろ入ってしまったと。あー。失敗だ……。</p>
<p>なんかbundle execを省略する方法もあるらしいけど、よくわかってないものをよくわかってないままに省略するのも危険なので、しばらくは自戒込めてプレフィックス付けるようにします。</p>
]]></description>
            <link>https://chroju.dev/blog/2013-12-08-02-post</link>
            <guid isPermaLink="false">2013-12-08-02-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 07 Dec 2013 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[GTD環境 2013年秋版]]></title>
            <description><![CDATA[<p>先日GTDの聖典を読み込み、ちょっと久しぶりにGTD環境を再構築した。今年に入ってからCatch Notesを使ったGTDを試すも、PCを使ってる時にわざわざブラウザからタスク追加するのが面倒になり、初夏あたりでtodo.txtに乗り換えた。しかしこれもソートがしづらいだとか、複数のリスト持つのが面倒（たぶん俺のVimスキルがアップすればなんとかなるんだけど）などがあり、晩夏あたりでストップしてしまっていた。それから先々週頃までGTD環境は空白状態。そして2ヶ月ぶりぐらいの再構築に至ったわけだが、やっぱしGTDやっとくとなんとなく気が楽ね。</p>
<p>で、どうにもツールに振り回されすぎてる嫌いがあるので、ここらでもう一度自分がやっていることをまとめておく。やりたいことを一つに定めれば、どんなツールを使っていようとも迷うことはない。そういう状態に持っていきたい。</p>
<h3>仕事とプライベートで環境を分ける</h3>
<p>入社当初、Toodledoで仕事もプライベートもすべてのタスクを管理していたことがあったのだが、これは無理だった。自分の職場の事情故の話ではあるが、会社PCではクラウドサービスの使用が禁じられているし、また仕事の資料を家に持ち帰ることはできない。つまり仕事のタスクをいつでも見られるようにとToodledoに入れておいても、会社ではそれを確認できないし、家では仕事の状況を確認する資料がないからタスクレビューができない。</p>
<p>よって今は仕事とプライベートのGTD環境を完全に分けている。仕事ではTaskChuteを使い、TaskChuteはGTDには向かないなどという声もあるが、まぁ仕事のタスクなんて今すぐやるか、いつかやるかのほぼ2択なので、降ってきたタスクを適当な日付にぶちこんでおしまいである。「いつかやる」リストに行くはずのタスクは1週間後の日付でとりあえず入れておけばいいだけだし、「連絡待ち」リストに行くタスクは適したタイミングで「○○さんに例の件確認」と入れればいい。正直、仕事はこれで本当にうまく回っている。</p>
<p>仕事とプライベートのGTD環境を分けることには利点もある。TaskChuteは会社のファイルサーバーに置いてあるので家からは確認のしようがなく、ON-OFFのメリハリがつくようになった。家に帰ってタスクリストを開いたら、仕事の予定がいっぱい入っているなんて状態は、精神によろしくない。</p>
<h3>軌道修正を図りやすくする</h3>
<p>ではプライベートのGTD環境とは何のためにあるのかということだが、軌道修正を図りやすくするためのものだと考えている。</p>
<p>プライベートのタスクとは何か。主には家事、勉強、娯楽に分けられる。このうち家事は細切れのタスクがほとんどだが、娯楽と勉強はPJのような形になることが多い。それは例えばRailsを習得する、だったり、秋の気になるアートイベントに行きまくる、だったり。</p>
<p>ただ、プライベートで抱えるPJを毎日コツコツ回せるかというと、なかなか時間は取れないもので、中には1ヶ月近く放置になってしまうものもある。そんなときに、「あれ？そういえばあれやりたくてやりかけにしてたけど、どこまでやったっけ？」とならないよう、フローの洗い出しと経過の記録を怠らないようにする。また進んでないPJにすぐ気付き、対策を打てるようにしておく。</p>
<p>そして長く時間を費やす「PJ」は、往々にして相応の理由がある。例えばRails習得はWeb系の転職を考えているからであり、ではWeb系になぜ転職したいのか？といえば、、、といった具合に、理由はより大きな理由に遡及できる。自分の立ち位置を見失わないためにも、理由の記録と記憶は必要だ。これを管理するには、GTDでいう高度の概念がふさわしい。</p>
<h3>ユビキタスキャプチャーを重視する</h3>
<p>週次レビュー以上に自分が意識しているのがユビキタスキャプチャー。いくらトリガーリストがあると言っても、やはり2時間うんうん唸ってタスクを書き出したところで、一度忘れたタスクは思い出しづらい。思いついたこと、インプットされた情報はとにかくすぐメモる。この方が確実だ。</p>
<p>ただ、自分はどうもこれが苦手で。あまり深く考えない性格なのか、気付けば新たな情報を右の耳から左の耳へ聞き流していることがある。どうすりゃいいんだろうな、これ。</p>
<h3>ToDoリストに手間をかけすぎない</h3>
<p>ToodledoはGTDに最適だとよく言われる。自分も使っていたが、そのことは肯定できる。だが、ちょっとガチガチに設定できすぎるような気もする。アレに凝りすぎると、ToDoリストを管理するというToDoに1日相当な時間を使いそうになる。</p>
<p>だからToDoリストは手間をかけすぎないのがいい。先に言及したTaskChuteはその点すごく楽で、開いたらAlt+s -> aで行を追加し、日付とタスク名と見積時間を入れれば登録完了だ。プロジェクトの入力も可だが、そのへんはお好みで。</p>
<p>プライベートでは今、Wunderlistを使っている。これもまた実にシンプルなツール。次点でTodo.txtだが、これはすでに述べた通りちょっと単機能すぎる。Google Tasksもまた然り。</p>
<h3>「いつやるのか」を明確にする</h3>
<p>GTDは元来、タスクのスケジューリングは必要としない。GTDにおいては、ToDoリストとは「時間があるときにやることのリスト」であり、やる時間が決まっているものはカレンダーに登録するべきだからだ。でも現実、そう上手くいくか？ この1週間のどこか空いた日で必ずやるとか、そういうタスクもあるだろう。</p>
<p>自分はWunderlistのスターを「スケジューリング」として使っている。スターが付いたタスクとは、「今週やるべきタスク」だ。「時間があるときにやること」の中でも、最優先でやるべきことにスターを付けている。</p>
<p>タスクのスケジューリングは重要だ。いつまでもリストに眠り続けるタスクを産まないためにも。</p>
<h3>現在の環境</h3>
<p>以上の方針を踏まえた上で、次のようなGTD環境（プライベートver）を回している。</p>
<ul>
<li>
<p>Wunderlist => タスクリスト</p>
</li>
<li>
<p>すべての「やること」がここにある。</p>
</li>
<li>
<p>リストはNext、Someday、Want＝やりたいこと、各PJ。</p>
</li>
<li>
<p>PJはノートを使って目的と〆切を書いている。タスクには最初マイルストーンだけを置いておき、実際に進めながら細かいタスクへ分解している。</p>
</li>
</ul>
<p><a href="http://www.flickr.com/photos/chroju/10776411723/"> title="スクリーンショット 2013-11-10 21.20.34 by chroju, on Flickr"><img src="http://farm6.staticflickr.com/5548/10776411723_fee1923491.jpg" width="500" height="410" alt="スクリーンショット 2013-11-10 21.20.34"></a></p>
<ul>
<li>
<p>Google Calendar => 予定管理</p>
</li>
<li>
<p>アナログ管理とすべきかだいぶ悩んだけど、繰り返しの予定とかが管理しやすいのでデジタルに軍配。</p>
</li>
<li>
<p>基本はプライベートの予定。仕事や休日や深夜のものだけ入れる。</p>
</li>
<li>
<p>「やる日が決まっているタスク」もここに入れる。</p>
</li>
<li>
<p>Dropbox&#x26;txt => ユビキタスキャプチャーその1</p>
</li>
<li>
<p>デジタルのユビキタスキャプチャー管理。メモはやっぱプレーンテキスト最強。</p>
</li>
<li>
<p>Macで扱うときはQFixHowmを使っている。</p>
</li>
<li>
<p>Androidで扱うときはDraft。これ最強。このエントリーもDraftで書いてます。</p>
</li>
<li>
<p>ポイントはクイック入力機能、Markdownの入力補助、全文検索機能。</p>
</li>
</ul>
<p><a href="https://play.google.com/store/apps/details?id=com.mvilla.draft&#x26;hl=ja"> target="_blank" rel="nofollow"><img class="alignleft" align="left" src="https://lh6.ggpht.com/AwZSLYU7QIp0nnwNEzPxR1Nmx03aKnOEmLAA_SOCW0miZ75oblV6JZU4NS6Lf3DB2jU1=w300" width="85" style="margin:0px 10px 1px 5px;padding:0px;border:none"></a><a href="https://play.google.com/store/apps/details?id=com.mvilla.draft&#x26;hl=ja"> target="_blank" rel="nofollow"><strong><span style="font-size:120%">Draft 0.12</span></strong></a><br>カテゴリ: 仕事効率化<br><a href="https://play.google.com/store/apps/details?id=com.mvilla.draft&#x26;hl=ja"> target="_blank" rel="nofollow">Google Playで詳細を見る</a><br style="clear: both;"></p>
<ul>
<li>
<p>Dropbox&#x26;txt => GTDの中枢</p>
</li>
<li>
<p>ユビキタスキャプチャー用のフォルダの中にGTDというフォルダを掘ってる</p>
</li>
<li>
<p>ここに何を入れているかというと、GTDで使う資料系一式。</p>
</li>
<li>
<p>例えばGTD.txtは、自分流GTDのフローと、各「高度」を書き込んでいる。GTDってなんだっけ状態になったらここに戻ってくる。</p>
</li>
<li>
<p>あとトリガーリストとかもここ。GTD関連でタスクでないもの全般って感じか。</p>
</li>
</ul>
<p><a href="http://www.flickr.com/photos/chroju/10776412153/"> title="スクリーンショット 2013-11-10 21.21.54 by chroju, on Flickr"><img src="http://farm8.staticflickr.com/7401/10776412153_43304f8401_n.jpg" width="279" height="320" alt="スクリーンショット 2013-11-10 21.21.54"></a></p>
<ul>
<li>
<p>ほぼ日手帳 => ユビキタスキャプチャーその2</p>
</li>
<li>
<p>アナログのユビキタスキャプチャー。仕事中は専らこれ。</p>
</li>
<li>
<p>予定もタスクもデジタル管理にしちゃったので、もはやただの日付入りメモ帳。</p>
</li>
<li>
<p>ホントはライフログっぽいこともしたいんだけど、TaskChuteがあるしいいやってなってる。</p>
</li>
<li>
<p>来年はEDITに浮気予定。ほぼ日よりシンプルで使いやすそうなので。</p>
</li>
</ul>
<p>こんなところ。正直プレーンテキスト最強論者（デバイスを選ばない、フォーマットフリー、Dropboxで共有＆バックアップも瞬時、Vimで編集もクソ楽）なので、全部プレーンテキストにまとめたいとも思ってるんだが、なかなか上手くいかなかった。まぁ予定はまず無理だし、タスクもちと辛い。いや、やってやれないこともないのだが、面倒だ。期日順に並べ替えたり、PJと期日の2つの観点からタスクを絞り込んだりとか、そういう有機的な操作はやっぱり専用アプリを使ったほうがいい。すなわちそれがWunderlistだった。</p>
<p>あと悩んでるのが、日課や週末の家事のような定期的タスク。Googleカレンダーに試しに繰り返しの予定で入れてはみたが、毎日同じ予定が表示されるのはちょっとウザかったり。かといってWunderlistで繰り返し設定して、毎日ちまちま消してくのもウザい。プレーンテキストでリスト化しとくのが楽かなーと思うのだが、それだと「やることは全部Wunderlistに集約」という原則が崩れてしまうし。むー。</p>
<p>とりあえずこの路線を1年は続けたい。浮気して、違うツール設定して試して、また戻ってきてなんて時間は、GTDの根本に反するような無駄に過ぎない。</p>
]]></description>
            <link>https://chroju.dev/blog/2013-11-10-post</link>
            <guid isPermaLink="false">2013-11-10-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 09 Nov 2013 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『RailsによるアジャイルWebアプリケーション開発』読了〜「設定より規約」なら、規約をまず知りたい]]></title>
            <description><![CDATA[<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4274068668/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51Gibg-iYTL._SL160_.jpg" alt="RailsによるアジャイルWebアプリケーション開発 第4版" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4274068668/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">RailsによるアジャイルWebアプリケーション開発 第4版</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.03.01</div></div><div class="amazlet-detail">Sam Ruby Dave Thomas David Heinemeier Hansson <br />オーム社 <br />売り上げランキング: 138,293<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4274068668/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>Rails入門の定番書。このブログで何度か読んでいる途中経過を報告してきたか、ようやく読み終えることができた。読了というか、読み終わったのはもうだいぶ前ではあるんだけど。しかし予定していた以上に時間をかけてしまった。。。最初は写経しながら読んでいたのだが、どうにも時間がかかりすぎてイライラしていて、途中からはザーッとRailsの概略を掴むためだけのような読み方になってしまった。写経した方がやっぱり頭には入ると思うのだけど、それでサンプルアプリを作ったところで、応用してすぐ自分のアプリを作れるとは限らなくて、なんとももどかしい。結果としてはまだ消化しきれてなくて、行ったり来たり読み返しながら自分なりにアプリを作り始めているのが今の段階。</p>
<p>この本は表題通り、架空のアジャイル開発案件を進めるかのように、徐々にRailsアプリを作る過程をなぞっていくことで、Railsで出来ること、Railsでアプリを作ることを教える構成を取っている。なので実践的でわかりやすい反面、解説なしにいきなりソースを提示されたりもするので「なぜこういうコードで動くのか？」が掴みにくいことも少なくなかった。アプリの完成まで読み進めると、その後に「Rails詳説」としてRailsの規約やらフレームワークを解説するページが現れるのだが、個人的には正直逆の構成の方が掴みやすい。あるいはアジャイル開発を1段階進めていくごとに、そこで書いたソースの詳細な解説を挟むようにしてほしい。</p>
<p>というのも、Railsはコードを省略したり、フレームワークによって自動生成されたりするものが非常に多い。だから初見ではどこまで書けば良いのか、どこからオートで作り上げてくれるのか、感覚が掴めないのだ。俺はウェブアプリケーションとしては初歩的なJavaアプリの経験しかないのだが、それと比べてRailsのアプリ構築は遥かに簡単な印象を受ける。正確に言えば、自分で書かなくてはならない部分が少ない。しかしそれ故に、手で書かなかった部分がどう動いているのかがわかりづらく、技術を手中に収めた感覚がない。Javaのウェブアプリはプラグインなどを使わない限りは「書いたものが動く」感覚だったので、手とアプリが連動しているという錯覚があった。</p>
<p>本書のような「実際に作る過程を見せる」という技術書は世の中に数多くあるし、基本的にはその方が「わかりやすい」本になるのだと思う。が、ことRailsに関しては作る前に「Railsは何を成してくれるのか」を解説してくれる本が必要なんじゃないかと。もちろん、本書においては「Rails詳説」の章がその役割を果たしているわけで、もう少し読み込まないとRailsをモノには出来そうにない。</p>
<p>次の本としては、これまた定番であるレシピブックを買った。これとRails詳説を片手に、Railsがどう動くのか？を学びながら、まずはローカル環境でアプリを作ってみる。外観まで含め、年内にきちんと形になるところまで持っていきたい。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4797363827/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41Tnr3W6b0L._SL160_.jpg" alt="Rails3レシピブック 190の技" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4797363827/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Rails3レシピブック 190の技</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.03.01</div></div><div class="amazlet-detail">高橋 征義 松田 明 諸橋 恭介 <br />ソフトバンククリエイティブ <br />売り上げランキング: 57,121<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4797363827/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
]]></description>
            <link>https://chroju.dev/blog/2013-11-04-post</link>
            <guid isPermaLink="false">2013-11-04-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 03 Nov 2013 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[短時間に限定して図書館で情報をザッピングするという勉強法]]></title>
            <description><![CDATA[<p>新しい分野の勉強をするときって、ネットの情報だけでは不十分だったり信頼性に欠けたりするし、だから書籍に頼ろうと思うんだけど、どんな本
を選べばいいのかわからなかったりもして悩ましい。かといって時間をかけて何冊も読む暇もないし、そんなにかけるお金もない。そういうとき、
基本に帰って図書館に行ってみたら良いのですよね。</p>
<p>NISAのこともあって、投資とか金融について少し勉強しようと思い立ったのだけど、特にこの分野って一人の言い分だけを鵜呑みにすると恐ろしく
危険。じゃあ時間を決めて、5冊ぐらいをザックリとザッピングしてみようということで、図書館に行きました。本を選び、時間を決めてザッピン
グ。とにかく多くの情報に触れることを重視したので、細部はバンバン読み飛ばす。わからない単語があったら取りあえずメモだけ取っておいて、
あとでググるなり調べることにする。そんな感じで約3時間で計7冊。A4見開きいっぱいに情報を書き留めて、それなりに情報を取り入れられた感じ
がした。</p>
<p>図書館を使うメリットとしては、</p>
<ul>
<li>お金がかからない（貧乏性でサーセン）</li>
<li>手元の情報じゃ足りないと気付いたとき、すぐ追加の本を探せる</li>
<li>とにかく静かで勉強するには快適</li>
<li>ハズレの本を引いたときのガッカリ感が少ない</li>
<li>逆にもし「これは！」という一冊があれば借りて帰れる</li>
<li>後から「あのとき読んだ本もっかい読みたい」と思っても楽に後追い可能</li>
</ul>
<p>というあたりか。あ、ただ小さな図書館で勉強スペースを長時間独占したりすると迷惑だったりもするので注意ね。ちゃんと勉強が許されてるとこ
で。</p>
<p>ちなみに俺が使ったのは<a href="http://hibiyal.jp/hibiya/index.html">日比谷図書文化館</a>。大学によくあるような勉強スペースが設けられてる上、館内のPRONTOで買ったコーヒーを飲みながら本
を読んでもOKだし、平日は22時まで（！！！）やってるから仕事帰りにも寄れて超オススメ。蔵書量はちょっと少ないかもしれんけど、オライリー
本がかなり置いてあったり面白い品揃えではある。あ、当然ながらわりと混んでます。あーやっぱ東京東部で働きてぇな。。。</p>
]]></description>
            <link>https://chroju.dev/blog/2013-10-20-post</link>
            <guid isPermaLink="false">2013-10-20-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 19 Oct 2013 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[GTDの原典読んでみたら意外にいろいろ勘違いしてたという話]]></title>
            <description><![CDATA[<p>GTDというかタスク管理についてはもうだいぶ長いこと悩んできたのだが、もうなんともにっちもさっちもいかなくなってきたので、ついに原典を紐解いてみた。といっても本当の原典ではなく、実践編の方。まぁWebでつまみ食い程度とはいえ、一応GTDの理念は知った上でタスク管理してたので、実践編の方が役に立ちそうかな、と。でも実際読んでみて、案外GTDの基礎を勘違いしてることに気付いたり。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4576101714/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51rqNl71s%2BL._SL160_.jpg" alt="ひとつ上のGTD ストレスフリーの整理術 実践編――仕事というゲームと人生というビジネスに勝利する方法" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4576101714/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">ひとつ上のGTD ストレスフリーの整理術 実践編――仕事というゲームと人生というビジネスに勝利する方法</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.03.01</div></div><div class="amazlet-detail">デビッド・アレン <br />二見書房 <br />売り上げランキング: 14,427<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4576101714/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<h2>GTDは頭の中を書き出すことがすべてではない</h2>
<p>GTDってなんとなく「2時間かけて頭の中を書き出しましょう」「そのリストを1週間おきに週次レビューで見なおして最新の状態を保ちましょう」っていうのが核だと思っていたのだが、それがすべてではなかった。というより、それはあくまで始まりである。書き出して意識の外で保存するだけでは中途半端で、それを「どう処理するのか？」という点で見極めた上で、適切なリストに並べておかなくてはならない。例えば時間の決まっている行動であればカレンダーに書き込むことになるし、誰かに頼めることであれば、依頼した上で「連絡待ち」リストに入れる。今は使わないが、いずれ興味が出そうなことであれば、数日後に思い出せるようリマインダーに仕込んでおく。</p>
<p>GTDとはすなわち「絶え間なく入ってくる情報を適切に整理し、すぐ行動に移せるようリスト化しておく」ことに他ならない。単なる「タスク管理」とはその意味で異なる。</p>
<h2>「高度」という考え方を取り入れる</h2>
<p>目の前のタスクを処理する、整理する他に、GTDには高度という考え方がある。一つ一つの具体的な行動を高度0メートルとして、それを1000メートル、2000メートルという名前の「より広い視点」から位置づけるのだ。例えば「GTDの本を読んだ感想をブログにまとめる」は、より広い視点から言えば「タスク管理方法を考えなおす」というプロジェクトの一部だ。さらにこのプロジェクトは、「時間を効率的に使う」という目標の一端を担うものとなる。という具合。</p>
<p>今気になっていることをリスト化して行動に移すという水平思考と同時に、GTDにはその各行動がどう位置づけられ、どのような優先順位とすべきなのかという垂直思考の考え方がある。この点ってあまりWebのGTD系記事では触れられていない気がして新鮮だった。そして特に「プロジェクト」や「目標」の管理に手を焼いていたので、ちょっと助かった思い。</p>
<p>とはいえ、この本はプロジェクトのリストとNext Actionリストの結びつけについては明確な答えを用意していない。きちんと整理された状態であれば、自ずと各リストの関連性が見えてくるといった回答が成されていたのだが、そんな曖昧なことに任せてられるかｗというのが正直なところ。プロジェクトには進行する上でのフローがあり、各フローをいつ、どのようにこなしていくかという視点から考えて、まとめておくことが必要なんじゃないかと思う。</p>
<h2>ゴールは「常に最善の行動を取れるようになる」こと</h2>
<p>何度も書くが、GTDはタスク管理の手法、ではない。今気になっていることと、それらの位置づけ、見通しをリスト化することにより、「今すべきこと」を明らかにすることだ。単なるタスク管理では、突発タスクを割り込ませる余裕がなくなったり、先々への見通しを持たず、目先の「やること」だけに集中してしまいがちだったりする。</p>
<p>GTDでは常にすべての行動がリスト化されているので、例えば突発的なタスクがあっても、それを既存のリストの中に位置づけ直した上で、いつどのように行動すべきかを捉え直すことができる。仮にその余裕がないほどの事態であったとすれば、すぐ元の状態、正常な状態に戻れることが重要だという。リストは完璧である必要はないが、信頼に足るもの、心の中の「気になっているもの」をすべて書き出したものである必要はある。そしてその状態を保つからこそ、常に最善の行動を取ることができる。</p>
<h2>今後この本をどう活かすか</h2>
<p>GTDの基本概念を捉え直すことはできた。その上で今悩んでいるのは以下のようなこと。</p>
<ul>
<li>様々なリストが必要なようだが、何で管理するのか？（Google Tasks？、プレーンテキスト？、Evernoteは重いので論外）</li>
<li>リストを見る気力もないときはどうしよう？（本書では「やる気がないことにすることリスト」も作っていたが、それすら見る気にならない時もある）</li>
<li>「次にやること」を実際いつやるのか、スケジューリングする必要はないか？</li>
</ul>
<p>GTDというのはあくまで、自分の日々の状況を「最善」にするための補助ツールに過ぎないわけで、それに長々と時間をかけてしまうのは本末転倒。早いとこやり方を決めて、自分なりに進めていきたいところなのだが、はてさて。</p>
]]></description>
            <link>https://chroju.dev/blog/2013-10-14-post</link>
            <guid isPermaLink="false">2013-10-14-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 13 Oct 2013 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[RoRでログイン機能を実装する]]></title>
            <description><![CDATA[<ul>
<li>sessionに情報を保存することで「ログイン」状態を実現する</li>
<li>逆に言えばsession破棄で「ログアウト」扱いになる</li>
<li>Railsにはsessionオブジェクトが用意されており、これを使えば簡単にsessionへアクセス可能</li>
</ul>
<p>……というわけで。</p>
<h3>1. sessionコントローラを作成する</h3>
<pre><code>$ rails g controller sessions new create destroy
</code></pre>
<ul>
<li>コントローラ作成のときは複数形！</li>
<li>newはログイン画面表示時に、createはログイン処理時に、destroyはログアウト処理時に使用</li>
</ul>
<p>コントローラを作成したらとりまログイン処理を書いていく</p>
<pre><code>  &#x3C;span class="synPreProc">def&#x3C;/span> &#x3C;span class="synIdentifier">create&#x3C;/span>↲
      user = &#x3C;span class="synType">User&#x3C;/span>.find_by_name(params[&#x3C;span class="synConstant">:name&#x3C;/span>])↲
      &#x3C;span class="synStatement">if&#x3C;/span> user &#x3C;span class="synStatement">and&#x3C;/span> user.authenticate(params[&#x3C;span class="synConstant">:password&#x3C;/span>])↲
          session[&#x3C;span class="synConstant">:user_id&#x3C;/span>] = user.id↲
          redirect_to tasks_url↲
      &#x3C;span class="synStatement">else&#x3C;/span>↲
          redirect_to login_url, &#x3C;span class="synConstant">:alert&#x3C;/span> => &#x3C;span class="synSpecial">"&#x3C;/span>&#x3C;span class="synConstant">無効なユーザー名／パスワードです。&#x3C;/span>&#x3C;span class="synSpecial">"&#x3C;/span>↲
      &#x3C;span class="synStatement">end&#x3C;/span>↲
  &#x3C;span class="synPreProc">end&#x3C;/span>↲

</code></pre>
<ul>
<li>フォームで入力した値など、URLパラメータを受け取るときはparamsを使う</li>
<li>authenticateメソッドは、引数とuserのパスワードダイジェストを比較して論理値を返す</li>
<li>タスク管理アプリを作っているので、ログイン成功時のリダイレクト先はtasks_url</li>
<li>ちな、hoge_urlは絶対パス、hoge_pathは相対パスになるらしい</li>
<li>302 Redirectでは完全修飾URLに飛ぶのが仕様なので、redirect_toではhoge_urlを使う</li>
<li>失敗時はlogin_urlに返し、エラーメッセージを渡す</li>
</ul>
<h3>2. ログイン画面を作成する</h3>
<p>/app/views/sessions/new.html.erbを編集</p>
<pre><code> &#x3C;span class="synIdentifier">&#x3C;&#x3C;/span>&#x3C;span class="synStatement">div&#x3C;/span>&#x3C;span class="synIdentifier"> &#x3C;/span>&#x3C;span class="synType">class&#x3C;/span>&#x3C;span class="synIdentifier">=&#x3C;/span>&#x3C;span class="synConstant">"form"&#x3C;/span>&#x3C;span class="synIdentifier">>&#x3C;/span>↲
    &#x3C;span class="synIdentifier">&#x3C;% if flash[:alert] %>&#x3C;/span>↲
        &#x3C;span class="synIdentifier">&#x3C;&#x3C;/span>&#x3C;span class="synStatement">p&#x3C;/span>&#x3C;span class="synIdentifier"> &#x3C;/span>&#x3C;span class="synType">id&#x3C;/span>&#x3C;span class="synIdentifier">=&#x3C;/span>&#x3C;span class="synConstant">"notice"&#x3C;/span>&#x3C;span class="synIdentifier">>&#x3C;%=&#x3C;/span>&#x3C;span class="synConstant"> flash[:alert]&#x3C;/span>&#x3C;span class="synIdentifier"> %>&#x3C;/&#x3C;/span>&#x3C;span class="synStatement">p&#x3C;/span>&#x3C;span class="synIdentifier">>&#x3C;/span>↲
    &#x3C;span class="synIdentifier">&#x3C;% end %>&#x3C;/span>↲
↲
    &#x3C;span class="synIdentifier">&#x3C;%=&#x3C;/span>&#x3C;span class="synConstant"> form_tag&#x3C;/span>&#x3C;span class="synIdentifier"> do %>&#x3C;/span>↲
        &#x3C;span class="synIdentifier">&#x3C;&#x3C;/span>&#x3C;span class="synStatement">fieldset&#x3C;/span>&#x3C;span class="synIdentifier">>&#x3C;/span>↲
            &#x3C;span class="synIdentifier">&#x3C;&#x3C;/span>&#x3C;span class="synStatement">legend&#x3C;/span>&#x3C;span class="synIdentifier">>&#x3C;/span>ログインして下さい&#x3C;span class="synIdentifier">&#x3C;/&#x3C;/span>&#x3C;span class="synStatement">legend&#x3C;/span>&#x3C;span class="synIdentifier">>&#x3C;/span>↲
↲
            &#x3C;span class="synIdentifier">&#x3C;&#x3C;/span>&#x3C;span class="synStatement">div&#x3C;/span>&#x3C;span class="synIdentifier">>&#x3C;/span>↲
                &#x3C;span class="synIdentifier">&#x3C;%=&#x3C;/span>&#x3C;span class="synConstant"> label_tag&#x3C;/span>&#x3C;span class="synIdentifier"> :&#x3C;/span>&#x3C;span class="synType">name&#x3C;/span>&#x3C;span class="synIdentifier">, &#x3C;/span>&#x3C;span class="synConstant">'ユーザー名：'&#x3C;/span>&#x3C;span class="synIdentifier"> %>&#x3C;/span>↲
                &#x3C;span class="synIdentifier">&#x3C;%=&#x3C;/span>&#x3C;span class="synConstant"> text_field_tag&#x3C;/span>&#x3C;span class="synIdentifier"> :&#x3C;/span>&#x3C;span class="synType">name&#x3C;/span>&#x3C;span class="synIdentifier">, params[:&#x3C;/span>&#x3C;span class="synType">name&#x3C;/span>&#x3C;span class="synIdentifier">] %>&#x3C;/span>↲
            &#x3C;span class="synIdentifier">&#x3C;/&#x3C;/span>&#x3C;span class="synStatement">div&#x3C;/span>&#x3C;span class="synIdentifier">>&#x3C;/span>↲
↲
            &#x3C;span class="synIdentifier">&#x3C;&#x3C;/span>&#x3C;span class="synStatement">div&#x3C;/span>&#x3C;span class="synIdentifier">>&#x3C;/span>↲
                &#x3C;span class="synIdentifier">&#x3C;%=&#x3C;/span>&#x3C;span class="synConstant"> label_tag&#x3C;/span>&#x3C;span class="synIdentifier"> :password, &#x3C;/span>&#x3C;span class="synConstant">'パスワード：'&#x3C;/span>&#x3C;span class="synIdentifier"> %>&#x3C;/span>↲
                &#x3C;span class="synIdentifier">&#x3C;%=&#x3C;/span>&#x3C;span class="synConstant"> password_field_tag&#x3C;/span>&#x3C;span class="synIdentifier"> :password, params[:password] %>&#x3C;/span>↲
            &#x3C;span class="synIdentifier">&#x3C;/&#x3C;/span>&#x3C;span class="synStatement">div&#x3C;/span>&#x3C;span class="synIdentifier">>&#x3C;/span>↲
↲
            &#x3C;span class="synIdentifier">&#x3C;&#x3C;/span>&#x3C;span class="synStatement">div&#x3C;/span>&#x3C;span class="synIdentifier">>&#x3C;/span>↲
                &#x3C;span class="synIdentifier">&#x3C;%=&#x3C;/span>&#x3C;span class="synConstant"> submit_tag&#x3C;/span>&#x3C;span class="synIdentifier"> &#x3C;/span>&#x3C;span class="synConstant">"ログイン"&#x3C;/span>&#x3C;span class="synIdentifier"> %>&#x3C;/span>↲
            &#x3C;span class="synIdentifier">&#x3C;/&#x3C;/span>&#x3C;span class="synStatement">div&#x3C;/span>&#x3C;span class="synIdentifier">>&#x3C;/span>↲
        &#x3C;span class="synIdentifier">&#x3C;/&#x3C;/span>&#x3C;span class="synStatement">fieldset&#x3C;/span>&#x3C;span class="synIdentifier">>&#x3C;/span>↲
    &#x3C;span class="synIdentifier">&#x3C;% end %>&#x3C;/span>↲
&#x3C;span class="synIdentifier">&#x3C;/&#x3C;/span>&#x3C;span class="synStatement">div&#x3C;/span>&#x3C;span class="synIdentifier">>&#x3C;/span>↲

</code></pre>
<ul>
<li>
<p>冒頭部分はログイン失敗時のalertメッセージ表示部分</p>
</li>
<li>
<p>flashオブジェクトについて良くわかってないので要調査</p>
</li>
<li>
<p>hoge_tagあたりのヘルパーメソッドももうちょっと調べときたい</p>
</li>
</ul>
<h3>3. ルーティング</h3>
<p>config/routes.rbを編集してlogin周りのルーティングを設定する。以下の5行を追加。</p>
<pre><code>controller sessions &#x3C;span class="synStatement">do&#x3C;/span>
    get &#x3C;span class="synSpecial">'&#x3C;/span>&#x3C;span class="synConstant">login&#x3C;/span>&#x3C;span class="synSpecial">'&#x3C;/span> => &#x3C;span class="synConstant">:new&#x3C;/span>
    post &#x3C;span class="synSpecial">'&#x3C;/span>&#x3C;span class="synConstant">login&#x3C;/span>&#x3C;span class="synSpecial">'&#x3C;/span> => &#x3C;span class="synConstant">:create&#x3C;/span>
    delete &#x3C;span class="synSpecial">'&#x3C;/span>&#x3C;span class="synConstant">logout&#x3C;/span>&#x3C;span class="synSpecial">'&#x3C;/span> => &#x3C;span class="synConstant">:destroy&#x3C;/span>
&#x3C;span class="synStatement">end&#x3C;/span>

</code></pre>
<ul>
<li>
<p>sessionsコントローラに対し、</p>
</li>
<li>
<p>/loginにGETでアクセスした場合はsessions#newを呼ぶ</p>
</li>
<li>
<p>/loginにPOSTでアクセスした場合はsessions#createを呼ぶ</p>
</li>
<li>
<p>/logoutにDELETEでアクセスした場合はsessions#destroyを呼ぶ</p>
</li>
<li>
<p>すなわちREST</p>
</li>
</ul>
<p>ざっくり簡単だが、とりあえずこれで認証画面とログイン処理は実装完了。</p>
<p>まだログアウトはできていないし、ログイン後の処理なんかも書いてないけど、とりあえずやりかたはわかったのでメモ。</p>
<h3>参考</h3>
<p><a href="http://ayaketan.hatenablog.com/entry/2012/12/19/210231">Ruby on Rails ログイン画面の作成 - ayaketanのプログラミング勉強日記</a></p>
]]></description>
            <link>https://chroju.dev/blog/2013-10-06-post</link>
            <guid isPermaLink="false">2013-10-06-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 05 Oct 2013 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[RoRでScaffold作成を間違えたときの対処法が知りたい]]></title>
            <description><![CDATA[<p>generate scaffoldはMVC全部作ってくれて便利なんだけど、うっかりカラム名間違えたりしたときの対処法ってあるのかしら。後から変更したい場合は全部逐一手動で変更してね☆ってことだとさすがに面倒臭すぎるんだが……。</p>
<p>とりあえず今はscaffoldを削除してイチから作り直す形で対処しているが。</p>
<blockquote>$ rails destroy scaffold hoge</blockquote>
<p>このとき、db:migrateすでにしちゃってるならsqlite入ってDROP TABLEするのも忘れずに。</p>
<p>後からアプリ改修して新しい属性付け足したりとかって場面もあるだろうし、何かしらscaffoldに変更をかける手段はあるんじゃないかと思って探してるんだけど見つからない。ぐぬぬ。</p>
]]></description>
            <link>https://chroju.dev/blog/2013-09-21-post</link>
            <guid isPermaLink="false">2013-09-21-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 20 Sep 2013 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[バージョン管理に注意しながら、Ruby on Railsの動作環境を構築する]]></title>
            <description><![CDATA[<p>資料によっていろいろ言っていることが違うので、自分なりに調べながらまとめる。こういうのchef?とかで書いとけば環境構築楽になるんだろうな。</p>
<h2>必要なもの</h2>
<ul>
<li>
<p>Ruby ……当然のごとく</p>
</li>
<li>
<p>Rails ……当然のごとく</p>
</li>
<li>
<p>rbenv ……RubyとRailsの管理システム</p>
</li>
<li>
<p>ruby-build ……rbenvとセットで使うっぽいがよくわかってない</p>
</li>
<li>
<p>Git ……バージョン管理。必須ではない気もするがあった方がいい。rbenvとかのインストールにも使う。</p>
</li>
<li>
<p>RubyGems ……Rubyのパッケージ管理システム</p>
</li>
<li>
<p>Bundler ……Gemパッケージの管理システム</p>
</li>
</ul>
<p>こんなところだろうか。直接的に必要なものの他に、それぞれを管理するためのツールが必要だったりしてなかなかに複雑であった。あとhomebrewとかのあたりまで遡るとキリが無くなりそうなのでさすがに割愛。というかOSによっても違ってきちゃうし。readlineとかopensslとかも依存関係があるっぽいんだけどよくわからないので割愛……。んー、意味あるのかこの記事。俺がRoRで使ってる環境はちなみにCent OSなので、その前提で書きます。</p>
<h2>rbenv</h2>
<p>本とか読んでるとRubyのバージョン管理にはRVM使わせているものが多いんだけど、rbenvの方が軽くてBundlerとの相性も良いらしい。よってrbenvを使うことにする。</p>
<p>参考：(<a href="http://passingloop.tumblr.com/post/10512902196/difference-between-rbenv-and-rvm">http://passingloop.tumblr.com/post/10512902196/difference-between-rbenv-and-rvm</a>)</p>
<p>インストール先のパスが迷う。。。ホームフォルダに不可視で入れるのが気持ちとしてスッキリするのでそれを採用。</p>
<blockquote>$ git clone git://github.com/sstephenson/rbenv.git ~/.rbenv</blockquote>
<p>で、bash_profileにパスを追加。</p>
<blockquote>echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
source ~/.bash_profile</blockquote>
<h3>追記</h3>
<p>実はこの記事書く前にすでにRVM入れちゃってたんだけど（今読んでる『RailsによるアジャイルWebアプリケーション開発』にはRVMが紹介されてたので）、RVM削除してrbenvを入れなおそうと思い立って調べてみた。そこで辿り着いたRVMのアンインストールコマンドがなかなかに衝撃的だったので追記。</p>
<blockquote>$ rvm seppuku</blockquote>
<p>切腹！！！ｗｗｗｗ</p>
<h2>ruby-build</h2>
<p>よくわかってないけど入れる。わかっていることとしては、これがないとrbenv installコマンドが使えない。rbenvのプラグインとしての位置づけらしいので、.rbenvフォルダ配下に入れる。公式のREADMEにもそう書かれてます故。</p>
<blockquote>$ git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build</blockquote>
<h2>Ruby</h2>
<p>Rubyはrbenvを使ってインストール。バージョンについては都度変わるので、$ rbenv install -lコマンドで落とせるバージョンを確認しつつ、必要なものを入れる感じで。まぁ使うバージョン選択できるんだから、そんなにセンシティブになる必要はないと思うが。</p>
<blockquote>$ rbenv install 1.9.3</blockquote>
<p>デフォで使うRubyのバージョンを設定。</p>
<blockquote>$ rbenv global 1.9.3 # これで設定
$ rbenv rehash # Rubyの新しいバージョンやコマンド付きのGemを落としたときに実行する</blockquote>
<p>インストール済みのRubyのバージョンは$ rbenv versionsで確かめられる。ちょうど今年の上半期にRuby 2.0が出たばかりだし、このあたりはしばらくの間重宝しそう。</p>
<h2>RubyGems</h2>
<p>入れる方法はいろいろあるみたいだけど、自分の使ってるCent OSを基本として考えて、yumで入れることにする。</p>
<blockquote>$ yum install rubygems</blockquote>
<p>めんどかったら-yオプション付ければ対話なしで全部インストールされておしまい。</p>
<h2>Rails</h2>
<p>いよいよRailsのインストール。RailsはGemパッケージとして配布されているので、今入れたRubyGemsを使ってインストールする。特定のバージョンを使う場合は-vオプションを使う。オプション無しだと最新版が入る。rbenvでRubyの複数バージョン切り替えるみたいにRailsもやってみたいんだけど、やり方がわからない。。。</p>
<blockquote>$ gem install rails</blockquote>
<h2>Bundler</h2>
<p>一番よくわかっていないところ。Rubyで使われるGemパッケージの管理ツールらしい。ルートディレクトリにあるGemfileに書いておいたパッケージについて、依存関係をチェックして自動でインストールしてくれるものらしい。ほお。</p>
<blockquote>$ bundle install</blockquote>
<p>Railsアプリケーションを$ rails newコマンドで作成した場合、ルートディレクトリに勝手にGemfileが作られる上、$ bundle installも自動で実行されるので、あまり意識はしなくていいっぽい。Rails自体もGemで配布されているのでbundlerを使って管理させたりとかもできるみたいなんだけど、そのあたりを調べた感じ、自分には何が何を管理してるのかメタにメタ重ねる感じで徐々に訳わからん感じになってきたので考えるのを、やめた。</p>
<p>RailsアプリケーションのGemfileにはcoffescriptやSASS、SQLiteなどをインストールするように記述されている。下手にこれいじると多分死ぬと思うんだけど、SQLiteじゃなくてMySQL使いたいとか、他のGemパッケージが何か必要になったとか、そういうときは編集してあげてから$ bundle installでおｋっぽい。便利！</p>
<h2>Git</h2>
<p>長くなりそうなので割愛。また別の機会にまとめたい。GitHubのアカウントも持ってる（ほぼ使ってないけど。。。）し、一度RSA認証で繋げるように設定はしたことあるんだけど、完全に忘れたんでもう一度ちゃんとまとめる。今度。</p>
<p>ツールをインストールするときは依存関係の処理とかの問題があるので、後々新バージョンが出たときに惑わないよう、なるたけ自動で管理できるような入れ方をする必要がある。その視点に立って一旦まとめてはみたけど、もっと良いやり方というのも多分あるのだろう。インストールするぐらいなら猿でも出来ると思いがちだが、これがなかなか奥が深い。</p>
]]></description>
            <link>https://chroju.dev/blog/2013-09-16-post</link>
            <guid isPermaLink="false">2013-09-16-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sun, 15 Sep 2013 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『RailsによるアジャイルWebアプリケーション開発』第II部読了]]></title>
            <description><![CDATA[<p>「仕事で忙しい」という最悪の理由により全然勉強してなかった件。Rails本、やっと第II部読み終わった……。</p>
<ul>
<li>
<p>基本的に rails generate hoge コマンドで色々作れる。scaffold、model、controllerとか、コマンドで作ればRailsが必要なファイルを用意してくれる。あとは作られたファイルをガチャガチャいじってアプリを作っていくというのが基本の流れ。</p>
</li>
<li>
<p>特にscaffold。これをバチコンと叩き込むとコントローラ、モデル、ビュー、マイグレーションファイルから何から全部作られる。英語で「足場」という意味らしいがまさにそんな感じ。</p>
</li>
<li>
<p>scaffold作ると編集画面（edit.html.erb）とか部分テンプレート（form.html.erb）まで作られるという至れり尽くせり感ビビる。</p>
</li>
<li>
<p>create()やupdate()などの基本的なアクションも作られるので、実装したい動作によっては新しいコントローラをわざわざ作るまでもなかったり。</p>
</li>
<li>
<p>テスト用のファイルも自動生成される。コントローラの機能を試すファンクションテスト、モデルの動きを試すユニットテスト、そしてアプリのフローを試す統合テスト。</p>
</li>
<li>
<p>テスト用ファイルの編集方法がいまいちよくわからず。このあたりは試してみないと実感わかないかも。</p>
</li>
<li>
<p>複数モデル（テーブルと読み替えてOK？）間の関係を表すには、modelsファイルにhas_manyやbelongs_toを追加する。DBを直接弄ったりはしない。</p>
</li>
<li>
<p>button_to()に:remote=>trueを加えるだけでAjaxが追加できる。……え？</p>
</li>
<li>
<p>そもそもAjax使ったことないんでこのへんはもう少し見直したいが。。。Ajaxと言っても、再読み込みなしで画面の一部が再描画される程度の話か。</p>
</li>
<li>
<p>ちなみRailsのCSSは標準でSCSSが使われている。SCSSって最近まで知らなかったけどクソ便利すぎて笑う。最初からCSSがこういう文法ならいいのに……。これもまた勉強が必要なり。</p>
</li>
<li>
<p>コントローラのrespond_toメソッドは出力形式を色々替えられる。format.json、format.atomとか。</p>
</li>
<li>
<p>メールの送信機能もある。。。（このへんになるともう色々出来過ぎてよくわからなくなってきた）</p>
</li>
<li>
<p>Railsのコードは当然ながらRubyで書くわけだが、他にヘルパーメソッドというものがある。フォーム用にボタンリンクを作るbutton_to()とか、リンクを作るlink_to()とか。Rubyをそもそもまだちゃんと理解できていないので、どれがRubyの文法でどれがヘルパーメソッドなのかの見分けもいまいちついていない状態。</p>
</li>
</ul>
<p>わーすげー簡単にまとめてしまった。全体の感想としては、とにかく何かと簡単かつ便利。自分でコーディングが必要な範囲は最低限。Javaでウェブアプリを組んだ経験があり、そのときはMVCそれぞれのファイルを全部イチから手で作っていたわけだが、RORではrails generate scaffoldで一発である。なんてこったい。しかし逆に言えばアプリの構造自体は全部任せて、中心的な機能や外観のコーディングだけに集中できるんだから、効率が良いわけで。</p>
<p>SCSSとかAjaxとか、ウェブアプリを作る上でよく使われる技術が標準で備わっているというのも利点だろう。だから覚えることも多い。SCSS、Ajax、あとはDBもか。DBはSQL文を直接発行するようなことはないように組まれているけど、has_manyとか正しく書くためにはDBの構造あたりを正しく知っていなくてはならない。うむ、これからいろいろと学ばなくては。</p>
<p>しかしこの本、いきなり実例から入ってしまうので理解がしやすいやらしにくいやら。実際に何か作りながら説明していく本というのは少なくないが、この本は第III部でRails全体の詳説が入る。「ここで入れるなら先に解説してくれよ！」と個人的には言いたい。いきなり知らないメソッドをバシバシ盛り込まれてどんどんコーディングを進められるより、そもRailsとはどういったディレクトリ構造になっていて、どういった動作をするものなのかという中身を知ってからの方が実例を理解しやすいのではと思う。まぁこのへんは好みか。</p>
<p>第III部を読みつつ、そろそろとりあえず何か作ってみてもいいかもしれない。SCSSやAjaxを知らない以上、見た目にこだわったりとかはできないけど、とにかくアプリっぽいもの、データを追加して編集して表示させてっていうものをまずは作る。9月はそれが目標だなー。</p>
]]></description>
            <link>https://chroju.dev/blog/2013-09-04-post</link>
            <guid isPermaLink="false">2013-09-04-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Tue, 03 Sep 2013 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[技術書のサンプル試す場合はバージョンを揃えるべきなのか]]></title>
            <description><![CDATA[<p>『RailsによるアジャイルWebアプリケーション開発』、大変くだらないところでつまずいているというか、なんか知らんがエラー出まくりで先に進めず。</p>
<p>問題が起きたのはp.79。モデルクラスのrbファイルにvalidatesメソッドによる検証過程を書き入れ、test/functional/xxxに有効なテストデータ（とされるもの）を入れてrake testコマンドを発行したところ、エラーが出る。何度やってもエラーが出る。仕方ないので一旦先に進もうともしたのだが、次に編集対象になっていたtest/unitフォルダが見当たらない。念のため別プロジェクトを作ったりもしてみたが、やはりtest/unitは生成されなかった。さすがにディレクトリ構造丸ごと違うとなると、自分のミスというよりはバージョンの相違によるものではないかと思い至る。この本ではRubyの1.9.2とrails 3.1.0を使っていたが、僕の環境はRuby2.0とrails 4.0.0だった（もっと他にも「バージョンが原因ではないか？」と思い当たった根拠があったはずなのだが失念。トラブルシュートは記録しながらやるべきだったなー……）。</p>
<p>というわけでRubyとrailsのバージョンを下げる。Rubyについてはrvmで管理しているので簡単に変更できたが、問題はrails。軽くググった感じでは、一度アンインストールしてから再度バージョン指定して入れなおせばよいという話だった。</p>
<blockquote>   #gem uninstall rails
<p>#gem install rails -v 3.1.0</blockquote></p>
<p>が、これだけで再びrake testを試すとまだエラー。Gemfile内のバージョン表記を変えろとのことだったので変更し、#bundle update。bundleについてはよくわかってないのでおいおい調べる予定。</p>
<p>しかし、まだエラー。エラーというより、SECURITY WARNINGとやらが表示された。どうもrails過去バージョンの脆弱性に起因するらしい。こういった事例がいくつかあり、最終的にはRails 3.2.13まで上げざるを得なかった。</p>
<p><a href="http://blog.popowa.com/2013/02/security-warning-no-secret-option.html">popowa: SECURITY WARNING: No secret option provided to Rack::Session::Cookie と出たら</a></p>
<p><a href="http://stackoverflow.com/questions/14206775/rails-emits-warning-rackfile-headers-parameter-replaces-cache-control-after">Rails emits warning: "Rack::File headers parameter replaces cache_control after Rack 1.5" - Stack Overflow</a></p>
<p>ここまででもうかなり疲れていたのだが、これでもまだ尚エラーが出るから嫌になる。Gemfileのcoffee-railsのバージョンがよろしくないらしく、以下サイトを参考にして編集。</p>
<p><a href="http://detham.tumblr.com/post/40225529175/rails-3-1-3-3-2-11-railties">Rails 3.1.3 -> 3.2.11 のアップデートで railties のdependencyが競合エラーになった - The longest day in my life</a></p>
<p>んで結論を言えばこれでもまだ上手く行かず、最終的にはRailsとRubyのバージョンを揃えた上で、イチからプロジェクトを作りなおしたらやっとエラーが出なくなった。もう自分のやってること何もかも間違ってる気がしてくる。</p>
<p>で、今回の一件からの考察というか帰結なのだが、技術書に沿って勉強していく場合、やはり技術書と同じバージョンの環境で進めていくべきなのだろうか。僕はそのへんわりと甘く見てしまっていたので、今回は「いや最新環境に慣れといた方がいいんじゃね？　Ruby2.0も最近出たとこで覚えといた方が得な気がするし」などという考えでRuby2.0とRails4.0.0を使っていたのだが、結果はこれである。Androidの勉強も似たような考え方でだいたい最新か、あるいは一つ前のOSで構築していたのだが、あちらは後方互換性が高いのか、それほど困ることもなかったので、Ruby on Railsでも安易に同じ事をしてしまった。</p>
<p>新しい環境に慣れておいた方がいい、というのはあると思う。が、技術書を読み進めていく上では、万が一バージョン相違によるエラーが出た場合、今回のように大きなロスを被ることになる。技術書、特にある分野での最初の一冊なんてのはとにかくまずは一冊流してみた方がいいわけで、最新バージョンへの対応なんてのはその後でゆっくり覚えればいいのかもしれない。旧バージョンの方がノウハウが多く蓄積されていて、エラー対処がしやすいという利点もある。とはいえ、Railsは旧バージョンを使っていると脆弱性の警告が出る場合があるので、新しいバージョンを使わざるを得ない場合もあるようなのだが。。。</p>
<p>あと、今回のトラブルシュートでいろいろググってみたところ、<a href="http://stackoverflow.com">Stack Overflow</a>が引っかかってくることが非常に多かった。やっぱ英語は必須。</p>
]]></description>
            <link>https://chroju.dev/blog/2013-08-03-post</link>
            <guid isPermaLink="false">2013-08-03-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 02 Aug 2013 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[『RailsによるアジャイルWebアプリケーション開発』第I部 読了]]></title>
            <description><![CDATA[<p>第I部はRailsのインストールから、とりあえずウェブアプリケーションを作って公開するまで。あとRoRにおけるMVCモデルの概要と、Rubyの簡単な紹介が主。</p>
<h1>第1章 Railsのインストール</h1>
<ul>
<li>apt-getを使って必要な依存関係をインストールしているけど、Cent OSではapt-getが使えず。yumで入れようとしたが、yumにはnodejsがないらしく入らない。。。やむを得ずwgetで落としてきて展開しました。</li>
<li>エディタはTextMateがオススメとあるけど、変えるのめんどいし取りあえずvimでいいか。。。</li>
</ul>
<h1>第2章 Hello, Rails!</h1>
<ul>
<li>ポート3000を使うってことでiptablesで開けてあげたりとか、そのへんは自分でやる必要があった。こういうのスムーズに出来るようにならなきゃなんだろうなぁ。</li>
<li>eRubyの&#x3C;% %>でコード埋め込むのがなんか気持ち悪いと思ってしまう。同じ理由でJSPも苦手だった。……と思ったら、この後の章で似たようなことが書いてあった。元々HTMLとJavaScript書いたりしてたからなんだろうけど、こういうのはなるたけ分離したいと思ってしまう。</li>
</ul>
<h1>第3章 Railsアプリケーションのアーキテクチャ</h1>
<ul>
<li>ちょっと置いてけぼり感あったので、この後の章でアプリ作りながら再読する。</li>
</ul>
<h1>第4章 Ruby入門</h1>
<ul>
<li>一応Rubyの基礎はさらったので割愛しよう……と思ったら！！！　『作りながら学ぶRuby入門』より記述範囲が広かった！</li>
<li>そういえばあの本、例外の処理とか出てこなかったな……。もう1冊、きちんとRubyの基礎をさらえる本を読んだ方が良さそうな気がしてきた。</li>
</ul>
<blockquote>キーワードreturnは省略可能です。returnがない場合、最後に評価した式の結果が戻り値になります。（p.39）</blockquote>
<ul>
<li>
<p>はあ！？</p>
</li>
<li>
<p>Rubyの文法ってなんか慣れない。。。</p>
</li>
</ul>
]]></description>
            <link>https://chroju.dev/blog/2013-07-25-post</link>
            <guid isPermaLink="false">2013-07-25-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Wed, 24 Jul 2013 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Kaoriya版Vimでtxtファイルの自動改行が解除できない件]]></title>
            <description><![CDATA[<p>2週間ぐらいハマってた。</p>
<p>プレーンテキストの管理やRuby書くときとかにKaoriya版MacVimを使っているのだが、.vimrcでset textwidth=0を設定しているにも関わらず、txtファイルのみ自動改行が解除できなくて困っていた。最近QFix_howmをよく使うようになっていて、機能としては申し分なかったんだけど、まったく関係ないこの一点のためにイライラしっぱなしだった。</p>
<p>で、結論。Kaoriya版Vimのデフォルト設定により、textwidthが上書かれてしまうらしい。</p>
<blockquote>Kaoriya版Vimではデフォルトの設定ファイルであるvimrc_example.vimを読み込んでおり、その設定ファイル内でテキストファイルを開いたときにtextwidth=78の設定が上書きされてしまうらしい。
<p><a href="http://d.hatena.ne.jp/WK6/20120606/1338993826">Vimのtextwidth設定と.vimrc - 続・日々の雑感</a></blockquote></p>
<p>なので引用元の記事にもある通り、.vimrcに以下を挿入すればおｋ。</p>
<pre><code class="language-vim">&#x3C;span class="synStatement">autocmd&#x3C;/span> &#x3C;span class="synType">FileType&#x3C;/span> text &#x3C;span class="synStatement">setlocal&#x3C;/span> &#x3C;span class="synPreProc">textwidth&#x3C;/span>=0

</code></pre>
<p>これでQFix_howm使って快適メモライフ！！！　他にもデフォルト設定いろいろ入ってそうなんで、見直した方がいいかもしれない。</p>
]]></description>
            <link>https://chroju.dev/blog/2013-07-23-post</link>
            <guid isPermaLink="false">2013-07-23-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Mon, 22 Jul 2013 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Ruby on Railsを学ぶ、とはどこまでの範囲を学ぶのか]]></title>
            <description><![CDATA[<p>VPSを使ってRuby on Railsでウェブサービスを作るにあたり、「まずは足元から」ということでLinuxの勉強から始めてボチボチやっていたんだけど、「むしろ取りあえずアプリ動かしてみた方が良いのではないか」と思い立ち、方針を転換。Linux→DB→Railsなんてゆっくりやるより、まずは動かしてみることにした。購入したのは以下の本。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4274068668/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51Gibg-iYTL._SL160_.jpg" alt="RailsによるアジャイルWebアプリケーション開発 第4版" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4274068668/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">RailsによるアジャイルWebアプリケーション開発 第4版</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.03.01</div></div><div class="amazlet-detail">Sam Ruby Dave Thomas David Heinemeier Hansson <br />オーム社 <br />売り上げランキング: 138,293<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4274068668/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>各所で絶賛されているのを見かけた上、立ち読みしてみた感じでもRubyのインストールという初歩から始まっていてわかりやすそうだった。候補としてはもうひとつ、インプレスの『基礎 Ruby on Rails』もあったんだけど、ザッと見た感じでは『Railsによる〜』の方が記載が細かそうだったのでこっちを選んだ。</p>
<p>さて、VPSでRuby on Railsを作るにあたり、どこまでの範囲を学べば良いのだろう。今回買った本だとおそらくはRailsとRuby、DBあたりのコーディングが内容の主なようで、インフラ側のチューニングの話なんぞは載っていなさそうだった。自分が想像するとこだとLinuxというかOSの準備、VPSであるならばOSに接続するためのSSHの使い方、ウェブに公開するのでそのあたりのセキュリティ、DBやApacheなどのアプリインストールなどなど、やることはかなりありそう。あとView側の問題として、Coffe ScriptやSCSSあたりもやんなくちゃいけないんだろうな。JavaScriptとCSSはそれなりに書いたことあるけど、せっかくだし挑戦してみたい。</p>
<p>……という感じのビジョンを描いているのだが、やはり全部まともにイチからやっていたらかなりの時間が必要だと思う。とりあえず作ってみて、あとは気になったところを徐々に手をつけていく感じでやっていきたい。あと、環境構築系だとこの本が良さそうだなーと目をつけている。</p>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4844333755/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51Mb377pxwL._SL160_.jpg" alt="Ruby on Rails環境構築ガイド" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4844333755/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Ruby on Rails環境構築ガイド</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.03.01</div></div><div class="amazlet-detail">黒田 努 <br />インプレスジャパン <br />売り上げランキング: 44,343<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4844333755/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<p>……で、『Railsによる〜』はとりあえず1章読破したのだが、まさかのここでつまずくという事件発生。つまずくのはえーよｗｗｗ</p>
<p>CentOSにRVMを入れようとしたのだが、以下のコマンドが通らなかった。curlのエラーっぽいんだけど、今をもって解消できてない。一応他の方法でRVMは入ったので、しばらく保留にしとこうかと思っている。</p>
<blockquote>   bash < <(curl -s [https://rvm.beginrescueend.com/install/rvm)](https://rvm.beginrescueend.com/install/rvm))</blockquote>
]]></description>
            <link>https://chroju.dev/blog/2013-07-21-post</link>
            <guid isPermaLink="false">2013-07-21-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Sat, 20 Jul 2013 15:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[お勉強ブログ、はじめます]]></title>
            <description><![CDATA[<p>SEという職に就いて2年ちょい経ったわけだが、最近はPJリーダーとか顧客との調整とかその手の仕事ばかりを回されるようになってきて、実機を触る機会がめっきり少なくなってきてる。まぁうちはいわゆる大手SIerというヤツだから、徐々に技術っぽい仕事をしなくなるのは必然、ではある。だがしかし、あまり自分はそういうキャリアを望んでいないし、さすがに3年目で管理系の道に入ってしまうのは、ちょっと早すぎる。</p>
<p>というわけで技術ブログである。会社で触れないなら家でやるしかない。エンジニアとして自負したいのであれば、もう精一杯足掻くしかないだろうと。指を咥えて与えられた仕事だけしてたら単なるダラダラリーマンになりそうなので、それは避けたい。そしてゆくゆくは、身につけた技術によって職を替えてもみたいのだが。</p>
<h1>現在位置を確認する</h1>
<p>自分はインフラ系のSEなので、日頃はスイッチのconfig書いたりVMwareでガリガリ仮装環境作ったり、そういう仕事が多い。ちなみに顧客環境の都合で業務上Linuxに触れた経験がないのは内緒である。</p>
<p>というわけで、自力で学ぶのは会社から離れた方向。アプリ系を中心に据えていきたい。これまで自分が納めた言語はJava、それもわりと簡単なことしかできていないので、Javaの腕を磨くことと、もう一言語使えるようになることを目標にしたい。</p>
<p>とはいえ現在の業務も重要ではあるので、同時にインフラ周りも学べるような道が吉。</p>
<h1>これから行く先を定める</h1>
<p>てわけで、当面の目標は二つ。</p>
<ul>
<li>VPSを借りて、Ruby on Railsで動くウェブサービスをつくる</li>
<li>Androidアプリをなんかつくる</li>
</ul>
<p>Javaに加える「もう一言語」はRubyにした。最近流行っているようだし、出来る事の幅も広そう。Pythonにも興味は惹かれたが、まあとりあえずRubyで。</p>
<p>そしてVPS。Ruby on RailsだとHerokuあたりで建てるのが主流みたいなんだけど、勉強も兼ねて足回りから全部自分で構築する。CentOSをいじって、ApacheとかDBとか入れてガリガリつくる。これでインフラ系SEとしての勉強も一応できるはず。</p>
<p>2番目の目標の方はサブ。1個の目標だけずーっと続けるのもなかなかしんどそうなので、息抜きとしてAndroidアプリをいじりたい。作りたいもののイメージとしては、Tumblrの過去ログを漁りやすくするようなアプリが出来たらいいなーと思っている。</p>
<h1>ブログをどう活用するか</h1>
<p>と、ここまで書いておいてなんだが、実はすでに勉強は始めている。本を読みながら作ったりなんだりとしていたのだが、どうにも身になっている気がしなかったので、アウトプットの場としてブログを始めることにした次第。</p>
<p>はじめはEvernoteとかqfix_howmあたりに勉強記録をつければいいかと思ったが、それだとモチベーションが上がりにくいし、整形もしない気がしたのでブログにしてみた。はてブロならMarkdownで書けるからちゃんとフォーマットも考えつつ書けそうだし、参考文献へのリンクの処理とかも楽。んでさすがに本家の方とは内容がかけ離れすぎてるので、別ブログとして開設。まぁひっそりとやっていきます。</p>
<p>書く内容としては、何を学んだのか、何がわかったのか、わからなかった点はどこで、次回はどうするのか、ということを1日の勉強が終わったときに書き留めていきたい。特に「次回はどうするのか」がすげー重要だと個人的には思っていて、本を読んだら読みっぱなしではなく、「この本ではこのあたりのことがよくわからなかったから、次はこういう本を買おう」というビジョンが必要。そういうビジョンを持ちながら勉強するためにも、学んだ内容をアウトプットして整理する必要があると思っている。</p>
<p>あ、あとは「うたうとき」の方でたまに書いてたライフハック的というか、情報整理環境みたいのについての記事もこっちに回してくるつもり。そういうのってこだわりすぎてもいけないんだけど、ある程度整備しとかないと色々支障をきたすものだとも思っている。</p>
<p>次回以降、勉強ブログとして書き進めていきます。ちなみに現時点までの記録として、以下に開発環境と読んだ本をば。</p>
<h1>これまでの足跡</h1>
<h2>開発環境</h2>
<ul>
<li>
<p>メインマシン</p>
</li>
<li>
<p>iMac late 2010</p>
</li>
<li>
<p>Mountain Lion</p>
</li>
<li>
<p>Java : Eclipse 4.2</p>
</li>
<li>
<p>Ruby : vim（良いIDEとかあるなら教えてくだしあ＞＜）</p>
</li>
<li>
<p>Editor : vim（出来ること多すぎてハマり気味。精神衛生上良くない）</p>
</li>
<li>
<p>サブマシン（いずれもVMware fusion上）</p>
</li>
<li>
<p>Cent OS 6.4（Linux勉強用）</p>
</li>
<li>
<p>Windows 8（ほぼ使ってない。一応持ってるWindows）</p>
</li>
<li>
<p>流行りのvagrantなんかも触ってみたいですね！</p>
</li>
</ul>
<h2>これまで読んだ本</h2>
<ul>
<li>Android</li>
</ul>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4839941009/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51KFio8rqSL._SL160_.jpg" alt="楽しみながら作ってみよう! はじめてのAndroidアプリプログラミング" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4839941009/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">楽しみながら作ってみよう! はじめてのAndroidアプリプログラミング</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 13.07.20</div></div><div class="amazlet-detail">塚田 翔也 <br />マイナビ <br />売り上げランキング: 15,868<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4839941009/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4048860682/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51pUNvCkwhL._SL160_.jpg" alt="Google Androidプログラミング入門 改訂2版" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4048860682/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Google Androidプログラミング入門 改訂2版</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.03.01</div></div><div class="amazlet-detail">江川崇 神原健一 山田暁通 佐野徹郎 郷田まり子 <br />アスキー・メディアワークス <br />売り上げランキング: 400,553<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4048860682/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<ul>
<li>Ruby</li>
</ul>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4797371277/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41VI40rlsIL._SL160_.jpg" alt="作りながら学ぶRuby入門 第2版" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4797371277/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">作りながら学ぶRuby入門 第2版</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.03.01</div></div><div class="amazlet-detail">久保秋 真 <br />ソフトバンククリエイティブ <br />売り上げランキング: 274,090<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4797371277/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
<ul>
<li>Linux</li>
</ul>
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4798031275/diary081213-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51VAhyp4eWL._SL160_.jpg" alt="はじめてのCentOS6 Linuxサーバ構築編 (TECHNICAL MASTER)" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4798031275/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">はじめてのCentOS6 Linuxサーバ構築編 (TECHNICAL MASTER)</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 15.03.01</div></div><div class="amazlet-detail">デージーネット <br />秀和システム <br />売り上げランキング: 210,008<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4798031275/diary081213-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
]]></description>
            <link>https://chroju.dev/blog/2013-07-20-post</link>
            <guid isPermaLink="false">2013-07-20-post</guid>
            <dc:creator><![CDATA[chroju]]></dc:creator>
            <pubDate>Fri, 19 Jul 2013 15:00:00 GMT</pubDate>
        </item>
    </channel>
</rss>