Не удается получить доступ к регистровой переменной в цикле

Я следил за этим примером playbook для создания стоечных серверов с использованием Ansible.

http://nicholaskuechler.com/2015/01/09/build-rackspace-cloud-servers-ansible-virtualenv/

Это прекрасно работает, но работает только на одном сервере за раз, поэтому я пытаюсь сделать его более динамичным, используя with_items для перебора количества серверов, которые я хочу построить.

tasks:
- name: Rackspace cloud server build request
    local_action:
        module: rax
        credentials: "{{ credentials }}"
        name: "{{ item }}"
        flavor: "{{ flavor }}"
        image: "{{ image }}"
        region: "{{ region }}"
        files: "{{ files }}"
        wait: yes
        state: present
        networks:
        - private
        - public
    with_items:
        - server-app-01
        - server-app-02
    register: rax

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

- name: Add new cloud server to host group
    local_action:
        module: add_host
        hostname: "{{ item.success.name }}"
        ansible_ssh_host: "{{ item.success.rax_accessipv4 }}"
        ansible_ssh_user: root
        groupname: deploy
    with_items: rax.results

(Я также пробовал много других способов нацеливания на это) Но я получаю «Одна или несколько неопределенных переменных: «объект списка» не имеет атрибута «rax_accessipv4»

Это урезанная версия объекта, который я получаю от rax через отладку. Этих серверов больше нет. http://pastebin.com/NRvM7anS

Может ли кто-нибудь сказать мне, где я ошибаюсь, я начинаю немного сходить с ума


person Michael Mallett    schedule 09.04.2015    source источник


Ответы (2)


Если вы заметили, что тип rax.results.success — это list.

Итак: hostname: "{{ item.success.name }}"

должно быть

  • hostname: "{{ item.success[0].name }}" or
  • hostname: "{{ item['success'][0]['name'] }}"

.

{
            "changed": true,
            "msg": "All items completed",
            "results": [
                {
                    "instances": [
                        {
                            "name": "server-app-01",
                            "rax_accessipv4": "134.213.51.171",
                            "rax_accessipv6": "2a00:1a48:7808:101:be76:4eff:fe08:5251",
                        }
                    ],
                    "item": "server-app-01",
                    "success": [
                        {
                            "name": "server-app-01",
                            "rax_accessipv4": "134.213.51.171",
                            "rax_accessipv6": "2a00:1a48:7808:101:be76:4eff:fe08:5251",
                        }
                    ],
                    "timeout": []
                },
          ......
}
person Kashyap    schedule 09.04.2015
comment
Это сделало это, хотя я не совсем уверен, почему. Спасибо - person Michael Mallett; 10.04.2015
comment
@MichaelMallett это потому, что успех - это список диктовок, а не диктовка. Таким образом, успех [0] дает вам первый дикт в списке. - person Kashyap; 10.04.2015

Я как раз боролся с этой пятницей. Вот мое решение:

---
- name: Provision rackspace webheads
  hosts: localhost
  gather_facts: false
  max_fail_percentage: 10
  tasks:
    - name: Provision a set of instances
      local_action:
          group: servers
          count: 5
          exact_count: yes
          credentials: cred.ini
          flavor: <FLAVOR ID>
          group: raxhosts
          image: <IMAGE ID>
          key_name: <SSH KEYNAME>
          module: rax
          name: webheads
          state: present
          wait: yes
      register: rax
    - name: Add new instances to the group 'raxhosts'
      local_action:
        module: add_host
        hostname: "{{ item.name }}"
        ansible_ssh_host: "{{ item.rax_accessipv4 }}"
        ansible_ssh_pass: "{{ item.rax_adminpass }}"
        groupname: raxhosts
      with_items: rax.success
      when: rax.action == 'create'
    - name: Wait for hosts
      local_action: wait_for host={{ item.rax_accessipv4 }} port=22 delay=60 timeout=600 state=started
      with_items: rax.success

Вот как выглядит мой cred.ini:

[rackspace_cloud]
username = 
api_key =

Запустите его так:

RAX_CREDS_FILE=cred.ini RAX_REGION=DFW ansible-playbook <playbook>.yml
person Matt Darby    schedule 09.04.2015
comment
Спасибо за ответ. Значит, вы вообще не создаете серверы с использованием цикла переменных? Разве все ваши серверы не называются одинаково? - person Michael Mallett; 09.04.2015
comment
Tbh, хотя это может делать то, что я хочу, я полон решимости выяснить, почему такой, казалось бы, простой цикл должен дать сбой, поскольку я, несомненно, снова столкнусь с ним. - person Michael Mallett; 09.04.2015
comment
К имени экземпляра будет автоматически добавлен номер; поэтому вы должны получить webheads1, webheads2 и т. д. до count. - person Matt Darby; 09.04.2015