Skip to main content

Authenticate Private Ansible Galaxy Content

Last updated on

The Harness Ansible plugin authenticates to private Ansible content when it runs ansible-galaxy collection install -r <requirements file> during the galaxy pre-flight (the dependency installation phase before playbook execution). This page explains the three mechanisms it supports: private Galaxy and Automation Hub servers, private Git collection sources, and .netrc credentials.

All three apply at galaxy install time, and none of them require embedding credentials in requirements.yml. Tokens and secrets are never written to requirements.yml, never printed to logs, and never passed on a command line.


What you will learn

  • Galaxy and Automation Hub servers: Authenticate to a private Galaxy server or Red Hat Automation Hub using ANSIBLE_GALAXY_SERVER_* settings.
  • Private Git collection sources: Authenticate git+https:// collection sources using indexed ANSIBLE_GIT_AUTH_<N>_* credential triples (a set of three related values: HOST, USERNAME, and TOKEN).
  • .netrc credentials: Provide a provider-agnostic .netrc file that git and Python use for HTTPS fetches.
  • Configuration sources and precedence: Supply settings either as pipeline-level environment variables or as playbook variables, with pipeline env taking precedence per key.

How credentials are supplied

The Galaxy server and Git mechanisms can each be configured from two sources. The .netrc mechanism is file-based and is described in its own section.

When the same key is set in both places, the pipeline-level value wins. Resolution is per key, not all-or-nothing, so a username can come from the pipeline while the token for the same entry comes from a playbook secret.

Playbook variable resolution

When a setting is defined as a playbook variable, the value reaches the plugin in one of two ways depending on its type.

Playbook variable typeWhere the value comes from
string (host, URL, username, server list)The literal value stored on the playbook variable.
secret (token, password, client secret)The playbook stores only a reference to a Harness secret. The resolved value is injected at runtime as an environment variable named ANSIBLE_PLAYBOOK_VAR__<KEY>.

Set the relevant key (for example, ANSIBLE_GALAXY_SERVER_<NAME>_TOKEN or ANSIBLE_GIT_AUTH_0_TOKEN) as a variable in the playbook UI. The ANSIBLE_PLAYBOOK_VAR__ prefix is added automatically on injection to avoid collisions with pipeline-level variables. The plugin strips the prefix and uses the real key.


Private Galaxy and Automation Hub servers

Use this mechanism when collections are hosted on a private Galaxy server or Red Hat Automation Hub rather than fetched directly from a Git repository.

How it works

Ansible builds a server list from ANSIBLE_GALAXY_SERVER_LIST and reads per-server settings from ANSIBLE_GALAXY_SERVER_<NAME>_<OPTION> variables. The <NAME> segment is the uppercased server name from the list. Server order matters: the first server in the list is tried first, then Ansible falls through to the next.

You can supply these settings as pipeline-level environment variables (Method A) or as playbook variables (Method B). Go to How credentials are supplied for the source precedence rules. The plugin makes the resolved settings available to ansible-galaxy through the environment, so no files are written.

Variables

The variable names are identical regardless of source. For playbook variables, set these same keys as playbook variables, and store secret-typed keys (_TOKEN, _PASSWORD, _CLIENT_SECRET) as Harness secrets.

VariableRequiredDescription
ANSIBLE_GALAXY_SERVER_LISTYesComma-separated, ordered list of server names, for example automation_hub,community. Order sets lookup priority.

For each server name <NAME> in the list (uppercased), the following per-server options are available.

VariableRequiredDescription
ANSIBLE_GALAXY_SERVER_<NAME>_URLYesThe server's API URL.
ANSIBLE_GALAXY_SERVER_<NAME>_TOKENFor token authAPI token for the server, for example Automation Hub.
ANSIBLE_GALAXY_SERVER_<NAME>_AUTH_URLFor SSO or KeycloakToken exchange (SSO) endpoint. Required for cloud Automation Hub offline tokens. Cloud Automation Hub uses offline tokens. Go to Get started with Automation Hub (Red Hat docs) to generate an offline token.
ANSIBLE_GALAXY_SERVER_<NAME>_USERNAMEFor basic authUsername, when using username and password instead of a token.
ANSIBLE_GALAXY_SERVER_<NAME>_PASSWORDFor basic authPassword, paired with username.
ANSIBLE_GALAXY_SERVER_<NAME>_API_VERSIONNoPin the Galaxy API version when auto-detection is undesirable.
ANSIBLE_GALAXY_SERVER_<NAME>_VALIDATE_CERTSNotrue or false to toggle TLS certificate verification.
ANSIBLE_GALAXY_SERVER_<NAME>_CLIENT_IDNoOAuth client ID for Keycloak flows.
ANSIBLE_GALAXY_SERVER_<NAME>_CLIENT_SECRETNoOAuth client secret for Keycloak flows.
ANSIBLE_GALAXY_SERVER_<NAME>_TIMEOUTNoPer-server request timeout in seconds.

Configuration examples

Two servers, a private Automation Hub (token and SSO) followed by public community Galaxy:

ANSIBLE_GALAXY_SERVER_LIST=automation_hub,community

ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_URL=https://hub.example.com/api/galaxy/content/published/
ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_AUTH_URL=https://sso.example.com/auth/realms/redhat-external/protocol/openid-connect/token
ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_TOKEN=<api-token>

ANSIBLE_GALAXY_SERVER_COMMUNITY_URL=https://galaxy.ansible.com/

A requirements.yml then references collections by name as usual:

collections:
- name: my_namespace.my_collection
- name: community.general

Detection output

During the galaxy pre-flight, the plugin prints a Galaxy server detection section so you can confirm which servers were detected from either source. Secret values are never shown, only the server name, URL, and auth presence:

▶ Galaxy server detection
✓ ok: detected 2 galaxy server(s)
- automation_hub (url: https://hub.example.com/api/galaxy/content/published/) auth: token (set)
- community (url: https://galaxy.ansible.com/) auth: none

For username and password servers, the auth line reads auth: basic (user: <username>). When no galaxy servers are configured, the section prints (no galaxy servers detected).

Galaxy server authentication
  • Server name in variable keys: The <NAME> in the variable key is the uppercased server name. A server named automation_hub becomes ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_*.
  • Auth by server type: Public Galaxy needs no auth. Private Automation Hub uses a token. Cloud Automation Hub (console.redhat.com) uses an offline token exchanged at the AUTH_URL.
  • Independent from Git auth: This mechanism is independent of the Git mechanism. A requirements.yml can mix named collections, resolved through the server list, and git+https:// sources, resolved through Git auth.
  • Missing auth errors: If you attempt to install a private collection without authentication configured, ansible-galaxy will fail with an HTTP 401 or 403 error indicating unauthorized access.

Private Git collection sources

Use this mechanism when requirements.yml pulls collections directly from a Git repository over HTTPS:

collections:
- name: git+https://github.com/my-org/private-collection.git
type: git
version: main

- name: git+https://git.harness.io/account/org/repo.git
type: git
version: main

The plugin configures transparent Git URL rewrites before running ansible-galaxy. For each configured host, a rewrite injects credentials so that a clone of:

https://github.com/my-org/private-collection.git

is transparently performed as:

https://<username>:<token>@github.com/my-org/private-collection.git

No change to requirements.yml is needed, and credentials never appear in it.

Credentials are defined as indexed triples (a set of three related values: HOST, USERNAME, and TOKEN). Each Git host is one numbered entry made of a HOST, a USERNAME, and a TOKEN.

Common username conventions per provider

ProviderUsername valueToken
GitHub (github.com or Enterprise Server)x-access-token (or oauth2)Personal access token or App installation token
Harness CodeYour Harness account emailHarness personal access token
GitLab (gitlab.com or self-hosted)oauth2Personal or project access token
Bitbucket CloudBitbucket usernameApp password
Gitea or ForgejoGit usernameAccess token

The host must be the exact hostname. For GitHub Enterprise Server, use your server host (for example, github.mycompany.com), not github.com.

There are two ways to supply these triples. Both produce the same result and differ only in where the values come from. When both define the same key, pipeline-level environment variables take precedence.

Variables

For each host, where <N> is the entry index (0, 1, 2, and so on):

VariableRequiredDescription
ANSIBLE_GIT_AUTH_<N>_HOSTYesGit host, for example github.com or git.harness.io.
ANSIBLE_GIT_AUTH_<N>_USERNAMEYesUsername for the host (see the conventions table above).
ANSIBLE_GIT_AUTH_<N>_TOKENYesToken or password for the host.

Index rules:

  • All three fields (HOST, USERNAME, TOKEN) are required for an entry to be used. An incomplete entry is skipped with a warning — see Detection output below for examples.
  • Indices do not have to start at 0 or be contiguous (non-contiguous indices are supported, for example you can use indices 1 and 3 without defining index 2). A set containing only ANSIBLE_GIT_AUTH_1_* works, and gaps (for example, 0 and 2 with no 1) are fine. All present entries are used.

Configuration examples

Single host (GitHub):

ANSIBLE_GIT_AUTH_0_HOST=github.com
ANSIBLE_GIT_AUTH_0_USERNAME=x-access-token
ANSIBLE_GIT_AUTH_0_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx

Multiple hosts:

ANSIBLE_GIT_AUTH_0_HOST=github.com
ANSIBLE_GIT_AUTH_0_USERNAME=x-access-token
ANSIBLE_GIT_AUTH_0_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx

ANSIBLE_GIT_AUTH_1_HOST=git.harness.io
ANSIBLE_GIT_AUTH_1_USERNAME=oauth2
ANSIBLE_GIT_AUTH_1_TOKEN=yyy

ANSIBLE_GIT_AUTH_2_HOST=gitlab.com
ANSIBLE_GIT_AUTH_2_USERNAME=oauth2
ANSIBLE_GIT_AUTH_2_TOKEN=zzz

.netrc credentials

A .netrc file is an alternative, provider-agnostic way to authenticate HTTPS fetches during the galaxy install. It is useful when you already manage credentials in .netrc format, or when authentication is needed by tools that read .netrc directly: git, used by ansible-galaxy for git+https:// collection sources, and Python's urllib.

Why a $HOME/.netrc copy is made

git and Python's urllib read credentials only from $HOME/.netrc and ignore the NETRC and ANSIBLE_NETRC environment variables. During the galaxy pre-flight, the plugin detects a .netrc file and copies its contents to $HOME/.netrc (written with owner-only 0600 permissions) so those tools pick it up. If $HOME/.netrc already exists, it is left untouched and not overwritten.

Detection order and sources

The plugin searches these locations in order and uses the first one found. Any additional .netrc files found are reported but not used.

OrderSourceLocation
1ANSIBLE_NETRCThe value is treated as a direct file path to an existing .netrc file, not the file's contents.
2Current working directory<cwd>/.netrc. By default cwd is /harness, so this resolves to /harness/.netrc.
3Ansible workspace<HARNESS_WORKSPACE>/.netrc
4File-type secretThe secret's resolved value is written to the path specified by file_name at runtime (mode 0600). The path must match one of the sources above for detection to pick it up. Go to Add and reference file secrets to create a file-type secret.

Write /harness/.netrc from an earlier step: Because /harness is the default working directory and is shared across all steps within a pipeline stage, a prior step such as a shell or Run step can create /harness/.netrc, and the Ansible step picks it up automatically (it matches detection source 2 above, the current working directory). This is the recommended approach when you do not want to use a file-type secret.

Use a file-type secret for sensitive credentials: A secret-type playbook variable that specifies a file_name has its resolved value written to disk at that file name (mode 0600) at runtime, so no credentials are committed to source control. Point this at a .netrc so detection finds it. This is the same general file-secret mechanism the plugin uses for other on-disk secrets, such as certificate files, and is not .netrc-specific.

info

The plugin does not read raw .netrc contents from an environment variable or a plain (non-file) secret and write $HOME/.netrc from it. A .netrc file must first exist on disk, either committed or staged, pointed to by ANSIBLE_NETRC, or materialized by a file-type secret. The plugin then copies that file into $HOME/.netrc.

.netrc format

Standard .netrc, one machine entry per host:

machine git.harness.io
login oauth2
password <token>

machine github.com
login x-access-token
password <token>

Detection output

During the galaxy pre-flight, the plugin prints a Netrc detection section. It reports the detected file path and source, and lists any additional unused .netrc files. Credentials inside the file are never printed.

▶ Netrc detection
✓ ok: detected /harness/.netrc (source: current working directory)
↳ copied /harness/.netrc to $HOME/.netrc

When none is found:

▶ Netrc detection
(no .netrc detected)

Notes

  • The mechanism is provider-agnostic and works for any HTTPS host you add a machine entry for.
  • The $HOME/.netrc copy is created only when a source .netrc is detected and $HOME/.netrc does not already exist.
  • .netrc and the ANSIBLE_GIT_AUTH_* Git mechanism both serve git+https:// sources. Use whichever fits your credential management. If both are present, the ANSIBLE_GIT_AUTH_* URL rewrite takes precedence because git uses embedded credentials in the URL before checking .netrc.

Precedence

The two private-Git methods can be combined. Resolution is per key, in this order from lowest to highest priority:

  1. Playbook string variable (Method B): Used for HOST and USERNAME.
  2. Playbook secret (Method B): Token resolved from the injected ANSIBLE_PLAYBOOK_VAR__<KEY>.
  3. Pipeline-level environment variable (Method A): Overrides the playbook value for the same key.

A pipeline-level ANSIBLE_GIT_AUTH_0_USERNAME overrides a playbook's ANSIBLE_GIT_AUTH_0_USERNAME, while the token for the same index can still come from the playbook secret. Values are merged key by key, not all-or-nothing.


Security

These behaviors apply to all mechanisms (Galaxy server, Git, and .netrc):

  • Secrets such as tokens and passwords are never written to requirements.yml.
  • Secrets are never printed to logs. The Git section reports only host and username. The Galaxy server detection section reports only server name, URL, and auth presence, for example auth: token (set).
  • Secret values stored as playbook secrets are resolved at runtime from injected ANSIBLE_PLAYBOOK_VAR__<KEY> env vars. The playbook itself stores only a reference.

Git-specific:

  • Tokens are never passed as command-line arguments, so they cannot appear in process listings.
  • The generated Git configuration is written to a temporary file with owner-only permissions and removed after the galaxy install completes.

Galaxy-server-specific:

  • Settings are made available to ansible-galaxy purely through the process environment, and no file is written. Promoted playbook values remain set for the remainder of the run.

.netrc-specific:

  • The detected .netrc is copied to $HOME/.netrc with owner-only (0600) permissions, and only when $HOME/.netrc does not already exist.
  • .netrc contents, including passwords, are never printed. Detection output reports only file paths and sources.

Supported Git providers

The URL-rewrite approach is provider-agnostic and works for any Git server reachable over HTTPS, including:

  • Harness Code
  • GitHub (github.com and Enterprise Server)
  • GitLab (gitlab.com and self-hosted)
  • Bitbucket Cloud
  • Gitea or Forgejo
  • Any other HTTPS Git server

Quick reference

The Galaxy server and Git mechanisms support the same two sources, with pipeline env taking precedence over playbook values per key. The .netrc mechanism is file-based.

Pipeline environment variables:

ANSIBLE_GALAXY_SERVER_LIST=<name1>,<name2>
ANSIBLE_GALAXY_SERVER_<NAME>_URL=<url>
ANSIBLE_GALAXY_SERVER_<NAME>_TOKEN=<token>
ANSIBLE_GALAXY_SERVER_<NAME>_AUTH_URL=<sso-url> # if applicable

Playbook variables:

# Playbook vars (string): ANSIBLE_GALAXY_SERVER_LIST, ANSIBLE_GALAXY_SERVER_<NAME>_URL
# Playbook var (secret): ANSIBLE_GALAXY_SERVER_<NAME>_TOKEN
# -> resolved at runtime as ANSIBLE_PLAYBOOK_VAR__ANSIBLE_GALAXY_SERVER_<NAME>_TOKEN

Precedence: Pipeline env over playbook secret or string, per key.


Explore these related topics to expand your Ansible automation capabilities in Harness IaCM: