2

I have encountered a problem and hope to get your help, thank you!

Example:

 - hosts: localhost
   tasks:
   - name: "set variable"
     set_fact:
       test1:
         a: 1
   - name: "assignment"
     set_fact:
       test2:
         a: "{{test1.a}}"
   - name: "print test2"
     debug:
       var: test2

Output is :

"test2":{ "a": "1"}

What i expect is :

"test2":{ "a": 1}
Y.Jie
  • 148
  • 1
  • 8

2 Answers2

3

Q: Output is : "test2":{ "a": "1"}

A: This is correct. An output of Jinja is a string (it's a template engine). You declared test1.a as an integer (without quotes)

    - set_fact:
        test1:
          a: 1
    - debug:
        msg: "{{ test1.a|type_debug }}"

gives

  msg: int

But, the evaluation of "{{ test1.a }}" resulted in a string

    - set_fact:
        test2:
          a: "{{ test1.a }}"
    - debug:
        var: test2
    - debug:
        msg: "{{ test2.a|type_debug }}"

give

  test2:
    a: '1'

  msg: str

There are more options on how to preserve types.

  1. Use configuration option DEFAULT_JINJA2_NATIVE (default: False).

"This option preserves variable types during template operations."

This will influence the whole playbook. For example

shell> ANSIBLE_JINJA2_NATIVE=True ansible-playbook pb.yml

gives

  test2:
    a: 1

  msg: int
  1. Next option is a combination of the dictionaries. For example
    - set_fact:
        test2: "{{ test2|default({})|combine({'a': test1.a}) }}"
    - debug:
        var: test2
    - debug:
        msg: "{{ test2.a|type_debug }}"

give

  test2:
    a: 1

  msg: int

Single (bare) variables behave differently and preserve the types. For example

   - set_fact:
        v2: 1
    - debug:
        msg: "{{ v2 }}"
    - debug:
        msg: "{{ v2|type_debug }}"

    - set_fact:
        v3: "{{ v2 }}"
    - debug:
        msg: "{{ v3 }}"
    - debug:
        msg: "{{ v3|type_debug }}"

give

  msg: 1
  msg: int
  msg: 1
  msg: int

(I've used yaml callback plugin "ANSIBLE_STDOUT_CALLBACK=yaml ansible-playbook pb.yml")

Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63
0

This is default behaviour. I am unsure why you would expect the value to display without quotes.

Perhaps you're thinking the value is converted to a string, but it is not.

   - name: set variable
     set_fact:
       test1:
         a: 1

   - name: check if variable is integer
     assert:
       that:
         - test1.a | type_debug == "int"
         - test1.a is regex("^[0-9]+$")

   - name: assignment
     debug:
       var: "{{ test1.a }}"
Kevin C
  • 4,851
  • 8
  • 30
  • 64