読者です 読者をやめる 読者になる 読者になる

DataScience.rb ワークショップを開催し、PyCall を用いたデータ解析の実演をしました

開発部 R&D グループの村田 (mrkn) です。

2017年05月19日、Speee Lounge で DataScience.rb ワークショップ 〜ここまでできる Rubyでデータサイエンス〜 を開催しました。 f:id:mogmog2:20170522144449j:plain

このワークショップは当初、私が2016年10月から取り組んでいる PyCall の開発 *1 と、Ruby アソシエーション開発助成の支援の下で実施された西田さん、三軒家さん、芦田さんによるプロジェクトの成果報告のために企画されました。そんな中、クリアコードの須藤さんが2017年2月頃から Apache Arrow の Ruby バインディングを開発する Red Data Tools プロジェクトを開始されました。Apache Arrow は2016年頃から開始されたプロジェクトで、私は当初から Ruby の将来にとって重要な基盤になるはずだと思い注目していたこともあり *2、Red Data Tools プロジェクトの進展には期待をしています。そこで、私から須藤さんにお願いして Apache Arrow と Red Data Tools の話をして頂くことになりました。

ワークショップの全体の流れは次のようになりました。

最初に、このワークショップの位置付けについて説明しました。私は、2016年から2017年初めにかけて、カンファレンスで何度か「Ruby はデータサイエンスでは使えないプログラミング言語である」ことを強い表現で説明してきました。このようなネガティブな話をし続けていても Ruby がデータ解析で使えるプログラミング言語になるわけではないので、私はこのワークショップを起点に、ネガティブな話をせず開発を前に進めていくことに注力したいと考えていました。そこで、オープニングで「今日を Ruby でデータサイエンスをやっていく日々の始まり」にするために、次のことを宣言しました。

  • Ruby をデータサイエンスで使えるプログラミング言語にしていこう
  • ネガティブな話はもうやめよう
  • 過去や現在に囚われず、粛々と開発を進めよう

f:id:mogmog2:20170522144502j:plain

そして、Ruby をデータサイエンスで使えるプログラミング言語にするために3つの道があることを説明しました。

  1. 巨人の肩に乗る
  2. 既存の gem をなんとかする
  3. Ruby のための仕組みを整えていく

ワークショップ当日のコンテンツは、これら3つのそれぞれについての現状報告でした。オープニングの後、次の順にそれぞれ発表とデモを実施しました。スライドや Jupyter notebook ファイル、関連ブログ記事へのリンクを記載したので、当日参加されていて復習したい方も、参加できなかった方も合わせてご覧ください。

  1. 巨人の肩に乗る ⇒ 村田賢太「PyCallを使ってRubyでデータ解析をやってみよう」 [slide] [jupyter notebook]
  2. 既存の gem をなんとかする ⇒ 西田孝三、三軒家佑將
「Ruby Association開発助成で得た知見の共有と今後」 [slide] [jupyter notebook]
  3. Ruby のための仕組みを整えていく ⇒ 須藤功平
「RubyもApache Arrowでデータ処理言語の仲間入り」 [slide] [blog]

DataScience.rb は今後も開発の節目ごとにワークショップを開催していく予定です。私たちの取組に賛同し、開発に協力してくださる方は、SciRuby の Slack や Red Data Tools の gitter に参加してください。利用事例の報告、バグレポートなどお待ちしております。

Ruby をデータサイエンスで使えるプログラミング言語にしていく活動を、今後ともよろしくお願いいたします。

*1:2016年12月〜2017年3月まで、しまねソフト研究開発センターさまに支援していただきました

*2:将来的に daru のバックエンドに採用したいと思ってこのような issue を作ったことがあります

ECSを使ってPR毎に確認環境を構築する社内ツールをOSSで開発してます!

 Speee開発基盤部、兼ヌリカエエンジニアの森岡です。 今回は、ECSを使ってPR毎に確認環境を構築する社内ツールであるwebapp-revieee をOSSとして公開しましたので、そのご紹介をさせて頂きます。

作ったもの

f:id:selmertsx:20170515113712p:plain

 PRを作ると、そのPRに対応した確認環境がECS上に構築され、PRに構築した確認環境にアクセスするためのURLがコメントされます。 ここで構築された確認環境は、PRがcloseされると一緒に閉じられます。主にデザイナの画面確認や、制作物のPOレビューなどが捗ります。 この社内ツールは一つのプロダクトだけでなく、社内のすべてのプロダクトの確認環境を用意することが可能です。 この社内ツールは、Webapp Revieeeという名前で開発されました。

