Technical Thursday – Azure resources with Ansible
In March I started a serie about Ansible. Now I would like to show you the first real code and solution how you can create Azure resources with Ansible. I know this is only the second part of the serie therefore I will show a simple and easy-to-understand example which can work in a live environment as well. Let’s start…
I hope you read the latest article and now you have a basic knowledge about Ansible.
Scenario
Our example for Today is a solution which creates the followings:
- Resource Group
- Virtual Network
- FrontEnd subnet for Virtual Network
- Network Security Group for FrontEnd subnet
- Some Network Cards which connect to FrontEnd subnet
Simple but covers some real life requests. 🙂
Prepapare our Ansible computer
Before we start the real scripting we have to install some packages to our system. We will use the Ansible 2.5.x for our example.
Install packages for ansible
# update PIP on your computer sudo pip install --upgrade pip # Install/Update azure sudo pip install azure --upgrade # Install/Update msrestazure sudo pip install msrestazure --upgrade # Install/update packaging sudo pip install packaging --upgrade # Install/Update cryptography sudo pip install cryptography --upgrade # Install/Update azure module for Ansible sudo pip install ansible[azure] --upgrade
Access on Azure for Ansible
Here we create a Service Principal in Azurre and the credential file for Azure access.
Create Service Principal
- Login to Azure (and set the default subscription)
az cloud update az cloud set -n AzureCloud # Login with your account az login -u <your username> # Set the required subsctiption az account set --subscription <subscriptionID>
- Create the service principal for automation
az ad sp create-for-rbac --name Automation_ResourceManager --query '{"client_id": appId, "secret": password, "tenant": tenant}'
- Please write down and store in a secret place the “secret” because you cannot receive again from system anymore.
- Required permission for this SP on subscription: Contributor
- You have to be owner or co-administrator privileges on Azure to be able to create Service Principal
Make credential file
When you execute a playbook with Ansible it requires the Azure login data. For this we have to create a file.
# Create directory mkdir ~/.azure # Create the azure file for credential vim ~/.azure/credentials [default] subscription_id=53455... client_id=7f37... secret=ft56... tenant=987d...
Ansible solution
Ansible files
Regarding Ansible there are 2 very important group of files.
. ├── inventory │ ├── group_vars │ │ ├── all.yml │ │ └── vms.yml │ └── hosts └── playbooks ├── azure_network.yml └── azure_vnet.yml
- Inventory files: Contain all parameters for our solution or Azure environment. (more information)
- hosts: this is the main file which contains the basic parameters and the basic groups. This is an INI-like file.
- all.yml: Contains the global variables for plays
- other yaml files which match with the group names in hosts file. These contains the group related information.
- Playbooks: Playbooks are Ansible’s configuration, deployment, and orchestration language. They can describe a policy you want to enforce. (more information)
Create Inventory files
Create these files into inventory directory.
hosts
As you read above this is a INI-like file and this is the file where we will define the groups we would like to deploy in Azure.
- [vnet]: In our example we will deploy Virtual Network related resources (VNET, Subnet, NSG) therefore we have to put here a [vnet] group. Because all the information will be used later we can manage the Virtual Network parameters as global variables. (so we will define them later) Here we just put a vnet value which is a suffix for our Virtual Network name.
- [vms]: As I mentioned above we will deploy some NICs so this group name could be [nics] but in the near future I will show you a whole VM deployment so this group name is fine for us. In this group we define the name of VMs (which will be part of the NICs’ names) and the NICs related FrontEnd IPv4 addresses.
Here is our hosts file:
[vnet] vnet [vms] cust-01 vm_fe_ip="79.0.0.11" cust-02 vm_fe_ip="79.0.0.12" cust-03 vm_fe_ip="79.0.0.13" cust-04 vm_fe_ip="79.0.0.14"
group_vars/vms.yml
This file is a [vms] group specific file where we could define things for [vms] group related activities. In our example this is an empty file.
---
group_vars/all.yml
This is the file which contains the global variables for plays and playbooks. Therefore we will define here all global variables and the [vnet] group related parameters.
--- env_id: "the1bit" location: "westeurope" resource_group: "custom" vnet_address_prefix: "79.0.0.0/23" vnet_fe_subnet_address_prefix: "79.0.0.0/24"
Of course you can create some other files and variables…
Create Playbooks
And now we will create the playbooks for the different steps. For this scenario only file would be enough. Nevertheless on this way it will be easy to understand.
The parameters from inventory files will be used like in MVC app. I mean when you would like to use the location variable from all.yml you can do that on this way: "{{location}}"
Then if you would like to use a variable from hosts file from the first column (where there is no variable name) such as “cust-03” from [vms] group you can do this on this way: "{{inventory_hostname}}"
.
Create these files into playbooks directory.
azure_vnet.yml
This file contains the following creation steps:
- Resource Group
- Virtual Network
- FrontEnd subnet for Virtual Network
- Network Security Group for FrontEnd subnet
- name: Create VirtualNetwork hosts: vnet connection: local vars: rgName: "{{env_id}}-rg-{{resource_group}}" vnet_name: "{{env_id}}-{{inventory_hostname}}" tasks: - name: Create resource Group - {{env_id}}-rg-{{resource_group}} shell: az group create -n "{{rgName}}" --location "{{location}}" - name: Create virtual network - {{vnet_name}} azure_rm_virtualnetwork: resource_group: "{{rgName}}" name: "{{vnet_name}}" address_prefixes: "{{vnet_address_prefix}}" - name: Add FE subnet {{vnet_name}}-subnet-fe azure_rm_subnet: resource_group: "{{rgName}}" name: "{{vnet_name}}-subnet-fe" address_prefix: "{{vnet_fe_subnet_address_prefix}}" virtual_network: "{{vnet_name}}" - name: Create Network Security Group - FE - {{vnet_name}}-nsg-fe azure_rm_securitygroup: resource_group: "{{rgName}}" name: "{{vnet_name}}-nsg-fe"
Here we have some exciting sections:
- hosts: name of group from hosts file
- connection: where we would like to execute this play. We will do it on this machine, so we use local
- vars: here you can create custom variables or create variables from concatenated variables
- tasks: tasks in this play (we have 4 tasks in this play)
- Create resource Group
- Create virtual network
- Add FE subnet
- Create Network Security Group
azure_network.yml
This file contains the following creation steps:
- Some Network Cards which connect to FrontEnd subnet (parallel)
- name: Create Network hosts: vms connection: local vars: rgName: "{{env_id}}-rg-{{resource_group}}" vnet_name: "{{env_id}}-vnet" tasks: - name: Create virtual network interface card - FE azure_rm_networkinterface: resource_group: "{{rgName}}" name: "{{env_id}}-{{inventory_hostname}}-nic-fe" virtual_network: "{{vnet_name}}" subnet: "{{vnet_name}}-subnet-fe" security_group: "{{vnet_name}}-nsg-fe" ip_configurations: - name: ipconfig1 private_ip_allocation_method: Static private_ip_address: "{{vm_fe_ip}}" primary: true
Here we have some exciting sections:
- hosts: name of group from hosts file
- connection: where we would like to execute this play. We will do it on this machine, so we use local
- vars: here you can create custom variables or create variables from concatenated variables
- tasks: tasks in this play (we have 1 task in this play, but this task will be executed multiple times according to the number of lines in [vms] group in hosts file)
- Create virtual network interface card for FrontEnd subnet
We are ready for execution.
Execute playbooks
Just only one step left: execute playbooks.
Please be sure you are out of inventory and playbooks directory. Then you have to execute the following commands
1. Create VNET related resources
ansible-playbook -i inventory/ playbooks/azure_vnet.yml
Where:
- after -i you have to put the root directory of inventory files
- then you put the path of vnet playbook
2. Create NETWORK related resources
ansible-playbook -i inventory/ playbooks/azure_network.yml
Where:
- after -i you have to put the root directory of inventory files
- then you put the path of network playbook
Result:
Final result in Azure:
As you can see with some simple configuration you can make some quite cool things. Nevertheless this is merely a fundamental for your future with Ansible.
You can find this and another exciting solutions for Ansible on my azansible Git repository.
Technical Thursday – Scheduled VM start in Azure – IT Blog for sharing
2018-06-21 @ 13:35
[…] Create a Service Principal for your account. More information is here […]
Technical Thursday – Dynamic DNS client for Linux (in Azure) – IT Blog for sharing
2018-06-14 @ 21:19
[…] Create a Service Principal for your account. More information is here […]