Ansible – Why Can’t {{ ansible_facts[‘ansible_distribution_release’] }} Be Used in Playbook?

ansible

I have ansible task run on localhost like this

  - name: add docker repository
    apt_repository:
      repo: "deb [arch=amd64] https://download.docker.com/linux/debian {{ ansible_facts['ansible_distribution_release'] }} stable"
      state: present
      filename: docker-ce

I wish to use variable ansible_facts['ansible_distribution_release'] to get the os distribution name, in my case, it should be buster. But it runs into an error like this

"The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'ansible_distribution_release'

I tried to use {{ ansible_distribution_release }} directly, and it works

repo: "deb [arch=amd64] https://download.docker.com/linux/debian {{ ansible_distribution_release }} stable"

Then I thought I should only access the facts directly, not access it as a key of the variable ansible_facts, but then I read the official document, I see use cases like

{{ ansible_facts['devices']['xvda']['model'] }}

It make me suspicious there is something wrong about my understanding of ansible variables

I've tried to not quote ansible_distribution_release in the [], ie, ansible_facts[ansible_distribution_release], but without luck

I run command below

$ ansible localhost -m setup -a "filter=ansible_distribution_release"

localhost | SUCCESS => {
    "ansible_facts": {
        "ansible_distribution_release": "buster"
    },
    "changed": false
}

thus proved there did have an attribute named ansible_distribution_release under ansible_facts.

Any help will be appreciated


udpate:
I use instructions show below

- name: debug                                                                                                                                                                                                      
  block:                                                                                                                                                                                                           
    - debug:                                                                                                                                                                                                       
        var: distribution_release                                                                                                                                                                        

    - debug:                                                                                                                                                                                                       
        var: ansible_distribution_release                                                                                                                                                                          

    - debug:                                                                                                                                                                                                       
        var: "{{ ansible_facts.keys() }}"                                                                                                                                                                          
  tags: show       

and find out distribution_release is not defined, ansible_distribution_release can be directly accessed, but there is no such key as ansible_distribution_release in ansible_facts, but there do have a key named distribution_release. this is difference from the out put from

ansible localhost -m setup

the documents says

INJECT_FACTS_AS_VARS

Facts are available inside the ansible_facts variable, this setting
also pushes them as their own vars in the main namespace. Unlike
inside the ansible_facts dictionary, these will have an ansible_
prefix.

It seems I can access facts in the mainspace without the ansible_ prefix

Best Answer

Take a look at all variables available to the host (localhost in this case)

- hosts: localhost
  tasks:
    - debug:
        var: hostvars.localhost

The debug tasks below are equivalent

    - debug:
        msg: "{{ ansible_facts['distribution_release'] }}"
    - debug:
        msg: "{{ ansible_distribution_release }}"

See Caching facts