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

tech.guitarrapc.cóm

C#, PowerShell, Unity, Cloud Platfrom Technical Update and Features

AWS Windows 自動化ラウンドテーブルのセッション資料公開

AWS C# PowerShell Serverless Slides

2016/5/13 に、アマゾン ウェブ サービス(AWS) 様主催で、AWS で Windows を扱っている方を集めてのクローズドなラウンドテーブルの第一回が開催されました。

私も、AWS Solution Architect の@keisuke69さんにお誘いいただき登壇させていただきました。今回の資料を作るきっかけを与えていただき、本当にありがとうございます。当日参加して下さった方もありがとうございます。

今回は、ラウンドテーブルで用いた資料と、グラニのインフラの基本的な考え方を紹介します。

目次

Simple Windows Architecture on AWS

グラニは3年以上に渡りAWSでインフラ環境を構築しています。

神獄のヴァルハラゲートのリリース当初はPHPだったためAmazon Linux でしたが、2013年7月のある晩にサービス運営中のコードベースをC# にリプレースし、以降は Windows Server を中心としています。

当時と現在では、大きくインフラ構成が異なります。最も大きな変更が、インフラコンポーネントを Disposable *1 にしたことであり、よりシンプルにすることの追求です。

なぜ構成を公開するのか

今回の構成は、かなり踏み込んだ部分まで公開しています。グラニのインフラ構成を公開したのは、自分達の現状の整理と戒めを強く意識しています。

過去もそうですが、現在のインフラ構成にも多くの不満があり直したいことが山積みです。しかし直すにあたっても、そもそも私の考えが間違っていることが非常に多い自覚があります。

資料の補足と現状の理解を確認することを兼ねて少し現在の考えを書きますが、この資料や記事を読んでいただいた素敵な皆様がおかしいと感じられたことをご指導いただけると本当に嬉しいです。

Cloud Design Pattern

Cloud Design Pattern というと、AWS Cloud Design Patterns をぱっと思い浮かべることが多いと思います。しかし同時に Azure Design Pattern も浮かべる方も多いのではないでしょうか?私は、それぞれのデザインパターンを次のように大雑把に捉えています。

Cloud Design Pattern 大雑把な解釈
AWS-CloudDesignPattern インフラコンポーネント構成に関するデザインパターン
アンチパターンでないパターン集
Cloud Design Patterns: Prescriptive Architecture Guidance for Cloud Applications サービス設計に関するデザインパターン
ベスト プラクティスパターン集

インフラ環境をDisposable(いつでも捨てられるよう)にする。これを実現するためにAWS上の構成変更を躊躇わず、マネージドサービスを積極的に利用し、インフラ全員がコードを書いています。しかし巷に溢れる優れたサービスを無差別に採用はできません、自分達にあったサービスを選択するための原則がないとすぐにカオスな状況に陥ります。

コード設計、サービス取捨選択の原則としている考え方が Azure の Cloud Design Pattern にある、Retry PatternExternal configuration store Pattern です。

Retry Pattern

AWS にかぎらず、パブリッククラウドにおける大原則であることが多いように思います。

f:id:guitarrapc_tech:20160515084145p:plain

そのための手法も多く公開されています。

docs.aws.amazon.com

azure.microsoft.com

グラニも同様に失敗しても再施行によって成功する構成を目指しています。*2

失敗時の処理方法を共有するのではなく、もう一回やればいい。

このシンプルさは失敗に対する心理的障壁を下げるだけでなく、チームに対しても単純で伝えやすいです。

External configuration store Pattern

グラニのインフラは、インスタンスを1台たてるのも100台立てるのも構成方法と処理時間に大きな違いがないようにしています。この担保をしている重要な要素が External configuration Pattern であり、スケーラビルティに大きく寄与すると思っています。

f:id:guitarrapc_tech:20160515084539p:plain

インフラは多くのミドルウェアが動きます。*3自分たちのコードもその一つです。そんな時に利用するのが External configuration store Patternです。

