Создание хранилища ключей Azure с помощью Python

Я пытаюсь создать хранилище ключей с помощью 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()

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
104
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ошибка обычно возникает, если у субъекта-службы недостаточно разрешений или ролей для выполнения операции.

Я попытался воспроизвести то же самое в своей среде и получил следующие результаты:

Я зарегистрировал одно веб-приложение с именем 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, как показано ниже:

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

спасибо, что уделили время моей проблеме. Я все еще застрял на шаге: Перейдите на портал Azure -> Ваша подписка -> Контроль доступа (IAM) -> Добавить назначение ролей -> Участник. На вкладке ролей я искал Contributor во встроенных ролях, но я не вижу этого. Я нашел Key Vault Contributor и Key Vault Secrets Officer. Я попытался назначить обе роли моему субъекту службы, но все еще имею ту же проблему.

Zin Yosrim 16.04.2023 16:19

Вам необходимо назначить роль Contributor субъекту-службе по подписке. Обычно его можно найти в самом начале, как это. Если вы все еще не можете его найти, не могли бы вы включить скриншот ролей, которые у вас есть, и какой экран вы получаете, редактируя свой вопрос?

Sridevi 16.04.2023 17:54

Тем временем я назначил роль, см. редактирование. При запуске вашего кода с моими учетными данными я получаю `Файл "/Users/deniz/Dev/az-storage/venv/lib/python3.9/site-package‌s/azure/core/pipelin‌​e/policies/_authenti‌ ​cation.py", строка 92, в on_request self._token = self._credential.get_token(*self._scopes) AttributeError: объект ServicePrincipalCredentials не имеет атрибута get_token.

Zin Yosrim 16.04.2023 19:35

Эта ошибка зависит от того, какие версии пакетов и модулей вы используете. Если вы используете пакет azure.identity, попробуйте клонировать этот образец GitHub

Sridevi 16.04.2023 20:05

Спасибо за подсказку, все заработало с последним опубликованным вами репо.

Zin Yosrim 16.04.2023 20:31

Другие вопросы по теме