I want to pull all the interface names from a host and then print all the information of that interface.
--- # Fetches network interfaces with IPs
- hosts: hta
gather_facts: yes
become: yes
tasks
- debug: msg=" {{ ansible_interfaces|length }}"
register: num
- name: moving template over to server
template: src=templates/network.j2 dest=/root/network_info.txt
And the network.j2 file
{% for int in ansible_interfaces %}
Interfaces: Interface-{{ int }}
Data: ansible_{{ int }}
{% endfor %}
So far i couldn't print the information and Ansible takes my input ansible_{{ int }} as literal.
The play below
- command: "ifconfig {{ item }}"
register: result
loop: "{{ ansible_interfaces }}"
- template:
src: template.j2
dest: int.txt
delegate_to: localhost
with this template
{% for int in result.results %}
Interfaces: Interface-{{ int.item }}
Data: {{ int.stdout }}
{% endfor %}
creates at localhost the file int.txt with the interfaces' data.
What I dont really get is that you are calling a server to gather info about its interfaces and send a file back to that same server with the info you could gather again any time. I don't really see the point but here we go.
Applying the KISS principle: call ifconfig which will return details about all the interfaces and store the result in a file on remote host
playbook.yml
- name: Simple interface info dump on hosts
hosts: whatevergroup_you_need
become: true
gather_facts: false
tasks:
- name: dump ifconfig result to /root/network_interface.txt
shell: ifconfig > /root/network_interfaces.txt
Notes:
become: true is only needed because you want to write your file in root's home. If you write the file anywhere else with proper permissions, ifconfig itself is executable by anyone
Since there is no need to collect any other info from the host, gather_facts: false will speed up the playbook for this one single easy task.
shell module is mandatory for the output redirection to the file. If you are concerned about security, you can use the command module instead (without the file redirection), capture the output with register and write the content to a file in a next task
I assumed you were calling a linux host and that ifconfig was outputing the info you need. If it is not the case, you need to rewrite your question and be more accurate about what you are trying to achieve.
Related
Im trying to find a clean way of converting a files list into a path(string) list.
So far i came up with this:
- name: Get apt source files
find:
paths: /etc/apt/sources.list.d
use_regex: yes
patterns: '^.*\.list$'
register: source_files
- name: loop trough source files
when:
- item != SOME_VAR
- DO_CLEAN_UP
lineinfile:
path: "{{ item }}"
regexp: "^deb {{ REPO_CLEAN_URL }}" # set in vars/main.yml
state: absent
with_items:
- /etc/apt/sources.list
- "{{ source_files.files | items2dict(key_name='path', value_name='path') | list }}"
I would like to improve the "with_items" part please.
There is no such thing as file-object in Ansible playbooks, you only work with basic data types supported by YAML/JSON: string, list, mapping (dictionary), integer and boolean.
When in doubt make use of debug module to display variables and how jinja2 constructs are evaluated, works well even with loops.
I have to check the target vm's /etc/hosts file. If any ips which starts with 10...* Are there in that file.it should report yes and show the ips and if there is no ips .it should report No under that target hostname . All this information should come to build artifacts in azure pipelines.. please suggest me that possibilities
Using the file lookup was actually a pretty good start. But as all lookups, it only runs on the controller machine (localhost). If you need to run this on a remote target vm, you will have to read the file from there. The idea I followed below is:
Use the slurp module to get /etc/hosts content from the target in a variable on the controller
split the content of the file on the new line character to get a list of lines.
loop on those lines and add the matching ips to a list. The ips are searched using a regexp with the match test and the regex_search filter
show the content of the resulting list if that list is not empty.
The example playbook:
---
- name: Check ips starting with 10. in /etc/hosts
hosts: localhost
gather_facts: false
tasks:
- name: Slurp /etc/hosts content from target vm
slurp:
src: /etc/hosts
register: my_host_entries_slurped
- name: Read /etc/hosts file in a list line by line
set_fact:
my_host_entries: "{{ (my_host_entries_slurped.content | b64decode).split('\n') }}"
- name: Add matching ips to a list
vars:
ip_regex: "^10(\\.\\d{1,3}){3}"
set_fact:
matching_ips: "{{ matching_ips | default([]) + [item | regex_search(ip_regex)] }}"
when: item is match(ip_regex)
loop: "{{ my_host_entries }}"
- name: Show list of matching ips
debug:
var: matching_ips
when: matching_ips | default([]) | length > 0
You can adapt to match your exact needs.
Note: if you are not totally familiar with regexp, the one I used which is (without the escaped \\ in the yaml string)
^10(\.\d{1,3}){3}
means:
search for 10 at the beginning of the line folowed by a group of chars starting with a . and followed by 1 to 3 digits. Repeat this last group 3 times exactly.
I have followed the solution posted on the post
Ansible to update sshd config file however I am getting the following errors.
TASK [Add Group to AllowGroups]
fatal: [testpsr]: FAILED! => {"changed": false, "msg": "Unsupported parameters for (lineinfile) module: when Supported parameters include: attributes, backrefs, backup, content, create, delimiter, directory_mode, firstmatch, follow, force, group, insertafter, insertbefore, line, mode, owner, path, regexp, remote_src, selevel, serole, setype, seuser, src, state, unsafe_writes, validate"}
Here are the tasks I have.
- name: Capture AllowUsers from sshd_config
command: bash -c "grep '^AllowUsers' /etc/ssh/sshd_config.bak"
register: old_userlist changed_when: no
- name: Add Group to AllowUsers
lineinfile: regexp: "^AllowUsers"
backup: True
dest: /etc/ssh/sshd_config.bak
line: "{{ old_userlist.stdout }} {{ usernames }}"
when: - old_userlist is succeeded
The error tells you whats wrong.
FAILED! => {"changed": false, "msg": "Unsupported parameters for (lineinfile) module: when
You nested when under lineinfile module, while it should be nested under the task itself.
This is your code fixed and probably what you meant.
- name: Capture AllowUsers from sshd_config
command: "grep '^AllowUsers' /etc/ssh/sshd_config.bak"
register: old_userlist
changed_when: no
- name: Add Group to AllowUsers
lineinfile:
regexp: "^AllowUsers"
backup: yes
dest: /etc/ssh/sshd_config.bak
line: "{{ old_userlist.stdout }} {{ usernames }}"
when: old_userlist is succeeded
I also fixed a couple of things. Using bash -c in command is redundant in your case
Please make sure you are using code formatting when pasting code or logs on StackOverflow, as your question is currently unreadable.
I tried this in my task, but doesn't seem to work
- name: Fix line endings from CRLF to LF
local_action: replace dest={{my_dir}}/conf/{{item}} regexp='\r\n' replace='\n'
I usually do this using sed as follows and it works
sed -i 's/\r//g' file
I want to avoid using shell module to do this replacement as it throws a warning in ansible
You can remove the CRLF line endings with the -replace command. Your playbook might look like:
---
- hosts: all
tasks:
- local_action: replace dest={{my_dir}}/conf/{{item}} regexp="\r"
By not specifying the replace parameter in the - replace command, it will just remove all carriage returns. See http://docs.ansible.com/ansible/replace_module.html.
I tested this with a local file I created and it worked when testing on localhost. It also worked when I added localhost to the /etc/ansible/hosts file and had the following playbook instead:
---
- hosts: all
tasks:
- replace: dest={{my_dir}}/conf/{{item}} regexp="\r"
Just be sure to use the absolute filepath.
You can do something like this:
set_fact:
my_content: "{{ lookup('file', "{{my_dir}}/conf/{{item}}" ) | replace('\r\n', '\n')}}"
After this you can use the content or save in the disk.
The following converts line endings using the Jinja2 template engine. A line-ending directive is inserted at the beginning of the source file on the ansible machine (delegate_to: localhost). Sending the file to the downstream server can then be done by applying template or win_template to the file.
It handles source files with any line-ending, which could be useful if you're working through a list of files from more than one origin.
- name: prepare to add line endings
lineinfile:
insertbefore: BOF
dest: '{{ src_file }}'
line: '#jinja2: newline_sequence:"\n"'
#for Linux to Windows: #line: '#jinja2: newline_sequence:"\r\n"'
delegate_to: localhost
- name: copy changed file with correct line-endings
template: # win_template for Linux to Windows
src: '{{ src_file }}'
dest: '{{ dest_file }}'
Currently I have the following rule for creating a directory
/init/dir:
file.recurse:
- source: salt://init_dir/init
- user: name
- group: group
- name: /path/init
- dir_mode: 2775
- file_mode: 777
Now I want to create a directory on new minions only if the directory does not exists already.
While your example does work, it's not necessary. file.directory will only attempt to create the directory if it doesn't exist.
Turned out to be pretty easy and well documented in the salt-stack documentation
Below is what I came up with.
{% if not salt['file.directory_exists' ]('/home/init_dir') %}
/home/init_dir:
file.directory:
- user: user
- name: /home/init_dir
- group: group
- mode: 755
{% else %}
cmd.run:
- name: echo "Directory exists"
{% endif %}