[Azure] Azure Container Instances のチュートリアル (Azure Cloud Shell 編)

## 本チュートリアルのベース
Azure Container Instances (ACI) の公式ドキュメントには、以下のページから始まる 3 部構成のチュートリアルが公開されており、第一歩として試してみたいときに便利です。
https://docs.microsoft.com/ja-jp/azure/container-instances/container-instances-tutorial-prepare-app

ただ、このチュートリアルを指示通りに進めるには、注釈にもある通り Azure CLI と Docker エンジンを含むローカル環境が必要です。
> 重要
>Azure Cloud Shell には Docker デーモンが含まれていないため、このチュートリアルを完了するためには、Azure CLI と Docker エンジンの両方を自分でローカル コンピューターにインストールする必要があります。 このチュートリアルで Azure Cloud Shell を使用することはできません。

本記事では、上記公式チュートリアルをベースに、ローカル環境を用意することなく Azure 環境だけでサンプルアプリケーションを ACI 上に立てる方法をご紹介します。

## 1. Azure Cloud Shell で アプリケーションコードを clone する
Azure Cloud Shell を立ち上げましょう。
コンソールが立ち上がったら、公式チュートリアル記載の Git コマンドでサンプルアプリケーションを取得します。

~~~shell
git clone https://github.com/Azure-Samples/aci-helloworld.git
~~~

この後、公式チュートリアルでは `docker build` コマンドが続きますが、Azure Cloud Shell には Docker デーモンが含まれておらず、実行するとエラーになります。
そのため、ここでは次の手順に進みます。

## 2. Azure Container Registry を用意する
Azure Container Registry (ACR) を用意しましょう。
まずは、リソースグループと ACR を作成します。

~~~shell
az group create --name <resourceGroupName> --location japaneast
az acr create --resource-group <resourceGroupName> --name <acrName> --sku Basic
~~~

公式チュートリアル ステップ 2 ではローカルイメージを作成し ACR にプッシュしています。
https://docs.microsoft.com/ja-jp/azure/container-instances/container-instances-tutorial-prepare-acr

しかし、Azure Cloud Shell ではイメージをつくれません。
そこで、ACR の機能である ACR タスクを活用します。

## 3. ACR タスクでイメージをビルドし、プッシュする
ACR タスクを一言でいうと、クラウド上のコンテナイメージビルドサービスです。
この機能を使うことで、Azure Cloud Shell ではできなかったイメージのビルドが可能になります。
※ ACR タスクにはその他にも機能がありますので、詳細は以下をご参照ください。
https://docs.microsoft.com/ja-jp/azure/container-registry/container-registry-tasks-overview

それでは、以下のコマンドで ACR タスクでイメージのビルド、およびプッシュをしましょう。

~~~shell
az acr build --image aci-tutorial-app:v1 \
  --registry <acrName> \
  --file ./aci-helloworld/Dockerfile ./aci-helloworld 
~~~

ACR のイメージ一覧を取得して、`aci-tutorial-app` が存在することを確認しましょう。

~~~shell
az acr repository list --name <acrName> --output table
~~~

`v1` タグも確認しましょう。

~~~shell
az acr repository show-tags --name <acrName> --repository aci-tutorial-app --output table
~~~

## 4. サービスプリンシパルを作成する
次は、サービスプリンシパルを作成します。
ACR に格納されたイメージを ACI がプルするために必要となります。

サービスプリンシパルの作成については以下のページで紹介されています。
https://docs.microsoft.com/ja-jp/azure/container-registry/container-registry-auth-aci

今回は、これを Azure Cloud Shell 上で実行していきます。
まず、以下のコマンドで簡易エディターを開きます。

~~~shell
code create-sp.sh
~~~

Azure Cloud Shell の上部にエディターが開いたと思います。
そこに、公式ページで公開されている以下のスクリプトをコピペします。
`<acrName>` には作成した ACR の名前を入れて保存します。

~~~shell
#!/bin/bash

# Modify for your environment.
# ACR_NAME: The name of your Azure Container Registry
# SERVICE_PRINCIPAL_NAME: Must be unique within your AD tenant
ACR_NAME=<acrName>
SERVICE_PRINCIPAL_NAME=acr-service-principal

# Obtain the full registry ID for subsequent command args
ACR_REGISTRY_ID=$(az acr show --name $ACR_NAME --query id --output tsv)

# Create the service principal with rights scoped to the registry.
# Default permissions are for docker pull access. Modify the '--role'
# argument value as desired:
# acrpull:     pull only
# acrpush:     push and pull
# owner:       push, pull, and assign roles
SP_PASSWD=$(az ad sp create-for-rbac --name http://$SERVICE_PRINCIPAL_NAME --scopes $ACR_REGISTRY_ID --role acrpull --query password --output tsv)
SP_APP_ID=$(az ad sp show --id http://$SERVICE_PRINCIPAL_NAME --query appId --output tsv)

# Output the service principal's credentials; use these in your services and
# applications to authenticate to the container registry.
echo "Service principal ID: $SP_APP_ID"
echo "Service principal password: $SP_PASSWD"
~~~

Azure Cloud Shell 側に戻って、以下のコマンドでスクリプトを実行します。

~~~shell
chmod 744 create-sp.sh
./create-sp.sh
~~~

スクリプトを実行すると、サービスプリンシパルが作成され、`Service principal ID` と `Service principal password` が表示されます。
これらの値は次のステップで使用しますので、手元にメモしておきましょう。

## 5. ACI でコンテナをデプロイする
あとは公式チュートリアル ステップ 3 の通りです。
https://docs.microsoft.com/ja-jp/azure/container-instances/container-instances-tutorial-deploy-app

ACR のログインサーバー名を取得します。

~~~shell
az acr show --name <acrName> --query loginServer
~~~

いよいよデプロイです。
`<acrLoginServer>` には取得したログインサーバー名を、`<service-principal-ID>` と `<service-principal-password>` は前の手順で手元にメモした値を使用します。
`<aciDnsLabel>` には任意の DNS label を指定してください (リージョン内で一意とする必要があります)。

~~~shell
az container create --resource-group <resourceGroupName> \
  --name aci-tutorial-app \
  --image <acrLoginServer>/aci-tutorial-app:v1 \
  --cpu 1 --memory 1 \
  --registry-login-server <acrLoginServer> \
  --registry-username <service-principal-ID> \
  --registry-password <service-principal-password> \
  --dns-name-label <aciDnsLabel> --ports 80
~~~

デプロイの進行状況を確認するには次のコマンドです。

~~~shell
az container show --resource-group <resourceGroupName> --name aci-tutorial-app --query instanceView.state
~~~

出力が　`Runnning` であればデプロイ完了です。
次のコマンドで FQDN を確認します。

~~~shell
az container show --resource-group <resourceGroupName> --name aci-tutorial-app --query ipAddress.fqdn
~~~~

ブラウザで FQDN にアクセスしてみましょう。
<img width="518" alt="2020-07-02_17h27_03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423135/5fd84933-6419-6f5e-e169-9c561fc22e5c.png">

Azure Cloud Shell に戻って、以下のコマンドでログが出力できます。

~~~shell
az container logs --resource-group <resourceGroupName> --name aci-tutorial-app
~~~

最後はリソースグループの削除を忘れずに。

~~~shell
az group delete --name <resourceGroupName>
~~~