Ansible Dynami c Инвентарь со стати c Группа с Dynami c Дети - PullRequest
0 голосов
/ 17 января 2020

Я уверен, что многие, кто работает с Terraform и Ansible или просто Ansible ежедневно, наверняка сталкивались с этим вопросом.

Немного предыстории:

Я создаю свою инфраструктуру на AWS с помощью Terraform и конфигурирую свои машины с помощью Ansible. мой файл инвентаризации содержит жестко запрограммированные IP-адреса publi c с некоторыми переменными Поскольку бизнес требует, я создаю и разрушаю свои машины очень часто.

Мой вопрос:

Я не хочу обновлять свой файл инвентаря новыми публичными c IP-адресами каждый раз, когда я уничтожаю и создаю свои экземпляры. Поэтому мое основное требование - каждый раз, когда я уничтожаю свою машину, я должен иметь возможность запускать сценарий Terraform для воссоздания машин, а когда я запускаю свою Ansible Playbook, Ansible должен иметь возможность выбрать нужные целевые машины и запустить сборник пьес. Мне нужно знать, что мне нужно описать в моем файле инвентаря, чтобы добиться этой автоматизации. Доменное имя (www.fooexample.com) и stati c publi c IP-адреса в файле инвентаризации не вариант в моем случае? Я видел сценарии, которые делают это с тем, как оно выглядит как имя хоста (webserver1)

Есть форумы, которые говорят об использовании опции ec2.py, но ec2.py получает все публичные c IP-адреса связан с учетной записью, но я хочу настроить таргетинг только на некоторые из машин, как вы можете себе представить, и не на все из них с помощью моей пьесы.

Любая помощь в этом отношении будет принята с благодарностью.

Заранее спасибо

1 Ответ

0 голосов
/ 18 января 2020

Я делаю что-то подобное в GCP, но концепция должна применяться к AWS.

Начиная с Ansible 2.7, существует новая архитектура плагинов инвентаря и несколько плагинов инвентаря для замены динамического c инвентаря скрипты (такие как ec2.py и gcp.py). Документация к плагину AWS находится по адресу https://docs.ansible.com/ansible/2.9/plugins/inventory/aws_ec2.html.

Сначала вам нужно пометить группы хостов, на которые вы хотите настроить таргетинг, в AWS. Вы должны быть в состоянии справиться с этим с помощью Terraform (например, Service = Web).

Далее, включите плагин aws_ec2 в ansible.cfg, добавив:

[inventory]
enable_plugins = aws_ec2

Теперь конвертируйте перейти на использование нового плагина вместо ec2.py. Это означает создание файла aws_ec2.yaml на основе документации. Пример может выглядеть так:

plugin: aws_ec2
regions:
  - us-east-1
keyed_groups:
  - prefix: tag
    key: tags
# Set individual variables with compose
compose:
  ansible_host: public_ip_address

Ключевыми частями здесь являются секции keyed_groups и compose. Это даст вам публичные c IP-адреса в качестве хоста для подключения в инвентаре и группах, которые вы можете ограничить с помощью -l или --limit.

Учитывая, что у вас есть несколько экземпляров в us-east-1 с тегами с помощью Service = Web вы можете настроить таргетинг на них следующим образом:

ansible -i aws_ec2.yaml -m ping -l tag_Service_Web

Это будет нацелено только на тех хостов с тегами на их опубликованном c IP-адресе. Любое динамическое c масштабирование, которое вы делаете (например, увеличиваете количество в Terraform для этого ресурса), будет подхвачено плагином инвентаря при следующем запуске.

Вы также можете использовать тег в игровых книгах. Если у вас была книга игр, которую вы всегда нацеливали на этих хостов, вы можете установить hosts: tag_Service_Web в книге игр.

Бонус:

Я экспериментировал с Ansible Pull модель, которая автоматизирует некоторые из этой начальной загрузки. Идея состоит в том, чтобы объединить cloud-init со специальным сценарием для bootstrap списка воспроизведения для этого хоста автоматически.

Пример сценария, который cloud-init запускает:

#!/bin/bash

set -euo pipefail

lock_files=(
    /var/lib/dpkg/lock
    /var/lib/apt/lists/lock
    /var/lib/dpkg/lock-frontend
    /var/cache/apt/archives/lock
    /var/lib/apt/daily_lock
)

export ANSIBLE_HOST_PATTERN_MISMATCH="ignore"
export PATH="/tmp/ansible-venv/bin:$PATH"

for file in "${lock_files[@]}"; do
    while fuser "$file" >/dev/null 2>&1; do
        echo "Waiting for lock $file to be available..."
        sleep 5
    done
done

apt-get update -qy
apt-get install --no-install-recommends -qy virtualenv python-virtualenv python-nacl python-wheel python-bcrypt

virtualenv -p /usr/bin/python --system-site-packages /tmp/ansible-venv
pip install ansible==2.7.10 apache-libcloud==2.3.0 jmespath==0.9.3

ansible-pull myplaybook.yaml \
    -U git@github.com:myorg/infrastructure.git \
    -i gcp_compute.yaml \
    --private-key /tmp/ansible-keys/infrastructure_ssh_deploy_key \
    --vault-password-file /tmp/ansible-keys/vault \
    -d /tmp/ansible-infrastructure \
    --accept-host-key

Этот скрипт немного упрощен по сравнению с моим реальным сценарием (исключая некоторую спецификацию домена c для аутентификации и предоставления ключей). Но вы можете адаптировать его к AWS, выполнив что-то вроде начальной загрузки ключей из S3 или KMS или другой службы настройки времени загрузки. Я считаю, что ansible-pull хорошо работает, когда на запуск playbook уходит всего одна или две минуты, и он не зависит от внешнего инвентаря (например, ссылки на другие группы, такие как сбор IP-адресов).

...