Azure で Nomad(Consul)のクラスターを作成する

Web サーバーとスケジュールジョブなら App Service と Logic App + Azure Container Instance が最初の選択肢だと考えていたが、他の選択肢を調べてみようと検証した。

Nomad 事情

Nomad は Hashicorp のプロダクト。
Nomad by HashiCorp

日本に馴染みがあるところでは Circle CI や trivago が使っている。
Who Uses Nomad - Nomad by HashiCorp

trivago の記事で KubernetesNomad の違いについて触れている。
"(意訳)Kubernetes は自動車だとしたら Nomad はスクーターで、場合に応じて使い分けます"
Maybe You Don't Need Kubernetes | Matthias Endler

公式でも Kubernetes との違いについて触れている。
"(意訳)Kubernetes は Docker にフォーカスしてますが Nomad は一般的な利用を想定しています"
Nomad vs. Kubernetes - Nomad by HashiCorp

Nomad が Docker 特化ではないとはいえ k8s を使うべきシーンはそこまで多くないと考えていて、Nomad がそのときの代替案になるのではないかと考えている。

知るかぎり Nomad の as a Service はないため、下回りは自分で整える必要がある。

事前知識

  • Nomad 公式の Getting Started を完了している
  • Azure Virtual Machine やその周辺の知識を保持している
  • Terraform は利用している
  • Consul と Packer は触ったことがない

チュートリアル

Hashicorp が手順を用意してくれているので、それに沿って行う。

github.com

Nomad と Consul を同じクラスターにデプロイすることにし、"Deploy Nomad and Consul in the same cluster" の手順を追う。
手順の中で terraform-azurerm-nomad を見ていたと思ったらリンク先が terraform-azurerm-consul でいつの間にか違うリポジトリ、ということがあるのでそこは注意すること。

Consul と Nomad 入りの VM イメージ作成

Use the install-consul module from the Consul Azure Module and the install-nomad module from this Module in a Packer template to create an Azure Image with Consul and Nomad.

Packer 使って VM Image を作成してねということなので、リポジトリ内の以下を参考に作成する。
https://github.com/hashicorp/terraform-azurerm-nomad/tree/master/examples/nomad-consul-image

Packer 初めてだったのでよくわからずにそのまま packer build nomad-consul.json したが、できていた。
環境変数として与える Service Principal のスコープを制限しようとしたところ、packer-XXX というリソースグループを作成できる必要があり、そこだけハマった。

Consul と Nomad のサーバークラスター作成

Deploy a small number of server nodes (typically, 3) using the consul-cluster module. Execute the run-consul script and the run-nomad script on each node during boot, setting the --server flag in both scripts.

Terraform を使ってクラスターを作成する。
クラスターは Virtual Machine Scale Set で構成されている。
ドキュメントを読んで必要なパラメータを入れれば構成できる、はずなのだが Consul と Nomad が動いておらず、デプロイ後にミドルウェアのインストールを SSH で接続して行った。
ここは仮想マシンの起動スクリプトで完結できないと不便なので、実用するときはもう少し掘り下げる予定。

Consul と Nomad のクライアントクラスター作成

Deploy as many client nodes as you need using the nomad-cluster module. Execute the run-consul script and the run-nomad script on each node during boot, setting the --client flag in both scripts.

基本的にサーバークラスターと同じ要領で作業を進めるのみ。
自分の場合はサーバークラスターを作成した時点でコア数上限に引っかかり、別リージョンに作成した。
Consul と Nomaddatacenterregion の値は terraform テンプレートにリージョンとして書いてある値に準じるため接続できないエラーが出ていた。
デプロイ後に config を書き直すことで対応。

感想

Consul サーバークラスターのマネージドサービスが現在プライベートベータになっている。
Announcing HashiCorp Consul Service on Azure

Kubernetes も踏まえてこれを提供しているようだが、Nomad のマネージドサービスが欲しいなという印象。
そうはいっても現状はないので、Virtual Machine Scale Set をうまく使って仮想マシンを操作する必要がないように起動スクリプトを整備するのと、Consul と Nomad のアップデートなどの運用フローを整備できれば実用に耐えられるかなという印象。

Infrastructure as Code ―クラウドにおけるサーバ管理の原則とプラクティス

Infrastructure as Code ―クラウドにおけるサーバ管理の原則とプラクティス

DMM英会話の予約メールから自動的にカレンダー予約(2019/9/3改訂版対応)

背景・問題

DMM 英会話を使い始めて9ヶ月近くになる。
DMM 英会話ではレッスンを登録すると、その日時が書かれたメールが届く。
スケジュール管理の都合上、以下の記事を参考に Google カレンダーに自動登録するハックを利用していた。

blog.shotarok.com

しかし、2019/09/03 に予約メールが重複して届くようになり、翌 09/04 には新しいフォーマットのメールのみ届くようになってしまった。

以前のメールフォーマットに依存していたため、これまでのハックが使えなくなってしまった。

原因

システム改訂にともなうフォーマット変更だと思われる。

2019/09/03 までのメール

  • タイトル「【DMM英会話】レッスン予約完了のお知らせ」
  • 送信元 no-reply@eikaiwa.dmm.com

2019/09/03 から後のメール

  • タイトル「レッスンのお知らせ」
  • 送信元 noreply@eikaiwa.dmm.com

解決策

Google Apps Script を少し修正した。

DMMEnglish.gs だけ修正すれば問題ないはず。
レッスン5分前あたりにリマインドメールが届くのだが、自分の場合はメール見てないのでこれも開封したことにしている。

function DMMEnglish() {
  var criteria = "from:noreply@eikaiwa.dmm.com レッスン予約";
  eachUnreadMessage(criteria, function (message) {
    var body = message.getBody();
    var [matched, year, month, day, sh, sm] = /様、(\d+)\/(\d\d)\/(\d\d)\s(\d\d):(\d\d)/.exec(body);
    var sdate = new Date(year, month-1, day, sh, sm);
    var edate = new Date(sdate.getTime() + 30 * 60000);
    createEvent("DMM英会話", sdate, edate, "https://eikaiwa.dmm.com/book/book_list/");
  });
  // レッスン前のリマインドメールも開く
  criteria = "from:noreply@eikaiwa.dmm.com レッスンのお知らせ";
  eachUnreadMessage(criteria, function (message) {
    //開くだけ
  });
}

ほかの設定はさきのブログ記事に準じたままなので、このスクリプトだけ直せばOK。

地方出身ITエンジニアが上京して2年経った今ギャップを考える

2019年も始まり、気づけば東京に来てから丸2年が経った。
2017年1月に転職と同時に上京したのだが、上京前に考えてたことと今それについてどう思うかをまとめる。


ITイベントいっぱい出(られ)る説

地方(富士市)にいたときは大きいイベントだけ参加していた。
当時参加したイベントは デブサミCROSSHTML5 Conference など。
日帰りで技術の関連性があるものはギョーム扱いで参加もしたこともあった。

上京直後は TECH PLAY から流れ込んでくる Connpass などの勉強会情報で関連性がある技術のものを片っ端から登録し、参加していた。
誰かに紹介されたものも基本されるがままに参加してた。

半年から1年くらい経った頃、IT勉強会に出ても技術は身につかないことがわかってきたので、最近はかなり選別して参加している。
コミュニティ活動を通じて知り合い増やしたりネットワーキングするようなことは全く得意ではないので、そういう人だとバンバン出ているようだ。これができる人はすごい。
技術動向を掴んだり、モチベーションを高めたり、もくもく作業したりするものを中心に参加していきたい。


優秀なITエンジニアいっぱいいる説

地方では 2:6:2 の法則がだいたい当てはまっていた。

この法則は現在も当てはまっていると思う。
ただ圧倒的に人が多いことと競争が多いためか、相対的にスキルが高いと感じる。
またクライアントワークするようになった関係か、お付き合いする会社の中にITエンジニアに限らずとびきり優秀な人がいたりして、やはり優秀な人はいるものだと思う。

あと一つ前のIT勉強会の話にも関連するが、東京のITエンジニアはみんな週末も勉強しているのかと思っていたが、そんなことはなく、勉強会に出てくるエンジニアは 2:6:2 の最初の2くらいだと思う。
勉強会ばかり出ているとすごい人と出くわすことが多いので、みんなそうかのように感じてしまうこともあるが、意外とそんなことはないし、勉強会を主催してみて主催のハードルが思っていたより低いこともわかったので、そこまで引け目を感じる必要はない。


求人多い説

多いと思っていたが多かった。
ただそれなりの高給が期待できる求人は、求人サイトよりも紹介のほうが期待できる。
採用は金銭的にも時間的にもコストがかかり、競争が激化しているのは日本どこも同じようだ。

待遇を気にしなければ求人がないということはありえないので、地方の程度によってはそもそもITエンジニアの求人すら存在しないので、そこと比べれば全然違う。
公共交通機関が整っていない状態で市内の求人が3件くらいしかないのは話にならない。
供給が追いついていないとも言えるので自分で開業すればいいのかも。需要はわからん。


転職頻度高い説

僕自身新卒採用の会社に12年おり、新卒採用中心だったために平均在籍年数がたぶん6-7年くらいはあったはず。
東京は2-3年でポンポン転職する人が多いと思っていた。

実際のところは短い頻度で転職する人とそこそこ長い年数で転職する人に大別できる気がしてる。
このバランスが地方では 3:7 東京では 7:3 くらいになっているのかな。
そういう意味ではそこそこ頻度が高い。


最後に

ということで本年もよろしくお願いします。

アフィリエイト眺めてたら見つけた謎のTシャツ

2018年に買ってよかったもの

年末年始に突入したもののやる気が高まらないので、作業意欲を高める一環でブログを書く。

スマートスピーカー関連

スマートLED電球
タイムセールで購入したが、残念ながら売り切れ中。
Hue は高いので手軽に購入したいと考えていたところ、当時2,000円ほどで購入できた。

照明をピンクにできるのでこういうこともできる模様。
[非エンジニアでもわかる]指パッチンで電球を色っぽくした話 - Qiita


電源オンオフ形の連携パターン。
Fire TV が HDMI 出力を専有するときの回避策として Alexa 連携を使う - ぐだぐだ言ってないでコードを書けよ、ハゲ。



エアコンを連携している。
「ただいま」と「いってらっしゃい」を学習リモコン sRemo-R で Alexa に最適化する - ぐだぐだ言ってないでコードを書けよ、ハゲ。


音楽聴かないなら Echo である必要はなく、普段音声でコントロールするので見た目はどうでもいいかなと思ってる。
Google Home からどちらかを置いて始めてハマるかどうかはかなり人を選ぶかなって感じ。
ITリテラシーが低い人には絶対に向かない。


AWS IoT エンタープライズボタン
AWS IoT Button を買ったのでトイレ IoT に使えそうなバックエンド書いた - ぐだぐだ言ってないでコードを書けよ、ハゲ。
職場のトイレ需要が下がってしまったので違う用途に切り替えた。 そのうち書きたい。

ガジェット全般

テザリング用途や枕元の充電など、複数用途を最小本数でしのぐ生活を送っていたが、「用途が多いならすべての場所にケーブルを置いたらいいじゃない」という発想で置いたところ完璧だった。
ミニマリストへの憧れは若干あるものの、このあたりのバランスは便利なほうに倒したい。


スプラトゥーンのオフ会目的で購入して便利だった。
あとはラズパイのデバッグで持ち運べるのがよい。
スプラトゥーンピークは20人近く集まっておりニーズも聞くので、何か理由をつけて不定期にやりたい。

ホーム

引越ししたのでステッカーを再び購入。
数百円で物理スパムフィルタが買えると考えると時間の節約としてよい。


洗面台や蛇口周りなど、水回り全般が新品状態で維持できる。
しかも使い捨てられる金額と最高。

コンビニ人間 (文春文庫)

コンビニ人間 (文春文庫)

諸事情で小説を読むことを勧められたので最初に読んだのがこれ。
話題の本を今頃って感じだが、まあ面白かった。
シゴトを生活の中心にするとこうなっていくのかなって感じ。
程度の違いはあれど、他人事ではない。


バラで読んでたものもあったが懐かしくて購入した。
こうして10冊まとめられると水戸黄門(観たことないが)のようにパターン化されつつあるのは否めないが、取り上げられるテーマが現代を映し出していると感じる。
ドラマも好きだったが小説のほうがスタイリッシュ。


歴史モノって学生時代よりも年を取ってから楽しく読めるようになった気がする。
背景となる歴史やいろんな予備知識がついたからかもしれない。


扱う設定が他になく新鮮さがあり、展開にもわくわくさせられる。

最後に

Amazon プライムの価値を考え直し始めてます。

App Service で KeyVault 参照する手順

この記事は Microsoft Azure Advent Calendar 2018 9日目の記事です。

Azure で好きなサービスは App Service です。
嬉しい機能追加のニュースが入ってきました。

Simplifying security for serverless and web apps with Azure Functions and App Service

Key Vault に保存した情報を App Service の環境変数から簡単に取り出せる仕組みができました。
動作や設定方法を簡単に確認します。

App Service の設定その1

App Service の Windows 版の場合は GUI で設定可能です。
ここでは App Service を Azure Active Directory にアプリケーション登録します。

App Service Register with Azure Active Directory
App Service Register with Azure Active Directory

Linux 版の場合も ドキュメント を読むと GUI で設定できそうでしたが、ポータルのUIが設定できなかったので Azure CLI で設定します。

Cloud Shell を開いてサクッと以下のコマンドを動かします。

