Назад | Перейти на главную страницу

Установка имен хостов динамического инвентаря из Ansible

Я настраиваю до 150 временных серверов EC2 для практического обучения.

Я успешно создаю инвентарь EC2 динамически и запускаю роли для экземпляров, которые созданы для настройки всего, но мне нужно установить простое имя хоста для каждого из них. Для этого у меня есть файл, содержащий простой список имен, которые я хочу использовать для имен хостов. Это в моей пьесе:

---
- hosts: localhost
  connection: local
  gather_facts: false

  tasks:
    - name: Provision a set of instances
      ec2:
        key_name: ubuntu
        instance_type: t2.micro
        image: "{{ ami_id }}"
        wait: true
        exact_count: {{ server_count }}
        count_tag:
          Name: Tutorial
        instance_tags:
          Name: Tutorial
        groups: ['SSH', 'Web']
      register: ec2

    - name: Add all instance public IPs to host group
      add_host: hostname={{ item.public_ip }} groups=ec2hosts
      loop: "{{ ec2.instances }}"

    - name: Set a host name for each instance in DNS
      route53:
        zone: {{ tutorial_domain }}
        record: "name.{{ tutorial_domain }}"
        state: present
        type: A
        ttl: 120
        value: {{ item.public_ip }}
        wait: yes
      loop: "{{ ec2.instances }}"

Это действительно сводится к тому record: "name.{{ tutorial_domain }}" line - как мне найти имя в моем списке имен и использовать его в качестве имени хоста, повернув name в {{ some_dynamic_name }}?

Я видел плагины поиска, но все они, похоже, сосредоточены на цикле по всему содержимому некоторого внешнего файла, но я уже перебираю список серверов, и этот список может быть короче, чем список имен (например, У меня может быть всего 10 серверов). В идеале я хочу один раз прочитать список имен в массиве, а затем использовать индекс из цикла сервера, чтобы выбрать имя (т.е. чтобы 3-й сервер получил 3-е имя). Как мне это сделать в анзибле? Или есть лучший подход?

Вы можете использовать zip фильтр, чтобы объединить ваш список экземпляров со списком имен, например:

---
- hosts: localhost
  gather_facts: false
  vars:
    tutorial_domain: example.com
    ec2:
      instances:
        - public_ip: 1.2.3.4
        - public_ip: 2.3.4.5

    names:
      - blue-duck
      - red-panda

  tasks:
    - debug:
        msg:
          route53:
            zone: "{{ tutorial_domain }}"
            record: "{{ item.1 }}.{{tutorial_domain}}"
            state: present
            type: A
            ttl: 120
            value: "{{ item.0.public_ip }}"
            wait: yes
      loop: "{{ ec2.instances|zip(names)|list }}"

В более старых версиях Ansible вы бы сделали то же самое с with_together петля.

Другой подход - использовать индекс цикла для перебора нескольких списков. Так будет проще добавить смещение в список.

- set_fact:
    ips: ['1.2.3.4', '5.6.7.8']
    hostnames: ['host1', 'host2']
- debug:
    msg: "ip={{ ips[index] }}, hostname={{ hostnames[index] }}"
  loop: "{{ ips }}"
  loop_control:
    index_var: index