作った理由

 今回このような社内ツールを作った背景として、確認環境の構築に時間的、金銭的コストを掛けたくない。 という理由があります。私が所属しているヌリカエというプロダクトにおいても、 確認環境がいくつか存在しています。しかもそれらの環境は、常に誰かが利用していて、 順番待ちが発生することが少なくありません。

この問題を解決する外部サービスとして、Heroku review appsというものが存在します。 当初このサービスの利用を検討したのですが、下記の理由で断念しました。

  • Elasticsearchなどのミドルウェアのバージョンを指定できない
  • 他のdynoと直接通信できないため、microservices の確認環境を構築できない
  • 本番環境ともローカル環境とも異なる環境なので、Heroku特有の問題に悩まされることがある
  • Enterpise でなければ、IP制限を入れることができない

 また、OSSでもdtan4 さんが開発されているpausというものがあります。 こちらは docker swarmを使ってEC2上で動いているのですが、docker swarmのクラスタ管理が手間であったり、 containerのログ取得が出来ないといった問題が存在します。 現在ではECSやGKEを利用すれば、この問題に対応できそうだったので、僕たちは自作するという選択肢を取りました。 そして下記の理由からECSを採用しました。

  • GKEとECSでは、実現できる機能に大きな差異は無い
  • 弊社ではGCPよりもAWSを利用しているプロダクトが多い
  • ユースケースを踏まえて料金を見積もったときに、AWSの方が20%ほどやすかった

Webapp Revieeeの使い方(理想)

 Webapp Revieeeは、社内のプロダクトで単純なrailsアプリケーションならば、 webhookを受け取るためのbotをリポジトリに招待するだけで使えます。 また、ユーザーはdockerに対する知識が無くとも、簡単に確認環境を構築することが出来ます。

というシステムを作るという理想を持って、僕たちはWebapp Revieeeの開発を開始しました。

Webapp Revieeeの構成

f:id:selmertsx:20170510101103p:plain:w500

Webapp Revieeeの構成図を上に乗せます。Webapp Revieeeは、app server, nginx, ECS, mysql instance, ECRの5つの要素からなります。 各要素の役割について、コンテナのデプロイと、確認環境へのアクセスを例に説明していきたいと思います。

コンテナのデプロイ

f:id:selmertsx:20170510102443p:plain

  • app_serverは、GitHubにてPRが作られた際にwebhookを受取ります
  • app_serverはPRが持つbranch情報を、起動するtaskに渡し、ECSのinstanceにデプロイします
  • containerをデプロイした ECS instanceのIPと、containerのport番号を MySQL に保存します。
  • 確認環境にアクセスするためのURLをGitHubの該当PRにコメントする

上記操作によって、確認環境がECS上に構築されます。 このとき、コンテナのentrypointは下記のようにしています。

f:id:selmertsx:20170510101214p:plain

タスク起動時にPRのbranch名を渡すことによって、任意のbranchでコンテナが起動するようにしています。

確認環境へのアクセス

f:id:selmertsx:20170510102456p:plain

  • ユーザーは、GitHubのPRにてコメントされる確認環境のURLにアクセスする
  • nginxはURLに該当するcontainerのアクセス情報をMySQLから取得して、ユーザーをそちらに流す

nginxからMySQLへのアクセスにはluaを使っています。

Webapp Revieee の使い方(現状)

  • Docker Imageを作成しECRに登録
  • Task Definitionの設定ファイルを作成
  • GitHubリポジトリにbotを招待
  • PRを作成

 現状では、Docker ImageのECRへの登録をユーザーが行うようにしています。 理由としては、開発環境で必要な MySQL等の初期データ投入等、プロダクト側でImageの更新をハンドリングしたいからです。

 Task Definitionの設定ファイル作成もユーザーにやって貰っています。 Docker Imageを作成する課程で、ほぼほぼ docker-compose.ymlを作ってもらえているはずなので、 そのdocker-compose.ymlを元にecs-cliを使って、Task Definitionを作る方法もあります。 しかし、今回は下記の理由により直接書いてもらう方法に落ち着きました。

  • ecs-cli compose は現状では、docker-compose のver3に対応していない
  • memory制限やlogging driverの設定など、docker-composeの設定を手元とECS環境で書き分ける必要がある
  • 自動化する前に素朴な仕組みで実現し、データを集めることで自動化するべき方向性を見極めたい

そこまでユーザー側が設定を完了させたのちに、botをGitHubリポジトリに招待して貰うことによって、本サービスは利用が可能となります。

今後の展望

僕たちのWebapp Revieeeは、ようやく社内で利用され始めた段階です。 現状ではまだまだ荒削りな状態で、運用や設定において手間であったり、 痒いところに手が届かない部分はあるかと思います。 今後は、僕たちのサービスを使ってくれる現場の声を聞きながら、自動化するべき点は自動化し、 エンジニアがいじりたいところはいじれるようにし、より便利に使ってもらえるように開発を進めていきたいと考えています。

同時に、Webapp RevieeeはOSSで開発しておりますので、アプリケーションのコードだけでなく、 本システムを構築する上で必要な設定も、どしどし公開していきたいと考えています。 Webapp Revieeeに対する要望やコードのイケてない部分、より良い実装方法等ありましたら、issue等で教えて頂けると幸いです。

最後に

本OSSはクリアコードの須藤さんに見て頂きながら、開発を進めていきました。 そのときの様子などは、クリアコードさんのOSS開発支援サービス事例の記事 にも記載されておりますので、そちらの方を参照下さい。

須藤さんには、OSSとしての開発の仕方だけでなく、適切なコミットメッセージの書き方、 コードレビューの仕方、Rubyでの設計など、様々な方面でご指導して頂きました。 本当にありがとうございます!

Androidで最新のJavaを使えない問題に向き合ってみた

Speee技術顧問の id:gfx です。

もうかなり時間が立ってしまいましたが、2月に行われたSpeeeKaigi #2 で基調講演をやらせてもらいました。 SpeeeKaigi #2の様子はこちらです。

tech.speee.jp

社内でこういうイベントがあるのはとてもいいですね。今回は自由テーマだったので、各人の興味分野が知れて大変楽しい一日でした。 f:id:mogmog2:20170508145255j:plain

私も普段の仕事とはあまり関係ない自由研究として、Retropilerというツールを開発して発表しました。当日のプレゼンテーションはQiitaにあります。

Retropiler: AndroidでJava8の機能を使うもう一つの方法

Retropiler: https://github.com/retropiler/retropiler

この資料はwhatにフォーカスしているので、それを補間すべくwhyとhowをこのエントリで書きます。

このretropilerを開発した動機は、「Androidで最新のJavaを使えない」という問題に対して何かできないかと思ったためです。鳴かぬなら鳴かせてみせようホトトギスの精神というわけです。

Retropilerでできること

Retropilerを使うと、次のようなコードを minSdkVersion=15 なアプリでも実行できます。

retropiler/MainActivity.java

// forEachは本来 API version 24 が必要
Arrays.asList("foo", "bar").forEach(s -> {
    Log.d("RetropilerExample", s); // => "foo", "bar"
});

// Optionalも本来 API version 24 が必要
Optional.of("foo").map(String::toUpperCase).ifPresent(s -> {
  Log.d("RetropilerExample", s); // => FOO
});

詳細はQiitaにポストした資料をご覧ください。

Androidで最新のJavaを使えないとはどういうことか

さて本題です。まず、Androidの開発環境における「Javaのバージョン」はいくつかの考え方があり、自明ではありません。ここでは3つに分けて考えます。

ひとつはAndroid端末にインストールされているAndroid OS、それにバンドルされているDalvik処理系(仮想マシン)がどのJVMバージョンに相当するかというものです。Androidの公式ドキュメントで「Javaの言語機能(language feature)」として言及される場合はこのバージョンです。

この言語機能のバージョンですが、Android 7.xまではJava 6相当と考えられています。2017年にリリース予定であるAndroid 8.xについては定かではありませんが、いまのところビルドツールはJava 6相当のDalvikバイトコードを生成するようです。

もうひとつは、Android端末にインストールされているAndroid OS、それにバンドルされているJava標準ライブラリのバージョンです。これはJDKのものとはだいぶ違うので「だいたいどのJDKに相当するか」としか言えないのですが、Android 7未満ではほぼJava7相当、Android 7以降はほぼJava8相当といえます。これはAndroidの公式ドキュメントでは「JavaのAPI」のバージョンと呼ばれています。

最後に、Androidアプリケーションを開発する際にJavaコンパイラに与えるバージョンです。

これは前二つと違ってAndroid OSのバージョンとある程度独立しているため、ビルドツールの進歩により改善する余地があります。実際、Android Studio 2.4 (Android Gradle Plugin 2.4) からは、minSdkVersionを古いまま(たとえば15)、開発時バージョンを Java8 (JavaVersion.VERSION_1_8) にしてアプリケーションをビルドできます。

ここでdesugarとよばれるツールにより、一部のJava8の言語機能、たとえばラムダ式をminSdkVersionに関わらず使うことができます*1。しかしdesugarは今のところアプリが動作する環境(=Android OS)に機能を追加できるわけではありません。つまりAndroid 7未満のバージョンで、Java8で追加された java.util.Optionaljava.util.function パッケージ、streamなどの標準ライブラリは使えません。これらをAndroidアプリで使いたければ、minSdkVersion=24 にする必要があります。

これがAndroid開発の現状であり、「Androidで最新のJavaを使えない」という問題です。

Retropilerが示したもの

さて、現状はこのとおりです。Android SDKに含まれる予定のdesugarは、ラムダなどの一部の言語機能をJava6のJVM向けに変換し、それをDalvikバイトコードに変換しますが、標準ライブラリに関しては何もしません。

しかし、原理的にはdesugarのようにバイトコードを編集し、Android OSにバンドルされていない新しいJava標準ライブラリ相当のものを差し込むことはできるはずなのです。このコンセプトを証明するためにRetropilerを開発してみた結果、ビルドフェーズにおける標準ライブラリの差し替えが可能であることを実証できました。

これは、アプリケーションコードで工夫するのではなく、ビルドシステムに干渉することで動作環境、つまりAndroid OSに足りないものを足してしまおうという発想です。世界のありようが気に入らなければ世界のほうを変えましょう。

実装

Retropilerは、Javassistを使ってバイトコードを編集するツールです。desugarと同様に、Android Gradle pluginのTransform APIを使って実装しています。

Javassistを使えばバイトコードをかなり自由に変更できます。たとえばRetropilerは Optional を使っている箇所を retropiler runtime の提供する _Optional に置き換えたり、 list.forEach(cb) の呼び出しを _Iterable.forEach(list, cb) に置き換えたりします。バイトコードの知識は必要になりますが、Javassistができることはまさに魔法です。

さてそういうわけで、RetropilerはJava8のクラスライブラリをランタイムライブラリとして提供する必要があります。たとえばこのように。

https://github.com/retropiler/retropiler/blob/master/runtime/src/main/java/io/github/retropiler/runtime/java/util/_Optional.java

なお、このファイルはAOSPからコピーしてきたものを改編したものですが、AOSPのファイルはOpen JDKからコピーしてきたもので、そのライセンスはGPL v2 + CE (classpath exception) となっています。Androidの場合CEについて定説がないようなので、今のところRetropilerを使うアプリケーションのライセンスをGPL v2(+CE)にしてソースコードを公開しなければなりません。製品で使う場合はその点にご注意ください。

まとめ

本エントリではRetropilerを紹介しました。まだやりたいことを全て実現したわけではないので、しばらくは開発を継続するつもりです。

もっとも実際には、Retropilerを実用的なレベルにするのは難しいかもしれません。差し込むためのライブラリを保守するのは一人では手に余るほど高コストです。しかし、なんといっても技術的に可能だということは示せました。また今回のGoogleによるdesugarの開発という事実もあります。もしかしたら数年後には公式でサポートもあり得るかもしれませんね。

という小難しいことは置いといて、 コードを書くのは楽しい とうことが伝わっていれば幸いです。

グロースハッカー大集合!A/BテストNightを開催しました!

こんにちは、Speeeでディレクターしております、荘司です。先日社内でABtestのノウハウをシェアするイベント、「ABtestNight」を開催しましたので、そのイベントレポをお伝えします。

ABtestNightとは

Speeeでは、クライアント様のデジタルマーケティングを支援するB2B事業と、自社メディアを展開するB2C事業を展開しており、その中でABテストなど、CVR改善などを目指して、日々サイト改善に取り組んでいます。今回はその事業間のグロースハックのノウハウ共有を目的として、「ABtestNight」を開催しました!当日は弊社が利用しているABtestツール「Optimizey」日本正規代理店の株式会社イー・エージェンシー様にもご登壇いただきました。

目標設定における失敗談

トップバッターは女性系メディアに携わる伊佐より、「ABテストの3つの失敗談」というタイトルで登壇しました。印象的だったのは「目標設計が不十分だった」という失敗談。

運用体制が固まり、ABテストが実際に回り始めると、今後毎月どの程度CVRが改善するなど、予想が立てづらくなど、なかなか目標設計が難しいものです。伊佐のチームでは、目標設定がうまくできないまま、ABテストを回していたため、達成の度合いを評価できず、チームメンバーのモチベーションを保つのも難しくなっていきました。

事業目標から改善目標を逆算する手もありますが、市場状況や流入元の変化によって、CVRなどは大きく変動します。そう考えるとABテストの目標設計は難しい問題です。そういった問題に対して、どう対処したのか。

f:id:kshouji12:20170428140646j:plain

回数×打率×改善率というプロセスKPI

ABテストの成果は、「テストを実施した回数」×「そのテストがオリジナルより良かった割合(=打率)」×「そのテストの改善率」で決まります。このチームでは、過去に実施したABテストデータを元に、回数と打率、改善率を計算し、それぞれの値をプロセスKPIとして設計したそうです。適切に目標を掲げて、着実に成果を積み上げていきたいですね。

オンラインCVRだけを見ていて後悔した話

次に登壇したヌリカエのディレクター阿部は、「CVRだけ見ていて後悔した話」というテーマで登壇しました。ヌリカエではオンラインページでのCVの後に、オフラインの架電などで事業成果が発生します。

当初ABテストを開始した際は、オフラインページでのCVRを向上させることに重きを置いていました。しかしある施策を打った際、オンラインのCVRが向上した一方、オフラインの数値が下がっていたことが判明したのです。事業全体から考えると、オンラインのCVRをあげるだけでなく、オフラインの数値も確認しておかなければ、結果的に事業改善から遠ざかってしまうこともありえます。 f:id:kshouji12:20170428140327j:plain

オフライン×オンラインでKPIを再設計

その後阿部のチームでは、オンラインの数値に加えて、オフラインの数値を加味したKPIを再設計し、その指標を判断軸に、ABテストを回しています。来店予約など、オフライン事業の集客窓口としてWebを使っている事業者の方は、心の留めておきたい教訓です。

コンサルタントとしてのデータに基づく客観的な分析

3人目は、弊社CRO(コンバージョンレート最適化)担当の岡井が登壇しました。彼らはクライアント様のサイト改善をミッションとして追っており、これまでの2名とは異なり、B2B事業の担当者ならでは視点での発表でした。

コンサルタントとして、クライアント様の改善点を見つけ、一緒に改善していくことが求められるため、「データに基づく客観的な分析」の必要性を強く語っていました。彼らが担当するのは、これまでクライアント様が愛着などを込めて運用されてきたサイトです。その改善点を指摘するためには、主観ではなく、クライアント様も理解できる客観的なデータを用いた、徹底したデータ分析で納得いただく必要があります。

そのため彼ら独自の分析手法を作り上げ、日々クライアントへの価値提供に努めているようです。

f:id:kshouji12:20170428140853j:plain

伝えるタイミングの重要性とは

最後4人目は、イー・エージェンシー社の吉野様にご登壇いただきました。テーマは「伝えるタイミング」。伝えたいことが明確な、わかりやすいプレゼンテーションでした。

通常ABtestを実施する際、キャッチコピーなどの「メッセージ」や、色やアイコン・形などの「見せ方」に注力しがちです。たとえばCTAボタンの文言や色形などです。しかしそのボタンをユーザーに見せるべき「タイミング(訴求する順番や位置)」をしっかり考えることも、同様に重要だと吉野様は語ります。

実際同じ「メッセージ」、同じ「見せ方」の施策でも、ユーザーへ伝えるタイミングによって大きく成果が変わります。プレゼンでは、ECサイトの例を引き合いに、「在庫切れ間近」のメッセージを表示するタイミング(位置)によって、成果が大きく異なった事例を紹介されていました。

ユーザー視点に立って仮説を立てた上で、「メッセージ」「見せ方」「タイミング」をしっかり考えた上で、成果の高いテストを繰り返したいですね。

f:id:kshouji12:20170428141009j:plain

プレゼン後は座談会

プレゼンのあとは、登壇者の方に質問を投げかけながら回答いただく座談会を実施しました。

たとえば、

  • 改善対象ページの決め方は?
  • 施策の優先順位の決め方は?
  • 施策の振り返りはどうしてる?
  • 統計的有意性がでないテストはどうする?

など、ABテストを進める方がよくぶつかるけれども、なかなか書籍に解が落ちていない問について、回答いただきました。各チームごとに色があり、終盤にはオススメのツールを紹介や、突発的なお悩み相談が始まるなど、非常にフランクの雰囲気で盛り上がりをみせました。

