[Azure] CircleCIからスロットをスワップする

# はじめに

CircleCIからAzure App Serviceのデプロイスロットをスワップします。

[以前REST APIでZipデプロイしたとき](https://qiita.com/blue32a/items/98b6a3a6210e13df9f08)、自動スワップが構成されていると結果をポーリングしている時にエラーになることがある、という現象がありました。

「相性が悪いので明示的にスワップしたほうがよい」ということだったので、それを実際にやってみます。

# 注意

以下の手順や情報は私が試行錯誤して試したもので、理解が浅い点や他に方法良い方法があるかもしれません。

# スワップする方法

外部からスワップするには[REST API](https://docs.microsoft.com/ja-jp/rest/api/appservice/webapps/swapslotslot)とAzure CLIを使用する方法の２択になりそうです。

REST APIを使用すると非同期通信になりそう（ポーリングが面倒...）なのでAzure CLIを使ってみようと思います。

# CircleCIでAzure CILを使う方法

[circleci/azure-cli Orb](https://circleci.com/developer/orbs/orb/circleci/azure-cli)を使うことで簡単に扱えます。

CircleCIの[Orb](https://circleci.com/docs/ja/2.0/orb-intro/)とはジョブやコマンドなどをまとめた再利用可能なパッケージです。

# CLIからログインする

前段階として、まずはログインしてみましょう。

## ユーザを追加する

CLIからスワップするには、まずログインする必要があります。
しかし、

> This approach doesn't work with Microsoft accounts or accounts that have two-factor authentication enabled.

（訳）このアプローチは、Microsoftアカウントまたは2要素認証が有効になっているアカウントでは機能しません。

[Sign in with credentials on the command line](https://docs.microsoft.com/ja-jp/cli/azure/authenticate-azure-cli#sign-in-with-credentials-on-the-command-line)

とのことで、私が普段使っているアカウントではログインできませんでした。

というわけでAzure Active Directoryで新しくユーザを追加します。

### Azure Active Directoryでユーザ作成

ユーザ情報については、本件を試すだけなら最低限の情報（ユーザ名とパスワードなど）を入力すれば十分みたいです。

※ 業務で使用される場合はセキュリティなどを考慮して適宜対応してください

ただし作成しただけでは足りず、もうひと手間必要です。

ユーザ作成で入力したパスワードは一時的なものらしく、この状態ではCLIからはログインできません。
というわけで、Azureポータルサイトから作成したユーザで一度ログインし、新しいパスワードを設定します。

これで準備完了です。

## ログインするためのCircleCI設定

```yaml:.circleci/config.yml
# 主要な部分のみ抜粋
version: 2.1

orbs:
  azure-cli: circleci/azure-cli@1.1.0

jobs:
  sample:
    executor: azure-cli/azure-docker
    steps:
      - azure-cli/login-with-user:
          alternate-tenant: true
```

[circleci/azure-cli Orb](https://circleci.com/developer/orbs/orb/circleci/azure-cli)のOrb Quick Start Guideにある通り、`version`と`orbs`を設定します。

`executor`はdefaultとazure-dockerの２種類ありますが、Pythonを使うなど特別な要件がなければazure-dockerで良さそうです。
（defaultの場合はまず`azure-cli/install`を実行する必要がありそうです。）

ログイン用のコマンドはいくつかありますが今回は[login-with-user](https://circleci.com/developer/orbs/orb/circleci/azure-cli#commands-login-with-user)で進めます。

まずはプロジェクトの環境変数にtenant、username、passwordを設定しましょう。
環境変数名はコマンドのドキュメントを参照してください。別の名称を使いたい場合はコマンドのパラメータとして名称を設定します。

※ tenantはAzure Active Directoryから参照できるテナントIDになりますが、tenantの概念がちゃんと理解できていないので、その点ご了承下さい。

以上を設定した上でジョブが正常終了すればログインは完了です。

# スロットをスワップする

ログインできたところでスワップに進みます。

## ユーザに権限を設定する

スロットをスワップさせるには、App Serviceに対して権限が必要です。
具体的には`Microsoft.Web/sites/slots/slotsswap/action`が必要で、組み込みロールの中ではWebsite Contributor（Webサイト共同作成者）がその権限を持ちます。

[Azure 組み込みロール](https://docs.microsoft.com/ja-jp/azure/role-based-access-control/built-in-roles)

App Serviceのアクセス制御（IAM）から「ロールの割り当ての追加」を行い、先程作成したユーザに対してWebsite Contributor（Webサイト共同作成者）を割り当てます。

※ 実際の業務ではセキュリティなどを考慮して適宜対応してください

これでCLIからスワップができるようになります。

## スワップするためのCircleCI設定

```yaml:.circleci/config.yml
# 主要な部分のみ抜粋
version: 2.1

orbs:
  azure-cli: circleci/azure-cli@1.1.0

jobs:
  sample:
    executor: azure-cli/azure-docker
    steps:
      - azure-cli/login-with-user:
          alternate-tenant: true

      - run:
          name: Slot swap
          command: az webapp deployment slot swap -g <Resource Group> -n <App Name> --slot <slot> --target-slot <target slot>
```

スワップのコマンドを追加しました。
パラメータはドキュメントを参照しつつ適宜設定してください。
[az webapp deployment slot swap](https://docs.microsoft.com/en-us/cli/azure/webapp/deployment/slot?view=azure-cli-latest#az_webapp_deployment_slot_swap)

ジョブが正常終了すればスワップは完了です。

# まとめ

ユーザ関係でつまづくところがあったものの、スワップ自体は難しいものではありませんでした。
（もうデプロイもCLIでいいんじゃないかな）

以上、参考になれば幸いです。