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

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.

Related

Ansible playbook for startup script with arguments

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

how to install the script interactive via ansible playbook

I can run the script with the command line argument on the linux server it works fine.
for e.g.: ./install.sh -n -I <IP address of the server>
The above command is able to install the script on the server.
When I am trying to do via ansible (version 2.5) playbook using the shell module it gives me an argument error.
- name: Running the script
shell: yes | ./fullinstall
Expect modules has been tried.
--my-arg1=IP address
- shell: "./install.sh -n -I"
args:
chdir: somedir/
creates: somelog.txt
You can look here for examples.
You can also place the install.sh file on the server as a template. Then you can set the variables as desired in Jinja2.
- name: Template install.sh
template:
src: /install.sh.j2
dest: /tmp/install.sh
- shell: "cd /tmp/ ; ./install.sh
Your install.sh.j2 contains:
IP adres: {{ my_ip }}
And set the variable on the command line with:
ansible-playbook -e my_ip="192.168.0.1"
Use command module
- name: run script
command: /path/to/install.sh -n -I {{ ip_addrress }}
playbook
ansible-playbook -e ip_address="192.168.3.9" play.yml
If you want to interactively wanted to enter the IP address, use prompt module.

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

Setting an environment variable in Ansible from a command output of bash command

I would like to set output of a shell command as an environment variable in Ansible.
I did the following to achieve it:
- name: Copy content of config.json into variable
shell: /bin/bash -l -c "cat /storage/config.json"
register: copy_config
tags: something
- name: set config
shell: "echo $TEMP_CONFIG"
environment:
TEMP_CONFIG: "{{copy_config}}"
tags: something
But somehow after the ansible run, when I do run the following command:
echo ${TEMP_CONFIG}
in my terminal it gives an empty result.
Any help would be appreciated.
There are at least two problems:
You should pass copy_config.stdout as a variable
- name: set config
shell: "echo $TEMP_CONFIG"
environment:
TEMP_CONFIG: "{{copy_config.stdout}}"
tags: something
You need to register the results of the above task and then again print the stdout, so:
- name: set config
shell: "echo $TEMP_CONFIG"
environment:
TEMP_CONFIG: "{{copy_config.stdout}}"
tags: something
register: shell_echo
- debug:
var: shell_echo.stdout
You never will be able to pass the variable to a non-related process this way. So unless you registered the results in an rc-file (like ~/.bash_profile which is sourced on interactive login if you use Bash) no other shell process would be able to see the value of TEMP_CONFIG. This is how system works.

Resources