Score:0

Dynamically passing a json as a parameter in a "command" task

lc flag

I have this task in my playbook:

- name: Update instance tags
    command: oci compute instance update -c {{ compartment }} --freeform-tags {{ tag_var_json }}

According to the oracle documentation for this command, the parameter --freeform-tags accepts a json that represents the key-value pair for the tag. I need to have this json be created dynamically in the playbook itself, so prior to running that task, I have this one for testing purposes:

  - name: Create a json object to use as tag
    set_fact:
      tag_var: '{ "test": "thisisatest" }'
    set_fact:
      tag_var_json: "{{ tag_var | to_json }}"

But I must be doing something wrong because I keep getting this error:
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'tag_var' is undefined

Is there an easier way of creating a json directly in the playbook and passing it as an argument to that parameter?

Thank you.

anx avatar
fr flag
anx
YAML keys ought to be unique. So your sample is incorrect syntax. Maybe you meant to set the variable in a different task?
anx avatar
fr flag
anx
Did you maybe misinterpret the error as something returned from your command? This is *ansible* itself talking, not a quote of a message returned from some program called!
Ress avatar
lc flag
I'm new to ansible so apologies. I'm just trying to pass a json in as as anrgument to a parameter as seen above, but I need to build said json in the same playbook
Score:1
th flag

There are two things going on here. The first is that you have created YAML that is accepted by the parser, but behaves in a slightly unexpected way (and will produce a warning in the current version of Ansible.)

  - name: Create a json object to use as tag
    set_fact:
      tag_var: '{ "test": "thisisatest" }'
    set_fact:
      tag_var_json: "{{ tag_var | to_json }}"

Keys in YAML are unique; when the parser encounters a second instance of the same key it throws away the first one. Since you've repeated set_fact, this is equivalent to:

  - name: Create a json object to use as tag
    set_fact:
      tag_var_json: "{{ tag_var | to_json }}"

Correcting the syntax error will still result in a failure, however.

  - name: Create a json object to use as tag
    set_fact:
      tag_var: '{ "test": "thisisatest" }'
      tag_var_json: "{{ tag_var | to_json }}"

The arguments to set_fact have to be templated before the task runs, at which point tag_var is still undefined (because this task is defining it.)

One correct way to write this task is as two separate tasks:

  - name: Create a tag object
    set_fact:
      tag_var:
        test: thisisatest

  - name: Create a JSON string for tagging
    set_fact: 
      tag_var_json: "{{ tag_var | to_json }}"

However, set_fact isn't required at all. You can just set the var directly on the task where you use it, which is both more efficient and makes it more tightly scoped.

- name: Update instance tags
    command: oci compute instance update -c {{ compartment }} --freeform-tags "{{ tag_var | to_json }}"
  vars:
    tag_var:
      test: thisisatest
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.