その後は懇親会として、簡単な軽食をつまみながら、各所でABtest談話に花が咲いていました。また登壇希望企業様がいれば、随時ABtestNight第二弾を開催していきたいと考えております。ご興味ある方はぜひ荘司までご連絡くださいませ。

共催のイー・エージェンシー様ブログの当イベント記事は以下からどうぞ。

https://optimizely.e-agency.co.jp/article/speee-abtest-review/

f:id:kshouji12:20170428141149j:plain

tech.speee.jp

tech.speee.jp

tech.speee.jp

tech.speee.jp

IDCフロンティアでオートスケール導入

コミュニケーションメディア事業部リードエンジニアのid:eva-hashimotoです。 今回はSpeeeKaigiで発表した開発しているVICOLLEのIDCフロンティアでオートスケールを導入した話をします。

SpeeeKaigiについてはこちら tech.speee.jp

発表時のスライドはこちら

スライドで発表した内容をつまみ食いしながら説明します。

IDCフロンティアのクラウド環境

IDCFのクラウド基盤としてCloudStackで構築されているため、CloudStack-APIを利用しCLIでインフラ操作が利用できます。 ただし公式のAPIドキュメントではなくIDCF ドキュメントを参照しましょう! 公式ではありとあらゆるインフラ、ミドルウェア操作が記載されていますがIDCF側で対応していないものもあるのです。

ステートレスにする

オートスケールで重要な点として対象のサーバはステートレスでなければなりません。 この点はAWSでも同じですね! 具体的にステートレスとはプログラムの状態やデータを保持しないシステムです。つまりセッション情報やミドルウェアの設定なんかも保持しないデータにあたります。

今回のオートスケール対象はアプリケーションサーバなので下記のミドルウェアが対象です。

  • Nginx
  • Ruby on Rails(Puma)

オートスケールの流れ

  • テンプレートから新規インスタンスを作成、起動
  • nginxの設定、アプリのデプロイ
  • バランサーにアサイン

テンプレート作成

テンプレートというのはAWSでいうとAMIのことです。作る上で先ほどのステートレスにするということが大前提になり、Railsについてのステートレス方法は他でググってください。 その他の設定としてはOSのパラメータチューニングを行っています。ネットワーク周りやファイルディスクリプタの閾値変更など行っておくといいと思います。

インスタンス作成

オートスケールが作動するトリガーとしてサーバ負荷やコネクション数などあると思います。 今回のサービスではサーバの負荷をトリガーとして説明します。

このような負荷の取得スクリプト(bash)を定期的に叩いてます。

CPU_LIMIT=50
APP_CPU=`sudo ssh {サーバのIP} "mpstat 2 1" | grep 平均値 |awk {'print 100-$12'} |cut -d. -f1

if test $APP_CPU -ge $CPU_LIMIT; then
   echo app autoscale!!
   {Jenkins-APIの新規インスタンス構築タスクを叩く}
fi

Jenkinsの新規構築タスクはCloudStackのAPIでテンプレートからインスタンスの作成を叩いてます。

ID=`cloudstack-api deployVirtualMachine \
      --serviceofferingid ${インスタンスサイズID} \
      --templateid ${テンプレートID} \
      --zoneid ${ゾーンID} \
      --group ${グループ名} \
      --name "${インスタンス名}" \
      | grep '"id":' | awk -F: {'print $2'}| awk -F\" {'print $2'}`

作成されたインスタンスIDが返却されるので変数で持ち、のちにバランサーのアサイン時のパラメータとして使ってます。

デプロイ

OS起動時にCapistranoを自動起動させています。[/etc/systemd/system/puma.service]

[Unit]
Description=puma server
After=nginx.service

[Service]
Type=oneshot
ExecStart={Capistranoのコマンド}
User=deploy

[Install]
WantedBy=multi-user.target

nginxの設定に関してはNFSで共有したり、githubで管理されてたりすると思いますので各々に管理されてる方法に合わせて設定ファイルを読み込みましょう。

nginxの設定変更、railsの起動ができたのちにバランサーアサインのAPIを叩いてオートスケール終了になります。

まとめ

IDCフロンティアでもちょっとした手間が必要ですがオートスケールの仕組みを作ることができます。 AWSではauto scaling groupなどで多少楽にできますが自作することでより細かい動作や自由度の高さはメリットではないでしょうか? 現在の仕組みでトリガー作動からバランサーアサインまでの時間が平均で3分くらいになります。 その他詳しい仕組みについてはご連絡いただければと思います。