首页 > 解决方案 > 如何在一个文件库中为多个主机定义 sudo 密码?

问题描述

我想在多个具有不同用户名和密码的 Linux 服务器上运行更新。我认为这是一个常见的用例,但文档中没有涵盖。有 SSH 身份验证,但我需要提升对更新过程的访问权限,而 Ansible 任务需要太多权限才能通过 sudoers 文件执行此操作。

如何从一个文件库中的清单中获取不同的ansible_password,以便我可以运行 playbook,只输入一个密码来解密所有 sudo 密码,并让它工作?

存货:

[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

剧本:

---
- 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

标签: ansible

解决方案


问:“我如何从一个文件库中的清单中获取不同的 ansible_password?”

A:可以使用set_fact和添加解密后的变量。例如

  1. 从清单文件中删除密码
[servers]
1.2.3.4    ansible_user=user1
1.2.3.5    ansible_user=user2
1.2.3.6    ansible_user=user3
  1. 使用密码创建字典
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'
  1. 加密文件
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
33613937636462643266613264333138376135313762663832393837616137323165363531666438
3564366531386130623162386332646366646561663763320a633533653631396637316138393339
66623531633936346363313965633565623566313264396636303136666432373037313666653630
3530343461616338370a323565346564383266323934376432383436646261313639663961343662
35336439646133333434363462616537323130373733363863646435376435343864323336323135
35623330303732666233313135643265393030386561306235303038353133386230336431396637
64663331316439336638646366636530626363353034326462393938363230386666303066383834
38643538343137633966336130393362303534666139373034356530303661643339623234356366
61316363333331613762663230616239643965333261353936373464366162646662323361626431
33663839386261313561396337393330616131663561646562373233373265646334383937386431
38386165653864363235646538353337373063376665386638653333646632316533363731663234
35663336663936653233
  1. 下面的剧本在第一次播放中将变量添加ansible_password到每个主机,并在第二次播放中使用它。例如
- hosts: servers
  gather_facts: false
  tasks:
    - set_fact:
        ansible_password: "{{ my_vault[inventory_hostname].ansible_password }}"
  
- hosts: servers
  tasks:
  - debug:
      var: ansible_password

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

推荐阅读