i hope everyone can help me with my ansible task problem. I deploy the snmp configurations via ansible on my servers and work with snmp-extend to trigger my scripts over snmp with certain OIDs. After my playbook has run and ansible deploy the snmp configurations, i manually execute the following command to become the OID for certain extend, for example:
snmptranslate -On NET-SNMP-EXTEND-MIB::nsExtendOutput1Line.\"folder-size-/home\"
This part i would like to do automatically via ansible, i have the variables:
snmp_mountpoints_extends:
- folder-size
- folder-avail
- folder-used
and in my inventory I define for host the following variables:
server1:
custom_mountpoints:
- /home
- /opt
my ansible part:
name: Generate OIDs for custom inventroy variables
become: yes
shell: 'snmptranslate -On NET-SNMP-EXTEND-MIB::nsExtendOutput1Line.\"{{ item }}-{{ custom_mountpoints[0] }}\"'
with_items:
"{{ snmp_mountpoints_extends }}"
register: custom_mountpoints_output
when:
- custom_mountpoints is defined
- name: print output from custom_mountpoints_output
debug: msg={{ custom_mountpoints_output }}
This work fine but only for first host variable /home. How can I iterate over my custom_mountpoints with each vars from snmp_mountpoints_extends?
thank you in advance
According Ansible documentation Iterating over nested lists you may use the following approach
---
- hosts:localhost
become: false
gather_facts: false
vars:
server1:
custom_mountpoints:
- /home
- /opt
snmp_mountpoints_extends:
- folder-size
- folder-avail
- folder-used
tasks:
- name: Iterating over nested lists
debug:
msg: "{{ item[0] }} and {{ item[1] }}"
loop: "{{ server1.custom_mountpoints | product(snmp_mountpoints_extend) | list }}"
resulting into the desired output.
/home and folder-size
/home and folder-avail
/home and folder-used
/opt and folder-size
/opt and folder-avail
/opt and folder-used
we want to create ansible code that ask interactive questions like the bash script
for now we have the following bash script, with diff 43 Questions , that finally create ini file according to our Questions
bash /home/gentwo.bash
how many machines?23
how many datanode services?
IP address for first machine - andnenda01?
.
.
.
---
as we know we cant do the same with ansible as the following:
- hosts: 17.12.22.56
gather_facts: yes
vars:
app_name: interactive process
ansible_user: root
ansible_password: XXXXXXXXXXX
tasks:
- name: interactive process
script: "/home/gentwo.bash"
register: results
so what is the equivalent approach with ansible?
You can use prompts for interactive input
e.g. from docs:
---
- hosts: all
vars_prompt:
- name: username
prompt: What is your username?
private: no
- name: password
prompt: What is your password?
tasks:
- name: Print a message
ansible.builtin.debug:
msg: 'Logging in as {{ username }}'
Ansible Doc: https://docs.ansible.com/ansible/latest/user_guide/playbooks_prompts.html
I want to extract the path out of the output given by the below command:
Command:
/opt/myapp/dir/bin/client -a 8101 -h localhost -u user -p pass properties-global-export
Output:
client: JAVA_HOME not set; results may vary
Exporting file: org.fusesource.fabric.agent.properties
Exporting file: local.app.node.vendor.service4.properties
Exporting file: local.app.node.data.service3.properties
Exporting file: local.app.node.vendor.service1.properties
Exporting file: local.app.node.vendor.service2.properties
Files dumped into directory: /opt/myapp/install-node/node-2.1.11/data/properties-tmp
and use /opt/myapp/install-node/node-2.1.11/data/properties-tmp path to perform a copy command within my playbook.
- name: Export Properties File
no_log: true
shell: "{{ fuse_esb_client_dir }} -h localhost -a {{ karaf_port }} -u {{ karaf_user }} -p {{ karaf_pass }} properties-global-export | grep -o '\''/[^ ]*'\ "
register: temp
- set_fact:
tempPath: "{{ temp.stdout }}"
- name: All Files Exported To Path
debug: var=temp.stdout
- name: Backup All Property Files to {{ backup_location }}
command: cp -r "{{ tempPath }}" "{{ backup_location }}"
Piped the output to grep grep -o '\''/[^ ]*'\ " The Extra '\' and \ on the start and end is used to escape the regex characters within the playbook. (Remove These if you want to test in your cli)
This Gave Me This Output
/opt/myapp/install-node/node-2.1.11/data/properties-tmp
Dumped that output with set_fact and used it within my playbook.
Hopefully someone finds this usefull. :))) Also for the pros like Jeff :) please let me know if I can improve anything within my playbook.
This is one little part of my working ansible playbook.
I want to send the information which will be gathered to a log file (which the playbook will create)
I have tried so many different way but getting no where.
No error is coming back which can only tell me that the script is working but I guess its going somewhere else other than the destination which I would like it to do
Here is my script
Would be grateful of your thoughts and help
- name: netstat check
shell: netstat -tulnp | awk '{print $4}' | sed -n 's/.*:\([^",]*\)[",]*$/\1/p'
register: netstat
- name: copy output to local file
copy:
content: "{{ netstat.stdout}}"
dest: "/home/user_name/netstat.txt"
Thanks
I executed your playbook in my ansible server(hosts: localhost) and it works fine. A new file is created with the required output.
Incase you want it on the localhost, try giving delegate_to: localhost
- name: copy output to local file
copy:
content: "{{ netstat.stdout}}"
dest: "/home/user_name/netstat.txt"
delegate_to: localhost
I want to use ansible setup module to retrieve hosts specs and I tried with a bash for loop.
Ansible version: 2.4
My hosts inventory has been defined in a group of machines which I called rhelmachines
I would like to collect the following list of variables called "specs"
declare -a specs=("ansible_all_ipv4_addresses" "ansible_processor" "ansible_processor_cores" "ansible_uptime_seconds")
I am then trying to include the ansible command in a for bash loop:
for i in "${specs[#]}"
do
ansible rhelmachines -m setup -a 'filter='$i'
done
how can I concatenate multiple filters in one connection only ?
Thanks!
With a little sed hackery to convert ansible's output to JSON, you can use jq to extract only the pieces you need:
ansible -m setup localhost | sed -e 's/^[[:alpha:]].*[|].* [>][>] {$/{/' | jq -n '
[inputs |
.ansible_facts as $facts |
$facts.ansible_hostname as $hostname |
{($hostname): {
"ipv4_addresses": $facts.ansible_all_ipv4_addresses,
"processor": $facts.ansible_processor[0],
"cores": $facts.ansible_processor_cores,
"uptime": $facts.ansible_uptime_seconds}}] | add'
...generates output of the form:
{
"my-current-hostname": {
"ipv4_addresses": [
"192.168.119.129"
],
"processor": "Intel(R) Core(TM) i7-6700HQ CPU # 2.60GHz",
"cores": 1,
"uptime": null
}
}
(run with ansible 1.4.5, which doesn't generate uptime).
As one of the possible solution, I implemented an Ansible code exploiting Ansible facts. I implemented it first gathering the ansible facts. Then, I used a local_action and a loop. The loop indices are the several ansible facts. For every fact I am writing out a line of a file. In this way I am getting a file composed by all the ansible facts I declared in the loop for the rhelmachines.
---
- hosts: rhelmachines
gather_facts: True
tasks:
- name: Gather Facts
setup:
gather_subset=all
register: facts
- debug:
msg: "{{ facts.ansible_facts.ansible_all_ipv4_addresses }}"
- name: copy content from facts to output file
local_action:
module: lineinfile
line: "{{ item }}"
path: /tmp/assessments/facts.txt
loop:
- "{{ facts.ansible_facts.ansible_all_ipv4_addresses }}"
- "{{ facts.ansible_facts.ansible_all_ipv6_addresses }}"
I took #Luigi Sambolino answer and make it better. His answer was failing on more than one host in the inventory. He proposed using lineinfile which has one con in this situation - every fact that was the same as other machines were omitted. Other drawback was that results wasn't sorted together, all was mixed.
I needed to take some basic information about systems, like IP, OS version, and so on. Here's my playbook:
- hosts: all
gather_facts: true
ignore_unreachable: true
tasks:
- name: get the facts
setup:
gather_subset=all
register: facts
- name: remove file
local_action:
module: file
path: results
state: absent
- name: save results in file
local_action:
module: shell
cmd: echo "{{ item }}" >> results
with_together:
- "{{ facts.ansible_facts.ansible_default_ipv4.address }}"
- "{{ facts.ansible_facts.ansible_architecture }}"
- "{{ facts.ansible_facts.ansible_distribution }}"
- "{{ facts.ansible_facts.ansible_distribution_version }}"
- "{{ facts.ansible_facts.ansible_hostname }}"
- "{{ facts.ansible_facts.ansible_kernel }}"
Now the results look like this:
...
['10.200.1.21', 'x86_64', 'Ubuntu', '18.04', 'bacula', '4.15.18-7-pve']
['10.200.2.53', 'x86_64', 'Ubuntu', '18.04', 'webserver', '4.15.18-27-pve']
...
Square brackets can be deleted by sed and we have a nice CSV file that can be used with any spreadsheet, for example.
specs=( "ansible_all_ipv4_addresses"
"ansible_processor"
"ansible_processor_cores"
"ansible_uptime_seconds" )
args=( )
for spec in "${specs[#]}"; do args+=( -a "$spec" ); done
ansible rhelmachines -m setup "${args[#]}"
...will result in your final command being equivalent to:
ansible rhelmachines -m setup \
-a ansible_all_ipv4_addresses \
-a ansible_processor \
-a ansible_processor_cores \
-a ansible_uptime_seconds