Skip to main content
Inventories in AWX define the hosts and groups that your playbooks will target. AWX supports static inventories, smart inventories, and dynamic inventory sources.

Understanding Inventories

An Inventory in AWX contains:
  • Hosts: Individual managed nodes
  • Groups: Logical collections of hosts
  • Variables: Inventory, group, and host-level variables
  • Inventory Sources: Dynamic inventory plugins

Inventory Types

Standard Inventory

Traditional static inventory with directly managed hosts and groups

Smart Inventory

Dynamic inventory based on host filters across all inventories

Constructed Inventory

Combines multiple inventories using the constructed inventory plugin

Creating a Standard Inventory

1

Create Inventory via Web UI

  1. Navigate to Inventories in the sidebar
  2. Click AddAdd inventory
  3. Fill in the details:
    • Name: Inventory name
    • Organization: Select organization
    • Instance Groups: Optional instance groups
    • Variables: Inventory-level variables in YAML/JSON
  4. Click Save
2

Create Inventory via API

curl -X POST https://awx.example.com/api/v2/inventories/ \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production Servers",
    "description": "Production environment inventory",
    "organization": 1,
    "variables": "---\nansible_connection: ssh\nansible_user: deploy"
  }'
3

Create Inventory via Ansible

- name: Create inventory
  awx.awx.inventory:
    name: Production Servers
    description: Production environment inventory
    organization: Engineering
    variables:
      ansible_connection: ssh
      ansible_user: deploy
    state: present
    controller_host: awx.example.com
    controller_oauthtoken: "{{ awx_token }}"

Managing Hosts

Adding Hosts

  1. Navigate to your inventory
  2. Click the Hosts tab
  3. Click Add
  4. Enter host details:
    • Name: Hostname or IP address
    • Description: Optional description
    • Variables: Host-specific variables
  5. Click Save

Bulk Host Management

- name: Add multiple hosts
  awx.awx.host:
    name: "{{ item.name }}"
    inventory: Production Servers
    variables:
      ansible_host: "{{ item.ip }}"
      server_role: "{{ item.role }}"
    state: present
  loop:
    - { name: web01, ip: 192.168.1.10, role: web }
    - { name: web02, ip: 192.168.1.11, role: web }
    - { name: db01, ip: 192.168.1.20, role: database }
    - { name: db02, ip: 192.168.1.21, role: database }

Host Variables

Common host variables:
# Connection settings
ansible_host: 192.168.1.10
ansible_port: 2222
ansible_user: admin
ansible_connection: ssh
ansible_ssh_private_key_file: /path/to/key

# Become settings
ansible_become: true
ansible_become_user: root
ansible_become_method: sudo

# Custom variables
server_role: web
application: myapp
environment: production

Managing Groups

Creating Groups

  1. Navigate to your inventory
  2. Click the Groups tab
  3. Click Add
  4. Enter group name and variables
  5. Click Save

Adding Hosts to Groups

# Add host to group
- name: Associate host with group
  awx.awx.group:
    name: webservers
    inventory: Production Servers
    hosts:
      - web01.example.com
      - web02.example.com
    state: present
    preserve_existing_hosts: true

Nested Groups

Create parent-child group relationships:
# Create parent group
- name: Create production group
  awx.awx.group:
    name: production
    inventory: Production Servers
    state: present

# Create child groups
- name: Create child groups
  awx.awx.group:
    name: "{{ item }}"
    inventory: Production Servers
    state: present
  loop:
    - webservers
    - databases
    - loadbalancers

# Set up parent-child relationships
- name: Add children to production group
  awx.awx.group:
    name: production
    inventory: Production Servers
    children:
      - webservers
      - databases
      - loadbalancers
    state: present
    preserve_existing_children: true
Resulting structure:
production/
├── webservers/
│   ├── web01
│   └── web02
├── databases/
│   ├── db01
│   └── db02
└── loadbalancers/
    └── lb01

Dynamic Inventory Sources

AWX supports various cloud and infrastructure providers as dynamic inventory sources:

Supported Sources

  • Amazon EC2
  • Google Compute Engine
  • Microsoft Azure
  • VMware vCenter
  • OpenStack
  • Red Hat Satellite
  • Red Hat Insights
  • ServiceNow
  • SCM (Git-based inventory)
  • Custom scripts
  • And many more via inventory plugins

Creating an AWS EC2 Inventory Source

1

Create AWS Credential

- name: Create AWS credential
  awx.awx.credential:
    name: AWS Credentials
    credential_type: Amazon Web Services
    organization: Engineering
    inputs:
      username: "{{ aws_access_key }}"
      password: "{{ aws_secret_key }}"
    state: present
2

Create Inventory Source

- name: Create EC2 inventory source
  awx.awx.inventory_source:
    name: AWS EC2 Production
    inventory: Production Servers
    source: ec2
    credential: AWS Credentials
    update_on_launch: true
    update_cache_timeout: 3600
    overwrite: true
    overwrite_vars: true
    source_vars:
      regions:
        - us-east-1
        - us-west-2
      filters:
        tag:Environment: production
      keyed_groups:
        - key: tags.Role
          prefix: role
      hostnames:
        - private-ip-address
    state: present
3

Sync Inventory Source

- name: Update inventory source
  awx.awx.inventory_source_update:
    name: AWS EC2 Production
    inventory: Production Servers
    wait: true

SCM-Based Inventory

Use inventory files from Git repositories:
- name: Create SCM inventory source
  awx.awx.inventory_source:
    name: Git Inventory
    inventory: Production Servers
    source: scm
    source_project: Infrastructure Playbooks
    source_path: inventory/production.yml
    update_on_launch: true
    overwrite: true
    state: present

Custom Inventory Scripts

Custom inventory scripts are deprecated. Use inventory plugins instead where possible.
For custom sources, use the constructed source type with source_vars defining your logic.

Smart Inventories

Smart inventories dynamically group hosts based on filters:

Creating a Smart Inventory

- name: Create smart inventory for web servers
  awx.awx.inventory:
    name: All Web Servers
    organization: Engineering
    kind: smart
    host_filter: 'server_role="web"'
    state: present

Host Filter Examples

# Hosts with specific variable
host_filter: 'server_role="database"'

# Multiple conditions (AND)
host_filter: 'server_role="web" and environment="production"'

# Multiple conditions (OR)
host_filter: 'server_role="web" or server_role="api"'

# Inventory membership
host_filter: 'inventory="Production Servers"'

# Group membership
host_filter: 'groups__name="webservers"'

# Complex queries
host_filter: 'server_role="web" and environment="production" and inventory="Production Servers"'

Constructed Inventories

Constructed inventories parse multiple source inventories:
- name: Create constructed inventory
  awx.awx.inventory:
    name: Multi-Region Inventory
    organization: Engineering
    kind: constructed
    state: present

- name: Link input inventories
  awx.awx.inventory:
    name: Multi-Region Inventory
    organization: Engineering
    input_inventories:
      - US East Production
      - US West Production
      - EU Production
    state: present
The constructed inventory source is automatically created and can be configured:
source_vars:
  plugin: constructed
  strict: false
  compose:
    full_name: name + '.' + domain
  groups:
    webservers: "'web' in server_role"
    databases: "'db' in server_role"
  keyed_groups:
    - key: environment
      prefix: env

Inventory Variables Hierarchy

Variables are resolved in this order (later takes precedence):
  1. Inventory variables
  2. Group variables (parent groups first)
  3. Host variables
  4. Extra variables (from job launch)
Example:
# Inventory variables
ansible_connection: ssh
ansible_user: deploy

# Group variables (webservers)
http_port: 80
ansible_user: webadmin  # Overrides inventory

# Host variables (web01)
ansible_host: 192.168.1.10
http_port: 8080  # Overrides group

# Final variables for web01:
# ansible_connection: ssh
# ansible_user: webadmin
# ansible_host: 192.168.1.10
# http_port: 8080

Limiting Job Execution

Limit jobs to specific hosts or groups:
# In job template
- name: Create job template with limit
  awx.awx.job_template:
    name: Deploy Web Application
    inventory: Production Servers
    limit: "webservers:&production"  # webservers AND production
    ask_limit_on_launch: true
    state: present
Launch with custom limit:
curl -X POST https://awx.example.com/api/v2/job_templates/1/launch/ \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"limit": "web01:web02"}'

Limit Patterns

# Single host
limit: "web01"

# Multiple hosts
limit: "web01:web02:web03"

# Group
limit: "webservers"

# Multiple groups
limit: "webservers:databases"

# Intersection (AND)
limit: "webservers:&production"

