Задача Ansible запускается один раз для каждого имени базы данных

Я использую ansible для развертывания нескольких сайтов на одном сервере. Каждый сайт является отдельным «хостом» в доступном hosts инвентаре, что очень хорошо работает.

Однако есть только две базы данных: производственная и тестовая. Как я могу убедиться, что моя задача по миграции базы данных выполняется только один раз для каждой базы данных?

Я читал о функциях group_by, run_once и delegate_to, но не уверен, как их объединить.

Хосты выглядят примерно так:

[production]
site1.example.com       ansible_ssh_host=webserver.example.com
site2.example.com       ansible_ssh_host=webserver.example.com

[beta]
beta-site1.example.com  ansible_ssh_host=webserver.example.com
beta-site2.example.com  ansible_ssh_host=webserver.example.com

[all:children]
production
beta

Текущий playbook выглядит так:

---
- hosts: all
- tasks:

  # ...

  - name: "postgres:  Create PostgreSQL database"
    sudo: yes
    sudo_user: postgres
    postgresql_db: db="{{ DATABASES.default.NAME }}" state=present template=template0 encoding='UTF-8' lc_collate='en_US.UTF-8' lc_ctype='en_US.UTF-8'
    tags: postgres
    register: createdb
    delegate_to: "{{ DATABASES.default.HOST|default(inventory_hostname) }}"

  # ...

  - name: "django-post:  Create Django database tables (migrate)"
    django_manage: command=migrate app_path={{ src_dir }} settings={{ item.settings }} virtualenv={{ venv_dir }}
    with_items: django_projects
    #run_once: true
    tags:
    - django-post
    - django-db
    - migrate

person vdboor    schedule 10.02.2015    source источник
comment
Как правило, семантика один раз на группу не поддерживается, и попытка собрать все в одну игру может быть больше проблем, чем она того стоит. Просто хочу уточнить, вы хотите, чтобы первая задача выполнялась один раз для каждого хоста, а вторая - ровно два раза, по одному разу в каждой группе?   -  person nik.shornikov    schedule 10.02.2015


Ответы (2)


Лучший способ, который я нашел, - это ограничить выполнение задачи первым хостом группы. Поэтому вам нужно добавить имя группы и базы данных в файл group_vars, например:

переменные_группы / производство

---
dbtype=production
django_projects:
    - name: project_1
      settings: ...
    - name: project_n
      settings: ...

group_vars / бета

---
dbtype=beta
django_projects:
    - name: project_1
      settings: ...
    - name: project_n
      settings: ...

хосты

[production]
site1.example.com       ansible_ssh_host=localhost ansible_connection=local
site2.example.com       ansible_ssh_host=localhost ansible_connection=local

[beta]
beta-site1.example.com  ansible_ssh_host=localhost ansible_connection=local
beta-site2.example.com  ansible_ssh_host=localhost ansible_connection=local


[all:children]
production
beta

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

- name: "django-post:  Create Django database tables (migrate)"
  django_manage: command=migrate app_path={{ src_dir }} settings={{ item.settings }} virtualenv={{ venv_dir }}
  with_items: django_projects
  when: groups[dbtype][0] == inventory_hostname 
  tags:
    - django-post
    - django-db
    - migrate
person Mathias Henze    schedule 28.02.2015

Итак, ниже будет показано, почему я говорю «один раз на группу», как правило, не поддерживается. Естественно, я хотел бы увидеть более чистый, готовый к работе способ, и дайте мне знать, если «один раз на группу» - это не то, что вам нужно.

Хосты:

[production]
site1.example.com       ansible_ssh_host=localhost ansible_connection=local
site2.example.com       ansible_ssh_host=localhost ansible_connection=local

[beta]
beta-site1.example.com  ansible_ssh_host=localhost ansible_connection=local
beta-site2.example.com  ansible_ssh_host=localhost ansible_connection=local

[beta:vars]
dbhost=beta-site1.example.com

[production:vars]
dbhost=site1.example.com

[all:children]
production
beta

Пример сценария, который будет делать что-то на dbhost один раз для каждой группы (две реальные группы):

---
- hosts: all
  tasks:
  - name: "do this once per group"
    sudo: yes
    delegate_to: localhost
    debug:
      msg: "do something on {{hostvars[groups[item.key].0]['dbhost']}} for {{item}}"
    register: create_db
    run_once: yes
    with_dict: groups
    when: item.key not in ['all', 'ungrouped']
person nik.shornikov    schedule 10.02.2015