1. Use a separate secret management service, such as Vault by HashiCorp, Keywhiz by Square, or a hosted service like AWS’s Key Management Service or Microsoft Azure’s Key Vault.
    2. Use Ansible Vault, which is built into Ansible and stores encrypted passwords and other sensitive data alongside the rest of your playbook.

    Ansible Vault works much like a real-world vault:

    1. You take any YAML file you would normally have in your playbook (e.g. a variables file, host vars, group vars, role default vars, or even task includes!), and store it in the vault.
    2. Ansible encrypts the vault (‘closes the door’), using a key (a password you set).
    3. You store the key (your vault’s password) separately from the playbook in a location only you control or can access.
    4. You use the key to let Ansible decrypt the encrypted vault whenever you run your playbook.

    Let’s see how it works in practice. Here’s a playbook in a file named main.yml that demonstrates the use of an API key:

    1. ---
    2. - hosts: localhost
    3. connection: local
    4. gather_facts: no
    5. vars_files:
    6. - vars/api_key.yml
    7. tasks:
    8. - name: Echo the API key which was injected into the env.
    9. shell: echo $API_KEY
    10. environment:
    11. API_KEY: "{{ myapp_api_key }}"
    12. register: echo_result
    13. - name: Show the result.
    14. debug: var=echo_result.stdout

    vars/api_key.yml:

    ---
    myapp_api_key: "l9bTqfBlbXTQiDaJMqgPJ1VdeFLfId98"
    

    This is convenient, but it’s not safe to store the API key in plain text. Even when running the playbook locally on an access-restricted computer, secrets should be encrypted.

    To encrypt the file with Vault, run:

    ~/Downloads/tmp took 2s
    ❯ ansible-vault encrypt vars/api_key.yml
    New Vault password:
    Confirm New Vault password:
    Encryption successful
    

    Enter a secure password for the file, and Ansible will encrypt it. If you open the file now, you should see something like:

    ~/Downloads/tmp took 8s
    ❯ cat vars/api_key.yml
    $ANSIBLE_VAULT;1.1;AES256
    36656634633630653262663338373235306137613534653431383835333662303162633536623066
    3736653466633939633639313565373734313930323436340a626533396534653266656162356538
    39326635303861343533306637663338623061663062663138623538386134656536303465656162
    3335343436396538660a663933353161616538363930646664626639653632353065303636376362
    31313931306332663862623463616135313838653632353763623761303739666266323663336235
    36663763313165356232373636633439326264306266303461373561383837333866626238373862
    626636653833396335373362633233313434
    

    Next time you run the playbook, you will need to provide the password. If you don’t specify the password, you’ll receive an error:

    ~/Downloads/tmp
    ❯ ansible-playbook main.yml
    [WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to
    see details
    ERROR! Attempting to decrypt but no vault secrets found
    

    There are a number of ways you can provide the password, depending on how you run playbooks. Providing the password at playbook runtime works well when running a playbook interactively:

    # Use --ask-vault-pass to supply the vault password at runtime.
    ~/Downloads/tmp
    ❯ ansible-playbook main.yml --ask-vault-pass
    Vault password:
    

    For convenience, or for automated playbook runs (e.g. on a continuous integration server), you can supply vault passwords via a password file. Just like secure keys in your ∼/.ssh folder, you should treat these files carefully: never check them into source control, and set strict permissions (e.g. 600) so only you can read or write this file. Create the file ∼/.ansible/vault_pass.txt with your password in it, set permissions to 600, and tell Ansible the location of the file when you run the playbook:

    # Use --vault-password-file to supply the password via file/script.
    ~/Downloads/tmp took 4s
    ❯ ansible-playbook main.yml --vault-password-file=~/.ansible/vault_pass.txt
    

    More options and examples are available in the official documentation for Ansible Vault.