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.