Ansible 无法调用剧本中主机名的变量

Ansible cannot invoke variable for hostname in playbook

我需要将新用户添加到多个 Ubuntu 服务器。不幸的是,密码和用户名不一致。每台机器都有自己的用户名,密码不能相同。例如,主机 1 将有一个用户帐户 host-1_username,密码为 host-1_password,主机 2 将有一个用户帐户 host-2_username,密码为 host-2_password,依此类推。

我想通过 Ansible 做到这一点。我有一个 list.yaml 文件:

---
list:
  - hostname: host-1
    username: host-1_username
    password: host-1_password
  - hostname: host-2
    username: host-2_username
    password: host-2_password
  - hostname: host-3
    username: host-3_username
    password: host-3_password

这是我的 Ansible 剧本:

- name: Crate new user
  vars_files:
    - list.yml
  hosts: "{{ item.hostname }}"
  remote_user: root
  become: true

  tasks:
  - name: Create new user
    ansible.builtin.user:
      name: "{{ item.username }}"
      groups: sudo
      password: "{{ item.password | password_hash('sha512') }}"
      shell: /bin/bash

  - name: Modify sshd_config 
    ansible.builtin.lineinfile:
      dest: /etc/ssh/sshd_config
      line: 'AllowUsers {{ item.username }}'
    
    loop: "{{ list }}"

但看起来 Ansible 无法调用变量添加到主机列中:

ERROR! couldn't resolve module/action 'hosts'. This often indicates a misspelling, missing collection, or incorrect module path.

我是 Ansible 的新手,非常感谢任何帮助!

给定数据

shell> cat list.yml 
users_list:
  - hostname: host-1
    username: host-1_username
    password: host-1_password
  - hostname: host-2
    username: host-2_username
    password: host-2_password
  - hostname: host-3
    username: host-3_username
    password: host-3_password

创建清单文件,例如

shell> cat hosts
host-1
host-2
host-3

将数据转换为字典,例如

- hosts: all
  gather_facts: false
  vars_files:
    - list.yml
  tasks:
    - set_fact:
        users_dict: "{{ users_list|items2dict(key_name='hostname', value_name='username') }}"
        psswd_dict: "{{ users_list|items2dict(key_name='hostname', value_name='password') }}"
      run_once: true

给予

  users_dict:
    host-1: host-1_username
    host-2: host-2_username
    host-3: host-3_username

  psswd_dict:
    host-1: host-1_password
    host-2: host-2_password
    host-3: host-3_password

使用字典select 主机的特定用户和密码,例如

    - debug:
        msg: "Create user: {{ users_dict[inventory_hostname] }}
              password: {{ psswd_dict[inventory_hostname] }}"

给予

TASK [debug] ***************************************************************
ok: [host-1] => 
  msg: 'Create user: host-1_username password: host-1_password'
ok: [host-2] => 
  msg: 'Create user: host-2_username password: host-2_password'
ok: [host-3] => 
  msg: 'Create user: host-3_username password: host-3_password'

您可以省略清单文件并创建完全由数据驱动的剧本。在第一个play中创建动态组my_group并在第二个play中使用它。下面的剧本给出了相同的结果

- name: Create dynamic group of the hosts from users_list
  hosts: localhost
  gather_facts: false
  vars_files:
    - list.yml
  tasks:
    - add_host:
        name: "{{ item.hostname }}"
        groups: my_group
      loop: "{{ users_list }}"

- name: Create users
  hosts: my_group
  gather_facts: false
  vars_files:
    - list.yml
  tasks:
    - set_fact:
        users_dict: "{{ users_list|items2dict(key_name='hostname', value_name='username') }}"
        psswd_dict: "{{ users_list|items2dict(key_name='hostname', value_name='password') }}"
      run_once: true
    - debug:
        var: users_dict
      run_once: true
    - debug:
        var: psswd_dict
      run_once: true
    - debug:
        msg: "Create user: {{ users_dict[inventory_hostname] }}
              password: {{ psswd_dict[inventory_hostname] }}"