Persistent set_fact

656 views
Skip to first unread message

Hagai Kariti

unread,
Sep 23, 2014, 12:51:56 PM9/23/14
to ansibl...@googlegroups.com
Hi

I was thinking about extending set_fact to be able to write the facts given as a local facts file. Something like this:

set_fact: var=value persistent_file=myvars

To create /etc/ansible/facts.d/myvars.fact as a json with the given vars.

Is this something that might be considered for core? Do you guys have opinions on semantics (separate to a different module maybe)?

Thanks

Michael DeHaan

unread,
Sep 23, 2014, 4:30:58 PM9/23/14
to Hagai Kariti, ansibl...@googlegroups.com
This is a pretty interesting way to do it and I don't think I'd have an objection to it.  

It would probably need to call the "copy" module in the action_plugin to make it work, using the "content" parameter.

Having it the same module seems to make sense to me.

Pull request would definitely be welcome!




--
You received this message because you are subscribed to the Google Groups "Ansible Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-deve...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Hagai Kariti

unread,
Sep 23, 2014, 5:50:10 PM9/23/14
to Michael DeHaan, ansible-devel

Is there a reason to keep it an action plugin and not a normal module? I'm thinking performance, is there something else?

James Cammarata

unread,
Sep 23, 2014, 8:45:11 PM9/23/14
to Hagai Kariti, Michael DeHaan, ansible-devel
If you look at set_fact now, it's completely an action plugin, since it only operates on the host running ansible and not on each individual host (others like this are add_host/group_by, template and fetch modules, which work entirely through action plugins). This saves a lot of effort in having to re-implement common functionality like copying a file out to a host.

To me, it sounds like this new module would be dumping the contents of the vars_cache[hostname] to a file, or perhaps just a subset of those variables?

Michael DeHaan

unread,
Sep 23, 2014, 10:19:32 PM9/23/14
to James Cammarata, Hagai Kariti, ansible-devel
One gotcha I just realized is local facts show up as "ansible_local.factname" to ensure they never override another fact, kind of as a safety feature.

I would think it would write just the one variable to a facts.d/variable_name file, but it should probably raise an error with persistent=yes if the variable name didn't start with "ansible_local", since otherwise it would be set and referenced differently when retrieved the second time.

Like so:

# works
set_fact: name=ansible_local.foo value=1234 persistent=yes

# raises error:  "when using persistent=yes, the variable must be prefixed with 'ansible_local'"
set_fact: name=foo value=1234 persistent=yes

# works fine but doesn't save
set_fact: name=foo value=1234

And then in the docs we could make a note of it.




Hagai Kariti

unread,
Sep 24, 2014, 3:19:06 AM9/24/14
to ansibl...@googlegroups.com, jcamm...@ansible.com, hka...@gmail.com

On Wednesday, September 24, 2014 5:19:32 AM UTC+3, michael wrote:
One gotcha I just realized is local facts show up as "ansible_local.factname" to ensure they never override another fact, kind of as a safety feature.

I would think it would write just the one variable to a facts.d/variable_name file, but it should probably raise an error with persistent=yes if the variable name didn't start with "ansible_local", since otherwise it would be set and referenced differently when retrieved the second time.

Like so:

# works
set_fact: name=ansible_local.foo value=1234 persistent=yes


This is different than how set_fact is used now - you pass args as key=value, not as name=key value=value. I think that will also make it harder to create more complex facts:

  set_fact: name=ansible_local.foo value={{ {key: value, key2:value2} }} persistent=yes # ugh

BTW do people use local facts for single values? I didn't think about it until now, and the docs don't give this usage in the examples. 

Another option, which may be a bit magic-y, is to set the facts in the ansible_local namespace if they're persistent:

  set_fact: myfact1=123 myfact2=asd # Will set myfact1=123, myfact2=asd
 
  set_fact: myfact=123 myfact2=asd persistent=hkariti # Will set ansible_local.hkariti={myfact1: 123, myfact2: asd} and save

This doesn't work for single values though.

Michael DeHaan

unread,
Sep 24, 2014, 11:29:03 AM9/24/14
to Hagai Kariti, ansibl...@googlegroups.com, James Cammarata
On Wed, Sep 24, 2014 at 3:19 AM, Hagai Kariti <hka...@gmail.com> wrote:

On Wednesday, September 24, 2014 5:19:32 AM UTC+3, michael wrote:
One gotcha I just realized is local facts show up as "ansible_local.factname" to ensure they never override another fact, kind of as a safety feature.

I would think it would write just the one variable to a facts.d/variable_name file, but it should probably raise an error with persistent=yes if the variable name didn't start with "ansible_local", since otherwise it would be set and referenced differently when retrieved the second time.

Like so:

# works
set_fact: name=ansible_local.foo value=1234 persistent=yes


This is different than how set_fact is used now - you pass args as key=value, not as name=key value=value. I think that will also make it harder to create more complex facts:

Sorry, this was just me tying too quickly, conceptually, I mean the same thing.
 

  set_fact: name=ansible_local.foo value={{ {key: value, key2:value2} }} persistent=yes # ugh

This isn't a thing with setting a hash like this in a one liner, BTW.  You must use the long form.

set_fact:
    key: { key: value, key2: value2 }

And if you want variables, you can template inside, etc.

 
Another option, which may be a bit magic-y, is to set the facts in the ansible_local namespace if they're persistent:

  set_fact: myfact1=123 myfact2=asd # Will set myfact1=123, myfact2=asd

I'd like to avoid this, because then the usage of the variable would have to be accessed by ansible_local.foo, which would be unclear
to readers of the playbook because it was set one way and is accessed another.
Reply all
Reply to author
Forward
0 new messages