# Ansible plugins and use cases

## ara_default callback: recording playbooks from Ansible

The `ara_default` Ansible callback plugin can be enabled by configuring Ansible with the `ANSIBLE_CALLBACK_PLUGINS` environment variable or the `callback_plugins` setting in an `ansible.cfg` file.

The callback is the component that recovers data during playbook execution and sends it to the API.

By default, the callback is configured up to use the local API server with the offline API client but it can be set up to use a remote API server, authenticate with credentials and more:

    callback: ara
    callback_type: notification
    requirements:
      - ara
    short_description: Sends playbook execution data to the ARA API internally or over HTTP
    description:
      - Sends playbook execution data to the ARA API internally or over HTTP
    options:
      api_client:
        description: The client to use for communicating with the API
        default: offline
        env:
          - name: ARA_API_CLIENT
        ini:
          - section: ara
            key: api_client
        choices: ['offline', 'http']
      api_server:
        description: When using the HTTP client, the base URL to the ARA API server
        default: http://127.0.0.1:8000
        env:
          - name: ARA_API_SERVER
        ini:
          - section: ara
            key: api_server
      api_username:
        description: If authentication is required, the username to authenticate with
        default: null
        env:
          - name: ARA_API_USERNAME
        ini:
          - section: ara
            key: api_username
      api_password:
        description: If authentication is required, the password to authenticate with
        default: null
        env:
          - name: ARA_API_PASSWORD
        ini:
          - section: ara
            key: api_password
      api_insecure:
        description: Can be enabled to ignore SSL certification of the API server
        type: bool
        default: false
        env:
          - name: ARA_API_INSECURE
        ini:
          - section: ara
            key: api_insecure
      api_timeout:
        description: Timeout, in seconds, before giving up on HTTP requests
        type: integer
        default: 30
        env:
          - name: ARA_API_TIMEOUT
        ini:
          - section: ara
            key: api_timeout
      argument_labels:
        description: |
            A list of CLI arguments that, if set, will be automatically applied to playbooks as labels.
            Note that CLI arguments are not always named the same as how they are represented by Ansible.
            For example, --limit is "subset", --user is "remote_user" but --check is "check".
        type: list
        default:
          - remote_user
          - check
          - tags
          - skip_tags
          - subset
        env:
          - name: ARA_ARGUMENT_LABELS
        ini:
          - section: ara
            key: argument_labels
      default_labels:
        description: A list of default labels that will be applied to playbooks
        type: list
        default: []
        env:
          - name: ARA_DEFAULT_LABELS
        ini:
          - section: ara
            key: default_labels
      ignored_facts:
        description: List of host facts that will not be saved by ARA
        type: list
        default: ["ansible_env"]
        env:
          - name: ARA_IGNORED_FACTS
        ini:
          - section: ara
            key: ignored_facts
      ignored_arguments:
        description: List of Ansible arguments that will not be saved by ARA
        type: list
        default: ["extra_vars"]
        env:
          - name: ARA_IGNORED_ARGUMENTS
        ini:
          - section: ara
            key: ignored_arguments
      ignored_files:
        description: List of patterns that will not be saved by ARA
        type: list
        default: []
        env:
          - name: ARA_IGNORED_FILES
        ini:
          - section: ara
            key: ignored_files
      callback_threads:
        description:
          - The number of threads to use in API client thread pools
          - When set to 0, no threading will be used (default) which is appropriate for usage with sqlite
          - Using threads is recommended when the server is using MySQL or PostgreSQL
        type: integer
        default: 0
        env:
          - name: ARA_CALLBACK_THREADS
        ini:
          - section: ara
            key: callback_threads

For example, a customized callback plugin configuration might look like this in an `ansible.cfg` file:

    [ara]
    api_client = http
    api_server = https://demo.recordsansible.org
    api_username = user
    api_password = password
    api_timeout = 15
    callback_threads = 4
    argument_labels = check,tags,subset
    default_labels = prod,deploy
    ignored_facts = ansible_env,ansible_all_ipv4_addresses
    ignored_arguments = extra_vars,vault_password_files

or as environment variables:

    export ARA_API_CLIENT=http
    export ARA_API_SERVER="https://demo.recordsansible.org"
    export ARA_API_USERNAME=user
    export ARA_API_PASSWORD=password
    export ARA_API_TIMEOUT=15
    export ARA_CALLBACK_THREADS=4
    export ARA_ARGUMENT_LABELS=check,tags,subset
    export ARA_DEFAULT_LABELS=prod,deploy
    export ARA_IGNORED_FACTS=ansible_env,ansible_all_ipv4_addresses
    export ARA_IGNORED_ARGUMENTS=extra_vars,vault_password_files

### Recording ad-hoc commands

It is possible to record ad-hoc commands in addition to playbooks since ara 1.4.1 and Ansible 2.9.7.

Ad-hoc command recording can be enabled by setting to `true` the `ANSIBLE_LOAD_CALLBACK_PLUGINS` environment variable or `bin_ansible_callbacks` in an `ansible.cfg` file.

### Playbook names and labels

Playbooks recorded by the ara callback can be given names or labels in order to make them easier to find and identify later.

They are set as ordinary Ansible variables and are evaluated at the beginning of each play. They can be provided directly in playbook files:

    - name: Deploy prod environment
      hosts: prod
      vars:
        ara_playbook_name: deploy prod
        ara_playbook_labels:
          - deploy
          - prod
      roles:
        - application

