2015-12-05 00:06:27 +01:00
#!/usr/bin/python
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
DOCUMENTATION = '''
- - -
module : azure_deployment
short_description : Create or destroy Azure Resource Manager template deployments
2016-03-14 18:52:45 +01:00
version_added : " 2.1 "
2015-12-05 00:06:27 +01:00
description :
- Create or destroy Azure Resource Manager template deployments via the Azure SDK for Python .
2016-03-14 18:20:36 +01:00
You can find some quick start templates in GitHub here https : / / github . com / azure / azure - quickstart - templates .
If you would like to find out more information about Azure Resource Manager templates , see https : / / azure . microsoft . com / en - us / documentation / articles / resource - group - template - deploy / .
2015-12-05 00:06:27 +01:00
options :
subscription_id :
description :
- The Azure subscription to deploy the template into .
required : true
resource_group_name :
description :
- The resource group name to use or create to host the deployed template
required : true
state :
description :
- If state is " present " , template will be created . If state is " present " and if deployment exists , it will be updated .
If state is " absent " , stack will be removed .
required : true
template :
description :
- A hash containg the templates inline . This parameter is mutually exclusive with ' template_link ' .
Either one of them is required if " state " parameter is " present " .
required : false
default : None
template_link :
description :
- Uri of file containing the template body . This parameter is mutually exclusive with ' template ' . Either one
of them is required if " state " parameter is " present " .
required : false
default : None
parameters :
description :
- A hash of all the required template variables for the deployment template . This parameter is mutually exclusive with ' parameters_link ' .
Either one of them is required if " state " parameter is " present " .
required : false
default : None
parameters_link :
description :
- Uri of file containing the parameters body . This parameter is mutually exclusive with ' parameters ' . Either
one of them is required if " state " parameter is " present " .
required : false
default : None
location :
description :
- The geo - locations in which the resource group will be located .
require : false
default : West US
2016-03-14 18:20:36 +01:00
author : " David Justice (@devigned) / Laurent Mazuel (@lmazuel) / Andre Price (@obsoleted) "
2015-12-05 00:06:27 +01:00
'''
EXAMPLES = '''
# Destroy a template deployment
- name : Destroy Azure Deploy
azure_deploy :
state : absent
subscription_id : xxxxxxxx - xxxx - xxxx - xxxx - xxxxxxxxxxxx
resource_group_name : dev - ops - cle
# Create or update a template deployment based on uris to paramters and a template
- name : Create Azure Deploy
azure_deploy :
state : present
subscription_id : xxxxxxxx - xxxx - xxxx - xxxx - xxxxxxxxxxxx
resource_group_name : dev - ops - cle
parameters_link : ' https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-simple-linux-vm/azuredeploy.parameters.json '
template_link : ' https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-simple-linux-vm/azuredeploy.json '
# Create or update a template deployment based on a uri to the template and parameters specified inline.
# This deploys a VM with SSH support for a given public key, then stores the result in 'azure_vms'. The result is then used
# to create a new host group. This host group is then used to wait for each instance to respond to the public IP SSH.
- - -
- hosts : localhost
tasks :
- name : Destroy Azure Deploy
azure_deployment :
state : absent
subscription_id : xxxxxxxx - xxxx - xxxx - xxxx - xxxxxxxxxxxx
resource_group_name : dev - ops - cle
- name : Create Azure Deploy
azure_deployment :
state : present
subscription_id : xxxxxxxx - xxxx - xxxx - xxxx - xxxxxxxxxxxx
resource_group_name : dev - ops - cle
parameters :
newStorageAccountName :
value : devopsclestorage1
adminUsername :
value : devopscle
dnsNameForPublicIP :
value : devopscleazure
location :
value : West US
vmSize :
value : Standard_A2
vmName :
value : ansibleSshVm
sshKeyData :
value : YOUR_SSH_PUBLIC_KEY
template_link : ' https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-vm-sshkey/azuredeploy.json '
register : azure
- name : Add new instance to host group
add_host : hostname = { { item [ ' ips ' ] [ 0 ] . public_ip } } groupname = azure_vms
with_items : azure . instances
- hosts : azure_vms
user : devopscle
tasks :
- name : Wait for SSH to come up
wait_for : port = 22 timeout = 2000 state = started
- name : echo the hostname of the vm
shell : hostname
# Deploy an Azure WebApp running a hello world'ish node app
- name : Create Azure WebApp Deployment at http : / / devopscleweb . azurewebsites . net / hello . js
azure_deployment :
state : present
subscription_id : cbbdaed0 - fea9 - 4693 - bf0c - d446ac93c030
resource_group_name : dev - ops - cle - webapp
parameters :
repoURL :
value : ' https://github.com/devigned/az-roadshow-oss.git '
siteName :
value : devopscleweb
hostingPlanName :
value : someplan
siteLocation :
value : westus
sku :
value : Standard
template_link : ' https://raw.githubusercontent.com/azure/azure-quickstart-templates/master/201-web-app-github-deploy/azuredeploy.json '
# Create or update a template deployment based on an inline template and parameters
- name : Create Azure Deploy
azure_deploy :
state : present
subscription_id : xxxxxxxx - xxxx - xxxx - xxxx - xxxxxxxxxxxx
resource_group_name : dev - ops - cle
template :
$ schema : " https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json# "
contentVersion : " 1.0.0.0 "
parameters :
newStorageAccountName :
type : " string "
metadata :
description : " Unique DNS Name for the Storage Account where the Virtual Machine ' s disks will be placed. "
adminUsername :
type : " string "
metadata :
description : " User name for the Virtual Machine. "
adminPassword :
type : " securestring "
metadata :
description : " Password for the Virtual Machine. "
dnsNameForPublicIP :
type : " string "
metadata :
description : " Unique DNS Name for the Public IP used to access the Virtual Machine. "
ubuntuOSVersion :
type : " string "
defaultValue : " 14.04.2-LTS "
allowedValues :
- " 12.04.5-LTS "
- " 14.04.2-LTS "
- " 15.04 "
metadata :
description : " The Ubuntu version for the VM. This will pick a fully patched image of this given Ubuntu version. Allowed values: 12.04.5-LTS, 14.04.2-LTS, 15.04. "
variables :
location : " West US "
imagePublisher : " Canonical "
imageOffer : " UbuntuServer "
OSDiskName : " osdiskforlinuxsimple "
nicName : " myVMNic "
addressPrefix : " 10.0.0.0/16 "
subnetName : " Subnet "
subnetPrefix : " 10.0.0.0/24 "
storageAccountType : " Standard_LRS "
publicIPAddressName : " myPublicIP "
publicIPAddressType : " Dynamic "
vmStorageAccountContainerName : " vhds "
vmName : " MyUbuntuVM "
vmSize : " Standard_D1 "
virtualNetworkName : " MyVNET "
vnetID : " [resourceId( ' Microsoft.Network/virtualNetworks ' ,variables( ' virtualNetworkName ' ))] "
subnetRef : " [concat(variables( ' vnetID ' ), ' /subnets/ ' ,variables( ' subnetName ' ))] "
resources :
-
type : " Microsoft.Storage/storageAccounts "
name : " [parameters( ' newStorageAccountName ' )] "
apiVersion : " 2015-05-01-preview "
location : " [variables( ' location ' )] "
properties :
accountType : " [variables( ' storageAccountType ' )] "
-
apiVersion : " 2015-05-01-preview "
type : " Microsoft.Network/publicIPAddresses "
name : " [variables( ' publicIPAddressName ' )] "
location : " [variables( ' location ' )] "
properties :
publicIPAllocationMethod : " [variables( ' publicIPAddressType ' )] "
dnsSettings :
domainNameLabel : " [parameters( ' dnsNameForPublicIP ' )] "
-
type : " Microsoft.Network/virtualNetworks "
apiVersion : " 2015-05-01-preview "
name : " [variables( ' virtualNetworkName ' )] "
location : " [variables( ' location ' )] "
properties :
addressSpace :
addressPrefixes :
- " [variables( ' addressPrefix ' )] "
subnets :
-
name : " [variables( ' subnetName ' )] "
properties :
addressPrefix : " [variables( ' subnetPrefix ' )] "
-
type : " Microsoft.Network/networkInterfaces "
apiVersion : " 2015-05-01-preview "
name : " [variables( ' nicName ' )] "
location : " [variables( ' location ' )] "
dependsOn :
- " [concat( ' Microsoft.Network/publicIPAddresses/ ' , variables( ' publicIPAddressName ' ))] "
- " [concat( ' Microsoft.Network/virtualNetworks/ ' , variables( ' virtualNetworkName ' ))] "
properties :
ipConfigurations :
-
name : " ipconfig1 "
properties :
privateIPAllocationMethod : " Dynamic "
publicIPAddress :
id : " [resourceId( ' Microsoft.Network/publicIPAddresses ' ,variables( ' publicIPAddressName ' ))] "
subnet :
id : " [variables( ' subnetRef ' )] "
-
type : " Microsoft.Compute/virtualMachines "
apiVersion : " 2015-06-15 "
name : " [variables( ' vmName ' )] "
location : " [variables( ' location ' )] "
dependsOn :
- " [concat( ' Microsoft.Storage/storageAccounts/ ' , parameters( ' newStorageAccountName ' ))] "
- " [concat( ' Microsoft.Network/networkInterfaces/ ' , variables( ' nicName ' ))] "
properties :
hardwareProfile :
vmSize : " [variables( ' vmSize ' )] "
osProfile :
computername : " [variables( ' vmName ' )] "
adminUsername : " [parameters( ' adminUsername ' )] "
adminPassword : " [parameters( ' adminPassword ' )] "
storageProfile :
imageReference :
publisher : " [variables( ' imagePublisher ' )] "
offer : " [variables( ' imageOffer ' )] "
sku : " [parameters( ' ubuntuOSVersion ' )] "
version : " latest "
osDisk :
name : " osdisk "
vhd :
uri : " [concat( ' http:// ' ,parameters( ' newStorageAccountName ' ), ' .blob.core.windows.net/ ' ,variables( ' vmStorageAccountContainerName ' ), ' / ' ,variables( ' OSDiskName ' ), ' .vhd ' )] "
caching : " ReadWrite "
createOption : " FromImage "
networkProfile :
networkInterfaces :
-
id : " [resourceId( ' Microsoft.Network/networkInterfaces ' ,variables( ' nicName ' ))] "
diagnosticsProfile :
bootDiagnostics :
enabled : " true "
storageUri : " [concat( ' http:// ' ,parameters( ' newStorageAccountName ' ), ' .blob.core.windows.net ' )] "
parameters :
newStorageAccountName :
value : devopsclestorage
adminUsername :
value : devopscle
adminPassword :
value : Password1 !
dnsNameForPublicIP :
value : devopscleazure
'''
2016-03-14 19:01:30 +01:00
RETURN = '''
'''
2015-12-05 00:06:27 +01:00
try :
import time
import yaml
from itertools import chain
2016-03-14 19:22:33 +01:00
from azure . common . credentials import ServicePrincipalCredentials
2016-03-08 21:03:10 +01:00
from azure . common . exceptions import CloudError
from azure . mgmt . resource . resources . models import (
DeploymentProperties ,
ParametersLink ,
TemplateLink ,
Deployment ,
ResourceGroup ,
Dependency
)
from azure . mgmt . resource . resources import ResourceManagementClient , ResourceManagementClientConfiguration
from azure . mgmt . network import NetworkManagementClient , NetworkManagementClientConfiguration
2015-12-05 00:06:27 +01:00
HAS_DEPS = True
except ImportError :
HAS_DEPS = False
AZURE_URL = " https://management.azure.com "
def get_azure_connection_info ( module ) :
azure_url = module . params . get ( ' azure_url ' )
2016-03-14 19:22:33 +01:00
tenant_id = module . params . get ( ' tenant_id ' )
2015-12-05 00:06:27 +01:00
client_id = module . params . get ( ' client_id ' )
client_secret = module . params . get ( ' client_secret ' )
resource_group_name = module . params . get ( ' resource_group_name ' )
subscription_id = module . params . get ( ' subscription_id ' )
if not azure_url :
if ' AZURE_URL ' in os . environ :
azure_url = os . environ [ ' AZURE_URL ' ]
else :
azure_url = None
if not subscription_id :
if ' AZURE_SUBSCRIPTION_ID ' in os . environ :
subscription_id = os . environ [ ' AZURE_SUBSCRIPTION_ID ' ]
else :
subscription_id = None
if not resource_group_name :
if ' AZURE_RESOURCE_GROUP_NAME ' in os . environ :
resource_group_name = os . environ [ ' AZURE_RESOURCE_GROUP_NAME ' ]
else :
resource_group_name = None
2016-03-14 19:22:33 +01:00
if not tenant_id :
2015-12-05 00:06:27 +01:00
if ' AZURE_TENANT_ID ' in os . environ :
2016-03-14 19:22:33 +01:00
tenant_id = os . environ [ ' AZURE_TENANT_ID ' ]
2015-12-05 00:06:27 +01:00
elif ' AZURE_DOMAIN ' in os . environ :
2016-03-14 19:22:33 +01:00
tenant_id = os . environ [ ' AZURE_DOMAIN ' ]
2015-12-05 00:06:27 +01:00
else :
2016-03-14 19:22:33 +01:00
tenant_id = None
2015-12-05 00:06:27 +01:00
if not client_id :
if ' AZURE_CLIENT_ID ' in os . environ :
client_id = os . environ [ ' AZURE_CLIENT_ID ' ]
else :
client_id = None
if not client_secret :
if ' AZURE_CLIENT_SECRET ' in os . environ :
client_secret = os . environ [ ' AZURE_CLIENT_SECRET ' ]
else :
client_secret = None
return dict ( azure_url = azure_url ,
2016-03-14 19:22:33 +01:00
tenant_id = tenant_id ,
2015-12-05 00:06:27 +01:00
client_id = client_id ,
client_secret = client_secret ,
resource_group_name = resource_group_name ,
subscription_id = subscription_id )
def build_deployment_body ( module ) :
"""
Build the deployment body from the module parameters
: param module : Ansible module containing the validated configuration for the deployment template
: return : body as dict
"""
properties = dict ( mode = ' Incremental ' )
properties [ ' templateLink ' ] = \
dict ( uri = module . params . get ( ' template_link ' ) ,
contentVersion = module . params . get ( ' content_version ' ) )
properties [ ' parametersLink ' ] = \
dict ( uri = module . params . get ( ' parameters_link ' ) ,
contentVersion = module . params . get ( ' content_version ' ) )
return dict ( properties = properties )
2016-03-12 01:44:01 +01:00
def get_failed_nested_operations ( client , resource_group , current_operations ) :
new_operations = [ ]
for operation in current_operations :
if operation . properties . provisioning_state == ' Failed ' :
new_operations . append ( operation )
if operation . properties . target_resource and ' Microsoft.Resources/deployments ' in operation . properties . target_resource . id :
nested_deployment = operation . properties . target_resource . resource_name
nested_operations = client . deployment_operations . list ( resource_group , nested_deployment )
new_nested_operations = get_failed_nested_operations ( client , resource_group , nested_operations )
new_operations + = new_nested_operations
return new_operations
def get_failed_deployment_operations ( module , client , resource_group , deployment_name ) :
operations = client . deployment_operations . list ( resource_group , deployment_name )
return [
dict (
id = op . id ,
operation_id = op . operation_id ,
status_code = op . properties . status_code ,
status_message = op . properties . status_message ,
target_resource = dict (
id = op . properties . target_resource . id ,
resource_name = op . properties . target_resource . resource_name ,
resource_type = op . properties . target_resource . resource_type
) if op . properties . target_resource else None ,
provisioning_state = op . properties . provisioning_state ,
)
for op in get_failed_nested_operations ( client , resource_group , operations )
]
2015-12-05 00:06:27 +01:00
def deploy_template ( module , client , conn_info ) :
"""
Deploy the targeted template and parameters
: param module : Ansible module containing the validated configuration for the deployment template
: param client : resource management client for azure
: param conn_info : connection info needed
: return :
"""
deployment_name = conn_info [ " deployment_name " ]
group_name = conn_info [ " resource_group_name " ]
2016-03-08 21:03:10 +01:00
deploy_parameter = DeploymentProperties ( )
deploy_parameter . mode = module . params . get ( ' deployment_mode ' )
2015-12-05 00:06:27 +01:00
if module . params . get ( ' parameters_link ' ) is None :
2016-03-08 21:03:10 +01:00
deploy_parameter . parameters = module . params . get ( ' parameters ' )
2015-12-05 00:06:27 +01:00
else :
2016-03-08 21:03:10 +01:00
parameters_link = ParametersLink (
uri = module . params . get ( ' parameters_link ' )
)
2015-12-05 00:06:27 +01:00
deploy_parameter . parameters_link = parameters_link
if module . params . get ( ' template_link ' ) is None :
2016-03-08 21:03:10 +01:00
deploy_parameter . template = module . params . get ( ' template ' )
2015-12-05 00:06:27 +01:00
else :
2016-03-08 21:03:10 +01:00
template_link = TemplateLink (
uri = module . params . get ( ' template_link ' )
)
2015-12-05 00:06:27 +01:00
deploy_parameter . template_link = template_link
2016-03-08 21:03:10 +01:00
params = ResourceGroup ( location = module . params . get ( ' location ' ) , tags = module . params . get ( ' tags ' ) )
2015-12-05 00:06:27 +01:00
try :
client . resource_groups . create_or_update ( group_name , params )
2016-03-08 21:03:10 +01:00
result = client . deployments . create_or_update ( group_name , deployment_name , deploy_parameter )
2016-03-12 01:44:01 +01:00
deployment_result = result . result ( ) # Blocking wait, return the Deployment object
if module . params . get ( ' wait_for_deployment_completion ' ) :
2016-03-14 18:52:45 +01:00
while not deployment_result . properties . provisioning_state in [ ' Canceled ' , ' Failed ' , ' Deleted ' , ' Succeeded ' ] :
2016-03-12 01:44:01 +01:00
deployment_result = client . deployments . get ( group_name , deployment_name )
time . sleep ( module . params . get ( ' wait_for_deployment_polling_period ' ) )
if deployment_result . properties . provisioning_state == ' Succeeded ' :
return deployment_result
failed_deployment_operations = get_failed_deployment_operations ( module , client , group_name , deployment_name )
module . fail_json ( msg = ' Deployment failed. Deployment id: %s ' % ( deployment_result . id ) , failed_deployment_operations = failed_deployment_operations )
2016-03-08 21:03:10 +01:00
except CloudError as e :
2016-03-14 20:45:06 +01:00
failed_deployment_operations = get_failed_deployment_operations ( module , client , group_name , deployment_name )
module . fail_json ( msg = ' Deploy create failed with status code: %s and message: " %s " ' % ( e . status_code , e . message ) , failed_deployment_operations = failed_deployment_operations )
2015-12-05 00:06:27 +01:00
def destroy_resource_group ( module , client , conn_info ) :
"""
Destroy the targeted resource group
: param module : ansible module
: param client : resource management client for azure
: param conn_info : connection info needed
: return : if the result caused a change in the deployment
"""
try :
2016-03-08 21:03:10 +01:00
result = client . resource_groups . delete ( conn_info [ ' resource_group_name ' ] )
result . wait ( ) # Blocking wait till the delete is finished
except CloudError as e :
2015-12-05 00:06:27 +01:00
if e . status_code == 404 or e . status_code == 204 :
return True
else :
module . fail_json (
msg = ' Delete resource group and deploy failed with status code: %s and message: %s ' % ( e . status_code , e . message ) )
def get_dependencies ( dep_tree , resource_type ) :
matches = [ value for value in dep_tree . values ( ) if value [ ' dep ' ] . resource_type == resource_type ]
for child_tree in [ value [ ' children ' ] for value in dep_tree . values ( ) ] :
matches + = get_dependencies ( child_tree , resource_type )
return matches
2016-03-08 21:03:10 +01:00
def build_hierarchy ( dependencies , tree = None ) :
2015-12-05 00:06:27 +01:00
tree = dict ( top = True ) if tree is None else tree
for dep in dependencies :
if dep . resource_name not in tree :
tree [ dep . resource_name ] = dict ( dep = dep , children = dict ( ) )
2016-03-08 21:03:10 +01:00
if isinstance ( dep , Dependency ) and dep . depends_on is not None and len ( dep . depends_on ) > 0 :
build_hierarchy ( dep . depends_on , tree [ dep . resource_name ] [ ' children ' ] )
2015-12-05 00:06:27 +01:00
if ' top ' in tree :
tree . pop ( ' top ' , None )
keys = list ( tree . keys ( ) )
for key1 in keys :
for key2 in keys :
2016-03-08 21:03:10 +01:00
if key2 in tree and key1 in tree [ key2 ] [ ' children ' ] and key1 in tree :
2015-12-05 00:06:27 +01:00
tree [ key2 ] [ ' children ' ] [ key1 ] = tree [ key1 ]
tree . pop ( key1 )
return tree
def get_ip_dict ( ip ) :
2016-03-12 01:44:01 +01:00
ip_dict = dict ( name = ip . name ,
2015-12-05 00:06:27 +01:00
id = ip . id ,
2016-03-08 21:03:10 +01:00
public_ip = ip . ip_address ,
2016-03-12 01:44:01 +01:00
public_ip_allocation_method = str ( ip . public_ip_allocation_method ) )
if ip . dns_settings :
ip_dict [ ' dns_settings ' ] = {
2016-03-08 21:03:10 +01:00
' domain_name_label ' : ip . dns_settings . domain_name_label ,
' fqdn ' : ip . dns_settings . fqdn
2016-03-12 01:44:01 +01:00
}
return ip_dict
2016-03-08 21:03:10 +01:00
2015-12-05 00:06:27 +01:00
2016-03-08 21:03:10 +01:00
def nic_to_public_ips_instance ( client , group , nics ) :
return [ client . public_ip_addresses . get ( group , public_ip_id . split ( ' / ' ) [ - 1 ] )
for nic_obj in [ client . network_interfaces . get ( group , nic [ ' dep ' ] . resource_name ) for nic in nics ]
for public_ip_id in [ ip_conf_instance . public_ip_address . id for ip_conf_instance in nic_obj . ip_configurations if ip_conf_instance . public_ip_address ] ]
2015-12-05 00:06:27 +01:00
2016-03-08 21:03:10 +01:00
def get_instances ( client , group , deployment ) :
dep_tree = build_hierarchy ( deployment . properties . dependencies )
2015-12-05 00:06:27 +01:00
vms = get_dependencies ( dep_tree , resource_type = " Microsoft.Compute/virtualMachines " )
2016-03-08 21:03:10 +01:00
vms_and_nics = [ ( vm , get_dependencies ( vm [ ' children ' ] , " Microsoft.Network/networkInterfaces " ) ) for vm in vms ]
vms_and_ips = [ ( vm [ ' dep ' ] , nic_to_public_ips_instance ( client , group , nics ) ) for vm , nics in vms_and_nics ]
2015-12-05 00:06:27 +01:00
2016-03-08 21:03:10 +01:00
return [ dict ( vm_name = vm . resource_name , ips = [ get_ip_dict ( ip ) for ip in ips ] ) for vm , ips in vms_and_ips if len ( ips ) > 0 ]
2015-12-05 00:06:27 +01:00
def main ( ) :
argument_spec = dict (
azure_url = dict ( default = AZURE_URL ) ,
2016-03-12 01:44:01 +01:00
subscription_id = dict ( ) ,
2015-12-05 00:06:27 +01:00
client_secret = dict ( no_log = True ) ,
2016-03-14 19:22:33 +01:00
client_id = dict ( required = True ) ,
tenant_id = dict ( required = True ) ,
2015-12-05 00:06:27 +01:00
resource_group_name = dict ( required = True ) ,
state = dict ( default = ' present ' , choices = [ ' present ' , ' absent ' ] ) ,
template = dict ( default = None , type = ' dict ' ) ,
parameters = dict ( default = None , type = ' dict ' ) ,
template_link = dict ( default = None ) ,
parameters_link = dict ( default = None ) ,
2016-03-08 21:03:10 +01:00
location = dict ( default = " West US " ) ,
deployment_mode = dict ( default = ' Complete ' , choices = [ ' Complete ' , ' Incremental ' ] ) ,
2016-03-12 01:44:01 +01:00
deployment_name = dict ( default = " ansible-arm " ) ,
wait_for_deployment_completion = dict ( default = True ) ,
wait_for_deployment_polling_period = dict ( default = 30 )
2015-12-05 00:06:27 +01:00
)
module = AnsibleModule (
argument_spec = argument_spec ,
mutually_exclusive = [ [ ' template_link ' , ' template ' ] , [ ' parameters_link ' , ' parameters ' ] ] ,
)
if not HAS_DEPS :
module . fail_json ( msg = ' requests and azure are required for this module ' )
conn_info = get_azure_connection_info ( module )
2016-03-14 19:22:33 +01:00
credentials = ServicePrincipalCredentials ( client_id = conn_info [ ' client_id ' ] ,
secret = conn_info [ ' client_secret ' ] ,
tenant = conn_info [ ' tenant_id ' ] )
2015-12-05 00:06:27 +01:00
2016-03-12 01:44:01 +01:00
subscription_id = conn_info [ ' subscription_id ' ]
2016-03-16 00:13:13 +01:00
resource_configuration = ResourceManagementClientConfiguration ( credentials , subscription_id )
resource_configuration . add_user_agent ( ' Ansible-Deploy ' )
resource_client = ResourceManagementClient ( resource_configuration )
network_configuration = NetworkManagementClientConfiguration ( credentials , subscription_id )
network_configuration . add_user_agent ( ' Ansible-Deploy ' )
network_client = NetworkManagementClient ( network_configuration )
2016-03-08 21:03:10 +01:00
conn_info [ ' deployment_name ' ] = module . params . get ( ' deployment_name ' )
2015-12-05 00:06:27 +01:00
if module . params . get ( ' state ' ) == ' present ' :
deployment = deploy_template ( module , resource_client , conn_info )
data = dict ( name = deployment . name ,
group_name = conn_info [ ' resource_group_name ' ] ,
id = deployment . id ,
outputs = deployment . properties . outputs ,
2016-03-08 21:03:10 +01:00
instances = get_instances ( network_client , conn_info [ ' resource_group_name ' ] , deployment ) ,
2015-12-05 00:06:27 +01:00
changed = True ,
msg = ' deployment created ' )
module . exit_json ( * * data )
else :
destroy_resource_group ( module , resource_client , conn_info )
module . exit_json ( changed = True , msg = ' deployment deleted ' )
2016-03-14 19:01:30 +01:00
# import module snippets
from ansible . module_utils . basic import *
2015-12-05 00:06:27 +01:00
if __name__ == ' __main__ ' :
main ( )