Adding to a list multiple times with set_fact

1,034 views
Skip to first unread message

Neech WORTHINGTON

unread,
Sep 9, 2015, 8:14:06 AM9/9/15
to Ansible Project, neech.wo...@alcatel-lucent.com
Greetings fellow Ansible users!

I have a use case where I want to add values to a list dependant on host groups. I will then use the resulting list as an argument to another task.

It's important than I don't have duplicate values in the list, so I am using union() to add new items to the list, as indicated by http://docs.ansible.com/ansible/playbooks_filters.html

For some reason, as soon as a set_fact task is run against the same host and variable for a second time, Ansible explodes with an unintuitive Python/Jinja2 error, saying it's getting a list when it doesn't expect a list (which makes NO sense to me, because union() wants two lists are arguments surely?!).

fatal: [host4-uk] => Failed to template fruit="{{ fruit | union([ 'Goosberry', 'Blackberry' ]) }}": an unexpected type error occurred. Error was coercing to Unicode: need string or buffer, list found

Can anybody shed any light on this? Am I doing something particularly silly? Is there a better way to achieve what I want to do?

To illustrate the problem, I have tried to distill the issue down to this simple example:

nicola $ ls -1 *
fruit.yaml
inventory

group_vars:
all


nicola $ cat group_vars/all
 fruit:
   - UniversalFruit1-Foo


nicola $ cat inventory
[tropical]
host1-asia ansible_ssh_host=172.18.32.89
host2-asia ansible_ssh_host=172.18.97.157

[domestic]
host3-uk ansible_ssh_host=172.18.128.12
host4-uk ansible_ssh_host=172.18.128.13

[berries]
host4-uk ansible_ssh_host=172.18.128.13


nicola $ cat fruit.yaml
---

- hosts: all
  tasks:
    - debug: var=fruit

- hosts: tropical
  tasks:
    - set_fact: fruit="{{ fruit | union([ 'Kiwi', 'Mango' ]) }}" #"

- hosts: all
  tasks:
    - debug: var=fruit

- hosts: domestic
  tasks:
    - set_fact: fruit="{{ fruit | union([ 'Apple', 'Blackberry' ]) }}" #"

- hosts: all
  tasks:
    - debug: var=fruit

- hosts: berries
  tasks:
    - set_fact: fruit="{{ fruit | union([ 'Goosberry', 'Blackberry' ]) }}" #"

- hosts: all
  tasks:
    - debug: var=fruit

- hosts: all
  tasks:
    - set_fact: fruit="{{ fruit | union([ 'UniversalFruit1-Foo', 'UniversalFruit2-Bar' ]) }}" #"

- hosts: all
  tasks:
    - debug: var=fruit


nicola $ ansible-playbook -i inventory fruit.yaml

PLAY [all] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [host3-uk]
ok: [host4-uk]
ok: [host1-asia]
ok: [host2-asia]

TASK: [debug var=fruit] *******************************************************
ok: [host1-asia] => {
    "var": {
        "fruit": [
            "UniversalFruit1-Foo"
        ]
    }
}
ok: [host2-asia] => {
    "var": {
        "fruit": [
            "UniversalFruit1-Foo"
        ]
    }
}
ok: [host4-uk] => {
    "var": {
        "fruit": [
            "UniversalFruit1-Foo"
        ]
    }
}
ok: [host3-uk] => {
    "var": {
        "fruit": [
            "UniversalFruit1-Foo"
        ]
    }
}

PLAY [tropical] ***************************************************************

GATHERING FACTS ***************************************************************
ok: [host1-asia]
ok: [host2-asia]

TASK: [set_fact fruit="{{ fruit | union([ 'Kiwi', 'Mango' ]) }}"] *************
ok: [host1-asia]
ok: [host2-asia]

PLAY [all] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [host3-uk]
ok: [host4-uk]
ok: [host1-asia]
ok: [host2-asia]

TASK: [debug var=fruit] *******************************************************
ok: [host4-uk] => {
    "var": {
        "fruit": [
            "UniversalFruit1-Foo"
        ]
    }
}
ok: [host1-asia] => {
    "var": {
        "fruit": [
            "UniversalFruit1-Foo",
            "Kiwi",
            "Mango"
        ]
    }
}
ok: [host2-asia] => {
    "var": {
        "fruit": [
            "UniversalFruit1-Foo",
            "Kiwi",
            "Mango"
        ]
    }
}
ok: [host3-uk] => {
    "var": {
        "fruit": [
            "UniversalFruit1-Foo"
        ]
    }
}

PLAY [domestic] ***************************************************************

GATHERING FACTS ***************************************************************
ok: [host3-uk]
ok: [host4-uk]

TASK: [set_fact fruit="{{ fruit | union([ 'Apple', 'Blackberry' ]) }}"] *******
ok: [host3-uk]
ok: [host4-uk]

PLAY [all] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [host4-uk]
ok: [host3-uk]
ok: [host1-asia]
ok: [host2-asia]

TASK: [debug var=fruit] *******************************************************
ok: [host2-asia] => {
    "var": {
        "fruit": [
            "UniversalFruit1-Foo",
            "Kiwi",
            "Mango"
        ]
    }
}
ok: [host1-asia] => {
    "var": {
        "fruit": [
            "UniversalFruit1-Foo",
            "Kiwi",
            "Mango"
        ]
    }
}
ok: [host4-uk] => {
    "var": {
        "fruit": [
            "UniversalFruit1-Foo",
            "Apple",
            "Blackberry"
        ]
    }
}
ok: [host3-uk] => {
    "var": {
        "fruit": [
            "UniversalFruit1-Foo",
            "Apple",
            "Blackberry"
        ]
    }
}

PLAY [berries] ****************************************************************

GATHERING FACTS ***************************************************************
ok: [host4-uk]

TASK: [set_fact fruit="{{ fruit | union([ 'Goosberry', 'Blackberry' ]) }}"] ***
fatal: [host4-uk] => Failed to template fruit="{{ fruit | union([ 'Goosberry', 'Blackberry' ]) }}": an unexpected type error occurred. Error was coercing to Unicode: need string or buffer, list found

FATAL: all hosts have already failed -- aborting

PLAY RECAP ********************************************************************
           to retry, use: --limit @/home/nworthington/fruit.yaml.retry

host1-asia                 : ok=8    changed=0    unreachable=0    failed=0
host2-asia                 : ok=8    changed=0    unreachable=0    failed=0
host3-uk                   : ok=8    changed=0    unreachable=0    failed=0
host4-uk                   : ok=9    changed=0    unreachable=1    failed=0

nicola $

trupti mali

unread,
Sep 13, 2015, 12:40:25 PM9/13/15
to Ansible Project, neech.wo...@alcatel-lucent.com
Hello,
How did you resolve this problem. I too faced the same  thing but no resolution yet.

~Trupti
Reply all
Reply to author
Forward
0 new messages