Integrate AWX 24.6 with HashiCorp Vault for dynamic secrets management and secure automation workflows

Advanced 45 min Apr 24, 2026
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Configure AWX to securely retrieve database credentials and API keys from HashiCorp Vault using dynamic secrets that automatically rotate. Set up credential types, database engines, and secure playbook execution with centralized secrets management.

Prerequisites

  • AWX 24.6 installed and running
  • PostgreSQL database server
  • Network connectivity between AWX and Vault
  • Basic understanding of Ansible playbooks

What this solves

AWX automation workflows often need database passwords, API keys, and certificates that change regularly. Hardcoding these secrets in playbooks or storing them in AWX credentials creates security risks and maintenance overhead. This integration allows AWX to dynamically fetch secrets from Vault at runtime, with automatic rotation and centralized policy management.

Prerequisites

You need AWX 24.6 running with PostgreSQL backend and HashiCorp Vault server accessible from your AWX instance. The AWX user must have network connectivity to your Vault server on the configured port (usually 8200).

Step-by-step configuration

Install and configure HashiCorp Vault

Set up Vault server with the database secrets engine for dynamic credential generation.

curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt update && sudo apt install -y vault
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
sudo dnf install -y vault

Configure Vault server

Create the Vault configuration file with API listener and file storage backend for development.

storage "file" {
  path = "/opt/vault/data"
}

listener "tcp" {
  address     = "0.0.0.0:8200"
  tls_disable = 1
}

api_addr = "http://127.0.0.1:8200"
cluster_addr = "https://127.0.0.1:8201"
ui = true
disable_mlock = true

Initialize and start Vault

Create the data directory, start Vault service, and initialize the Vault cluster.

sudo mkdir -p /opt/vault/data
sudo chown -R vault:vault /opt/vault
sudo systemctl enable --now vault
sudo systemctl status vault

Initialize Vault and capture the unseal keys and root token.

export VAULT_ADDR='http://127.0.0.1:8200'
vault operator init -key-shares=5 -key-threshold=3

Unseal Vault and enable database engine

Unseal Vault using three of the five keys, then authenticate with the root token.

# Unseal with 3 different keys (replace with your actual keys)
vault operator unseal 
vault operator unseal 
vault operator unseal 

Login with root token

vault auth

Enable database secrets engine

vault secrets enable database

Configure PostgreSQL database connection

Set up Vault to connect to PostgreSQL and generate dynamic credentials.

# Configure database connection (adjust connection details)
vault write database/config/postgresql-db \
    plugin_name=postgresql-database-plugin \
    connection_url="postgresql://{{username}}:{{password}}@localhost:5432/postgres?sslmode=disable" \
    allowed_roles="awx-role" \
    username="vault_admin" \
    password="secure_password123!"

Create role for AWX with limited permissions

vault write database/roles/awx-role \ db_name=postgresql-db \ creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";"\ default_ttl="1h" \ max_ttl="24h"

Create Vault policy for AWX

Define access policy that allows AWX to read database credentials and KV secrets.

path "database/creds/awx-role" {
  capabilities = ["read"]
}

path "secret/data/awx/*" {
  capabilities = ["read", "list"]
}

path "auth/token/lookup-self" {
  capabilities = ["read"]
}

path "auth/token/renew-self" {
  capabilities = ["update"]
}
# Apply the policy
vault policy write awx-policy /tmp/awx-policy.hcl

Create token for AWX with specific policy

vault token create -policy=awx-policy -ttl=8760h

Enable KV secrets engine for static secrets

Configure Key-Value store for API keys and certificates that AWX playbooks need.

# Enable KV v2 secrets engine
vault secrets enable -path=secret kv-v2

Store sample API keys and certificates

vault kv put secret/awx/api-keys \ github_token="ghp_example123456789" \ slack_webhook="https://hooks.slack.com/services/example" vault kv put secret/awx/certificates \ ssl_cert="-----BEGIN CERTIFICATE-----\nMIIC...\n-----END CERTIFICATE-----" \ ssl_key="-----BEGIN PRIVATE KEY-----\nMIIE...\n-----END PRIVATE KEY-----"

Install AWX Vault collection

Add the HashiCorp Vault collection to AWX for Vault integration capabilities.

# On AWX server, install collection in virtual environment
sudo su - awx
source /var/lib/awx/venv/awx/bin/activate
ansible-galaxy collection install community.hashi_vault

Create Vault credential type in AWX

Define custom credential type in AWX for HashiCorp Vault authentication.

fields:
  - id: vault_url
    type: string
    label: Vault URL
    help_text: "HashiCorp Vault server URL (e.g., http://vault.example.com:8200)"
  - id: vault_token
    type: string
    label: Vault Token
    secret: true
    help_text: "Vault authentication token with appropriate policies"
  - id: vault_namespace
    type: string
    label: Vault Namespace (Optional)
    help_text: "Vault namespace for Vault Enterprise (leave empty for OSS)"
    required: false
required:
  - vault_url
  - vault_token
env:
  VAULT_ADDR: '{{ vault_url }}'
  VAULT_TOKEN: '{{ vault_token }}'
  VAULT_NAMESPACE: '{{ vault_namespace }}'
extra_vars:
  vault_url: '{{ vault_url }}'
  vault_token: '{{ vault_token }}'

Create Vault credential in AWX

Set up the actual credential using the custom Vault credential type.

In AWX web interface, navigate to Resources > Credentials and create new credential:

  • Name: HashiCorp Vault
  • Credential Type: HashiCorp Vault (custom type created above)
  • Vault URL: http://127.0.0.1:8200
  • Vault Token: (paste the token created earlier)

Create sample playbook with dynamic secrets

Create an Ansible playbook that retrieves dynamic database credentials from Vault.

---
  • name: Example playbook using Vault dynamic database secrets
hosts: localhost connection: local gather_facts: false vars: vault_url: "{{ ansible_env.VAULT_ADDR }}" vault_token: "{{ ansible_env.VAULT_TOKEN }}" tasks: - name: Get dynamic PostgreSQL credentials from Vault community.hashi_vault.vault_read: url: "{{ vault_url }}" token: "{{ vault_token }}" path: database/creds/awx-role register: db_creds no_log: true - name: Display database username (password hidden) debug: msg: "Database username: {{ db_creds.data.username }}" - name: Connect to database with dynamic credentials postgresql_query: login_host: localhost login_user: "{{ db_creds.data.username }}" login_password: "{{ db_creds.data.password }}" db: postgres query: "SELECT version();" register: db_version - name: Show database version debug: msg: "PostgreSQL version: {{ db_version.query_result[0].version }}" - name: Get API keys from Vault KV store community.hashi_vault.vault_kv2_get: url: "{{ vault_url }}" token: "{{ vault_token }}" path: awx/api-keys register: api_secrets no_log: true - name: Use GitHub API token (example) uri: url: "https://api.github.com/user" method: GET headers: Authorization: "token {{ api_secrets.data.data.github_token }}" register: github_response ignore_errors: true - name: Show API response debug: msg: "GitHub API status: {{ github_response.status | default('Failed') }}"

Create job template in AWX

Set up AWX job template to run the Vault-integrated playbook with proper credentials.

In AWX web interface, create new Job Template:

  • Name: Vault Database Example
  • Inventory: Demo Inventory
  • Project: (your project containing the playbook)
  • Playbook: vault-database-example.yml
  • Credentials: HashiCorp Vault (the credential created earlier)
  • Verbosity: 1 (Normal)

Configure automatic secret rotation

Set up shorter TTL values for more frequent credential rotation in production.

# Update role with shorter TTL for production security
vault write database/roles/awx-role \
    db_name=postgresql-db \
    creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";"\
    default_ttl="30m" \
    max_ttl="2h"

Create scheduled job template for credential refresh

This ensures AWX gets fresh credentials before expiration

Set up Vault audit logging

Enable audit logging to track secret access from AWX for security compliance.

# Enable file audit backend
sudo mkdir -p /var/log/vault
sudo chown vault:vault /var/log/vault
vault audit enable file file_path=/var/log/vault/audit.log

Enable syslog audit for centralized logging

vault audit enable syslog

Configure advanced Vault integration

Set up Vault Agent for token renewal

Configure Vault Agent on AWX server to automatically renew tokens and cache secrets.

vault {
  address = "http://127.0.0.1:8200"
}

auto_auth {
  method "token_file" {
    config = {
      token_file_path = "/opt/vault-agent/token"
    }
  }
  
  sink "file" {
    config = {
      path = "/opt/vault-agent/sink"
    }
  }
}

cache {
  use_auto_auth_token = true
}

listener "tcp" {
  address = "127.0.0.1:8100"
  tls_disable = true
}

template {
  source      = "/opt/vault-agent/db-creds.tpl"
  destination = "/opt/vault-agent/db-creds.json"
  command     = "systemctl reload awx"
}

Create database credential template

Set up template for automatic credential file generation with rotation.

{{- with secret "database/creds/awx-role" -}}
{
  "username": "{{ .Data.username }}",
  "password": "{{ .Data.password }}",
  "generated_at": "{{ now.Format "2006-01-02T15:04:05Z" }}"
}
{{- end -}}

Verify your setup

Test the complete integration to ensure AWX can retrieve secrets from Vault successfully.

# Check Vault status
vault status

Verify database role works

vault read database/creds/awx-role

Test KV secret retrieval

vault kv get secret/awx/api-keys

Check AWX can connect to Vault

curl -H "X-Vault-Token: $VAULT_TOKEN" \ -X GET \ http://127.0.0.1:8200/v1/sys/health

Run the AWX job template and verify it completes without credential errors:

# Check AWX job output in web interface or via API
failed_when: "'FAILED' in job_output or 'ERROR' in job_output"
success_when: "'PLAY RECAP' in job_output and 'failed=0' in job_output"

Common issues

Symptom Cause Fix
AWX job fails with "connection refused" Vault server not accessible Check firewall rules: sudo ufw allow 8200
"permission denied" reading secrets Insufficient Vault policy permissions Update policy with required paths: vault policy write awx-policy /path/to/policy.hcl
Database credentials don't work PostgreSQL user creation failed Check PostgreSQL logs and verify vault_admin user has CREATEROLE privilege
Vault token expires during job Token TTL too short Create token with longer TTL: vault token create -policy=awx-policy -ttl=168h
Collection not found error HashiVault collection not installed Install in AWX venv: ansible-galaxy collection install community.hashi_vault
SSL verification errors Self-signed certificates Add validate_certs: false to vault tasks or configure proper CA

Production hardening

Security recommendations: Enable TLS encryption between AWX and Vault, use shorter credential TTLs (15-30 minutes), implement proper Vault policies with least-privilege access, enable audit logging, and consider using Vault Enterprise namespaces for multi-tenant deployments. Never store Vault tokens in plaintext files.

For production deployments, consider using Vault PKI backend for automatic certificate management and auto-unseal with cloud KMS for enhanced security.

Next steps

Running this in production?

Want this handled for you? Running this at scale adds a second layer of work: capacity planning, failover drills, cost control, and on-call. Our managed platform covers monitoring, backups and 24/7 response by default.

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle managed devops services for businesses that depend on uptime. From initial setup to ongoing operations.