Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass integer variable to task without losing the integer type

Tags:

ansible

I've got a task (actually a role, but using a task here to make the example easier) that I don't own which does some operations on a variable. It assumes the variable is an integer. I need to somehow pass it a variable and have it come through as an int, and I'm not having any luck.

Here is a super simplified version of the task that I don't own:

frob.yml

- name: Validate that frob_count is <= 100
  fail: msg="{{frob_count}} is greater than 100"
  when: frob_count > 100

- name: Do real work
  debug: msg="We frobbed {{frob_count}} times!"

My playbook is:

- name: Frob some things
  hosts: localhost
  vars:
    things:
      - parameter: 1
      - parameter: 2
      - parameter: 45
  tasks:
    - with_items: "{{things}}"
      include: frob.yml
      vars:
        frob_count: "{{item.parameter}}"

No matter what, I get errors like "1 is greater than 100" from frob.yml. Looks like it's getting the var as a string instead of an integer.

I've tried stuff like frob_count: "{{item.parameter | int}}" with no luck. If I could change frob.yml it'd be easy, but like I said, that's out of my control. Any thoughts?

This is on Ansible 2.6.4

like image 488
Joe Avatar asked Sep 24 '18 21:09

Joe


1 Answers

Solution

  1. Upgrade to Ansible 2.7 (currently available as the stable-2.7 branch, scheduled for GA on Oct. 4th, 2018).

  2. Add jinja2_native=True to the [defaults] section of the ansible.cfg (or set an environment variable ANSIBLE_JINJA2_NATIVE=True.

  3. Leave your code as in the question (i.e., frob_count: "{{item.parameter}}").

The result:

TASK [Do real work] **********************************************************************************************************************
ok: [localhost] => {
    "msg": "We frobbed 1 times!"
}

TASK [Validate that frob_count is <= 100] ************************************************************************************************
skipping: [localhost]

TASK [Do real work] **********************************************************************************************************************
ok: [localhost] => {
    "msg": "We frobbed 2 times!"
}

TASK [Validate that frob_count is <= 100] ************************************************************************************************
skipping: [localhost]

TASK [Do real work] **********************************************************************************************************************
ok: [localhost] => {
    "msg": "We frobbed 45 times!"
}

Explanation

Currently any value returned by Jinja2 template is a string, so even if you used the int filter inside (as in {{item.parameter | int}}) the output is always rendered to a string by Ansible.

Ansible 2.7 will use (with the above parameter) a feature of Jinja 2.10 called Native Python Types and retain the data type.

like image 83
techraf Avatar answered Oct 21 '22 19:10

techraf