Можно ли использовать Ansible authorized_key исключительно с несколькими ключами?

Я новичок в использовании Ansible и читал здесь, а также в Google и пока не нашел ответа.

Мой сценарий состоит в том, что у меня есть 1 пользователь на сервере, но 2-3 разных ключа pub, которые нужно поместить в файл authorized_keys.

Я могу успешно удалить все ключи или добавить все ключи с помощью этого скрипта:

---
  - hosts: all

 tasks:
  - name: update SSH keys
    authorized_key:
     user: <user>
     key: "{{ lookup('file', item) }}"
     state: present
     #exclusive: yes
    with_fileglob:
      - ../files/pub_keys/*.pub

С флагом present он считывает и добавляет все ключи. С флагом absent удаляются все перечисленные ключи.

Проблема в том, что у меня есть старый ключ, который находится только на сервере, и я хочу удалить / перезаписать его, а для будущих развертываний перезаписать любые неавторизованные ключи, которые могут быть на сервере, а не в моем playbook.

С флагом exclusive он берет и добавляет только последний ключ. Было бы здорово, если бы он выполнял цикл и повторно добавлял все ключи. Если в Ansible есть способ сделать это, я его не нашел.

Есть ли способ перебрать файлы pub и одновременно использовать параметр exclusive?


person Valien    schedule 10.08.2016    source источник


Ответы (4)


Есть ли способ перебрать файлы публикации и одновременно использовать эксклюзивную опцию?

Нет. В документации есть примечание о циклах и исключениях:

эксклюзивный: следует ли удалять все остальные неуказанные ключи из файла authorized_keys. В одном значении ключевой строки можно указать несколько ключей, разделив их символами новой строки. Этот параметр не поддерживает цикл, поэтому, если вы используете with_, он будет эксклюзивным для каждой итерации цикла, если вы хотите, чтобы в файле было несколько ключей, вам нужно передать их все для ключа в одном пакете, как упомянуто выше.

Значит, вам нужно соединить все свои ключи и отправить все сразу.
Примерно так:

- name: update SSH keys
  authorized_key:
    user: <user>
    key: "{{ lookup('pipe','cat ../files/pub_keys/*.pub') }}"
    state: present
    exclusive: yes

Проверьте этот код перед запуском в производственную среду!

person Konstantin Suvorov    schedule 10.08.2016
comment
О боже, ты же палочка-выручалочка! Работает отлично! Я только что открыл для себя lookup материал, но пытался разобраться в этом. Большое тебе спасибо! - person Valien; 10.08.2016
comment
Будьте осторожны и ставьте EOL в конце каждого ключевого файла публикации. В противном случае ключи могут быть объединены в одну строку. - person dzieciou; 31.05.2021

Если вы хотите избежать поиска pipe (например, потому что путь не зависит от роли), вы также можете использовать комбинацию поиска file и fileglob:

- name: update SSH keys
  authorized_key:
    user: <user>
    key:  "{% for key in lookup('fileglob', 'pub_keys/*.pub').split(',') %}{{ lookup('file', key) ~ '\n'}}{% endfor %}"
    state: present
    exclusive: yes
person morxa    schedule 20.02.2018
comment
Даже лучше, когда вы используете запрос, чем поиск - таким образом вы избегаете необходимости разделения и получаете защиту от несуществующих путей: key: "{% for key in query('fileglob', 'pub_keys/*') %}{{ lookup('file', key) ~ '\n'}}{% endfor %}" - person keypress; 14.06.2018

Если вы держите своих пользователей внутри переменной, вы можете использовать это:

---

- hosts: all
  vars_files:
    - roles/users/vars/main.yml
  tasks:
    - name: Allow other users to login to the account
      authorized_key:
        user: user_name
        exclusive: yes
        key: "{{ developers|map(attribute='publish_ssh_key')|join('\n') }}"

roles/users/vars/main.yml выглядит так:

---

developers:
  - name: user1
    publish_ssh_key: ssh-rsa AAAA...
  - name: user2
    publish_ssh_key: ssh-rsa AAAA...
person czerasz    schedule 26.10.2016
comment
При этом добавляется только последний ключ, но, согласно документации, он должен работать. Несколько ключей можно указать в одном строковом значении ключа, разделив их символами новой строки docs.ansible.com/ansible/authorized_key_module.html Знаете ли вы, почему он не работает? - person goetzc; 01.07.2017
comment
@goetzc я не знаю :-( - person czerasz; 03.07.2017
comment
Эй, это было то, что у меня были тестовые ключи, которые были идентичны, только с другим комментарием, а затем Ansible добавил только последний :) - person goetzc; 03.07.2017

как я писал в этом другом ответе (Ansible - управление несколькими ключами SSH для нескольких пользователей и ролей) именно так я решил эту проблему для своего варианта использования. Может быть, здесь это пригодится?

Я передаю массив имен файлов в переменной моей роли user-account. Затем роль получает содержимое каждого из этих файлов, складывает их вместе в строку, разделенную новой строкой, а затем, наконец, устанавливает это значение как ssh-ключ для нового пользователя.

.

Файл плейбука:

- hosts: aws-node1
  roles:
    - { role: user-account, username: 'developer1', ssh_public_keyfiles: ['peter-sshkey.pub', 'paul-sshkey.pub'] }

.

Определение роли для user-account:

- name: add user
  user:
    name: "{{username}}"


- name: lookup ssh pubkeys from keyfiles and create ssh_pubkeys_list
  set_fact:
    ssh_pubkeys_list: "{{ lookup('file', item) }}"
  with_items:
    "{{ssh_public_keyfiles}}"
  register: ssh_pubkeys_results_list


- name: iterate over ssh_pubkeys_list and join into a string
  set_fact:
    ssh_pubkeys_string: "{{ ssh_pubkeys_results_list.results | map(attribute='ansible_facts.ssh_pubkeys_list') | list | join('\n') }}"


- name: update SSH authorized_keys for user {{ username }} with contents of ssh_pubkeys_string
  authorized_key:
    user: "{{ username }}"
    key: "{{ ssh_pubkeys_string }}"
    state: present
    exclusive: yes
person DrGecko    schedule 01.11.2018