Azureのマネージドサービスで作るWebアプリケーションスタック

[Azure Advent Calendar 2019](https://qiita.com/advent-calendar/2019/azure) 9日目の記事です。
担当は@saboyutakaです。

Azureには様々なサービスがありますが、今回はWebアプリケーションを作る時に利用するマネージドサービスを使って作るWebアプリケーションスタックを3つの構成パターンで紹介していこうと思います。

* Azure App Service で単一アプリケーションを構築する
* Azure Front Doorを使って複数のアップストリームを構築する
* Azure API Managementを使ってMicroservices化する


<blockquote class="twitter-tweet"><a href="https://twitter.com/saboyutaka/status/1195271444554371072"/></blockquote>


## Azure App Service で単一アプリケーションを構築する

### 構築イメージ
 <img width="600" alt="Azure App Service で単一アプリケーションを構築する" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28262/6551ef58-1d32-efad-ae6d-bd421b984170.png">

Webアプリケーションを単一のランタイムで作成します。Laravel, Ruby on Rails, Django, Express, Wordpress などを構築するイメージです。

### Azure App Service
 <img width="300" alt="Azure App Service" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28262/ed89c1fe-ac9d-eaed-e8f7-977fbe7698a0.png">


[App Service の概要](https://docs.microsoft.com/ja-jp/azure/app-service/overview)
> Azure App Service は、Web アプリケーション、REST API、およびモバイル バックエンドをホストするための HTTP ベースのサービスです。 開発には、.NET、.NET Core、Java、Ruby、Node.js、PHP、Python のうち、お気に入りの言語をご利用いただけます。 

App Serviceはアプリケーションを動かすランタイムを提供するPaaSです。Amazon Elastic Beanstalk, HerokuのAzure版です。設定でランタイム, OSを選択するだけで、好きな言語でアプリケーションのランタイムをAzure上に構築できます。OSはWindowsかLinuxを選択できます。
主要な言語のランタイムは用意されてますが、Web App for ContainersとしてDockerfileでランタイムを構築できるので用意されていない言語を使いたい、独自で必要なライブラリを用意したい場合はDockerで立てる事ができます。

App Serviceで構築されるランタイムもDockerで構築されていてDockerfileは公開されているのでApp Serviceのランタイムで利用されているライブラリの確認をしたり、ローカルで本番と同一の開発環境を作ることも可能です。

https://github.com/microsoft/Oryx

### Azure App Serviceでできる事
* WebAppのホスティング
* カスタムドメイン
* 無料のマネージドSSL証明書の発行
    * Let's Encrypt的なやつ
    * [Azure App Service free Managed Certificate for SSL/TLSを試してみた](https://blog.kokoni.jp/entry/2019/12/02/070000)
    * こちらのブログで初めて知りました。便利そう。
* デプロイ
    * ブルーグリーンデプロイ
    * Gitリポジトリの更新フックでのデプロイ
    * GitHub Action, Azure DevOpsのDeployを利用したCI/CD
    * Dockerの場合は、Azure Container Registryを利用する

* デプロイスロット
    * stagingを2クリックくらいで作れる
    * カナリアリリース
        * [Azure Web Appsでカナリアリリースを試してみた](https://blog.kokoni.jp/entry/20191204)
* SSHで直接操作
* オートスケール
* メトリックの監視, アラート

## Azure Front Doorを使って複数のアップストリームを構築する

### 構築イメージ
<img width="600" alt="Azure Front Doorを使って複数のアップストリームを構築する" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28262/1c3de37f-d5df-d040-18e9-5d38e80d11cf.png">

同一ドメインで複数のアップストリームを立てる場合の構築例です。最初はモノリシックで始めたサービスをNuxt.jsなどを使ってフロントエンドを切り分けするイメージです。

### Azure Front Door
 <img width="300" alt="azure-front-door-logo.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28262/c4c3b00f-7ce8-2166-6a88-5a4fbfb720fb.jpeg">

[Azure Front Door Service とは](https://docs.microsoft.com/ja-jp/azure/frontdoor/front-door-overview)
> Azure Front Door Service では、高可用性のために最大限のパフォーマンスと即時グローバル フェイルオーバーを最適化することで、Web トラフィックのグローバル ルーティングを定義、管理、および監視することができます。 Front Door を使用すると、グローバル (複数リージョン) のコンシューマーや企業のアプリケーションを、Azure を使用して世界中のユーザーに発信する、堅牢で高性能なパーソナライズされた最新のアプリケーション、API、およびコンテンツに変換することができます。

Azure Front Door はアプリケーションへのエンドポイントと高機能Webサーバーを一つにしたようなマネージドサービスです。利用するとURLパターンに基づいてアップストリームを切り分ける事ができます、同一ドメインで後方に複数のアプリケーションを立てる時に利用します。ソフトウェアで言うとNginxのようなやつです。


### Azure Front Doorでできる事
* L7ロードバランサ
    * URLパターンに基づいて複数のアップストリームへリクエストをフォワードします
    * URL書き換え可能
    * 重みによる負荷分散
    * カナリアリリース
* カスタムドメイン
* Web Application Firewall(WAF)
    * Front DoorからWAFが利用できます
* グローバルなエンドポイント
    * Azureが用意した世界中にあるエンドポイントからリクエストを受け付けます。　リクエストはユーザーの最寄りのエンドポイントが受け付るため、レイテンシーが通常の単一のオリジンへのアクセスより短くなるらしいです?
    * あるエンドポイントがダウンした場合でもシームレスに別のエンドポイントが引き継ぎます。ネットワーク障害が起きた場合でもユーザーはアプリケーションにアクセスする事ができます。
* geoフィルタリング
    * 特定の地域からのアクセスをフィルタリングできます
* CDN
    * URLパターンによってレスポンスをキャッシュできる&グローバルにエンドポイントが存在する、ためCDNのように動作させる事ができます
* HTTP/2のサポート
* マネージドサービスなのでリクエスト増大によるCPU, メモリへの負荷は気にしなくていいはず


## Azure API Managementを使ってMicroservices化する

### 構成イメージ
<img width="600" alt="Azure API Managementを使ってMicroservices化する" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28262/1ceca044-02f5-9ca5-d7d1-857def1b22e8.png">

 サービスが大きくなってきて単一のAPIサーバーで構築していたものをMicroservices化する必要が出てきました。ユーザー認証基盤をAuth0に載せ換え、API ManagementはOpenID Connectでユーザーを認証します。APIは既存のAPIに加え、他の言語をApp Serviceで構築したAPI, Azure Functionsで構築されたAPI(後方のAzureの各サービスへ接続を行う)、AWS Lambdaで作られたAPIなどと接続します。 API Managementを利用する事でAPIとして必要な要件をAPI Managementにオフロードします。

### Azure API Management

<img width="300" alt="Azure API Management" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28262/6c43a183-31b6-b2d4-6162-b13d59ae94ba.png">


[API Management の概要](https://docs.microsoft.com/ja-jp/azure/api-management/api-management-key-concepts)

> API Management (APIM) は、既存のバックエンドのサービスに対して一貫性のある最新の API ゲートウェイを迅速に作成する手段です。

API Managementを利用する事でAPIとして共通で必要な機能をAPI Managementにオフロードすることができます。認証, APIを横断したログの取得, キャッシュ機構, セキュリティなど。ソフトウェアとしては[Kong Gateway](https://konghq.com/kong/)がありますが[API Gateway Pattern](https://microservices.io/patterns/apigateway.html)のマネージドサービスです。

### API Managementで出来る事

* 認証(OAuth 2.0, OpenID Connect, 証明書等)
* API登録
    * リクエストのフォワード
    * リクエスト、レスポンスの加工
    * Header付与、破棄
* ログ
* キャッシュ
* ポリシーによる柔軟な制御
    * Rate Limit
    * 再試行


## まとめ
AzureのWebアプリケーションに関連が深いサービスを3つ紹介しました。Azureのサービスを使う事でどんなアーキテクチャでも(だいたいは)サービスを組み合わせる事で実現する事ができます。マネージドサービスが年々充実していきているので最近はVMを立てて直接アプリケーションを構築することが減ってきて運用コスト・環境構築のコストが少なくなって益々アプリケーションの開発に専念できるようになってきてます。数年前まではAWSを使っていてAzureよくわからんと言う感じでしたが、この2年ぐらいAzureを触っていてAzureで不足しているものはない、むしろAzureめちゃくちゃ便利と思うことが多くなってきたので興味ある方ぜひ触ってみてください ☺️

## 筆者について
株式会社EBILABでAzureを使ってデータ連携のサーバレスアーキテクチャ構築やマネージドサービスを使い倒したWebアプリケーションの開発などやってます。興味ある方はツイッターなどで連絡ください🙋‍♀️