I recently learned that it's not possible to use the wildcard on Ansible. So I would like to know how could I run the next command with a Role.
cat /sys/class/net/*/address | while read mac
I tried to do it so, but it doesn't work.
- name: Cat address file
command: 'cat /sys/class/net/lo/address'
register: my_items
- name: Cat address file 2
command: 'cat /sys/class/net/enp2s0/address'
register: my_items
- name: Cat address file 3
command: 'cat /sys/class/net/wlo1/address'
register: my_items
- name: Read address file
command: read
with_items: my_items.stout_lines
I don't know whats your error but I used this and it works for me:
---
- hosts: dev
become: yes
tasks:
- name: get mac
shell: cat /sys/class/net/*/address
register: items
- name: debug
debug:
msg: "{{items.stdout_lines}}"
Result:
Related
I have an ansible play file that has to performs two tasks, first on the local machine get the disk usage and another task is to get the disk usage of a remote machine and install apache2 in the remote machine.
When I am trying to run the file I am getting the error "ERROR! 'sudo' is not a valid attribute for a Play"
When I remove the sudo and apt section from the yml file, it is running fine.
I am using ansible 2.9.4. Below are two playbook files:
File running without any error,
---
-
connection: local
hosts: localhost
name: play1
tasks:
-
command: "df -h"
name: "Find the disk space available"
-
command: "ls -lrt"
name: "List all the files"
-
name: "List All the Files"
register: output
shell: "ls -lrt"
-
debug: var=output.stdout_lines
-
hosts: RemoteMachine1
name: play2
tasks:
- name: "Find the disk space"
command: "df -h"
register: result
- debug: var=result.stdout_lines
File running with error:
---
-
connection: local
hosts: localhost
name: play1
tasks:
-
command: "df -h"
name: "Find the disk space available"
-
command: "ls -lrt"
name: "List all the files"
-
name: "List All the Files"
register: output
shell: "ls -lrt"
-
debug: var=output.stdout_lines
-
hosts: RemoteMachine1
name: play2
sudo: yes
tasks:
- name: "Find the disk space"
command: "df -h"
register: result
- name: "Install Apache in the remote machine"
apt: name=apache2 state=latest
- debug: var=result.stdout_lines
Complete error message:
ERROR! 'sudo' is not a valid attribute for a Play
The error appears to be in '/home/Documents/ansible/play.yml': line 20, column 3, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
-
hosts: RemoteMachine1
^ here
Ansible play keyword sudo was (long ago) deprecated with warnings in version 2.0 and removed in version 2.2
See the actual supported play keywords. Use:
become: true
- hosts: RemoteMachine1
name: play2
become: yes
tasks:
- name: "Find the disk space"
command: "df -h"
register: result
- name: "Install Apache in the remote machine"
apt: name=apache2 state=latest
- debug: var=result.stdout_lines
use become: yes it will run your tasks as the root user.
Become directives
I am trying to use hostname -f command in variable with ansible-playbook. After I set the variable, I will use it in sed command. When manually execute the commands it works but with Ansible, variable does not work.
When I echo $hostn output is empty.
---
- hosts: test
become: true
become_user: root
tasks:
- name: test
shell: "{{ item }}"
with_items:
- hostn=`hostname -f` <<<<<< not working
- echo $hostn <<<<<< not working
- sed -i "s/test/$hostn/g" /file <<<< manually works
Can you help me?
My advise would be that you should not try to fit all your commands in Ansible shell this way, but rather translate them into the corresponding Ansible modules.
What you are looking to achieve can be done with the replace module — in place of sed — and the Ansible fact ansible_hostname — in place of hostname -f.
This would be the equivalent playbook:
- hosts: test
become: true
become_user: root
tasks:
- replace:
path: /file
regexp: test
replace: "{{ ansible_hostname }}"
This question already has answers here:
Ansible - use fact from local host in remote host template
(2 answers)
Closed 4 years ago.
In a single playbook, I'm working with two hosts and want to use one host variable into another. Like number of files in directory on different hosts. Is there way to do so in ansible
- hosts: abc
tasks:
- name: Check
shell: ls -ltrh /tmp/test1/ | wc -l
register : something_result
- hosts: cde
tasks:
- name: True
shell: ls -ltrh /tmp/test1/ | wc -l
register: something2_result
failed_when: something2_result != something_result
When you register a variable for a shell module the output of the command will be put into a substructure output as explained on the documentation.
so for your code your have to compare something_result.stdout against something2_result.stdout at the failed_when keyword
please try as below::
- hosts: server1.com
tasks:
- name: do something
shell: ls -ltrh /home | wc -l
register : something_result
- name: set fact
set_fact:
var1: "{{ something_result.stdout }}"
- hosts: server2.com
tasks:
- name: do something
shell: ls -ltrh /home | wc -l
register: something2_result
failed_when: ( something2_result.stdout != hostvars['server1.com']['var1'] )
Use set_fact to register the variable for the host. Then call the variable using "hostvars"
In Ansible, I have written an Yaml playbook that takes list of host name and the executes command for each host. I have registered a variable for these task and at the end of executing a task I append output of each command to a single file.
But every time I try to append to my output file, only the last record is getting persisted.
---
- hosts: list_of_hosts
become_user: some user
vars:
output: []
tasks:
- name: some name
command: some command
register: output
failed_when: "'FAILED' in output"
- debug: msg="{{output | to_nice_json}}"
- local_action: copy content='{{output | to_nice_json}}' dest="/path/to/my/local/file"
I even tried to append using lineinfile using insertafter parameter yet was not successful.
Anything that I am missing?
You can try something like this:
- name: dummy
hosts: myhosts
serial: 1
tasks:
- name: create file
file:
dest: /tmp/foo
state: touch
delegate_to: localhost
- name: run cmd
shell: echo "{{ inventory_hostname }}"
register: op
- name: append
lineinfile:
dest: /tmp/foo
line: "{{ op }}"
insertafter: EOF
delegate_to: localhost
I have used serial: 1 as I am not sure if lineinfile tasks running in parallel will garble the output file.
Ansible doc recommend use copy:
- name: get jstack
shell: "/usr/lib/jvm/java/bin/jstack -l {{PID_JAVA_APP}}"
args:
executable: /bin/bash
register: jstackOut
- name: write jstack
copy:
content: "{{jstackOut.stdout}}"
dest: "tmp/jstack.txt"
If you want write local file, add this:
delegate_to: localhost
Why to complicate things ?
I did this like that and it worked:
ansible-playbook your_playbook.yml >> /file/you/want/to/redirect/output.txt
you can also try some parsing with grep or some other stuff with tee -a.
I always wonder what is the good way to replace the following shell tasks using the "ansible way" (with get_url, etc.):
- name: Install oh-my-zsh
shell: wget -qO - https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh | bash -
or
- name: Install nodesource repo
shell: curl -sL https://deb.nodesource.com/setup_5.x | bash -
This worked for me:
- name: Download zsh installer
get_url:
url: https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh dest=/tmp/zsh-installer.sh
- name: Execute the zsh-installer.sh
shell: /tmp/zsh-installer.sh
- name: Remove the zsh-installer.sh
file:
path: /tmp/zsh-installer.sh
state: absent
#RaviTezu solution doesn't work because the file/script that you wish to execute must be on the machine where you execute your play/role.
As per the documentation here
The local script at path will be transferred to the remote node and then executed.
So one way to do it is by downloading the file locally and using a task like below:
- name: execute the script.sh
script: /local/path/to/script.sh
Or you can do this:
- name: download setup_5.x file to tmp dir
get_url:
url: https://deb.nodesource.com/setup_5.x
dest: /tmp/
mode: 0755
- name: execute setup_5.x script
shell: setup_5.x
args:
chdir: /tmp/
I would go for the first method if you are uploading your own script, the second method is more useful in your case because the script might gets updated in time so you are sure each time you execute it it uses the latest script.
For me, the following statement worked:
- name: "Execute Script"
shell: curl -sL https://rpm.nodesource.com/setup_6.x | bash -
Consider using the get_url or uri module rather than running curl.
For example:
- name: Download setup_8.x script
get_url: url=https://deb.nodesource.com/setup_8.x dest=/opt mode=755
- name: Setup Node.js
command: /opt/setup_8.x
- name: Install Node.js (JavaScript run-time environment)
apt: name=nodejs state=present
This playbook is what I've come up with. So far, it's as close to an idiomatic solution as I have come, and seems to be idempotent.
It will check for the existence of a command (in this case, starship) and if/when the test fails it will download the script.
---
- name: Check for Starship command
command: command -v starship >/dev/null 2>&1
register: installed
no_log: true
ignore_errors: yes
- name: Download Starship installer
get_url:
url: https://starship.rs/install.sh
dest: /tmp/starship-installer.sh
mode: 'u+rwx'
when: installed.rc != 0
register: download
- name: Run the install script
shell: /tmp/starship-installer.sh
when: download.changed
- name: Remove the starship-installer.sh
file:
path: /tmp/starship-installer.sh
state: absent
May be this basic example can help you to start:
---
- name: Installing Zsh and git
apt: pkg=zsh,git state=latest
register: installation
- name: Backing up existing ~/.zshrc
shell: if [ -f ~/.zshrc ]; then mv ~/.zshrc{,.orig}; fi
when: installation|success
sudo: no
- name: Cloning oh-my-zsh
git:
repo=https://github.com/robbyrussell/oh-my-zsh
dest=~/.oh-my-zsh
when: installation|success
register: cloning
sudo: no
- name: Creating new ~/.zshrc
copy:
src=~/.oh-my-zsh/templates/zshrc.zsh-template
dest=~/.zshrc
when: cloning|success
sudo: no
Note the: "force=yes", which will always download the script, overriding the old one.
Also note the "changed_when", which you can refine per your case.
- name: 'Download {{ helm.install_script_url }}'
environment:
http_proxy: '{{proxy_env.http_proxy | default ("") }}'
https_proxy: '{{proxy_env.https_proxy | default ("") }}'
no_proxy: '{{proxy_env.no_proxy | default ("") }}'
get_url: url={{ helm.install_script_url | default ("") }} dest=/tmp/helm_install_script force=yes mode="0755"
when: helm.install_script_url is defined
tags:
- helm_x
- name: Run {{ helm.install_script_url }}
environment:
http_proxy: '{{proxy_env.http_proxy | default ("") }}'
https_proxy: '{{proxy_env.https_proxy | default ("") }}'
no_proxy: '{{proxy_env.no_proxy | default ("") }}'
command: "/tmp/helm_install_script"
register: command_result
changed_when: "'is up-to-date' not in command_result.stdout"
when: helm.install_script_url is defined
args:
chdir: /tmp/
tags:
- helm_x