Spec-Zone.ru › Ansible

Плагин динамической инвентаризации

Плагин динамической инвентаризации позволяет пользователям указывать источники данных для формирования списка узлов, которые Ansible использует для запуска задач, через параметры командной строки -i /path/to/file и/или -i 'host1, host2' либо из других источников конфигурации.

При использовании Ansible с AWS поддерживать файл инвентаризации будет непросто, поскольку AWS часто меняет IP-адреса, автоматически масштабирует экземпляры и выполняет другие операции. После запуска узлов AWS EC2 вам, вероятно, понадобится снова с ними взаимодействовать. При работе с облачной инфраструктурой лучше не поддерживать статический список облачных имён узлов в текстовых файлах. Вместо этого лучше всего использовать плагин динамической инвентаризации aws_ec2.

Плагин динамической инвентаризации aws_ec2 во время выполнения обращается к API AWS, чтобы получить список узлов инвентаризации из Amazon Web Services EC2. Он динамически предоставляет сведения об экземплярах EC2 для управления инфраструктурой AWS.

Плагин также возвращает экземпляры, созданные вне Ansible, и позволяет Ansible управлять ими.

Чтобы начать использовать плагин динамической инвентаризации aws_ec2 с источником конфигурации YAML, создайте файл с допустимым именем, соответствующим описанной для плагина схеме (файл конфигурации YAML с окончанием aws_ec2.(yml|yaml), например demo.aws_ec2.yml), а затем добавьте plugin: amazon.aws.aws_ec2. Если плагин входит в коллекцию, укажите его полное имя.

Аутентификация

Если контроллер Ansible не находится в AWS, аутентификация выполняется либо с помощью указанных в переменных среды ключей доступа и секретных ключей, либо с помощью аргументов плагина инвентаризации.

Для переменных среды:

export AWS_ACCESS_KEY_ID='AK123'
export AWS_SECRET_ACCESS_KEY='abc123'

Также можно использовать переменную среды AWS_SECURITY_TOKEN, но она поддерживается только для обратной совместимости. AWS_SECURITY_TOKEN заменяет AWS_SESSION_TOKEN и требуется только при использовании временных учётных данных.

Также можно задать aws_access_key, aws_secret_key и security_token в файле конфигурации инвентаризации.

# demo.aws_ec2.yml
plugin: amazon.aws.aws_ec2

# The access key for your AWS account.
aws_access_key: <YOUR-AWS-ACCESS-KEY-HERE>
# The secret access key for your AWS account.
aws_secret_key: <YOUR-AWS-SECRET-KEY-HERE>

Если для разных инструментов или приложений используются разные учётные данные, можно использовать профили.

Аргумент profile нельзя использовать одновременно с параметрами aws_access_key, aws_secret_key и security_token. Если учётные данные не заданы явно, используемый Ansible пакет AWS SDK (boto3) будет использовать свои файлы конфигурации (обычно ~/.aws/credentials). По умолчанию общий файл учётных данных находится по адресу ~/.aws/credentials. Изменить расположение общего файла учётных данных можно с помощью переменной среды AWS_SHARED_CREDENTIALS_FILE.

# demo.aws_ec2.yml
plugin: amazon.aws.aws_ec2

# Attach the default AWS profile
aws_profile: default

# You could use Jinja2 to attach the AWS profile from the environment variable.
aws_profile: "{{ lookup('env', 'AWS_PROFILE') | default('dev-profile', true) }}"

Профиль AWS также можно задать с помощью переменной среды:

export AWS_PROFILE='test-profile'

Если контроллер Ansible работает на экземпляре EC2 с назначенной ролью IAM, учётные данные можно не указывать. Подробнее см. в документации по контроллеру.

Для поиска в инвентаризации также можно использовать ARN роли IAM, которую нужно принять. Это может быть полезно для подключения к разным аккаунтам или ограничения доступа пользователей. Для этого укажите iam_role_arn. При этом всё равно необходимо предоставить учётные данные AWS с достаточными правами для выполнения действия AssumeRole.

