> ## Documentation Index
> Fetch the complete documentation index at: https://infisical.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Fetch secrets in Ansible

> Fetch secrets from Infisical in Ansible playbooks.

You can find the Infisical Ansible collection on [Ansible Galaxy](https://galaxy.ansible.com/ui/repo/published/infisical/vault/).

This Ansible Infisical collection includes a variety of Ansible content to help automate the management of Infisical services. This collection is maintained by the Infisical team.

## Ansible version compatibility

Tested with the Ansible Core >= 2.12.0 versions, and the current development version of Ansible. Ansible Core versions prior to 2.12.0 haven't been tested.

## Python version compatibility

This collection depends on the Infisical SDK for Python.

Requires Python 3.7 or greater.

## Installing this collection

You can install the Infisical collection with the Ansible Galaxy CLI:

```bash theme={"dark"}
ansible-galaxy collection install infisical.vault
```

The python module dependencies aren't installed by ansible-galaxy. They can be manually installed using pip:

```bash theme={"dark"}
pip install infisicalsdk
```

## Using this collection

You can either call modules by their Fully Qualified Collection Name (FQCN), such as `infisical.vault.read_secrets`, or you can call modules by their short name if you list the `infisical.vault` collection in the playbook's collections keyword.

## Authentication

The Infisical Ansible Collection supports [Universal Auth](https://infisical.com/docs/documentation/platform/identities/universal-auth.md), [OIDC Auth](https://infisical.com/docs/documentation/platform/identities/oidc-auth/general.md), [LDAP Auth](https://infisical.com/docs/documentation/platform/identities/ldap-auth/general.md), and [Token Auth](https://infisical.com/docs/documentation/platform/identities/token-auth.md) for authenticating against Infisical.

### Login module (recommended)

The recommended approach is to use the `login` module to authenticate once and reuse the credentials across multiple tasks. This reduces authentication overhead and makes playbooks cleaner. Alternatively, you can still pass credentials directly to each plugin/module if preferred.

```yaml theme={"dark"}
- name: Login to Infisical
  infisical.vault.login:
    url: "https://app.infisical.com"
    auth_method: universal_auth
    universal_auth_client_id: "{{ client_id }}"
    universal_auth_client_secret: "{{ client_secret }}"
  register: infisical_login

- name: Read secrets using cached login
  infisical.vault.read_secrets:
    login_data: "{{ infisical_login.login_data }}"
    project_id: "{{ project_id }}"
    env_slug: "dev"
    path: "/"
    as_dict: true
  register: secrets

- name: Use the secrets
  debug:
    msg: "Database URL is {{ secrets.secrets.DATABASE_URL }}"
```

> [accordion] Universal Auth
>
> Using Universal Auth for authentication is the most straight-forward way to get started with using the Ansible collection.
>
> To use Universal Auth, you need to provide the Client ID and Client Secret of your Infisical Machine Identity.
>
> ```yaml theme={"dark"}
> - name: Login with Universal Auth
>   infisical.vault.login:
>     url: "https://app.infisical.com"
>     auth_method: universal_auth
>     universal_auth_client_id: "<client-id>"
>     universal_auth_client_secret: "<client-secret>"
>   register: infisical_login
> ```
>
> You can also provide the `auth_method`, `universal_auth_client_id`, and `universal_auth_client_secret` parameters through environment variables:
>
> | Parameter Name | Environment Variable Name |
> | - | - |
> | `auth_method` | `INFISICAL_AUTH_METHOD` |
> | `universal_auth_client_id` | `INFISICAL_UNIVERSAL_AUTH_CLIENT_ID` |
> | `universal_auth_client_secret` | `INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET` |

> [accordion] OIDC Auth
>
> To use OIDC Auth, you'll need to provide the ID of your machine identity, and the OIDC JWT to be used for authentication.
>
> > [!NOTE]
> >
> > Please note that in order to use OIDC Auth, you must have `1.0.10` or newer of the `infisicalsdk` package installed.
>
> ```yaml theme={"dark"}
> - name: Login with OIDC Auth
>   infisical.vault.login:
>     url: "https://app.infisical.com"
>     auth_method: oidc_auth
>     identity_id: "<identity-id>"
>     jwt: "<oidc-jwt>"
>   register: infisical_login
> ```
>
> You can also provide the `auth_method`, `identity_id`, and `jwt` parameters through environment variables:
>
> | Parameter Name | Environment Variable Name |
> | - | - |
> | auth\_method | `INFISICAL_AUTH_METHOD` |
> | identity\_id | `INFISICAL_IDENTITY_ID` |
> | jwt | `INFISICAL_JWT` |

> [accordion] LDAP Auth
>
> LDAP Auth allows you to authenticate with Infisical using a machine identity configured with an LDAP directory. You need to provide the identity ID and your LDAP username and password.
>
> > [!NOTE]
> >
> > Please note that in order to use LDAP Auth, you must have `1.0.16` or newer of the `infisicalsdk` package installed.
>
> ```yaml theme={"dark"}
> - name: Login with LDAP Auth
>   infisical.vault.login:
>     url: "https://app.infisical.com"
>     auth_method: ldap_auth
>     identity_id: "<identity-id>"
>     username: "<ldap-username>"
>     password: "<ldap-password>"
>   register: infisical_login
> ```
>
> You can also provide the `auth_method`, `identity_id`, `username`, and `password` parameters through environment variables:
>
> | Parameter Name | Environment Variable Name |
> | - | - |
> | auth\_method | `INFISICAL_AUTH_METHOD` |
> | identity\_id | `INFISICAL_IDENTITY_ID` |
> | username | `INFISICAL_LDAP_USERNAME` |
> | password | `INFISICAL_LDAP_PASSWORD` |

> [accordion] Token Auth
>
> Token Auth is the simplest authentication method that allows you to authenticate directly with an access token. This can be either a [Machine Identity Token Auth](https://infisical.com/docs/documentation/platform/identities/token-auth.md) token or a User JWT token.
>
> > [!NOTE]
> >
> > Please note that in order to use Token Auth, you must have `1.0.13` or newer of the `infisicalsdk` package installed.
>
> ```yaml theme={"dark"}
> - name: Login with Token Auth
>   infisical.vault.login:
>     url: "https://app.infisical.com"
>     auth_method: token_auth
>     token: "<your-token>"
>   register: infisical_login
>   no_log: true
> ```
>
> > [!WARNING]
> >
> > Your token is returned as-is in `login_data.access_token` so it can be reused in later tasks. As a result, Ansible no longer masks it, and it can appear in:
> >
> > * Verbose output (`-v`/`-vvv`)
> > * Log files (`ANSIBLE_LOG_PATH`)
> > * CI/CD logs
> >
> > Always set `no_log: true` on the login task, as shown above, to keep the token out of output and logs.
>
> You can also provide the `auth_method` and `token` parameters through environment variables:
>
> | Parameter Name | Environment Variable Name |
> | - | - |
> | auth\_method | `INFISICAL_AUTH_METHOD` |
> | token | `INFISICAL_TOKEN` |

## Available plugins and modules

### Lookup plugins

* `infisical.vault.login` - Authenticate and return reusable login data
* `infisical.vault.read_secrets` - Read secrets from Infisical
* `infisical.vault.read_folders` - Read folders from Infisical

### Modules

**Authentication:**

* `infisical.vault.login` - Authenticate and return reusable login data

**Static Secrets:**

* `infisical.vault.read_secrets` - Read secrets from Infisical
* `infisical.vault.create_secret` - Create a new secret
* `infisical.vault.update_secret` - Update an existing secret
* `infisical.vault.delete_secret` - Delete a secret

**Folders:**

* `infisical.vault.create_folder` - Create a new folder
* `infisical.vault.read_folders` - List folders at a path, or get one by ID
* `infisical.vault.update_folder` - Rename or re-describe an existing folder
* `infisical.vault.delete_folder` - Delete a folder

**Dynamic Secrets:**

* `infisical.vault.create_dynamic_secret` - Create a dynamic secret configuration
* `infisical.vault.get_dynamic_secret` - Get a dynamic secret by name
* `infisical.vault.update_dynamic_secret` - Update a dynamic secret
* `infisical.vault.delete_dynamic_secret` - Delete a dynamic secret

**Dynamic Secret Leases:**

* `infisical.vault.create_dynamic_secret_lease` - Create a lease (generates credentials)
* `infisical.vault.get_dynamic_secret_lease` - Get lease details
* `infisical.vault.renew_dynamic_secret_lease` - Renew an existing lease
* `infisical.vault.delete_dynamic_secret_lease` - Delete/revoke a lease

## Examples

### Reading secrets

```yaml theme={"dark"}
---
- name: Read secrets from Infisical
  hosts: localhost
  gather_facts: false

  tasks:
    - name: Login to Infisical
      infisical.vault.login:
        url: "https://app.infisical.com"
        auth_method: universal_auth
        universal_auth_client_id: "{{ lookup('env', 'INFISICAL_CLIENT_ID') }}"
        universal_auth_client_secret: "{{ lookup('env', 'INFISICAL_CLIENT_SECRET') }}"
      register: infisical_login

    - name: Read all secrets as dictionary
      infisical.vault.read_secrets:
        login_data: "{{ infisical_login.login_data }}"
        project_id: "your-project-id"
        env_slug: "dev"
        path: "/"
        as_dict: true
      register: secrets

    - name: Use the secrets
      debug:
        msg: "Database: {{ secrets.secrets.DATABASE_URL }}"
```

#### Reading secrets with full metadata

Use the `raw` option to retrieve complete secret metadata including version, creation time, tags, and more:

```yaml theme={"dark"}
- name: Read all secrets with full metadata
  infisical.vault.read_secrets:
    login_data: "{{ infisical_login.login_data }}"
    project_id: "your-project-id"
    env_slug: "dev"
    path: "/"
    raw: true
  register: raw_secrets
  # Returns: [{"id": "...", "secretKey": "HOST", "secretValue": "google.com", "version": 1, "type": "shared", ...}, ...]

- name: Read all secrets with full metadata as dict
  infisical.vault.read_secrets:
    login_data: "{{ infisical_login.login_data }}"
    project_id: "your-project-id"
    env_slug: "dev"
    path: "/"
    raw: true
    as_dict: true
  register: raw_secrets_dict
  # Returns: {"HOST": {"id": "...", "secretKey": "HOST", "secretValue": "google.com", "version": 1, ...}, ...}
```

#### Using the lookup plugin

The `read_secrets` lookup plugin allows for inline secret retrieval. Unlike modules that run on target hosts, lookup plugins run on the Ansible controller during playbook parsing. This is useful for retrieving secrets to use in variable definitions:

```yaml theme={"dark"}
vars:
  read_all_secrets_within_scope: "{{ lookup('infisical.vault.read_secrets', universal_auth_client_id='<>', universal_auth_client_secret='<>', project_id='<>', path='/', env_slug='dev', url='https://app.infisical.com') }}"
  # [{ "key": "HOST", "value": "google.com" }, { "key": "SMTP", "value": "gmail.smtp.edu" }]

  read_all_secrets_as_dict: "{{ lookup('infisical.vault.read_secrets', as_dict=True, universal_auth_client_id='<>', universal_auth_client_secret='<>', project_id='<>', path='/', env_slug='dev', url='https://app.infisical.com') }}"
  # { "SECRET_KEY_1": "secret-value-1", "SECRET_KEY_2": "secret-value-2" } -> Can be accessed as secrets.SECRET_KEY_1

  read_secret_by_name_within_scope: "{{ lookup('infisical.vault.read_secrets', universal_auth_client_id='<>', universal_auth_client_secret='<>', project_id='<>', path='/', env_slug='dev', secret_name='HOST', url='https://app.infisical.com') }}"
  # { "key": "HOST", "value": "google.com" }
```

### Managing secrets (CRUD)

Create, update, and delete secrets programmatically:

```yaml theme={"dark"}
- name: Create a secret
  infisical.vault.create_secret:
    login_data: "{{ infisical_login.login_data }}"
    project_id: "{{ project_id }}"
    env_slug: "dev"
    path: "/"
    secret_name: "API_KEY"
    secret_value: "my-api-key"
    secret_comment: "API key for external service"
  register: created_secret

- name: Update a secret
  infisical.vault.update_secret:
    login_data: "{{ infisical_login.login_data }}"
    project_id: "{{ project_id }}"
    env_slug: "dev"
    path: "/"
    secret_name: "API_KEY"
    secret_value: "new-api-key"
  register: updated_secret

- name: Rename a secret
  infisical.vault.update_secret:
    login_data: "{{ infisical_login.login_data }}"
    project_id: "{{ project_id }}"
    env_slug: "dev"
    path: "/"
    secret_name: "OLD_SECRET_NAME"
    new_secret_name: "NEW_SECRET_NAME"
  register: renamed_secret

- name: Delete a secret
  infisical.vault.delete_secret:
    login_data: "{{ infisical_login.login_data }}"
    project_id: "{{ project_id }}"
    env_slug: "dev"
    path: "/"
    secret_name: "API_KEY"
  register: deleted_secret
```

### Managing folders

[Folders](https://infisical.com/docs/documentation/platform/folder.md) are the path namespace that the `path` option on every secret module addresses. Create a folder before writing secrets into it.

> [!NOTE]
>
> Folder operations require `infisicalsdk` version 1.0.17 or newer. The modules fail with a clear message when the installed version is older.

```yaml theme={"dark"}
- name: Create a folder
  infisical.vault.create_folder:
    login_data: "{{ infisical_login.login_data }}"
    project_id: "{{ project_id }}"
    env_slug: "dev"
    path: "/"
    name: "services"
    description: "Per-service secrets"
  register: created_folder

- name: List the folders at the root
  infisical.vault.read_folders:
    login_data: "{{ infisical_login.login_data }}"
    project_id: "{{ project_id }}"
    env_slug: "dev"
    path: "/"
  register: folders

- name: Show the folder names
  debug:
    msg: "{{ folders.folders | map(attribute='name') | list }}"

- name: Get a single folder by ID
  infisical.vault.read_folders:
    login_data: "{{ infisical_login.login_data }}"
    folder_id: "{{ created_folder.folder.id }}"
  register: one_folder

- name: Rename the folder
  infisical.vault.update_folder:
    login_data: "{{ infisical_login.login_data }}"
    project_id: "{{ project_id }}"
    env_slug: "dev"
    path: "/"
    folder_id: "{{ created_folder.folder.id }}"
    name: "apps"

- name: Delete the folder and everything inside it
  infisical.vault.delete_folder:
    login_data: "{{ infisical_login.login_data }}"
    project_id: "{{ project_id }}"
    env_slug: "dev"
    path: "/"
    folder_id_or_name: "apps"
    force_delete: true
```

`read_folders` returns only the direct children of `path`. Set `recursive: true` to list every folder below it instead.

Set `path` to the folder's parent path, not to the folder itself. To rename `/services/backend`, pass `path: "/services"`.

`update_folder` targets a folder only by `folder_id`, never by name, so use `read_folders` to look the ID up first. It also requires `name` on every call, so pass the current name when you only want to change the description. `delete_folder` is more flexible and accepts either an ID or a name through `folder_id_or_name`.

> [!WARNING]
>
> Setting `force_delete: true` deletes every secret and subfolder inside the folder along with it.

#### Reading folders with the lookup plugin

The `read_folders` lookup plugin retrieves folders inline, the same way `read_secrets` does. It returns a plain list rather than the `folders` key the module returns, and returns a one-element list when you pass `folder_id`:

```yaml theme={"dark"}
- name: Read folder names with a lookup
  set_fact:
    folder_names: "{{ lookup('infisical.vault.read_folders', login_data=infisical_login.login_data, project_id='<project-id>', env_slug='dev', path='/') | map(attribute='name') | list }}"
```

### Dynamic secrets

Dynamic secrets generate credentials on-demand with automatic expiration. They support various providers like SQL databases, AWS, GCP, Azure, and more. For the full list of supported providers and their configuration options, see the [Dynamic Secrets documentation](https://infisical.com/docs/documentation/platform/dynamic-secrets/overview).

#### Creating a dynamic secret

```yaml theme={"dark"}
# Create a dynamic secret for PostgreSQL
- name: Create a PostgreSQL dynamic secret
  infisical.vault.create_dynamic_secret:
    login_data: "{{ infisical_login.login_data }}"
    project_slug: "my-project"
    env_slug: "dev"
    path: "/"
    name: "postgres-dev"
    provider_type: "sql-database"
    inputs:
      client: "postgres"
      host: "localhost"
      port: 5432
      database: "mydb"
      username: "admin"
      password: "admin-password"
      creationStatement: "CREATE USER \"{{username}}\" WITH PASSWORD '{{password}}';"
      revocationStatement: "DROP USER \"{{username}}\";"
    default_ttl: "1h"
    max_ttl: "24h"
  register: dynamic_secret
```

> [!NOTE]
>
> For the full list of supported provider types and their input configurations, see the [Dynamic Secrets API Documentation](https://infisical.com/docs/api-reference/endpoints/dynamic-secrets/create.md#body-provider).

#### Getting and using dynamic secret credentials

To use a dynamic secret, you need to create a **lease** which generates the actual credentials:

```yaml theme={"dark"}
# Create a lease to get database credentials
- name: Get database credentials
  infisical.vault.create_dynamic_secret_lease:
    login_data: "{{ infisical_login.login_data }}"
    project_slug: "my-project"
    env_slug: "dev"
    path: "/"
    dynamic_secret_name: "postgres-dev"
    ttl: "30m"
  register: lease

# Use the generated credentials
- name: Connect to database
  community.postgresql.postgresql_query:
    login_host: localhost
    login_user: "{{ lease.data.DB_USERNAME }}"
    login_password: "{{ lease.data.DB_PASSWORD }}"
    db: mydb
    query: "SELECT version();"
```

#### Managing leases

```yaml theme={"dark"}
# Get lease details
- name: Get lease information
  infisical.vault.get_dynamic_secret_lease:
    login_data: "{{ infisical_login.login_data }}"
    project_slug: "my-project"
    env_slug: "dev"
    path: "/"
    lease_id: "{{ lease.lease.id }}"
  register: lease_details

# Renew a lease before it expires
- name: Renew a lease for 2 more hours
  infisical.vault.renew_dynamic_secret_lease:
    login_data: "{{ infisical_login.login_data }}"
    project_slug: "my-project"
    env_slug: "dev"
    path: "/"
    lease_id: "{{ lease.lease.id }}"
    ttl: "2h"
  register: renewed_lease

# Revoke the credentials when done
- name: Delete the lease
  infisical.vault.delete_dynamic_secret_lease:
    login_data: "{{ infisical_login.login_data }}"
    project_slug: "my-project"
    env_slug: "dev"
    path: "/"
    lease_id: "{{ lease.lease.id }}"
```

#### Updating and deleting dynamic secrets

```yaml theme={"dark"}
# Update a dynamic secret's TTL
- name: Update dynamic secret TTL
  infisical.vault.update_dynamic_secret:
    login_data: "{{ infisical_login.login_data }}"
    project_slug: "my-project"
    env_slug: "dev"
    path: "/"
    name: "postgres-dev"
    default_ttl: "2h"
    max_ttl: "48h"
  register: updated_secret

# Delete a dynamic secret (also revokes all active leases)
- name: Delete a dynamic secret
  infisical.vault.delete_dynamic_secret:
    login_data: "{{ infisical_login.login_data }}"
    project_slug: "my-project"
    env_slug: "dev"
    path: "/"
    name: "postgres-dev"
  register: deleted_secret
```

## Troubleshoot

> [accordion] I'm getting a error related to objc\[72832]: +\[\_\_NSCFConstantString initialize]
>
> If you get this Python error when you running the lookup plugin:
>
> ```
> objc[72832]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called. We can't safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
> Fatal Python error: Aborted
> ```
>
> You'll need to add this to your shell environment or ansible wrapper script:
>
> ```
> export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
> ```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.