ansible connects with default remote_user even if I specify another one

Viewed 1399

I create a virtual linux server using an ansible module from my hoster. This works fine. The next task should add a user 'ansible' using

- include: task-files/users_create_ansible_user.yml
    delegate_to: '{{ createdserver.ipv4_address }}'
    remote_user: root

As you see I added remote_user in here (I also added it to the task that is included).

But despite those two remote_user entries it still tries to connect with the remote_user that is set in ansible.cfg (There I set remote_user to 'ansible' as I want to do all the following tasks with this user once it has been created).

More Details:

This is the first task in the included tasks file (this fails)

- name: "Create 'ansible' user"
  remote_user: root
  user:
    name: "ansible"

that returns

fatal: [localhost]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ansible@116.203.119.43: Permission denied (publickey,password).", "unreachable": true}'

As you can see it does not connect with the specified remote_user: root but with the user 'ansible' (not created yet). When I change the remote_user in ansible.cfg to root...it can connect here.

Can anyone guide me to my misconception?

1 Answers

Q: "Does not connect with the specified remote_user: root but with the user 'ansible'."

A: Very probably the remote_user is overridden by the variable ansible_user. The variable has a higher precedence. See the last section. For example


    - set_fact:
        ansible_user: admin
    - command: whoami
      remote_user: root
      register: result
    - debug:
        var: result.stdout

give

    "result.stdout": "admin"

Without the variable ansible_user this should work. remote_user is defined on the task level. For example,

    - command: whoami
      remote_user: admin
      register: result
    - debug:
        var: result.stdout

    - command: whoami
      remote_user: root
      register: result
    - debug:
        var: result.stdout

give

    "result.stdout": "admin"

    "result.stdout": "root"


Debug

Put a debug task into the code and see the value of the variable ansible_user. For example

- debug:
    var: ansible_user
- name: "Create 'ansible' user"
  remote_user: root
  user:
    name: "ansible"

Use ansible_user

Use ansible_user if there shouldn't be any chance to override the value.

See also parameter remote_user of the SSH connect plugin. remote_user is the parameter in the Ansible configuration. Instead, it is also possible to use variable ansible_user to change the remote user from a playbook, or task. The variable has the highest preference. See the last section. For example

    - command: whoami
      register: result
      vars:
        ansible_user: admin
    - debug:
        var: result.stdout

    - command: whoami
      register: result
      vars:
        ansible_user: root
    - debug:
        var: result.stdout

work as expected and give


    "result.stdout": "admin"

    "result.stdout": "root"
}

Best practice is to use public key authentication with the password of the private key provided by ssh-agent.


Disable root login

But, the best practice is to Disable root login: "Use a normal user account to initiate your connection instead, together with sudo." For example

    - command: whoami
      register: result
      become: true
      become_method: sudo
      become_user: root
      vars:
        ansible_user: admin
    - debug:
        var: result.stdout

gives

    "result.stdout": "root"

The remote user admin must be allowed sudo, of course

root@test_01> cat /usr/local/etc/sudoers
...
admin ALL=(ALL) NOPASSWD: ALL


Precedence

It's necessary to understand that many configuration parameters can be overridden by variables from play to the task level. In most cases, these variables are created from the name of the parameter by the addition of the prefix ansible_. The variable ansible_user and parameter remote_user is an exception (FWIW, I'm not aware of any other exception).

It's also important to keep in mind that the variables got precedence over playbook's keywords.

As an example, become directives can also be specified as variables. For example

    - command: whoami
      register: result
      vars:
        ansible_user: admin
        ansible_become: true
        ansible_become_method: sudo
        ansible_become_user: root
    - debug:
        var: result.stdout

gives

    "result.stdout": "root"
Related