Use ODBC connection to managed Azure SQL Database - ansible

I need to run a SQL query on Azure SQL Database from an Ansible playbook.
My task is:
- name: Sql server - rights
vars:
sql_groups:
- { group_name: "{{ reader_group }}", db_access: "db_datareader" }
- { group_name: "{{ contributer_group }}", db_access: "db_datawriter" }
- { group_name: "{{ owner_group }}", db_access: "db_owner" }
community.general.odbc:
dsn: "Driver={ODBC Driver 13 for SQL Server};Server=tcp:{{ sql_server_host }},1433;Database={{ sql_server_db }};Uid={{ mssql_login_user }};Pwd={{ mssql_login_password }};Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;Authentication=ActiveDirectoryPassword"
query: |
CREATE USER ["{{ group_name }}"] FROM EXTERNAL PROVIDER
EXEC sp_addrolemember '{{ db_access }}', '{{ group_name }}'
loop: "{{ sql_groups }}"
When I run the playbook with the following command, Ansible tries to communicate via SSH.
ansible-playbook -i inventory.yml playbook.yml --check
The error is :
[WARNING]: Unhandled error in Python interpreter discovery for host XXXXXX: Failed to connect to the host via ssh: ssh: Could not resolve hostname XXXXXX: Name
or service not known
fatal: [XXXXXX]: UNREACHABLE! => {"changed": false, "msg": "Data could not be sent to remote host \"XXXXXX\". Make sure this host can be reached over ssh: ssh: Could not resolve hostname XXXXXX: Name or service not known\r\n", "unreachable": true}
I think I need to force the use of an ODBC connection with something like below (example is for Windows server) :
ansible_connection: winrm
ansible_port: 5986
ansible_winrm_transport: credssp
ansible_winrm_server_cert_validation: ignore
What should I do ?
ansible_port: 1433 ? And what other parameters ?
I don't see how to communicate via ODBC.

Related

Save ansible variable in local file

I am executing a PS script on a windows host and want to store its stdout in a file on an ansible local machine. I have a playbook like following:
---
- name: Check Antivirus software
hosts: all
become: false
gather_facts: no
tasks:
- name: Get AV details
win_shell: |
echo "script printing data on stdout"
register: result
- name: save response
copy:
content: '{{ result.stdout }}'
dest: '{{ response_file }}'
delegate_to: localhost
From the above playbook, 1st task gets executed without any issues. But 2nd task gives the following error.
TASK [save response] *******************************************************************************************************************************************
fatal: [20.15.102.192 -> localhost]: UNREACHABLE! => {"changed": false, "msg": "ntlm: HTTPSConnectionPool(host='localhost', port=5986): Max retries exceeded with url: /wsman (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7f4940760208>: Failed to establish a new connection: [Errno 111] Connection refused',))", "unreachable": true}
I also tried local_action which is also giving the same error.

Define mysql_user privileges on specific host - "Invalid privileges string: Invalid privileges specified"

