Ansible更新authorized_keys文件

时间:2019-04-16 02:52:22

标签: ansible

我正在尝试编写通用操作,以使我们所有服务器上的authorized_keys文件保持最新状态。基本上,我想保留列表开发人员,并指定允许他们连接到哪些服务器。

这就是我所拥有的...

ssh.yaml

  tasks:
    - name: 'provision dev-app servers with correct keys'
      authorized_key:
        user: 'deployment'
        key: '{{ item.key }}'
        comment: '{{ item.email }}'
        state: '{{ item.state }}'
      when: "('dev-app' in group_names) and ('dev-app' in item.servers or 'all' in item.servers)"
      with_items:
        - '{{ users }}'

vars.yaml

  - name: 'Jacob Haug'
    username: 'jacob'
    email: 'jacob@jacobhaug.com'
    key: "{{ lookup('file', 'permissions/keys/jacob.pub') }}"
    servers:
      - 'all'
    state: 'present'

  - name: 'Some Developer'
    username: 'developer'
    email: 'developer@example.com'
    key: "{{ lookup('file', 'permissions/keys/developer.pub') }}"
    servers:
      - 'dev-app'
      - 'dev-admin'
      - 'prd-app'
      - 'prd-admin'
      - 'prd-scraper'
    state: 'present'

这很好用。但是,我想删除以其他某种方式添加到authorized_keys的所有项目。根据authorized_keys模块的文档,我可以使用exclusive参数,但是,该选项不是循环感知的,需要我在一个批处理操作中传递所有密钥。

https://docs.ansible.com/ansible/latest/modules/authorized_key_module.html

有什么更好的方法?任何建议将不胜感激。

3 个答案:

答案 0 :(得分:2)

您在有关exclusive选项的问题中所指向的文档

  

是否要从authorized_keys文件中删除所有其他未指定的密钥。 可以通过换行符将多个键指定在单个键字符串值中

我将尝试的方法:将set_fact与循环一起使用,以创建具有所需内容的var,然后在下一个任务中,在authorized_keys模块中使用带有exclusive选项的var。诸如此类(经过全面测试和调整):

tasks:
    - name: 'get keys to declare'
      set_fact:
        declare_keys: >-
          {{
            declare_keys | default([])
            +
            [item.key + ' ' + item.email])
          }}
      when:
        - "item.state == 'present'"
        - "'dev-app' in group_names"
        - "'dev-app' in item.servers or 'all' in item.servers"
      with_items:
        - '{{ users }}'

    - name: 'provision dev-app servers with correct keys'
      authorized_key:
        user: 'deployment'
        key: '{{ declare_keys.join("\n") }}'
        exclusive: yes

答案 1 :(得分:0)

我遇到了与您相同的问题,恕我直言,唯一的解决方案是在本地构建一个密钥文件,然后将其分发到目标服务器。我正在执行以下操作:

- name: Create authorized_keys file
  local_action: "shell cat {{ ssh_user_key_path }}/{{ item }} >>{{ authorized_keys  }}"
  check_mode: False
  changed_when: False
  loop:
    - user1
    - user2
    - user3

- name: Distribute authorized_keys file to servers
  authorized_key:
    user: kvbapp
    key: "{{ lookup('file', authorized_keys) }}"
    path: "~/.ssh/authorized_keys"
    exclusive: True
    manage_dir: True

- name: remove local temporary authorized_keys file
  local_action:
    module: file
    state: absent
    path: '{{ authorized_keys }}'
  check_mode: False
  changed_when: False
  run_once: True

答案 2 :(得分:0)

下面的播放创建了词典“ my_keys ”的列表,可用于配置专有的“ authorized_key ”。

- set_fact:
    my_hosts: "{{ my_hosts|default([]) + item.servers }}"
  loop: "{{ users }}"
  when: item.state == "present"
- set_fact:
    my_keys: "{{ my_keys|default({})|combine({item: users|json_query(my_query)}) }}"
  vars:
    my_query: "[?servers.contains(@, '{{ item }}')].{key: key, state: state}"
  loop: "{{ my_hosts|unique }}"
- debug:
    msg: "{{ item.key }} {{ item.value|json_query('[?state==`present`].key') }}"
  loop: "{{ my_keys|dict2items }}"

给予:

"msg": "dev-app [u'permissions/keys/jacob.pub', u'permissions/keys/developer.pub']"
"msg": "all [u'permissions/keys/jacob.pub']"
"msg": "dev-admin [u'permissions/keys/developer.pub']"

具有用于演示目的的修改数据 1)两个用户使用同一台服务器“ dev-app” 2)文件名而不是密钥

users:
  - name: 'Jacob Haug'
    username: 'jacob'
    email: 'jacob@jacobhaug.com'
    key: "permissions/keys/jacob.pub"
    servers:
      - 'all'
      - 'dev-app'
    state: 'present'
  - name: 'Some Developer'
    username: 'developer'
    email: 'developer@example.com'
    key: "permissions/keys/developer.pub"
    servers:
      - 'dev-app'
      - 'dev-admin'
    state: 'present'