az webapp identity assign --name myApp --resource-group myResourceGroup

Key Vault の設定

今回はシークレットを利用します。
Key Vault を開き、シークレット DbPassword を作成します。

keyvault-kv-secrets-list
Key Vault Secret List

シークレットを作成すると URI ができます。

keyvault-kv-uri
Key Vault Secret URI

この Secret Identifier URI は後で使うのでどこかにコピーしておきます。

次にアクセスポリシーを設定します。

Key Vault Add Policy1
Key Vault Add Policy1

Active Directory に登録した App Service をここで設定します。
アクセス権限については、今回はシークレットの読み込みだけなので、Get だけあれば動きます。

Key Vault Add Policy2
Key Vault Add Policy2

これで Key Vault の設定は終わりです。

App Service の設定その2

環境変数からの読み込みを App Settings で設定します。

App Service App Settings
App Service App Settings

以下のフォーマットを Value に設定します。

@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931)

SecretUri については Key Vault でコピーしておいた文字を入力しましょう。

設定は以上です。

設定がうまくいっていれば値が無事取得できます。

App Service Key Vault 参照成功
App Service Key Vault 参照成功

アクセス権が設定できていなかったり、取得に失敗した場合は以下のように、設定したとおりの値になります。

App Service Key Vault 参照失敗
App Service Key Vault 参照失敗

当然、みんな大好き Kudu でも読み出されたシークレットを確認できます。

App Service Kudu
App Service Kudu

あとがき

この機能は App Service 起動時に読み出し、環境変数に展開しているようです。
というのも、起動後に KeyVault 上のアクセスポリシーを削除してもアプリケーションが値を取得可能だったことからこれに至ります。
そのため、リクエスト毎取得するアプリケーション側の実装するよりもパフォーマンスへの影響を少なくできます。

また、アプリケーションの言語に依存せずに機能を利用できるのがありがたいですね。

参考記事

Azure Blob Storage を使った Static website の DevOps

kheiakiyama.hateblo.jp

以前から Static website 使ってポートフォリオサイト を動かしている。
Travic CI で AzCopy on Linux を使って適当なコンテナにデプロイし、そこから $web に手動コピーしてリリースするという手順を取っていた。

AzCopy がいつの間にか $web に対応していたので完全に自動化した。

Travic CI

サイトでは jekyll を使っているが、_site の部分を読み替えれば他のコンテンツ作成手段でも利用できるはず。

# Require Environment Variables
# - BLOB_CONTAINER_URL 
# - STORAGE_KEY
language: ruby
rvm:
  - 2.5
before_script:
  - chmod +x ./scripts/cibuild
script: ./scripts/cibuild
after_success:
  - sudo apt-get update
  - sudo apt-get install apt-transport-https -y
  - sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"
  - sudo add-apt-repository "deb http://cz.archive.ubuntu.com/ubuntu xenial main"
  - sudo apt-get update
  - sudo apt-get install libicu55 -y
  - sudo apt-get install libunwind-dev -y
  - wget -O azcopy.tar.gz https://aka.ms/downloadazcopylinux64
  - tar -xf azcopy.tar.gz
  - sudo ./install.sh
  - ls -la ./_site
  - azcopy --version
  - azcopy --source ./_site --destination "$BLOB_CONTAINER_URL" --dest-key $STORAGE_KEY --recursive --quiet --set-content-type
branches:
  only:
    - master
env:
  global:
    - NOKOGIRI_USE_SYSTEM_LIBRARIES=true # speeds up installation of html-proofer

環境変数

$BLOB_CONTAINER_URLhttps://xxx.blob.core.windows.net/$web のような指定になるが、Travis CI では特殊文字エスケープが必要なため、 https://xxx.blob.core.windows.net/\$web とする必要がある。

Environment Variables - Travis CI

デバッグ

最新の AzCopy on Linux を動かすために、Travis CI のデバッグで少し苦労した。

Travis CI で動くエージェントは Docker イメージが用意されているので下のリンクから該当イメージを探して手元で試すと早い。
ただし ruby のイメージは3GB超。。

Common Build Problems - Travis CI

Azure CDN への反映

コンテンツ更新するため、キャッシュを一旦削除した。

Azure CDN エンドポイントの消去 | Microsoft Docs

ドキュメントに載っていないが、Microsoft CDN のパージは3分くらいだったように感じる。

Go lang で SSL チェックするプログラム

書いた。

github.com

感想

badssl.com を使って TLS Version のテストケース書くなどした。

大量にリクエストを送って動作確認する実装なので、テスト実行するときは気をつけたい。

Go言語による並行処理

Go言語による並行処理