I'm learning ansible to create Linux VM's on azure and I used this sample playbook in this link (https://learn.microsoft.com/en-us/azure/developer/ansible/vm-configure?tabs=ansible) to create one VM on azure. If I want to deploy 10 VM's exactly like this with ansible-playbook how should I do it? Please help. Thanks in advance
Update: I tried it like this but the script fails after creating two public IP addresses.
- name: Create Azure VM
hosts: localhost
connection: local
tasks:
- name: Create resource group to hold VM
azure_rm_resourcegroup:
name: TestingResource
location: eastus
- name: Create virtual network
azure_rm_virtualnetwork:
resource_group: TestingResource
name: testingvnet
address_prefixes: "10.0.0.0/16"
- name: Add subnet
azure_rm_subnet:
resource_group: TestingResource
name: testingsubnet
address_prefix: "10.0.1.0/24"
virtual_network: testingvnet
- name: Create public IP address
azure_rm_publicipaddress:
resource_group: TestingResource
allocation_method: Static
name: "{{ item }}" #CHANGE HERE
loop:
- testingpublicIP2
- testingpublicIP3
register: output_ip_address
#- name: Dump public IP for VM which will be created
#debug:
#msg: "The public IP is {{ output_ip_address.state.ip_address }}."
- name: Create Network Security Group that allows SSH
azure_rm_securitygroup:
resource_group: TestingResource
name: TestingSecurityGroup
rules:
- name: SSH
protocol: Tcp
destination_port_range: 22
access: Allow
priority: 1001
direction: Inbound
- name: Create virtual network interface card
azure_rm_networkinterface:
resource_group: TestingResource
name: "{{ item }}" #CHANGE HERE
loop:
- TestingNIC2
- TestingNIC3
virtual_network: testingvnet
subnet: testingsubnet
public_ip_name: "{{ item }}" #CHANGE HERE
loop:
- testingpublicIP2
- testingpublicIP3
security_group: TestingSecurityGroup
- name: Create VM
azure_rm_virtualmachine:
resource_group: TestingResource
name: "{{ item }}" #CHANGE HERE VM NAME
loop:
- TestingResource2
- TestingResource3
vm_size: Standard_B2s
admin_username: admin
admin_password: password#123
ssh_password_enabled: true
network_interfaces: "{{ item }}" #CHANGE HERE
loop:
- TestingNIC2
- TestingNIC3
image:
offer: UbuntuServer
publisher: Canonical
sku: '18.04-LTS'
version: latest
You can use the loops function to create multiple VMs through ansible as you showed in the question, but you'd better use a list variable to loop so that you don't need to write all the elements every time. And the variables also can be used for other things like resource group name, location, and so on that use multiple times in the code. Here is the example:
- hosts: localhost
vars:
resource_group: myResourceGroup
...
tasks:
- name: Create resource group to hold VM
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: eastus
...
And the variable for the loop:
loop: "{{ var_list }}"
I found out it's quite easy with terraform to deploy multiple VM's on azure just by changing one variable in the configuration file, Here's the configuration file that i used (https://github.com/RichardPhilipsRoy/terraform-azure-linuxVMs)
Related
I was trying to provision an Azure load-balancer with only a private IP address in an existing subnet. I could accomplish this with the below code.
- name: create load balancer
azure_rm_loadbalancer:
resource_group: "{{resource_group_name}}"
name: my_new_lb
frontend_ip_configurations:
- name: frontendipconf0
private_ip_address:
private_ip_allocation_method: dynamic
subnet: /subscriptions/1234445sdffew11111111/resourceGroups/RG_NAME/providers/Microsoft.Network/virtualNetworks/vnet-stage/subnets/default
backend_address_pools:
- name: backend_pool1
probes:
- name: prob0
port: 80
load_balancing_rules:
- name: lbrbalancingrule0
frontend_ip_configuration: frontendipconf0
backend_address_pool: backend_pool1
frontend_port: 8000
backend_port: 443
probe: prob0
But is there a way we can provision a loadbalancer without providing a complete subnet id in the task file?
I could resolve the issue with the help of azure_rm_resource_info as well. Adding the script below.
azure_rm_resource_info:
api_version: '2018-08-01'
resource_group: "{{ resource_group_name }}"
provider: network
resource_type: virtualnetworks
resource_name: "{{ vnet_name }}"
subresource:
- type: subnets
name: "{{ subnet_name }}"
register: subnet
- name: create load balancer
azure_rm_loadbalancer:
resource_group: "{{resource_group_name}}"
name: lb_name
frontend_ip_configurations:
- name: frontendipconf0
private_ip_address:
private_ip_allocation_method: dynamic
subnet: "{{subnet.response[0].id }}"
If you want to provision the load balancer with a private IP address, then you must associate a subnet to the load balancer, so I think an existing subnet resource id is necessary. It's impossible not to provide a complete subnet id in the task file.
Update:
Here is the example to get the virtual network info:
- name: Get the Load Balancer info
azure_rm_virtualnetwork_info:
resource_group: "{{ resource_group_name }}"
name: "{{ vnet_name }}"
register: vnet
Then you can input the subnet id in the load balancer like this:
subnet: "{{ vnet.virtualnetworks[0].subnets[0].id }}"
You can get the VNet info and change the subnet you want to use. Please read the azure_rm_virtualnetwork_info example carefully.
We have a Playbook to create a Linux VM in Mincrosoft azure following a role to do post install things like installing some applications packages. Our playbook is running fine and able to deploy the VM in azure, However the second role which is to configure the VM after deployment is not running on the VM as, we are not able to pass the vm (IP/Hostname) to the second role.
What we wan to achieve is to deploy VM using ansible playbook/role, Run the roles after the machine is deployed to configure the business specific tasks.
Path:
Below is the path where all ansible plays and roles are coming. here roles folders contains all the post install tasks, i believe there will be a better way there Keeping the test-creatVM-sur.yml there itself within role but as a learner i'm bit struggling..
$ ls -l /home/azure1/ansible_Dir
-rw-r-----. 1 azure1 hal 1770 Sep 17 17:03 test-creatVM-sur.yml
-rw-r-----. 1 azure1 hal 320 Sep 17 22:30 licence-test.yml
drwxr-x---. 6 azure1 hal 4096 Sep 17 21:46 roles
My main Play file:
$ cat licence-test.yml
---
- name: create vm
hosts: localhost
connection: local
become: yes
become_method: sudo
become_user: root
vars:
Res_Group: "some_value"
LOCATION: "some_value"
VNET: "some_value"
IMAGE_ID: "some_value"
SUBNET: "some_value"
KEYDATA: "some_value"
DISK_SIZE: 100
DISK_TYPE: Premium_LRS
tasks:
- name: include task
include_tasks:
file: creattest_VM.yml <-- This portion works fine
- hosts: "{{ VM_NAME }}" <-- this portion does not work as it's not able to fetch the newly created VM name.
become: yes
become_method: sudo
become_user: root
roles:
- azure_license
...
Play (test-creatVM-sur.yml) which created VM in azure is below:
---
- name: Create Network Security Group that allows SSH
azure_rm_securitygroup:
resource_group: "{{ Res_Group }}"
location: "{{ LOCATION }}"
name: "{{ VM_NAME }}-nsg"
rules:
- name: SSH
protocol: Tcp
destination_port_range: 22
access: Allow
priority: 100
direction: Inbound
- name: Create virtual network interface card
azure_rm_networkinterface:
resource_group: "{{ Res_Group }}"
location: "{{ LOCATION }}"
name: "{{ VM_NAME }}-nic1"
subnet: "{{ SUBNET }}"
virtual_network: "{{ VNET }}"
security_group: "{{ VM_NAME }}-nsg"
enable_accelerated_networking: True
public_ip: no
state: present
- name: Create VM
azure_rm_virtualmachine:
resource_group: "{{ Res_Group }}"
location: "{{ LOCATION }}"
name: "{{ VM_NAME }}"
vm_size: Standard_D4s_v3
admin_username: automation
ssh_password_enabled: false
ssh_public_keys:
- path: /home/automation/.ssh/authorized_keys
key_data: "{{ KEYDATA }}"
network_interfaces: "{{ VM_NAME }}-nic1"
os_disk_name: "{{ VM_NAME }}-osdisk"
managed_disk_type: "{{ DISK_TYPE }}"
os_disk_caching: ReadWrite
os_type: Linux
image:
id: "{{ IMAGE_ID }}"
publisher: redhat
plan:
name: rhel-lvm78
product: rhel-byos
publisher: redhat
- name: Add disk to VM
azure_rm_manageddisk:
name: "{{ VM_NAME }}-datadisk01"
location: "{{ LOCATION }}"
resource_group: "{{ Res_Group }}"
disk_size_gb: "{{ DISK_SIZE }}"
managed_by: "{{ VM_NAME }}"
- name: "wait for 3 Min"
pause:
minutes: 3
...
Edit:
I managed to define the vars into a separated name_vars under include_vars.
---
- name: create vm
hosts: localhost
connection: local
become: yes
become_method: sudo
become_user: root
tasks:
- include_vars: name_vars.yml
- include_tasks: creattest_VM.yml
- name: Apply license hardening stuff
hosts: "{{ VM_NAME }}"
become: yes
become_method: sudo
become_user: root
roles:
- azure_license
...
It works after doing some dirty hack but that doesn't looks proper as i am creating an invetory test to putting there VM_NAME as well as an extra variable with -e below.
$ ansible-playbook -i test -e VM_NAME=mylabhost01.hal.com licence-test.yml -k -u my_user_id
Any help will be much appreciated.
I am creating an azure vm using ansible using azure_rm_virtualmachine command. For this case the host is localhost (ansible_connection=local). I need to copy a ssh private key which is ansible-vault encrypted. How can i do this?
Here's what is already tried:
Use command and run SCP: problem is the file is still encrypted.
Decrypt the file , scp and encrypt: problem is after decryption if the scp command fails the file is now open decrypted.
Anyone has any idea on how to approach this problem?
FYI: While creating the VM i have added my pub key there so i can access the machine
As far as I understand your use-case, you first create a new VM in Azure, and then you want to send a new private key on that fresh VM. I have two options for you.
Split in 2 plays
In the same playbook, you can have 2 different plays:
---
- name: Provisioning of my pretty little VM in Azure
hosts: localhost
vars:
my_vm_name: myprettyvm
my_resource_group: myprettygroup
…
tasks:
- name: Create the VM
azure_rm_virtualmachine:
resource_group: "{{ my_resource_group }}"
name: "{{ my_vm_name }}"
…
- name: Configure my pretty little VM with
hosts: myprettyvm
vars:
my_priv_key: !vault |
$ANSIBLE_VAULT;1.1;AES256
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
tasks:
- name: Copy my private key
copy:
content: "{{ my_priv_key }}"
dest: /root/.ssh/id_rsa
Delagate to localhost
Only one play in your playbook, but you delegate the provisioning task to localhost.
---
- name: Creation of my pretty little VM in Azure
hosts: myprettyvm
gather_facts: no
vars:
my_vm_name: myprettyvm
my_resource_group: myprettygroup
…
my_priv_key: !vault |
$ANSIBLE_VAULT;1.1;AES256
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
tasks:
- name: Create the VM
azure_rm_virtualmachine:
resource_group: "{{ my_resource_group }}"
name: "{{ my_vm_name }}"
…
delegate_to: localhost
- name: Copy my private key
copy:
content: "{{ my_priv_key }}"
dest: /root/.ssh/id_rsa
Don't forget to set gather_facts to no as host is the VM that does not exist yet. So no fact available.
I created an Ansible-Playbook to install AKS on Ubuntu .
Flowing microsoft tutorial
https://learn.microsoft.com/en-us/azure/ansible/ansible-create-configure-aks
Yml file:
- 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
But it given error:
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Unsupported
kubernetes version. Expected one of [u'1.11.9', u'1.11.8', u'1.10.12',
u'1.10.13', u'1.12. 8', u'1.13.5', u'1.12.7'] but got None"}
Then i switched to another Kubernetes Service which its version is 1.12.8
But it still given this error.
How can i fix it? Or how can i change the version of kubernetes service ?
you need to specify kubernetes_version according to the module wiki. this is also what the error text is telling you
- 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 }}"
kubernetes_version: 1.13.5
xxx
How can you get the private IP for a VM in am Azure scale set in Ansible?
None of these seem to have the info:
azure_rm_virtualmachinescaleset_facts
azure_rm_virtualmachinescalesetinstance_facts
azure_rm_virtualmachine_facts
azure_rm_subnet_facts
azure_rm_networkinterface_facts
in order to get the IPs of my ScaleSet instances, I take the little detour via the PrivateDNS of Azure with auto-registration. As soon as the machines are available, they will be updated in the DNS.
Code Snippet:
- name: Fetch IPs from ScaleSet instances
hosts: localhost
connection: local
vars:
resource_group: "test-lbs1"
vmss_name: "vmss"
zone_name: "my.private.dns.zone"
tasks:
#############################################
# Fetch all Instances from Scaleset
#############################################
- name: List all of the instances
azure.azcollection.azure_rm_virtualmachinescalesetinstance_info:
resource_group: "{{ resource_group }}"
vmss_name: "{{ vmss_name }}"
register: __instances
#############################################
# Fetch IP from PrivateDNS Record
#############################################
- name: Get network interfaces
azure.azcollection.azure_rm_privatednsrecordset_info:
resource_group: "{{ resource_group }}"
zone_name: "{{ zone_name }}"
relative_name: "{{ item.computer_name }}"
record_type: A
with_items: "{{ __instances.instances }}"
register: __network_ips
- debug:
var: __network_ips