--- - name: Update Linode Dynamic Inventory hosts: localhost gather_facts: true connection: local vars: # Override these variables as needed linode_inventory_output_dir: "/tmp/linode_inventory" inventory_format: "json" # or "ini" awx_integration: true cleanup_temp_files: false # Optional filters include_only_running: false specific_regions: [] # e.g., ['us-east', 'us-west'] specific_tags: [] # e.g., ['production', 'web'] pre_tasks: - name: Check for Linode API token (will be injected by AWX credential) ansible.builtin.fail: msg: "Linode API Token credential must be attached to this job template in AWX" when: linode_api_token is undefined or linode_api_token == "" - name: Display configuration ansible.builtin.debug: msg: | Linode Inventory Configuration: Output directory: {{ linode_inventory_output_dir }} Output format: {{ inventory_format }} AWX integration: {{ awx_integration }} Include only running: {{ include_only_running }} roles: - role: roles/inventory/linode vars: linode_api_token: "{{ linode_api_token }}" post_tasks: - name: Display next steps ansible.builtin.debug: msg: | Inventory update complete! Next steps for AWX integration: 1. Copy the inventory script to your SCM repository 2. Create a custom inventory source in AWX 3. Point it to the linode_inventory.py script 4. Set up the Linode API credential Files created: - JSON inventory: {{ linode_inventory_output_dir }}/{{ linode_inventory_output_file }} {% if inventory_format == "ini" %} - INI inventory: {{ linode_inventory_output_dir }}/linode_static_inventory.ini {% endif %} # Optional: Run against discovered Linode hosts - name: Debug and use discovered Linode hosts hosts: localhost gather_facts: false tasks: - name: Check if inventory file exists ansible.builtin.stat: path: "{{ linode_inventory_output_dir | default('/tmp/linode_inventory') }}/{{ linode_inventory_output_file | default('linode_inventory.json') }}" register: inventory_file_stat - name: Display inventory file status ansible.builtin.debug: msg: | Inventory file path: {{ linode_inventory_output_dir | default('/tmp/linode_inventory') }}/{{ linode_inventory_output_file | default('linode_inventory.json') }} File exists: {{ inventory_file_stat.stat.exists }} File size: {{ inventory_file_stat.stat.size | default(0) }} bytes - name: Load and display inventory contents ansible.builtin.slurp: src: "{{ linode_inventory_output_dir | default('/tmp/linode_inventory') }}/{{ linode_inventory_output_file | default('linode_inventory.json') }}" register: inventory_content when: inventory_file_stat.stat.exists - name: Parse inventory JSON ansible.builtin.set_fact: dynamic_inventory: "{{ inventory_content.content | b64decode | from_json }}" when: inventory_file_stat.stat.exists - name: Display parsed inventory summary ansible.builtin.debug: msg: | Inventory loaded successfully! Total hostvars: {{ dynamic_inventory._meta.hostvars | length }} Groups: {{ dynamic_inventory.keys() | reject('equalto', '_meta') | list }} Hosts in hostvars: {{ dynamic_inventory._meta.hostvars.keys() | list }} when: dynamic_inventory is defined - name: Add discovered hosts to in-memory inventory ansible.builtin.add_host: name: "{{ item.key }}" groups: discovered_linodes ansible_host: "{{ item.value.ansible_host }}" linode_id: "{{ item.value.linode_id }}" linode_region: "{{ item.value.linode_region }}" linode_type: "{{ item.value.linode_type }}" linode_status: "{{ item.value.linode_status }}" loop: "{{ dynamic_inventory._meta.hostvars | dict2items }}" when: - dynamic_inventory is defined - item.value.linode_status == "running" - name: Display added hosts ansible.builtin.debug: msg: "Added {{ groups['discovered_linodes'] | default([]) | length }} running Linode hosts to inventory" - name: Test connection to discovered Linode hosts hosts: discovered_linodes gather_facts: false vars: ansible_user: root ansible_ssh_common_args: '-o StrictHostKeyChecking=no -o ConnectTimeout=10' tasks: - name: Test connectivity ansible.builtin.ping: register: ping_result ignore_errors: true - name: Display connectivity status ansible.builtin.debug: msg: "{{ inventory_hostname }} ({{ ansible_host }}): {{ 'REACHABLE' if ping_result is succeeded else 'UNREACHABLE' }}"