Support MSI for ansible on Azure resources (#36634)

* msi

* add env and param

* add msi in default

* add azure_rm

* add document

* subscription param

* if not enabled msi

* remove the msi in default mode since the infinite loop will block if not enabled msi

* lint

* lint

* Update azure_rm_common.py

* fix

* catch exc and make error message more friendly

* lint

* Minor docs changes to the msi source option
This commit is contained in:
Yuwei Zhou 2018-03-22 04:01:44 +08:00 committed by Jordan Borean
parent 05220d693d
commit 8c819dd9cb
2 changed files with 29 additions and 1 deletions

View file

@ -23,7 +23,7 @@ except ImportError:
AZURE_COMMON_ARGS = dict(
auth_source=dict(
type='str',
choices=['auto', 'cli', 'env', 'credential_file']
choices=['auto', 'cli', 'env', 'credential_file', 'msi']
),
profile=dict(type='str'),
subscription_id=dict(type='str', no_log=True),
@ -127,6 +127,7 @@ except ImportError as exc:
try:
from enum import Enum
from msrestazure.azure_exceptions import CloudError
from msrestazure.azure_active_directory import MSIAuthentication
from msrestazure.tools import resource_id, is_valid_resource_id
from msrestazure import azure_cloud
from azure.common.credentials import ServicePrincipalCredentials, UserPassCredentials
@ -138,6 +139,7 @@ try:
from azure.mgmt.web.version import VERSION as web_client_version
from azure.mgmt.network import NetworkManagementClient
from azure.mgmt.resource.resources import ResourceManagementClient
from azure.mgmt.resource.subscriptions import SubscriptionClient
from azure.mgmt.storage import StorageManagementClient
from azure.mgmt.compute import ComputeManagementClient
from azure.mgmt.dns import DnsManagementClient
@ -489,6 +491,23 @@ class AzureRMModuleBase(object):
return None
def _get_msi_credentials(self, subscription_id_param=None):
credentials = MSIAuthentication()
subscription_id = subscription_id_param or os.environ.get(AZURE_CREDENTIAL_ENV_MAPPING['subscription_id'], None)
if not subscription_id:
try:
# use the first subscription of the MSI
subscription_client = SubscriptionClient(credentials)
subscription = next(subscription_client.subscriptions.list())
subscription_id = str(subscription.subscription_id)
except Exception as exc:
self.fail("Failed to get MSI token: {0}. "
"Please check whether your machine enabled MSI or grant access to any subscription.".format(str(exc)))
return {
'credentials': credentials,
'subscription_id': subscription_id
}
def _get_azure_cli_credentials(self):
credentials, subscription_id = get_azure_cli_credentials()
cloud_environment = get_cli_active_cloud()
@ -526,6 +545,10 @@ class AzureRMModuleBase(object):
if not auth_source:
auth_source = os.environ.get('ANSIBLE_AZURE_AUTH_SOURCE', 'auto')
if auth_source == 'msi':
self.log('Retrieving credenitals from MSI')
return self._get_msi_credentials(arg_credentials['subscription_id'])
if auth_source == 'cli':
if not HAS_AZURE_CLI_CORE:
self.fail("Azure auth_source is `cli`, but azure-cli package is not available. Try `pip install azure-cli --upgrade`")

View file

@ -68,11 +68,16 @@ options:
C(~/.azure/credentials).
- When set to C(cli), the credentials will be sources from the default Azure CLI profile.
- Can also be set via the C(ANSIBLE_AZURE_AUTH_SOURCE) environment variable.
- When set to C(msi), the host machine must be an azure resource with an enabled MSI extension. C(subscription_id) or the
environment variable C(AZURE_SUBSCRIPTION_ID) can be used to identify the subscription ID if the resource is granted
access to more than one subscription, otherwise the first subscription is chosen.
- The C(msi) was added in Ansible 2.6.
choices:
- auto
- cli
- credential_file
- env
- msi
default: auto
version_added: 2.5
api_profile: