Using cloud-init as custom_data with ansible - azure

I deploy a VM using an ansible playbook, similar to this demo.
- name: Create VM
azure_rm_virtualmachine:
resource_group: myResourceGroup
name: myVM
...
custom_data: cloud-init.yml
Now I also want to install some packages and do some minor preparations. I made a cloud-config.yml
#cloud-config
package_upgrade: true
packages:
- npm
- nodejs-legacy
runcmd:
- sudo mkdir -p /data/projects/
It seems that cloud-init.yml is not executed, so I guess this is not the correct syntax. How should you pass cloud-init files in an ansible playbook? Or is there another method to reach this goal?

custom_data parameter in azure_rm_virtualmachine requires the data, not a filename.
You can use file lookup plugin to fetch the data from a file on an Ansible controller:
- name: Create VM
azure_rm_virtualmachine:
resource_group: myResourceGroup
name: myVM
...
custom_data: "{{ lookup('file', 'cloud-init.yml') }}"

Related

Update the disk storage type in azure windows vm using ansible playbook

I have written 4 tasks for it first for power off the vm, second to verify if it is stopped, 3rd to update and then power on the vm. But the problem is even when the machine is stopped ansible is giving error "Operation not allowed". You can see the error below. Please suggest me the correct way of doing it as I am new to ansible. Please also clarify which task to run on localhost and which on windows.
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Error creating the managed disk: Azure Error: OperationNotAllowed\nMessage: Cannot change account type, fault domain or network spine of disk <<disk_name>> while it is attached to running VM <<vm_name>>."}
- name: Update Disk type
hosts: localhost
gather_facts: no
tasks:
- name: Power off the VM
azure_rm_virtualmachine:
resource_group: "{{resource_group}}"
name: "{{vm_name}}"
started: no
- name: Verify that the machine is stopped
win_ping:
#delegate_to: localhost
failed_when: false
ignore_unreachable: true
register: ping_result
- debug: var=ping_result
- name: Update the disk type
azure_rm_manageddisk:
name: "{{disk_name}}"
resource_group: "{{resource_group}}"
storage_account_type: "{{type}}"
disk_size_gb: "{{size}}"
- name: Power on the VM
azure_rm_virtualmachine:
resource_group: "{{resource_group}}"
name: "{{vm_name}}"
The issue was resolved by changing
name: Power off the VM
azure_rm_virtualmachine:
resource_group: "{{resource_group}}"
name: "{{vm_name}}"
started: no
to
name: Power off the VM
azure_rm_virtualmachine:
resource_group: "{{resource_group}}"
name: "{{vm_name}}"
allocated: no
Also as per Richa's Update we need to use az CLI to update the disk as it is mentioned in Github repo for ansible that disk updation is not possible through ansible module due to some server constraints.
Reference: az disk | Microsoft Docs

How to apply the changes of a Linux users group assignments inside a local ansible playbook?

I´m trying to install docker and create a docker image within a local ansible playbook containing multiple plays, adding the user to docker group in between:
- hosts: localhost
connection: local
become: yes
gather_facts: no
tasks:
- name: install docker
ansible.builtin.apt:
update_cache: yes
pkg:
- docker.io
- python3-docker
- name: Add current user to docker group
ansible.builtin.user:
name: "{{ lookup('env', 'USER') }}"
append: yes
groups: docker
- name: Ensure that docker service is running
ansible.builtin.service:
name: docker
state: started
- hosts: localhost
connection: local
gather_facts: no
tasks:
- name: Create docker container
community.docker.docker_container:
image: ...
name: ...
When executing this playbook with ansible-playbook I´m getting a permission denied error at the "Create docker container" task. Rebooting and calling the playbook again solves the error.
I have tried manually executing some of the commands suggested here and executing the playbook again which works, but I´d like to do everything from within the playbook.
Adding a task like
- name: allow user changes to take effect
ansible.builtin.shell:
cmd: exec sg docker newgrp `id -gn`
does not work.
How can I refresh the Linux user group assignments from within the playbook?
I´m on Ubuntu 18.04.

How to set target VM for an Azure loadbalancer inbound NAT rule with Ansible-azure?

I need to create an inbound nat rule on my loadbalancer to redirect a certain port to a virtual machine. I've created my loadbalancer like so. I'm on Ansible 2.9.6.
- name: Create loadbalancers
azure_rm_loadbalancer:
resource_group: "{{ item.lb_resource_group }}"
name: "{{ item.lb_name }}"
frontend_ip_configurations: "{{ item.lb_frontend_ip_configurations }}"
backend_address_pools: "{{ item.lb_backend_address_pools }}"
probes: "{{ item.lb_probes }}"
load_balancing_rules: "{{ item.lb_load_balancing_rules }}"
inbound_nat_rules: "{{ item.lb_inbound_nat_rules }}"
with_items:
- "{{ lbs }}"
tags:
- lb
The inbound nat-rule looks like this.
- name: "nat-rule-in"
backend_port: 821
protocol: Tcp
frontend_port: 380
frontend_ip_configuration: "lb-frontend"
I've looked in this documentation and can not find anything that says something about this. Is it not possible to set a target VM for an inbound nat-rule using Ansible or do I need to do it somewhere else?
I've also searched the VM documentation for Ansible-azure but can't find anything related to NAT rules there either.
What you need to find is not the azure_rm_virtualmachine module in Ansible, it should be the azure_rm_networkinterface module. You can configure the ip_configurations property of the azure_rm_networkinterface to set the load_balancer_backend_address_pools, this property can associate the VM to the Load Balancer.
Seems as if this really isn't an option with Ansible-azure itself.
I instead used the Azure-CLI with an SPN and ran the command through Ansible using command.
$ sudo apt-get install azure-cli
Within Ansible I used the code below to set the target VM after creating the inbound nat rule.
- name: Create inbound NAT rules
command: az network nic ip-config inbound-nat-rule add --ip-config-name <name> --resource-group <name> --lb-name <name> --nic-name <name> --inbound-nat-rule <name>
Same issue with az cli ...
It costed me a lot of time, glad I found this page. Indeed the way to (currently still) link the NAT rule to a backend is via the ipconfig object of the nic of the VM. https://learn.microsoft.com/en-us/cli/azure/network/nic/ip-config/inbound-nat-rule?view=azure-cli-latest

Ansible - How to run YAML code in Azure Cloud Shell

Question: How do I run the following YAML in Azure Cloud Shell?
In step 1 of this Ansible tutorial, the author is asking to run the following YAML - to create a resource group. I'm using PowerShell in Azure Cloud Shell (where Ansible is pre-installed).
- name: Create resource group
azure_rm_resourcegroup:
name: rg-cs-ansible
location: eastus
Save it to a playbook.yaml text file and run it with ansible-playbook playbook.yaml, but you also need to have a proper structure to the playbook file. something like this:
---
- hosts: localhost
tasks:
- name: Create resource groupf
azure_rm_resourcegroup:
name: rg-cs-ansible
location: eastus

SQL Server does not allow for firewall update - Error creating the Firewall Rule instance

Hello community i am running the below ansible playbook through azure cli.
Also i get similar results from an Ubuntu 18.04.4 LTS.
Also i have raised a github issue: https://github.com/Azure/Ansible/issues/21
What i mean using Azure CLI?
Go to Azure:
-> Create a new Cloud Shell
-> Ansible is already installed
-> create a new yml file. Copy the below script.
-> Run the below playbook. With this command ansible-playbook nameofyourfile.yml
-> The below script fails
- hosts: localhost
connection: local
vars:
resource_group: ansibleResourceGroupName
webapp_name: ansibleWebAppName
plan_name: ansibleWebPlanName
location: westeurope
server_name: AnisbleDemoSqlServer
database_name: AnsibleDemoSqlDatabase
tasks:
- name: Create a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"
- name: Create App Service on Linux with dotnetcore
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: "dotnetcore"
version: "3.1"
- name: Create (or update) SQL Server
azure_rm_sqlserver:
resource_group: "{{ resource_group }}"
name: "{{ server_name }}"
location: "{{ location }}"
admin_username: panoskarajohn
admin_password: Testpasswordxyz12!
- name: Create (or update) SQL Database
azure_rm_sqldatabase:
resource_group: "{{ resource_group }}"
server_name: "{{ server_name }}"
name: "{{ database_name }}"
location: "{{ location }}"
- name: Create (or update) Firewall Rule
azure_rm_sqlfirewallrule:
resource_group: "{{ resource_group }}"
server_name: "{{ server_name }}"
name: firewallruleAllowAll
start_ip_address: 0.0.0.0.
end_ip_address: 255.255.255.255
My sqlserver is created.
But the firewall rule fails, with an unauthorised error.
At the end i have provided the errors
Also when i try to do it manually to add a firewall rule through the azure portal.
Everything is deactivated. Also the add client ip seems to be inactive.
Also even with the choices i am allowed to change, the save button is unresponsive.
The whole firewalls page seems unresponsive.
See image for more info.
When i create through the azure portal a new sql server, everything seems to operate.
Any help is appreciated.
Error i get:
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Error creating the Firewall Rule instance: 400 Client Error: Bad Request for url: -> Some url.
When i click on the url i get this json -> {"error":{"code":"AuthenticationFailed","message":"Authentication failed. The 'Authorization' header is missing."}}
Ansible Version for my Ubuntu Machine
ansible 2.9.6
config file = None
configured module search path = [u'/home/pkaragiannis/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python2.7/dist-packages/ansible
executable location = /usr/local/bin/ansible
python version = 2.7.17 (default, Nov 7 2019, 10:07:09) [GCC 7.4.0]
Ansible Output from Ubuntu VM
PLAY [localhost] ***************************************************************************************
TASK [Gathering Facts] *********************************************************************************
ok: [localhost]
TASK [Create a resource group] *************************************************************************
changed: [localhost]
TASK [Create App Service on Linux with dotnetcore] *****************************************************
changed: [localhost]
TASK [Create (or update) SQL Server] *******************************************************************
[WARNING]: Azure API profile latest does not define an entry for SqlManagementClient
changed: [localhost]
TASK [Create (or update) SQL Database] *****************************************************************
changed: [localhost]
TASK [Create (or update) Firewall Rule] ****************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Error creating the Firewall Rule instance: 400 Client Error: Bad Request for url: https://management.azure.com/subscriptions/******-*****-*******/resourceGroups/ansibleResourceGroupName/providers/Microsoft.Sql/servers/AnisbleDemoSqlServer/firewallRules/firewallruleAllowAll?api-version=2014-04-01"}
PLAY RECAP *********************************************************************************************
localhost : ok=5 changed=4 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
When you want to create the SQL server and the firewall rules for it, I see you use the service principal to authenticate. So first of all, the service principal should have the Contributor role of the subscription or the resource group that you would use.
Log in with the service principal, and then the Azure CLI command to create the SQL server and the firewall rules:
az sql server create -l westus -g mygroup -n myserver -u myadminuser -p myadminpassword
az sql server firewall-rule create -g mygroup -s myserver -n myrule --start-ip-address 1.2.3.4 --end-ip-address 5.6.7.8
With the Ansible, it should also work and I did not see any problems in the code. Just set the credentials for it with the service principal correctly.
Update:
Here is the screenshot of the ansible:
Update-1:
Here is the YAML file of above screenshot:
- hosts: localhost
connection: local
tasks:
- name: Create (or update) SQL Server
azure_rm_sqlserver:
resource_group: mygroup
name: mysqlname
location: eastus
admin_username: username
admin_password: password
- name: Create (or update) Firewall Rule
azure_rm_sqlfirewallrule:
resource_group: mygroup
server_name: mysqlname
name: FirewallRule1
start_ip_address: 10.0.17.62
end_ip_address: 10.0.17.62

Resources