# demo.aws_ec2.yml
plugin: amazon.aws.aws_ec2

iam_role_arn: arn:aws:iam::1234567890:role/assumed-ansible

Простой пример

Получить все узлы в us-east-1; в качестве имени узла используется общедоступное DNS-имя, если оно есть, в противном случае — частный IP-адрес.

# demo.aws_ec2.yml
plugin: amazon.aws.aws_ec2

# This sets the region. If empty (the default) default this will include all regions, except possibly
# restricted ones like us-gov-west-1 and cn-north-1.
regions:
- us-east-1

Указав все необходимые параметры, можно просмотреть заполненную инвентаризацию с помощью ansible-inventory -i demo.aws_ec2.yml --graph:

@all:
 |--@aws_ec2:
 |  |--ip-10-210-0-189.ec2.internal
 |  |--ip-10-210-0-195.ec2.internal
 |--@ungrouped:

Допустимые параметры

Некоторые параметры плагина динамической инвентаризации aws_ec2 подробно описаны ниже. Полный список см. в документации по плагину.

hostnames

Параметр hostnames предоставляет различные настройки для выбора способа отображения имени узла.

Ниже приведены примеры:

hostnames:
  # This option allows displaying the public ip addresses.
  - ip-address

  # This option allows displaying the private ip addresses using `tag:Name` as a prefix.
  # `name` can be one of the options specified in http://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html#options.
  - name: 'private-ip-address'
    separator: '_'
    prefix: 'tag:Name'

  # Using literal values for hostname
  # # Hostname will be aws-test_literal
  - name: 'test_literal'
    separator: '-'
    prefix: 'aws'

  # To use tags as hostnames use the syntax `tag:Name=Value` to use the hostname `Name_Value`, or
  # `tag:Name` to use the value of the Name tag. If value provided does not exist in the above options,
  # it will be used as a literal string.
  - name: 'tag:Tag1=Test1,Tag2=Test2'

  # Use dns-name attribute as hostname
  - dns-name

  # You can also specify a list in order of precedence for hostname variables.
  - ip-address
  - dns-name
  - tag:Name
  - private-ip-address

По умолчанию инвентаризация возвращает только первое совпадение из записей hostnames. Возможно, вам понадобится получить все потенциальные совпадения в инвентаризации; это также приведёт к появлению дублирующихся записей. Чтобы включить такое поведение, задайте для ключа конфигурации allow_duplicated_hosts значение True.

keyed_groups

С помощью параметра keyed_groups можно создавать динамические группы, используя переменные узлов. keyed_groups состоит из префикса и ключа. Префикс — это имя группы узлов, к которому добавляется ключ.

Ниже приведены примеры:

keyed_groups:
# This creates host groups based on architecture.
- prefix: arch
  key: architecture

# This creates host groups based on `x86_64` architecture.
- prefix: arch
  key: architecture
  value:
      'x86_64'

# This creates host groups based on availability zone.
- prefix: az
  key: placement.availability_zone

# If the EC2 tag Name had the value `redhat` the tag variable would be: `tag_Name_redhat`.
# Similarly, if a tag existed for an AWS EC2 instance as `Applications` with the value of `nodejs` the
# variable would be: `tag_Applications_nodejs`.
- prefix: tag
  key: ec2_tags

# This creates host groups using instance_type, e.g., `instance_type_z3_tiny`.
- prefix: instance_type
  key: instance_type

# This creates host groups using security_groups id, e.g., `security_groups_sg_abcd1234` group for each security group.
- key: 'security_groups|json_query("[].group_id")'
  prefix: 'security_groups'

# This creates a host group for each value of the Application tag.
- key: ec2_tags.Application
  separator: ''

# This creates a host group per region e.g., `aws_region_us_east_2`.
- key: placement.region
  prefix: aws_region

# This creates host groups based on the value of a custom tag `Role` and adds them to a metagroup called `project`.
- key: ec2_tags['Role']
  prefix: foo
  parent_group: "project"

# This creates a common parent group for all EC2 availability zones.
- key: placement.availability_zone
  parent_group: all_ec2_zones

# This creates a group per distro (distro_CentOS, distro_Debian) and assigns the hosts that have matching values to it,
# using the default separator "_".
- prefix: distro
  key: ansible_distribution

groups

Также можно создавать группы с помощью параметра groups.

Ниже приведены примеры:

groups:
  # This created two groups - `Production` and `PreProduction` based on tags
  # These conditionals are expressed using Jinja2 syntax.
  redhat: "'Production' in ec2_tags.Environment"
  ubuntu: "'PreProduction' in ec2_tags.Environment"

  # This created a libvpc group based on specific condition on `vpc_id`.
  libvpc: vpc_id == 'vpc-####'

compose

compose создаёт и изменяет переменные узлов на основе выражений Jinja2.

compose:
  # This sets the ansible_host variable to connect with the private IP address without changing the hostname.
  ansible_host: private_ip_address

  # This sets location_vars variable as a dictionary with location as a key.
  location_vars:
    location: "east_coast"
    server_type: "ansible_hostname | regex_replace ('(.{6})(.{2}).*', '\\2')"

  # This sets location variable.
  location: "'east_coast'"

  # This lets you connect over SSM to the instance id.
  ansible_host: instance_id
  ansible_connection: 'amazon.aws.aws_ssm'

  # This defines combinations of host servers, IP addresses, and related SSH private keys.
  ansible_host: private_ip_address
  ansible_user: centos
  ansible_ssh_private_key_file: /path/to/private_key_file

  # This sets the ec2_security_group_ids variable.
  ec2_security_group_ids: security_groups | map(attribute='group_id') | list |  join(',')

  # Host variables that are strings need to be wrapped with two sets of quotes.
  # See https://docs.ansible.com/ansible/latest/plugins/inventory.html#using-inventory-plugins for details.
  ansible_connection: '"amazon.aws.aws_ssm"'
  ansible_user: '"ssm-user"'

include_filters и exclude_filters

Параметры include_filters и exclude_filters позволяют сформировать инвентаризацию с помощью нескольких запросов (см. доступные фильтры).

include_filters:
# This includes everything in the inventory that has the following tags.
- tag:Project:
    - 'planets'
- tag:Environment:
    - 'demo'

# This excludes everything from the inventory that has the following tag:Name.
exclude_filters:
- tag:Name:
    - '{{ resource_prefix }}_3'

filters

filters используются для фильтрации экземпляров AWS EC2 по условиям (см. доступные фильтры).

filters:
  # This selects only running instances with tag `Environment` tag set to `dev`.
  tag:Environment: dev
  instance-state-name : running

  # This selects only instances with tag `Environment` tag set to `dev` and `qa` and specific security group id.
  tag:Environment:
    - dev
    - qa
  instance.group-id: sg-xxxxxxxx

  # This selects only instances with tag `Name` fulfilling specific conditions.
  - tag:Name:
    - dev-*
    - share-resource
    - hotfix

use_contrib_script_compatible_ec2_tag_keys и use_contrib_script_compatible_sanitization

Устарело начиная с версии 11.2.0: Параметр use_contrib_script_compatible_ec2_tag_keys устарел и будет удалён в одном из выпусков после 2026-12-01. Вместо него используйте структуру ec2_tags (например, ec2_tags.TAGNAME вместо ec2_tag_TAGNAME).

Устарело начиная с версии 11.2.0: Параметр use_contrib_script_compatible_sanitization устарел и будет удалён в одном из выпусков после 2026-12-01. Вместо него используйте стандартную очистку имён групп Ansible.

Если для use_contrib_script_compatible_ec2_tag_keys задано значение True, этот параметр предоставляет теги узлов с ключами ec2_tag_TAGNAME, как в старом скрипте инвентаризации ec2.py.

По умолчанию плагин aws_ec2 выполняет общую очистку имён групп, чтобы создавать безопасные и пригодные для использования в Ansible имена.

Параметр use_contrib_script_compatible_sanitization позволяет переопределить это поведение для облегчения перехода со старого скрипта инвентаризации и соответствует очистке имён групп скриптом, если для параметра replace_dash_in_groups задано значение False. Чтобы воспроизвести поведение replace_dash_in_groups = True с помощью создаваемых групп, для соответствующих записей необходимо заменять дефисы символами подчёркивания с помощью фильтра regex_replace.

Чтобы это работало, необходимо также отключить параметр TRANSFORM_INVALID_GROUP_CHARS, иначе основной движок дополнительно применит стандартную очистку.

Такое поведение не используется по умолчанию, поскольку подобные имена нарушают работу некоторых функций: не все символы допустимы в идентификаторах Python, которыми фактически являются имена групп.

Использовать эту возможность не рекомендуется; советуем перейти на новую структуру ec2_tags.

# demo.aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions:
- us-east-1
filters:
  tag:Name:
  - 'instance-*'
hostnames:
- tag:Name
use_contrib_script_compatible_sanitization: True
use_contrib_script_compatible_ec2_tag_keys: True

Указав все необходимые параметры, можно просмотреть заполненную инвентаризацию с помощью ansible-inventory -i demo.aws_ec2.yml --list:

{
  "_meta": {
      "hostvars": {
          "instance-01": {
              "aws_ami_launch_index_ec2": 0,
              "aws_architecture_ec2": "x86_64",
              ...
              "ebs_optimized": false,
              "ec2_tag_Environment": "dev",
              "ec2_tag_Name": "instance-01",
              "ec2_tag_Tag1": "Test1",
              "ec2_tag_Tag2": "Test2",
              "ena_support": true,
              "enclave_options": {
                  "enabled": false
              },
              ...
          },
          "instance-02": {
            ...
            "ebs_optimized": false,
            "ec2_tag_Environment": "dev",
            "ec2_tag_Name": "instance-02",
            "ec2_tag_Tag1": "Test3",
            "ec2_tag_Tag2": "Test4",
            "ena_support": true,
            "enclave_options": {
                "enabled": false
            },
            ...
          }
      }
  },
  "all": {
        "children": [
            "aws_ec2",
            "ungrouped"
        ]
    },
    "aws_ec2": {
        "hosts": [
            "instance-01",
            "instance-02"
        ]
    }
}

hostvars_prefix и hostvars_suffix

Параметры hostvars_prefix и hostvars_suffix позволяют задавать префикс и суффикс для переменных узлов.

# demo.aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions:
- us-east-1
filters:
  tag:Name:
  - 'instance-*'
hostvars_prefix: 'aws_'
hostvars_suffix: '_ec2'
hostnames:
- tag:Name

Теперь результат ansible-inventory -i demo.aws_ec2.yml --list:

{
  "_meta": {
      "hostvars": {
          "instance-01": {
              "aws_ami_launch_index_ec2": 0,
              "aws_architecture_ec2": "x86_64",
              "aws_block_device_mappings_ec2": [
                  {
                      "device_name": "/dev/sda1",
                      "ebs": {
                          "attach_time": "2022-06-27T09:04:57+00:00",
                          "delete_on_termination": true,
                          "status": "attached",
                          "volume_id": "vol-06e065bca44e6eae5"
                      }
                  }
              ],
              "aws_capacity_reservation_specification_ec2": {
                  "capacity_reservation_preference": "open"
              }
              ...,
          },
          "instance-02": {
            ...,
          }
      }
  },
  "all": {
        "children": [
            "aws_ec2",
            "ungrouped"
        ]
    },
    "aws_ec2": {
        "hosts": [
            "instance-01",
            "instance-02"
        ]
    }
}

strict и strict_permissions

При отсутствии фактов strict: False пропустит их, а не выдаст ошибку.

strict_permissions: False будет игнорировать ошибки 403, а не прерывать выполнение.

use_ssm_inventory

Параметр use_ssm_inventory: True позволяет получать дополнительные сведения об экземплярах EC2 из службы инвентаризации AWS Systems Manager (SSM) и добавлять их в hostvars. Используя данные инвентаризации SSM, параметр use_ssm_inventory предоставляет дополнительные сведения и атрибуты экземпляров EC2 в инвентаризации. Они могут включать сведения об операционной системе, установленном программном обеспечении, конфигурации сети и пользовательские атрибуты инвентаризации, определённые в SSM.

route53_enabled

Параметр route53_enabled: True позволяет использовать сведения DNS из Route 53 в качестве имени узла. Параметр route53_hostnames задаёт список суффиксов DNS-имён Route 53, учитываемых при фильтрации имён узлов, а параметр route53_excluded_zones задаёт список зон узлов Route53, которые следует исключить.

# route53_inventory.aws_ec2.yml
plugin: aws_ec2
# This enables Route53 DNS information
route53_enabled: true
# Specifies the list of Route53 DNS zones to exclude
route53_excluded_zones:
- foo.bar.zone1
- foo.bar.zone2
# Specifies the list of Route53 DNS suffix to consider
route53_hostnames:
- example.net
- example.org

cache

Плагин инвентаризации aws_ec2 поддерживает кэширование с использованием общих настроек кэша фактов, заданных в разделе [defaults] файла ansible.cfg, или отдельных настроек инвентаризации в разделе [inventory]. Настройки кэширования для конкретного плагина можно указать в файле конфигурации:

# demo.aws_ec2.yml
plugin: aws_ec2
# This enables cache.
cache: yes
# Plugin to be used.
cache_plugin: jsonfile
cache_timeout: 7200
# Location where files are stored in the cache.
cache_connection: /tmp/aws_inventory
cache_prefix: aws_ec2

Ниже приведён пример настройки кэширования инвентаризации с некоторыми параметрами кэша фактов по умолчанию для используемого плагина кэширования и времени ожидания в файле ansible.cfg:

[defaults]
fact_caching = ansible.builtin.jsonfile
fact_caching_connection = /tmp/ansible_facts
cache_timeout = 3600

[inventory]
cache = yes
cache_connection = /tmp/ansible_inventory

Сложный пример

Ниже приведён сложный пример aws_ec2, в котором используются некоторые из перечисленных выше параметров:

# demo.aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions:
  - us-east-1
  - us-east-2
keyed_groups:
  # add hosts to tag_Name_value groups for each aws_ec2 host's ec2_tags.Name variable.
  - key: ec2_tags.Name
    prefix: tag_Name_
    separator: ""
groups:
  # add hosts to the group dev if any of the dictionary's keys or values is the word 'dev'.
  development: "'dev' in (ec2_tags|list)"
filters:
  tag:Name:
    - 'instance-01'
    - 'instance-03'
include_filters:
- tag:Name:
  - 'instance-02'
  - 'instance-04'
exclude_filters:
- tag:Name:
  - 'instance-03'
  - 'instance-04'
hostnames:
  # You can also specify a list in order of precedence for hostname variables.
  - ip-address
  - dns-name
  - tag:Name
  - private-ip-address
compose:
  # This sets the `ansible_host` variable to connect with the private IP address without changing the hostname.
  ansible_host: private_ip_address

Если у узла нет переменных, указанных в конфигурации выше (например, ec2_tags.Name, ec2_tags, private_ip_address), он не будет добавлен в группы, кроме групп, создаваемых плагином инвентаризации, а переменная узла ansible_host не будет изменена.

Теперь результат ansible-inventory -i demo.aws_ec2.yml --graph:

@all:
|--@aws_ec2:
|  |--instance-01
|  |--instance-02
|--@tag_Name_instance_01:
|  |--instance-01
|--@tag_Name_instance_02:
|  |--instance-02
|--@ungrouped:

Использование динамической инвентаризации в плейбуке

Чтобы использовать динамическую инвентаризацию в плейбуке, достаточно указать имя группы в переменной hosts, как показано ниже.

---
- name: Ansible Test Playbook
  gather_facts: false
  hosts: tag_Name_instance_02

  tasks:
    - name: Run Shell Command
      command: echo "Hello World"

© 2012–2018 Michael DeHaan
© 2018–2025 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/projects/ansible/latest/collections/amazon/aws/docsite/aws_ec2_guide.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API