This document describes how the Ansible for OpenShift Virtualization Migration manages sensitive credentials and the recommended practices for keeping them secure.
The Ansible for OpenShift Virtualization Migration uses a layered approach to credential management:
- Ansible Vault — Encrypts sensitive variable files at rest so credentials are never stored in plaintext in Git.
- AAP Credential Types — Stores and injects credentials at runtime via Ansible Automation Platform's built-in credential management.
- Kubernetes Secrets — Stores credentials (API tokens, service account keys) in OpenShift.
- Environment Variable Injection — AAP custom credential types inject secrets as environment variables or extra vars into job template execution.
┌──────────────────────────────────────────────────┐
│ Ansible Automation Platform │
│ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ Machine │ │ Source │ │ Custom │ │
│ │ Creds │ │ Control │ │ Cred │ │
│ │ (SSH keys) │ │ (Git) │ │ Types │ │
│ └─────┬──────┘ └─────┬──────┘ └─────┬──────┘ │
│ │ │ │ │
│ └───────────┬────┘───────────────┘ │
│ │ │
│ Injected at runtime │
│ │ │
│ ┌─────▼──────┐ │
│ │ Job │ │
│ │ Template │ │
│ │ Execution │ │
│ └────────────┘ │
└──────────────────────────────────────────────────┘
The following credentials are managed by the Ansible for OpenShift Virtualization Migration:
| Credential | Storage Method | Used By |
|---|---|---|
| Red Hat account (username/password) | AAP Credential / Vault | bootstrap role |
| OpenShift API token | Kubernetes Secret / AAP | create_mf_aap_token, all k8s tasks |
| Git repository (username/password or SSH key) | AAP Source Control Credential | aap_seed role, project sync |
| Container registry (host/username/password) | AAP Container Registry Credential | EE image pulls |
| Automation Hub tokens (certified + validated) | AAP Galaxy Credential | Collection sync |
| VMware vCenter (host/username/password) | AAP Custom Credential | mtv_management provider tasks |
| oVirt/RHV (host/username/password) | AAP Custom Credential | mtv_management provider tasks |
| VDDK registry (username/password) | AAP Custom Credential | mtv_management VDDK tasks |
| AAP admin (hostname/username/password/token) | AAP Credential | aap_seed, bootstrap |
| Machine SSH keys | AAP Machine Credential | aap_machine_credentials role |
| iDRAC (username/password) | AAP Custom Credential | Bootstrap bare-metal tasks |
Note: This table reflects the credentials at time of writing and may not capture all credentials as the project evolves. Refer to the role defaults and AAP credential type definitions for the authoritative list.
Ansible Vault encrypts variable files so that sensitive values are never stored in plaintext.
-
Copy the example vault file and populate it with real values:
cp inventory.vault.yml.example inventory.vault.yml
-
Edit
inventory.vault.ymland replace placeholder values with actual credentials. -
Encrypt the file:
ansible-vault encrypt inventory.vault.yml
-
Optionally, create a vault password file (excluded from Git by
.gitignore):echo 'your-vault-password' > .vault-password chmod 600 .vault-password
With a password prompt:
ansible-playbook -e @inventory.vault.yml \
playbooks/bootstrap.yml --ask-vault-passWith a password file:
ansible-playbook -e @inventory.vault.yml \
playbooks/bootstrap.yml --vault-password-file .vault-passwordWith ansible-navigator (password prompt):
ansible-navigator run playbooks/bootstrap.yml \\
-e @inventory.vault.yml --pae false \\
-- --ask-vault-passWith ansible-navigator (password file):
ansible-navigator run playbooks/bootstrap.yml \\
-e @inventory.vault.yml --pae false \\
-- --vault-password-file .vault-passwordansible-vault edit inventory.vault.ymlansible-vault rekey inventory.vault.ymlThe aap_seed role creates the following custom credential types in
AAP. These store secrets in AAP's encrypted database and inject them
into job template runs.
Config-as-Code credential that stores Ansible for OpenShift Virtualization Migration configuration including AAP settings, organization, and project details.
Injected as extra vars:
aap_version,aap_instance_name,aap_execution_environmentaap_org_name,aap_namespace,aap_project,aap_inventoryaap_job_template_extra_vars,migration_targets
Per-target VMware credentials for MTV provider configuration.
Injected as extra vars and environment variables:
VMWARE_HOST,VMWARE_USER,VMWARE_PASSWORD(env)- Target name, host, insecure SSL flag, VDDK image details (extra vars)
Per-target oVirt/RHV credentials for MTV provider configuration.
Injected as extra vars and environment variables:
OVIRT_HOSTNAME,OVIRT_USERNAME,OVIRT_PASSWORD(env)- Target name, host, insecure SSL flag (extra vars)
All tasks that handle sensitive data use the no_log directive to
prevent credentials from appearing in Ansible output:
- name: Task with sensitive data
some_module:
password: "{{ secret_value }}"
no_log: "{{ secure_logging | default(true) }}"The secure_logging variable defaults to true. Set it to false
only in development environments when debugging credential issues.
- Use AAP's role-based access control (RBAC) to restrict credential access to specific teams and users.
- Grant the minimum permission level required: Use for job template execution, Admin only for credential managers.
- Audit credential access regularly via AAP's activity stream.
- Use a unique vault password per environment (dev, staging, production).
- Store vault passwords in a secure location (e.g., a password manager or secrets management service).
- Never commit vault password files to Git — they are excluded by
.gitignore. - Rotate vault passwords periodically using
ansible-vault rekey.
- The
create_mf_aap_tokenrole creates a ServiceAccount withcluster-adminprivileges. Limit the scope if your environment permits. - Use OpenShift's RBAC to restrict access to the
migration-factory-aap-sa-tokensecret. - Rotate service account tokens periodically.
- Prefer SSH key authentication over username/password for Git operations.
- Use deploy keys with read-only access where possible.
- The
.gitignoreexcludes common secret file patterns (secrets.yml,*.vault.yml,vault-password*,.vault-password*). - Gitleaks is configured (
.gitleaks.toml) and integrated into pre-commit hooks and CI to detect accidental secret commits.
If you have an existing inventory.yml with real credential values:
-
Extract all sensitive values into
inventory.vault.yml. -
Add the values to the vaulted
inventory.vault.ymlfile. -
Replace the values in
inventory.ymlwith variable references:# inventory.yml (safe to commit) rh_username: "{{ vault_rh_username }}" rh_password: "{{ vault_rh_password }}"
# inventory.vault.yml (encrypted) vault_rh_username: "actual-username" vault_rh_password: "actual-password"
-
Encrypt the vault file:
ansible-vault encrypt inventory.vault.yml
-
Verify no secrets remain in plaintext:
gitleaks detect --config .gitleaks.toml --no-git