Passer au contenu principal

Expertise (Ansible)

Inventaire dynamique avancé

Sur une infrastructure élastique, maintenir un inventaire statique est une tâche ingrate. Un plugin d'inventaire dynamique interroge une source de vérité externe à chaque exécution et reconstruit l'inventaire en temps réel.

Netbox comme source de vérité

pip install pynetbox
ansible-galaxy collection install netbox.netbox
# inventory/netbox.yml
plugin: netbox.netbox.nb_inventory
api_endpoint: https://netbox.example.com
token: "{{ lookup('env', 'NETBOX_TOKEN') }}"
validate_certs: true
group_by:
  - site
  - role
  - platform
device_query_filters:
  - status: active
  - has_primary_ip: true
compose:
  ansible_host: primary_ip4.address | ipaddr('address')
NETBOX_TOKEN=xxx ansible-inventory -i inventory/netbox.yml --graph

AWS EC2

# inventory/aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions:
  - eu-west-1
filters:
  tag:Env: production
  instance-state-name: running
keyed_groups:
  - key: tags.Role
    prefix: role
compose:
  ansible_host: public_ip_address

Écrire un plugin d'inventaire custom

# inventory_plugins/mycmdb.py
from ansible.plugins.inventory import BaseInventoryPlugin
import requests

class InventoryModule(BaseInventoryPlugin):
    NAME = "mycmdb"

    def verify_file(self, path):
        return path.endswith("mycmdb.yml")

    def parse(self, inventory, loader, path, cache=True):
        super().parse(inventory, loader, path)
        config = self._read_config_data(path)
        response = requests.get(
            config["api_url"] + "/api/servers",
            headers={"Authorization": f"Bearer {config['token']}"},
        )
        for server in response.json():
            hostname = server["fqdn"]
            self.inventory.add_host(hostname)
            self.inventory.set_variable(hostname, "ansible_host", server["ip"])
            self.inventory.add_group(server["environment"])
            self.inventory.add_host(hostname, group=server["environment"])

Cache d'inventaire

# ansible.cfg
[inventory]
cache = true
cache_plugin = jsonfile
cache_connection = /tmp/ansible_inventory_cache
cache_timeout = 3600
ansible-inventory -i inventory/aws_ec2.yml --list --flush-cache