通信経路閉域化された Azure App Service Web App へ Pipeline から Web アプリをデプロイする

# はじめに
ここで紹介している App Service は[こちら](https://www.slideshare.net/ssuser56097c/vnetprivate-linkazure-app-service)の資料で示された手順に沿って構築されたプライベートなアプリです。本記事の情報は2020年5月末現在の情報です。

パブリックに公開された App Service の場合、以下の画像のように Azure ポータルから CI/CD のパイプラインを GUI で構築することが可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161850/d62f7163-c3bd-e700-ebac-45c1f45cef12.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161850/8be9b319-9fa7-f8d6-71f3-ea2eb25f7891.png)

しかしながら、[こちら](https://www.slideshare.net/ssuser56097c/vnetprivate-linkazure-app-service)の資料で示された構成の App Service でそのまま Pipeline を構築すると、
`Error: Error Code: ERROR_COULD_NOT_CONNECT_TO_REMOTESVC More Information: Could not connect to the remote computer ("YOUR_WEBSITE_URL") using the specified process ("Web Management Service") because the server did not respond.`
とデプロイ時にエラーが出ます。
これはよくよく考えると当たり前のことで、パブリックに公開されていない App Service であるため、デプロイ時に Pipeline からのアクセスが許可されていない状態となっております。そこで今回は、パブリックからのアクセスが遮断されている App Service に対しての Pipeline 構築を Azure DevOps を用いて行います。

↓今回のアーキテクチャ概要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161850/a45b11a8-8377-28cf-e58d-6ba0eb2273b6.png)
App Service Web App へアクセス可能な VNET 内に Pipeline の Agent をホストした Virtual Machine を置いて、その Virtual Machine 経由でアプリのデプロイを行います。


# Azure DevOps 側の準備
### App Service の確認
はじめに、https://{YOUR_APP_SERVICE_NAME}.azurewebsites.net にパブリック IP からアクセスし、403 Forbidden が返ってくることを確認してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161850/792e865d-875a-9498-b29f-df8e27745772.png)

### Azure Pipelines を用いた CI/CD の構築
次に、Azure DevOps のプロジェクトを準備します。今回は非常に単純な ASP .NET Core の Web アプリのリポジトリを持ったプロジェクトを利用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161850/341ead38-912d-a129-7063-9451c3b78dcc.png)

Azure DevOps のプロジェクトが準備できましたら、Azure ポータルへアクセスし、App Service のデプロイセンターから CI/CD の設定を行います。今回はソース管理に Azure Repos 、ビルドプロバイダーに Azure Pipelines（プレビュー）を利用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161850/18c4459f-3c49-667f-c0d7-5c010feccc6e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161850/cc6de357-f59b-5e69-6b2b-1579a30836a4.png)
構成の設定では、先ほど準備した Azure DevOps のプロジェクトを選択し、デプロイの対象としたいリポジトリとブランチを選択します。その後構成の確認を行い、 CI/CD Pipeline が構築されたことを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161850/e3e46a37-6482-63ac-b16f-e635de24bf31.png)

次に、Azure DevOps のプロジェクトに戻り、Pipelines の項目をチェックします。先ほど App Service 側で設定した Pipeline が構築されていることがわかります。CI Pipeline は Pipelines の項目から、CD Pipeline は Releases の項目からチェックできます。また、そのままの設定では、デプロイが失敗していることが確認できます（デプロイ先の App Service がパブリックアクセスを拒否しているため、Microsoft Hosted のデプロイマシンによるデプロイも拒否されています）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161850/a5f671f1-6bfc-06c7-271d-174d2698c411.png)


# Pipeline Agent の準備
### Agent pool 作成
はじめに、Pipeline 用の Agent を作成します。プロジェクトの左下の Project Settings から Agent pools を選択し、Add pool をクリックしてください。作成する Pool Type は Self-hosted を選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161850/f794ace4-632d-66c2-b74b-1bcc5434f98d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161850/9dbe3750-b643-dadb-f5ef-8622e52883f6.png)

作成した Agent pool をクリックし、Agents タブから New agent をクリックしてください。エージェントの種類は Windows x64 を選択し、ダウンロードリンクをコピーしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161850/690238e2-16d1-5db5-2d42-6a3dcdfec1b5.png)


### PAT トークン取得
次に、Azure DevOps のアクセストークンを取得します。プロジェクトの画面右上の設定ボタンから Personal access tokens をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161850/cb91ec7f-544d-2faf-1779-b6754eba23cd.png)
New Token をクリックし、トークンの名前や有効期限を設定してください。また、Scopes は Custom defined を選択し、Agent Pools の Read & manage にのみチェックを入れてください（Agent Poolsが出てこない場合は Ahow all scopes をクリックしてください）。最後に Create をクリックし、表示されるトークンを後で利用するためにメモしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161850/a487c14c-f8e4-0f1d-2627-78ff638f6cbf.png)


### Agent を Virtual Machine 上に展開
次に、App Service へアクセス可能な Virtual Machine（今回は Windows Server 2019）へ RDP で接続し、先ほどコピーしたリンクから Agent をダウンロードしてください。Agent は zip ファイルでダウンロードされますので、お好きな場所で解凍してください。解凍しましたら、config.bat ファイルを実行してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161850/8ce2a810-97c5-5b88-3668-6758ce33322b.png)
ここで様々なことを入力する必要があるのですが、以下の通り入力してください。

- Enter server URL: `https://dev.azure.com/{YOUR＿ORGANIZATION}`を入力してください
- Enter authentication type (press enter for PAT): そのまま Enter を押してください
- Enter personal access token: 先ほど取得した PAT トークンを入力してください
- Enter agent pool (press enter for default): 先ほど作成した Agent pool の名前を入力してください
- Enter agent name: お好きな Agent の名前を入力してください
- Enter work folder (press enter for _work): そのまま Enter を押してください
- Enter run agent as service? (Y/N): Y を入力してください
- Enter User account to use for the service: そのまま Enter を押してください

設定が終了しましたら run.bat ファイルを実行してください。Azure DevOps の Agent pools にて、ここで作成した Agent が正常に認識されているか確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161850/b33b4e5b-54a8-6a62-8817-3c81d67a6e29.png)

### 作成した Agent を Pipeline で利用する
Releases Pipeline の Edit を選択し、Task の編集を行います。Run on agent を選択し、Agent pool を [Hosted] Azure Pipelines から、今回作成した Agent pool を選択し、Save をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161850/66eeb0b1-cc21-3027-a4cf-f2a4305f0e86.png)

最後に、コードの編集を Commit した後に、CI/CD Pipeline が正常に稼働し、無事 Web アプリに変更が適用されたことを確認します。これで、パブリックに公開されていない App Service に対しても CI/CD Pipeline を構築することができました。

# おわりに
GitHub Actions でも同じことができるのか試してみたいですね（たぶんできそう…）。
本記事の情報は2020年5月末現在の情報です。
## 参考資料
https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/v2-windows?view=azure-devops
https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/agents?view=azure-devops&tabs=browser