AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

HashiCorp Vault Integration with Ansible Automation Platform: Credential Management at Scale

By Luca Berton · Published 2024-01-01 · Category: installation

How to integrate HashiCorp Vault with Ansible Automation Platform for enterprise credential management.

Introduction

Managing credentials at scale is one of the biggest challenges in enterprise automation. Hard-coded passwords in playbooks, shared SSH keys, and static API tokens create security vulnerabilities that grow with your infrastructure. HashiCorp Vault solves this by providing centralized secret management with dynamic credentials, automatic rotation, and detailed audit logging.

When integrated with Ansible Automation Platform (AAP), Vault becomes the single source of truth for all automation credentials — from database passwords to cloud provider tokens to SSH keys.

See also: Ansible Zero Trust Security: Implement Zero Trust Architecture for Enterprise Infrastructure

Why Vault + AAP?

Traditional credential management breaks down at scale. Teams share static passwords through encrypted Ansible Vault files, but these still require manual rotation and offer no audit trail of who accessed what. HashiCorp Vault introduces dynamic secrets — credentials generated on-demand with automatic expiration.

Key benefits of the integration: • Dynamic credentials — Database passwords, AWS keys, and SSH certificates generated per-job with automatic expiration • Centralized policy — Fine-grained access control based on team, project, and environment • Complete audit trail — Every secret access logged with timestamp, identity, and source IP • Zero-trust model — No long-lived credentials stored anywhere in the automation pipeline • Automatic rotation — Vault handles credential lifecycle; no manual intervention needed

Architecture

The integration works through AAP's credential plugin system and Ansible's hashi_vault lookup plugin: AAP authenticates to Vault using AppRole (machine-to-machine auth) At job launch, AAP fetches required secrets from Vault Secrets are injected as extra vars or environment variables Playbooks use dynamic credentials — never stored on disk After job completion, dynamic credentials expire automatically

See also: Ansible AAP as OIDC Authentication Provider for HashiCorp Vault: Zero Trust Workflow

Setup Vault for AAP

Enable AppRole Authentication

# Enable AppRole auth method
vault auth enable approle

# Create policy for AAP with least-privilege access vault policy write aap-automation - <<POLICY # Read secrets from KV store path "secret/data/ansible/*" { capabilities = ["read", "list"] }

# Generate dynamic database credentials path "database/creds/ansible-role" { capabilities = ["read"] }

# Generate dynamic AWS credentials path "aws/creds/ansible-role" { capabilities = ["read"] }

# Sign SSH certificates path "ssh-client-signer/sign/ansible-role" { capabilities = ["create", "update"] } POLICY

# Create AppRole for AAP vault write auth/approle/role/aap \ token_policies="aap-automation" \ token_ttl=1h \ token_max_ttl=4h \ secret_id_ttl=720h

# Retrieve credentials for AAP configuration vault read auth/approle/role/aap/role-id vault write -f auth/approle/role/aap/secret-id

Store Static Secrets

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

# Store automation credentials vault kv put secret/ansible/database \ username="ansible_svc" \ password="SecureDbP@ss!"

vault kv put secret/ansible/api-keys \ github_token="ghp_xxxxxxxxxxxx" \ slack_webhook="https://hooks.slack.com/xxx"

Configure AAP Credential Type

Create a custom credential type in AAP to store Vault connection details:

# Input Configuration
fields:
  - id: vault_url
    type: string
    label: Vault URL
  - id: vault_role_id
    type: string
    label: Vault Role ID
  - id: vault_secret_id
    type: string
    label: Vault Secret ID
    secret: true
  - id: vault_path
    type: string
    label: Secret Path

# Injector Configuration extra_vars: vault_url: "{{ vault_url }}" vault_secret_path: "{{ vault_path }}" env: VAULT_ADDR: "{{ vault_url }}" VAULT_ROLE_ID: "{{ vault_role_id }}" VAULT_SECRET_ID: "{{ vault_secret_id }}"

See also: Ansible Automation Platform and HashiCorp Vault: End-to-End Trusted Automation (Integration Guide)

Ansible Playbook with Vault Lookup

Install the Collection

ansible-galaxy collection install community.hashi_vault
pip install hvac  # HashiCorp Vault Python client

Read Static Secrets

---
- name: Deploy application with Vault credentials
  hosts: webservers
  become: true
  vars:
    vault_addr: "{{ lookup('env', 'VAULT_ADDR') }}"
    db_creds: "{{ lookup('community.hashi_vault.hashi_vault',
      'secret/data/ansible/database',
      url=vault_addr,
      auth_method='approle',
      role_id=lookup('env', 'VAULT_ROLE_ID'),
      secret_id=lookup('env', 'VAULT_SECRET_ID')
    ) }}"
  tasks:
    - name: Deploy database configuration
      ansible.builtin.template:
        src: db-config.j2
        dest: /etc/myapp/database.conf
        mode: '0600'
      vars:
        db_user: "{{ db_creds.data.username }}"
        db_pass: "{{ db_creds.data.password }}"
      no_log: true

