Ansible - múltiplas instruções com as mesmas variáveis

2

Sou novo no Ansible, então talvez esteja faltando algo óbvio. Eu tenho um manual que faz o seguinte:

- 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" }

Reutilizando basicamente o with_items repetidas vezes. Idealmente, gostaria de armazenar isso em um arquivo externo com todos os campos que eu provavelmente usaria.

Isso é possível? Onde devo começar a procurar?

Ta .... Tom

    
por Tom 13.06.2016 / 23:02

2 respostas

6

I'm new to ansible

Estou listando aqui algumas opções diferentes, para que você possa aprender um pouco mais do que apenas a solução ideal (Opção 5)

Opção 1: use âncoras e referências YAML

Isso não tem nenhuma relação com o Ansible, mas como os arquivos estão no formato YAML, você pode fazer algo assim:

- 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

Opção 2: variáveis em blocos

Os blocos são um recurso introduzido no Ansible 2. Você pode definir variáveis para blocos e usá-los nas tarefas contidas

- 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 }}"

Opção 3: aplique o loop a uma tarefa include e tenha suas tarefas no arquivo incluído

- 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

No arquivo incluído, você poderá acessar o item e suas propriedades, por exemplo item.user_name , assim como você já tinha:

- 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

Opção 4: defina um fato que contenha sua lista de usuários em uma tarefa separada

- 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 }}"

Opção 5: usar group_vars

group_vars provavelmente fazem mais sentido aqui. Eu acho que seus hosts estão em algum grupo em seu arquivo de inventário, vamos chamá-lo de foo .

Crie um arquivo group_vars/foo relativo ao seu playbook com o conteúdo:

userlist:
  - user_name: user1
    user_description: user 1
    user_id: 2000
  - user_name: user2
    user_description: user 2
    user_id: 2001

Todos os hosts que pertencem ao grupo foo agora terão automaticamente acesso à variável userlist . E você pode usá-lo em suas tarefas:

- 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 }}"

Se você não tiver grupos ou não quiser limitá-lo a determinados grupos, poderá armazenar o arquivo vars como group_vars/all para o qual todos os hosts têm acesso.

    
por 14.06.2016 / 16:10
1

Obrigado por uma resposta tão completa. No final, descobri que poderia usar with_dict assim:

1) Crie um arquivo vars.yml (no mesmo diretório)

---
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) Crie o novo manual:

---
- 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}}"

Parece que funciona perfeitamente.

Eu só mudei para usersxxx para garantir que eu não estivesse atingindo nenhuma primitiva python / ansible.

Espero que isso ajude alguém!

    
por 14.06.2016 / 21:29

Tags