I'm working on a task that is supposed to authorize a specific IP address to connect remotely to a MySQL database.
Here is the YAML file of the role :
- name: Change MariaDB password
mysql_user:
login_unix_socket: /var/run/mysqld/mysqld.sock
name: "{{ mysql_user }}"
password: "{{ mysql_password }}"
priv:
"*.*:{{ mysql_user }}#{{ hostvars['mariadb']['ansible_host'] }}"
state: present
I get the following error :
fatal: [mariadb]: FAILED! => {"changed": false, "msg": "invalid privileges string: Invalid privileges specified: frozenset({'MARIADB.IP'})"}```

Not able to connect Arista switches using Ansible

I'm trying to connect Arista switches using Ansible.
I get the following error When I try to connect to Arista switches.
fatal: [172.21.21.166]: FAILED! => {"changed": false, "msg": "operation requires privilege escalation"}
My playbook:
- name: Create Loopback
gather_facts: false
hosts: Leaf
tasks:
- name: configure loopback interface
arista.eos.eos_l3_interface:
name: Loopback 77
ipv4: "{{ hostvars[inventory_hostname]['lo_ip'] }}/32"
My hosts file:
[Leaf]
172.21.21.154 lo_ip=192.168.0.1
172.21.21.164 lo_ip=192.168.0.2
172.21.21.165 lo_ip=192.168.0.3
172.21.21.166 lo_ip=192.168.0.4
172.21.21.179 lo_ip=192.168.0.5
[Leaf:vars]
ansible_connection=ansible.netcommon.network_cli
ansible_network_os=arista.eos.eos
ansible_user=mikronet
ansible_password=XXXXX

How to get response of Ansible telnet module

Below are couple of IP addresses and their telnet response (output)
telnet 10.9.9.112 22
Trying 10.9.9.112......
telnet 10.9.9.143 22
Trying 10.9.9.143.....
telnet: connect to address 10.9.9.143: Connection refused.
For the first IP 10.9.9.112 there is no connection and firewall blocks any connection from source to destination. The output simply says Trying .... and stays that way without printing anything else.
For the second IP 10.9.9.143 i get Connection refused immediately in the output and the control back to the prompt.
I wish to grab both scenarios in when condition and perform different activities for both the cases.
I tried to use Ansible's telnet module but I don't know how to grab both the different outputs in the registered variable.
In my case it prints the same message for both the IPs.
Ansible output for first ip:
TASK [debug] *************************************
ok: [localhost] => {
"msg": "HERE:{u'msg': u'Timeout when waiting for 10.9.9.112', u'failed': True, 'changed': False, u'elapsed': 4}"
Ansible Output for second ip:
TASK [debug] *************************************
ok: [localhost] => {
"msg": "HERE:{u'msg': u'Timeout when waiting for 10.9.9.143', u'failed': True, 'changed': False, u'elapsed': 3}"
The only difference I see is the value for elapsed.
Here is my playbook.
---
- name: "Play 1"
hosts: localhost
tasks:
- wait_for:
hosts: "{{ item }}"
port: 22
state: started
delay: 3
timeout: 90
ignore_errors: yes
register: telnetout
loop:
- 10.9.9.112
- 10.9.9.143
- debug:
msg: "HERE: {{ telnetout }}"
telnet module unfortunately does not record Connection Refused message in the output.
We have to use raw module instead like below.
---
- name: "Play 1"
hosts: localhost
tasks:
- raw: "timeout --signal=9 2 telnet {{ item }} 22"
ignore_errors: yes
register: telnetout
loop:
- 10.9.9.112
- 10.9.9.143
- debug:
msg: "HERE: {{ telnetout }}"

Trying to get IPs from file and use it as Inventory in Ansible

I get list of IP address in test.text file from which I am trying to get the IP in loop
and then try to get in group or variable and use it as hosts (dynamic_groups)
Below is my playlist
---
- name: provision stack
hosts: localhost
connection: local
gather_facts: no
serial: 1
tasks:
- name: Get Instance IP Addresses From File
shell: cat /home/user/test.text
register: serverlist
- debug: msg={{ serverlist.stdout_lines }}
- name: Add Instance IP Addresses to temporary inventory groups
add_host:
groups: dynamic_groups
hostname: "{{item}}"
with_items: serverlist.stdout_lines
- hosts: dynamic_groups
become: yes
become_user: root
become_method: sudo
gather_facts: True
serial: 1
vars:
ansible_connection: "{{ connection_type }}"
ansible_ssh_user: "{{ ssh_user_name }}"
ansible_ssh_private_key_file: "{{ ssh_private_key_file }}"
tasks:
.....
.....
After running above playbbok I am getting below error
TASK [debug] *****************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": [
"192.168.1.10",
"192.168.1.11",
"192.168.1.50"
]
}
TASK [Add Instance IP Addresses to temporary inventory groups] ***************************************************************************************************************************************************************************
changed: [localhost] => (item=serverlist.stdout_lines)
PLAY [dynamic_groups] *********************************************************************************************************************************************************************************************************************
TASK [Some Command] **********************************************************************************************************************************************************************************************************************
fatal: [serverlist.stdout_lines]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: Could not resolve hostname serverlist.stdout_lines: Name or service not known", "unreachable": true}
What Am I missing here?
Below is correct way to use variable
- name: Add Instance IP Addresses to temporary inventory groups
add_host:
groups: working_hosts
hostname: "{{item}}"
with_items: "{{ serverlist.stdout_lines }}"
It should solve your problem.
As reported in fatal error message "Failed to connect to the host via ssh: ssh: Could not resolve hostname serverlist.stdout_lines", it is trying to connect to "serverlist.stdout_lines", not to a valid IP.
This is caused by an error when passing variable to with_items. In your task:
with_items: serverlist.stdout_lines
it is passing serverlist.stdout_lines string and not its value.
With_items requires variable definition using "{{ ... }}" (https://docs.ansible.com/ansible/2.7/user_guide/playbooks_loops.html#with-items).
This is the correct way for your task:
- name: Add Instance IP Addresses to temporary inventory groups
add_host:
groups: dynamic_groups
hostname: "{{item}}"
with_items: "{{ serverlist.stdout_lines }}"
You can simply use ansible-playbook -i inventory_file_name playbook.yaml for this. inventory_file is the file containing your groups and ips.

Resources