#mynavi(Azureメモ)
#setlinebreak(on);

* 概要 [#gb9ab00c]
#html(<div class="pl10">)
Azure のサービスプリンシパルを作成後、それを使用してログインする手順を記載する。
#html(</div>)


* 目次 [#kc48b057]
#contents
- 関連
-- [[Azureメモ]]
-- [[Azure CLI の操作]]

* パスワードベースのサービスプリンシパルの作成 [#m92c293d]
#html(<div class="pl10">)

サービスプリンシパル作成
#myterm2(){{
az ad sp create-for-rbac --name サービスプリンシパル名

{
  "appId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "displayName": "サービスプリンシパル名",
  "name": "http://サービスプリンシパル名",
  "password": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "tenant": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
}}

ログイン確認
#myterm2(){{
az login --service-principal -u 表示されたname -p 表示されたpassword --tenant 表示されたテナント
}}

#html(</div>)


* 証明書ベースのサービスプリンシパル作成 [#fe799b1e]
#html(<div class="pl10">)

証明書の作成(パスワードなしで作成)
#myterm2(){{
openssl req \
  -newkey rsa:4096 -nodes -sha256 -keyout my_cert.key \
  -x509 -days 365 -out my_cert.crt
}}

# 秘密キーと証明書を1ファイルに纏める
#myterm2(){{
cat my_cert.key >my_cert.pem
cat my_cert.crt >>my_cert.pem
rm -rf my_cert.key && rm -rf my_cert.crt
}}

サービスプリンシパル作成
#myterm2(){{
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"
}
}}

ログイン確認
#myterm2(){{
az login --service-principal -u http://サービスプリンシパル名 -p ./my_cert.pem --tenant テナント表示されたtenant
}}

#html(</div>)

* 必要なロールを割り当てる [#m398f03d]
#html(<div class="pl10">)

サービス プリンシパルの既定のロールは共同作成者になっているので、必要なロールのみを割り当て直しておく必要がある。

[[Azure 組み込みロール>https://docs.microsoft.com/ja-jp/azure/role-based-access-control/built-in-roles]] を使用すれば楽なのだが、これでは操作対象のリソース/サービスが大きくなりすぎてしまう為、
カスタムロールを作成して必要な権限のみを割り当てるのが良いと思われる。

参考
- [[サービス プリンシパル ロールを管理する>https://docs.microsoft.com/ja-jp/cli/azure/create-an-azure-service-principal-azure-cli?view=azure-cli-latest#manage-service-principal-roles]]
- [[Azure 組み込みロール>https://docs.microsoft.com/ja-jp/azure/role-based-access-control/built-in-roles]]
- [[Azure ロールの定義について>https://docs.microsoft.com/ja-jp/azure/role-based-access-control/role-definitions]]
- [[Azure カスタム ロール>https://docs.microsoft.com/ja-jp/azure/role-based-access-control/custom-roles]]
- [[Azure リソース プロバイダーの操作>https://docs.microsoft.com/ja-jp/azure/role-based-access-control/resource-provider-operations]]
- [[チュートリアル:Azure CLI を使用して Azure カスタム ロールを作成する>https://docs.microsoft.com/ja-jp/azure/role-based-access-control/tutorial-custom-role-cli]]

** カスタムロールの作成 [#j91f5cf2]
#html(<div class="pl10">)

*** ロールの定義の作成 [#qa6c9774]
#html(<div class="pl10">)

#html(){{
<div id="tabs1">
  <ul>
    <li><a href="#tabs1-1">関数アプリのデプロイ用</a></li>
    <li><a href="#tabs1-2">App Service のデプロイ</a></li>
  </ul>
}}

// START tabs1-1
#html(<div id="tabs1-1">)

以下は ''az functionapp deployment ...'' 及び ''az functionapp restart ...'' に必要な権限。

MyFuncAppDeploy.json
#mycode2(){{
{
  "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/リソースグループ名"
  ]
}
}}
#html(</div>)
// END tabs1-1

// START tabs1-2
#html(<div id="tabs1-2">)

以下、''az acr build ...'' 及び ''az webapp restart ...'' に必要な権限。

MyAppServiceDeploy.json
#mycode2(){{
{
  "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/リソースグループ名"
  ]
}
}}

#html(</div>)
// END tabs1-2

#html(</div>)
// END tabs1

#html(<script>$(function() { $("#tabs1").tabs(); });</script>)

#html(</div>)

*** ロールの作成 [#u96a01a5]
#html(<div class="pl10">)

#myterm2(){{
az role definition create --role-definition `pwd`/MyFuncAppDeploy.json
az role definition create --role-definition `pwd`/MyAppServiceDeploy.json
}}
#html(</div>)
#html(</div>)

** サービスプリンシパルに作成したロールを割り当てる [#je6147cd]
#html(<div class="pl10">)

#myterm2(){{
# 関数アプリのデプロイ用ロールを割り当て
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/リソースグループ名"
}}

#html(</div>)

** 共同作成者ロールを削除しておく [#efffc5eb]
#html(<div class="pl10">)
#myterm2(){{
az role assignment delete --assignee http://サービスプリンシパル名 --role Contributor
}}
#html(</div>)

#html(</div>)

* 補足 [#k8c4ac2a]
#html(<div class="pl10">)

** カスタムロールに必要な権限の探し方 [#b4201a37]
#html(<div class="pl10">)

Azure CLI のコマンド毎に必要な権限などが記載されたドキュメントは見つける事ができなかった。
なので、今回はロール割当がない状態から、コマンド発行を行ってエラーメセージを見ながら、必要な権限を割り出した。(この作業はかなりツライ)

#html(</div>)

** リソースグループが異なる場合はロール自体を分けて --scope を指定して作成するのが吉 [#y674072a]
#html(<div class="pl10">)

az role assignment create 時に、以下のように怒られるケースがある。
#html(){{
<div style="background: #000; color: #fff; padding: 10px;">
# ロール作成<br />
az role definition create --role-definition `pwd`/MyAppDeploy.json<br />
<br />
# ロール割り当て<br />
az role assignment create --assignee http://サービスプリンシパル名 --role "MyAppDeploy"<br />
<br />
<div style="color: #f00">The role MyAppDeploy is not available for assignment at the requested scope.</div>
</div>
}}

エラーになったのは、ロール定義(json)で、以下のようにリソースグループを指定した場合。
※ az role assignment create の引数で --scope を指定した場合はこのエラーは表示されなかった。
#mycode2(){{
   :
  "AssignableScopes": [
    "/subscriptions/サブスクリプションID/resourceGroups/リソースグループ名"
  ]
}}

挙動を見る限り、「az role assignment create」 コマンドの --scope と異なるものを json ファイル内で指定した場合に起こる模様。
※ 「az role assignment create」 の --scope を省略した場合 「/subscriptions/サブスクリプションID」 となる。

現在(2020/9) は、Linux と Windows のプランを同じリソースグループに配置できない等の不具合もある為、リソースグループを分けないといけないケースも普通にあるので、これは結構面倒。
※ https://feedback.azure.com/forums/169385-web-apps/suggestions/37287583-allow-a-linux-and-windows-app-service-plan-to-exis

#html(</div>)


#html(</div>)

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS