Skip to content

Empty or nonexistent Consul values in consul_kv lookup returns string "None" instead of None type or throwing error #11039

@malberton

Description

@malberton

Summary

In cases where a Consul key might not exist (e.g. typo in the key name) or if it has an empty value, rather than throwing an error and allowing us to fix the problem, the code continues to run.

Issue Type

Bug Report

Component Name

consul_kv lookup plugin

Ansible Version

$ ansible --version
ansible [core 2.18.1]
  config file = None
  configured module search path = ['/Users/malberton/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/malberton/.local/pipx/venvs/ansible-core/lib/python3.13/site-packages/ansible
  ansible collection location = /Users/malberton/.ansible/collections:/usr/share/ansible/collections
  executable location = /Users/malberton/.local/bin/ansible
  python version = 3.13.5 (main, Jun 11 2025, 15:36:57) [Clang 17.0.0 (clang-1700.0.13.3)] (/Users/malberton/.local/pipx/venvs/ansible-core/bin/python)
  jinja version = 3.1.5
  libyaml = True

Community.general Version

$ ansible-galaxy collection list community.general

# /Users/malberton/.ansible/collections/ansible_collections
Collection        Version
----------------- -------
community.general 10.2.0

Configuration

$ ansible-config dump --only-changed

OS / Environment

No response

Steps to Reproduce

# Start off by creating a real value and empty value in Consul to compare output
# $ consul kv put $CONSUL_PATH/foo "bar"
# $ consul kv put $CONSUL_PATH/empty ""

# Ansible
- name: Test Consul and Vault value lookup
  hosts: localhost
  gather_facts: no
  tasks:
    - name: Get 'foo' from Consul CLI
      command: consul kv get {{ consul_base_path }}foo
      register: consul_foo_cli_result
    - name: Get 'empty' from Consul CLI
      command: consul kv get {{ consul_base_path }}empty
      register: consul_empty_cli_result
    - name: Get 'foo' and 'empty' from Consul using lookup plugin
      set_fact:
        consul_foo: "{{ lookup('community.general.consul_kv', consul_base_path + 'foo') }}"
        consul_empty: "{{ lookup('community.general.consul_kv', consul_base_path + 'empty') }}"
        consul_empty_default: "{{ lookup('community.general.consul_kv', consul_base_path + 'empty') | default(None, true) }}"
        consul_empty_default_string: "{{ lookup('community.general.consul_kv', consul_base_path + 'empty') | default('', true) }}"
    - name: Display retrieved CLI values
      debug:
        msg:
          - "Consul CLI foo: '{{ consul_foo_cli_result.stdout }}' (length: {{ consul_foo_cli_result.stdout | length }})"
          - "Consul CLI empty: '{{ consul_empty_cli_result.stdout }}' (length: {{ consul_empty_cli_result.stdout | length }})"
    - name: Display retrieved LOOKUP values
      debug:
        msg:
          - "Consul foo: '{{ consul_foo }}' (length: {{ consul_foo | length }})"
          - "Consul empty: '{{ consul_empty }}' (length: {{ consul_empty | length }})"
          - "Consul empty_default: '{{ consul_empty_default }}' (length: {{ consul_empty_default | length }})"
          - "Consul empty_default_string: '{{ consul_empty_default_string }}' (length: {{ consul_empty_default_string | length }})"

Expected Results

I expected the lookup plugin to return the literal value that is stored in Consul, which the consul kv get ... CLI command does. In the case of the empty key, that would be either throwing an error, returning an empty string or returning a Python None type instead of the string "None".

Actual Results

PLAY [Test Consul and Vault value lookup] *****************************************************************************************************************************************************************

TASK [Get 'foo' from Consul CLI] **************************************************************************************************************************************************************************
changed: [localhost]

TASK [Get 'empty' from Consul CLI] ************************************************************************************************************************************************************************
changed: [localhost]

TASK [Get 'foo' and 'empty' from Consul using lookup plugin] **********************************************************************************************************************************************
ok: [localhost]

TASK [Display retrieved CLI values] ***********************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        "Consul CLI foo: 'bar' (length: 3)",
        "Consul CLI empty: '' (length: 0)"
    ]
}

TASK [Display retrieved LOOKUP values] ********************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        "Consul foo: 'bar' (length: 3)",
        "Consul empty: 'None' (length: 4)",
        "Consul empty_default: 'None' (length: 4)",
        "Consul empty_default_string: 'None' (length: 4)"
    ]
}

PLAY RECAP ************************************************************************************************************************************************************************************************
localhost                  : ok=5    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Code of Conduct

  • I agree to follow the Ansible Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis issue/PR relates to a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions