Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Managing remotely-generated API keys with Ansible

I’m using ansible to provision a particular service, and before I can interact with it I must first generate an API key. But I can’t predefine that key in my playbook (as a secret) – it is generated by the server, returned to me once, and will never be exposed again (the typical scnenario for API keys).

I could ask the server to generate a new API key every time I run that playbook, or tags in that playbook, but that is very slow. Ideally I should save that API key locally and reuse it.

My approach has been to simply write it to a local file in my user directory (~/.ansible/custom/api_key.txt) so it has some protection. That works but feels kind of dirty.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Does ansible have an official / robust way to handle this scenario?

>Solution :

This is kind of a broad question. There are a variety of ways of handling secrets in your playbooks; this article describes several options, and there are a variety of articles online that cover similar topics.

A simple option might be to encrypt the API key to a GPG public key for which the private key is only available when you’re logged in and able to provide the passphrase.

Here’s a simple (i.e. not particularly robust) example:

- hosts: localhost
  gather_facts: false

  tasks:
    # Check if the file in which we cache the API key exists.
    # If not, fetch the API key from the API and store it in
    # a GPG-encrypted file.
    - when: apikey_file is not file
      block:
        # This is just a dummy task to give us a string; you would of
        # course replace this with the logic to acquire an API key.
        - name: Get key from API
          command: echo secret.key
          register: apikey

        # Encrypt the key using the public key for the identity
        # stored in apikey_gpg_id.
        - name: Write API key to file
          command: >-
            gpg -o "{{ apikey_file }}" -e -r "{{ apikey_gpg_id }}"
          args:
            stdin: "{{ apikey.stdout }}"

- hosts: localhost
  gather_facts: false

  tasks:
    # Decrypt the API key file to stdout. This requires us to type in
    # the passphrase (which may be cached for some amount of time in your
    # GPG agent).
    - name: Read API key from file
      command: >-
        gpg -d "{{ apikey_file }}"
      register: apikey

    # Show what we got from the previous task.
    - debug:
        var: apikey.stdout

This presumes that the variables apikey_file and apikey_gpg_id are defined in advance — I’ve put them in group_vars/all.yaml, but they could also be defined in your inventory or elsewhere depending on how your project is structured.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading