You are on page 1of 141

Contents

Ansible on Azure documentation


Overview
About Ansible on Azure
Quickstarts
Deploy Ansible solution template to CentOS
Install Ansible on Linux virtual machines
Configure Linux virtual machines
Manage Linux virtual machines
Run playbooks in Cloud Shell
Tutorials
Azure Application Gateway
Manage web traffic
Azure App Service
Configure apps
Scale apps
Azure DevTest Labs
Configure labs
Azure Kubernetes Service (AKS)
Configure AKS clusters
Configure Azure CNI networking
Configure kubenet networking
Configure RBAC roles in AKS cluster
Azure HDInsight
Configure clusters
Azure Service Bus
Configure queues
Configure topics
Database
Configure Azure Database for MySQL
Configure Azure Cosmos DB accounts
Configure Azure Cache for Redis
Dynamic inventory
Manage your Azure resources
Virtual machines scale sets
Configure
Deploy
Autoscale
Update custom image
Virtual network
Configure peering
Configure route tables
Reference
Playbook roles
azure_module
azure_preview_module
Releases and features
Azure Container Instances
Azure Functions
Load balancers
Virtual machines
All modules for Azure
Tools
Visual Studio Code extension for Ansible
Using Ansible with Azure
5/7/2019 • 2 minutes to read • Edit Online

Ansible is an open-source product that automates cloud provisioning, configuration management, and application
deployments. Using Ansible you can provision virtual machines, containers, and network and complete cloud
infrastructures. Also, Ansible allows you to automate the deployment and configuration of resources in your
environment.
This article gives a basic overview of some of the benefits of using Ansible with Azure.

Ansible playbooks
Ansible playbooks allow you to direct Ansible to configure your environment. Playbooks are coded using YAML so
as to be human-readable. The Tutorials section gives many examples of using playbooks to install and configure
Azure resources.

Ansible modules
Ansible includes a suite of Ansible modules that are run directly on remote hosts or via playbooks. Users can create
their own modules. Modules are used to control system resources - such as services, packages, or files - or execute
system commands.
For interacting with Azure services, Ansible includes a suite of Ansible cloud modules. These modules enable you
to create and orchestrate your infrastructure on Azure.

Migrate existing workload to Azure


Once you use Ansible to define your infrastructure, you can apply your application's playbook letting Azure
automatically scale your environment as needed.

Automate cloud-native application in Azure


Ansible enables you to automate cloud-native applications in Azure using Azure microservices such as Azure
Functions and Kubernetes on Azure.

Manage deployments with dynamic inventory


Via its dynamic inventory feature, Ansible provides the ability to pull inventory from Azure resources. You can then
tag your existing Azure deployments and manage those tagged deployments through Ansible.

Additional Azure Marketplace options


The Ansible Tower is an Azure Marketplace image by Red Hat.
Ansible Tower is a web-based UI and dashboard for Ansible that has the following features:
Enables you to define role-based access control, job scheduling, and graphical inventory management.
Includes a REST API and CLI so you can insert Tower into existing tools and processes.
Supports real-time output of playbook runs.
Encrypts credentials - such as Azure and SSH keys - so you can delegate tasks without exposing credentials.
Ansible module and version matrix for Azure
Ansible includes a suite of modules for use in provisioning and configuring Azure resources. These resources
include virtual machines, scale sets, networking services, and container services. The Ansible matrix lists the
Ansible modules for Azure and the Ansible versions in which they ship.

Next steps
Quickstart: Deploy the Ansible solution template for Azure to CentOS
Quickstart: Configure Linux virtual machines in Azure using Ansible
Quickstart: Deploy the Ansible solution template for
Azure to CentOS
5/7/2019 • 3 minutes to read • Edit Online

The Ansible solution template for Azure is designed to configure an Ansible instance on a CentOS virtual machine
along with Ansible and a suite of tools configured to work with Azure. The tools include:
Ansible modules for Azure - The Ansible modules for Azure are a suite of modules that enable you to create
and manage your infrastructure on Azure. The latest version of these modules is deployed by default. However,
during the solution-template deployment process, you can specify a version number that is appropriate for your
environment.
Azure Command-Line Interface (CLI ) 2.0 - The Azure CLI 2.0 is a cross-platform command-line experience
for managing Azure resources.
managed identities for Azure resources - The managed identities for Azure resources feature addresses the
issue of keeping cloud application credentials secure.

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.

Deploy the Ansible solution template


1. Browse to the Ansible solution template in the Azure Marketplace.
2. Select GET IT NOW.
3. A window appears that details the Terms of Use, Privacy Policy, and Use of Azure Marketplace Terms. Select
Continue.
4. The Azure portal appears and displays the Ansible page that describes the solution template. Select Create.
5. In the Create Ansible page, you see several tabs. On the Basics tab, enter the required information:
Name - Specify the name your Ansible instance. For demo purposes, the name ansiblehost is used.
User name: - Specify the user name that will have access to the Ansible instance. For demo
purposes, the name ansibleuser is used.
Authentication type: - Select either Password or SSH public key. For demo purposes, SSH
public key is selected.
Password and Confirm password - If you select Password for Authentication type, enter your
password for these values.
SSH public key - If you select SSH public key for Authentication type, enter your RSA public
key in the single-line format - starting with ssh-rsa .
Subscription - Select your Azure subscription from the dropdown list.
Resource group - Select an existing resource group from the dropdown list, or select Create new
and specify a name for a new resource group. For demo purposes, a new resource group named
ansiblerg is used.
Location - Select the location from the dropdown list that is appropriate for your scenario.

6. Select OK.
7. In the Additional Settings tab, enter the required information:
Size - The Azure portal defaults to a standard size. To specify a different size that accommodates
your specific scenario, select the arrow to display a list of different sizes.
VM disk type - Select either SSD (Premium Solid-State Drive) or HDD (Hard Disk Drive). For
demo purposes, SSD is selected for its performance benefits. For more information on each these
types of disk storage, see the following articles:
High-performance Premium Storage and managed disks for VMs
Standard SSD Managed Disks for Azure Virtual machine workloads
Public IP Address - Specify this setting if you want to communicate with the virtual machine from
outside the virtual machine. The default is a new public IP address that has the name ansible-pip . To
specify a different IP address, select the arrow specify the attributes - such as name, SKU, and
Assignment, of that IP address.
Domain name label - Enter the public-facing domain name of the virtual machine. The name must
be unique and meet naming requirements. For more information about specifying a name for the
virtual machine, see Naming conventions for Azure resources.
Ansible version - Specify either a version number or the value latest to deploy the latest version.
Select the information icon next to Ansible version to see more information about available
versions.

8. Select OK.
9. In the Ansible Integration Settings tab, specify the authentication type. For more information about
securing Azure resources, see What is managed identities for Azure resources?.

10. Select OK.


11. The Summary page displays showing the validation process and listing the specified criteria for the Ansible
deployment. A link at the bottom of the tab allows you to Download the template and parameters for
use with supported Azure languages and platforms.
12. Select OK.
13. When the Create tab appears, select OK to deploy Ansible.
14. Select the Notifications icon at the top of the portal page to track the Ansible deployment. Once the
deployment is complete, select Go to resource group.

15. On the resource group page, get the IP address of your Ansible host and sign in to manage your Azure
resources using Ansible.

Next steps
Quickstart: Configure a Linux virtual machine in Azure using Ansible
Quickstart: Run Ansible playbooks via Bash in Azure
Cloud Shell
5/7/2019 • 2 minutes to read • Edit Online

Azure Cloud Shell is an interactive, browser-accessible shell for managing Azure resources. Cloud Shell provides
enables you to use either a Bash or Powershell command line. In this article, you use Bash within Azure Cloud
Shell to run an Ansible playbook.

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Configure Azure Cloud Shell - If you're new to Azure Cloud Shell, see Quickstart for Bash in Azure Cloud
Shell.

Use Azure Cloud Shell


Azure hosts Azure Cloud Shell, an interactive shell environment that you can use through your browser. Cloud
Shell lets you use either bash or PowerShell to work with Azure services. You can use the Cloud Shell pre-
installed commands to run the code in this article without having to install anything on your local environment.
To launch Azure Cloud Shell:

OPTION EXAMPLE/LINK

Select Try It in the upper-right corner of a code block.


Selecting Try It doesn't automatically copy the code to Cloud
Shell.

Go to https://shell.azure.com or select the Launch Cloud


Shell button to open Cloud Shell in your browser.

Select the Cloud Shell button on the top-right menu bar in


the Azure portal.

To run the code in this article in Azure Cloud Shell:


1. Launch Cloud Shell.
2. Select the Copy button on a code block to copy the code.
3. Paste the code into the Cloud Shell session with Ctrl+Shift+V on Windows and Linux, or Cmd+Shift+V
on macOS.
4. Press Enter to run the code.

Automatic credential configuration


When signed into the Cloud Shell, Ansible authenticates with Azure to manage infrastructure without any
additional configuration.
When working with multiple subscriptions, specify the subscription Ansible uses by exporting the
AZURE_SUBSCRIPTION_ID environment variable.
To list all of your Azure subscriptions, run the following command:

az account list

Using your Azure subscription ID, set the AZURE_SUBSCRIPTION_ID as follows:

export AZURE_SUBSCRIPTION_ID=<your-subscription-id>

Verify the configuration


To verify the successful configuration, use Ansible to create an Azure resource group.
1. In Cloud Shell, create a file named rg.yml .

code rg.yml

2. Paste the following code into the editor:

---
- hosts: localhost
connection: local
tasks:
- name: Create resource group
azure_rm_resourcegroup:
name: ansible-rg
location: eastus
register: rg
- debug:
var: rg

3. Save the file and exit the editor.


4. Run the playbook using the ansible-playbook command:

ansible-playbook rg.yml

After running the playbook, you see output similar to the following results:
PLAY [localhost] *********************************************************************************

TASK [Gathering Facts] ***************************************************************************


ok: [localhost]

TASK [Create resource group] *********************************************************************


changed: [localhost]

TASK [debug] *************************************************************************************


ok: [localhost] => {
"rg": {
"changed": true,
"contains_resources": false,
"failed": false,
"state": {
"id": "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/ansible-rg",
"location": "eastus",
"name": "ansible-rg",
"provisioning_state": "Succeeded",
"tags": null
}
}
}

PLAY RECAP ***************************************************************************************


localhost : ok=3 changed=1 unreachable=0 failed=0

Next steps
Quickstart: Configure virtual machine in Azure using Ansible
Tutorial: Manage web traffic with Azure Application
Gateway using Ansible
5/7/2019 • 5 minutes to read • Edit Online

IMPORTANT
Ansible 2.7 (or later) is required to run the sample playbooks in this article.

Azure Application Gateway is a web traffic load balancer that enables you to manage traffic to your web
applications. Based on the source IP address and port, traditional load balancers route traffic to a destination IP
address and port. Application Gateway gives you a finer level of control where traffic can be routed based on the
URL. For example, you could define that if images is URL's path, traffic is routed to a specific set of servers (known
as a pool) configured for images.
In this tutorial, Ansible is used to:
Set up a network
Create two Azure container instances with HTTPD images
Create an application gateway that works with the Azure container instances in the server pool

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.

Create a resource group


The playbook code in this section creates an Azure resource group. A resource group is a logical container in which
Azure resources are configured.
Save the following playbook as rg.yml :

- hosts: localhost
vars:
resource_group: myResourceGroup
location: eastus
tasks:
- name: Create a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"

Before running the playbook, see the following notes:


The resource group name is myResourceGroup . This value is used throughout the tutorial.
The resource group is created in the eastus location.
Run the playbook using the ansible-playbook command:

ansible-playbook rg.yml

Create network resources


The playbook code in this section creates a virtual network to enable the application gateway to communicate with
other resources.
Save the following playbook as vnet_create.yml :

- hosts: localhost
vars:
resource_group: myResourceGroup
location: eastus
vnet_name: myVNet
subnet_name: myAGSubnet
publicip_name: myAGPublicIPAddress
publicip_domain: mydomain
tasks:
- name: Create a virtual network
azure_rm_virtualnetwork:
name: "{{ vnet_name }}"
resource_group: "{{ resource_group }}"
address_prefixes_cidr:
- 10.1.0.0/16
- 172.100.0.0/16
dns_servers:
- 127.0.0.1
- 127.0.0.2

- name: Create a subnet


azure_rm_subnet:
name: "{{ subnet_name }}"
virtual_network_name: "{{ vnet_name }}"
resource_group: "{{ resource_group }}"
address_prefix_cidr: 10.1.0.0/24

- name: Create a public IP address


azure_rm_publicipaddress:
resource_group: "{{ resource_group }}"
allocation_method: Dynamic
name: "{{ publicip_name }}"
domain_name_label: "{{ publicip_domain }}"

Before running the playbook, see the following notes:


The vars section contains the values that are used to create the network resources.
You'll need to change these values for your specific environment.
Run the playbook using the ansible-playbook command:

ansible-playbook vnet_create.yml

Create servers
The playbook code in this section creates two Azure container instances with HTTPD images to be used as web
servers for the application gateway.
Save the following playbook as aci_create.yml :

- hosts: localhost
vars:
resource_group: myResourceGroup
location: eastus
aci_1_name: myACI1
aci_2_name: myACI2
tasks:
- name: Create a container with httpd image
azure_rm_containerinstance:
resource_group: "{{ resource_group }}"
name: "{{ aci_1_name }}"
os_type: linux
ip_address: public
location: "{{ location }}"
ports:
- 80
containers:
- name: mycontainer
image: httpd
memory: 1.5
ports:
- 80

- name: Create another container with httpd image


azure_rm_containerinstance:
resource_group: "{{ resource_group }}"
name: "{{ aci_2_name }}"
os_type: linux
ip_address: public
location: "{{ location }}"
ports:
- 80
containers:
- name: mycontainer
image: httpd
memory: 1.5
ports:
- 80

Run the playbook using the ansible-playbook command:

ansible-playbook aci_create.yml

Create the application gateway


The playbook code in this section creates an application gateway named myAppGateway .
Save the following playbook as appgw_create.yml :

- hosts: localhost
connection: local
vars:
resource_group: myResourceGroup
vnet_name: myVNet
subnet_name: myAGSubnet
location: eastus
publicip_name: myAGPublicIPAddress
appgw_name: myAppGateway
aci_1_name: myACI1
aci_2_name: myACI2
tasks:
tasks:
- name: Get info of Subnet
azure_rm_resource_facts:
api_version: '2018-08-01'
resource_group: "{{ resource_group }}"
provider: network
resource_type: virtualnetworks
resource_name: "{{ vnet_name }}"
subresource:
- type: subnets
name: "{{ subnet_name }}"
register: subnet

- name: Get info of backend server 2


azure_rm_resource_facts:
api_version: '2018-04-01'
resource_group: "{{ resource_group }}"
provider: containerinstance
resource_type: containergroups
resource_name: "{{ aci_1_name }}"
register: aci_1_output
- name: Get info of backend server 2
azure_rm_resource_facts:
api_version: '2018-04-01'
resource_group: "{{ resource_group }}"
provider: containerinstance
resource_type: containergroups
resource_name: "{{ aci_2_name }}"
register: aci_2_output

- name: Create instance of Application Gateway


azure_rm_appgateway:
resource_group: "{{ resource_group }}"
name: "{{ appgw_name }}"
sku:
name: standard_small
tier: standard
capacity: 2
gateway_ip_configurations:
- subnet:
id: "{{ subnet.response[0].id }}"
name: appGatewayIP
frontend_ip_configurations:
- public_ip_address: "{{ publicip_name }}"
name: appGatewayFrontendIP
frontend_ports:
- port: 80
name: appGatewayFrontendPort
backend_address_pools:
- backend_addresses:
- ip_address: "{{ aci_1_output.response[0].properties.ipAddress.ip }}"
- ip_address: "{{ aci_2_output.response[0].properties.ipAddress.ip }}"
name: appGatewayBackendPool
backend_http_settings_collection:
- port: 80
protocol: http
cookie_based_affinity: enabled
name: appGatewayBackendHttpSettings
http_listeners:
- frontend_ip_configuration: appGatewayFrontendIP
frontend_port: appGatewayFrontendPort
name: appGatewayHttpListener
request_routing_rules:
- rule_type: Basic
backend_address_pool: appGatewayBackendPool
backend_http_settings: appGatewayBackendHttpSettings
http_listener: appGatewayHttpListener
name: rule1
Before running the playbook, see the following notes:
appGatewayIP is defined in the gateway_ip_configurations block. A subnet reference is required for IP
configuration of the gateway.
appGatewayBackendPool is defined in the backend_address_pools block. An application gateway must have at
least one back-end address pool.
appGatewayBackendHttpSettings is defined in the backend_http_settings_collection block. It specifies that port
80 and an HTTP protocol are used for communication.
appGatewayHttpListener is defined in the backend_http_settings_collection block. It's the default listener
associated with appGatewayBackendPool.
appGatewayFrontendIP is defined in the frontend_ip_configurations block. It assigns myAGPublicIPAddress to
appGatewayHttpListener.
rule1 is defined in the request_routing_rules block. It's the default routing rule associated with
appGatewayHttpListener.
Run the playbook using the ansible-playbook command:

ansible-playbook appgw_create.yml

It might take several minutes for the application gateway to be created.

Test the application gateway


1. In the Create a resource group section, you specify a location. Note its value.
2. In the Create network resources section, you specify the domain. Note its value.
3. For the test URL by replacing the following pattern with the location and domain:
http://<domain>.<location>.cloudapp.azure.com .

4. Browse to the test URL.


5. If you see the following page, the application gateway is working as expected.

Clean up resources
When no longer needed, delete the resources created in this article.
Save the following code as cleanup.yml :

- hosts: localhost
vars:
resource_group: myResourceGroup
tasks:
- name: Delete a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
state: absent

Run the playbook using the ansible-playbook command:


ansible-playbook cleanup.yml

Next steps
Ansible on Azure
Tutorial: Configure apps in Azure App Service using
Ansible
5/7/2019 • 4 minutes to read • Edit Online

IMPORTANT
Ansible 2.7 (or later) is required to run the sample playbooks in this article.

Azure App Service enables you to build and host code. This code can be in the form of web apps, mobile backends,
and RESTful APIs. Using App Service, you can develop you code using the programming language of your choice
without managing infrastructure. App Service supports both Windows and Linux. Automated deployments from
any Git repo are supported, including GitHub and Azure DevOps.
In this tutorial, Ansible is used to:
Create an app in Azure App Service with Java 8 and the Tomcat container runtime
Create an Azure Traffic Manager profile
Define a Traffic Manager endpoint using the created app

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.

Create a basic app service


The playbook code in this section defines the following resources:
Azure resource group within which the App Service plan and app are deployed
App service on Linux with Java 8 and the Tomcat container runtime
Save the following playbook as firstwebapp.yml :
- hosts: localhost
connection: local
vars:
resource_group: myResourceGroup
webapp_name: myfirstWebApp
plan_name: myAppServicePlan
location: eastus
tasks:
- name: Create a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"

- name: Create App Service on Linux with Java Runtime


azure_rm_webapp:
resource_group: "{{ resource_group }}"
name: "{{ webapp_name }}"
plan:
resource_group: "{{ resource_group }}"
name: "{{ plan_name }}"
is_linux: true
sku: S1
number_of_workers: 1
frameworks:
- name: "java"
version: "8"
settings:
java_container: tomcat
java_container_version: 8.5

Run the playbook using the ansible-playbook command:

ansible-playbook firstwebapp.yml

After running the playbook, you see output similar to the following results:

PLAY [localhost]

TASK [Gathering Facts]


ok: [localhost]

TASK [Create a resource group]


changed: [localhost]

TASK [Create App Service on Linux with Java Runtime]


[WARNING]: Azure API profile latest does not define an entry for WebSiteManagementClient

changed: [localhost]

PLAY RECAP
localhost : ok=3 changed=2 unreachable=0 failed=0

Create an app and use Azure Traffic Manager


Azure Traffic Manager enables you to control how requests from web clients are distributed to apps in Azure App
Service. When App Service endpoints are added to an Azure Traffic Manager profile, Traffic Manager tracks the
status of your App Service apps. Statuses include running, stopped, and deleted. Traffic Manager is used to decide
which endpoints should receive the traffic.
In App Service, an app runs in an App Service plan. An App Service plan defines a set of compute resources for an
app to run. You can manage your App Service plan and web app in different groups.
The playbook code in this section defines the following resources:
Azure resource group within which the App Service plan is deployed
App Service plan
Azure resource group within which the app is deployed
App service on Linux with Java 8 and the Tomcat container runtime
Traffic Manager profile
Traffic Manager endpoint using the created app
Save the following playbook as webapp.yml :

- hosts: localhost
connection: local
vars:
resource_group_webapp: myResourceGroupWebapp
resource_group: myResourceGroup
webapp_name: myLinuxWebApp
plan_name: myAppServicePlan
location: eastus
traffic_manager_profile_name: myTrafficManagerProfile
traffic_manager_endpoint_name: myTrafficManagerEndpoint

tasks:
- name: Create resource group
azure_rm_resourcegroup:
name: "{{ resource_group_webapp }}"
location: "{{ location }}"

- name: Create secondary resource group


azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"

- name: Create App Service Plan


azure_rm_appserviceplan:
resource_group: "{{ resource_group }}"
name: "{{ plan_name }}"
location: "{{ location }}"
is_linux: true
sku: S1
number_of_workers: 1

- name: Create App Service on Linux with Java Runtime


azure_rm_webapp:
resource_group: "{{ resource_group_webapp }}"
name: "{{ webapp_name }}"
plan:
resource_group: "{{ resource_group }}"
name: "{{ plan_name }}"
is_linux: true
sku: S1
number_of_workers: 1
app_settings:
testkey: "testvalue"
frameworks:
- name: java
version: 8
settings:
java_container: "Tomcat"
java_container_version: "8.5"

- name: Get web app facts


azure_rm_webapp_facts:
resource_group: "{{ resource_group_webapp }}"
resource_group: "{{ resource_group_webapp }}"
name: "{{ webapp_name }}"
register: webapp

- name: Create Traffic Manager Profile


azure_rm_trafficmanagerprofile:
resource_group: "{{ resource_group_webapp }}"
name: "{{ traffic_manager_profile_name }}"
location: global
routing_method: performance
dns_config:
relative_name: "{{ traffic_manager_profile_name }}"
ttl: 60
monitor_config:
protocol: HTTPS
port: 80
path: '/'

- name: Add endpoint to traffic manager profile, using created web site
azure_rm_trafficmanagerendpoint:
resource_group: "{{ resource_group_webapp }}"
profile_name: "{{ traffic_manager_profile_name }}"
name: "{{ traffic_manager_endpoint_name }}"
type: azure_endpoints
location: "{{ location }}"
target_resource_id: "{{ webapp.webapps[0].id }}"

Run the playbook using the ansible-playbook command:

ansible-playbook webapp.yml

After running the playbook, you see output similar to the following results:
PLAY [localhost]

TASK [Gathering Facts]


ok: [localhost]

TASK [Create resource group]


changed: [localhost]

TASK [Create resource group for app service plan]


changed: [localhost]

TASK [Create App Service Plan]


[WARNING]: Azure API profile latest does not define an entry for WebSiteManagementClient

changed: [localhost]

TASK [Create App Service on Linux with Java Runtime]


changed: [localhost]

TASK [Get web app facts]


ok: [localhost]

TASK [Create Traffic Manager Profile]


[WARNING]: Azure API profile latest does not define an entry for TrafficManagerManagementClient

changed: [localhost]

TASK [Add endpoint to traffic manager profile, using the web site created above]
changed: [localhost]

TASK [Get Traffic Manager Profile facts]


ok: [localhost]

PLAY RECAP
localhost : ok=9 changed=6 unreachable=0 failed=0

Next steps
Tutorial: Scale apps in Azure App Service using Ansible
Tutorial: Scale apps in Azure App Service using
Ansible
5/7/2019 • 2 minutes to read • Edit Online

IMPORTANT
Ansible 2.7 (or later) is required to run the sample playbooks in this article.

Azure App Service enables you to build and host code. This code can be in the form of web apps, mobile backends,
and RESTful APIs. Using App Service, you can develop you code using the programming language of your choice
without managing infrastructure. App Service supports both Windows and Linux. Automated deployments from
any Git repo are supported, including GitHub and Azure DevOps.
In this tutorial, Ansible is used to:
Get facts of an existing App Service plan
Scale up the App Service plan to S2 with three workers

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.
Azure App Service app - If you don't have an Azure App Service app, configure an app in Azure App Service
using Ansible.

Scale up an app
There are two workflows for scaling: scale up and scale out.
Scale up: To scale up means to acquire more resources. These resources include CPU, memory, disk space, VMs,
and more. You scale up an app by changing the pricing tier of the App Service plan to which the app belongs. Scale
out: To scale out means to increase the number of VM instances that run your app. Depending on your App
Service plan pricing tier, you can scale out to as many as 20 instances. Autoscaling allows you to scale instance
count automatically based on predefined rules and schedules.
The playbook code in this section defines following operation:
Get facts of an existing App Service plan
Update the App service plan to S2 with three workers
Save the following playbook as webapp_scaleup.yml :
- hosts: localhost
connection: local
vars:
resource_group: myResourceGroup
plan_name: myAppServicePlan
location: eastus

tasks:
- name: Get facts of existing App service plan
azure_rm_appserviceplan_facts:
resource_group: "{{ resource_group }}"
name: "{{ plan_name }}"
register: facts

- debug:
var: facts.appserviceplans[0].sku

- name: Scale up the App service plan


azure_rm_appserviceplan:
resource_group: "{{ resource_group }}"
name: "{{ plan_name }}"
is_linux: true
sku: S2
number_of_workers: 3

- name: Get facts


azure_rm_appserviceplan_facts:
resource_group: "{{ resource_group }}"
name: "{{ plan_name }}"
register: facts

- debug:
var: facts.appserviceplans[0].sku

Run the playbook using the ansible-playbook command:

ansible-playbook webapp_scaleup.yml

After running the playbook, you see output similar to the following results:
PLAY [localhost]

TASK [Gathering Facts]


ok: [localhost]

TASK [Get facts of existing App service plan]


[WARNING]: Azure API profile latest does not define an entry for WebSiteManagementClient

ok: [localhost]

TASK [debug]
ok: [localhost] => {
"facts.appserviceplans[0].sku": {
"capacity": 1,
"family": "S",
"name": "S1",
"size": "S1",
"tier": "Standard"
}
}

TASK [Scale up the App service plan]


changed: [localhost]

TASK [Get facts]


ok: [localhost]

TASK [debug]
ok: [localhost] => {
"facts.appserviceplans[0].sku": {
"capacity": 3,
"family": "S",
"name": "S2",
"size": "S2",
"tier": "Standard"
}
}

PLAY RECAP
localhost : ok=6 changed=1 unreachable=0 failed=0

Next steps
Ansible on Azure
Tutorial: Configure labs in Azure DevTest Labs using
Ansible
5/7/2019 • 7 minutes to read • Edit Online

IMPORTANT
Ansible 2.8 (or later) is required to run the sample playbooks in this article.

Azure DevTest Labs allows developers to automate the creation of VM environments for their apps. These
environments can be configured for app developing, testing, and training.
In this tutorial, Ansible is used to:
Create a lab
Set the lab policies
Set the lab schedules
Create the lab virtual network
Define an artifact source for the lab
Create a VM within the lab
List the lab's artifact sources and artifacts
Get Azure Resource Manager information for the artifact sources
Create the lab environment
Create the lab image
Delete the lab

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Azure service principal: Create a service principal, making note of the following values: appId,
displayName, password, and tenant.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.

Create resource group


The sample playbook snippet creates an Azure resource group. A resource group is a logical container in which
Azure resources are deployed and managed.

- name: Create a resource group


azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"
Create the lab
The next task creates the sample lab.

- name: Create the lab


azure_rm_devtestlab:
resource_group: "{{ resource_group }}"
name: "{{ lab_name }}"
location: "{{ location }}"
storage_type: standard
premium_data_disks: no
register: output_lab

Set the lab policies


You can set up lab policy settings. The following values can be set:
user_owned_lab_vm_count is the number of VMs a user can own
user_owned_lab_premium_vm_count is the number of premium VMs a user can own
lab_vm_count is the maximum number of lab VMs
lab_premium_vm_count is the maximum number of lab premium VMs
lab_vm_size is the allowed lab VMs size(s)
gallery_image is the allowed gallery image(s)
user_owned_lab_vm_count_in_subnet is the maximum number of user’s VMs in a subnet
lab_target_cost is the target cost of the lab

- name: Set the lab policies


azure_rm_devtestlabpolicy:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
policy_set_name: myDtlPolicySet
name: myDtlPolicy
fact_name: user_owned_lab_vm_count
threshold: 5

Set the lab schedules


The sample task in this section configures the lab schedule.
In the following code snippet, the lab_vms_startup value is used to specify the VM startup time. Likewise, setting
the lab_vms_shutdown value establishes the lab VM shutdown time.

- name: Set the lab schedule


azure_rm_devtestlabschedule:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
name: lab_vms_shutdown
time: "1030"
time_zone_id: "UTC+12"
register: output

Create the lab virtual network


This following task creates the default lab virtual network.
- name: Create the lab virtual network
azure_rm_devtestlabvirtualnetwork:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
name: "{{ vn_name }}"
location: "{{ location }}"
description: My lab virtual network
register: output

Define an artifact source for the lab


An artifacts source is a properly structured GitHub repository that contains artifact definition and Azure Resource
Manager templates. Every lab comes with predefined public artifacts. The follow tasks shows you how to create an
artifact source for a lab.

- name: Define the lab artifacts source


azure_rm_devtestlabartifactsource:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
name: "{{ artifacts_name }}"
uri: https://github.com/Azure/azure_preview_modules.git
source_type: github
folder_path: /tasks
security_token: "{{ github_token }}"

Create a VM within the lab


Create a VM within the lab.

- name: Create a VM within the lab


azure_rm_devtestlabvirtualmachine:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
name: "{{ vm_name }}"
notes: Virtual machine notes, just something....
os_type: linux
vm_size: Standard_A2_v2
user_name: dtladmin
password: ZSasfovobocu$$21!
lab_subnet:
virtual_network_name: "{{ vn_name }}"
name: "{{ vn_name }}Subnet"
disallow_public_ip_address: no
image:
offer: UbuntuServer
publisher: Canonical
sku: 16.04-LTS
os_type: Linux
version: latest
artifacts:
- source_name: "{{ artifacts_name }}"
source_path: "/Artifacts/linux-install-mongodb"
allow_claim: no
expiration_date: "2029-02-22T01:49:12.117974Z"

List the lab's artifact sources and artifacts


To list all default and custom artifacts sources in the lab, use the following task:
- name: List the artifact sources
azure_rm_devtestlabartifactsource_facts:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
register: output
- debug:
var: output

The following task lists all the artifacts:

- name: List the artifact facts


azure_rm_devtestlabartifact_facts:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
artifact_source_name: public repo
register: output
- debug:
var: output

Get Azure Resource Manager information for the artifact sources


To list all the Azure Resource Manager templates in public environment repository , the predefined repository with
templates:

- name: List the Azure Resource Manager template facts


azure_rm_devtestlabartifactsource_facts:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
register: output
- debug:
var: output

And the following task retrieves details of a specific Azure Resource Manager template from the repository:

- name: Get Azure Resource Manager template facts


azure_rm_devtestlabarmtemplate_facts:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
artifact_source_name: "public environment repo"
name: ServiceFabric-LabCluster
register: output
- debug:
var: output

Create the lab environment


The following task creates the lab environment based on one of the templates from public environment repository.

- name: Create the lab environment


azure_rm_devtestlabenvironment:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
user_name: "@me"
name: myEnvironment
location: eastus
deployment_template: "{{ output_lab.id }}/artifactSources/public environment repo/armTemplates/WebApp"
register: output
Create the lab image
The following task creates an image from a VM. The image allows you to create identical VMs.

- name: Create the lab image


azure_rm_devtestlabcustomimage:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
name: myImage
source_vm: "{{ output_vm.virtualmachines[0]['name'] }}"
linux_os_state: non_deprovisioned

Delete the lab


To delete the lab, use the following task:

- name: Delete the lab


azure_rm_devtestlab:
resource_group: "{{ resource_group }}"
name: "{{ lab_name }}"
state: absent
register: output
- name: Assert the change was correctly reported
assert:
that:
- output.changed

Get the sample playbook


There are two ways to get the complete sample playbook:
Download the playbook and save it to devtestlab-create.yml .
Create a new file named devtestlab-create.yml and copy into it the following contents:

---
- hosts: localhost
#roles:
# - azure.azure_preview_modules
vars:
resource_group: "{{ resource_group_name }}"
lab_name: myLab
vn_name: myLabVirtualNetwork
vm_name: myLabVm
artifacts_name: myArtifacts
github_token: "{{ lookup('env','GITHUB_ACCESS_TOKEN') }}"
location: eastus
tasks:
- name: Create a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"

- name: Create the lab


azure_rm_devtestlab:
resource_group: "{{ resource_group }}"
name: "{{ lab_name }}"
location: eastus
storage_type: standard
premium_data_disks: no
register: output_lab
- name: Set the lab policies
azure_rm_devtestlabpolicy:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
policy_set_name: myDtlPolicySet
name: myDtlPolicy
fact_name: user_owned_lab_vm_count
threshold: 5

- name: Set the lab schedule


azure_rm_devtestlabschedule:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
name: lab_vms_shutdown
time: "1030"
time_zone_id: "UTC+12"
register: output

- name: Create the lab virtual network


azure_rm_devtestlabvirtualnetwork:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
name: "{{ vn_name }}"
location: eastus
description: My lab virtual network
register: output

- name: Define the lab artifacts source


azure_rm_devtestlabartifactsource:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
name: "{{ artifacts_name }}"
uri: https://github.com/Azure/azure_preview_modules.git
source_type: github
folder_path: /tasks
security_token: "{{ github_token }}"

- name:
set_fact:
artifact_source:
- source_name: "{{ artifacts_name }}"
source_path: "/Artifacts/linux-install-mongodb"
when: "github_token | length > 0"

- name:
set_fact:
artifact_source: null
when: "github_token | length == 0"

- name: Create a VM within the lab


azure_rm_devtestlabvirtualmachine:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
name: "{{ vm_name }}"
notes: Virtual machine notes, just something....
os_type: linux
vm_size: Standard_A2_v2
user_name: dtladmin
password: ZSasfovobocu$$21!
lab_subnet:
virtual_network_name: "{{ vn_name }}"
name: "{{ vn_name }}Subnet"
disallow_public_ip_address: no
image:
offer: UbuntuServer
publisher: Canonical
sku: 16.04-LTS
os_type: Linux
version: latest
version: latest
artifacts:
- source_name: "{{ artifacts_name }}"
source_path: "/Artifacts/linux-install-mongodb"
allow_claim: no
expiration_date: "2029-02-22T01:49:12.117974Z"

- name: List the artifact sources


azure_rm_devtestlabartifactsource_facts:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
register: output
- debug:
var: output

- name: List the artifact facts


azure_rm_devtestlabartifact_facts:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
artifact_source_name: public repo
register: output
- debug:
var: output

- name: List the Azure Resource Manager template facts


azure_rm_devtestlabarmtemplate_facts:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
artifact_source_name: "public environment repo"
register: output
- debug:
var: output

- name: Get Azure Resource Manager template facts


azure_rm_devtestlabarmtemplate_facts:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
artifact_source_name: "public environment repo"
name: ServiceFabric-LabCluster
register: output
- debug:
var: output

- name: Create the lab environment


azure_rm_devtestlabenvironment:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
user_name: "@me"
name: myEnvironment
location: eastus
deployment_template: "{{ output_lab.id }}/artifactSources/public environment repo/armTemplates/WebApp"

- name: Create the lab image


azure_rm_devtestlabcustomimage:
resource_group: "{{ resource_group }}"
lab_name: "{{ lab_name }}"
name: myImage
source_vm: "{{ vm_name }}"
linux_os_state: non_deprovisioned

- name: Delete the lab


azure_rm_devtestlab:
resource_group: "{{ resource_group }}"
name: "{{ lab_name }}"
state: absent

Run the playbook


In this section, run the playbook to test various features shown in this article.
Before running the playbook, make the following changes:
In the vars section, replace the {{ resource_group_name }} placeholder with the name of your resource group.
Store the GitHub token as an environment variable named GITHUB_ACCESS_TOKEN .

Run the playbook using the ansible-playbook command:

ansible-playbook devtestlab-create.yml

Clean up resources
When no longer needed, delete the resources created in this article.
Save the following code as cleanup.yml :

- hosts: localhost
vars:
resource_group: myResourceGroup
tasks:
- name: Delete a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
force_delete_nonempty: yes
state: absent

Run the playbook using the ansible-playbook command:

ansible-playbook cleanup.yml

Next steps
Ansible on Azure
Tutorial: Configure Azure Kubernetes Service (AKS)
clusters in Azure using Ansible
5/7/2019 • 3 minutes to read • Edit Online

IMPORTANT
Ansible 2.8 (or later) is required to run the sample playbooks in this article.

Azure Kubernetes Service (AKS ) makes it simple to deploy a managed Kubernetes cluster in Azure. AKS reduces
the complexity and operational overhead of managing Kubernetes by offloading much of that responsibility to
Azure. As a hosted Kubernetes service, Azure handles critical tasks like health monitoring and maintenance for you.
The Kubernetes masters are managed by Azure. You only manage and maintain the agent nodes. As a managed
Kubernetes service, AKS is free - you pay only for the agent nodes within your clusters; not for the masters.
AKS can be configured to use Azure Active Directory (AD ) for user authentication. Once configured, you use your
Azure AD authentication token to sign into the AKS cluster. The RBAC can be based on a user's identity or
directory group membership.
In this tutorial, Ansible is used to:
Create an AKS cluster
Configure an AKS cluster

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Azure service principal: Create a service principal, making note of the following values: appId,
displayName, password, and tenant.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.

Create a managed AKS cluster


The sample playbook creates a resource group and an AKS cluster within the resource group.
Save the following playbook as azure_create_aks.yml :
- name: Create Azure Kubernetes Service
hosts: localhost
connection: local
vars:
resource_group: myResourceGroup
location: eastus
aks_name: myAKSCluster
username: azureuser
ssh_key: "your_ssh_key"
client_id: "your_client_id"
client_secret: "your_client_secret"
tasks:
- name: Create resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"
- name: Create a managed Azure Container Services (AKS) cluster
azure_rm_aks:
name: "{{ aks_name }}"
location: "{{ location }}"
resource_group: "{{ resource_group }}"
dns_prefix: "{{ aks_name }}"
linux_profile:
admin_username: "{{ username }}"
ssh_key: "{{ ssh_key }}"
service_principal:
client_id: "{{ client_id }}"
client_secret: "{{ client_secret }}"
agent_pool_profiles:
- name: default
count: 2
vm_size: Standard_D2_v2
tags:
Environment: Production

Before running the playbook, see the following notes:


The first section within tasks defines a resource group named myResourceGroup within the eastus location.
The second section within tasks defines an AKS cluster named myAKSCluster within the myResourceGroup
resource group.
For the your_ssh_key placeholder, enter your RSA public key in the single-line format - starting with "ssh-rsa"
(without the quotes).

Run the playbook using the ansible-playbook command:

ansible-playbook azure_create_aks.yml

Running the playbook shows results similar to the following output:


PLAY [Create AKS]

TASK [Gathering Facts]


ok: [localhost]

TASK [Create resource group]


changed: [localhost]

TASK [Create an Azure Container Services (AKS) cluster]


changed: [localhost]

PLAY RECAP
localhost : ok=3 changed=2 unreachable=0 failed=0

Scale AKS nodes


The sample playbook in the previous section defines two nodes. You adjust the number of nodes by modifying the
count value in the agent_pool_profiles block.

Save the following playbook as azure_configure_aks.yml :

- name: Scale AKS cluster


hosts: localhost
connection: local
vars:
resource_group: myResourceGroup
location: eastus
aks_name: myAKSCluster
username: azureuser
ssh_key: "your_ssh_key"
client_id: "your_client_id"
client_secret: "your_client_secret"
tasks:
- name: Scaling an existed AKS cluster
azure_rm_aks:
name: "{{ aks_name }}"
location: "{{ location }}"
resource_group: "{{ resource_group }}"
dns_prefix: "{{ aks_name }}"
linux_profile:
admin_username: "{{ username }}"
ssh_key: "{{ ssh_key }}"
service_principal:
client_id: "{{ client_id }}"
client_secret: "{{ client_secret }}"
agent_pool_profiles:
- name: default
count: 3
vm_size: Standard_D2_v2

Before running the playbook, see the following notes:


For the your_ssh_key placeholder, enter your RSA public key in the single-line format - starting with "ssh-rsa"
(without the quotes).

Run the playbook using the ansible-playbook command:

ansible-playbook azure_configure_aks.yml

Running the playbook shows results similar to the following output:


PLAY [Scale AKS cluster]

TASK [Gathering Facts]


ok: [localhost]

TASK [Scaling an existed AKS cluster]


changed: [localhost]

PLAY RECAP
localhost : ok=2 changed=1 unreachable=0 failed=0

Delete a managed AKS cluster


The sample playbook deletes an AKS cluster.
Save the following playbook as azure_delete_aks.yml :

- name: Delete a managed Azure Container Services (AKS) cluster


hosts: localhost
connection: local
vars:
resource_group: myResourceGroup
aks_name: myAKSCluster
tasks:
- name:
azure_rm_aks:
name: "{{ aks_name }}"
resource_group: "{{ resource_group }}"
state: absent

Run the playbook using the ansible-playbook command:

ansible-playbook azure_delete_aks.yml

Running the playbook shows results similar to the following output:

PLAY [Delete a managed Azure Container Services (AKS) cluster]

TASK [Gathering Facts]


ok: [localhost]

TASK [azure_rm_aks]

PLAY RECAP
localhost : ok=2 changed=1 unreachable=0 failed=0

Next steps
Tutorial: Scale application in Azure Kubernetes Service (AKS )
Tutorial: Configure Azure CNI networking in Azure
Kubernetes Service (AKS) using Ansible
5/7/2019 • 4 minutes to read • Edit Online

IMPORTANT
Ansible 2.8 (or later) is required to run the sample playbooks in this article.

Azure Kubernetes Service (AKS ) makes it simple to deploy a managed Kubernetes cluster in Azure. AKS reduces
the complexity and operational overhead of managing Kubernetes by offloading much of that responsibility to
Azure. As a hosted Kubernetes service, Azure handles critical tasks like health monitoring and maintenance for you.
The Kubernetes masters are managed by Azure. You only manage and maintain the agent nodes. As a managed
Kubernetes service, AKS is free - you pay only for the agent nodes within your clusters; not for the masters.
Using AKS, you can deploy a cluster using the following network models:
Kubenet networking - Network resources are typically created and configured as the AKS cluster is deployed.
Azure CNI networking - AKS cluster is connected to existing virtual network (VNET) resources and
configurations.
For more information about networking to your applications in AKS, see Network concepts for applications in
AKS.
In this tutorial, Ansible is used to:
Create an AKS cluster
Configure Azure CNI networking

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Azure service principal: Create a service principal, making note of the following values: appId,
displayName, password, and tenant.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.

Create a virtual network and subnet


The sample playbook code in this section is used to:
Create a virtual network
Create a subnet within the virtual network
Save the following playbook as vnet.yml :
- name: Create vnet
azure_rm_virtualnetwork:
resource_group: "{{ resource_group }}"
name: "{{ name }}"
address_prefixes_cidr:
- 10.0.0.0/8

- name: Create subnet


azure_rm_subnet:
resource_group: "{{ resource_group }}"
name: "{{ name }}"
address_prefix_cidr: 10.240.0.0/16
virtual_network_name: "{{ name }}"
register: subnet

Create an AKS cluster in the virtual network


The sample playbook code in this section is used to:
Create an AKS cluster within a virtual network.
Save the following playbook as aks.yml :

- name: List supported kubernetes version from Azure


azure_rm_aks_version:
location: "{{ location }}"
register: versions

- name: Create AKS cluster within a VNet


azure_rm_aks:
resource_group: "{{ resource_group }}"
name: "{{ name }}"
dns_prefix: "{{ name }}"
kubernetes_version: "{{ versions.azure_aks_versions[-1] }}"
agent_pool_profiles:
- count: 3
name: nodepool1
vm_size: Standard_D2_v2
vnet_subnet_id: "{{ vnet_subnet_id }}"
linux_profile:
admin_username: azureuser
ssh_key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
service_principal:
client_id: "{{ lookup('ini', 'client_id section=default file=~/.azure/credentials') }}"
client_secret: "{{ lookup('ini', 'secret section=default file=~/.azure/credentials') }}"
network_profile:
network_plugin: azure
docker_bridge_cidr: 172.17.0.1/16
dns_service_ip: 10.2.0.10
service_cidr: 10.2.0.0/24
register: aks

Here are some key notes to consider when working with the sample playbook:
Use the azure_rm_aks_version module to find the supported version.
The vnet_subnet_id is the subnet created in the previous section.
The playbook loads ssh_key from ~/.ssh/id_rsa.pub . If you modify it, use the single-line format - starting
with "ssh-rsa" (without the quotes).
The client_id and client_secret values are loaded from ~/.azure/credentials , which is the default
credential file. You can set these values to your service principal or load these values from environment
variables:

client_id: "{{ lookup('env', 'AZURE_CLIENT_ID') }}"


client_secret: "{{ lookup('env', 'AZURE_SECRET') }}"

Run the sample playbook


The sample playbook code in this section is used to test various features shown throughout this tutorial.
Save the following playbook as aks-azure-cni.yml :

---
- hosts: localhost
vars:
resource_group: aksansibletest
name: aksansibletest
location: eastus
tasks:
- name: Ensure resource group exists
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"

- name: Create vnet


include_tasks: vnet.yml

- name: Create AKS


vars:
vnet_subnet_id: "{{ subnet.state.id }}"
include_tasks: aks.yml

- name: Show AKS cluster detail


debug:
var: aks

Here are some key notes to consider when working with the sample playbook:
Change the aksansibletest value to your resource group name.
Change the aksansibletest value to your AKS name.
Change the eastus value to your resource group location.

Run the playbook using the ansible-playbook command:

ansible-playbook aks-azure-cni.yml

After running the playbook, you see output similar to the following results:

PLAY [localhost]

TASK [Gathering Facts]


ok: [localhost]

TASK [Ensure resource group exists]


changed: [localhost]

TASK [Create vnet]


included: /home/devops/aks-cni/vnet.yml for localhost

TASK [Create vnet]


TASK [Create vnet]
changed: [localhost]

TASK [Create subnet]


changed: [localhost]

TASK [Create AKS]


included: /home/devops/aks-cni/aks.yml for localhost

TASK [List supported kubernetes version from Azure]


[WARNING]: Azure API profile latest does not define an entry for
ContainerServiceClient

ok: [localhost]

TASK [Create AKS cluster with vnet]


changed: [localhost]

TASK [Show AKS cluster detail]


ok: [localhost] => {
"aks": {
"aad_profile": {},
"addon": {},
"agent_pool_profiles": [
{
"count": 3,
"name": "nodepool1",
"os_disk_size_gb": 100,
"os_type": "Linux",
"storage_profile": "ManagedDisks",
"vm_size": "Standard_D2_v2",
"vnet_subnet_id": "/subscriptions/BBBBBBBB-BBBB-BBBB-BBBB-
BBBBBBBBBBBB/resourceGroups/aksansibletest/providers/Microsoft.Network/virtualNetworks/aksansibletest/subnets/a
ksansibletest"
}
],
"changed": true,
"dns_prefix": "aksansibletest",
"enable_rbac": false,
"failed": false,
"fqdn": "aksansibletest-0272707d.hcp.eastus.azmk8s.io",
"id": "/subscriptions/BBBBBBBB-BBBB-BBBB-BBBB-
BBBBBBBBBBBB/resourcegroups/aksansibletest/providers/Microsoft.ContainerService/managedClusters/aksansibletest"
,
"kube_config": "..."
},
"location": "eastus",
"name": "aksansibletest",
"network_profile": {
"dns_service_ip": "10.2.0.10",
"docker_bridge_cidr": "172.17.0.1/16",
"network_plugin": "azure",
"network_policy": null,
"pod_cidr": null,
"service_cidr": "10.2.0.0/24"
},
"node_resource_group": "MC_aksansibletest_aksansibletest_eastus",
"provisioning_state": "Succeeded",
"service_principal_profile": {
"client_id": "AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA"
},
"tags": null,
"type": "Microsoft.ContainerService/ManagedClusters",
"warnings": [
"Azure API profile latest does not define an entry for ContainerServiceClient",
"Azure API profile latest does not define an entry for ContainerServiceClient"
]
}
}
PLAY RECAP
localhost : ok=9 changed=4 unreachable=0 failed=0 skipped=0 rescued=0
ignored=0

Clean up resources
When no longer needed, delete the resources created in this article.
The sample playbook code in this section is used to:
Delete a resource group referred to in the vars section.

Save the following playbook as cleanup.yml :

---
- hosts: localhost
vars:
resource_group: {{ resource_group_name }}
tasks:
- name: Clean up resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
state: absent
force: yes

Here are some key notes to consider when working with the sample playbook:
Replace the {{ resource_group_name }} placeholder with the name of your resource group.
All resources within the specified resource group will be deleted.
Run the playbook using the ansible-playbook command:

ansible-playbook cleanup.yml

Next steps
Tutorial: Configure Azure Active Directory in AKS using Ansible
Tutorial: Configure kubenet networking in Azure
Kubernetes Service (AKS) using Ansible
5/7/2019 • 6 minutes to read • Edit Online

IMPORTANT
Ansible 2.8 (or later) is required to run the sample playbooks in this article.

Azure Kubernetes Service (AKS ) makes it simple to deploy a managed Kubernetes cluster in Azure. AKS reduces
the complexity and operational overhead of managing Kubernetes by offloading much of that responsibility to
Azure. As a hosted Kubernetes service, Azure handles critical tasks like health monitoring and maintenance for you.
The Kubernetes masters are managed by Azure. You only manage and maintain the agent nodes. As a managed
Kubernetes service, AKS is free - you pay only for the agent nodes within your clusters; not for the masters.
Using AKS, you can deploy a cluster using the following network models:
Kubenet networking - Network resources are typically created and configured as the AKS cluster is deployed.
Azure Container Networking Interface (CNI) networking - AKS cluster is connected to existing virtual network
resources and configurations.
For more information about networking to your applications in AKS, see Network concepts for applications in AKS.
In this tutorial, Ansible is used to:
Create an AKS cluster
Configure Azure kubenet networking

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Azure service principal: Create a service principal, making note of the following values: appId,
displayName, password, and tenant.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.

Create a virtual network and subnet


The playbook code in this section creates the following Azure resources:
Virtual network
Subnet within the virtual network
Save the following playbook as vnet.yml :
- name: Create vnet
azure_rm_virtualnetwork:
resource_group: "{{ resource_group }}"
name: "{{ name }}"
address_prefixes_cidr:
- 10.0.0.0/8

- name: Create subnet


azure_rm_subnet:
resource_group: "{{ resource_group }}"
name: "{{ name }}"
address_prefix_cidr: 10.240.0.0/16
virtual_network_name: "{{ name }}"
register: subnet

Create an AKS cluster in the virtual network


The playbook code in this section creates an AKS cluster within a virtual network.
Save the following playbook as aks.yml :

- name: List supported kubernetes version from Azure


azure_rm_aks_version:
location: "{{ location }}"
register: versions

- name: Create AKS cluster with vnet


azure_rm_aks:
resource_group: "{{ resource_group }}"
name: "{{ name }}"
dns_prefix: "{{ name }}"
kubernetes_version: "{{ versions.azure_aks_versions[-1] }}"
agent_pool_profiles:
- count: 3
name: nodepool1
vm_size: Standard_D2_v2
vnet_subnet_id: "{{ vnet_subnet_id }}"
linux_profile:
admin_username: azureuser
ssh_key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
service_principal:
client_id: "{{ lookup('ini', 'client_id section=default file=~/.azure/credentials') }}"
client_secret: "{{ lookup('ini', 'secret section=default file=~/.azure/credentials') }}"
network_profile:
network_plugin: kubenet
pod_cidr: 192.168.0.0/16
docker_bridge_cidr: 172.17.0.1/16
dns_service_ip: 10.0.0.10
service_cidr: 10.0.0.0/16
register: aks

Here are some key notes to consider when working with the sample playbook:
Use azure_rm_aks_version module to find the supported version.
The vnet_subnet_id is the subnet created in the previous section.
The network_profile defines the properties for the kubenet network plugin.
The service_cidr is used to assign internal services in the AKS cluster to an IP address. This IP address
range should be an address space that isn't used elsewhere in your network.
The dns_service_ip address should be the ".10" address of your service IP address range.
The pod_cidr should be a large address space that isn't in use elsewhere in your network environment. The
address range must be large enough to accommodate the number of nodes that you expect to scale up to.
You can't change this address range once the cluster is deployed.
The pod IP address range is used to assign a /24 address space to each node in the cluster. In the following
example, the pod_cidr of 192.168.0.0/16 assigns the first node 192.168.0.0/24, the second node
192.168.1.0/24, and the third node 192.168.2.0/24.
As the cluster scales or upgrades, Azure continues to assign a pod IP address range to each new node.
The playbook loads ssh_key from ~/.ssh/id_rsa.pub . If you modify it, use the single-line format - starting
with "ssh-rsa" (without the quotes).
The client_id and client_secret values are loaded from ~/.azure/credentials , which is the default
credential file. You can set these values to your service principal or load these values from environment
variables:

client_id: "{{ lookup('env', 'AZURE_CLIENT_ID') }}"


client_secret: "{{ lookup('env', 'AZURE_SECRET') }}"

Associate the network resources


When you create an AKS cluster, a network security group and route table are created. These resources are
managed by AKS and updated when you create and expose services. Associate the network security group and
route table with your virtual network subnet as follows.
Save the following playbook as associate.yml .

- name: Get route table


azure_rm_routetable_facts:
resource_group: "{{ node_resource_group }}"
register: routetable

- name: Get network security group


azure_rm_securitygroup_facts:
resource_group: "{{ node_resource_group }}"
register: nsg

- name: Parse subnet id


set_fact:
subnet_name: "{{ vnet_subnet_id | regex_search(subnet_regex, '\\1') }}"
subnet_rg: "{{ vnet_subnet_id | regex_search(rg_regex, '\\1') }}"
subnet_vn: "{{ vnet_subnet_id | regex_search(vn_regex, '\\1') }}"
vars:
subnet_regex: '/subnets/(.+)'
rg_regex: '/resourceGroups/(.+?)/'
vn_regex: '/virtualNetworks/(.+?)/'

- name: Associate network resources with the node subnet


azure_rm_subnet:
name: "{{ subnet_name[0] }}"
resource_group: "{{ subnet_rg[0] }}"
virtual_network_name: "{{ subnet_vn[0] }}"
security_group: "{{ nsg.ansible_facts.azure_securitygroups[0].id }}"
route_table: "{{ routetable.route_tables[0].id }}"

Here are some key notes to consider when working with the sample playbook:
The node_resource_group is the resource group name in which the AKS nodes are created.
The vnet_subnet_id is the subnet created in previous section.

Run the sample playbook


This section lists the complete sample playbook that calls the tasks creating in this article.
Save the following playbook as aks-kubenet.yml :

---
- hosts: localhost
vars:
resource_group: aksansibletest
name: aksansibletest
location: eastus
tasks:
- name: Ensure resource group exist
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"

- name: Create vnet


include_tasks: vnet.yml

- name: Create AKS


vars:
vnet_subnet_id: "{{ subnet.state.id }}"
include_tasks: aks.yml

- name: Associate network resources with the node subnet


vars:
vnet_subnet_id: "{{ subnet.state.id }}"
node_resource_group: "{{ aks.node_resource_group }}"
include_tasks: associate.yml

- name: Get details of the AKS


azure_rm_aks_facts:
name: "{{ name }}"
resource_group: "{{ resource_group }}"
show_kubeconfig: user
register: output

- name: Show AKS cluster detail


debug:
var: output.aks[0]

In the vars section, make the following changes:


For the resource_group key, change the aksansibletest value to your resource group name.
For the name key, change the aksansibletest value to your AKS name.
For the Location key, change the eastus value to your resource group location.

Run the complete playbook using the ansible-playbook command:

ansible-playbook aks-kubenet.yml

Running the playbook shows results similar to the following output:

PLAY [localhost]

TASK [Gathering Facts]


ok: [localhost]
TASK [Ensure resource group exist]
ok: [localhost]

TASK [Create vnet]


included: /home/devops/aks-kubenet/vnet.yml for localhost

TASK [Create vnet]


ok: [localhost]

TASK [Create subnet]


ok: [localhost]

TASK [Create AKS]


included: /home/devops/aks-kubenet/aks.yml for localhost

TASK [List supported kubernetes version from Azure]


[WARNING]: Azure API profile latest does not define an entry for
ContainerServiceClient

ok: [localhost]

TASK [Create AKS cluster with vnet]


changed: [localhost]

TASK [Associate network resources with the node subnet]


included: /home/devops/aks-kubenet/associate.yml for localhost

TASK [Get route table]


ok: [localhost]

TASK [Get network security group]


ok: [localhost]

TASK [Parse subnet id]


ok: [localhost]

TASK [Associate network resources with the node subnet]


changed: [localhost]

TASK [Get details of the AKS]


ok: [localhost]

TASK [Show AKS cluster detail]


ok: [localhost] => {
"output.aks[0]": {
"id": /subscriptions/BBBBBBBB-BBBB-BBBB-BBBB-
BBBBBBBBBBBB/resourcegroups/aksansibletest/providers/Microsoft.ContainerService/managedClusters/aksansibletest"
,
"kube_config": "apiVersion: ...",
"location": "eastus",
"name": "aksansibletest",
"properties": {
"agentPoolProfiles": [
{
"count": 3,
"maxPods": 110,
"name": "nodepool1",
"osDiskSizeGB": 100,
"osType": "Linux",
"storageProfile": "ManagedDisks",
"vmSize": "Standard_D2_v2",
"vnetSubnetID": "/subscriptions/BBBBBBBB-BBBB-BBBB-BBBB-
BBBBBBBBBBBB/resourceGroups/aksansibletest/providers/Microsoft.Network/virtualNetworks/aksansibletest/subnets/a
ksansibletest"
}
],
"dnsPrefix": "aksansibletest",
"enableRBAC": false,
"fqdn": "aksansibletest-cda2b56c.hcp.eastus.azmk8s.io",
"fqdn": "aksansibletest-cda2b56c.hcp.eastus.azmk8s.io",
"kubernetesVersion": "1.12.6",
"linuxProfile": {
"adminUsername": "azureuser",
"ssh": {
"publicKeys": [
{
"keyData": "ssh-rsa ..."
}
]
}
},
"networkProfile": {
"dnsServiceIP": "10.0.0.10",
"dockerBridgeCidr": "172.17.0.1/16",
"networkPlugin": "kubenet",
"podCidr": "192.168.0.0/16",
"serviceCidr": "10.0.0.0/16"
},
"nodeResourceGroup": "MC_aksansibletest_pcaksansibletest_eastus",
"provisioningState": "Succeeded",
"servicePrincipalProfile": {
"clientId": "AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA"
}
},
"type": "Microsoft.ContainerService/ManagedClusters"
}
}

PLAY RECAP
localhost : ok=15 changed=2 unreachable=0 failed=0 skipped=0 rescued=0
ignored=0

Clean up resources
When no longer needed, delete the resources created in this article.
Save the following code as cleanup.yml :

---
- hosts: localhost
vars:
resource_group: aksansibletest
tasks:
- name: Clean up resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
state: absent
force: yes

In the vars section, replace the {{ resource_group_name }} placeholder with the name of your resource group.
Run the playbook using the ansible-playbook command:

ansible-playbook cleanup.yml

Next steps
Tutorial - Configure Azure Container Networking Interface (CNI) networking in AKS using Ansible
Tutorial: Configure role-based access control (RBAC)
roles in Azure Kubernetes Service (AKS) using Ansible
7/10/2019 • 5 minutes to read • Edit Online

IMPORTANT
Ansible 2.8 (or later) is required to run the sample playbooks in this article.

Azure Kubernetes Service (AKS ) makes it simple to deploy a managed Kubernetes cluster in Azure. AKS reduces
the complexity and operational overhead of managing Kubernetes by offloading much of that responsibility to
Azure. As a hosted Kubernetes service, Azure handles critical tasks like health monitoring and maintenance for
you. The Kubernetes masters are managed by Azure. You only manage and maintain the agent nodes. As a
managed Kubernetes service, AKS is free - you pay only for the agent nodes within your clusters; not for the
masters.
AKS can be configured to use Azure Active Directory (AD ) for user authentication. Once configured, you use your
Azure AD authentication token to sign into the AKS cluster. The RBAC can be based on a user's identity or
directory group membership.
In this tutorial, Ansible is used to:
Create an Azure AD -enabled AKS cluster
Configure an RBAC role in the cluster

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Azure service principal: Create a service principal, making note of the following values: appId,
displayName, password, and tenant.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.
Install the RedHat OpenShift library - pip install openshift

Configure Azure AD for AKS authentication


When configuring Azure AD for AKS authentication, two Azure AD applications are configured. This operation
must be completed by an Azure tenant administrator. For more information, see Integrate Azure Active Directory
with AKS.
From the Azure tenant administrator, get the following values:
Server app secret
Server app ID
Client app ID
Tenant ID
These values are needed to run the sample playbook.

Create an AKS cluster


In this section, you create an AKS with the Azure AD application.
Here are some key notes to consider when working with the sample playbook:
The playbook loads ssh_key from ~/.ssh/id_rsa.pub . If you modify it, use the single-line format - starting
with "ssh-rsa" (without the quotes).
The client_id and client_secret values are loaded from ~/.azure/credentials , which is the default
credential file. You can set these values to your service principal or load these values from environment
variables:

client_id: "{{ lookup('env', 'AZURE_CLIENT_ID') }}"


client_secret: "{{ lookup('env', 'AZURE_SECRET') }}"

Save the following playbook as aks-create.yml :


- name: Create resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"

- name: List supported kubernetes version from Azure


azure_rm_aksversion_facts:
location: "{{ location }}"
register: versions

- name: Create AKS cluster with RBAC enabled


azure_rm_aks:
resource_group: "{{ resource_group }}"
name: "{{ name }}"
dns_prefix: "{{ name }}"
enable_rbac: yes
kubernetes_version: "{{ versions.azure_aks_versions[-1] }}"
agent_pool_profiles:
- count: 3
name: nodepool1
vm_size: Standard_D2_v2
linux_profile:
admin_username: azureuser
ssh_key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
service_principal:
client_id: "{{ lookup('ini', 'client_id section=default file=~/.azure/credentials') }}"
client_secret: "{{ lookup('ini', 'secret section=default file=~/.azure/credentials') }}"
aad_profile:
client_app_id: "{{ client_app_id }}"
server_app_id: "{{ server_app_id }}"
server_app_secret: "{{ server_app_secret }}"
tenant_id: "{{ app_tenant_id }}"
register: aks

- name: Save cluster user config


copy:
content: "{{ aks.kube_config }}"
dest: "aks-{{ name }}-kubeconfig-user"

- name: Get admin config of AKS


azure_rm_aks_facts:
resource_group: "{{ resource_group }}"
name: "{{ name }}"
show_kubeconfig: admin
register: aks

- name: Save the kubeconfig


copy:
content: "{{ aks.aks[0].kube_config }}"
dest: "aks-{{ name }}-kubeconfig"

Get the Azure AD Object ID


To create an RBAC binding, you first need to get the Azure AD Object ID.
1. Sign in to the Azure portal.
2. In the search field at the top of the page, enter Azure Active Directory .
3. Click Enter .
4. In the Manage menu, select Users.
5. In the name field, search for your account.
6. In the Name column, select the link to your account.
7. In the Identity section, copy the Object ID.

Create RBAC binding


In this section, you create a role binding or cluster role binding in AKS.
Save the following playbook as kube-role.yml :

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-admins
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: <your-aad-account>

Replace the &lt;your-aad-account> placeholder with your Azure AD tenant Object ID.
Save the following playbook - that deploys your new role to AKS - as aks-kube-deploy.yml :

- name: Apply role to AKS


k8s:
src: kube-role.yml
kubeconfig: "aks-{{ name }}-kubeconfig"

Run the sample playbook


This section lists the complete sample playbook that calls the tasks creating in this article.
Save the following playbook as aks-rbac.yml :
---
- hosts: localhost
vars:
resource_group: aksansibletest
name: aksansibletest
location: eastus
tasks:
- name: Ensure resource group exist
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"

- name: Create AKS


vars:
client_app_id: <client id>
server_app_id: <server id>
server_app_secret: <server secret>
app_tenant_id: <tenant id>
include_tasks: aks-create.yml

- name: Enable RBAC


include_tasks: aks-kube-deploy.yml

In the vars section, replace the following placeholders with your Azure AD information:
<client id>
<server id>
<server secret>
<tenant id>

Run the complete playbook using the ansible-playbook command:

ansible-playbook aks-rbac.yml

Verify the results


In this section, you use kubectl list the nodes creating in this article.
Enter the following command at a terminal prompt:

kubectl --kubeconfig aks-aksansibletest-kubeconfig-user get nodes

The command will direct you to an authentication page. Sign in with your Azure account.
Once authenticated, kubectl lists the nodes in similar fashion to the following results:

To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code XXXXXXXX
to authenticate.
NAME STATUS ROLES AGE VERSION
aks-nodepool1-33413200-0 Ready agent 49m v1.12.6
aks-nodepool1-33413200-1 Ready agent 49m v1.12.6
aks-nodepool1-33413200-2 Ready agent 49m v1.12.6

Clean up resources
When no longer needed, delete the resources created in this article.
Save the following code as cleanup.yml :

---
- hosts: localhost
vars:
name: aksansibletest
resource_group: aksansibletest
tasks:
- name: Clean up resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
state: absent
force: yes
- name: Remove kubeconfig
file:
state: absent
path: "aks-{{ name }}-kubeconfig"

Run the playbook using the ansible-playbook command:

ansible-playbook cleanup.yml

Next steps
Ansible on Azure
Tutorial: Configure a cluster in Azure HDInsight using
Ansible
5/7/2019 • 5 minutes to read • Edit Online

IMPORTANT
Ansible 2.8 (or later) is required to run the sample playbooks in this article.

Azure HDInsight is a Hadoop-based analytics service for processing data. HDInsight is an ETL (extract, transform,
load) tool used to work with big data - either structured or unstructured. HDInsight supports several cluster types
where each type supports a different set of components.
In this tutorial, Ansible is used to:
Create a storage account for HDInsight
Configure a HDInsight Spark cluster.
Resize a cluster
Delete a cluster

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.

Create a random postfix


The playbook code in this section creates a random postfix to use as part of the Azure HDInsight cluster name.

- hosts: localhost
vars:
resource_group: "{{ resource_group_name }}"
tasks:
- name: Prepare random prefix
set_fact:
rpfx: "{{ resource_group | hash('md5') | truncate(7, True, '') }}{{ 1000 | random }}"
run_once: yes

Create resource group


An Azure resource group is a logical container in which Azure resources are deployed and managed.
The playbook code in this section creates a resource group.
tasks:
- name: Create a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"

Create a storage account and retrieve key


An Azure storage account is used as the default storage for the HDInsight cluster.
The playbook code in this section retrieves the key used to access the storage account.

- name: Create storage account


azure_rm_storageaccount:
resource_group: "{{ resource_group }}"
name: "{{ storage_account_name }}"
account_type: Standard_LRS
location: eastus2

- name: Get storage account keys


azure_rm_resource:
api_version: '2018-07-01'
method: POST
resource_group: "{{ resource_group }}"
provider: storage
resource_type: storageaccounts
resource_name: "{{ storage_account_name }}"
subresource:
- type: listkeys
register: storage_output

- debug:
var: storage_output

Create an HDInsight Spark cluster


The playbook code in this section creates the Azure HDInsight cluster.
- name: Create instance of Cluster
azure_rm_hdinsightcluster:
resource_group: "{{ resource_group }}"
name: "{{ cluster_name }}"
location: eastus2
cluster_version: 3.6
os_type: linux
tier: standard
cluster_definition:
kind: spark
gateway_rest_username: http-user
gateway_rest_password: MuABCPassword!!@123
storage_accounts:
- name: "{{ storage_account_name }}.blob.core.windows.net"
is_default: yes
container: "{{ cluster_name }}"
key: "{{ storage_output['response']['keys'][0]['value'] }}"
compute_profile_roles:
- name: headnode
target_instance_count: 1
vm_size: Standard_D3
linux_profile:
username: sshuser
password: MuABCPassword!!@123
- name: workernode
target_instance_count: 1
vm_size: Standard_D3
linux_profile:
username: sshuser
password: MuABCPassword!!@123
- name: zookeepernode
target_instance_count: 3
vm_size: Medium
linux_profile:
username: sshuser
password: MuABCPassword!!@123

The instance creation can take several minutes to complete.

Resize the cluster


After cluster creation, the only setting you can change is the number of worker nodes.
The playbook code in this section increments the number of worker nodes by updating target_instance_count
within workernode .
- name: Resize cluster
azure_rm_hdinsightcluster:
resource_group: "{{ resource_group }}"
name: "{{ cluster_name }}"
location: eastus2
cluster_version: 3.6
os_type: linux
tier: standard
cluster_definition:
kind: spark
gateway_rest_username: http-user
gateway_rest_password: MuABCPassword!!@123
storage_accounts:
- name: "{{ storage_account_name }}.blob.core.windows.net"
is_default: yes
container: "{{ cluster_name }}"
key: "{{ storage_output['response']['keys'][0]['value'] }}"
compute_profile_roles:
- name: headnode
target_instance_count: 1
vm_size: Standard_D3
linux_profile:
username: sshuser
password: MuABCPassword!!@123
- name: workernode
target_instance_count: 2
vm_size: Standard_D3
linux_profile:
username: sshuser
password: MuABCPassword!!@123
- name: zookeepernode
target_instance_count: 3
vm_size: Medium
linux_profile:
username: sshuser
password: MuABCPassword!!@123
tags:
aaa: bbb
register: output

Delete the cluster instance


Billing for HDInsight clusters is prorated per minute.
The playbook code in this section deletes the cluster.

- name: Delete instance of Cluster


azure_rm_hdinsightcluster:
resource_group: "{{ resource_group }}"
name: "{{ cluster_name }}"
state: absent

Get the sample playbook


There are two ways to get the complete sample playbook:
Download the playbook and save it to hdinsight_create.yml .
Create a new file named hdinsight_create.yml and copy into it the following contents:

---
- hosts: localhost
vars:
vars:
resource_group: "{{ resource_group_name }}"
tasks:
- name: Prepare random prefix
set_fact:
rpfx: "{{ resource_group | hash('md5') | truncate(7, True, '') }}{{ 1000 | random }}"
run_once: yes

- hosts: localhost
#roles:
# - azure.azure_preview_modules
vars:
resource_group: "{{ resource_group_name }}"
location: eastus2
vnet_name: myVirtualNetwork
subnet_name: mySubnet
cluster_name: mycluster{{ rpfx }}
storage_account_name: mystorage{{ rpfx }}

tasks:
- name: Create a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"

- name: Create storage account


azure_rm_storageaccount:
resource_group: "{{ resource_group }}"
name: "{{ storage_account_name }}"
account_type: Standard_LRS
location: "{{ location }}"

- name: Get storage account keys


azure_rm_resource:
api_version: '2018-07-01'
method: POST
resource_group: "{{ resource_group }}"
provider: storage
resource_type: storageaccounts
resource_name: "{{ storage_account_name }}"
subresource:
- type: listkeys
register: storage_output
- debug:
var: storage_output

- name: Create instance of Cluster


azure_rm_hdinsightcluster:
resource_group: "{{ resource_group }}"
name: "{{ cluster_name }}"
location: "{{ location }}"
cluster_version: 3.6
os_type: linux
tier: standard
cluster_definition:
kind: spark
gateway_rest_username: http-user
gateway_rest_password: MuABCPassword!!@123
storage_accounts:
- name: "{{ storage_account_name }}.blob.core.windows.net"
is_default: yes
container: "{{ cluster_name }}"
key: "{{ storage_output['response']['keys'][0]['value'] }}"
compute_profile_roles:
- name: headnode
target_instance_count: 1
vm_size: Standard_D3
linux_profile:
username: sshuser
password: MuABCPassword!!@123
password: MuABCPassword!!@123
- name: workernode
target_instance_count: 1
vm_size: Standard_D3
linux_profile:
username: sshuser
password: MuABCPassword!!@123
- name: zookeepernode
target_instance_count: 3
vm_size: Medium
linux_profile:
username: sshuser
password: MuABCPassword!!@123

- name: Resize cluster


azure_rm_hdinsightcluster:
resource_group: "{{ resource_group }}"
name: "{{ cluster_name }}"
location: "{{ location }}"
cluster_version: 3.6
os_type: linux
tier: standard
cluster_definition:
kind: spark
gateway_rest_username: http-user
gateway_rest_password: MuABCPassword!!@123
storage_accounts:
- name: "{{ storage_account_name }}.blob.core.windows.net"
is_default: yes
container: "{{ cluster_name }}"
key: "{{ storage_output['response']['keys'][0]['value'] }}"
compute_profile_roles:
- name: headnode
target_instance_count: 1
vm_size: Standard_D3
linux_profile:
username: sshuser
password: MuABCPassword!!@123
- name: workernode
target_instance_count: 2
vm_size: Standard_D3
linux_profile:
username: sshuser
password: MuABCPassword!!@123
- name: zookeepernode
target_instance_count: 3
vm_size: Medium
linux_profile:
username: sshuser
password: MuABCPassword!!@123
tags:
aaa: bbb
register: output
- debug:
var: output

- name: Assert the state has changed


assert:
that:
- output.changed

- name: Delete instance of Cluster


azure_rm_hdinsightcluster:
resource_group: "{{ resource_group }}"
name: "{{ cluster_name }}"
state: absent
Run the sample playbook
In this section, run the playbook to test various features shown in this article.
Before running the playbook, make the following changes:
In the vars section, replace the {{ resource_group_name }} placeholder with the name of your resource group.

Run the playbook using the ansible-playbook command:

ansible-playbook hdinsight.yml

Clean up resources
When no longer needed, delete the resources created in this article.
Save the following code as cleanup.yml :

- hosts: localhost
vars:
resource_group: myResourceGroup
tasks:
- name: Delete a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
force_delete_nonempty: yes
state: absent

Run the playbook using the ansible-playbook command:

ansible-playbook cleanup.yml

Next steps
Ansible on Azure
Tutorial: Configure queues in Azure Service Bus using
Ansible
5/7/2019 • 3 minutes to read • Edit Online

IMPORTANT
Ansible 2.8 (or later) is required to run the sample playbooks in this article.

Azure Service Bus is an enterprise integration message broker. Service bus supports two types of communication:
queues and topics.
Queues support asynchronous communications between applications. An app sends messages to a queue, which
stores the messages. The receiving application then connects to and reads the messages from the queue.
Topics support the publish-subscribe pattern, which enables a one-to-many relationship between the message
originator and the messager receiver(s).
In this tutorial, Ansible is used to:
Create a queue
Create a SAS plicy
Retrieve namespace information
Retrieve queue information
Revoke the queue SAS policy

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.

Create the Service Bus queue


The sample playbook code creates the following resources:
Azure resource group
Service Bus namespace within the resource group
Service Bus queue with the namespace
Save the following playbook as servicebus_queue.yml :
---
- hosts: localhost
vars:
resource_group: servicebustest
location: eastus
namespace: servicebustestns
queue: servicebustestqueue
tasks:
- name: Ensure resource group exist
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"
- name: Create a namespace
azure_rm_servicebus:
name: "{{ namespace }}"
resource_group: "{{ resource_group }}"
- name: Create a queue
azure_rm_servicebusqueue:
name: "{{ queue }}"
namespace: "{{ namespace }}"
resource_group: "{{ resource_group }}"
register: queue
- debug:
var: queue

Run the playbook using the ansible-playbook command:

ansible-playbook servicebus_queue.yml

Create the SAS policy


A Shared Access Signature (SAS ) is a claims-based authorization mechanism using tokens.
The sample playbook code creates two SAS policies for a Service Bus queue with different privileges.
Save the following playbook as servicebus_queue_policy.yml :

---
- hosts: localhost
vars:
resource_group: servicebustest
namespace: servicebustestns
queue: servicebustestqueue
tasks:
- name: Create a policy with send and listen priviledge
azure_rm_servicebussaspolicy:
name: "{{ queue }}-policy"
queue: "{{ queue }}"
namespace: "{{ namespace }}"
resource_group: "{{ resource_group }}"
rights: listen_send
register: policy
- debug:
var: policy

Before running the playbook, see the following notes:


The rightsvalue represents the privilege a user has with the queue. Specify one of the following values:
manage , listen , send , or listen_send .

Run the playbook using the ansible-playbook command:


ansible-playbook servicebus_queue_policy.yml

Retrieve namespace information


The sample playbook code queries the namespace information.
Save the following playbook as servicebus_namespace_info.yml :

---
- hosts: localhost
vars:
resource_group: servicebustest
namespace: servicebustestns
tasks:
- name: Get a namespace's information
azure_rm_servicebus_facts:
type: namespace
name: "{{ namespace }}"
resource_group: "{{ resource_group }}"
show_sas_policies: yes
register: ns
- debug:
var: ns

Before running the playbook, see the following notes:


The show_sas_policies value indicates whether to show the SAS policies under the specified namespace. By
default, the value is False to avoid additional network overhead.

Run the playbook using the ansible-playbook command:

ansible-playbook servicebus_namespace_info.yml

Retrieve queue information


The sample playbook code queries queue information.
Save the following playbook as servicebus_queue_info.yml :

---
- hosts: localhost
vars:
resource_group: servicebustest
namespace: servicebustestns
queue: servicebustestqueue
tasks:
- name: Get a queue's information
azure_rm_servicebus_facts:
type: queue
name: "{{ queue }}"
namespace: "{{ namespace }}"
resource_group: "{{ resource_group }}"
show_sas_policies: yes
register: queue
- debug:
var: queue

Before running the playbook, see the following notes:


The show_sas_policies value indicates whether to show the SAS policies under the specified queue. By default,
this value is set to False to avoid additional network overhead.

Run the playbook using the ansible-playbook command:

ansible-playbook servicebus_queue_info.yml

Revoke the queue SAS policy


The sample playbook code deletes a queue SAS policy.
Save the following playbook as servicebus_queue_policy_delete.yml :

---
- hosts: localhost
vars:
resource_group: servicebustest
namespace: servicebustestns
queue: servicebustestqueue
tasks:
- name: Create a policy with send and listen priviledge
azure_rm_servicebussaspolicy:
name: "{{ queue }}-policy"
queue: "{{ queue }}"
namespace: "{{ namespace }}"
resource_group: "{{ resource_group }}"
state: absent

Run the playbook using the ansible-playbook command:

ansible-playbook servicebus_queue_policy_delete.yml

Clean up resources
When no longer needed, delete the resources created in this article.
Save the following code as cleanup.yml :
---
- hosts: localhost
vars:
resource_group: servicebustest
namespace: servicebustestns
queue: servicebustestqueue
tasks:
- name: Delete queue
azure_rm_servicebusqueue:
name: "{{ queue }}"
resource_group: "{{ resource_group }}"
namespace: "{{ namespace }}"
state: absent
- name: Delete namespace
azure_rm_servicebus:
name: "{{ namespace }}"
resource_group: "{{ resource_group }}"
state: absent
- name: Delete resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
state: absent
force_delete_nonempty: yes

Run the playbook using the ansible-playbook command:

ansible-playbook cleanup.yml

Next steps
Tutorial: Configure a topic in Azure Service Bus using Ansible
Tutorial: Configure topics in Azure Service Bus using
Ansible
5/7/2019 • 4 minutes to read • Edit Online

IMPORTANT
Ansible 2.8 (or later) is required to run the sample playbooks in this article.

Azure Service Bus is an enterprise integration message broker. Service bus supports two types of communication:
queues and topics.
Queues support asynchronous communications between applications. An app sends messages to a queue, which
stores the messages. The receiving application then connects to and reads the messages from the queue.
Topics support the publish-subscribe pattern, which enables a one-to-many relationship between the message
originator and the messager receiver(s).
In this tutorial, Ansible is used to:
Create a topic
Create a subscription
Create a SAS policy
Retrieve namespace information
Retrieve topic and subscription information
Revoke a SAS policy

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.

Create the Service Bus topic


The sample playbook code creates the following resources:
Azure resource group
Service Bus namespace within the resource group
Service Bus topic with the namespace
Save the following playbook as servicebus_topic.yml :
---
- hosts: localhost
vars:
resource_group: servicebustest
location: eastus
namespace: servicebustestns
topic: servicebustesttopic
tasks:
- name: Ensure resource group exist
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"
- name: Create a namespace
azure_rm_servicebus:
name: "{{ namespace }}"
resource_group: "{{ resource_group }}"
- name: Create a topic
azure_rm_servicebustopic:
name: "{{ topic }}"
namespace: "{{ namespace }}"
resource_group: "{{ resource_group }}"
register: topic
- debug:
var: topic

Run the playbook using the ansible-playbook command:

ansible-playbook servicebus_topic.yml

Create the subscription


The sample playbook code creates the subscription under a Service Bus topic. Azure Service Bus topics can have
multiple subscriptions. A subscriber to a topic can receives a copy of each message sent to the topic. Subscriptions
are named entities, which are durably created, but can optionally expire.

---
- hosts: localhost
vars:
resource_group: servicebustest
location: eastus
namespace: servicebustestns
topic: servicebustesttopic
subscription: servicebustestsubs
tasks:
- name: Create a subscription
azure_rm_servicebustopicsubscription:
name: "{{ subscription }}"
topic: "{{ topic }}"
namespace: "{{ namespace }}"
resource_group: "{{ resource_group }}"
register: subs
- debug:
var: subs

Save the following playbook as servicebus_subscription.yml :


Run the playbook using the ansible-playbook command:

ansible-playbook servicebus_subscription.yml
Create the SAS policy
A Shared Access Signature (SAS ) is a claims-based authorization mechanism using tokens.
The sample playbook code creates two SAS policies for a Service Bus queue with different privileges.
Save the following playbook as servicebus_topic_policy.yml :

---
- hosts: localhost
vars:
resource_group: servicebustest
namespace: servicebustestns
topic: servicebustesttopic
tasks:
- name: Create a policy with send and listen privilege
azure_rm_servicebussaspolicy:
name: "{{ topic }}-{{ item }}"
topic: "{{ topic }}"
namespace: "{{ namespace }}"
resource_group: "{{ resource_group }}"
rights: "{{ item }}"
with_items:
- send
- listen
register: policy
- debug:
var: policy

Run the playbook using the ansible-playbook command:

ansible-playbook servicebus_topic_policy.yml

Retrieve namespace information


The sample playbook code queries the namespace information.
Save the following playbook as servicebus_namespace_info.yml :

---
- hosts: localhost
vars:
resource_group: servicebustest
namespace: servicebustestns
tasks:
- name: Get a namespace's information
azure_rm_servicebus_facts:
type: namespace
name: "{{ namespace }}"
resource_group: "{{ resource_group }}"
show_sas_policies: yes
register: ns
- debug:
var: ns

Before running the playbook, see the following notes:


The show_sas_policies value indicates whether to show the SAS policies under the specified namespace. By
default, the value is False to avoid additional network overhead.
Run the playbook using the ansible-playbook command:

ansible-playbook servicebus_namespace_info.yml

Retrieve topic and subscription information


The sample playbook code queries for the following information:
Service Bus topic information
List of subscription details for the topic
Save the following playbook as servicebus_list.yml :

---
- hosts: localhost
vars:
resource_group: servicebustest
namespace: servicebustestns
topic: servicebustesttopic
tasks:
- name: Get a topic's information
azure_rm_servicebus_facts:
type: topic
name: "{{ topic }}"
namespace: "{{ namespace }}"
resource_group: "{{ resource_group }}"
show_sas_policies: yes
register: topic_fact
- name: "List subscriptions under topic {{ topic }}"
azure_rm_servicebus_facts:
type: subscription
topic: "{{ topic }}"
namespace: "{{ namespace }}"
resource_group: "{{ resource_group }}"
register: subs_fact
- debug:
var: "{{ item }}"
with_items:
- topic_fact.servicebuses[0]
- subs_fact.servicebuses

Before running the playbook, see the following notes:


The show_sas_policies value indicates whether to show the SAS policies under the specified queue. By default,
this value is set to False to avoid additional network overhead.
Run the playbook using the ansible-playbook command:

ansible-playbook servicebus_list.yml

Revoke the queue SAS policy


The sample playbook code deletes a queue SAS policy.
Save the following playbook as servicebus_queue_policy_delete.yml :
---
- hosts: localhost
vars:
resource_group: servicebustest
namespace: servicebustestns
topic: servicebustesttopic
tasks:
- name: Delete a policy
azure_rm_servicebussaspolicy:
name: "{{ topic }}-policy"
topic: "{{ topic }}"
namespace: "{{ namespace }}"
resource_group: "{{ resource_group }}"
state: absent

Run the playbook using the ansible-playbook command:

ansible-playbook servicebus_topic_policy_delete.yml

Clean up resources
When no longer needed, delete the resources created in this article.
Save the following code as cleanup.yml :

---
- hosts: localhost
vars:
resource_group: servicebustest
namespace: servicebustestns
topic: servicebustesttopic
subscription: servicebustestsubs
tasks:
- name: Delete subscription
azure_rm_servicebustopicsubscription:
name: "{{ subscription }}"
topic: "{{ topic }}"
resource_group: "{{ resource_group }}"
namespace: "{{ namespace }}"
state: absent
- name: Delete topic
azure_rm_servicebustopic:
name: "{{ topic }}"
resource_group: "{{ resource_group }}"
namespace: "{{ namespace }}"
state: absent
- name: Delete namespace
azure_rm_servicebus:
name: "{{ namespace }}"
resource_group: "{{ resource_group }}"
state: absent
- name: Delete resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
state: absent
force_delete_nonempty: yes

Run the playbook using the ansible-playbook command:

ansible-playbook cleanup.yml
Next steps
Ansible on Azure
Tutorial: Configure databases in Azure Database for
MySQL using Ansible
5/7/2019 • 5 minutes to read • Edit Online

IMPORTANT
Ansible 2.7 (or later) is required to run the sample playbooks in this article.

Azure Database for MySQL is a relational database service based on the MySQL Community Edition. Azure
Database for MySQL enables you to manage MySQL databases in your web apps.
In this tutorial, Ansible is used to:
Create a MySql server
Create a MySql database
Configure a filewall rule so that an external app can connect to your server
Connect to your MySql server from the Azure cloud shell
Query your available MySQL servers
List all databases in your connected servers

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.

Create a resource group


The playbook code in this section creates an Azure resource group. A resource group is a logical container in which
Azure resources are deployed and managed.
Save the following playbook as rg.yml :

- hosts: localhost
vars:
resource_group: myResourceGroup
location: eastus
tasks:
- name: Create a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"

Before running the playbook, see the following notes:


A resource group named myResourceGroup is created.
The resource group is created in the eastus location:
Run the playbook using the ansible-playbook command:

ansible-playbook rg.yml

Create a MySQL server and database


The playbook code in this section creates a MySQL server and an Azure Database for MySQL instance. The new
MySQL server is a Gen 5 Basic Purpose server with one vCore and is named mysqlserveransible . The database
instance is named mysqldbansible .
For more information about pricing tiers, see Azure Database for MySQL pricing tiers.
Save the following playbook as mysql_create.yml :

- hosts: localhost
vars:
resource_group: myResourceGroup
location: eastus
mysqlserver_name: mysqlserveransible
mysqldb_name: mysqldbansible
admin_username: mysqladmin
admin_password: <server_admin_password>
tasks:
- name: Create MySQL Server
azure_rm_mysqlserver:
resource_group: "{{ resource_group }}"
name: "{{ mysqlserver_name }}"
sku:
name: B_Gen5_1
tier: Basic
location: "{{ location }}"
version: 5.6
enforce_ssl: True
admin_username: "{{ admin_username }}"
admin_password: "{{ admin_password }}"
storage_mb: 51200
- name: Create instance of MySQL Database
azure_rm_mysqldatabase:
resource_group: "{{ resource_group }}"
server_name: "{{ mysqlserver_name }}"
name: "{{ mysqldb_name }}"

Before running the playbook, see the following notes:


In the vars section, the value of mysqlserver_name must be unique.
In the vars section, replace <server_admin_password> with a password.
Run the playbook using the ansible-playbook command:

ansible-playbook mysql_create.yml

Configure a firewall rule


A server-level firewall rule allows an external app to connect to your server through the Azure MySQL service
firewall. Examples of external apps are the mysql command-line tool and the MySQL Workbench.
The playbook code in this section creates a firewall rule named extenalaccess that allows connections from any
external IP address.
Save the following playbook as mysql_firewall.yml :

- hosts: localhost
vars:
resource_group: myResourceGroup
mysqlserver_name: mysqlserveransible
tasks:
- name: Open firewall to access MySQL Server from outside
azure_rm_resource:
api_version: '2017-12-01'
resource_group: "{{ resource_group }}"
provider: dbformysql
resource_type: servers
resource_name: "{{ mysqlserver_name }}"
subresource:
- type: firewallrules
name: externalaccess
body:
properties:
startIpAddress: "0.0.0.0"
endIpAddress: "255.255.255.255"

Before running the playbook, see the following notes:


In the vars section, replace startIpAddress and endIpAddress . Use the range of IP addresses that correspond to
the range from which you'll be connecting.
Connections to Azure Database for MySQL communicate over port 3306. If you try to connect from within a
corporate network, outbound traffic over port 3306 might not be allowed. In that case, you can't connect to your
server unless your IT department opens port 3306.
The playbook uses the azure_rm_resource module, which allows direct use of the REST API.
Run the playbook using the ansible-playbook command:

ansible-playbook mysql_firewall.yml

Connect to the server


In this section, you use the Azure cloud shell to connect to the server you created previously.
1. Select the Try It button in the following code:

mysql -h mysqlserveransible.mysql.database.azure.com -u mysqladmin@mysqlserveransible -p

2. At the prompt, enter the following command to query the server status:

mysql> status

If everything goes well, you see output similar to the following results:
demo@Azure:~$ mysql -h mysqlserveransible.mysql.database.azure.com -u mysqladmin@mysqlserveransible -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 65233
Server version: 5.6.39.0 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its


affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> status
--------------
mysql Ver 14.14 Distrib 5.7.23, for Linux (x86_64) using EditLine wrapper

Connection id: 65233


Current database:
Current user: mysqladmin@13.76.42.93
SSL: Cipher in use is AES256-SHA
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server version: 5.6.39.0 MySQL Community Server (GPL)
Protocol version: 10
Connection: mysqlserveransible.mysql.database.azure.com via TCP/IP
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8
TCP port: 3306
Uptime: 36 min 21 sec

Threads: 5 Questions: 559 Slow queries: 0 Opens: 96 Flush tables: 3 Open tables: 10 Queries per
second avg: 0.256
--------------

Query MySQL servers


The playbook code in this section queries MySQL servers in myResourceGroup and lists the databases on the found
servers.
Save the following playbook as mysql_query.yml :
- hosts: localhost
vars:
resource_group: myResourceGroup
mysqlserver_name: mysqlserveransible
tasks:
- name: Query MySQL Servers in current resource group
azure_rm_mysqlserver_facts:
resource_group: "{{ resource_group }}"
register: mysqlserverfacts

- name: Dump MySQL Server facts


debug:
var: mysqlserverfacts

- name: Query MySQL Databases


azure_rm_mysqldatabase_facts:
resource_group: "{{ resource_group }}"
server_name: "{{ mysqlserver_name }}"
register: mysqldatabasefacts

- name: Dump MySQL Database Facts


debug:
var: mysqldatabasefacts

Run the playbook using the ansible-playbook command:

ansible-playbook mysql_query.yml

After running the playbook, you see output similar to the following results:

"servers": [
{
"admin_username": "mysqladmin",
"enforce_ssl": false,
"fully_qualified_domain_name": "mysqlserveransible.mysql.database.azure.com",
"id": "/subscriptions/685ba005-af8d-4b04-8f16-
a7bf38b2eb5a/resourceGroups/myResourceGroup/providers/Microsoft.DBforMySQL/servers/mysqlserveransible",
"location": "eastus",
"name": "mysqlserveransible",
"resource_group": "myResourceGroup",
"sku": {
"capacity": 1,
"family": "Gen5",
"name": "B_Gen5_1",
"tier": "Basic"
},
"storage_mb": 5120,
"user_visible_state": "Ready",
"version": "5.6"
}
]

You also see the following output for the MySQL database:
"databases": [
{
"charset": "utf8",
"collation": "utf8_general_ci",
"name": "information_schema",
"resource_group": "myResourceGroup",
"server_name": "mysqlserveransible"
},
{
"charset": "latin1",
"collation": "latin1_swedish_ci",
"name": "mysql",
"resource_group": "myResourceGroup",
"server_name": "mysqlserveransibler"
},
{
"charset": "latin1",
"collation": "latin1_swedish_ci",
"name": "mysqldbansible",
"resource_group": "myResourceGroup",
"server_name": "mysqlserveransible"
},
{
"charset": "utf8",
"collation": "utf8_general_ci",
"name": "performance_schema",
"resource_group": "myResourceGroup",
"server_name": "mysqlserveransible"
}
]

Clean up resources
When no longer needed, delete the resources created in this article.
Save the following playbook as cleanup.yml :

- hosts: localhost
vars:
resource_group: myResourceGroup
tasks:
- name: Delete a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
state: absent

Run the playbook using the ansible-playbook command:

ansible-playbook cleanup.yml

Next steps
Ansible on Azure
Tutorial: Configure Azure Cosmos DB accounts using
Ansible
5/7/2019 • 4 minutes to read • Edit Online

IMPORTANT
Ansible 2.8 (or later) is required to run the sample playbooks in this article.

Azure Cosmos DB is a database service that supports several database types. These databases types include
document, key-value, wide-column, and graph. Using Ansible, you can automate the deployment and configuration
of resources in your environment.
In this tutorial, Ansible is used to:
Create an account
Retrieve the account keys
Delete the account

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Azure service principal: Create a service principal, making note of the following values: appId,
displayName, password, and tenant.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.

Create a random postfix


The sample playbook snippet creates a random postfix. The postfix is used as part of the Azure Cosmos DB
account name.

- hosts: localhost
tasks:
- name: Prepare random postfix
set_fact:
rpfx: "{{ 1000 | random }}"
run_once: yes

Create resource group


The sample playbook snippet creates an Azure resource group. A resource group is a logical container in which
Azure resources are deployed and managed.
- name: Create a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"

Create virtual network and subnet


The following code creates a virtual network and subnet for the Azure Cosmos DB account:

- name: Create virtual network


azure_rm_virtualnetwork:
resource_group: "{{ resource_group }}"
name: "{{ vnet_name }}"
address_prefixes_cidr:
- 10.1.0.0/16
- 172.100.0.0/16
dns_servers:
- 127.0.0.1
- 127.0.0.3

- name: Add subnet


azure_rm_subnet:
name: "{{ subnet_name }}"
virtual_network_name: "{{ vnet_name }}"
resource_group: "{{ resource_group }}"
address_prefix_cidr: "10.1.0.0/24"

Create an Azure Cosmos DB account


The following code creates the Cosmos DB account:

- name: Create instance of Cosmos DB Account


azure_rm_cosmosdbaccount:
resource_group: "{{ resource_group }}"
name: "{{ cosmosdbaccount_name }}"
location: eastus
kind: global_document_db
geo_rep_locations:
- name: eastus
failover_priority: 0
- name: westus
failover_priority: 1
database_account_offer_type: Standard
is_virtual_network_filter_enabled: yes
virtual_network_rules:
- subnet:
resource_group: "{{ resource_group }}"
virtual_network_name: "{{ vnet_name }}"
subnet_name: "{{ subnet_name }}"
ignore_missing_vnet_service_endpoint: yes
enable_automatic_failover: yes

The account creation takes a few minutes to complete.

Retrieve the keys


The following code fetches the keys to use in your app.
- name: Get Cosmos DB Account facts with keys
azure_rm_cosmosdbaccount_facts:
resource_group: "{{ resource_group }}"
name: "{{ cosmosdbaccount_name }}"
retrieve_keys: all
register: output

- name: Display Cosmos DB Acccount facts output


debug:
var: output

Delete the Azure Cosmos DB account


Finally, the last snippet shows how to delete an Azure Cosmos DB account.

- name: Delete instance of Cosmos DB Account


azure_rm_cosmosdbaccount:
resource_group: "{{ resource_group }}"
name: "{{ cosmosdbaccount_name }}"
state: absent

Get the sample playbook


There are two ways to get the complete sample playbook:
Download the playbook and save it to cosmosdb.yml .
Create a new file named cosmosdb.yml and copy into it the following contents:

---
- hosts: localhost
tasks:
- name: Prepare random postfix
set_fact:
rpfx: "{{ 1000 | random }}"
run_once: yes

- hosts: localhost
# roles:
# - azure.azure_preview_modules
vars:
resource_group: "{{ resource_group_name }}"
location: eastus
vnet_name: myVirtualNetwork
subnet_name: mySubnet
cosmosdbaccount_name: cosmos{{ rpfx }}

tasks:
- name: Create a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"

- name: Create virtual network


azure_rm_virtualnetwork:
resource_group: "{{ resource_group }}"
name: "{{ vnet_name }}"
address_prefixes_cidr:
- 10.1.0.0/16
- 172.100.0.0/16
dns_servers:
- 127.0.0.1
- 127.0.0.3
- 127.0.0.3

- name: Add subnet


azure_rm_subnet:
name: "{{ subnet_name }}"
virtual_network_name: "{{ vnet_name }}"
resource_group: "{{ resource_group }}"
address_prefix_cidr: "10.1.0.0/24"

- name: Create instance of Cosmos DB Account


azure_rm_cosmosdbaccount:
resource_group: "{{ resource_group }}"
name: "{{ cosmosdbaccount_name }}"
location: eastus
kind: global_document_db
geo_rep_locations:
- name: eastus
failover_priority: 0
- name: westus
failover_priority: 1
database_account_offer_type: Standard
is_virtual_network_filter_enabled: yes
virtual_network_rules:
- subnet:
resource_group: "{{ resource_group }}"
virtual_network_name: "{{ vnet_name }}"
subnet_name: "{{ subnet_name }}"
ignore_missing_vnet_service_endpoint: yes
enable_automatic_failover: yes

- name: Get Cosmos DB Account facts with keys


azure_rm_cosmosdbaccount_facts:
resource_group: "{{ resource_group }}"
name: "{{ cosmosdbaccount_name }}"
retrieve_keys: all
register: output

- name: Display Cosmos DB Account facts output


debug:
var: output

- name: Delete instance of Cosmos DB Account


azure_rm_cosmosdbaccount:
resource_group: "{{ resource_group }}"
name: "{{ cosmosdbaccount_name }}"
state: absent

Run the sample playbook


In this section, run the playbook to test various features shown in this article.
Before running the playbook, make the following changes:
In the vars section, replace the {{ resource_group_name }} placeholder with the name of your resource group.
Ensure that the `cosmosdbaccount_name contains only lowercase characters and is globally unique.
Run the playbook using the ansible-playbook command:

ansible-playbook cosmosdb.yml

Clean up resources
When no longer needed, delete the resources created in this article.
Save the following code as cleanup.yml :

- hosts: localhost
vars:
resource_group: myResourceGroup
tasks:
- name: Delete a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
force_delete_nonempty: yes
state: absent

Run the playbook using the ansible-playbook command:

ansible-playbook cleanup.yml

Next steps
Ansible on Azure
Tutorial: Configure caches in Azure Cache for Redis
using Ansible
5/7/2019 • 6 minutes to read • Edit Online

IMPORTANT
Ansible 2.8 (or later) is required to run the sample playbooks in this article.

Azure Cache for Redis is an open-source compatible service that allows you to build responsive apps by providing
fast access to data.
In this tutorial, Ansible is used to:
Create a cache
Scale a cache
Reboot a cache
Add a firewall rule to a cache
Delete a cache

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.

Create a cache
Create an Azure Cache for Redis within a new resource group.

- name: Create resource group


azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"

- name: Create Azure Cache for Redis


azure_rm_rediscache:
resource_group: "{{ resource_group }}"
name: "{{ redis_name }}"
sku:
name: basic
size: C1

It can take several minutes to provision a cache. The following code tells Ansible wait for the operation to complete:
- name: Wait for Redis provisioning to complete
azure_rm_rediscache_facts:
resource_group: "{{ resource_group }}"
name: "{{ redis_name }}"
register: facts
until: "{{ facts.rediscaches[0]['provisioning_state'] == 'Succeeded' }}"
retries: 100
delay: 60

During the lengthy provisioning process, several "error" messages will be displayed. These messages can safely be
ignored. The important message is the last message. In the following example, there are many error messages until
the final ("ok") message.

FAILED - RETRYING: Get facts (100 retries left).


FAILED - RETRYING: Get facts (99 retries left).
FAILED - RETRYING: Get facts (98 retries left).
FAILED - RETRYING: Get facts (97 retries left).
FAILED - RETRYING: Get facts (96 retries left).
FAILED - RETRYING: Get facts (95 retries left).
FAILED - RETRYING: Get facts (94 retries left).
FAILED - RETRYING: Get facts (93 retries left).
FAILED - RETRYING: Get facts (92 retries left).
FAILED - RETRYING: Get facts (91 retries left).
ok: [localhost]

Scale the cache


Azure Cache for Redis has different cache offerings depending on your app's needs. These cache options provide
flexibility in the choice of cache size and features. If your app requirements change after the cache is created, you
can scale the cache as needed. For more information about scaling, see How to Scale Azure Cache for Redis.
The following sample code scales the cache to Standard:

- name: Scale up Azure Cache for Redis


azure_rm_rediscache:
resource_group: "{{ resource_group }}"
name: "{{ redis_name }}"
sku:
name: standard
size: C1

It can take several minutes to scale a cache. The following code tells Ansible wait for the operation to complete:

- name: Wait for Redis scaling up to complete


azure_rm_rediscache_facts:
resource_group: "{{ resource_group }}"
name: "{{ redis_name }}"
register: facts
until: "{{ facts.rediscaches[0]['provisioning_state'] == 'Succeeded' }}"
retries: 100
delay: 60

Similar to the task to provision Azure Cache for Redis, output like the following message is normal:

**FAILED - RETRYING: Get facts (100 retries left)** is normal.


Reboot the cache
The following code reboots the cache created in previous sections.

- name: Reboot Azure Cache for Redis


azure_rm_rediscache:
resource_group: "{{ resource_group }}"
name: "{{ redis_name }}"
reboot:
reboot_type: all

Add firewall rule


The following code adds a firewall rule to the cache:

- name: Add Firewall rule


azure_rm_rediscachefirewallrule:
resource_group: "{{ resource_group }}"
cache_name: "{{ redis_name }}"
name: rule1
start_ip_address: 168.1.1.1
end_ip_address: 168.1.1.4

Delete the cache


The following code deletes the cache:

- name: Delete Azure Cache for Redis


azure_rm_rediscache:
resource_group: "{{ resource_group }}"
name: "{{ redis_name }}"
state: absent

Get the sample playbook


There are two ways to get the complete sample playbook:
Download the playbook and save it to rediscache.yml .
Create a new file named rediscache.yml and copy into it the following contents:

- name: Manage Azure Cache for Redis


hosts: localhost
connection: local
vars:
resource_group: "{{ resource_group_name }}"
redis_name: "redis{{ resource_group_name }}"
location: eastus2

roles:
- azure.azure_preview_modules

tasks:
- name: Create resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"

- name: Create Azure Cache for Redis


azure_rm_rediscache:
resource_group: "{{ resource_group }}"
resource_group: "{{ resource_group }}"
name: "{{ redis_name }}"
sku:
name: basic
size: C1

- name: Wait for Redis provisioning to complete


azure_rm_rediscache_facts:
resource_group: "{{ resource_group }}"
name: "{{ redis_name }}"
register: facts
until: "{{ facts.rediscaches[0]['provisioning_state'] == 'Succeeded' }}"
retries: 100
delay: 60

- name: Scale up Azure Cache for Redis


azure_rm_rediscache:
resource_group: "{{ resource_group }}"
name: "{{ redis_name }}"
sku:
name: standard
size: C1

- name: Wait for Redis scaling up to complete


azure_rm_rediscache_facts:
resource_group: "{{ resource_group }}"
name: "{{ redis_name }}"
register: facts
until: "{{ facts.rediscaches[0]['provisioning_state'] == 'Succeeded' }}"
retries: 100
delay: 60

- name: Reboot Azure Cache for Redis


azure_rm_rediscache:
resource_group: "{{ resource_group }}"
name: "{{ redis_name }}"
reboot:
reboot_type: all

- name: Add Firewall rule


azure_rm_rediscachefirewallrule:
resource_group: "{{ resource_group }}"
cache_name: "{{ redis_name }}"
name: rule1
start_ip_address: 168.1.1.1
end_ip_address: 168.1.1.4

- name: Delete Azure Cache for Redis


azure_rm_rediscache:
resource_group: "{{ resource_group }}"
name: "{{ redis_name }}"
state: absent

Run the sample playbook


In this section, run the playbook to test various features shown in this article.
In the vars section, replace the {{ resource_group_name }} placeholder with the name of your resource group.
Run the playbook using the ansible-playbook command:

ansible-playbook rediscache.yml

The output looks similar to the following results:


TASK [create resource group]
Tuesday 12 March 2019 16:21:07 +0800 (0:00:00.054) 0:00:01.503
ok: [localhost]

TASK [Create Azure Cache for Redis]


Tuesday 12 March 2019 16:21:09 +0800 (0:00:01.950) 0:00:03.454
[WARNING]: Azure API profile latest does not define an entry for RedisManagementClient

changed: [localhost]

TASK [Dump host name]


Tuesday 12 March 2019 16:21:49 +0800 (0:00:40.125) 0:00:43.580
ok: [localhost] =>
output['host_name']: redis0312.redis.cache.windows.net

TASK [Get facts]


Tuesday 12 March 2019 16:21:49 +0800 (0:00:00.056) 0:00:43.636
[WARNING]: conditional statements should not include jinja2 templating delimiters such as {{ }} or {% %}.
Found: {{ facts.rediscaches[0]['provisioning_state'] == 'Succeeded' }}

FAILED - RETRYING: Get facts (100 retries left).


FAILED - RETRYING: Get facts (99 retries left).
FAILED - RETRYING: Get facts (98 retries left).
FAILED - RETRYING: Get facts (97 retries left).
FAILED - RETRYING: Get facts (96 retries left).
FAILED - RETRYING: Get facts (95 retries left).
FAILED - RETRYING: Get facts (94 retries left).
FAILED - RETRYING: Get facts (93 retries left).
FAILED - RETRYING: Get facts (92 retries left).
FAILED - RETRYING: Get facts (91 retries left).
FAILED - RETRYING: Get facts (90 retries left).
ok: [localhost]

TASK [Scale up Azure Cache for Redis]


Tuesday 12 March 2019 16:33:20 +0800 (0:11:31.296) 0:12:14.933
changed: [localhost]

TASK [Get facts]


Tuesday 12 March 2019 16:33:29 +0800 (0:00:09.164) 0:12:24.097
[WARNING]: conditional statements should not include jinja2 templating delimiters such as {{ }} or {% %}.
Found: {{ facts.rediscaches[0]['provisioning_state'] == 'Succeeded' }}

FAILED - RETRYING: Get facts (100 retries left).


FAILED - RETRYING: Get facts (99 retries left).
FAILED - RETRYING: Get facts (98 retries left).
FAILED - RETRYING: Get facts (97 retries left).
FAILED - RETRYING: Get facts (96 retries left).
FAILED - RETRYING: Get facts (95 retries left).
FAILED - RETRYING: Get facts (94 retries left).
FAILED - RETRYING: Get facts (93 retries left).
FAILED - RETRYING: Get facts (92 retries left).
FAILED - RETRYING: Get facts (91 retries left).
ok: [localhost]

TASK [Reboot Azure Cache for Redis]


Tuesday 12 March 2019 16:43:57 +0800 (0:10:27.740) 0:22:51.838
ok: [localhost]

TASK [Add Firewall rule]


Tuesday 12 March 2019 16:44:02 +0800 (0:00:05.432) 0:22:57.271
changed: [localhost]

TASK [Delete Azure Cache for Redis]


Tuesday 12 March 2019 16:44:08 +0800 (0:00:05.137) 0:23:02.409
changed: [localhost]

PLAY RECAP
localhost : ok=10 changed=4 unreachable=0 failed=0 skipped=1 rescued=0
ignored=0
ignored=0

Tuesday 12 March 2019 16:44:14 +0800 (0:00:06.217) 0:23:08.626

Clean up resources
When no longer needed, delete the resources created in this article.
Save the following code as cleanup.yml :

- hosts: localhost
vars:
resource_group: "{{ resource_group_name }}"
tasks:
- name: Delete a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
state: absent

In the vars section, replace the {{ resource_group_name }} placeholder with the name of your resource group.
Run the playbook using the ansible-playbook command:

ansible-playbook cleanup.yml

Next steps
Ansible on Azure
Tutorial: Configure dynamic inventories of your Azure
resources using Ansible
5/7/2019 • 5 minutes to read • Edit Online

Ansible can be used to pull inventory information from various sources (including cloud sources such as Azure)
into a dynamic inventory.
In this tutorial, Ansible is used to:
Configure two test virtual machines.
Tag one of the virtual machines
Install Nginx on the tagged virtual machines
Configure a dynamic inventory that includes the configured Azure resources

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Azure service principal: Create a service principal, making note of the following values: appId,
displayName, password, and tenant.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.

Create the test VMs


1. Sign in to the Azure portal.
2. Open Cloud Shell.
3. Create an Azure resource group to hold the virtual machines for this tutorial.

IMPORTANT
The Azure resource group you create in this step must have a name that is entirely lower-case. Otherwise, the
generation of the dynamic inventory will fail.

az group create --resource-group ansible-inventory-test-rg --location eastus

4. Create two Linux virtual machines on Azure using one of the following techniques:
Ansible playbook - The article, Create a basic virtual machine in Azure with Ansible illustrates how
to create a virtual machine from an Ansible playbook. If you use a playbook to define one or both of
the virtual machines, ensure that the SSH connection is used instead of a password.
Azure CLI - Issue each of the following commands in the Cloud Shell to create the two virtual
machines:
az vm create --resource-group ansible-inventory-test-rg \
--name ansible-inventory-test-vm1 \
--image UbuntuLTS --generate-ssh-keys

az vm create --resource-group ansible-inventory-test-rg \


--name ansible-inventory-test-vm2 \
--image UbuntuLTS --generate-ssh-keys

Tag a VM
You can use tags to organize your Azure resources by user-defined categories.
Enter the following az resource tag command to tag the virtual machine ansible-inventory-test-vm1 with the key
nginx :

az resource tag --tags nginx --id /subscriptions/<YourAzureSubscriptionID>/resourceGroups/ansible-inventory-


test-rg/providers/Microsoft.Compute/virtualMachines/ansible-inventory-test-vm1

Generate a dynamic inventory


Once you have your virtual machines defined (and tagged), it's time to generate the dynamic inventory.
Using Ansible version < 2.8
Ansible provides a Python script named azure_rm.py that generates a dynamic inventory of your Azure resources.
The following steps walk you through using the azure_rm.py script to connect to your two test Azure virtual
machines:
1. Use the GNU wget command to retrieve the azure_rm.py script:

wget https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/azure_rm.py

2. Use the chmod command to change the access permissions to the azure_rm.py script. The following
command uses the +x parameter to allow for execution (running) of the specified file ( azure_rm.py ):

chmod +x azure_rm.py

3. Use the ansible command to connect to your resource group:

ansible -i azure_rm.py ansible-inventory-test-rg -m ping

4. Once connected, you see results similar to the following output:


ansible-inventory-test-vm1 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}
ansible-inventory-test-vm2 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}

Ansible version >= 2.8


Starting with Ansible 2.8, Ansible provides an Azure dynamic-inventory plugin. The following steps walk you
through using the plugin:
1. The inventory plugin requires a configuration file. The configuration file must end in azure_rm and have an
extension of either yml or yaml . For this tutorial example, save the following playbook as myazure_rm.yml :

plugin: azure_rm
include_vm_resource_groups:
- ansible-inventory-test-rg
auth_source: auto

2. Run the following command to ping VMs in the resource group:

ansible all -m ping -i ./myazure_rm.yml

3. When running the preceding command, you could receive the following error:

Failed to connect to the host via ssh: Host key verification failed.

If you do receive the "host-key verification" error, add the following line to the Ansible configuration file. The
Ansible configuration file is located at /etc/ansible/ansible.cfg .

host_key_checking = False

4. When you run the playbook, you see results similar to the following output:

ansible-inventory-test-vm1_0324 : ok=1 changed=0 unreachable=0 failed=0 skipped=0


rescued=0 ignored=0
ansible-inventory-test-vm2_8971 : ok=1 changed=0 unreachable=0 failed=0 skipped=0
rescued=0 ignored=0

Enable the VM tag


Once you've set a tag, you need to "enable" that tag. One way to enable a tag is by exporting the tag to an
environment variable AZURE_TAGS via the export command:

export AZURE_TAGS=nginx

If you're using Ansible < 2.8, run the following command:


ansible -i azure_rm.py ansible-inventory-test-rg -m ping

If you're using Ansible >= 2.8, run the following command:

ansible all -m ping -i ./myazure_rm.yml

You now see only one virtual machine (the one whose tag matches the value exported into the AZURE_TAGS
environment variable):

ansible-inventory-test-vm1 | SUCCESS => {


"changed": false,
"failed": false,
"ping": "pong"
}

Set up Nginx on the tagged VM


The purpose of tags is to enable the ability to quickly and easily work with subgroups of your virtual machines. For
example, let's say you want to install Nginx only on virtual machines to which you've assigned a tag of nginx . The
following steps illustrate how easy that is to accomplish:
1. Create a file named nginx.yml :

code nginx.yml

2. Paste the following sample code into the editor:

---
- name: Install and start Nginx on an Azure virtual machine
hosts: all
become: yes
tasks:
- name: install nginx
apt: pkg=nginx state=installed
notify:
- start nginx

handlers:
- name: start nginx
service: name=nginx state=started

3. Save the file and exit the editor.


4. Run the playbook using the ansible-playbook command:
Ansible < 2.8:

ansible-playbook -i azure_rm.py nginx.yml

Ansible >= 2.8:

ansible-playbook -i ./myazure_rm.yml nginx.yml


5. After running the playbook, you see output similar to the following results:

PLAY [Install and start Nginx on an Azure virtual machine]

TASK [Gathering Facts]


ok: [ansible-inventory-test-vm1]

TASK [install nginx]


changed: [ansible-inventory-test-vm1]

RUNNING HANDLER [start nginx]


ok: [ansible-inventory-test-vm1]

PLAY RECAP
ansible-inventory-test-vm1 : ok=3 changed=1 unreachable=0 failed=0

Test Nginx installation


This section illustrates one technique to test that Nginx is installed on your virtual machine.
1. Use the az vm list-ip-addresses command to retrieve the IP address of the ansible-inventory-test-vm1
virtual machine. The returned value (the virtual machine's IP address) is then used as the parameter to the
SSH command to connect to the virtual machine.

ssh `az vm list-ip-addresses \


-n ansible-inventory-test-vm1 \
--query [0].virtualMachine.network.publicIpAddresses[0].ipAddress -o tsv`

2. While connected to the ansible-inventory-test-vm1 virtual machine, run the nginx -v command to
determine if Nginx is installed.

nginx -v

3. Once you run the nginx -v command, you see the Nginx version (second line) that indicates that Nginx is
installed.

tom@ansible-inventory-test-vm1:~$ nginx -v

nginx version: nginx/1.10.3 (Ubuntu)

tom@ansible-inventory-test-vm1:~$

4. Click the <Ctrl>D keyboard combination to disconnect the SSH session.


5. Doing the preceding steps for the ansible-inventory-test-vm2 virtual machine yields an informational
message indicating where you can get Nginx (which implies that you don't have it installed at this point):

tom@ansible-inventory-test-vm2:~$ nginx -v
The program 'nginx' can be found in the following packages:
* nginx-core
* nginx-extras
* nginx-full
* nginx-lightTry: sudo apt install <selected package>
tom@ansible-inventory-test-vm2:~$
Next steps
Quickstart: Configure Linux virtual machines in Azure using Ansible
Tutorial: Configure virtual machine scale sets in Azure
using Ansible
5/7/2019 • 5 minutes to read • Edit Online

IMPORTANT
Ansible 2.7 (or later) is required to run the sample playbooks in this article.

Azure virtual machine scale sets is an Azure feature that lets you configure a group of identical, load balanced
VMs. There's no additional cost to scale sets and they're built from virtual machines. You pay only for the
underlying compute resources such as the VM instances, load balancers, or Managed Disk storage. With scale sets,
the management and automation layers are provided to run and scale your applications. You could instead
manually create and manage individual VMs. However, there are two key benefits to using scale sets. They're built
into Azure and they automatically scale your virtual machines to meet application needs.
In this tutorial, Ansible is used to:
Configure the resources for a VM
Configure a scale set
Scale the scale set by increasing it's VM instances

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.

Configure a scale set


The playbook code in this section defines the following resources:
Resource group into which all of your resources will be deployed.
Virtual network in the 10.0.0.0/16 address space
Subnet within the virtual network
Public IP address that allows you to access resources across the Internet
Network security group that controls the flow of network traffic in and out of your scale set
Load balancer that distributes traffic across a set of defined VMs using load balancer rules
Virtual machine scale set that uses all the created resources
There are two ways to get the sample playbook:
Download the playbook and save it to vmss-create.yml .
Create a new file named vmss-create.yml and copy into it the following contents:

- hosts: localhost
vars:
vars:
resource_group: myResourceGroup
vmss_name: myScaleSet
vmss_lb_name: myScaleSetLb
location: eastus
admin_username: azureuser
admin_password: "{{ admin_password }}"
tasks:
- name: Create a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"
- name: Create virtual network
azure_rm_virtualnetwork:
resource_group: "{{ resource_group }}"
name: "{{ vmss_name }}"
address_prefixes: "10.0.0.0/16"
- name: Add subnet
azure_rm_subnet:
resource_group: "{{ resource_group }}"
name: "{{ vmss_name }}"
address_prefix: "10.0.1.0/24"
virtual_network: "{{ vmss_name }}"
- name: Create public IP address
azure_rm_publicipaddress:
resource_group: "{{ resource_group }}"
allocation_method: Static
name: "{{ vmss_name }}"
- name: Create Network Security Group that allows SSH
azure_rm_securitygroup:
resource_group: "{{ resource_group }}"
name: "{{ vmss_name }}"
rules:
- name: SSH
protocol: Tcp
destination_port_range: 22
access: Allow
priority: 1001
direction: Inbound

- name: Create a load balancer


azure_rm_loadbalancer:
name: "{{ vmss_lb_name }}"
location: "{{ location }}"
resource_group: "{{ resource_group }}"
public_ip: "{{ vmss_name }}"
probe_protocol: Tcp
probe_port: 8080
probe_interval: 10
probe_fail_count: 3
protocol: Tcp
load_distribution: Default
frontend_port: 80
backend_port: 8080
idle_timeout: 4
natpool_frontend_port_start: 50000
natpool_frontend_port_end: 50040
natpool_backend_port: 22
natpool_protocol: Tcp

- name: Create Scale Set


azure_rm_virtualmachinescaleset:
resource_group: "{{ resource_group }}"
name: "{{ vmss_name }}"
vm_size: Standard_DS1_v2
admin_username: "{{ admin_username }}"
admin_password: "{{ admin_password }}"
ssh_password_enabled: true
capacity: 2
virtual_network_name: "{{ vmss_name }}"
virtual_network_name: "{{ vmss_name }}"
subnet_name: "{{ vmss_name }}"
upgrade_policy: Manual
tier: Standard
managed_disk_type: Standard_LRS
os_disk_caching: ReadWrite
image:
offer: UbuntuServer
publisher: Canonical
sku: 16.04-LTS
version: latest
load_balancer: "{{ vmss_lb_name }}"
data_disks:
- lun: 0
disk_size_gb: 20
managed_disk_type: Standard_LRS
caching: ReadOnly
- lun: 1
disk_size_gb: 30
managed_disk_type: Standard_LRS
caching: ReadOnly

Before running the playbook, see the following notes:


In the vars section, replace the {{ admin_password }} placeholder with your own password.
Run the playbook using the ansible-playbook command:

ansible-playbook vmss-create.yml

After running the playbook, you see output similar to the following results:

PLAY [localhost]

TASK [Gathering Facts]


ok: [localhost]

TASK [Create a resource group]


changed: [localhost]

TASK [Create virtual network]


changed: [localhost]

TASK [Add subnet]


changed: [localhost]

TASK [Create public IP address]


changed: [localhost]

TASK [Create Network Security Group that allows SSH]


changed: [localhost]

TASK [Create a load balancer]


changed: [localhost]

TASK [Create Scale Set]


changed: [localhost]

PLAY RECAP
localhost : ok=8 changed=7 unreachable=0 failed=0
View the number of VM instances
The configured scale set currently has two instances. The following steps are used to confirm that value:
1. Sign in to the Azure portal.
2. Navigate to the scale set you configured.
3. You see the scale set name with the number of instances in parenthesis: Standard_DS1_v2 (2 instances)

4. You can also verify the number of instances with the Azure Cloud Shell by running the following command:

az vmss show -n myScaleSet -g myResourceGroup --query '{"capacity":sku.capacity}'

The results of running the Azure CLI command in Cloud Shell show that three instances now exist:

{
"capacity": 3,
}

Scale out a scale set


The playbook code in this section retrieves information about the scale set and changes its capacity from two to
three.
There are two ways to get the sample playbook:
Download the playbook and save it to vmss-scale-out.yml .
Create a new file named vmss-scale-out.yml and copy into it the following contents:

- hosts: localhost
vars:
resource_group: myResourceGroup
vmss_name: myScaleSet
tasks:
- name: Get scaleset info
azure_rm_virtualmachine_scaleset_facts:
resource_group: "{{ resource_group }}"
name: "{{ vmss_name }}"
format: curated
register: output_scaleset

- name: Dump scaleset info


debug:
var: output_scaleset

- name: Modify scaleset (change the capacity to 3)


set_fact:
body: "{{ output_scaleset.ansible_facts.azure_vmss[0] | combine({'capacity': 3}, recursive=True) }}"

- name: Update something in that scale set


azure_rm_virtualmachinescaleset: "{{ body }}"

Run the playbook using the ansible-playbook command:

ansible-playbook vmss-scale-out.yml

After running the playbook, you see output similar to the following results:
PLAY [localhost]

TASK [Gathering Facts]


ok: [localhost]

TASK [Get scaleset info]


ok: [localhost]

TASK [Dump scaleset info]


ok: [localhost] => {
"output_scaleset": {
"ansible_facts": {
"azure_vmss": [
{
......
}
]
},
"changed": false,
"failed": false
}
}

TASK [Modify scaleset (set upgradePolicy to Automatic and capacity to 3)]


ok: [localhost]

TASK [Update something in that scale set]


changed: [localhost]

PLAY RECAP
localhost : ok=5 changed=1 unreachable=0 failed=0

Verify the results


Verify your results of your work via the Azure portal:
1. Sign in to the Azure portal.
2. Navigate to the scale set you configured.
3. You see the scale set name with the number of instances in parenthesis: Standard_DS1_v2 (3 instances)

4. You can also verify the change with the Azure Cloud Shell by running the following command:

az vmss show -n myScaleSet -g myResourceGroup --query '{"capacity":sku.capacity}'

The results of running the Azure CLI command in Cloud Shell show that three instances now exist:

{
"capacity": 3,
}

Next steps
Tutorial: Deploy apps to virtual machine scale sets in Azure using Ansible
Tutorial: Deploy apps to virtual machine scale sets in
Azure using Ansible
5/7/2019 • 4 minutes to read • Edit Online

IMPORTANT
Ansible 2.7 (or later) is required to run the sample playbooks in this article.

Azure virtual machine scale sets is an Azure feature that lets you configure a group of identical, load balanced
VMs. There's no additional cost to scale sets and they're built from virtual machines. You pay only for the
underlying compute resources such as the VM instances, load balancers, or Managed Disk storage. With scale sets,
the management and automation layers are provided to run and scale your applications. You could instead
manually create and manage individual VMs. However, there are two key benefits to using scale sets. They're built
into Azure and they automatically scale your virtual machines to meet application needs.
In this tutorial, Ansible is used to:
Retrieve host information for a group of Azure VMs
Clone and build the sample app
Install the JRE (Java Runtime Environment) on a scale set
Deploy the Java application to a scale set

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.
Virtual machine scale set: If you don't already have a scale set, you can configure a scale set with Ansible.
git - git is used to download a Java sample used in this tutorial.
Java SE Development Kit (JDK) - The JDK is used to build the sample Java project.
Apache Maven - Apache Maven is used to build the sample Java project.

Get host information


The playbook code in this section retrieves host information for a group of virtual machines. The code gets the
public IP addresses and load balancer within a specified resource group and creates a host group named
scalesethosts in inventory.

Save the following sample playbook as get-hosts-tasks.yml :


- name: Get facts for all Public IPs within a resource groups
azure_rm_publicipaddress_facts:
resource_group: "{{ resource_group }}"
register: output_ip_address

- name: Get loadbalancer info


azure_rm_loadbalancer_facts:
resource_group: "{{ resource_group }}"
name: "{{ loadbalancer_name }}"
register: output

- name: Add all hosts


add_host:
groups: scalesethosts
hostname: "{{ output_ip_address.ansible_facts.azure_publicipaddresses[0].properties.ipAddress }}_{{
item.properties.frontendPort }}"
ansible_host: "{{ output_ip_address.ansible_facts.azure_publicipaddresses[0].properties.ipAddress }}"
ansible_port: "{{ item.properties.frontendPort }}"
ansible_ssh_user: "{{ admin_username }}"
ansible_ssh_pass: "{{ admin_password }}"
with_items:
- "{{ output.ansible_facts.azure_loadbalancers[0].properties.inboundNatRules }}"

Prepare an application for deployment


The playbook code in this section uses git to clone a Java sample project from GitHub and builds the project.
Save the following playbook as app.yml :

- hosts: localhost
vars:
repo_url: https://github.com/spring-guides/gs-spring-boot.git
workspace: ~/src/helloworld

tasks:
- name: Git Clone sample app
git:
repo: "{{ repo_url }}"
dest: "{{ workspace }}"

- name: Build sample app


shell: mvn package chdir="{{ workspace }}/complete"

Run the sample Ansible playbook with the following command:

ansible-playbook app.yml

After running the playbook, you see output similar to the following results:
PLAY [localhost]

TASK [Gathering Facts]


ok: [localhost]

TASK [Git Clone sample app]


changed: [localhost]

TASK [Build sample app]


changed: [localhost]

PLAY RECAP
localhost : ok=3 changed=2 unreachable=0 failed=0

Deploy the application to a scale set


The playbook code in this section is used to:
Install the JRE on a host group named saclesethosts
Deploy the Java application to a host group named saclesethosts

There are two ways to get the sample playbook:


Download the playbook and save it to vmss-setup-deploy.yml .
Create a new file named vmss-setup-deploy.yml and copy into it the following contents:

- hosts: localhost
vars:
resource_group: myResourceGroup
scaleset_name: myScaleSet
loadbalancer_name: myScaleSetLb
admin_username: azureuser
admin_password: "{{ admin_password }}"
tasks:
- include: get-hosts-tasks.yml

- name: Install JRE on a scale set


hosts: scalesethosts
become: yes
vars:
workspace: ~/src/helloworld
admin_username: azureuser

tasks:
- name: Install JRE
apt:
name: default-jre
update_cache: yes

- name: Copy app to Azure VM


copy:
src: "{{ workspace }}/complete/target/gs-spring-boot-0.1.0.jar"
dest: "/home/{{ admin_username }}/helloworld.jar"
force: yes
mode: 0755

- name: Start the application


shell: java -jar "/home/{{ admin_username }}/helloworld.jar" >/dev/null 2>&1 &
async: 5000
poll: 0
Before running the playbook, see the following notes:
In the vars section, replace the {{ admin_password }} placeholder with your own password.
To use the ssh connection type with passwords, install the sshpass program:
Ubuntu:

apt-get install sshpass

CentOS:

yum install sshpass

In some environments, you may see an error about using an SSH password instead of a key. If you do
receive that error, you can disable host key checking by adding the following line to
/etc/ansible/ansible.cfg or ~/.ansible.cfg :

[defaults]
host_key_checking = False

Run the playbook with the following command:

ansible-playbook vmss-setup-deploy.yml

The output from running the ansible-playbook command indicates that the sample Java application has been
installed to the host group of the scale set:
PLAY [localhost]

TASK [Gathering Facts]


ok: [localhost]

TASK [Get facts for all Public IPs within a resource groups]
ok: [localhost]

TASK [Get loadbalancer info]


ok: [localhost]

TASK [Add all hosts]


changed: [localhost] ...

PLAY [Install JRE on scale set]

TASK [Gathering Facts]


ok: [40.114.30.145_50000]
ok: [40.114.30.145_50003]

TASK [Copy app to Azure VM]


changed: [40.114.30.145_50003]
changed: [40.114.30.145_50000]

TASK [Start the application]


changed: [40.114.30.145_50000]
changed: [40.114.30.145_50003]

PLAY RECAP
40.114.30.145_50000 : ok=4 changed=3 unreachable=0 failed=0
40.114.30.145_50003 : ok=4 changed=3 unreachable=0 failed=0
localhost : ok=4 changed=1 unreachable=0 failed=0

Verify the results


Verify the results of your work by navigating to the URL of the load balancer for your scale set:

Next steps
Tutorial: Autoscale virtual machine scale sets in Azure using Ansible
Tutorial: Autoscale virtual machine scale sets in Azure
using Ansible
5/7/2019 • 4 minutes to read • Edit Online

IMPORTANT
Ansible 2.7 (or later) is required to run the sample playbooks in this article.

Azure virtual machine scale sets is an Azure feature that lets you configure a group of identical, load balanced
VMs. There's no additional cost to scale sets and they're built from virtual machines. You pay only for the
underlying compute resources such as the VM instances, load balancers, or Managed Disk storage. With scale sets,
the management and automation layers are provided to run and scale your applications. You could instead
manually create and manage individual VMs. However, there are two key benefits to using scale sets. They're built
into Azure and they automatically scale your virtual machines to meet application needs.
The feature of automatically adjusting the number of VM instances is called autoscale. The benefit of autoscale is
that it reduces the management overhead to monitor and optimize the performance of your application. Autoscale
can be configured in response to demand or on a defined schedule. Using Ansible, you can specify the autoscale
rules that define the acceptable performance for a positive customer experience.
In this tutorial, Ansible is used to:
Define an autoscale profile
Autoscale based on a recurring schedule
Autoscale based on app performance
Retrieve autoscale settings information
Disable an autoscale setting

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.
Virtual machine scale set: If you don't already have a scale set, you can configure a scale set with Ansible.

Autoscale based on a schedule


To enable autoscale on a scale set, you first define an autoscale profile. This profile defines the default, minimum,
and maximum scale set capacity. These limits let you control cost by not continually creating VM instances, and
balance acceptable performance with a minimum number of instances that remain in a scale-in event.
Ansible allows you to scale your scale sets on a specific date or recurring schedule.
The playbook code in this section increases the number of VM instances to three at 10:00 every Monday.
Save the following playbook as vmss-auto-scale.yml :

---
- hosts: localhost
vars:
resource_group: myResourceGroup
vmss_name: myScaleSet
name: autoscalesetting
tasks:
- name: Create autoscaling
azure_rm_autoscale:
resource_group: "{{ resource_group }}"
name: "{{ name }}"
target:
namespace: "Microsoft.Compute"
types: "virtualMachineScaleSets"
name: "{{ vmss_name }}"
enabled: true
profiles:
- count: '3'
min_count: '3'
max_count: '3'
name: Auto created scale condition
recurrence_timezone: Pacific Standard Time
recurrence_frequency: Week
recurrence_days:
- Monday
recurrence_mins:
- '0'
recurrence_hours:
- '10'

Run the playbook using the ansible-playbook command:

ansible-playbook vmss-auto-scale.yml

Autoscale based on performance data


If your application demand increases, the load on the VM instances in your scale sets increases. If this increased
load is consistent, rather than just a brief demand, you can configure autoscale rules to increase the number of VM
instances in the scale set. When these VM instances are created and your applications are deployed, the scale set
starts to distribute traffic to them through the load balancer. Ansible allows you to control what metrics to monitor,
such as CPU usage, disk usage, and app-load time. You can scale in and scale out in scale sets based on
performance metric thresholds, by a recurring schedule, or by a particular date.
The playbook code in this section checks the CPU workload for the previous 10 minutes at 18:00 every Monday.
Based on the CPU percentage metrics, the playbook does one of the following actions:
Scales out the number of VM instances to four
Scales in the number of VM instances to one
Save the following playbook as vmss-auto-scale-metrics.yml :

---
- hosts: localhost
vars:
resource_group: myResourceGroup
vmss_name: myScaleSet
name: autoscalesetting
tasks:
tasks:
- name: Get facts of the resource group
azure_rm_resourcegroup_facts:
name: "{{ resource_group }}"
register: rg

- name: Get scale set resource uri


set_fact:
vmss_id: "{{ rg.ansible_facts.azure_resourcegroups[0].id
}}/providers/Microsoft.Compute/virtualMachineScaleSets/{{ vmss_name }}"

- name: Create autoscaling


azure_rm_autoscale:
resource_group: "{{ resource_group }}"
name: "{{ name }}"
target: "{{ vmss_id }}"
enabled: true
profiles:
- count: '1'
max_count: '1'
min_count: '1'
name: 'This scale condition is executed when none of the other scale condition(s) match'
recurrence_days:
- Monday
recurrence_frequency: Week
recurrence_hours:
- 18
recurrence_mins:
- 0
recurrence_timezone: Pacific Standard Time
- count: '1'
min_count: '1'
max_count: '4'
name: Auto created scale condition
recurrence_days:
- Monday
recurrence_frequency: Week
recurrence_hours:
- 18
recurrence_mins:
- 0
recurrence_timezone: Pacific Standard Time
rules:
- cooldown: 5
direction: Increase
metric_name: Percentage CPU
metric_resource_uri: "{{ vmss_id }}"
operator: GreaterThan
statistic: Average
threshold: 70
time_aggregation: Average
time_grain: 1
time_window: 10
type: ChangeCount
value: '1'
- cooldown: 5
direction: Decrease
metric_name: Percentage CPU
metric_resource_uri: "{{ vmss_id }}"
operator: LessThan
statistic: Average
threshold: 30
time_aggregation: Average
time_grain: 1
time_window: 10
type: ChangeCount
value: '1'
Run the playbook using the ansible-playbook command:

ansible-playbook vmss-auto-scale-metrics.yml

Get autoscale settings information


The playbook code in this section uses the azure_rm_autoscale_facts module to retrieve the details of autoscale
setting.
Save the following playbook as vmss-auto-scale-get-settings.yml :

- hosts: localhost
vars:
resource_group: myResourceGroup
name: autoscalesetting
tasks:
- name: Retrieve autoscale settings information
azure_rm_autoscale_facts:
resource_group: "{{ resource_group }}"
name: "{{ name }}"
register: autoscale_query

- debug:
var: autoscale_query.autoscales[0]

Run the playbook using the ansible-playbook command:

ansible-playbook vmss-auto-scale-get-settings.yml

Disable autoscale settings


There are two ways to disable autoscale settings. One way is to change the enabled key from true to false . The
second way is to delete the setting.
The playbook code in this section deletes the autoscale setting.
Save the following playbook as vmss-auto-scale-delete-setting.yml :

- hosts: localhost
vars:
resource_group: myResourceGroup
name: autoscalesetting
tasks:
- name: Delete autoscaling
azure_rm_autoscale:
resource_group: "{{ resource_group }}"
name: "{{ name }}"
state: absent

Run the playbook using the ansible-playbook command:

vmss-auto-scale-delete-setting.yml

Next steps
Tutorial: Update custom image of Azure virtual machine scale sets using Ansible
Tutorial: Update the custom image of Azure virtual
machine scale sets using Ansible
5/7/2019 • 8 minutes to read • Edit Online

IMPORTANT
Ansible 2.8 (or later) is required to run the sample playbooks in this article.

Azure virtual machine scale sets is an Azure feature that lets you configure a group of identical, load balanced
VMs. There's no additional cost to scale sets and they're built from virtual machines. You pay only for the
underlying compute resources such as the VM instances, load balancers, or Managed Disk storage. With scale sets,
the management and automation layers are provided to run and scale your applications. You could instead
manually create and manage individual VMs. However, there are two key benefits to using scale sets. They're built
into Azure and they automatically scale your virtual machines to meet application needs.
After a VM is deployed, you configure the VM with the software your app needs. Instead of doing this
configuration task for each VM, you can create a custom image. A custom image is a snapshot of an existing VM
that includes any installed software. When you configure a scale set, you specify the image to use for that scale
set's VMs. By using a custom image, each VM instance is identically configured for your app. Sometimes, you may
need to update your scale set's custom image. That task is the focus of this tutorial.
In this tutorial, Ansible is used to:
Configure two VMs with HTTPD
Create a custom image from an existing VM
Create a scale set from an image
Update the custom image

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.

Configure two VMs


The playbook code in this section creates two virtual machines with HTTPD installed on both.
The index.html page for each VM displays a test string:
First VM displays the value Image A
Second VM displays the value Image B

This string is meant to mimic configuring each VM with different software.


There are two ways to get the sample playbook:
Download the playbook and save it to create_vms.yml .
Create a new file named create_vms.yml and copy into it the following contents:

- name: Create two VMs (A and B) with HTTPS


hosts: localhost
connection: local
vars:
vm_name: vmforimage
admin_username: testuser
admin_password: Pass123$$$abx!
location: eastus
tasks:
- name: Create a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"

- name: Create virtual network


azure_rm_virtualnetwork:
resource_group: "{{ resource_group }}"
name: "{{ vm_name }}"
address_prefixes: "10.0.0.0/16"

- name: Create subnets for VM A and B


azure_rm_subnet:
resource_group: "{{ resource_group }}"
virtual_network: "{{ vm_name }}"
name: "{{ vm_name }}"
address_prefix: "10.0.1.0/24"

- name: Create Network Security Group that allows HTTP


azure_rm_securitygroup:
resource_group: "{{ resource_group }}"
name: "{{ vm_name }}"
rules:
- name: HTTP
protocol: Tcp
destination_port_range: 80
access: Allow
priority: 1002
direction: Inbound

- name: Create public IP addresses for VM A and B


azure_rm_publicipaddress:
resource_group: "{{ resource_group }}"
allocation_method: Static
name: "{{ vm_name }}_{{ item }}"
loop:
- A
- B
register: pip_output

- name: Create virtual network inteface cards for VM A and B


azure_rm_networkinterface:
resource_group: "{{ resource_group }}"
name: "{{ vm_name }}_{{ item }}"
virtual_network: "{{ vm_name }}"
subnet: "{{ vm_name }}"
public_ip_name: "{{ vm_name }}_{{ item }}"
security_group: "{{ vm_name }}"
loop:
- A
- B

- name: Create VM A and B


azure_rm_virtualmachine:
resource_group: "{{ resource_group }}"
name: "{{ vm_name }}{{ item }}"
admin_username: "{{ admin_username }}"
admin_password: "{{ admin_password }}"
vm_size: Standard_B1ms
network_interfaces: "{{ vm_name }}_{{ item }}"
image:
offer: UbuntuServer
publisher: Canonical
sku: 16.04-LTS
version: latest
loop:
- A
- B

- name: Create VM Extension


azure_rm_virtualmachineextension:
resource_group: "{{ resource_group }}"
name: testVMExtension
virtual_machine_name: "{{ vm_name }}{{ item }}"
publisher: Microsoft.Azure.Extensions
virtual_machine_extension_type: CustomScript
type_handler_version: 2.0
auto_upgrade_minor_version: true
settings: {"commandToExecute": "sudo apt-get -y install apache2"}
loop:
- A
- B

- name: Create VM Extension


azure_rm_virtualmachineextension:
resource_group: "{{ resource_group }}"
name: testVMExtension
virtual_machine_name: "{{ vm_name }}{{ item }}"
publisher: Microsoft.Azure.Extensions
virtual_machine_extension_type: CustomScript
type_handler_version: 2.0
auto_upgrade_minor_version: true
settings: {"commandToExecute": "printf '<html><body><h1>Image {{ item }}</h1></body></html>' >>
index.html; sudo cp index.html /var/www/html/"}
loop:
- A
- B

- debug:
msg: "Public IP Address A: {{ pip_output.results[0].state.ip_address }}"

- debug:
msg: "Public IP Address B: {{ pip_output.results[1].state.ip_address }}"

Run the playbook using the ansible-playbook command, replacing myrg with your resource group name:

ansible-playbook create-vms.yml --extra-vars "resource_group=myrg"

Because of the debug sections of the playbook, the ansible-playbook command will print the IP address of each
VM. Copy these IP addresses for later use.
Connect to the two VMs
In this section, you connect to each VM. As mentioned in the previous section, the strings Image A and Image B
mimic having two distinct VMs with different configurations.
Using the IP addresses from the previous section, connect to both VMs:

Create images from each VM


At this point, you have two VMs with slightly different configurations (their index.html files).
The playbook code in this section creates a custom image for each VM:
image_vmforimageA - Custom image created for the VM that displays Image A on its home page.
image_vmforimageB - Custom image created for the VM that displays Image B on its home page.

There are two ways to get the sample playbook:


Download the playbook and save it to capture-images.yml .
Create a new file named capture-images.yml and copy into it the following contents:
- name: Capture VM Images
hosts: localhost
connection: local
vars:
vm_name: vmforimage
tasks:

- name: Stop and generalize VMs


azure_rm_virtualmachine:
resource_group: "{{ resource_group }}"
name: "{{ vm_name }}{{ item }}"
generalized: yes
loop:
- A
- B

- name: Create an images from a VMs


azure_rm_image:
resource_group: "{{ resource_group }}"
name: "image_{{ vm_name }}{{ item }}"
source: "{{ vm_name }}{{ item }}"
loop:
- A
- B

Run the playbook using the ansible-playbook command, replacing myrg with your resource group name:

ansible-playbook capture-images.yml --extra-vars "resource_group=myrg"

Create scale set using Image A


In this section, a playbook is used to configure the following Azure resources:
Public IP address
Load balancer
Scale set that references image_vmforimageA

There are two ways to get the sample playbook:


Download the playbook and save it to create-vmss.yml .
Create a new file named create-vmss.yml and copy into it the following contents:"
---
- hosts: localhost
vars:
vmss_name: vmsstest
location: eastus
admin_username: vmssadmin
admin_password: User123!!!abc
vm_name: vmforimage
image_name: "image_vmforimageA"

tasks:

- name: Create public IP address


azure_rm_publicipaddress:
resource_group: "{{ resource_group }}"
allocation_method: Static
name: "{{ vmss_name }}"
register: pip_output

- name: Create a load balancer


azure_rm_loadbalancer:
name: "{{ vmss_name }}lb"
location: "{{ location }}"
resource_group: "{{ resource_group }}"
public_ip: "{{ vmss_name }}"
probe_protocol: Tcp
probe_port: 80
probe_interval: 10
probe_fail_count: 3
protocol: Tcp
load_distribution: Default
frontend_port: 80
backend_port: 80
idle_timeout: 4
natpool_frontend_port_start: 50000
natpool_frontend_port_end: 50040
natpool_backend_port: 22
natpool_protocol: Tcp

- name: Create a scale set


azure_rm_virtualmachinescaleset:
resource_group: "{{ resource_group }}"
name: "{{ vmss_name }}"
vm_size: Standard_DS1_v2
admin_username: "{{ admin_username }}"
admin_password: "{{ admin_password }}"
ssh_password_enabled: true
capacity: 2
virtual_network_name: "{{ vm_name }}"
subnet_name: "{{ vm_name }}"
upgrade_policy: Manual
tier: Standard
managed_disk_type: Standard_LRS
os_disk_caching: ReadWrite
image:
name: "{{ image_name }}"
resource_group: "{{ resource_group }}"
load_balancer: "{{ vmss_name }}lb"

- debug:
msg: "Scale set public IP address: {{ pip_output.state.ip_address }}"

Run the playbook using the ansible-playbook command, replacing myrg with your resource group name:
ansible-playbook create-vmss.yml --extra-vars "resource_group=myrg"

Because of the debug section of the playbook, the ansible-playbook command will print the IP address of the
scale set. Copy this IP address for later use.

Connect to the scale set


In this section, you connect to the scale set.
Using the IP address from the previous section, connect to the scale set.
As mentioned in the previous section, the strings Image A and Image B mimic having two distinct VMs with
different configurations.
The scale set references the custom image named image_vmforimageA . Custom image image_vmforimageA was
created from the VM whose home page displays Image A .
As a result, you see a home page displaying Image A :

Leave your browser window open as you continue to the next section.

Change custom image in scale set and upgrade instances


The playbook code in this section changes the scale set's image - from image_vmforimageA to image_vmforimageB .
Also, all current virtual machines deployed by the scale set are updated.
There are two ways to get the sample playbook:
Download the playbook and save it to update-vmss-image.yml .
Create a new file named update-vmss-image.yml and copy into it the following contents:
- name: Update scale set image reference
hosts: localhost
connection: local
vars:
vmss_name: vmsstest
image_name: image_vmforimageB
admin_username: vmssadmin
admin_password: User123!!!abc
tasks:

- name: Update scale set - second image


azure_rm_virtualmachinescaleset:
resource_group: "{{ resource_group }}"
name: "{{ vmss_name }}"
vm_size: Standard_DS1_v2
admin_username: "{{ admin_username }}"
admin_password: "{{ admin_password }}"
ssh_password_enabled: true
capacity: 3
virtual_network_name: "{{ vmss_name }}"
subnet_name: "{{ vmss_name }}"
upgrade_policy: Manual
tier: Standard
managed_disk_type: Standard_LRS
os_disk_caching: ReadWrite
image:
name: "{{ image_name }}"
resource_group: "{{ resource_group }}"
load_balancer: "{{ vmss_name }}lb"

- name: List all of the instances


azure_rm_virtualmachinescalesetinstance_facts:
resource_group: "{{ resource_group }}"
vmss_name: "{{ vmss_name }}"
register: instances

- debug:
var: instances

- name: manually upgrade all the instances


azure_rm_virtualmachinescalesetinstance:
resource_group: "{{ resource_group }}"
vmss_name: "{{ vmss_name }}"
instance_id: "{{ item.instance_id }}"
latest_model: yes
with_items: "{{ instances.instances }}"

Run the playbook using the ansible-playbook command, replacing myrg with your resource group name:

ansible-playbook update-vmss-image.yml --extra-vars "resource_group=myrg"

Return to the browser and refresh the page.


You see that virtual machine's underlying custom image is updated.
Clean up resources
When no longer needed, delete the resources created in this article.
Save the following code as cleanup.yml :

- hosts: localhost
vars:
resource_group: myrg
tasks:
- name: Delete a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
force_delete_nonempty: yes
state: absent

Run the playbook using the ansible-playbook command:

ansible-playbook cleanup.yml

Next steps
Ansible on Azure
Tutorial: Configure Azure virtual network peering
using Ansible
5/7/2019 • 5 minutes to read • Edit Online

IMPORTANT
Ansible 2.8 (or later) is required to run the sample playbooks in this article.

Virtual network (VNet) peering allows you to seamlessly connect two Azure virtual networks. Once peered, the two
virtual networks appear as one for connectivity purposes.
Traffic is routed between VMs in the same virtual network through private IP addresses. Similarly, traffic between
VMs in a peered virtual network is routed through the Microsoft backbone infrastructure. As a result, VMs in
different virtual networks can communicate with each other.
In this tutorial, Ansible is used to:
Create two virtual networks
Peer the two virtual networks
Delete the peering between the two networks

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.

Create two resource groups


A resource group is a logical container in which Azure resources are deployed and managed.
The sample playbook code in this section is used to:
Create two resource groups

- name: Create a resource group


azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"
- name: Create secondary resource group
azure_rm_resourcegroup:
name: "{{ resource_group_secondary }}"
location: "{{ location }}"

Create the first virtual network


The sample playbook code in this section is used to:
Create a virtual network
Create a subnet within the virtual network

- name: Create first virtual network


azure_rm_virtualnetwork:
resource_group: "{{ resource_group }}"
name: "{{ vnet_name1 }}"
address_prefixes: "10.0.0.0/16"
- name: Add subnet
azure_rm_subnet:
resource_group: "{{ resource_group }}"
name: "{{ vnet_name1 }}"
address_prefix: "10.0.0.0/24"
virtual_network: "{{ vnet_name1 }}"

Create the second virtual network


The sample playbook code in this section is used to:
Create a virtual network
Create a subnet within the virtual network

- name: Ceate second virtual network


azure_rm_virtualnetwork:
resource_group: "{{ resource_group_secondary }}"
name: "{{ vnet_name2 }}"
address_prefixes: "10.1.0.0/16"
- name: Add subnet
azure_rm_subnet:
resource_group: "{{ resource_group }}"
name: "{{ vnet_name2 }}"
address_prefix: "10.1.0.0/24"
virtual_network: "{{ vnet_name2 }}"

Peer the two virtual networks


The sample playbook code in this section is used to:
Initialize virtual-network peering
Peer two previously created virtual networks
- name: Initial vnet peering
azure_rm_virtualnetworkpeering:
resource_group: "{{ resource_group }}"
name: "{{ peering_name }}"
virtual_network: "{{ vnet_name1 }}"
remote_virtual_network:
resource_group: "{{ resource_group_secondary }}"
name: "{{ vnet_name2 }}"
allow_virtual_network_access: true
allow_forwarded_traffic: true

- name: Connect vnet peering


azure_rm_virtualnetworkpeering:
resource_group: "{{ resource_group_secondary }}"
name: "{{ peering_name }}"
virtual_network: "{{ vnet_name2 }}"
remote_virtual_network:
resource_group: "{{ resource_group }}"
name: "{{ vnet_name1 }}"
allow_virtual_network_access: true
allow_forwarded_traffic: true

Delete the virtual network peering


The sample playbook code in this section is used to:
Delete the peering between the two previously created virtual networks

- name: Delete vnet peering


azure_rm_virtualnetworkpeering:
resource_group: "{{ resource_group }}"
name: "{{ peering_name }}"
virtual_network: "{{ vnet_name1 }}"
state: absent

Get the sample playbook


There are two ways to get the complete sample playbook:
Download the playbook and save it to vnet_peering.yml .
Create a new file named vnet_peering.yml and copy into it the following contents:

- hosts: localhost
tasks:
- name: Prepare random postfix
set_fact:
rpfx: "{{ 1000 | random }}"
run_once: yes

- name: Connect virtual networks with virtual network peering


hosts: localhost
connection: local
vars:
resource_group: "{{ resource_group_name }}"
resource_group_secondary: "{{ resource_group_name }}2"
vnet_name1: "myVnet{{ rpfx }}"
vnet_name2: "myVnet{{ rpfx }}2"
peering_name: peer1
location: eastus2
tasks:
- name: Create a resource group
azure_rm_resourcegroup:
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"
- name: Create secondary resource group
azure_rm_resourcegroup:
name: "{{ resource_group_secondary }}"
location: "{{ location }}"
- name: Create first virtual network
azure_rm_virtualnetwork:
resource_group: "{{ resource_group }}"
name: "{{ vnet_name1 }}"
address_prefixes: "10.0.0.0/16"
- name: Add subnet
azure_rm_subnet:
resource_group: "{{ resource_group }}"
name: "{{ vnet_name1 }}"
address_prefix: "10.0.0.0/24"
virtual_network: "{{ vnet_name1 }}"
- name: Ceate second virtual network
azure_rm_virtualnetwork:
resource_group: "{{ resource_group_secondary }}"
name: "{{ vnet_name2 }}"
address_prefixes: "10.1.0.0/16"
- name: Add subnet
azure_rm_subnet:
resource_group: "{{ resource_group }}"
name: "{{ vnet_name2 }}"
address_prefix: "10.1.0.0/24"
virtual_network: "{{ vnet_name2 }}"
- name: Initial vnet peering
azure_rm_virtualnetworkpeering:
resource_group: "{{ resource_group }}"
name: "{{ peering_name }}"
virtual_network: "{{ vnet_name1 }}"
remote_virtual_network:
resource_group: "{{ resource_group_secondary }}"
name: "{{ vnet_name2 }}"
allow_virtual_network_access: true
allow_forwarded_traffic: true

- name: Connect vnet peering


azure_rm_virtualnetworkpeering:
resource_group: "{{ resource_group_secondary }}"
name: "{{ peering_name }}"
virtual_network: "{{ vnet_name2 }}"
remote_virtual_network:
resource_group: "{{ resource_group }}"
name: "{{ vnet_name1 }}"
allow_virtual_network_access: true
allow_forwarded_traffic: true

- name: Delete vnet peering


azure_rm_virtualnetworkpeering:
resource_group: "{{ resource_group }}"
name: "{{ peering_name }}"
virtual_network: "{{ vnet_name1 }}"
state: absent

Run the sample playbook


The sample playbook code in this section is used to test various features shown throughout this tutorial.
Here are some key notes to consider when working with the sample playbook:
In the vars section, replace the {{ resource_group_name }} placeholder with the name of your resource group.
Run the playbook using the ansible-playbook command:

ansible-playbook vnet_peering.yml

After running the playbook, you see output similar to the following results:

PLAY [localhost]

TASK [Gathering Facts]


ok: [localhost]

TASK [Prepare random postfix]


ok: [localhost]

PLAY [Connect virtual networks with virtual network peering]

TASK [Gathering Facts]


ok: [localhost]

TASK [Create a resource group]


changed: [localhost]

TASK [Create secondary resource group]


changed: [localhost]

TASK [Create first virtual network]


changed: [localhost]

TASK [Add subnet]


changed: [localhost]

TASK [Ceate second virtual network]


changed: [localhost]

TASK [Add subnet]


changed: [localhost]

TASK [Initial vnet peering]


changed: [localhost]

TASK [Connect vnet peering]


changed: [localhost]

TASK [Delete vnet peering]


changed: [localhost]

PLAY RECAP
localhost : ok=12 changed=9 unreachable=0 failed=0 skipped=0 rescued=0
ignored=0

Clean up resources
When no longer needed, delete the resources created in this article.
The sample playbook code in this section is used to:
Delete the two resources groups created earlier
Save the following playbook as cleanup.yml :
- hosts: localhost
vars:
resource_group: "{{ resource_group_name-1 }}"
resource_group_secondary: "{{ resource_group_name-2 }}"
tasks:
- name: Delete a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
force_delete_nonempty: yes
state: absent

- name: Delete a resource group


azure_rm_resourcegroup:
name: "{{ resource_group_secondary }}"
force_delete_nonempty: yes
state: absent

Here are some key notes to consider when working with the sample playbook:
Replace the {{ resource_group_name-1 }} placeholder with the name of the first resource group created.
Replace the {{ resource_group_name-2 }} placeholder with the name of the second resource group created.
All resources within the two specified resource groups will be deleted.
Run the playbook using the ansible-playbook command:

ansible-playbook cleanup.yml

Next steps
Ansible on Azure
Tutorial: Configure Azure route tables using Ansible
5/7/2019 • 4 minutes to read • Edit Online

IMPORTANT
Ansible 2.8 (or later) is required to run the sample playbooks in this article.

Azure automatically routes traffic between Azure subnets, virtual networks, and on-premises networks. If you need
more control over your environment's routing, you can create a route table.
In this tutorial, Ansible is used to:
Create a route table Create a virtual network and subnet Associate a route table with a subnet Disassociate a route
table from a subnet Create and delete routes Query a route table Delete a route table

Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Install Ansible: Do one of the following options:
Install and configure Ansible on a Linux virtual machine
Configure Azure Cloud Shell and - if you don't have access to a Linux virtual machine - create a virtual
machine with Ansible.

Create a route table


The playbook code in this section creates a route table. For information on route-table limits, see Azure limits.
Save the following playbook as route_table_create.yml :

- hosts: localhost
vars:
route_table_name: myRouteTable
resource_group: myResourceGroup
tasks:
- name: Create a route table
azure_rm_routetable:
name: "{{ route_table_name }}"
resource_group: "{{ resource_group }}"

Run the playbook using the ansible-playbook command:

ansible-playbook route_table_create.yml

Associate a route table to a subnet


The playbook code in this section:
Creates a virtual network
Creates a subnet within the virtual network
Associates a route table to the subnet
Route tables aren't associated to virtual networks. Rather, route tables are associated with the subnet of a virtual
network.
The virtual network and route table must coexist in the same Azure location and subscription.
Subnets and route tables have a one-to-many relationship. A subnet can be defined with no associated route table
or one route table. Route tables can be associated with none, one, or many subnets.
Traffic from the subnet is routed based on:
routes defined within route tables
default routes
routes propagated from an on-premises network
The virtual network must be connected to an Azure virtual network gateway. The gateway can be ExpressRoute, or
VPN if using BGP with a VPN gateway.
Save the following playbook as route_table_associate.yml :

- hosts: localhost
vars:
subnet_name: mySubnet
virtual_network_name: myVirtualNetwork
route_table_name: myRouteTable
resource_group: myResourceGroup
tasks:
- name: Create virtual network
azure_rm_virtualnetwork:
name: "{{ virtual_network_name }}"
resource_group: "{{ resource_group }}"
address_prefixes_cidr:
- 10.1.0.0/16
- 172.100.0.0/16
dns_servers:
- 127.0.0.1
- 127.0.0.3
- name: Create a subnet with route table
azure_rm_subnet:
name: "{{ subnet_name }}"
virtual_network_name: "{{ virtual_network_name }}"
resource_group: "{{ resource_group }}"
address_prefix_cidr: "10.1.0.0/24"
route_table: "{ route_table_name }"

Run the playbook using the ansible-playbook command:

ansible-playbook route_table_associate.yml

Dissociate a route table from a subnet


The playbook code in this section dissociates a route table from a subnet.
When dissociating a route table from a subnet, set the route_table for the subnet to None .
Save the following playbook as route_table_dissociate.yml :
- hosts: localhost
vars:
subnet_name: mySubnet
virtual_network_name: myVirtualNetwork
resource_group: myResourceGroup
tasks:
- name: Dissociate a route table
azure_rm_subnet:
name: "{{ subnet_name }}"
virtual_network_name: "{{ virtual_network_name }}"
resource_group: "{{ resource_group }}"
address_prefix_cidr: "10.1.0.0/24"

Run the playbook using the ansible-playbook command:

ansible-playbook route_table_dissociate.yml

Create a route
The playbook code in this section a route within a route table.
Save the following playbook as route_create.yml :

- hosts: localhost
vars:
route_name: myRoute
route_table_name: myRouteTable
resource_group: myResourceGroup
tasks:
- name: Create route
azure_rm_route:
name: "{{ route_name }}"
resource_group: "{{ resource_group }}"
next_hop_type: virtual_network_gateway
address_prefix: "10.1.0.0/16"
route_table_name: "{{ route_table_name }}"

Before running the playbook, see the following notes:


virtual_network_gateway is defined as next_hop_type . For more information about how Azure selects routes,
see Routing overview.
address_prefix is defined as 10.1.0.0/16 . The prefix can't be duplicated within the route table.

Run the playbook using the ansible-playbook command:

ansible-playbook route_create.yml

Delete a route
The playbook code in this section deletes a route from a route table.
Save the following playbook as route_delete.yml :
- hosts: localhost
vars:
route_name: myRoute
route_table_name: myRouteTable
resource_group: myResourceGroup
tasks:
- name: Remove route
azure_rm_route:
name: "{{ route_name }}"
resource_group: "{{ resource_group }}"
route_table_name: "{{ route_table_name }}"
state: absent

Run the playbook using the ansible-playbook command:

ansible-playbook route_delete.yml

Get route table information


The playbook code in this section uses the Ansible module azure_rm_routetable_facts to retrieve route table
information.
Save the following playbook as route_table_facts.yml :

- hosts: localhost
vars:
route_table_name: myRouteTable
resource_group: myResourceGroup
tasks:
- name: Get route table information
azure_rm_routetable_facts:
resource_group: "{{ resource_group }}"
name: "{{ route_table_name }}"
register: query

- debug:
var: query.route_tables[0]

Run the playbook using the ansible-playbook command:

ansible-playbook route_table_facts.yml

Delete a route table


The playbook code in this section a route table.
When a route table is deleted, all of its routes are also deleted.
A route table can't be deleted if it's associated with a subnet. Dissociate the route table from any subnets before
attempting to delete the route table.
Save the following playbook as route_table_delete.yml :
- hosts: localhost
vars:
route_table_name: myRouteTable
resource_group: myResourceGroup
tasks:
- name: Create a route table
azure_rm_routetable:
name: "{{ route_table_name }}"
resource_group: "{{ resource_group }}"
state: absent

Run the playbook using the ansible-playbook command:

ansible-playbook route_table_delete.yml

Next steps
Ansible on Azure
Ansible module and version matrix
5/7/2019 • 6 minutes to read • Edit Online

Ansible includes a suite of modules for use in provisioning and configuring Azure resources. These resources
include virtual machines, scale sets, networking services, and container services. This article lists the various
Ansible modules for Azure and the Ansible versions in which they ship.

Ansible modules for Azure


The following modules can be executed directly on remote hosts or through playbooks.
These modules are available from the Ansible official release and from the following Microsoft playbook roles.

ANSIBLE
MODULE FOR
AZURE ANSIBLE 2.4 ANSIBLE 2.5 ANSIBLE 2.6 ANSIBLE 2.7 ANSIBLE 2.8 ANSIBLE ROLE

Compute

azure_rm_avai Yes Yes Yes Yes Yes Yes


labilityset

azure_rm_avai Yes Yes Yes Yes Yes Yes


labilityset_fact
s

azure_rm_depl Yes Yes Yes Yes Yes Yes


oyment

azure_rm_depl - - - - Yes Yes


oyment_facts

azure_rm_func Yes Yes Yes Yes Yes Yes


tionapp

azure_rm_func Yes Yes Yes Yes Yes Yes


tionapp_facts

azure_rm_ima - Yes Yes Yes Yes Yes


ge

azure_rm_ima - - - - Yes Yes


ge_facts

azure_rm_reso - - Yes Yes Yes Yes


urce

azure_rm_reso - - Yes Yes Yes Yes


urce_facts

azure_rm_reso Yes Yes Yes Yes Yes Yes


urcegroup
ANSIBLE
MODULE FOR
AZURE ANSIBLE 2.4 ANSIBLE 2.5 ANSIBLE 2.6 ANSIBLE 2.7 ANSIBLE 2.8 ANSIBLE ROLE

azure_rm_reso Yes Yes Yes Yes Yes Yes


urcegroup_fac
ts

azure_rm_virt Yes Yes Yes Yes Yes Yes


ualmachine

azure_rm_virt - - - Yes Yes Yes


ualmachine_fa
cts

azure_rm_virt Yes Yes Yes Yes Yes Yes


ualmachineext
ension

azure_rm_virt - - - - Yes Yes


ualmachineext
ension_facts

azure_rm_virt Yes Yes Yes Yes Yes Yes


ualmachineim
age_facts

azure_rm_virt Yes Yes Yes Yes Yes Yes


ualmachinesca
leset

azure_rm_virt Yes Yes Yes Yes Yes Yes


ualmachinesca
leset_facts

azure_rm_virt - - - - Yes Yes


ualmachinesca
lesetextension

azure_rm_virt - - - - Yes Yes


ualmachinesca
lesetextension
_facts

azure_rm_virt - - - - Yes Yes


ualmachinesca
lesetinstance

azure_rm_virt - - - - Yes Yes


ualmachinesca
lesetinstance_f
acts

Networking

azure_rm_app - - - Yes Yes Yes


gateway
ANSIBLE
MODULE FOR
AZURE ANSIBLE 2.4 ANSIBLE 2.5 ANSIBLE 2.6 ANSIBLE 2.7 ANSIBLE 2.8 ANSIBLE ROLE

azure_rm_app - - - - - Yes
gwroute

azure_rm_app - - - - - Yes
gwroute_facts

azure_rm_app - - - - - Yes
gwroutetable

azure_rm_app - - - - - Yes
gwroutetable_
facts

azure_rm_appl - - - - Yes Yes


icationsecurity
group

azure_rm_appl - - - - Yes Yes


icationsecurity
group_facts

azure_rm_cdn - - - - Yes Yes


endpoint

azure_rm_cdn - - - - Yes Yes


endpoint_fact
s

azure_rm_cdn - - - - Yes Yes


profile

azure_rm_cdn - - - - Yes Yes


profile_facts

azure_rm_dns Yes Yes Yes Yes Yes Yes


recordset

azure_rm_dns Yes Yes Yes Yes Yes Yes


recordset_fact
s

azure_rm_dns Yes Yes Yes Yes Yes Yes


zone

azure_rm_dns Yes Yes Yes Yes Yes Yes


zone_facts

azure_rm_load Yes Yes Yes Yes Yes Yes


balancer

azure_rm_load Yes Yes Yes Yes Yes Yes


balancer_facts
ANSIBLE
MODULE FOR
AZURE ANSIBLE 2.4 ANSIBLE 2.5 ANSIBLE 2.6 ANSIBLE 2.7 ANSIBLE 2.8 ANSIBLE ROLE

azure_rm_net Yes Yes Yes Yes Yes Yes


workinterface

azure_rm_net Yes Yes Yes Yes Yes Yes


workinterface_
facts

azure_rm_pub Yes Yes Yes Yes Yes Yes


licipaddress

azure_rm_pub Yes Yes Yes Yes Yes Yes


licipaddress_fa
cts

azure_rm_rout - - - Yes Yes Yes


e

azure_rm_rout - - - Yes Yes Yes


etable

azure_rm_rout - - - Yes Yes Yes


etable_facts

azure_rm_sec Yes Yes Yes Yes Yes Yes


uritygroup

azure_rm_sub Yes Yes Yes Yes Yes Yes


net

azure_rm_sub - - - - Yes Yes


net_facts

azure_rm_traff - - - Yes Yes Yes


icmanagerend
point

azure_rm_traff - - - Yes Yes Yes


icmanagerend
point_facts

azure_rm_traff - - - Yes Yes Yes


icmanagerprof
ile

azure_rm_traff - - - Yes Yes Yes


icmanagerprof
ile_facts

azure_rm_virt Yes Yes Yes Yes Yes Yes


ualnetwork
ANSIBLE
MODULE FOR
AZURE ANSIBLE 2.4 ANSIBLE 2.5 ANSIBLE 2.6 ANSIBLE 2.7 ANSIBLE 2.8 ANSIBLE ROLE

azure_rm_virt Yes Yes Yes Yes Yes Yes


ualnetwork_fa
cts

azure_rm_virt - - - - Yes Yes


ualnetworkpe
ering

Storage

azure_rm_ma Yes Yes Yes Yes Yes Yes


nageddisk

azure_rm_ma Yes Yes Yes Yes Yes Yes


nageddisk_fac
ts

azure_rm_stor Yes Yes Yes Yes Yes Yes


ageaccount

azure_rm_stor Yes Yes Yes Yes Yes Yes


ageaccount_fa
cts

azure_rm_stor Yes Yes Yes Yes Yes Yes


ageblob

Web

azure_rm_app - - - Yes Yes Yes


serviceplan

azure_rm_app - - - Yes Yes Yes


serviceplan_fa
cts

azure_rm_web - - - Yes Yes Yes


app

azure_rm_web - - - Yes Yes Yes


app_facts

azure_rm_web - - - - Yes Yes


appslot

Containers

azure_rm_acs Yes Yes Yes Yes Yes Yes

azure_rm_aks - - Yes Yes Yes Yes


ANSIBLE
MODULE FOR
AZURE ANSIBLE 2.4 ANSIBLE 2.5 ANSIBLE 2.6 ANSIBLE 2.7 ANSIBLE 2.8 ANSIBLE ROLE

azure_rm_aks_ - - Yes Yes Yes Yes


facts

azure_rm_aks - - - - Yes Yes


version_facts

azure_rm_con - Yes Yes Yes Yes Yes


tainerinstance

azure_rm_con - - - - Yes Yes


tainerinstance
_facts

azure_rm_con - Yes Yes Yes Yes Yes


tainerregistry

azure_rm_con - - - Yes Yes Yes


tainerregistry_
facts

azure_rm_con - - - - Yes Yes


tainerregistryr
eplication

azure_rm_con - - - - Yes Yes


tainerregistryr
eplication_fact
s

azure_rm_con - - - - Yes Yes


tainerregistry
webhook

azure_rm_con - - - - Yes Yes


tainerregistry
webhook_fact
s

Databases

azure_rm_cos - - - - Yes Yes


mosdbaccoun
t

azure_rm_cos - - - - Yes Yes


mosdbaccoun
t_facts

azure_rm_mar - - - - Yes Yes


iadbconfigurat
ion
ANSIBLE
MODULE FOR
AZURE ANSIBLE 2.4 ANSIBLE 2.5 ANSIBLE 2.6 ANSIBLE 2.7 ANSIBLE 2.8 ANSIBLE ROLE

azure_rm_mar - - - - Yes Yes


iadbconfigurat
ion_facts

azure_rm_mar - - - - Yes Yes


iadbdatabase

azure_rm_mar - - - - Yes Yes


iadbdatabase_
facts

azure_rm_mar - - - - Yes Yes


iadbfirewallrul
e

azure_rm_mar - - - - Yes Yes


iadbfirewallrul
e_facts

azure_rm_mar - - - - Yes Yes


iadbserver

azure_rm_mar - - - - Yes Yes


iadbserver_fac
ts

azure_rm_mys - - - - Yes Yes


qlconfiguratio
n

azure_rm_mys - - - - Yes Yes


qlconfiguratio
n_facts

azure_rm_mys - Yes Yes Yes Yes Yes


qldatabase

azure_rm_mys - - - Yes Yes Yes


qldatabase_fa
cts

azure_rm_mys - - - - Yes Yes


qlfirewallrule

azure_rm_mys - - - - Yes Yes


qlfirewallrule_f
acts

azure_rm_mys - Yes Yes Yes Yes Yes


qlserver

azure_rm_mys - - - Yes Yes Yes


qlserver_facts
ANSIBLE
MODULE FOR
AZURE ANSIBLE 2.4 ANSIBLE 2.5 ANSIBLE 2.6 ANSIBLE 2.7 ANSIBLE 2.8 ANSIBLE ROLE

azure_rm_pos - - - - Yes Yes


tgresqlconfigu
ration

azure_rm_pos - - - - Yes Yes


tgresqlconfigu
ration_facts

azure_rm_pos - Yes Yes Yes Yes Yes


tgresqldataba
se

azure_rm_pos - - - Yes Yes Yes


tgresqldataba
se_facts

azure_rm_pos - - - - Yes Yes


tgresqlfirewall
rule

azure_rm_pos - - - - Yes Yes


tgresqlfirewall
rule_facts

azure_rm_pos - Yes Yes Yes Yes Yes


tgresqlserver

azure_rm_pos - - - Yes Yes Yes


tgresqlserver_
facts

azure_rm_redi - - - - Yes Yes


scache

azure_rm_redi - - - - Yes Yes


scache_facts

azure_rm_redi - - - - Yes Yes


scachefirewallr
ule

azure_rm_sqld - Yes Yes Yes Yes Yes


atabase

azure_rm_sqld - - - - Yes Yes


atabase_facts

azure_rm_sqle - - - - Yes Yes


lasticpool

azure_rm_sqle - - - - Yes Yes


lasticpool_fact
s
ANSIBLE
MODULE FOR
AZURE ANSIBLE 2.4 ANSIBLE 2.5 ANSIBLE 2.6 ANSIBLE 2.7 ANSIBLE 2.8 ANSIBLE ROLE

azure_rm_sqlfi - - - Yes Yes Yes


rewallrule

azure_rm_sqlfi - - - - Yes Yes


rewallrule_fact
s

azure_rm_sqls - Yes Yes Yes Yes Yes


erver

azure_rm_sqls - Yes Yes Yes Yes Yes


erver_facts

Analytics

azure_rm_hdi - - - - Yes Yes


nsightcluster

Integration

azure_rm_serv - - - - Yes Yes


icebus

azure_rm_serv - - - - Yes Yes


icebus_facts

azure_rm_serv - - - - Yes Yes


icebusqueue

azure_rm_serv - - - - Yes Yes


icebussaspolic
y

azure_rm_serv - - - - Yes Yes


icebustopic

azure_rm_serv - - - - Yes Yes


icebustopicsu
bscription

Security

azure_rm_key - Yes Yes Yes Yes Yes


vault

azure_rm_key - - - - Yes Yes


vault_facts

azure_rm_key - Yes Yes Yes Yes Yes


vaultkey
ANSIBLE
MODULE FOR
AZURE ANSIBLE 2.4 ANSIBLE 2.5 ANSIBLE 2.6 ANSIBLE 2.7 ANSIBLE 2.8 ANSIBLE ROLE

azure_rm_key - Yes Yes Yes Yes Yes


vaultsecret

azure_rm_role - - - - Yes Yes


assignment

azure_rm_role - - - - Yes Yes


assignment_fa
cts

azure_rm_role - - - - Yes Yes


definition

azure_rm_role - - - - Yes Yes


definition_fact
s

DevOps

azure_rm_dev - - - - Yes Yes


testlab

azure_rm_dev - - - - Yes Yes


testlab_facts

azure_rm_dev - - - - Yes Yes


testlabarmte
mplate_facts

azure_rm_dev - - - - Yes Yes


testlabartifact
_facts

azure_rm_dev - - - - Yes Yes


testlabartifact
source

azure_rm_dev - - - - Yes Yes


testlabartifact
source_facts

azure_rm_dev - - - - Yes Yes


testlabcustom
image

azure_rm_dev - - - - Yes Yes


testlabenviron
ment

azure_rm_dev - - - - Yes Yes


testlabpolicy
ANSIBLE
MODULE FOR
AZURE ANSIBLE 2.4 ANSIBLE 2.5 ANSIBLE 2.6 ANSIBLE 2.7 ANSIBLE 2.8 ANSIBLE ROLE

azure_rm_dev - - - - Yes Yes


testlabschedul
e

azure_rm_dev - - - - Yes Yes


testlabvirtual
machine

azure_rm_dev - - - - Yes Yes


testlabvirtual
machine_facts

azure_rm_dev - - - - Yes Yes


testlabvirtualn
etwork

azure_rm_dev - - - - Yes Yes


testlabvirtualn
etwork_facts

Azure
Monitor

azure_rm_aut - - - Yes Yes Yes


oscale

azure_rm_aut - - - Yes Yes Yes


oscale_facts

azure_rm_loga - - - - Yes Yes


nalyticsworks
pace

azure_rm_loga - - - - Yes Yes


nalyticsworks
pace_facts

Introduction to playbook role for Azure


The azure_preview_module playbook role includes all the latest Azure modules. The updates and bug fixes are
done in a more timely manner than the official Ansible release. If you use Ansible for Azure resource provisioning
purposes, you're encouraged to install the azure_preview_module playbook role.
The azure_preview_module playbook role is released every three weeks.

Next steps
For more information about playbook roles, see Creating reusable playbooks.

You might also like