【问题标题】:How can I run a Python script in Azure DevOps with Azure Resource Manager credentials?如何使用 Azure 资源管理器凭据在 Azure DevOps 中运行 Python 脚本?
【发布时间】:2019-04-14 13:17:54
【问题描述】:

我有一个 Python 脚本,我想在 Azure DevOps 管道任务中的 Azure 资源管理器上下文中运行,以便能够访问 Azure 资源(如 Azure CLI 或 Azure PowerShell 任务)。

如何将存储在 Azure DevOps 中的 Azure RM 服务端点凭据作为 ServicePrincipal/Secret 或 OAuth 令牌传递到脚本中?

【问题讨论】:

    标签: python azure-devops azure-resource-manager


    【解决方案1】:

    取决于您所说的 python 脚本,但无论哪种方式,Azure DevOps 都没有对 python sdk(或您的自定义 python 脚本)进行身份验证的本机支持,但是您可以将来自 build\release 变量的凭据传递给您的脚本,或尝试从 Azure Cli 中提取它(我认为它将数据存储在 /home/.azure/ 下的某处。

    【讨论】:

    • 一个很好的提示。谢谢。我正在尝试使用 Azure CLI 任务、Windows 批处理内联脚本 python "$(Build.SourcesDirectory)\anyscript.py" "%USERPROFILE%\.azure\accessTokens.json" 并在 PY 脚本中解析文件。仍在苦苦挣扎,因为管理端点的授权不起作用 - 但这可能是一个不相关的问题。
    • 那是一个不相关的问题:)
    • 奇怪 - 我得到了一个 requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: https://management.azure.com/subscriptions/... 与 CLI 存储的令牌。必须检查范围。
    • 你应该为此提出一个新问题并考虑接受这个作为答案;)
    • 还没有 ;-) accessTokens.json 包含一个 56 位的 accessToken 而不是我需要的 OAuth / Bearer 令牌
    【解决方案2】:

    基于上面4c74356b41 给出的提示,并对Azure CLI 进行了一些剖析,我创建了这个函数,允许从登录的Service Princial 中通过ADAL 提取OAuth 令牌。 Azure DevOps - Azure CLI 任务

    import os
    import json
    import adal
    
    _SERVICE_PRINCIPAL_ID = 'servicePrincipalId'
    _SERVICE_PRINCIPAL_TENANT = 'servicePrincipalTenant'
    _TOKEN_ENTRY_TOKEN_TYPE = 'tokenType'
    _ACCESS_TOKEN = 'accessToken'
    
    def get_config_dir():
        return os.getenv('AZURE_CONFIG_DIR', None) or os.path.expanduser(os.path.join('~', '.azure'))
    
    def getOAuthTokenFromCLI():
        token_file = (os.environ.get('AZURE_ACCESS_TOKEN_FILE', None)
                  or os.path.join(get_config_dir(), 'accessTokens.json'))
    
        with open(token_file) as f:
            tokenEntry = json.load(f)[0] # just assume first entry
    
        tenantID = tokenEntry[_SERVICE_PRINCIPAL_TENANT]
        appId = tokenEntry[_SERVICE_PRINCIPAL_ID]
        appPassword = tokenEntry[_ACCESS_TOKEN]
        authURL = "https://login.windows.net/" + tenantID
        resource = "https://management.azure.com/"
        context = adal.AuthenticationContext(authURL, validate_authority=tenantID, api_version=None)
        token = context.acquire_token_with_client_credentials(resource,appId,appPassword)
        return token[_TOKEN_ENTRY_TOKEN_TYPE] + " " + token[_ACCESS_TOKEN]
    

    【讨论】:

    • 你是如何得到 _ACCESS_TOKEN 的?我可以将 ADAL 与这样的 AAD 应用凭据一起使用来向 azure devops 进行身份验证吗?
    • @AnjanaDyna - 我不确定,但我想在 Azure DevOps 方面没有办法绕过 PAT/个人访问令牌。
    • 您知道如何将新用户添加到 azure devops 中吗?使用 python 客户端库或 REST API?我在这里问了这个问题:stackoverflow.com/questions/56591886/… 但还没有得到任何答案。
    • @AnjanaDyna - 我会使用这个 REST API:docs.microsoft.com/en-us/rest/api/azure/devops/…
    【解决方案3】:

    如果我正确理解该问题,您希望使用 Python Azure CLI 包装类来管理或访问 Azure 资源。而不是使用 shell 或 PowerShell 命令。我遇到了同样的问题并使用以下步骤来解决它。

    import sys
    from azure.identity import ClientSecretCredential    
    tenant_id = sys.argv[1]
    client_id = sys.argv[2]
    client_secret = sys.argv[3]
    
    credentials = ClientSecretCredential(tenant_id, client_id, client_secret)
    
    1. 添加“用户 Python 版本”步骤以将正确版本的 Python 添加到代理的 PATH
    2. 添加“Azure CLI”步骤。这里的目标是安装您的需求并执行脚本。
    3. 在 Azure CLI 步骤中,请务必选中“高级”部分中的“访问脚本中的服务主体详细信息”框。这将允许您将服务主体详细信息作为参数传递到脚本中。
    4. 传入 $tenantId $servicePrincipalId $servicePrincipalKey 变量作为参数。只要选中步骤 3 中的框,这些变量就是管道定义的。您无需执行任何操作来定义它们。
    5. 设置您的 Python 脚本以接受这些值并设置您的 证书。请参阅上面的脚本

    【讨论】:

    • 我今天对此进行了更多试验,并注意到您甚至不需要传递凭据。在 Azure CLI 任务中运行时可以使用 AzureCliCredential 类,它将获取会话详细信息
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-26
    • 1970-01-01
    • 1970-01-01
    • 2021-08-20
    • 2016-04-10
    • 2021-05-15
    相关资源
    最近更新 更多