Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

removed subscription_id from azure_keyvault_secret lookup when using az cli auth #1175

Merged
merged 5 commits into from
Aug 22, 2023
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 30 additions & 28 deletions plugins/lookup/azure_keyvault_secret.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2022 Hai Cao, <[email protected]>
# Copyright (c) 2022 Hai Cao, <[email protected]>, Marcin Slowikowski (@msl0)
#
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

Expand All @@ -10,6 +10,7 @@
name: azure_keyvault_secret
author:
- Hai Cao (@tk5eq) <[email protected]>
- Marcin Slowikowski (@msl0)
version_added: '1.12.0'
requirements:
- requests
Expand All @@ -32,21 +33,22 @@
description: Secret of the service principal.
tenant_id:
description: Tenant id of service principal.
subscription_id:
description: Your Azure subscription Id.
notes:
- If version is not provided, this plugin will return the latest version of the secret.
- If ansible is running on Azure Virtual Machine with MSI enabled, client_id, secret and tenant isn't required.
- For enabling MSI on Azure VM, please refer to this doc https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/
- After enabling MSI on Azure VM, remember to grant access of the Key Vault to the VM by adding a new Acess Policy in Azure Portal.
- If MSI is not enabled on ansible host, it's required to provide a valid service principal which has access to the key vault.
- To authenticate via service principal, pass client_id, secret and tenant_id or set environment variables AZURE_CLIENT_ID, AZURE_CLIENT_SECRET and AZURE_TENANT_ID.
msl0 marked this conversation as resolved.
Show resolved Hide resolved
msl0 marked this conversation as resolved.
Show resolved Hide resolved
- Authentication via C(az login) is also supported.
- To use a plugin from a collection, please reference the full namespace, collection name, and lookup plugin name that you want to use.
"""

EXAMPLE = """
- name: Look up secret when azure cli login
debug:
msg: msg: "{{ lookup('azure.azcollection.azure_keyvault_secret', 'testsecret', vault_url=key_vault_uri, subscription_id=subscription_id)}}"
msg: msg: "{{ lookup('azure.azcollection.azure_keyvault_secret', 'testsecret', vault_url=key_vault_uri)}}"

- name: Look up secret when ansible host is MSI enabled Azure VM
debug:
msg: "the value of this secret is {{
Expand Down Expand Up @@ -108,23 +110,29 @@
_raw:
description: secret content string
"""
from ansible.errors import AnsibleError, AnsibleParserError

from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase
from ansible.utils.display import Display
try:
import requests
from azure.keyvault.secrets import SecretClient
import logging
import os
from azure.common.credentials import get_cli_profile
from azure.identity._credentials.client_secret import ClientSecretCredential
from azure.common.exceptions import ClientRequestError
from msrest.exceptions import ClientRequestError
from azure.keyvault.models import KeyVaultErrorException
msl0 marked this conversation as resolved.
Show resolved Hide resolved
from azure.identity import DefaultAzureCredential, ClientSecretCredential
from azure.keyvault.secrets import SecretClient

except ImportError:
pass

display = Display()

TOKEN_ACQUIRED = False

logger = logging.getLogger("azure.identity").setLevel(logging.ERROR)

token_params = {
'api-version': '2018-02-01',
'resource': 'https://vault.azure.net'
Expand Down Expand Up @@ -155,30 +163,24 @@ def lookup_secret_non_msi(terms, vault_url, kwargs):
logging.getLogger('msrestazure.azure_active_directory').addHandler(logging.NullHandler())
logging.getLogger('msrest.service_client').addHandler(logging.NullHandler())

client_id = kwargs['client_id'] if kwargs.get('client_id') else os.environ.get('AZURE_CLIENT_ID')
secret = kwargs['secret'] if kwargs.get('secret') else os.environ.get('AZURE_SECRET')
tenant_id = kwargs['tenant_id'] if kwargs.get('tenant_id') else os.environ.get('AZURE_TENANT')
subscription_id = kwargs['subscription_id'] if kwargs.get('subscription_id') else os.environ.get('AZURE_SUBSCRIPTION_ID')

try:
if client_id is not None and secret is not None and tenant_id is not None:
credentials = ClientSecretCredential(
client_id=client_id,
client_secret=secret,
tenant_id=tenant_id
)
elif subscription_id is not None:
profile = get_cli_profile()
credentials, subscription_id, tenant = profile.get_login_credentials(
subscription_id=subscription_id, resource="https://vault.azure.net")
client = SecretClient(vault_url=vault_url, credential=credentials)
except Exception as ec:
raise AnsibleError('Invalid credentials provided. excption as {0}'.format(ec))
client_id = kwargs['client_id'] if kwargs.get('client_id') else None
secret = kwargs['secret'] if kwargs.get('secret') else None
tenant_id = kwargs['tenant_id'] if kwargs.get('tenant_id') else None

if all(v is not None for v in [client_id, secret, tenant_id]):
credential = ClientSecretCredential(
tenant_id=tenant_id,
client_id=client_id,
client_secret=secret,
)
else:
credential = DefaultAzureCredential()
client = SecretClient(vault_url, credential)

ret = []
for term in terms:
try:
secret_val = client.get_secret(term, '').value
secret_val = client.get_secret(term).value
ret.append(secret_val)
except Exception:
raise AnsibleError('Failed to fetch secret ' + term + '.')
Expand Down