> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/infrastructure-as-code-management/use-iacm/configuration-management/inventories.md).

# Create Ansible Inventories

Create static, dynamic, plugin, and remote Ansible inventories in Harness IaCM, configure dynamic sources from workspace resources, and filter hosts with attribute conditions.

{% hint style="info" %}
This feature is in Beta[^1] and requires enablement. [View all early access features.](/release-notes/features.md)

{% @harness-feature-flag-access/request-feature-flag-access module="infrastructure-as-code-management" pagePath="infrastructure-as-code-management/use-iacm/configuration-management/inventories" featureFlags="%5B%7B%22name%22%3A%22Ansible%20Remote%20Static%20Inventory%22%2C%22key%22%3A%22IACM\_ANSIBLE\_REMOTE\_INVENTORY%22%2C%22status%22%3A%22BETA%22%2C%22description%22%3A%22Adds%20the%20Remote%20inventory%20type%2C%20which%20reads%20a%20static%20inventory%20file%20from%20a%20Git%20repository%20instead%20of%20hosts%20defined%20manually%20in%20Harness.%22%7D%5D" %}
{% endhint %}

An inventory defines the machines your playbooks target and the variables those machines carry. This guide shows you how to create a static inventory with manually defined hosts, a dynamic inventory that derives hosts from the resources in a Terraform or OpenTofu workspace, a plugin inventory that fetches hosts from a cloud provider through an Ansible inventory plugin, and a remote inventory that reads a static inventory file from a Git repository.

***

## What you will learn from this topic

* **Inventory types:** When to choose a static, dynamic, plugin, or remote inventory.
* **Static setup:** Create an inventory and define hosts and groups manually.
* **Dynamic setup:** Add a source that resolves hosts from workspace resources, select the host address attribute, and filter hosts with conditions.
* **Plugin setup:** Point Harness at a Git-stored inventory plugin configuration and a cloud connector.
* **Remote setup:** Point Harness at a Git-stored static inventory file and understand how inventory variables override it.
* **Variables:** Attach inventory-level variables and environment variables, including secrets.

***

## Before you begin

* **Harness account with IaCM enabled:** You need **Infrastructure as Code Management** under **Infrastructure** in Harness. Go to [Getting started with Harness Platform](/harness-ai/new-to-harness-platform/get-started.md) to access or create a Harness account.

  <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p><strong>Contact Harness support</strong></p><p>If IaCM does not appear, go to <a href="/infrastructure-as-code-management/new-to-iacm/get-started.md">Get started with IaCM</a>, or contact your account administrator or <a href="mailto:support@harness.io">Harness Support</a>.</p></div>
* **Ansible concepts:** Familiarity with hosts, groups, and inventories. Go to [Configuration management with Ansible](/infrastructure-as-code-management/use-iacm/configuration-management.md) to review the concepts.
* **A provisioned workspace (dynamic inventories only):** Dynamic sources resolve hosts from the resources of an IaCM workspace, so the workspace must exist and hold state. Go to [Get started with IaCM](/infrastructure-as-code-management/new-to-iacm/get-started.md) to create and provision a workspace.
* **Git and cloud connectors (plugin inventories only):** The plugin configuration file lives in a Git repository, and provider credentials come from a cloud connector. Go to [Connect to a code repository](/harness-ai/use-harness-platform/connectors/code-repositories/connect-to-code-repo.md) and [Cloud connectors](/harness-ai/use-harness-platform/connectors/cloud-providers.md) to set these up.

***

### Choose an inventory type

Harness IaCM supports four inventory types. Choose based on how your hosts come into existence:

* **Static:** You define a list of hosts and groups manually. Best for fixed fleets, bastion hosts, and small stateful clusters where the topology is known and stable.
* **Dynamic:** Hosts are derived dynamically from different sources, such as the resources of a Terraform or OpenTofu workspace. Best when provisioning creates or replaces hosts, because the inventory tracks state without manual updates.
* **Plugin:** Hosts are fetched from a cloud provider by an Ansible inventory plugin, with the plugin configuration file stored in your Git repository. Best when your team already standardizes on plugins such as `aws_ec2` or `azure_rm`.
* **Remote:** Hosts and groups are read from a static inventory file stored in a Git repository, instead of being entered manually in Harness. Best when you already maintain an INI-format inventory file in Git and want Harness to read it directly rather than re-entering hosts.

***

### Create an inventory

Follow the interactive guide or the step-by-step instructions to create an inventory.

{% tabs %}
{% tab title="Interactive guide" %}
{% embed url="<https://app.tango.us/app/embed/458abc24-16d1-4684-81ae-866ad750cbed?skipCover=false&defaultListView=false&skipBranding=false&makeViewOnly=false&hideAuthorAndDetails=true>" %}
Create New Inventory in Harness
{% endembed %}
{% endtab %}

{% tab title="Step-by-step" %}
To create an inventory, do the following:

1. In the Harness UI, navigate to the **IaCM** module.
2. In the left sidebar under **Configuration**, select **Inventories**.
3. Select **+ New Inventory**. The **New Inventory** dialog opens on the **About Inventory** step.
4. Enter a **Name**. An Id is generated automatically and cannot be changed after creation. **Description** and **Tags** are optional.
5. Under **How do you want to set up the inventory?**, select **Static**, **Dynamic**, **Plugin**, or **Remote**.
6. For Static and Dynamic, select **Create**. For Plugin or Remote, select **Next** and complete the extra steps described in the Plugin or Remote tab below.
   {% endtab %}
   {% endtabs %}

After creation, Harness opens the inventory detail page with four tabs: **Hosts**, **Variables**, **Activity History**, and **Configuration**. The remaining setup differs by type.

{% tabs %}
{% tab title="Static" %}
A static inventory starts empty. You add groups and hosts manually on the **Hosts** tab.

1. Select **+ New Group** to add a group, or **+ New Host** to add a host directly.
2. For a group, enter a **Group name** and optionally select existing hosts that belong to it, then select **Apply Changes**.
3. For a host, enter the **Host Address** (for example, `web1.example.com` or `10.0.1.25`), optionally assign it to groups, then select **Apply Changes**.

Go to [Manage hosts and groups](/infrastructure-as-code-management/use-iacm/configuration-management/inventories/hosts.md) for the full host and group workflow, including host-level variables and connection settings.
{% endtab %}

{% tab title="Dynamic" %}
A dynamic inventory resolves hosts from one or more **sources**. Each source points at an IaCM workspace and selects resources from its state.

To add a source, do the following:

1. On the inventory's **Hosts** tab, select **+ Source**. The **Source Configuration** panel opens with three tabs: **Configuration**, **Static Variables**, and **Dynamic Variables**.
2. On the **Configuration** tab, enter a **Name**. The source identifier becomes the Ansible group name for the hosts it resolves.
3. Select the **Workspace** that provisions the hosts you want to configure.
4. Select the **Resource Type** to match (for example, `aws_instance`). The list is populated from the resource types present in the workspace state.
5. Select the **Host Address Attribute**. This is the resource attribute Ansible uses to connect to each host (for example, `public_dns` or `public_ip`).
6. Optionally, under **Filters (optional)**, select **+ Add Filter** to narrow which resources become hosts. Go to [Filter hosts with conditions](#filter-hosts-with-conditions).
7. Select **Apply Changes**.

At pipeline run time, Harness queries the workspace state, applies your filters, and renders each matching resource as a host in the source's group.

{% hint style="success" %}
Add one source per logical tier. For example, a `webservers` source that selects `aws_instance` resources tagged `Role=web`, and a `databases` source that selects instances tagged `Role=db`. Playbooks can then target each group by the source identifier.
{% endhint %}
{% endtab %}

{% tab title="Plugin" %}
A plugin inventory uses an Ansible inventory plugin to fetch hosts from a cloud provider. The plugin configuration file (for example, `aws_ec2.yml`) lives in your Git repository, and a cloud connector supplies the provider credentials. Selecting **Plugin** extends the dialog into a three-step wizard.

1. On the **About Inventory** step, enter the name and select **Plugin**, then select **Next**.
2. On the **Source** step, define where the inventory configuration is stored:
   * **Select Git Provider:** Choose **Harness Code Repository** or **Third-party Git provider**.
   * **Git Connector:** Select the connector with read access to the repository (third-party providers only).
   * **Repository:** Select or enter the repository name.
   * **Git Fetch Type:** Choose **Latest from Branch**, **Git Tag**, or **Commit SHA**, and supply the branch, tag, or SHA.
   * **Folder Path (optional):** Enter the path to the folder containing your plugin configuration.
3. Select **Next**. On the **Provider** step, select a cloud provider for first-class integration (**AWS**, **GCP**, or **Azure**) or select **Custom** to use any other inventory plugin.
4. Select the **Cloud Connector** that holds the provider credentials.
5. Select **Create**.

At pipeline run time, the plugin queries the provider API through the connector credentials and renders the hosts your configuration file selects.

A plugin inventory's detail page differs from the other types: instead of a **Hosts** tab, it opens on an **Inventory Definition** tab that renders your plugin configuration file from Git. A typical `aws_ec2.yaml` looks like this:

```yaml
plugin: amazon.aws.aws_ec2
regions:
  - us-east-1
filters:
  "tag:infra": "ansibleHost"
  instance-state-name: running
hostnames:
  - tag:Name
compose:
  ansible_host: public_ip_address
```

{% endtab %}

{% tab title="Remote" %}
A remote inventory reads a static, INI-format inventory file from a Git repository instead of hosts entered manually in Harness. Selecting **Remote** extends the dialog into a two-step wizard.

1. On the **About Inventory** step, enter the name and select **Remote**, then select **Next**.
2. On the **Source** step, define where the inventory file is stored:
   * **Select Git Provider:** Choose **Harness Code Repository** or **Third-party Git provider**.
   * **Select Repository:** Select or enter the repository name. The field shows a scope badge (**Project**, **Organization**, or **Account**) for the resolved repository.
   * **Git Fetch Type:** Choose **Latest from Branch** or **Git Tag**.
   * **Git Branch:** Select or enter the branch to fetch from (shown when **Git Fetch Type** is **Latest from Branch**). Commit SHA pinning is not supported for Remote inventories.
   * **Inventory Path:** Enter the path to the inventory file within the repository, for example `inventory/hosts.ini`.
3. Select **Create**.

At pipeline run time, Harness fetches the inventory file from Git and parses its hosts and groups.

A remote inventory's detail page differs from the other types: instead of a **Hosts** tab, it opens on an **Inventory Definition** tab that renders the fetched inventory file from Git. A typical `hosts.ini` looks like this:

```ini
[webservers]
web1.example.com
web2.example.com

[databases]
db1.example.com

[webservers:vars]
http_port=80
```

{% hint style="warning" %}
For every other inventory type, an inventory-level **Variables** row is the weakest source of precedence and is overridden by the same key defined in the Git-stored file. For a **Remote** inventory, this is reversed: inventory-level variables you define in the Harness UI are passed as `--extra-vars`, which is the strongest precedence in Ansible. A UI variable overrides the same key defined in `group_vars` or `host_vars` inside the repository, on every run, until you remove it from the **Variables** tab.
{% endhint %}
{% endtab %}
{% endtabs %}

***

### Filter hosts with conditions

Filters control which workspace resources a dynamic source turns into hosts. Each filter is a condition made of an attribute, an operator, and a value. Multiple filters combine with **AND** logic, so a resource must match every condition to be included.

To add a filter in the **Source Configuration** panel, do the following:

1. Select **Add Filter**.
2. Select the resource **attribute** to evaluate (for example, `tags.environment`).
3. Select an operator: **equals**, **not equals**, **contains**, **does not contain**, **starts with**, or **ends with**.
4. Enter the **value** to compare against (for example, `prod`).

Some common filter patterns are:

* **Environment scoping:** `tags.environment` **equals** `prod` so only production resources are configured.
* **Role scoping:** `tags.Role` **contains** `web` so database instances never receive the web playbook.
* **Naming conventions:** `tags.Name` **starts with** `edge-` to select a named subset of a larger fleet.

***

### Use dynamic variables from resource attributes

Dynamic sources can attach variables to every host they resolve, with values drawn from each resource's attributes or the workspace outputs. Use Harness expressions in the value field:

* `<+attributes.ATTRIBUTE_NAME>` reads an attribute from the matched resource, for example `<+attributes.private_ip>`.
* `<+outputs.OUTPUT_NAME>` reads an output from the workspace, for example `<+outputs.cluster_endpoint>`.

For example, a dynamic variable with key `region` and value `<+attributes.availability_zone>` gives every resolved host a `region` host variable your playbook can reference as `{{ region }}`. Static values are also allowed and apply unchanged to every host in the source.

***

### Add inventory variables

Inventory-level variables apply to every host in the inventory and are the right place for connection settings and shared configuration. In the inventory's **Variables** tab, do the following:

1. Select **+ Variables**. A new variable row appears.
2. Select the variable type: **string** for plain-text values or **secret** for sensitive values.
3. Enter the variable key and value.
4. Select **Save Changes** to persist the rows.

A common baseline for SSH-based fleets stores the connection user as a string (for example, `ansible_user: ubuntu`) and the private key as a **secret**-type variable (`ansible_ssh_private_key_file`) referencing a [Harness secret](/harness-ai/use-harness-platform/secrets/secrets-management/harness-secret-manager-overview.md). Secret values are masked in pipeline logs.

Environment variables defined on the inventory are injected into the Ansible process environment at run time rather than becoming Ansible variables.

{% hint style="warning" %}
For a **Remote** inventory, inventory-level variables are passed as `--extra-vars` and take the strongest precedence, overriding the same key defined in the Git-stored inventory file. For every other inventory type, the same field is the weakest precedence and is overridden by the file. Go to [Choose an inventory type](#choose-an-inventory-type) to review the precedence difference.
{% endhint %}

***

### View activity history

The **Activity History** tab lists past executions that used this inventory, including the playbook, the pipeline execution, and the run status. Use it to correlate configuration runs with provisioning events and to audit who changed what, when.

***

## Troubleshooting

<details>

<summary>Dynamic inventory source resolves no hosts from workspace resources in Harness IaCM Ansible</summary>

Confirm the workspace holds state with resources of the selected Resource Type, and that every filter condition matches. Filters combine with AND logic, so one non-matching condition excludes the resource.

</details>

<details>

<summary>Host address is empty or wrong for hosts resolved by a dynamic inventory source in Harness IaCM</summary>

Check the Host Address Attribute on the source. The selected attribute must exist on the matched resource type and contain a reachable address, for example public\_dns or public\_ip.

</details>

<details>

<summary>Cannot edit the inventory identifier after creating an inventory in Harness IaCM</summary>

Inventory identifiers are immutable after creation. Create a new inventory with the desired identifier and delete the old one.

</details>

<details>

<summary>Remote inventory file fails to parse or hosts are missing in Harness IaCM Ansible</summary>

Harness does not validate the inventory file when you save the Remote inventory configuration; a malformed file only surfaces an error at pipeline run time. Confirm the file at the configured path is valid INI-format Ansible inventory syntax, and that the Git connector, repository, and branch or tag are correct.

</details>

<details>

<summary>A Remote inventory variable does not match the value in the Git-stored inventory file</summary>

Inventory-level variables on a Remote inventory are passed as `--extra-vars`, which takes the highest precedence in Ansible. Remove the variable from the inventory's **Variables** tab to fall back to the value defined in `group_vars` or `host_vars` in the repository.

</details>

***

## Next steps

You created an inventory and connected it to real hosts, either manually, from workspace state, or from a Git-stored inventory file.

* Go to [Manage hosts and groups](/infrastructure-as-code-management/use-iacm/configuration-management/inventories/hosts.md) to add host-level variables, groups, and connection settings.
* Go to [Create Ansible playbooks](/infrastructure-as-code-management/use-iacm/configuration-management/playbooks.md) to register the playbook that will run against this inventory.
* Go to [Example Ansible use cases](/infrastructure-as-code-management/use-iacm/configuration-management/example-use-cases.md) to apply inventories to web fleets, patching, and compliance patterns.

{% @harness-feedback/feedback %}

[^1]: Beta features are feature-complete but still being validated. Available on request.
