Azure CLI を使用して Azure サービス プリンシパルを操作する
Azure サービスを使用する自動化ツールのアクセス許可は、常に制限されている必要があります。 完全な特権を持つユーザーとしてアプリケーションをサインインさせる代わりに、Azure にはサービス プリンシパルが用意されています。
Azure サービス プリンシパルとは
Azure サービス プリンシパルは、Azure リソースにアクセスするアプリケーション、ホストされるサービス、自動化ツールで使用するために作成される ID です。 サービス プリンシパルに割り当てられているロールは、アクセスを制限します。 これにより、どのリソースにどのレベルでアクセスできるかを制御できるようになります。 セキュリティ上の理由から、自動化ツールにはユーザー ID でのサインインを許可するのではなく、常にサービス プリンシパルを使用することを推奨します。
この記事では、Azure CLI を使用して Azure サービス プリンシパルの作成、情報取得、およびリセットを行うための手順について説明します。
1. サービス プリンシパルを作成する
Azure サービス プリンシパルは、az ad sp create-for-rbac コマンドを使用して作成します。
appId
キーと tenant
キーは az ad sp create-for-rbac
の出力に表示され、サービス プリンシパルの認証で使用されます。 これらの値を記録してください。ただし、az ad sp list を使用していつでも取得できます。
サービス プリンシパルを作成する際に、サービス プリンシパルが使用するサインイン認証の種類を選択します。 Azure サービス プリンシパルで使用できる認証には、パスワードベースの認証と証明書ベースの認証の 2 種類があります。
警告
az ad sp create-for-rbac
コマンドを使用して Azure サービス プリンシパルを作成する場合、出力には、保護する必要がある資格情報が含まれます。 これらの資格情報をコードに含めないようにするか、資格情報をソース管理にチェックインしてください。 別の方法として、資格情報を使用する必要がないように、可能であればマネージド ID を使用することを検討してください。
サービス プリンシパルが侵害されるリスクを軽減するには、より具体的なロールを割り当て、そのスコープをリソースまたはリソース グループに絞り込みます。 詳細については、「ロールの割り当てを追加する手順」を参照してください。
パスワードベースの認証
パスワードベースの認証では、ランダムなパスワードが作成されます。 --name
パラメータ値を指定しない場合は、タイム スタンプを含む名前が作成されます。 この値には既定値がないため、--scopes
を指定する必要があります。 必要に応じて、az role assignment create を使用して後でロールの割り当てを設定できます。
# Create a service principal without a role assignment
az ad sp create-for-rbac --scopes /subscriptions/mySubscriptionID
# Create a service principal for a resource group using a preferred name and role
az ad sp create-for-rbac --name myServicePrincipalName \
--role reader \
--scopes /subscriptions/mySubscriptionID/resourceGroups/myResourceGroupName
変数を使用してサービス プリンシパルを作成することもできます。
let "randomIdentifier=$RANDOM*$RANDOM"
servicePrincipalName="msdocs-sp-$randomIdentifier"
roleName="azureRoleName"
subscriptionID=$(az account show --query id -o tsv)
# Verify the ID of the active subscription
echo "Using subscription ID $subscriptionID"
resourceGroup="myResourceGroupName"
echo "Creating SP for RBAC with name $servicePrincipalName, with role $roleName and in scopes /subscriptions/$subscriptionID/resourceGroups/$resourceGroup"
az ad sp create-for-rbac --name $servicePrincipalName --role $roleName --scopes /subscriptions/$subscriptionID/resourceGroups/$resourceGroup
パスワード認証によるサービス プリンシパルの出力には、password
キーが含まれます。 この値は必ずコピーしてください。 取得することはできません。 パスワードを紛失した場合は、サービス プリンシパルの資格情報をリセットします。
証明書ベースの認証
証明書ベースの認証の場合は、--cert
パラメーターを使用します。 このパラメーターを使用するには、既存の証明書を保持しておく必要があります。 このサービス プリンシパルを使用する任意のツールから、証明書の秘密キーにアクセスできることを確認します。 証明書は、PEM、CER、または DER などの ASCII 形式でなければなりません。 文字列として証明書を渡すか、@path
形式を使用してファイルから証明書を読み込みます。
注意
PEM ファイルを使用する場合は、ファイル内で PRIVATE KEY (秘密キー) に CERTIFICATE (証明書) を追加する必要があります。
az ad sp create-for-rbac --name myServicePrincipalName \
--role roleName \
--scopes /subscriptions/mySubscriptionID/resourceGroups/myResourceGroupName \
--cert "-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----"
az ad sp create-for-rbac --name myServicePrincipalName \
--role roleName \
--scopes /subscriptions/mySubscriptionID/resourceGroups/myResourceGroupName \
--cert @/path/to/cert.pem
--keyvault
パラメーターを追加すると、Azure Key Vault 内の証明書を使用できます。 ここでは、--cert
値は証明書の名前を表します。
az ad sp create-for-rbac --name myServicePrincipalName \
--role roleName \
--scopes /subscriptions/mySubscriptionID/resourceGroups/myResourceGroupName \
--cert certificateName \
--keyvault vaultName
認証用の "自己署名" 証明書を作成するには、--create-cert
パラメーターを使用します
az ad sp create-for-rbac --name myServicePrincipalName \
--role roleName \
--scopes /subscriptions/mySubscriptionID/resourceGroups/myResourceGroupName \
--create-cert
コンソール出力:
Creating a role assignment under the scopes of "/subscriptions/myId"
Please copy C:\myPath\myNewFile.pem to a safe place.
When you run 'az login', provide the file path in the --password parameter
{
"appId": "myAppId",
"displayName": "myDisplayName",
"fileWithCertAndPrivateKey": "C:\\myPath\\myNewFile.pem",
"name": "http://myName",
"password": null,
"tenant": "myTenantId"
}
新しい PEM ファイルの内容:
-----BEGIN PRIVATE KEY-----
myPrivateKeyValue
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
myCertificateValue
-----END CERTIFICATE-----
注意
az ad sp create-for-rbac --create-cert
コマンドはサービス プリンシパルと PEM ファイルを作成します。 PEM ファイルには、正しく書式設定された PRIVATE KEY (秘密キー) と CERTIFICATE (証明書) が含まれます。
--keyvault
パラメーターを追加すると、証明書を Azure Key Vault に格納できます。 --keyvault
を使用する場合は、--cert
パラメータが必要です。
az ad sp create-for-rbac --name myServicePrincipalName \
--role roleName \
--scopes /subscriptions/mySubscriptionID/resourceGroups/myResourceGroupName \
--create-cert \
--cert certificateName \
--keyvault vaultName
証明書を Key Vault に格納しない場合は、出力に fileWithCertAndPrivateKey
キーが含まれています。 このキーの値を見ると、生成された証明書の格納場所がわかります。
証明書は必ず安全な場所にコピーしてください。そうしないと、このサービス プリンシパルでサインインすることができません。
証明書の秘密キーにアクセスできない場合は、サービス プリンシパルの資格情報をリセットします。
Key Vault からの証明書の取得
Key Vault に格納されている証明書の場合、az keyvault secret show を使用して証明書とその秘密キーを取得して、それを PEM ファイルに変換します。 Key Vault では、証明書のシークレットの名前は、証明書の名前と同じです。
az keyvault secret download --file /path/to/cert.pfx --vault-name VaultName --name CertName --encoding base64
openssl pkcs12 -in cert.pfx -passin pass: -out cert.pem -nodes
既存の PKCS12 ファイルを変換する
PKCS#12 ファイルが既にある場合は、OpenSSL を使用して PEM 形式に変換できます。 パスワードがある場合は、passin
引数を変更します。
openssl pkcs12 -in fileName.p12 -clcerts -nodes -out fileName.pem -passin pass:
2. 既存のサービス プリンシパルを取得する
az ad sp list を使用して、テナント内のサービス プリンシパルの一覧を取得できます。 既定では、このコマンドによって、テナントの最初の 100 個のサービス プリンシパルが返されます。 テナントのサービス プリンシパルをすべて取得するには、--all
パラメーターを使用します。 この一覧の取得には時間がかかる場合があるため、次のパラメーターのいずれかを使用して一覧をフィルター処理することをお勧めします。
--display-name
は、指定した名前に一致する "プレフィックス" を持つサービス プリンシパルを要求します。 サービス プリンシパルの表示名は、作成時に--name
パラメーターで設定した値です。 サービス プリンシパルの作成時に--name
を設定していない場合、名前のプレフィックスはazure-cli-
になります。--spn
は、正確に一致するサービス プリンシパル名でフィルター処理します。 サービス プリンシパル名は常にhttps://
で始まります。--name
に使用した値が URI ではない場合、この値はhttps://
とこれに続く表示名となります。--show-mine
は、サインインしているユーザーによって作成されたサービス プリンシパルのみを要求します。--filter
は OData フィルターを使用して、"サーバー側" のフィルター処理を実行します。 この方法は、CLI の--query
パラメーターを使用したクライアント側のフィルター処理よりも推奨されます。 OData フィルターの詳細については、フィルターのための OData 式の構文に関するページをご覧ください。
サービス プリンシパル オブジェクトについて返される情報は、詳細情報です。 サインインに必要な情報のみを取得するには、クエリ文字列 [].{id:appId, tenant:appOwnerTenantId}
を使用します。 たとえば、現在ログインしているユーザーによって作成されたすべてのサービス プリンシパルのサインイン情報を取得するには、次のコマンドを使用します。
az ad sp list --show-mine --query "[].{id:appId, tenant:appOwnerTenantId}"
重要
az ad sp list
または az ad sp show を使用するとユーザーとテナントは取得されますが、認証シークレット "も" 認証方法も取得されません。
Key Vault 内の証明書のシークレットは az keyvault secret show を使用して取得できますが、既定では、それ以外のシークレットは保存されません。
認証方法やシークレットを忘れた場合は、サービス プリンシパルの資格情報をリセットします。
3. サービス プリンシパル ロールを管理する
Azure CLI には、ロールの割り当てを管理するために、次のコマンドが用意されています。
共同作成者ロールには、Azure アカウントに対して読み取りと書き込みを行うための完全なアクセス許可があります。 閲覧者ロールは制限がより厳しく、読み取り専用アクセスが提供されます。 ロールベースのアクセス制御 (RBAC) とロールの詳細については、RBAC の組み込みのロールに関するページをご覧ください。
この例では、閲覧者ロールを追加し、共同作成者ロールを削除します。
az role assignment create --assignee appID \
--role Reader \
--scope /subscriptions/mySubscriptionID/resourceGroups/myResourceGroupName
az role assignment delete --assignee appID \
--role Contributor \
--scope /subscriptions/mySubscriptionID/resourceGroups/myResourceGroupName
ロールを追加しても、以前に割り当てられたアクセス許可は制限され "ません"。 サービス プリンシパルのアクセス許可を制限する場合は、以前に割り当てられていた共同作成者ロールは削除する必要があります。
変更を確認するには、割り当てられているロールの一覧を表示します。
az role assignment list --assignee appID
4. サービス プリンシパルを使用してサインインする
サインインして、新しいサービス プリンシパルの資格情報とアクセス許可をテストします。 サービス プリンシパルでサインインするには、appId
、tenant
、および資格情報が必要です。
パスワードを使用してサービス プリンシパルでサインインするには、次のコマンドを使用します。
az login --service-principal --username appID --password PASSWORD --tenant tenantID
証明書を使用してサインインする場合、その証明書は、ASCII 形式の PEM または DER ファイルとしてローカルで使用できる必要があります。 PEM ファイルを使用する場合は、ファイル内に秘密キーと証明書を共に追加する必要があります。
az login --service-principal --username appID --tenant tenantID --password /path/to/cert
サービス プリンシパルを使用したサインインの詳細については、「Azure CLI を使用してサインインする」を参照してください。
5. サービス プリンシパルを使用してリソースを作成する
次のセクションでは、以下のコマンドを使用して、サービス プリンシパルで Azure Storage のリソースを作成する方法の例を示します。
サービス プリンシパルを使用してサインインするには、サービス プリンシパルを作成したときに応答として返された appID
、tenantID
、password
が必要です。
サービス プリンシパルとしてサインインします。
az login --service-principal --username appID --password PASSWORD --tenant tenantID
同じクイックスタート、チュートリアル、または開発プロジェクトに使用されるすべてのリソースを保持するリソース グループを作成します。
az group create --location westus --name myResourceGroupName
ストレージ アカウントを作成します。
Azure Storage の場合、
<KIND>
パラメーターの有効な値は次のとおりです。- BlobStorage
- BlockBlobStorage
- FileStorage
- ストレージ
- StorageV2
az storage account create --name myStorageAccountName --resource-group myResourceGroupName --kind <KIND> --sku F0 --location westus --yes
Azure ストレージ アカウントの認証のためにコードで使用するリソース キーを取得します。
az storage account keys list --name myStorageAccountName --resource-group myResourceGroupName
6. 資格情報をリセットする
サービス プリンシパルの資格情報をなくした場合は、az ad sp credential reset を使用します。 リセット コマンドでは、az ad sp create-for-rbac
と同じパラメーターを使用します。
az ad sp credential reset --name myServicePrincipal_appID_or_name
7. トラブルシューティング
十分な特権がありません
ご利用のアカウントにサービス プリンシパルを作成するためのアクセス許可がない場合は、az ad sp create-for-rbac
から "この操作を完了するのに十分な特権がありません" というエラー メッセージが返されます。サービス プリンシパルを作成するには、Azure Active Directory 管理者にお問い合わせください。
テナントが無効です
無効なサブスクリプション ID を指定している場合、"要求には、サブスクリプションまたは有効なテナント レベル リソース プロバイダーがありませんでした" というエラー メッセージが表示されます。変数を使用している場合は、Bash echo
コマンドを使用して、参照コマンドに渡される値を確認してください。 az account set を使用してサブスクリプションを変更するか、Azure CLI を使用して Azure サブスクリプションを管理する方法を学習します。
リソース グループが見つかりません
無効なリソース グループ名を指定している場合、"リソース グループ 'name' が見つかりませんでした" というエラー メッセージが表示されます。変数を使用している場合は、Bash echo
コマンドを使用して、サブスクリプション コマンドと参照コマンドの両方に渡される値を確認してください。 az group list を使用して、現在のサブスクリプションのリソース グループを表示するか、Azure CLI を使用して Azure リソース グループを管理する方法を学習します。
アクションを実行するための承認
ロールを割り当てるためのアクセス許可がアカウントにない場合は、アカウントに "'Microsoft.Authorization/roleAssignments/write' のアクションを実行するためのアクセス権限がありません" というエラー メッセージが表示されます。ロールを管理するには、Azure Active Directory 管理者にお問い合わせください。