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

Keyvault Lookup Plugin Added #109

Merged
merged 37 commits into from
Apr 14, 2022
Merged
Changes from 22 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
e957801
Keyvault Lookup Plugin Added
May 12, 2020
c88e05e
Merge branch 'dev' into feature/keyvault-lookup
taasest8 May 15, 2020
fe0974d
Merge branch 'dev' into feature/keyvault-lookup
taasest8 May 20, 2020
3143945
Merge branch 'dev' into feature/keyvault-lookup
taasest8 Jun 19, 2020
c106dcf
Merge branch 'dev' into feature/keyvault-lookup
taasest8 Jun 24, 2020
6a84718
Merge branch 'dev' into feature/keyvault-lookup
taasest8 Jul 3, 2020
3e4f26e
Merge branch 'dev' into feature/keyvault-lookup
taasest8 Jul 18, 2020
aeef7a2
Keyvault Lookup Plugin Added
May 12, 2020
bea6af3
Merge branch 'feature/keyvault-lookup' of https://github.com/taasest8…
Jul 27, 2020
b77cf9d
Merge branch 'dev' into feature/keyvault-lookup
taasest8 Aug 9, 2020
c1ed9c5
Merge branch 'feature/keyvault-lookup' of https://github.com/taasest8…
Aug 25, 2020
3adbab7
Merge branch 'dev' into feature/keyvault-lookup
taasest8 Aug 31, 2020
cfa197e
Merge branch 'dev' into feature/keyvault-lookup
taasest8 Oct 10, 2020
e076957
Merge branch 'dev' into feature/keyvault-lookup
Fred-sun Nov 6, 2020
473f79f
Merge branch 'dev' into feature/keyvault-lookup
Fred-sun Nov 6, 2020
7aa4d1c
Merge branch 'dev' into feature/keyvault-lookup
taasest8 Jan 5, 2021
aec4c73
Merge branch 'dev' into feature/keyvault-lookup
Fred-sun Mar 23, 2021
51bdf17
Merge branch 'dev' into feature/keyvault-lookup
Fred-sun Apr 6, 2021
84874ec
Merge branch 'dev' into feature/keyvault-lookup
Fred-sun May 31, 2021
5565000
Merge branch 'dev' into feature/keyvault-lookup
Fred-sun Jun 8, 2021
4e8ec73
Merge branch 'dev' into feature/keyvault-lookup
Fred-sun Jun 30, 2021
989d69e
Merge branch 'dev' into feature/keyvault-lookup
Fred-sun Jul 1, 2021
d1c99f2
Apply suggestions from code review
taasest8 Apr 1, 2022
b9382f4
Update plugins/lookup/azure_keyvault_secret.py
taasest8 Apr 1, 2022
62b297d
linting
Apr 4, 2022
b8ac615
Update plugins/lookup/azure_keyvault_secret.py
taasest8 Apr 6, 2022
90f34be
Update plugins/lookup/azure_keyvault_secret.py
taasest8 Apr 6, 2022
0fe16cd
Update plugins/lookup/azure_keyvault_secret.py
taasest8 Apr 7, 2022
a5dce0f
Update plugins/lookup/azure_keyvault_secret.py
taasest8 Apr 7, 2022
e5f5bc3
Update plugins/lookup/azure_keyvault_secret.py
taasest8 Apr 7, 2022
36804d1
Update plugins/lookup/azure_keyvault_secret.py
taasest8 Apr 7, 2022
fee5bdb
Update plugins/lookup/azure_keyvault_secret.py
taasest8 Apr 7, 2022
1f3eb52
Update azure_keyvault_secret.py
taasest8 Apr 7, 2022
15dd49b
Update plugins/lookup/azure_keyvault_secret.py
taasest8 Apr 7, 2022
023297c
Update plugins/lookup/azure_keyvault_secret.py
taasest8 Apr 7, 2022
9f1b6ad
Update plugins/lookup/azure_keyvault_secret.py
taasest8 Apr 7, 2022
808203e
fix doc error
xuzhang3 Apr 14, 2022
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
178 changes: 178 additions & 0 deletions plugins/lookup/azure_keyvault_secret.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

DOCUMENTATION = """
lookup: azure_keyvault_secret
author:
- Hai Cao <t-haicao@microsoft.com>
version_added: 2.7
taasest8 marked this conversation as resolved.
Show resolved Hide resolved
requirements:
- requests
- azure
- msrest
short_description: Read secret from Azure Key Vault.
description:
- This lookup returns the content of secret saved in Azure Key Vault.
- When ansible host is MSI enabled Azure VM, user don't need provide any credential to access to Azure Key Vault.
options:
_terms:
description: Secret name, version can be included like secret_name/secret_version.
required: True
vault_url:
description: Url of Azure Key Vault.
required: True
client_id:
description: Client id of service principal that has access to the Azure Key Vault
secret:
description: Secret of the service principal.
tenant_id:
description: Tenant id of service principal.
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 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 ansible host is MSI enabled Azure VM
debug: msg="the value of this secret is {{lookup('azure.azcollection.azure_keyvault_secret','testSecret/version',vault_url='https://yourvault.vault.azure.net')}}"
taasest8 marked this conversation as resolved.
Show resolved Hide resolved

- name: Look up secret when ansible host is general VM
vars:
url: 'https://yourvault.vault.azure.net'
secretname: 'testSecret/version'
client_id: '123456789'
secret: 'abcdefg'
tenant: 'uvwxyz'
debug: msg="the value of this secret is {{lookup('azure.azcollection.azure_keyvault_secret',secretname,vault_url=url, cliend_id=client_id, secret=secret, tenant_id=tenant)}}"
taasest8 marked this conversation as resolved.
Show resolved Hide resolved

# Example below creates an Azure Virtual Machine with SSH public key from key vault using 'azure_keyvault_secret' lookup plugin.
- name: Create Azure VM
hosts: localhost
connection: local
no_log: True
vars:
resource_group: myResourceGroup
vm_name: testvm
location: eastus
ssh_key: "{{ lookup('azure.azcollection.azure_keyvault_secret','myssh_key') }}"
- name: Create VM
azure_rm_virtualmachine:
resource_group: "{{ resource_group }}"
name: "{{ vm_name }}"
vm_size: Standard_DS1_v2
admin_username: azureuser
ssh_password_enabled: false
ssh_public_keys:
- path: /home/azureuser/.ssh/authorized_keys
key_data: "{{ ssh_key }}"
network_interfaces: "{{ vm_name }}"
image:
offer: UbuntuServer
publisher: Canonical
sku: 16.04-LTS
version: latest
"""

RETURN = """
_raw:
description: secret content string
"""

from ansible.errors import AnsibleError, AnsibleParserError
from ansible.plugins.lookup import LookupBase
from ansible.utils.display import Display
import requests
taasest8 marked this conversation as resolved.
Show resolved Hide resolved

display = Display()

TOKEN_ACQUIRED = False

token_params = {
'api-version': '2018-02-01',
'resource': 'https://vault.azure.net'
}
token_headers = {
'Metadata': 'true'
}
token = None
try:
taasest8 marked this conversation as resolved.
Show resolved Hide resolved
token_res = requests.get('http://169.254.169.254/metadata/identity/oauth2/token', params=token_params, headers=token_headers)
taasest8 marked this conversation as resolved.
Show resolved Hide resolved
if token_res.ok:
token = token_res.json().get("access_token")
if token is not None:
TOKEN_ACQUIRED = True
else:
display.v('Successfully called MSI endpoint, but no token was available. Will use service principal if provided.')
else:
display.v("Unable to query MSI endpoint, Error Code %s. Will use service principal if provided" % token_res.status_code)
except requests.exceptions.RequestException:
taasest8 marked this conversation as resolved.
Show resolved Hide resolved
display.v('Unable to fetch MSI token. Will use service principal if provided.')
TOKEN_ACQUIRED = False


taasest8 marked this conversation as resolved.
Show resolved Hide resolved

def lookup_secret_non_msi(terms, vault_url, kwargs):
import logging
logging.getLogger('msrestazure.azure_active_directory').addHandler(logging.NullHandler())
logging.getLogger('msrest.service_client').addHandler(logging.NullHandler())

try:
from azure.common.credentials import ServicePrincipalCredentials
from azure.keyvault import KeyVaultClient
from msrest.exceptions import AuthenticationError, ClientRequestError
from azure.keyvault.models.key_vault_error import KeyVaultErrorException
except ImportError:
raise AnsibleError('The azure_keyvault_secret lookup plugin requires azure.keyvault and azure.common.credentials to be installed.')

client_id = kwargs.pop('client_id', None)
secret = kwargs.pop('secret', None)
tenant_id = kwargs.pop('tenant_id', None)

try:
credentials = ServicePrincipalCredentials(
client_id=client_id,
secret=secret,
tenant=tenant_id
)
client = KeyVaultClient(credentials)
except AuthenticationError:
raise AnsibleError('Invalid credentials provided.')

ret = []
for term in terms:
try:
secret_val = client.get_secret(vault_url, term, '').value
ret.append(secret_val)
except ClientRequestError:
raise AnsibleError('Error occurred in request')
except KeyVaultErrorException:
raise AnsibleError('Failed to fetch secret ' + term + '.')
return ret


class LookupModule(LookupBase):

def run(self, terms, variables, **kwargs):

ret = []
vault_url = kwargs.pop('vault_url', None)
if vault_url is None:
raise AnsibleError('Failed to get valid vault url.')
if TOKEN_ACQUIRED:
secret_params = {'api-version': '2016-10-01'}
secret_headers = {'Authorization': 'Bearer ' + token}
for term in terms:
try:
secret_res = requests.get(vault_url + '/secrets/' + term, params=secret_params, headers=secret_headers)
ret.append(secret_res.json()["value"])
except requests.exceptions.RequestException:
taasest8 marked this conversation as resolved.
Show resolved Hide resolved
raise AnsibleError('Failed to fetch secret: ' + term + ' via MSI endpoint.')
taasest8 marked this conversation as resolved.
Show resolved Hide resolved
except KeyError:
taasest8 marked this conversation as resolved.
Show resolved Hide resolved
raise AnsibleError('Failed to fetch secret ' + term + '.')
taasest8 marked this conversation as resolved.
Show resolved Hide resolved
return ret
else:
return lookup_secret_non_msi(terms, vault_url, kwargs)