Dynamic Database Credentials

- name: Use dynamic database credentials
  hosts: appservers
  vars:
    dynamic_creds: "{{ lookup('community.hashi_vault.hashi_vault',
      'database/creds/ansible-role',
      url=vault_addr,
      auth_method='approle',
      role_id=lookup('env', 'VAULT_ROLE_ID'),
      secret_id=lookup('env', 'VAULT_SECRET_ID')
    ) }}"
  tasks:
    - name: Configure application
      ansible.builtin.template:
        src: app-config.j2
        dest: /etc/myapp/config.yml
      vars:
        db_username: "{{ dynamic_creds.username }}"
        db_password: "{{ dynamic_creds.password }}"
      no_log: true
      # Credentials auto-expire after TTL!

Dynamic AWS Credentials

- name: Provision AWS with dynamic credentials
  hosts: localhost
  connection: local
  vars:
    aws_creds: "{{ lookup('community.hashi_vault.hashi_vault',
      'aws/creds/ansible-role',
      url=vault_addr,
      auth_method='approle',
      role_id=lookup('env', 'VAULT_ROLE_ID'),
      secret_id=lookup('env', 'VAULT_SECRET_ID')
    ) }}"
  tasks:
    - name: Launch EC2 instance
      amazon.aws.ec2_instance:
        name: web-server
        instance_type: t3.micro
        image_id: ami-0abcdef1234567890
        aws_access_key: "{{ aws_creds.access_key }}"
        aws_secret_key: "{{ aws_creds.secret_key }}"
        security_token: "{{ aws_creds.security_token }}"
      no_log: true

SSH Certificate Signing

- name: Sign SSH key with Vault CA
  hosts: localhost
  connection: local
  tasks:
    - name: Sign SSH public key
      community.hashi_vault.vault_write:
        url: "{{ vault_addr }}"
        path: ssh-client-signer/sign/ansible-role
        data:
          public_key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
          valid_principals: deploy
          ttl: 30m
      register: signed_key
      no_log: true

- name: Write signed certificate ansible.builtin.copy: content: "{{ signed_key.data.signed_key }}" dest: ~/.ssh/id_rsa-cert.pub mode: '0600'

Vault Secret Engines for Ansible

| Engine | Use Case | Credential Type | |--------|----------|----------------| | KV v2 | Static secrets | Passwords, API keys, tokens | | Database | Database access | Dynamic username/password (PostgreSQL, MySQL, MongoDB) | | AWS | Cloud provisioning | Dynamic IAM credentials with STS | | SSH | Server access | Signed SSH certificates (short-lived) | | PKI | TLS/mTLS | Dynamic X.509 certificates | | Azure | Azure resources | Dynamic service principals | | GCP | GCP resources | Dynamic service account keys |

Best Practices

Use dynamic credentials whenever possible — Short-lived secrets that auto-expire eliminate the rotation burden entirely Always use no_log: true — On every task that handles Vault data to prevent secrets in job output Scope Vault policies tightly — Each AAP team/project gets its own Vault policy with minimum required permissions Use AppRole for machine authentication — Not human user tokens; AppRole is designed for automated workflows Enable audit logging — Every secret access should be logged: vault audit enable file file_path=/var/log/vault-audit.log Rotate AppRole Secret IDs — Automate Secret ID rotation on a regular schedule Separate environments — Use different Vault paths or namespaces for dev/staging/production Test with --check mode — Vault lookups still execute in check mode; plan accordingly

Troubleshooting

"Permission denied" from Vault

# Check current token policies
vault token lookup

# Verify path access directly vault kv get secret/ansible/database

# Check AppRole role configuration vault read auth/approle/role/aap

"hvac module not found"

pip install hvac
# On AAP: Add hvac to your execution environment requirements

FAQ

Can I use this with ansible-playbook CLI (not AAP)?

Yes — set VAULT_ADDR and VAULT_TOKEN environment variables, or pass auth_method parameters directly in the lookup plugin. AAP just wraps this in its credential system.

HashiCorp Vault vs Ansible Vault?

Ansible Vault encrypts files at rest (symmetric encryption). HashiCorp Vault is a full secret management platform with dynamic credentials, rotation, access policies, and audit logging. They complement each other — use Ansible Vault to encrypt the Vault connection details.

Vault Community vs Enterprise?

Community (free) works fully with AAP. Enterprise adds namespaces (multi-tenancy), cross-datacenter replication, HSM auto-unseal, and Sentinel policies for governance.

Conclusion

Integrating HashiCorp Vault with Ansible Automation Platform transforms credential management from a security liability into a competitive advantage. Dynamic secrets, automatic rotation, and comprehensive audit logging enable true zero-trust automation at enterprise scale.

Related Articles

Ansible Vault Complete GuideAnsible AWXAnsible AWS Complete Guide

Category: installation

Browse all Ansible tutorials · AnsiblePilot Home