Смотрите также: https://stackoverflow.com/questions/29003420/reload-ansibles-dynamic-inventory.
Мой вопрос: есть ли лучший способ сделать то, что ниже?
У меня есть роль ansible, которая подготавливает машины AWS и работает правильно (обратите внимание на provision
тег):
- name: AWS provision
hosts: localhost
gather_facts: no
vars_files:
- vars/dev.yml
user: ec2-user
roles:
- provision
tags:
- provision
Затем у меня есть base
роль, которую я хочу запускать независимо (например, во время разработки, поэтому мне не нужно ждать повторной инициализации (обратите внимание на base
тег). Я запускаю пьесу find running instances
который фильтрует и сохраняет хосты в группе started
:
- name: find running instances
hosts: localhost
vars_files:
- vars/dev.yml
gather_facts: no
tags:
- base
tasks:
- name: gather remote facts
ec2_remote_facts:
region: "{{ target_aws_region }}"
filters:
instance-state-name: running
"tag:Name": "{{ instance_name }}"
register: ec2_facts
- debug: var=ec2_facts
- name: add hosts to groups
add_host:
name: "{{ item.id }}"
ansible_ssh_host: "{{ item.public_dns_name }}"
groups: started
changed_when: false
with_items: ec2_facts.instances
- name: base setup
hosts: started
gather_facts: no
vars_files:
- vars/dev.yml
user: ec2-user
roles:
- base
tags:
- base
Мой вопрос: пьесы работают, но есть ли лучший способ сделать это? Например у меня есть gather_facts: no
с последующим ec2_remote_facts
и filters
- все это кажется довольно запутанным.
Уточнение: спасибо за комментарий о ec2.py
- Уже использую в своей первой игре (когда звоню provision
роль).
Но в целях тестирования я хочу перейти к последующим играм без повторной (медленной) подготовки. Так как повторно заполнить данные моих хостов? Является ec2_remote_facts
с последующим add_host
правильный путь? Или я могу как-то использовать gather_facts: yes
?
Я бы, вероятно, использовал вместо этого сценарий динамической инвентаризации EC2, который вы можете использовать, настроив ec2.ini
и прохождение -i ec2.py
к ansible-playbook
.
Видеть http://docs.ansible.com/ansible/intro_dynamic_inventory.html#example-aws-ec2-external-inventory-script для получения дополнительной информации.
Обратите внимание, что в ec2.ini
. Обязательно посмотрите на них, например cache_max_age
. Вы также можете ускорить создание инвентаря, отфильтровав ненужные ресурсы (например, установите rds = False
если вас интересуют только экземпляры EC2).
ОБНОВИТЬ: С Ansible 2.x + вы также можете использовать - meta: refresh_inventory
в середине игры.
В то время meta: refresh_inventory
является «предпочтительным методом», мне нравится предложение OP об использовании ec2_remote_facts
в сочетании с add_host
. Я установил такой сценарий, и он имеет силу быть 100% динамичным без сбоев кеширования.
Предполагая, что ваш ПГС зажгли экземпляры с env: cool_asg_instance
тег, просто добавьте следующее под ec2_asg
вызов playbook:
- ec2_remote_facts: filters: "tag:env": "cool_asg_instance" register: instance_facts
Затем вы соберете полный JSON набор данных, содержащий всю необходимую информацию, оттуда вы можете использовать Jinja2
возможности в playbook для извлечения вновь созданных IP-адресов, то есть:
- name: group hosts add_host: hostname={{ item }} groups=launched with_items: "{{ instance_facts.instances|selectattr('state', 'equalto', 'running')|map(attribute='private_ip_address')|list }}"
Фильтр любезно предоставлен этим замечательным сообщением в блоге: https://bonovoxly.github.io/2016-02-11-ansible-stuffs-ec2_remote_facts_instead_of_ec2_py
С этого момента вы можете использовать launched
группа в вашем родительском развертывании YAML файл вроде этого:
- hosts: launched gather_facts: no tasks: - name: wait for SSH wait_for: port=22 host="{{ inventory_hostname }}" search_regex=OpenSSH delay=5
Некоторые могут спросить, почему головная боль, хорошо представьте, что вместо того, чтобы userdata
который будет git clone
как Ansible, так и playbook из Интернета, вы можете запустить установку экземпляра из собственного центра развертывания, настроив простой SNS тема, которая будет опубликована в SQS очередь, за которой следит 10-строчный код Python (https://github.com/alexandregama/python-sqs-consumer/blob/master/sqs-message-consumer-polling.py), который вызовет Ansible при выходе нового экземпляра.
Я обнаружил, что это оказалось проще, чем я ожидал. Следующий код позволяет запускать playbooks для существующего инвентаря AWS, что я изначально и хотел сделать. На основании [1] и [2].
(мое решение немного более гибкое, например, custom ansible.cfg
& ssh_config
)
Установите доступный конфигурационный файл и используйте его:
% cat ./ansible.cfg.foo
[defaults]
hostfile = inventory
host_key_checking = false
private_key_file = bar.pem
remote_user = ec2-user
ssh_args = -F ./ssh_config
export ANSIBLE_CONFIG=ansible.cfg.foo
При желании настройте пользовательскую конфигурацию ssh, чтобы настройки вашего ноутбука не мешали. Конфигурация ssh также может быть выполнена в ansible.cfg.foo
, но мне нравится, когда он отдельный, поэтому существующий ~/.ssh/config
могут использоваться третьими лицами.
% cat ./ssh_config
StrictHostKeyChecking no
...
Запустите свой playbook:
ansible-playbook config.yml --tags base
Где playbook может выглядеть следующим образом. теги aws (например, tag_env_test
) используются для выбора хостов.
% cat config.yml
- name: base setup
hosts:
- tag_env_test
become: true
vars_files:
- vars/qux.yml
roles:
- base
tags:
- base
- name: java setup
hosts:
...
я использую ./ec2.py --list > ../ec2_output.txt
для исследования хостов, которые я хочу выбрать.
Я отметил ответ Юкки как решение, чтобы поблагодарить его за помощь :-)
[1] http://www.slideshare.net/bfschott/using-ansible-dynamic-inventory-with-amazon-ec2