I would like to run my ansible playbook against a remote test machine, but as way of testing I'd like to verify between each step that what I expected to be done was done.
I'd like to add, more or less, a "pause" task after every task command, but without actually putting it into my yaml script. Does ansible have any sort of 'debug' mode that would allow for this?
I'm using ansible 1.5, but am open to answers that use features in newer versions.
Yes, ansible has a "step" mode, which will make it to pause before every task and wait for user confirmation to execute the task.
Simply call your playbook with the step flag:
ansible-playbook ... --step
start-at-task
To gain time, you can use --start-at-task to execute only the last comands which are probably those who are bugging. But for that you have to name your task :
This shell task has no name
- shell: vagrant provision; vagrant up;
args:
chdir: /vm/vagrant
This one does :
- name: start vagrant
shell: vagrant provision; vagrant up;
args:
chdir: /vm/vagrant
then run :
ansible-playbook playbook.yml --start-at-task="start vagrant"
tags
Another helpful tip is to use tags. For exemple you want to try only one command
- shell: vagrant provision; vagrant up;
args:
chdir: /linux/{{item.name}}
tags: [shell, debug]
Now you can debug this one doing :
ansible-playbook playbook.yml --tags="debug"
And it will start only tasks that received the tag debug.
Verbose
And if you want more informations, you can ask Ansible to be more verbose using -v, -vv, -vvv or -vvvvv
ansible-playbook -vvvv playbook.yml --tags="debug"
This will tell you all it can on the specified task
I do not think ansible provides a feature like that. One way to do this is put a pause between plays and make it conditional. When you execute the playbook, define a variable which decides whether to pause or not.
- pause:
when: PAUSE is defined
When you execute the playbook, don't define PAUSE if you don't want to pause. But if you want to pause between plays, then define it.
ansible-playbook -v .... --extra-vars "PAUSE=yes" ... myplay.yml
Related
Is it possible in Ansible to write the startup script with input of arguments?
For example, in Unix, when we run it we can do:
/etc/init.d/SCRIPT start|stop|restart
Is it possible to do it in Ansible so it will read the input of start|stop|restart?
You can pass variables into your playbook at runtime using the -e argument. For example:
ansible-playbook playbook.yml -e mode=start
Given the above command line, inside the playbook, you can examine the mode variable:
- hosts: localhost
tasks:
- name: start something
command: echo do you want to be starting something
when: "mode|default('') == 'start'"
You can use as many -e arguments as you want, and you can include variables from a file rather than including them on the command line. E.g., if you have a file vars.yml, you could run:
ansible-playbook playbook.yml -e #vars.yml
So from one perspective, you would need to have three different tasks, each with a different when statement to handle the three start/stop/restart conditions.
But depending on what you're trying to do, there may be a simpler solution. If you're just trying to call the init script from a task, you could instead do this:
- hosts: localhost
tasks:
- name: start something
command: /etc/init.d/SCRIPT {{ mode }}
I am having a problem related to a Zabbix action.
I have a trigger that fires when my /mnt volume is full.
Then I have an action for that trigger that runs an Ansible playbook that will remove an image located at /mnt.
I tested the Ansible playbook on my local machine and it does the job.
Before I had a shell script to remove the image and that worked too.
But now it executes ansible-playbook /mnt/myplatform/playbook.yml and shows that the command was executed in the Zabbix log, but nothing happens.
Before sudo rm /mnt/test.img worked.
Now ansible-playbook /mnt/myplatform/playbook.yml doesn't work.
What is the difference between raw, shell and command in the ansible playbook? And when to use which?
command: executes a remote command on the target host, in the same shell of other playbook's tasks.
It can be used for launch scripts (.sh) or for execute simple commands. For example:
- name: Cat a file
command: cat somefile.txt
- name: Execute a script
command: somescript.sh param1 param2
shell: executes a remote command on the target host, opening a new shell (/bin/sh).
It can be used if you want to execute more complex commands, for example, commands concatenated with pipes. For example:
- name: Look for something in a file
shell: cat somefile.txt | grep something
raw: executes low-level commands where the interpreter is missing on the target host, a common use case is for installing python. This module should not be used in all other cases (where command and shell are suggested)
Since I were I stumbling about the same question, I wanted to share my findings here too.
The command and shell module, as well gather_facts (annot.: setup.py) depend on a properly installed Python interpreter on the Remote Node(s). If that requirement isn't fulfilled one may experience errors were it isn't possible to execute
python <ansiblePython.py>
In a Debian 10 (Buster) minimal installation i.e., python3 was installed but the symlink to python missing.
To initialize the system correctly before applying all other roles, I've used an approach with the raw module
ansible/initSrv/main.yml
- hosts: "{{ target_hosts }}"
gather_facts: no # is necessary because setup.py depends on Python too
pre_tasks:
- name: "Make sure remote system is initialized correctly"
raw: 'ln -s /usr/bin/python3 /usr/bin/python'
register: set_symlink
failed_when: set_symlink.rc != 0 and set_symlink.rc != 1
which is doing something like
/bin/sh -c 'ln -s /usr/bin/python3 /usr/bin/python'
on the remote system.
Further Documentation
raw module – Executes a low-down and dirty command
A common case is installing python on a system without python installed by default.
... but not only restricted to that
Playbook Keyword - pre_tasks
A list of tasks to execute before roles.
Set the order of task execution in Ansible
I'm trying to follow this solution to add use the shell module and ssh-keyscan to add a key to my known_hosts file of a newly created EC2 instance.
After trying to do this multiple ways as listed on that question I eventually ran just the ssh-keyscan command using the shell module without the append. I am getting no output from this task:
- name: accept new ssh fingerprints
shell: ssh-keyscan -H {{ item.public_ip }}
args:
executable: /bin/bash
with_items: "{{ ec2.instances }}"
register: keyscan
- debug: var=keyscan
Debug here shows nothing in stdout and stdout_lines and nothing in stderr and stderr_lines
Note: I tried running this with the bash as the executable shown after reading that the shell module defaults to /bin/sh which is the dash shell on my Linux Mint VirtualBox. But it's the same regardless.
I have tested the shell command with the following task and I see the proper output in stdout and stdout_lines:
- name: test the shell
shell: echo hello
args:
executable: /bin/bash
register: hello
- debug: var=hello
What is going on here? Running ssh-keyscan in a terminal (not through Ansible) works as expected.
EDIT: Looking at the raw_params output from debug shows ssh-keyscan -H x.x.x.x and copying and pasting this into the terminal works as expected.
The answer is that it doesn't work the first time. While researching another method I stumbled across the retries keyword in ansible that allows a retry of whatever command. I tried this and on attempt number 2 in the retry loop it is working.
I am new to Ansible. I have a bash script which has three arguments to be passed. I have to run this bash script on the remote server from Ansible.
Basically, I want to declare the hostname, duration and the comment fields as arguments while executing the Ansible command. I don't want to edit the file, as I am doing it from a Slack channel.
- hosts: nagiosserver
tasks:
- name: Executing a script
command: sh /home/aravind/downtime.sh {hostname} {duration} {comments}
If you're executing ansible via ansible-playbook myplay.yml, you can pass additional variables via -e varname=varvalue. A lazy fix would be to run with
ansible-playbook myplay.yml -e my_hostname=foo -e my_duration=bar -e my_comments=foobar
But you should consider that the hostname is already defined in your inventory or gathered facts.
So you could update your playbook to use these additional variables using
- hosts: nagiosserver
tasks:
- name: Executing a script
- command: "sh /home/aravind/downtime.sh {{my_hostname}} {{my_duration}} {{my_comments}}"