Specify sudo password for Ansible

Ansible

Ansible Problem Overview


How do I specify a sudo password for Ansible in non-interactive way?

I'm running Ansible playbook like this:

$ ansible-playbook playbook.yml -i inventory.ini \
    --user=username --ask-sudo-pass

But I want to run it like this:

$ ansible-playbook playbook.yml -i inventory.ini \
    --user=username` **--sudo-pass=12345**

Is there a way? I want to automate my project deployment as much as possible.

Ansible Solutions


Solution 1 - Ansible

The docs strongly recommend against setting the sudo password in plaintext, and instead using --ask-sudo-pass on the command line when running ansible-playbook


2016 Update:

Ansible 2.0 (not 100% when) marked --ask-sudo-pass as deprecated. The docs now recommend using --ask-become-pass instead, while also swapping out the use of sudo throughout your playbooks with become.

Solution 2 - Ansible

You can pass variable on the command line via --extra-vars "name=value". Sudo password variable is ansible_sudo_pass. So your command would look like:

ansible-playbook playbook.yml -i inventory.ini --user=username \
                              --extra-vars "ansible_sudo_pass=yourPassword"

Update 2017: Ansible 2.2.1.0 now uses var ansible_become_pass. Either seems to work.

Update 2021: ansible_become_pass is still working, but for now, we should use -e instead of --extra-vars

Solution 3 - Ansible

Probably the best way to do this - assuming that you can't use the NOPASSWD solution provided by scottod - is to use Mircea Vutcovici's solution in combination with Ansible vault Archived.

For example, you might have a playbook something like this:

- hosts: all

  vars_files:
    - secret

  tasks:
    - name: Do something as sudo
      service: name=nginx state=restarted
      sudo: yes

Here we are including a file called secret which will contain our sudo password.

We will use ansible-vault to create an encrypted version of this file:

ansible-vault create secret

This will ask you for a password, then open your default editor to edit the file. You can put your ansible_sudo_pass in here.

e.g.: secret:

ansible_sudo_pass: mysudopassword

Save and exit, now you have an encrypted secret file which Ansible is able to decrypt when you run your playbook. Note: you can edit the file with ansible-vault edit secret (and enter the password that you used when creating the file)

The final piece of the puzzle is to provide Ansible with a --vault-password-file which it will use to decrypt your secret file.

Create a file called vault.txt and in that put the password that you used when creating your secret file. The password should be a string stored as a single line in the file.

From the Ansible Docs:

> .. ensure permissions on the file are such that no one else can access your key and do not add your key to source control

Finally: you can now run your playbook with something like

ansible-playbook playbook.yml -u someuser -i hosts --sudo --vault-password-file=vault.txt 

The above is assuming the following directory layout:

.
|_ playbook.yml
|_ secret
|_ hosts
|_ vault.txt

You can read more about Ansible Vault here: https://docs.ansible.com/playbooks_vault.html Archived


https://docs.ansible.com/ansible/latest/user_guide/vault.html

Solution 4 - Ansible

Looking at the code (runner/__init__.py), I think you can probably set it in your inventory file :

[whatever]
some-host ansible_sudo_pass='foobar'

There seem to be some provision in ansible.cfg config file too, but not implemented right now (constants.py).

Solution 5 - Ansible

I don't think ansible will let you specify a password in the flags as you wish to do. There may be somewhere in the configs this can be set but this would make using ansible less secure overall and would not be recommended.

One thing you can do is to create a user on the target machine and grant them passwordless sudo privileges to either all commands or a restricted list of commands.

If you run sudo visudo and enter a line like the below, then the user 'privilegedUser' should not have to enter a password when they run something like sudo service xxxx start:

%privilegedUser ALL= NOPASSWD: /usr/bin/service

Solution 6 - Ansible

The sudo password is stored as a variable called ansible_sudo_pass. You can set this variable in a few ways:

Per host, in your inventory hosts file (inventory/<inventoryname>/hosts)

[server]
10.0.0.0 ansible_sudo_pass=foobar

Per group, in your inventory groups file (inventory/<inventoryname>/groups)

[server:vars]
ansible_sudo_pass=foobar

Per group, in group vars (group_vars/<groupname>/ansible.yml)

ansible_sudo_pass: "foobar"

Per group, encrypted (ansible-vault create group_vars/<groupname>/ansible.yml)

ansible_sudo_pass: "foobar"

Solution 7 - Ansible

You can set the password for a group or for all servers at once:

[all:vars]
ansible_sudo_pass=default_sudo_password_for_all_hosts

[group1:vars]
ansible_sudo_pass=default_sudo_password_for_group1

Solution 8 - Ansible

I was tearing my hair out over this one, now I found a solution which does what i want:

1 encrypted file per host containing the sudo password

/etc/ansible/hosts:

[all:vars]
ansible_ssh_connection=ssh ansible_ssh_user=myuser ansible_ssh_private_key_file=~/.ssh/id_rsa

[some_service_group]
node-0
node-1

then you create for each host an encrypted var-file like so:

ansible-vault create /etc/ansible/host_vars/node-0

with content

ansible_sudo_pass: "my_sudo_pass_for_host_node-0"

how you organize the vault password (enter via --ask-vault-pass) or by cfg is up to you

based on this i suspect you can just encrypt the whole hosts file...

Solution 9 - Ansible

A more savvy way to do this is to store your sudo password in a secure vault such as LastPass or KeePass and then pass it to ansible-playbook using the -e@ but instead of hardcoding the contents in an actual file, you can use the construct -e@<(...) to run a command in a sub-shell, and redirect its output (STDOUT) to a anonymous file descriptor, effectively feeding the password to the -e@<(..).

Example
$ ansible-playbook -i /tmp/hosts pb.yml \
   -e@<(echo "ansible_sudo_pass: $(lpass show folder1/item1 --password)")

The above is doing several things, let's break it down.

  • ansible-playbook -i /tmp/hosts pb.yml - obviously running a playbook via ansible-playbook
  • $(lpass show folder1/item1 --password)" - runs the LastPass CLI lpass and retrieves the password to use
  • echo "ansible_sudo_pass: ...password..." - takes the string 'ansible_sudo_pass: ' and combines it with the password supplied by lpass
  • -e@<(..) - puts the above together, and connects the subshell of <(...) as a file descriptor for ansible-playbook to consume.
Further improvements

If you'd rather not type that every time you can simply things like so. First create an alias in your .bashrc like so:

$ cat ~/.bashrc
alias asp='echo "ansible_sudo_pass: $(lpass show folder1/item1 --password)"'

Now you can run your playbook like this:

$ ansible-playbook -i /tmp/hosts pb.yml -e@<(asp)
References

Solution 10 - Ansible

If you are comfortable with keeping passwords in plain text files, another option is to use a JSON file with the --extra-vars parameter (be sure to exclude the file from source control):

ansible-playbook --extra-vars "@private_vars.json" playbook.yml 

Ansible has supported this option since 1.3.

Solution 11 - Ansible

Ansible vault has been suggested a couple of times here, but I prefer git-crypt for encrypting sensitive files in my playbooks. If you're using git to keep your ansible playbooks, it's a snap. The problem I've found with ansible vault is that I inevitably end up coming across encrypted copies of the file that I want to work with and have to go decrypt it before I can work. git-crypt offers a nicer workflow IMO.

Using this, you can put your passwords in a var in your playbook, and mark your playbook as an encrypted file in .gitattributes like this:

 my_playbook.yml filter=git-crypt diff=git-crypt

Your playbook will be transparently encrypted on Github. Then you just need to either install your encryption key on the host you use to run ansible, or follow the instruction on the documentation to set it up with gpg.

There's a good Q&A on forwarding gpg keys like your ssh-agent forwards SSH keys here: https://superuser.com/questions/161973/how-can-i-forward-a-gpg-key-via-ssh-agent.

Solution 12 - Ansible

you can write sudo password for your playbook in the hosts file like this:

[host-group-name]
host-name:port ansible_sudo_pass='*your-sudo-password*'

Solution 13 - Ansible

My hack to automate this was to use an environment variable and access it via --extra-vars="ansible_become_pass='{{ lookup('env', 'ANSIBLE_BECOME_PASS') }}'".

Export an env var, but avoid bash/shell history (prepend with a space, or other methods). E.g.:

     export ANSIBLE_BECOME_PASS='<your password>'

Lookup the env var while passing the extra ansible_become_pass variable into the ansible-playbook, E.g.:

ansible-playbook playbook.yml -i inventories/dev/hosts.yml -u user --extra-vars="ansible_become_pass='{{ lookup('env', 'ANSIBLE_BECOME_PASS') }}'"

Good alternate answers:

Solution 14 - Ansible

Using ansible 2.4.1.0 and the following shall work:

[all]
17.26.131.10
17.26.131.11
17.26.131.12
17.26.131.13
17.26.131.14

[all:vars]
ansible_connection=ssh
ansible_user=per
ansible_ssh_pass=per
ansible_sudo_pass=per

And just run the playbook with this inventory as:

ansible-playbook -i inventory copyTest.yml

Solution 15 - Ansible

You can use ansible vault which will code your password into encrypted vault. After that you can use variable from vault in playbooks.

Some documentation on ansible vault:
http://docs.ansible.com/playbooks_vault.html

We are using it as vault per environment. To edit vault we have command as:
ansible-vault edit inventories/production/group_vars/all/vault

If you want to call vault variable you have to use ansible-playbook with parameters like:
ansible-playbook -s --vault-password-file=~/.ansible_vault.password

Yes we are storing vault password in local directory in plain text but it's not more dangerous like store root password for every system. Root password is inside vault file or you can have it like sudoers file for your user/group.

I'm recommending to use sudoers file on the server. Here is example for group admin:
%admin ALL=(ALL) NOPASSWD:ALL

Solution 16 - Ansible

You can use sshpass utility as below,

$ sshpass -p "your pass" ansible pattern -m module -a args \
   -i inventory --ask-sudo-pass

Solution 17 - Ansible

Just call your playbook with --extra-vars "become_pass=Password"

become_pass=('ansible_become_password', 'ansible_become_pass')

Solution 18 - Ansible

After five years, I can see this is still a very relevant subject. Somewhat mirroring leucos's answer which I find the best in my case, using ansible tools only (without any centralised authentication, tokens or whatever). This assumes you have the same username and the same public key on all servers. If you don't, of course you'd need to be more specific and add the corresponding variables next to the hosts:

[all:vars]
ansible_ssh_user=ansible
ansible_ssh_private_key_file=home/user/.ssh/mykey
[group]
192.168.0.50 ansible_sudo_pass='{{ myserver_sudo }}'

ansible-vault create mypasswd.yml
ansible-vault edit mypasswd.yml

Add:

myserver_sudo: mysecretpassword

Then:

ansible-playbook -i inv.ini my_role.yml --ask-vault --extra-vars '@passwd.yml'

At least this way you don't have to write more the variables which point to the passwords.

Solution 19 - Ansible

Just an addendum, so nobody else goes through the annoyance I recently did:

AFAIK, the best solution is one along the general lines of toast38coza's above. If it makes sense to tie your password files and your playbook together statically, then follow his template with vars_files (or include_vars). If you want to keep them separate, you can supply the vault contents on the command line like so:

ansible-playbook --ask-vault-pass -e@<PATH_TO_VAULT_FILE> <PLAYBOOK_FILE>

That's obvious in retrospect, but here are the gotchas:

  1. That bloody @ sign. If you leave it out, parsing will fail silently, and ansible-playbook will proceed as though you'd never specified the file in the first place.

  2. You must explicitly import the contents of the vault, either with a command-line --extra-vars/-e or within your YAML code. The --ask-vault-pass flag doesn't do anything by itself (besides prompt you for a value which may or may not be used later).

May you include your "@"s and save an hour.

Solution 20 - Ansible

Above solution by @toast38coza worked for me; just that sudo: yes is deprecated in Ansible now. Use become and become_user instead.

tasks:
 - name: Restart apache service
   service: name=apache2 state=restarted
   become: yes
   become_user: root

Solution 21 - Ansible

For new updates

just run your playbook with the flag -K and he will ask you for your sudo password

g.e ansible-playbook yourPlaybookFile.yaml -K

from the doc

> To specify a password for sudo, run ansible-playbook with --ask-become-pass (-K for short)

Solution 22 - Ansible

we Can also Use EXPECT BLOCK in ansible to spawn bash and customize it as per your needs

- name: Run expect to INSTALL TA
  shell: |
    set timeout 100
    spawn /bin/sh -i

    expect -re "$ "
    send "sudo yum remove -y xyz\n"

    expect "$ "
    send "sudo yum localinstall -y {{ rpm_remotehost_path_for_xyz }}\n"

    expect "~]$ "
    send "\n"

    exit 0
  args:
  executable: /usr/bin/expect

Solution 23 - Ansible

If you are using the pass password manager, you can use the module passwordstore, which makes this very easy.

Let's say you saved your user's sudo password in pass as

> Server1/User

Then you can use the decrypted value like so

{{ lookup('community.general.passwordstore', 'Server1/User')}}"

I use it in my inventory:

---
   servers:
     hosts:
       server1:
         ansible_become_pass: "{{ lookup('community.general.passwordstore', 'Server1/User')}}"

Note that you should be running gpg-agent so that you won't see a pinentry prompt every time a 'become' task is run.

Solution 24 - Ansible

You can pass it during playbook execution. the syntax is -

ansible-playbook -i inventory my.yml \
--extra-vars 'ansible_become_pass=YOUR-PASSWORD-HERE'

But that is not a good idea for security reasons. Better to use ansible vault

First update your inventory file as follows:

[cluster:vars]
k_ver="linux-image-4.13.0-26-generic"
ansible_user=vivek  # ssh login user
ansible_become=yes  # use sudo 
ansible_become_method=sudo 
ansible_become_pass='{{ my_cluser_sudo_pass }}'
 
[cluster]
www1
www2
www3
db1
db2
cache1
cache2

Next create a new encrypted data file named password.yml, run the following command:

$ ansible-vault create passwd.yml

Set the password for vault. After providing a password, the tool will start whatever editor you have defined with $EDITOR. Append the following my_cluser_sudo_pass: your_sudo_password_for_remote_servers Save and close the file in vi/vim. Finally run playbook as follows:

$ ansible-playbook -i inventory --ask-vault-pass --extra-vars '@passwd.yml' my.yml

How to edit my encrypted file again

ansible-vault edit passwd.yml

How to change password for my encrypted file

ansible-vault rekey passwd.yml

Solution 25 - Ansible

Very simple, and only add in the variable file:

Example:

$ vim group_vars/all

And add these:

Ansible_connection: ssh
Ansible_ssh_user: rafael
Ansible_ssh_pass: password123
Ansible_become_pass: password123

Solution 26 - Ansible

This worked for me... Created file /etc/sudoers.d/90-init-users file with NOPASSWD

echo "user ALL=(ALL)       NOPASSWD:ALL" > 90-init-users

where "user" is your userid.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSlava Fomin IIView Question on Stackoverflow
Solution 1 - AnsibledeefourView Answer on Stackoverflow
Solution 2 - AnsibleAlexandr NikitinView Answer on Stackoverflow
Solution 3 - Ansibletoast38cozaView Answer on Stackoverflow
Solution 4 - AnsibleleucosView Answer on Stackoverflow
Solution 5 - AnsiblescottodView Answer on Stackoverflow
Solution 6 - AnsibleBouke VersteeghView Answer on Stackoverflow
Solution 7 - AnsibleMircea VutcoviciView Answer on Stackoverflow
Solution 8 - Ansiblegreenone83View Answer on Stackoverflow
Solution 9 - AnsibleslmView Answer on Stackoverflow
Solution 10 - AnsiblesidecarcatView Answer on Stackoverflow
Solution 11 - Ansibleuser2432419View Answer on Stackoverflow
Solution 12 - AnsiblefawadRafiqView Answer on Stackoverflow
Solution 13 - AnsibleJPvRielView Answer on Stackoverflow
Solution 14 - AnsibleHearenView Answer on Stackoverflow
Solution 15 - AnsiblemaxoView Answer on Stackoverflow
Solution 16 - AnsibleSachinView Answer on Stackoverflow
Solution 17 - AnsibleCryptoView Answer on Stackoverflow
Solution 18 - AnsibleLethargosView Answer on Stackoverflow
Solution 19 - AnsibleEric AndersonView Answer on Stackoverflow
Solution 20 - AnsibleNätuView Answer on Stackoverflow
Solution 21 - AnsibleHamza AZIZView Answer on Stackoverflow
Solution 22 - AnsibleAshish RanjanView Answer on Stackoverflow
Solution 23 - AnsibleArneJView Answer on Stackoverflow
Solution 24 - AnsibleSudipView Answer on Stackoverflow
Solution 25 - AnsiblerafaelrmsView Answer on Stackoverflow
Solution 26 - AnsibleScottMView Answer on Stackoverflow