Я новичок в Ansible, поэтому могу упустить что-то очевидное. У меня есть playbook, делающий следующее:
- name: Create real users
user: name="{{item.user_name}}" comment="{{item.user_description}}" home="/home/{{item.user_name}}" shell="/bin/bash" uid="{{item.user_id}}"
with_items:
- { user_name: "user1", user_description: "user 1", user_id: "2000" }
- { user_name: "user2", user_description: "user 2", user_id: "2001" }
- name: Copy SSH keys
copy:
src: "keys/{{ item.user_name }}.key"
dest: "/home/{{ item.user_name }}/.ssh/authorized_keys"
owner: "{{ item.user_name }}"
group: "{{ item.user_name }}"
mode: 0600
with_items:
- { user_name: "user1", user_description: "user 1", user_id: "2000" }
- { user_name: "user2", user_description: "user 2", user_id: "2001" }
В основном повторное использование with_items
снова и снова. В идеале я хотел бы сохранить это во внешнем файле со всеми полями, которые я, вероятно, буду использовать.
Это возможно? С чего мне начать искать?
Та .... Том
Я новичок в ансибле
Я перечисляю здесь несколько различных вариантов, чтобы вы могли узнать немного больше, чем просто идеальное решение (вариант 5).
Вариант 1. Используйте якоря и ссылки YAML
Это совершенно не связано с Ansible, но поскольку файлы находятся в формате YAML, вы можете сделать что-то вроде этого:
- name: Create real users
user: name="{{item.user_name}}" comment="{{item.user_description}}" home="/home/{{item.user_name}}" shell="/bin/bash" uid="{{item.user_id}}"
with_items: &my_items
- user_name: user1
user_description: user 1
user_id: 2000
- user_name: user2
user_description: user 2
user_id: 2001
- name: Copy SSH keys
copy:
src: "keys/{{ item.user_name }}.key"
dest: "/home/{{ item.user_name }}/.ssh/authorized_keys"
owner: "{{ item.user_name }}"
group: "{{ item.user_name }}"
mode: 0600
with_items: *my_items
Вариант 2: переменные в блоках
Блоки - это функция, представленная в Ansible 2. Вы можете определять переменные для блоков и использовать их в содержащихся задачах.
- vars:
userlist:
- user_name: user1
user_description: user 1
user_id: 2000
- user_name: user2
user_description: user 2
user_id: 2001
block:
- name: Create real users
user: name="{{item.user_name}}" comment="{{item.user_description}}" home="/home/{{item.user_name}}" shell="/bin/bash" uid="{{item.user_id}}"
with_items: "{{ userlist }}"
- name: Copy SSH keys
copy:
src: "keys/{{ item.user_name }}.key"
dest: "/home/{{ item.user_name }}/.ssh/authorized_keys"
owner: "{{ item.user_name }}"
group: "{{ item.user_name }}"
mode: 0600
with_items: "{{ userlist }}"
Вариант 3. Примените петлю к include
задача и ваши задачи во включенном файле
- include: other_file.yml
with_items:
- user_name: user1
user_description: user 1
user_id: 2000
- user_name: user2
user_description: user 2
user_id: 2001
Во включенном файле вы сможете получить доступ к элементу и его свойствам, например item.user_name
, как будто он у вас уже был:
- name: Create real users
user: name="{{item.user_name}}" comment="{{item.user_description}}" home="/home/{{item.user_name}}" shell="/bin/bash" uid="{{item.user_id}}"
- name: Copy SSH keys
copy:
src: "keys/{{ item.user_name }}.key"
dest: "/home/{{ item.user_name }}/.ssh/authorized_keys"
owner: "{{ item.user_name }}"
group: "{{ item.user_name }}"
mode: 0600
Вариант 4: выделите факт, содержащий ваш список пользователей, в отдельную задачу
- set_fact:
userlist:
- user_name: user1
user_description: user 1
user_id: 2000
- user_name: user2
user_description: user 2
user_id: 2001
- name: Create real users
user: name="{{item.user_name}}" comment="{{item.user_description}}" home="/home/{{item.user_name}}" shell="/bin/bash" uid="{{item.user_id}}"
with_items: "{{ userlist }}"
- name: Copy SSH keys
copy:
src: "keys/{{ item.user_name }}.key"
dest: "/home/{{ item.user_name }}/.ssh/authorized_keys"
owner: "{{ item.user_name }}"
group: "{{ item.user_name }}"
mode: 0600
with_items: "{{ userlist }}"
Вариант 5: используйте group_vars
group_vars вероятно, имеет здесь наибольший смысл. Я предполагаю, что ваши хосты находятся в какой-то группе в вашем файле инвентаря, назовем это foo
.
Создать файл group_vars/foo
относительно вашей playbook с контентом:
userlist:
- user_name: user1
user_description: user 1
user_id: 2000
- user_name: user2
user_description: user 2
user_id: 2001
Все хосты, которые принадлежат группе foo
теперь автоматически получит доступ к userlist
переменная. А можно просто использовать в своих задачах:
- name: Create real users
user: name="{{item.user_name}}" comment="{{item.user_description}}" home="/home/{{item.user_name}}" shell="/bin/bash" uid="{{item.user_id}}"
with_items: "{{ userlist }}"
- name: Copy SSH keys
copy:
src: "keys/{{ item.user_name }}.key"
dest: "/home/{{ item.user_name }}/.ssh/authorized_keys"
owner: "{{ item.user_name }}"
group: "{{ item.user_name }}"
mode: 0600
with_items: "{{ userlist }}"
Если у вас нет групп или вы не хотите ограничивать их определенными группами, вы можете сохранить файл vars как group_vars/all
где все хосты имеют доступ.
Спасибо за такой исчерпывающий ответ. В конце концов я обнаружил, что могу использовать with_dict вот так:
1) Создайте файл vars.yml (в том же каталоге)
---
usersxxx:
user1:
description: User1
user_id: 2001
shell: /bin/bash
...other options here
user2:
description: User2
user_id: 2002
shell: /bin/bash
...other options here
2) Создайте новую пьесу:
---
- hosts: home
vars_files:
- vars.yml
become: yes
tasks:
- name: Create real users
user: name="{{item.key}}" comment="{{item.value.description}}" home="/home/{{item.key}}" uid="{{item.value.user_id}}"
with_dict: "{{usersxxx}}"
Похоже, работает отлично.
Я только изменил его на usersxxx, чтобы убедиться, что я не попал ни в какие примитивы python / ansible.
Надеюсь, это поможет кому-то другому!