简体   繁体   中英

How to define sudo passwords for multiple hosts in one file vault?

I want to run updates on multiple Linux servers that all have different user names and passwords. I think this is a common use case, but it's not covered in the documentation. There is SSH auth, but I need elevated access for the update process and Ansible tasks require way too many permissions to do this through the sudoers files.

How do I get the different ansible_password from the inventory in one file vault so I can run the playbook, enter only one password to decrypt all sudo passwords, and have it work?

Inventory:

[servers]
1.2.3.4    ansible_user=user1 ansible_password=password1
1.2.3.5    ansible_user=user2 ansible_password=password2
1.2.3.6    ansible_user=user3 ansible_password=password3

Playbook:

---
- hosts: servers
  become: yes
  become_method: sudo
  gather_facts: false
  vars:
    verbose: false
    log_dir: "/var/log/ansible/dist-upgrade/{{ inventory_hostname }}"
  pre_tasks:
    - name: Install python for Ansible
      raw: sudo bash -c "test -e /usr/bin/python || (apt -qqy update && apt install -qy python-minimal)"
      changed_when: false
  tasks:
    - name: Update packages
      apt:
        update_cache: yes
        upgrade: dist
        autoremove: no
      register: output

    - name: Check changes
      set_fact:
        updated: true
      when: not output.stdout is search("0 upgraded, 0 newly installed")

    - name: Display changes
      debug:
        msg: "{{ output.stdout_lines }}"
      when: verbose or updated is defined

    - block:
      - name: "Create log directory"
        file:
          path: "{{ log_dir }}"
          state: directory
        changed_when: false

      - name: "Write changes to logfile"
        copy:
          content: "{{ output.stdout }}"
          dest: "{{ log_dir }}/dist-upgrade_{{ ansible_date_time.iso8601 }}.log"
        changed_when: false

      when: updated is defined
      connection: local

Q: "How do I get the different ansible_password from the inventory in one file vault?"

A: Create a dictionary with the passwords. For example, given the tree

shell> tree .
.
├── ansible.cfg
├── group_vars
│   └── servers
│       ├── ansible_password.yml
│       └── my_vault.yml
├── hosts
└── pb.yml
  1. Remove the passwords from the inventory file
shell> cat hosts
[servers]
1.2.3.4    ansible_user=user1
1.2.3.5    ansible_user=user2
1.2.3.6    ansible_user=user3
  1. Create a dictionary with the passwords
shell> cat group_vars/servers/my_vault.yml
my_vault:
  1.2.3.4:
    ansible_password: password1
  1.2.3.5:
    ansible_password: password2
  1.2.3.6:
    ansible_password: password3

and declare the variable ansible_password

shell> cat group_vars/servers/ansible_password.yml 
ansible_password: "{{ my_vault[inventory_hostname].ansible_password }}"
  1. Encrypt the file
shell> ansible-vault encrypt group_vars/servers/my_vault.yml
Encryption successful

shell> cat group_vars/servers/my_vault.yml
$ANSIBLE_VAULT;1.1;AES256
3361393763646264326661326433313837613531376266383239383761...
3564366531386130623162386332646366646561663763320a63353365...
...
  1. The playbook
shell> cat pb.yml
- hosts: servers
  tasks:
    - debug:
        var: ansible_password

gives

ok: [1.2.3.4] => 
  ansible_password: password1
ok: [1.2.3.5] => 
  ansible_password: password2
ok: [1.2.3.6] => 
  ansible_password: password3

Use pass the standard unix password manager

You can use pass instead of vault . For example, put the passwords into pass

shell> pass 1.2.3.4/user1
password1

shell> pass 1.2.3.5/user2
password2

shell> pass 1.2.3.6/user3
password3

and use the lookup plugin community.general.passwordstore . See details

shell> ansible-doc -t lookup community.general.passwordstore

Remove the file group_vars/servers/my_vault.yml and change the declaration of ansible_password

shell> cat group_vars/servers/ansible_password.yml
passwordstore_name: "{{ inventory_hostname }}/{{ ansible_user }}"
ansible_password: "{{ lookup('community.general.passwordstore',
                             passwordstore_name) }}"

The playbook above will give the same results.

Move ansible_user and ansible_password out of your inventory and into your host_vars directory. That is, make your inventory look like this:

[servers]
1.2.3.4
1.2.3.5
1.2.3.6

Then ansible-vault create host_vars/1.2.3.4.yml and give it the content:

ansible_user: user1
ansible_password: password1

And so on for the other hosts in your inventory.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM