Ansible playbook for startup script with arguments - ansible

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 }}

Related

Use string variable (or some other way) as command with args?

Is it possible to pass command (with args) as variable in ansible?
For example, I have this playbook:
- name: My playbook
hosts: myhosts
tasks:
- name: Run Service Command
ansible.builtin.command: "docker compose run --rm service {{ cmd }}"
args:
chdir: "{{ PATH_COMPOSE_DIR }}"
And then I try to run it as:
ansible-playbook my-book.yml -e cmd="my-cmd --arg1 --arg2"
But then it just stucks on running it and nothing happens. Don't see any errors, anything.
If I fully define command on ansible task or just use variables on arg values, it works. But would be nice to be able to pass whole command, so playbook could be more versatile.

Whats the difference between ansible 'raw', 'shell' and 'command'?

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

Passing value of script variable to the playbook output

I'm quite new to Ansible so I'm still in learning curve. I'm looking for a way to retrieve a value from script's variable and use it further along with ansible-playbook command.
Saying I have a script I would like to retrieve $hostname info in target node. The script is run in a playbook. When a $HOSTNAME value returns, how can I pass it to my wrapper script so I can reference it with other list?
The script is as simple as follows:
HOSTNAME=$(hostname)
ECHO "$HOSTNAME"
Assuming you are running a script with ansible in one task, you would register the output:
tasks:
- name: Echo value
command: "echo Hello"
register: command_output
Then in your next task, maybe you want to create a file for the hostname:
- shell: "touch {{ item }} "
with_items:
- "{{ command_output.stdout_lines }}"
That's the basic structure - you don't say what command you want to run, but this should get you started.
Here's a nice tutorial: http://www.mydailytutorials.com/ansible-register-variables/

Execute a bash script with arguments in Ansible

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}}"

Does ansible have any feature to allow for debugging/pausing?

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

Resources