コンテナ化したMeCabをAzure Container Instancesで実行する例


#はじめに
[Azure FunctionsでMeCabを実行する例](https://qiita.com/kwhrkzk/items/1828d0c0d45c6762260b)
の続きなんですけどAzure Storageに格納しているユーザー辞書をコンパイルしようと思い、試行錯誤したので情報共有します。

#やりたいこと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109302/a7642074-640b-ff7b-fdd7-184483b141de.png)


MeCabをコンテナ化したイメージをサーバーレスで実行するために

+ イメージの置き場所をAzure Container Registry
+ コンテナの実行場所をAzure Container Instances
+ ボリュームのマウント位置をAzure File Storage
+ トリガーとアクションをAzure Logic Apps

の構成でやることにしました。

#MeCabのコンテナを作成する

```dockerfile:dockerfile
FROM gcc
ENV LD_LIBRARY_PATH /usr/local/lib:$LD_LIBRARY_PATH
WORKDIR /src
# mecabダウンロード
RUN wget "https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7cENtOXlicTFaRUE" -O mecab-0.996.tar.gz
RUN tar xzvf mecab-0.996.tar.gz
WORKDIR mecab-0.996
# mecab make
RUN set -x && \
    ./configure --with-charset=utf8 --enable-utf8-only && \
    make && \
    make check && \
    make install
WORKDIR /src
# ipadic ダウンロード
RUN set -x && \
    wget "https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7MWVlSDBCSXZMTXM" -O mecab-ipadic-2.7.0-20070801.tar.gz && \
    tar xzvf mecab-ipadic-2.7.0-20070801.tar.gz
WORKDIR mecab-ipadic-2.7.0-20070801
# ipadic make
RUN set -x && \
    ./configure --with-charset=utf8 --enable-utf8-only && \
    make && \
    make install
ENTRYPOINT ["/usr/local/libexec/mecab/mecab-dict-index", "-d", "/usr/local/lib/mecab/dic/ipadic", "-u", "/data/user.dic", "-f", "utf-8", "-t", "utf-8", "/data/user.csv" ]
```

```powershell
docker build -t mecabdictindex .
```

ユーザー辞書作成が目的なのでENTRYPOINTにガチガチに記載しています。
/dataがマウントされる予定の位置で/data/user.csvを入力として/data/user.dicを出力するイメージです。
イメージは例としてmecabdictindexという名前にしてます。

#Azure Container Registry(ACR)にpushする
参考
[Azure Container Registry を使ってみた](https://blog.shibayan.jp/entry/20161202/1480606440)
[Azure Container Registryの作成からDockerイメージのプッシュまで](https://tech-lab.sios.jp/archives/8517)

出来上がったイメージをAzure Container Registryにプッシュします。
Azure Container Registryを作成していて管理ユーザを有効にしている状況からのコマンド例です。
latestではなくタグ付けする必要があります。

```powershell
docker login xxx.azurecr.io
docker tag mecabdictindex xxx.azurecr.io/mecabdictindex:v1
docker push xxx.azurecr.io/mecabdictindex:v1
```

#Azure Container Instance(ACI)を作成する
Azure Portalでは細かな設定が出来ないのでCLIで行います。
見やすさのために改行しています。

```powershell
az container create
    --resource-group <リソースグループ名>
    --name <ACIの名前>
    --image <ACRに格納しているイメージ>  # 例としてxxx.azurecr.io/mecabdictindex:v1
    --registry-login-server <ACRの場所> # 例としてxxx.azurecr.io
    --registry-username <ACRの名前> # 例としてxxx
    --registry-password <パスワード> # 管理者ユーザを有効にしたときに画面に表示される
    --azure-file-volume-account-name <ストレージアカウント名> # マウントしたいFilesを設定している場所の名前
    --azure-file-volume-account-key <ストレージアカウントアクセスキー> # ストレージアカウントの[設定][アクセスキー]にある
    --azure-file-volume-share-name <Files名>
    --azure-file-volume-mount-path <マウント先> # 例として /data
    --restart-policy <再起動ポリシー> # 常時起動させるコンテナではないのでNever
```

設定項目多すぎて嫌になりますが、主にイメージの格納先とVolumeのマウント先の設定です。

#Azure Logic Appsを作成してトリガーとアクションを指定する

トリガーとしてAzure Container InstanceのStartがあれば良かったんですが
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109302/51e12105-eb94-ad01-2923-3569f05fa63c.png)
ないのでHttpアクションでRest APIとして叩きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109302/4c52754a-dba1-b326-7892-5750e38c18f1.png)


Rest APIのリファレンスは
[Container Groups - Start](https://docs.microsoft.com/en-us/rest/api/container-instances/containergroups/start)
にあります。
テンプレートが

```text
https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ContainerInstance/containerGroups/{containerGroupName}/start?api-version=2018-10-01
```

こんな感じでありますので必要な情報を差し替えていきます。
操作したいACIのプロパティのリソースIDを見ればsubscriptions以降start前までの情報が載っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109302/55f6fc02-1223-528c-a176-84be0e73db45.png)

これで実行すればACIが起動するかと思ったんですが駄目でした。

#権限の付与が必要
Azure Logic AppsにはAzure Container Instanceを操作する権限がないため、怒られます。
Azure Portalから権限を付与します。
参考
[Azure Logic Apps でマネージド ID を使用して認証し、リソースにアクセスする](https://docs.microsoft.com/ja-jp/azure/logic-apps/create-managed-service-identity)

## マネージドIDを有効にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109302/bcd24d82-37a9-cb7c-9f57-3ae9e7c55a4f.png)

## ACIのアクセス制御にマネージドIDを追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109302/3077b543-c1d2-d5fd-a40c-e45089e6b642.png)

ロール(役割)は色々あるんですがとりあえず最上位の所有者でやってみました。

#Azure Logic Appsを修正
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109302/12fe7c6e-114d-c490-0a37-3f35077259a8.png)

認証欄でマネージドIDを指定して、新しいパラメータの追加の中から対象ユーザーを選びます。

#結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109302/1451c9c9-a820-2ee3-582c-f5cbce244f94.png)

レスポンスが204 No ContentになっちゃってますがとりあえずENDPOINTに記載されている内容は動いてくれました。

#まとめ
コンテナ化したコンソールアプリっぽいものを起動したいだけだったのに結構苦労しました。
ほしいアクションがないときはAzure Functionを括り付けて、その中でREST API叩いていたんですが認証周りがとても面倒でした。
そんななかマネージドIDを利用した認証はとても楽で気軽にREST APIを試せると思いました。

コンテナ化したコンソールアプリっぽいものをサーバーレスで起動する方法について別の楽な方法等ありましたらご教示願います。