はじめに
業務でApp Service - Web App for Containersを利用し、Webアプリケーションの構築を行っています。その開発環境を構築するために、Azure Developer CLI(以降はazdとする)を試しました。
本記事では、azdとazdでWeb App for Containersを実現するための問題点とその対応について記載します。
Azure Developer CLI
クラウド上にサービスを展開する際の開発フローでは、devcontainer等でローカルに構築した開発環境での動作確認後、クラウド上に予め構築した各メンバーで共有の開発環境にデプロイし、動作検証を行うことが多いと思います。そのため、クラウド上での動作検証でエラーを出すと、他メンバーの作業の遅延を齎す可能性があります。また、クラウドサービスの細かく検証するために自分で検証用のクラウド環境を1から構築する必要があり大変労力を使います。
これらの問題を解決する1つのツールとして、Azureで2023年5月にGAされたazdに注目しました。azdは開発効率化のためのツールです。azdを使用することで、個人専用のアプリケーションがデプロイされたAzure環境を1コマンドで構築することができます。専用のため、自由に作って試して壊せる環境です。その環境で動作確認してからチーム共有のクラウド環境にデプロイするため、クラウド上でのエラーが少なくなることが考えられます。また、クラウドサービス検証のための構築作業を大幅に軽減し気軽に実施することができます。
導入フロー
azdでは導入を簡略化するために、いくつかテンプレートが用意されています。
1から導入するのは非常に労力が掛かるため、基本的にテンプレートからパクることから始まります。例えば、C# API と Azure 上のSQL Databaseを使用した静的React Web アプリ + 関数を作成したい場合、以下の少ないコマンド数で構築が完了します。
# テンプレートの構成でプロジェクトを初期化
$ azd init --template Azure-Samples/todo-csharp-sql-swa-func
# Azureリソースとアプリケーションコードをデプロイ
$ azd up
azd init --template
を実行することで自身のプロジェクトにazdに必要な要素を構築するため、ディレクトリ構成等で参考になります。
他のテンプレート一覧: https://github.com/topics/azd-templates
各種コマンド
azdで環境構築する方は、基本的に以下の4つのコマンドさえ覚えておけば十分です。
$ azd up # アプリケーションとインラフを両方デプロイ
$ azd deploy # アプリケーションのみデプロイ
$ azd provision # インラフのみデプロイ
$ azd down # azdで作成したリソースを全て削除
他にもコマンドはありますが、多く使用するのは上記のコマンドです。azd up
を実行すると自動的に環境が作成されます。azd down
を実行するとその環境は綺麗さっぱりなくなります。
非常に簡単なコマンドで環境を自由に作って壊してということが可能になります。
azdに必要な構成ファイル
project
|- azure.yaml // azdデプロイ時のワークフローの定義ファイル
|- infra/ // AzureリソースのBicep群
|- .azure // ローカルで扱うazdの設定ファイル
azure.yaml
azdデプロイ時のワークフローの定義ファイルになります。以下はAppServiceにNode.jsのWebアプリケーションをデプロイする定義ファイルです
name: yourApp
metadata:
template: yourApp@0.0.1-beta
services:
web:
project: ./src/web # package.jsonが存在するWebプロジェクトのディレクトリを指定
dist: build # buildによって成果物が格納されるディレクトリ
language: js # アプリケーションコードの言語
host: appservice # デプロイ先のAzureサービス
services.webというプロパティは以下のようなAppServiceに付与したazd専用の特殊なタグ(tags: { 'azd-service-name': 'web' }
)をつけることでデプロイ先のAzureリソースを認識させています。
resource appService 'Microsoft.Web/sites@2022-03-01' = {
name: name
location: location
tags: { 'azd-service-name': 'web' }
...
}
他にもオプションは存在し、特定のhost
ではdocker
プロパティを指定することでDockerイメージの構築を実施することもできます。
infra/
この階層にはBicepで書かれた沢山のIaCコードを格納していきます。azdを導入する上で一番の労力はこのBicepコードをガリガリと書いていく作業です。導入フローでも説明したテンプレートにはBicepのコードが沢山含まれています。プロジェクトによってAzure構成が異なるため、テンプレート丸パクリでは難しいですが、作業コストを軽減するためにできるだけプロジェクトに似た構成のテンプレートからパクることを推奨します。
頑張りましょう!
.azure/
azd init
を実行すると.azure
配下に設定ファイルが構築されます。azdコマンドを実行する際は、常に.azure
配下の設定ファイルが参照されます。infra/main.bicep
でのBicepのoutputで指定した変数が設定ファイルに記載され、azdコマンドの実行で使用することができます。
導入における制限
azdは新しいツールなため、まだまだ制限は厳しめです。azdが導入可能かどうかの確認が必要です。
azdでWeb App for Containersを構築
ここまで、Azure Developer CLIについて書いてきましたが、今回やりたいのはazdでWeb App for Containersを構築することです。
問題
azdの制限により、現在AppSerivceではコンテナイメージのデプロイをサポートしていません。同じことをやろうとした方がissueに上げていました。しかしながら、issueのやりとりの通り、Azure Container Apps(ACA)を使う無理やりする方法が提案されていた (むむむ、、こしゃくな、、)
対応策
azure.yamlでは、hooks
というプロパティが存在し、Azureインフラのリソースもしくはアプリケーションのデプロイ前/後のイベントをフックし、任意のスクリプトを実行することができます。
今回、実現するために書いたazure.yamlとスクリプトは以下になります。
name: web
services:
web:
project: ./src/web # package.jsonが存在するWebプロジェクトのディレクトリを指定
dist: build # buildによって成果物が格納されるディレクトリ
language: js # アプリケーションコードの言語
host: appservice # デプロイ先のAzureサービス
hooks:
postdeploy: # アプリケーションのデプロイ後にスクリプトを実行
shell: sh # sh or pwshを指定可能
run: | # 複数行の記載が可能
echo "Deploy Web App"
./deploy-webapp.sh
azure.yamlでは、アプリケーションコードのデプロイ後のイベントをフックし、AppServiceにデプロイするスクリプトを実行しています。
#!/bin/bash
echo "========================================"
echo "login ACR"
echo "========================================"
ACR_USER=`az acr credential show --name ${ACR_NAME} --resource-group ${AZURE_RESOURCE_GROUP} --query username -o tsv`
ACR_PASS=`az acr credential show --name ${ACR_NAME} --resource-group ${AZURE_RESOURCE_GROUP} --query passwords[0].value -o tsv`
az acr login -n ${ACR_NAME} --username ${ACR_USER} --password ${ACR_PASS}
echo "========================================"
echo "webapp build and push"
echo "========================================"
cd ./src/web
docker build -t ${ACR_NAME}.azurecr.io/${ACR_REPOSITORY_NAME}:latest .
docker push ${ACR_NAME}.azurecr.io/${ACR_REPOSITORY_NAME}:latest
# webappにデプロイ(latestを常に取得するようにしているのでAppServiceを再起動)
echo "========================================"
echo "Restart WebApp"
echo "========================================"
az webapp restart -g ${AZURE_RESOURCE_GROUP} -n ${APPSERVICE_WEBAPP_NAME}
deploy-webapp.shの中身はシンプルです。
- Azure Container Registry(ACR)にログイン
- Dockerイメージのビルド/プッシュ
- latestを常に取得するようにしているためAppServiceを再起動
スクリプト内の環境変数やACR、AppServiceはinfra/配下にBicepコードをガリガリ書く必要があります。dockerファイルも予め準備する必要があります。今回提示したazure.yamlやスクリプトは単なる一例なので参考程度にしてください。
まとめ
開発環境として、気軽に作って試して壊せる自分しかイジらない専用のAzure環境を構築するために、Azure Developer CLI(以降はazdとする)の説明と、azdでApp Service - Web App for Containersを構築する上での問題とその対応策について記載しました
azdは以下の旨味があります。
- 開発/本番環境で運用しているクラウド環境を1コマンドで気軽に作って試して壊せる自分用のAzure環境の構築が可能
- 事前に個人専用のクラウド環境での動作確認が可能なため、チーム共有の開発環境へのデプロイ時にクラウド特有のエラーが少なくなる
- クラウドサービス検証のための構築作業を大幅に軽減し、気軽に検証を進めることができる
- オンボーディング作業が軽減されます
azdはWeb App for Containersへのデプロイをサポートしていないため、イベントフックと独自のカスタムスクリプトをワークフローに仕込むことで対応しました。もしazdがネイティブにサポートされていなくても、このイベントフックを使いこなすことで大抵の環境は対応できると思います。
AppServiceの上にコンテナを載せるというアプローチは多くの方がとっているはずですが、それがサポートされていないとなると、まだまだ機能が潤沢ではない印象です。
2023年5月にGAにリリースされたため、言語やAzureサービスの制約が厳しいですが、これからサポートされることを願います。
最近、Azure Developer CLIはAzure Deployment Environmentsにサポートしたようで、今後はそれを触っていこうと思っています。