ミドルウェアをインスタンスに配置するにあたり、構成ファイルをデプロイ自体に含めるのではなく、S3 や Blob、場合によっては Github など外部に寄せるようにする。

もちろん自動デプロイ/再デプロイが高速、容易な場合はその限りではありません。またコードを書くにしても、AWS LambdaAzure Functions といった Serverless を利用できないかまず検討しています。*4

Github に push すれば、全サーバーの構成が速やかに自動的に変わるというのは楽なものです。

Stamp Pattern

さて、インフラ視点のクラウドデザインパターンとして採用しているのが Stamp Pattern です。*5

ウェブサーバーに限らず、事前構成に時間が掛かる役割のEC2は Stamp パターンを用いてることで、全て同一構成に揃うようにしています。

f:id:guitarrapc_tech:20160515103111p:plain

CDP:Stampパターン - AWS-CloudDesignPattern

この辺は過去にも記事で書いたことがあります。

gihyo.jp

個人的には柔軟性、展開速度、シンプルさの観点からStamp Pattern はかなり嫌いです。*6Amazon AMI に Configuration Management を適用するだけで済む場合は、Stamp Pattern を利用せず CM を適用するだけで構成しています。

このあたりはWindows版 Docker が Windows Server 2016 で出るのを心から待っています。リリースされたらすぐに乗り換えて、全サーバーコンポーネントを一新します。

他の基本としている要素

Design Pattern とは少し違いますが、基本としている要素があります。

速度

先日のセッションと公開した資料の中で、「何度も、素早く繰り返すこと」(高速なイテレーション)を重視していることを述べました。

リトライするにしても、一回の処理に30min もかかっていては繰り返し自体が困難です。なるべく一回の施行は高速に、そして短いスパンで繰り返せることを目指しています。

もちろん何でも速さが正義ではありません。頻度との兼ね合いで、一日一回しか実行しないなら数分、数秒に大きなこだわりを出しても仕方ないと思っています。

副作用を伴う改善は極力選択しない

「課題A」を改善するために、「回避不可能な別の課題B」を生じる。

そんな改善は選択しないように気をつけています。*7

もちろん程度問題なので、課題B が限定的だったり無視できるようなデメリットなら採用することが多いです。また、短期的にデメリットがあっても、すぐに改善するとわかっているなら課題の大きさによっては待たずに即採用もあります。*8

大事にしているのは、「根本の問題がなんなのか、原因を分析」することです。その場ですぐに解決できなくても後日ヒントや解決策に気づけるように意識づけています。

コスト意識

AWS EC2 なら、Lambda や S3 など「実行時課金」の Serverless へ変更できないかいつも考えています。

もしEC2でやるしかなくても、Spot Instance を積極的に採用しています。EC2 オンデマンドだったり、他のリソースなら Reserved Instance を検討します。

グラニのインフラにおいて、AWS 利用コストは当初と比較して劇的に改善しました。今も、不定期に構成を見なおして改善できないか検討しています。

自動化を常に考慮する

マネージドサービスを導入する際は、自動化できることを強く評価しています。Webhook、APIを含めて、サービス間連携できることが自動化手段を提供しているかどうかは重要です。

逆に、.NET SDK がなくとも APIが公開されていれば問題とすることがあまりありません。*9

そういえば AWS でウェブコンソールを使って最後にEC2を立てたのは3年前です。ずっと SDK 経由で作成しかしていません。

デプロイ戦略

今回構成したインフラ構成において、アプリは C#6.0、ASP.NET MVC 5.3.2 です。

そのため、2013年当時は MSDeployを用いていましたが、内製ツールのRapidHouse へと一年以上前に切り替えました。

残念ながらRapidHouse の公開は今のところ予定にないのですが、当初の構想通りデプロイが 1秒で終わるようにできたのは体感できるインパクトが大きくよかったと思っています。

f:id:guitarrapc_tech:20160516040959p:plain

ずっと言っているのですが、Windows におけるシンボリックリンクの重要性は極めて高く、インフラ構成を「柔軟、簡素」にすることができる可能性が高いのでぜひ検討してください。

mamiya の発表を見た時に、ほとんど同じ発想だったのでどこの環境でも同じことを考えるのだなぁと思い、ブラッシュアップのため参考にさせていただきました。

github.com

資料も非常に分かりやすかったので、セッション資料でも参考にしています。

speakerdeck.com

インフラ基盤を C#へ

RapidHouse によって 各Windowsサーバーの操作がAPI公開されているので、サーバーの管理は PowerShell Remoting から HTTP(S)経由に完全移行し、C# がフル活用できるようになっています。

察しの良い方は気づかれた通り、昔のグラニは PowerShell をインフラの中心としていましたが、現在はC# が中心になっています。

もちろんPowerShell も利用しますが、ただのツールです。PowerShell DSC の Configuration や ワンライナー、補助スクリプトがメインで長大なコードは次々とC#にリプレースされています。

構成図の見直し

今回は、ヴァルハラゲートの構成図でしたが、最初期からみてどんどん変わっていっています。

変化は大事だと思っています。停滞はサービスの死に直結します。

そして変化の記録と公開も同様に大事にしています。弊社のサービス構成図は、CTOのスライド でも度々引用されています。

少し時系列で並べて見ます。構成図にない変化がかなりあるのですが、ここでは触れません。

時期 構成図
2013年3月 f:id:guitarrapc_tech:20160515102546p:plain
2013年9月 f:id:guitarrapc_tech:20160515102636p:plain
2014年1月 f:id:guitarrapc_tech:20160515102801p:plain
2015年12月 f:id:guitarrapc_tech:20160515102841p:plain
2016年5月 f:id:guitarrapc_tech:20160515103249p:plain

構成図自体も変化しています。従来は構成図を Visio で書いていましたが、現在は CloudCraft に移行しています。Visio、昔から使っていますが、ついにトドメを刺せました。

だれでも直感的に使えて再利用も共有も可能。しかも、コンポーネントの違いも3D で表現しやすい構成図。CloudCraft はそんなサービスだと思います。

cloudcraft.co

まとめ

どうでしょうか?目新しいことがない、ふつーの構成ではありませんか?Windows を AWS で使うのがツラい、Linux にしたいという声をよく聞きますが、私達は Unix/Linux でのふつーをWindows でも十分に構築できると考え実践する努力をしています。インフラの多くのコンポーネントは、実は Serverless だったりもします。

AWSにロックイン、ということもよく耳にしますが一切そんなことはありません。AWS じゃなくても、いつでも Azure や Google Cloud Platform に移行できる体制でもあります。それでも AWS を使うのは全てのバランスとAurora などの各リソースの強力、安定さからです。

グラニのインフラが目指しているのは、Windowsでうんぬんより、ユーザーにサービスをよりよく楽しんでもらえることです。そのためにできることをチーム全員が積極的に挑戦しています。Linux には、共有するという文化から始まり、多くの面でインフラのトレンドを突き進んでいます。新しい考え方、手法にはサービスがより良くなることが多く秘められています。それが Windows でできないということは誰も言っていません、だから採用する努力をしています。

あ、あと、グラニのこんなインフラを変えたい、もっと良くしたいとお考えの方をインフラ一同心からお待ちしています。

*1:Immutable Infrastructure というより Disposable Infrastructure という方がグラニには適しています

*2:失敗したらリトライ可能な状態にロールバックする、冪等性を担保するなど、多くのやり方があるでしょう

*3:なるべく動かしたくないですし、減らすことを常に図っていますが!

*4:AWS Lambda が C# に対応してくれれば、Azure Functions にある不満が API Gateway/Lambda で強く改善できるので変更するのですが...

*5:いわゆるゴールデンイメージですね

*6:正確にはEC2が嫌いです

*7:それでも失敗します……

*8:なるべく待ちますが

*9:特に Swagger に対応していると嬉しいです