Not possible to source .bashrc with Ansible
I can ssh to the remote host and do a source /home/username/.bashrc
- everything works fine.
However if I do:
- name: source bashrc
sudo: no
action: command source /home/username/.bashrc
I get:
failed: [hostname] => {"cmd": ["source", "/home/username/.bashrc"], "failed": true, "rc": 2}
msg: [Errno 2] No such file or directory
I have no idea what I'm doing wrong...
Solution 1:
You have two options to use source with ansible. One is with the "shell:" command and /bin/sh (the ansible default). "source" is called "." in /bin/sh. So your command would be:
- name: source bashrc
sudo: no
shell: . /home/username/.bashrc && [the actual command you want run]
Note you have to run a command after sourcing .bashrc b/c each ssh session is distinct - every ansible command runs in a separate ssh transaction.
Your second option is to force Ansible shell to use bash and then you can use the "source" command:
- name: source bashrc
sudo: no
shell: source /home/username/.bashrc && [the actual command you want run]
args:
executable: /bin/bash
Finally, I'll note that you may want to actually source "/etc/profile" if you're on Ubuntu or similar, which more completely simulates a local login.
Solution 2:
So command
will only run executables. source
per se is not an executable. (It's a builtin shell command).
Is there any reason why you want to source
a full environment variable?
There are other ways to include environment variables in Ansible. For example, the environment
directive:
- name: My Great Playbook
hosts: all
tasks:
- name: Run my command
sudo: no
action: command <your-command>
environment:
HOME: /home/myhome
Another way is to use the shell
Ansible module:
- name: source bashrc
sudo: no
action: shell source /home/username/.bashrc && <your-command>
or
- name: source bashrc
sudo: no
shell: source /home/username/.bashrc && <your-command>
In these cases, the shell instance/environment will terminate once the Ansible step is run.
Solution 3:
I know this answer come too late but I have seen in enough code you can use the sudo option -i
so:
- name: source bashrc
shell: sudo -iu {{ansible_user_id}} [the actual command you want run]
As said in the documentation
The -i (simulate initial login) option runs the shell specified by the password database entry of the target user as a login shell. This means that login-specific
resource files such as .profile or .login will be read by the shell. If a command is specified, it is passed to the shell for execution via the shell's -c option.
If no command is specified, an interactive shell is executed. sudo attempts to change to that user's home directory before running the shell. It also initializes
the environment to a minimal set of variables, similar to what is present when a user logs in. The Command environment section below documents in detail how the -i
option affects the environment in which a command is run.