Я пытаюсь создать хранилище ключей с помощью Python, запустив код из здесь:
import os
import json
from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.keyvault import KeyVaultManagementClient
from azure.mgmt.resource.resources import ResourceManagementClient
from haikunator import Haikunator
haikunator = Haikunator()
WEST_US = "westus"
GROUP_NAME = "azure-sample-group"
KV_NAME = haikunator.haikunate()
# The object ID of the User or Application for access policies. Find this number in the portal
OBJECT_ID = "401e9294-xxxx-xxxx-xxxx-xxxx"
# Manage resources and resource groups - create, update and delete a resource group,
# deploy a solution into a resource group, export an ARM template. Create, read, update
# and delete a resource
#
# This script expects that the following environment vars are set:
#
# AZURE_TENANT_ID: with your Azure Active Directory tenant id or domain
# AZURE_CLIENT_ID: with your Azure Active Directory Application Client ID
# AZURE_CLIENT_SECRET: with your Azure Active Directory Application Secret
# AZURE_SUBSCRIPTION_ID: with your Azure Subscription Id
#
def run_example():
"""Resource Group management example."""
#
# Create the Resource Manager Client with an Application (service principal) token provider
#
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]
credentials = ServicePrincipalCredentials(
client_id=os.environ["AZURE_CLIENT_ID"],
secret=os.environ["AZURE_CLIENT_SECRET"],
tenant=os.environ["AZURE_TENANT_ID"],
)
kv_client = KeyVaultManagementClient(credentials, subscription_id)
resource_client = ResourceManagementClient(credentials, subscription_id)
# You MIGHT need to add KeyVault as a valid provider for these credentials
# If so, this operation has to be done only once for each credentials
resource_client.providers.register("Microsoft.KeyVault")
# Create Resource group
print("\nCreate Resource Group")
resource_group_params = {"location": WEST_US}
print_item(
resource_client.resource_groups.create_or_update(
GROUP_NAME, resource_group_params
)
)
# Create a vault
print("\nCreate a vault")
vault = kv_client.vaults.create_or_update(
GROUP_NAME,
KV_NAME,
{
"location": WEST_US,
"properties": {
"sku": {"name": "standard"},
"tenant_id": os.environ["AZURE_TENANT_ID"],
"access_policies": [
{
"tenant_id": os.environ["AZURE_TENANT_ID"],
"object_id": OBJECT_ID,
"permissions": {"keys": ["all"], "secrets": ["all"]},
}
],
},
},
)
print_item(vault)
# List the Key vaults
print("\nList KeyVault")
for vault in kv_client.vaults.list():
print_item(vault)
# Delete Resource group and everything in it
print("\nDelete Resource Group")
delete_async_operation = resource_client.resource_groups.delete(GROUP_NAME)
delete_async_operation.wait()
print("\nDeleted: {}".format(GROUP_NAME))
def print_item(group):
"""Print an instance."""
print("\tName: {}".format(group.name))
print("\tId: {}".format(group.id))
print("\tLocation: {}".format(group.location))
print("\tTags: {}".format(group.tags))
if __name__ == "__main__":
run_example()
Получив комментарии, я назначил Contributeроль субъекту-службе.
Моя единственная модификация кода заключалась в замене идентификатора объекта идентификатором из моего субъекта-службы (см. изображение ниже):
Я получаю следующую ошибку:
Обновлено: Принят ответ @sridev, потому что я решил проблему, запустив пример кода, ссылка на который была указана в комментариях.
Вот мой рабочий код, основанный на этом репозитории GitHub, при условии, что переменные среды Azure установлены правильно:
import os
from azure.identity import DefaultAzureCredential
from azure.mgmt.keyvault import KeyVaultManagementClient
from azure.mgmt.resource import ResourceManagementClient
def main():
TENANT_ID = os.environ.get("AZURE_TENANT_ID", None)
SUBSCRIPTION_ID = os.environ.get("AZURE_SUBSCRIPTION_ID", None)
GROUP_NAME = "resource_group_name"
VAULT = "vault_name"
LOCATION = "azure_location_eg_westus"
OBJECT_ID = "service_principal_object_id"
# Create client
# Other authentication approaches: https://pypi.org/project/azure-identity/
resource_client = ResourceManagementClient(
credential=DefaultAzureCredential(), subscription_id=SUBSCRIPTION_ID
)
keyvault_client = KeyVaultManagementClient(
credential=DefaultAzureCredential(), subscription_id=SUBSCRIPTION_ID
)
# Create resource group
resource_client.resource_groups.create_or_update(GROUP_NAME, {"location": LOCATION})
# Create vault
vault = keyvault_client.vaults.begin_create_or_update(
GROUP_NAME,
VAULT,
{
"location": LOCATION,
"properties": {
"tenant_id": TENANT_ID,
"sku": {"family": "A", "name": "standard"},
"access_policies": [
{
"tenant_id": TENANT_ID,
"object_id": OBJECT_ID,
"permissions": {
"keys": [
"encrypt",
"decrypt",
"wrapKey",
"unwrapKey",
"sign",
"verify",
"get",
"list",
"create",
"update",
"import",
"delete",
"backup",
"restore",
"recover",
"purge",
],
"secrets": [
"get",
"list",
"set",
"delete",
"backup",
"restore",
"recover",
"purge",
],
},
}
],
"enabled_for_deployment": True,
"enabled_for_disk_encryption": True,
"enabled_for_template_deployment": True,
},
},
).result()
print("Create vault:\n{}".format(vault))
# Get vault
vault = keyvault_client.vaults.get(GROUP_NAME, VAULT)
print("Get vault:\n{}".format(vault))
# Update vault
vault = keyvault_client.vaults.update(
GROUP_NAME, VAULT, {"tags": {"category": "Marketing"}}
)
print("Update vault:\n{}".format(vault))
# Delete vault
keyvault_client.vaults.delete(GROUP_NAME, VAULT)
print("Delete vault.\n")
# Purge a deleted vault
keyvault_client.vaults.begin_purge_deleted(VAULT, LOCATION).result()
print("Purge a deleted vault.\n")
# Delete Group
resource_client.resource_groups.begin_delete(GROUP_NAME).result()
if __name__ == "__main__":
main()






Ошибка обычно возникает, если у субъекта-службы недостаточно разрешений или ролей для выполнения операции.
Я попытался воспроизвести то же самое в своей среде и получил следующие результаты:
Я зарегистрировал одно веб-приложение с именем SriApp в своем арендаторе Azure AD, как показано ниже:

Когда я запустил приведенный ниже код без назначения какой-либо роли RBAC указанному выше принципалу службы, я получил ту же ошибку, что и ниже:
import os
import json
from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.keyvault import KeyVaultManagementClient
from azure.mgmt.resource.resources import ResourceManagementClient
from haikunator import Haikunator
haikunator = Haikunator()
WEST_US = 'Germany West Central'
GROUP_NAME = 'azure-sample-resources'
KV_NAME = haikunator.haikunate()
# The object ID of the User or Application for access policies. Find this number in the portal
OBJECT_ID = 'bfc7171d-8c25-4b41-9764-xxxxxxxxxxx'
def run_example():
"""Resource Group management example."""
#
# Create the Resource Manager Client with an Application (service principal) token provider
#
subscription_id = '124c97c3-58a7-4eb5-ac50-xxxxxxxxxx'
credentials = ServicePrincipalCredentials(
client_id='794cb163-ca1c-4fec-b7df-xxxxxxxxxxxx',
secret='xxxxxxxxxxxxxxxxxxxxxx',
tenant='6c3f1c39-b84c-4188-b49f-xxxxxxxxx'
)
kv_client = KeyVaultManagementClient(credentials, subscription_id)
resource_client = ResourceManagementClient(credentials, subscription_id)
# You MIGHT need to add KeyVault as a valid provider for these credentials
# If so, this operation has to be done only once for each credentials
resource_client.providers.register('Microsoft.KeyVault')
# Create Resource group
print('\nCreate Resource Group')
resource_group_params = {'location': WEST_US}
print_item(resource_client.resource_groups.create_or_update(
GROUP_NAME, resource_group_params))
# Create a vault
print('\nCreate a vault')
vault = kv_client.vaults.create_or_update(
GROUP_NAME,
KV_NAME,
{
'location': WEST_US,
'properties': {
'sku': {
'name': 'standard'
},
'tenant_id': '6c3f1c39-b84c-4188-b49f-xxxxxxxxx',
'access_policies': [{
'tenant_id': '6c3f1c39-b84c-4188-b49f-xxxxxxxx',
'object_id': OBJECT_ID,
'permissions': {
'keys': ['all'],
'secrets': ['all']
}
}]
}
}
)
print_item(vault)
# List the Key vaults
print('\nList KeyVault')
for vault in kv_client.vaults.list():
print_item(vault)
# Delete Resource group and everything in it
# print('\nDelete Resource Group')
# delete_async_operation = resource_client.resource_groups.delete(GROUP_NAME)
# delete_async_operation.wait()
# print("\nDeleted: {}".format(GROUP_NAME))
def print_item(group):
"""Print an instance."""
print("\tName: {}".format(group.name))
print("\tId: {}".format(group.id))
print("\tLocation: {}".format(group.location))
print("\tTags: {}".format(group.tags))
if __name__ == "__main__":
run_example()
Ответ

Чтобы устранить эту ошибку, вам необходимо назначить роль Contributor субъекту-службе в вашей подписке, как показано ниже:
Перейдите на портал Azure -> Ваша подписка -> Контроль доступа (IAM) -> Добавить назначение ролей -> Участник.

После назначения роли я снова запустил код и успешно получил ответ, как показано ниже:
import os
import json
from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.keyvault import KeyVaultManagementClient
from azure.mgmt.resource.resources import ResourceManagementClient
from haikunator import Haikunator
haikunator = Haikunator()
WEST_US = 'Germany West Central'
GROUP_NAME = 'azure-sample-resources'
KV_NAME = haikunator.haikunate()
# The object ID of the User or Application for access policies. Find this number in the portal
OBJECT_ID = 'bfc7171d-8c25-4b41-9764-xxxxxxxxxxx'
def run_example():
"""Resource Group management example."""
#
# Create the Resource Manager Client with an Application (service principal) token provider
#
subscription_id = '124c97c3-58a7-4eb5-ac50-xxxxxxxxxx'
credentials = ServicePrincipalCredentials(
client_id='794cb163-ca1c-4fec-b7df-xxxxxxxxxxxx',
secret='xxxxxxxxxxxxxxxxxxxxxx',
tenant='6c3f1c39-b84c-4188-b49f-xxxxxxxxx'
)
kv_client = KeyVaultManagementClient(credentials, subscription_id)
resource_client = ResourceManagementClient(credentials, subscription_id)
# You MIGHT need to add KeyVault as a valid provider for these credentials
# If so, this operation has to be done only once for each credentials
resource_client.providers.register('Microsoft.KeyVault')
# Create Resource group
print('\nCreate Resource Group')
resource_group_params = {'location': WEST_US}
print_item(resource_client.resource_groups.create_or_update(
GROUP_NAME, resource_group_params))
# Create a vault
print('\nCreate a vault')
vault = kv_client.vaults.create_or_update(
GROUP_NAME,
KV_NAME,
{
'location': WEST_US,
'properties': {
'sku': {
'name': 'standard'
},
'tenant_id': '6c3f1c39-b84c-4188-b49f-xxxxxxxxx',
'access_policies': [{
'tenant_id': '6c3f1c39-b84c-4188-b49f-xxxxxxxx',
'object_id': OBJECT_ID,
'permissions': {
'keys': ['all'],
'secrets': ['all']
}
}]
}
}
)
print_item(vault)
# List the Key vaults
print('\nList KeyVault')
for vault in kv_client.vaults.list():
print_item(vault)
# Delete Resource group and everything in it
# print('\nDelete Resource Group')
# delete_async_operation = resource_client.resource_groups.delete(GROUP_NAME)
# delete_async_operation.wait()
# print("\nDeleted: {}".format(GROUP_NAME))
def print_item(group):
"""Print an instance."""
print("\tName: {}".format(group.name))
print("\tId: {}".format(group.id))
print("\tLocation: {}".format(group.location))
print("\tTags: {}".format(group.tags))
if __name__ == "__main__":
run_example()
Ответ:

Чтобы подтвердить это, я проверил то же самое на портале, где хранилище ключей успешно создано в новой группе ресурсов с расположением как Germany West Central, как показано ниже:

Когда я проверил политики доступа к этому хранилищу ключей, к нему было добавлено приложение с разрешениями, как показано ниже:

Вам необходимо назначить роль Contributor субъекту-службе по подписке. Обычно его можно найти в самом начале, как это. Если вы все еще не можете его найти, не могли бы вы включить скриншот ролей, которые у вас есть, и какой экран вы получаете, редактируя свой вопрос?
Тем временем я назначил роль, см. редактирование. При запуске вашего кода с моими учетными данными я получаю `Файл "/Users/deniz/Dev/az-storage/venv/lib/python3.9/site-packages/azure/core/pipeline/policies/_authenti cation.py", строка 92, в on_request self._token = self._credential.get_token(*self._scopes) AttributeError: объект ServicePrincipalCredentials не имеет атрибута get_token.
Эта ошибка зависит от того, какие версии пакетов и модулей вы используете. Если вы используете пакет azure.identity, попробуйте клонировать этот образец GitHub
Спасибо за подсказку, все заработало с последним опубликованным вами репо.
спасибо, что уделили время моей проблеме. Я все еще застрял на шаге: Перейдите на портал Azure -> Ваша подписка -> Контроль доступа (IAM) -> Добавить назначение ролей -> Участник. На вкладке ролей я искал
Contributorво встроенных ролях, но я не вижу этого. Я нашелKey Vault ContributorиKey Vault Secrets Officer. Я попытался назначить обе роли моему субъекту службы, но все еще имею ту же проблему.