Azure のサービスプリンシパルを作成後、それを使用してログインする手順を記載する。
サービスプリンシパル作成
az ad sp create-for-rbac --name サービスプリンシパル名 { "appId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "displayName": "サービスプリンシパル名", "name": "http://サービスプリンシパル名", "password": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "tenant": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }
ログイン確認
az login --service-principal -u 表示されたname -p 表示されたpassword --tenant 表示されたテナント
証明書の作成(パスワードなしで作成)
openssl req \ -newkey rsa:4096 -nodes -sha256 -keyout my_cert.key \ -x509 -days 365 -out my_cert.crt
# 秘密キーと証明書を1ファイルに纏める
cat my_cert.key >my_cert.pem cat my_cert.crt >>my_cert.pem rm -rf my_cert.key && rm -rf my_cert.crt
サービスプリンシパル作成
az ad sp create-for-rbac --name サービスプリンシパル名 --cert @`pwd`/my_cert.pem { "appId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "displayName": "サービスプリンシパル名", "name": "http://サービスプリンシパル名", "password": null, "tenant": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }
ログイン確認
az login --service-principal -u http://サービスプリンシパル名 -p ./my_cert.pem --tenant テナント表示されたtenant
サービス プリンシパルの既定のロールは共同作成者になっているので、必要なロールのみを割り当て直しておく必要がある。
Azure 組み込みロール を使用すれば楽なのだが、これでは操作対象のリソース/サービスが大きくなりすぎてしまう為、
カスタムロールを作成して必要な権限のみを割り当てるのが良いと思われる。
参考
以下は az functionapp deployment ... 及び az functionapp restart ... に必要な権限。
MyFuncAppDeploy.json
{ "Name": "MyFuncAppDeploy", "IsCustom": true, "Description": "Deploy function apps.", "Actions": [ "Microsoft.Web/sites/read", "Microsoft.Web/serverfarms/read", "Microsoft.Web/sites/config/read", "Microsoft.Web/sites/restart/action", "Microsoft.Web/sites/config/list/action", "Microsoft.Web/sites/publishxml/action" ], "NotActions": [], "DataActions": [], "NotDataActions": [], "AssignableScopes": [ "/subscriptions/サブスクリプションID/resourceGroups/リソースグループ名" ] }
以下、az acr build ... 及び az webapp restart ... に必要な権限。
MyAppServiceDeploy.json
{ "Name": "MyAppServiceDeploy", "IsCustom": true, "Description": "Deploy App Service.", "Actions": [ "Microsoft.ContainerRegistry/registries/read", "Microsoft.ContainerRegistry/registries/listBuildSourceUploadUrl/action", "Microsoft.ContainerRegistry/registries/scheduleRun/action", "Microsoft.ContainerRegistry/registries/runs/listLogSasUrl/action", "Microsoft.Web/sites/read", "Microsoft.Web/sites/restart/action" ], "NotActions": [], "DataActions": [], "NotDataActions": [], "AssignableScopes": [ "/subscriptions/サブスクリプションID/resourceGroups/リソースグループ名" ] }
az role definition create --role-definition `pwd`/MyFuncAppDeploy.json az role definition create --role-definition `pwd`/MyAppServiceDeploy.json
# 関数アプリのデプロイ用ロールを割り当て az role assignment create --assignee http://サービスプリンシパル名 --role "MyFuncAppDeploy" \ --scope "/subscriptions/サブスクリプションID/resourceGroups/リソースグループ名" # App Service のデプロイ用ロールを割り当て az role assignment create --assignee http://サービスプリンシパル名 --role "MyAppServiceDeploy" \ --scope "/subscriptions/サブスクリプションID/resourceGroups/リソースグループ名"
az role assignment delete --assignee http://サービスプリンシパル名 --role Contributor
Azure CLI のコマンド毎に必要な権限などが記載されたドキュメントは見つける事ができなかった。
なので、今回はロール割当がない状態から、コマンド発行を行ってエラーメセージを見ながら、必要な権限を割り出した。(この作業はかなりツライ)
「az role assignment create」 でスコープを指定せずにロールを作成して、AssignableScopes でリソースグループを複数の列挙すると、
サービスプリンシパルへの割当時に 「The role XXXXXXXXXX is not available for assignment at the requested scope.」 と怒られる。
挙動を見る限り、「az role assignment create」 コマンドの --scope と異なるものを json ファイル内で指定した場合に起こる模様。
ヘルプを見る限り 「az role assignment create」 の --scope のデフォルトは 「/subscriptions/サブスクリプションID」 らしいので、
json 側で /subscriptions/サブスクリプションID/resourceGroups/リソースグループ名 を指定してさらに絞り込んでも問題ないように思われるが、これはエラーになる。(2020/9時点)
現在(2020/9) は、Linux と Windows のプランを同じリソースグループに配置できない等の不具合もある為、リソースグループを分けないといけないケースも普通にあるので、これは結構面倒。
※ https://feedback.azure.com/forums/169385-web-apps/suggestions/37287583-allow-a-linux-and-windows-app-service-plan-to-exis