# Exclusion (NOT)
limit: "webservers:!web01"

# Complex patterns
limit: "webservers:&production:!web01"

Inventory Sync Scheduling

Schedule automatic inventory source updates:
- name: Schedule daily inventory sync
  awx.awx.schedule:
    name: Daily EC2 Sync
    unified_job_template: AWS EC2 Production
    rrule: "DTSTART:20260101T060000Z RRULE:FREQ=DAILY;INTERVAL=1"
    enabled: true
    state: present

Instance Groups

Assign instance groups to control where jobs run:
- name: Create inventory with instance groups
  awx.awx.inventory:
    name: Production Servers
    organization: Engineering
    instance_groups:
      - Production Instance Group
      - Default
    prevent_instance_group_fallback: false
    state: present

Inventory Permissions

Grant access to inventories:
# Grant team use permission
- name: Grant inventory access
  awx.awx.role:
    team: DevOps Team
    inventory: Production Servers
    role: use
    state: present

# Grant adhoc permission (run ad-hoc commands)
- name: Grant adhoc permission
  awx.awx.role:
    user: admin.user
    inventory: Production Servers
    role: adhoc
    state: present

# Grant update permission (sync inventory sources)
- name: Grant update permission
  awx.awx.role:
    user: automation.user
    inventory: Production Servers
    role: update
    state: present
Inventory roles:
  • Admin: Full control
  • Use: Use in job templates
  • Adhoc: Run ad-hoc commands
  • Update: Sync inventory sources
  • Read: View-only access

Viewing Inventory Data

Get Inventory Script Output

# Get inventory in Ansible format
curl https://awx.example.com/api/v2/inventories/1/script/ \
  -H "Authorization: Bearer YOUR_TOKEN"
Output:
{
  "all": {
    "hosts": ["web01", "db01"],
    "vars": {
      "ansible_connection": "ssh"
    },
    "children": ["webservers", "databases"]
  },
  "webservers": {
    "hosts": ["web01", "web02"],
    "vars": {
      "http_port": 80
    }
  },
  "_meta": {
    "hostvars": {
      "web01": {
        "ansible_host": "192.168.1.10"
      }
    }
  }
}

List Hosts

# List all hosts in inventory
curl https://awx.example.com/api/v2/inventories/1/hosts/ \
  -H "Authorization: Bearer YOUR_TOKEN"

# List hosts in a group
curl https://awx.example.com/api/v2/groups/1/hosts/ \
  -H "Authorization: Bearer YOUR_TOKEN"

Troubleshooting

Check:
  • Credentials are valid and have necessary permissions
  • Network connectivity to the source (cloud provider, vCenter, etc.)
  • Source configuration (regions, filters) is correct
  • Review sync job output:
curl https://awx.example.com/api/v2/inventory_updates/123/stdout/ \
  -H "Authorization: Bearer YOUR_TOKEN"
Common issues:
  • Overwrite settings: Check overwrite and overwrite_vars settings
  • Filters: Verify source filters aren’t excluding hosts
  • Enabled state: Check if enabled_var and enabled_value are correct
Test the inventory plugin locally:
ansible-inventory -i aws_ec2.yml --graph
Variables not applying as expected:
  1. Check variable precedence: inventory → group → host → extra_vars
  2. Use ansible-inventory to debug:
# Get final variables for a host
curl https://awx.example.com/api/v2/hosts/1/variable_data/ \
  -H "Authorization: Bearer YOUR_TOKEN"
  • Verify filter syntax: use field lookups like groups__name for relationships
  • Test filter in the API:
# Preview smart inventory results
curl 'https://awx.example.com/api/v2/hosts/?server_role=web' \
  -H "Authorization: Bearer YOUR_TOKEN"
  • Common filter fields: name, groups__name, inventory, custom variables

Best Practices

Use Dynamic Sources

Prefer dynamic inventory sources over manual host management for cloud environments

Organize with Groups

Use groups to organize hosts logically and share variables

Leverage Smart Inventories

Create smart inventories for cross-inventory queries and automation

Schedule Syncs

Set up scheduled syncs for dynamic sources to keep inventory current

Running Jobs

Execute playbooks against your inventories

Inventory API

Complete API reference for inventories

Credentials

Configure credentials for inventory sources

Organizations

Organize inventories within organizations

Build docs developers (and LLMs) love