# Persistent set\_fact

**URL:** <https://forum.ansible.com/t/persistent-set-fact/16309>\
**Category:** Ansible Developer\
**Created:** [September 23, 2014, 4:51pm UTC](https://forum.ansible.com/t/persistent-set-fact/16309 "2014-09-23T16:51:56Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Hagai\_Kariti](https://avatars.discourse-cdn.com/v4/letter/h/4491bb/32.png) [@Hagai\_Kariti](https://forum.ansible.com/u/Hagai_Kariti)\
**Post date:** [September 23, 2014, 4:51pm UTC](https://forum.ansible.com/t/persistent-set-fact/16309/1 "2014-09-23T16:51:56Z")

</div>

Hi

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

&nbsp;&nbsp;&nbsp;&nbsp;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

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [September 23, 2014, 8:30pm UTC](https://forum.ansible.com/t/persistent-set-fact/16309/2 "2014-09-23T20:30:55Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![Hagai\_Kariti](https://avatars.discourse-cdn.com/v4/letter/h/4491bb/32.png) [@Hagai\_Kariti](https://forum.ansible.com/u/Hagai_Kariti)\
**Post date:** [September 23, 2014, 9:50pm UTC](https://forum.ansible.com/t/persistent-set-fact/16309/3 "2014-09-23T21:50:07Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![James\_Cammarata](https://avatars.discourse-cdn.com/v4/letter/j/7c8e57/32.png) [@James\_Cammarata](https://forum.ansible.com/u/James_Cammarata)\
**Post date:** [September 24, 2014, 12:45am UTC](https://forum.ansible.com/t/persistent-set-fact/16309/4 "2014-09-24T00:45:10Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [September 24, 2014, 2:19am UTC](https://forum.ansible.com/t/persistent-set-fact/16309/5 "2014-09-24T02:19:30Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Hagai\_Kariti](https://avatars.discourse-cdn.com/v4/letter/h/4491bb/32.png) [@Hagai\_Kariti](https://forum.ansible.com/u/Hagai_Kariti)\
**Post date:** [September 24, 2014, 7:19am UTC](https://forum.ansible.com/t/persistent-set-fact/16309/6 "2014-09-24T07:19:06Z")

</div>

> 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.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [September 24, 2014, 3:29pm UTC](https://forum.ansible.com/t/persistent-set-fact/16309/7 "2014-09-24T15:29:02Z")

</div>

> > 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.

> &nbsp;&nbsp;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:  
&nbsp;&nbsp;&nbsp;&nbsp;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:
> 
> &nbsp;&nbsp;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.
