Ansible 运行 循环中本地的许多命令中的一个

Ansible running one command out of many locally in a loop

背景,

我正在尝试创建一个循环,该循环遍历从 qa.yml 文件中读取的哈希值,并针对列表中的每个用户尝试在本地服务器上查找文件(public 键) ,一旦找到文件,它就会在远程机器上创建用户,并将 public 密钥复制到远程机器上的 authorized_key。

我正在尝试以迭代的方式实现它,所以为了更新密钥或添加更多用户密钥,我需要更改 .yml 列表并将 public 密钥文件放在合适的地方。但是我无法让 local_action + find 工作。

---
- hosts: tag_Ansible_CLOUD_QA

  vars_files:
    - ../users/qa.yml
    - ../users/groups.yml
  remote_user: ec2-user
  sudo: yes

  tasks:

  - name: Create groups
    group: name="{{ item.key }}" state=present
    with_dict: "{{ user_groups }}"

  - name: Create remote users QA
    user: name="{{ item.key }}" comment="user" group=users groups="qa"
    with_dict: "{{ qa_users }}"

  - name: Erase previous authorized keys QA
    shell: rm -rf /home/"{{ item.key }}"/.ssh/authorized_keys
    with_dict: "{{ qa_users }}"

  - name: Add public keys to remote users QA
    local_action:
      find: paths="{{'/opt/pubkeys/2016/q2/'}}" patterns="{{ item.key }}"
      register: result
    authorized_key: user="{{ item.key }}" key="{{ lookup('file', result) }}"
    with_dict: "{{ qa_users }}"

哈希:

qa_users:
  user1:
    name: User 1
  user2:
    name: User 2

你在最后一个任务中将两个任务塞进一个任务项中,所以 Ansible 不会喜欢那样。

正确拆分任务应该可行:

  - name: Find keys
    local_action: find paths="{{'/opt/pubkeys/2016/q2/'}}" patterns="{{ item.key }}"
    register: result
    with_dict: "{{ qa_users }}"

  - name: Add public keys to remote users QA
    authorized_key: user="{{ item.0.key }}" key="{{ lookup('file', item.1.stdout) }}"
    with_together:
      - "{{ qa_users }}"
      - result

第二个任务然后使用 with_together 循环遍历字典和前一个任务的结果,该循环逐步通过两个数据结构。

但是,这似乎不是解决您问题的理想方法。

如果你看看你的任务在这里试图做什么,你可以用这样的东西更简单地替换它:

  - name: Add public keys to remote users QA
    authorized_key: user="{{ item.key }}" key="{{ lookup('file', '/opt/pubkeys/2016/q2/' + item.key ) }}"
    with_dict:
      - "{{ qa_users }}"

您还可以通过简单地使用 authorized_keys 模块的 exclusive 参数来删除清除用户以前的密钥的 thid 任务:

  - name: Add public keys to remote users QA
    authorized_key: user="{{ item.key }}" key="{{ lookup('file', '/opt/pubkeys/2016/q2/' + item.key ) }}" exclusive=yes
    with_dict:
      - "{{ qa_users }}"

另外,对于这个问题,您可能试图以一种奇怪的方式简化事情,但您现在使用的数据结构并不理想,所以我会看一下是否确实如此他们长什么样。

感谢@ydaetskcoR 分享正确的方法,当文件驻留在本地机器上并在远程 EC2 机器上配置时,以下解决方案为我做了动态 public 密钥分发:

---
- hosts: tag_Ansible_CLOUD_QA

  vars_files:
    - ../users/groups.yml
    - ../users/qa.yml
  remote_user: ec2-user
  become: yes
  become_method: sudo

  tasks:
  - name: Find user matching key files
    become_user: jenkins
    local_action: find paths="{{'/opt/pubkeys/2016/q1/'}}" patterns="{{ '*' + item.key + '*' }}"
    register: pub_key_files
    with_dict: "{{ qa_users }}"

  - name: Create groups
    group: name="{{ item.key }}" state=present
    with_dict: "{{ user_groups }}"

  - name: Allow test users to have passwordless sudo
    lineinfile: "dest=/etc/sudoers state=present regexp='^%{{ item.key }} ALL=.*ALL.* NOPASSWD: ALL' line='%{{ item.key }} ALL=(ALL) NOPASSWD: ALL'"
    with_dict: "{{ user_groups }}"

  - name: Create remote users qa
    user: name="{{ item.key }}" comment="user" group=users groups="qa"
    with_dict: "{{ qa_users }}"

  - name: Add public keys to remote users qa
    #debug: "msg={{ 'User:' + item.item.key + '  KeyFile:' + item.files.0.path }}"
    authorized_key: user="{{ item.item.key }}" key="{{ lookup('file', item.files.0.path) }}" exclusive=yes
    with_items: "{{ pub_key_files.results }}"

这是根据 EC2 标签获取动态清单的命令行:

ansible-playbook -i inventory/ec2.py --private-key <path to your key file> --extra-vars '{"QUATER":"q1"}' credentials/distribute-public-key.yml