or as extra-vars:

    ansible-playbook -i hosts playbook.yaml \
        -e ara_playbook_name="deploy prod" \
        -e ara_playbook_labels=deploy,prod

Once set, they can be searched for in the UI, the API:

- `/api/v1/playbooks?name=prod`

- `/api/v1/playbooks?label=prod`

or the CLI:

- `ara playbook list --name prod`

- `ara playbook list --label prod`

### Default labels

Default labels will be applied to every playbook recorded by the callback plugin and can be specified with an `ansible.cfg` file:

    [defaults]
    # ...
    [ara]
    default_labels = deploy,prod

or through the environment variable `ARA_DEFAULT_LABELS`:

    export ARA_DEFAULT_LABELS=deploy,prod

### CLI argument labels

CLI argument labels will automatically apply labels to playbooks when specified CLI arguments are used.

For example, if `--check` is used and set up as an argument label, the playbook will be tagged with `check:True` if `--check` was used or `check:False` if it wasn’t.

Note

Some CLI arguments are not always named the same as how they are represented by Ansible. For example, `--limit` is “subset”, `--user` is “remote_user” but `--check` is “check”.

Argument labels can be configured through an `ansible.cfg` file:

    [defaults]
    # ...
    [ara]
    argument_labels = check,subset,tags

or through the environment variable `ARA_ARGUMENT_LABELS`:

    export ARA_ARGUMENT_LABELS=check,subset,tags

## ara_api: free-form API queries

The `ara_api` Ansible lookup plugin can be enabled by configuring Ansible with the `ANSIBLE_LOOKUP_PLUGINS` environment variable or the `lookup_plugins` setting in an `ansible.cfg` file.

It can be used to do free-form queries to the ara API while the playbook is running:

    - name: Test playbook
      hosts: localhost
      tasks:
        - name: Get failed results
          set_fact:
            failed: "{{ lookup('ara_api', '/api/v1/results?status=failed') }}"

        - name: Print task data from failed results
          vars:
            task_id: "{{ item.task | string }}"
            task: "{{ lookup('ara_api', '/api/v1/tasks/' + task_id ) }}"
            host_id: "{{ item.host | string }}"
            host: "{{ lookup('ara_api', '/api/v1/hosts/' + host_id) }}"
          debug:
            msg: "{{ host.name }} failed | {{ task.name }} ({{ task.path }}:{{ task.lineno }})"
          loop: "{{ failed.results }}"

## ara_playbook: get the running playbook or one in specific

The `ara_playbook` Ansible action plugin can be enabled by configuring Ansible with the `ANSIBLE_ACTION_PLUGINS` environment variable or the `action_plugins` setting in an `ansible.cfg` file.

Without any arguments, it can be used to return data about the playbook from which it is running:

    - name: Test playbook
      hosts: localhost
      tasks:
        - name: Get the currently running playbook
          ara_playbook:
          register: query

        - name: Retrieve playbook id
          set_fact:
            playbook_id: "{{ query.playbook.id | string }}"

        # With the playbook id we can create a link to the playbook report
        - name: Recover base url from ara
          set_fact:
            api_base_url: "{{ lookup('ara_api', '/api/') }}"

        - name: Print link to playbook report
          vars:
            ui_base_url: "{{ api_base_url.api[0] | regex_replace('/api/v1/', '') }}"
          debug:
            msg: "{{ ui_base_url }}/playbooks/{{ playbook_id }}.html"

With an argument, it can retrieve data from a specific playbook:

    - name: Test playbook
      hosts: localhost
      tasks:
        - name: Get a specific playbook
          ara_playbook:
            playbook: 9001
          register: query

        - name: Print data about the playbook
          debug:
            msg: "Playbook {{ query.playbook.status }} in {{ query.playbook.duration }}"

## ara_record: arbitrary key/values in playbook reports

The `ara_record` Ansible action plugin can be enabled by configuring Ansible with the `ANSIBLE_ACTION_PLUGINS` environment variable or the `action_plugins` setting in an `ansible.cfg` file.

It can be used to attach data or metadata to playbook reports so they are available later:

    - name: Test playbook
      hosts: localhost
      tasks:
        - name: Get git version of playbooks
          command: git rev-parse HEAD
          register: git_version

        - name: Record git version
          ara_record:
            key: "git_version"
            value: "{{ git_version.stdout }}"
          register: version

        - name: Print recorded data
          debug:
            msg: "{{ version.playbook_id }} - {{ version.key }}: {{ version.value }}

It is possible to declare a type which can be used to render the data appropriately later:

    - name: Record different things
      ara_record:
        key: "{{ item.key }}"
        value: "{{ item.value }}"
        type: "{{ item.type }}"
      loop:
        - { key: "log", value: "error", type: "text" }
        - { key: "website", value: "http://domain.tld", type: "url" }
        - { key: "data", value: '{ "key": "value" }', type: "json" }
        - { key: "somelist", value: ['one', 'two'], type: "list" }
        - { key: "somedict", value: {'key': 'value' }, type: "dict" }

### Adding records to playbooks after their completion

`ara_record` can attach data to a specific playbook by providing a playbook id. This can be useful for attaching data that might only be available once a playbook has been completed:

    - name: Attach data to a specific playbook
      ara_record:
        playbook: 9001
        key: logs
        value: "{{ lookup('file', '/var/log/ansible.log') }}"
        type: text

Or as an ad-hoc command:

    ansible localhost -m ara_record \
            -a "playbook=14 key=logs value={{ lookup('file', '/var/log/ansible.log') }}"