How can I create a path variable containing a timestamp?

Hi,

I’m trying to create something like:

vars:
path_to_somewhere: /home/somewhere/${timestamp}/foo

the timestamp format should be like the output of ‘date +%Y%m%d%H%M%S’ → 20130321164525

Is this possible?

Thank you

Clifford

Currently you can use "register" to store a variable, and then access it.

If you want all the timestamps to be the same, you could use a
particular host for the value and pull it out of hostvars.

See the documentation on "register" for some starter content.

Hi Michael,

thanks for answering.

As I undestand when using “register” the variable is created during task execution.
But I also need the variable in var files that are included.

– app-playbook.yml –

vars:
path_to_somewhere: /home/somewhere/${timestamp}/foo


vars_files:
…/vars/common_vars.yml

– common_vars.yml –
path_1: ${path_to_somewhere}/bar
path_2: ${path_1}/blah

path_1 and path_2 are then used in the task file

I also thought about getting the timestamp out of the hostvars but couldn’t find the right value yet.

Clifford

As I undestand when using "register" the variable is created during task execution.

But I also need the variable in var files that are included.

You could into the $PIPE lookup plugin

$PIPE(some command here)

The only downside is it will be evaluated a *lot*, work to make this
be evaluated outside of the multiprocessing loop can be done to make
it convert to variables earlier, but I must say including a variable
file based on the time and date seems
a little complicated to me.

Can I ask what the underlying use case is?

Hi Michael,

You could into the $PIPE lookup plugin

$PIPE(some command here)

so

vars:
timestamp: $PIPE(date +%Y%m%d%H%M%S)
path_1: /app/releases/${timestamp}-v1.0/ROOT

path_2: /app/config/${timestamp}-v2.3.1
path_3: ${path_2}/properties

would work? That would be great!

The only downside is it will be evaluated a lot, work to make this
be evaluated outside of the multiprocessing loop can be done to make
it convert to variables earlier, but I must say including a variable
file based on the time and date seems
a little complicated to me.

The documentation says:

“… and if it is used in a variable definition, it will be executed each time the variable is evaluated”

Does this mean that it would be called twice per server in the example above and there would be the possiblity of different values for ‘timestamp’?
This would be ok for my use case I think. It is not essential that those timestamps are equal.
I just need them to sort the folder names.

Can I ask what the underlying use case is?

Sure. I’m deploying using Ansible to deploy webapps and webservices to our tomcat instances.

The main steps of the workflow are:

  1. download artifact (zip containing application war and configuration jar) from Nexus into tmp folder /app/tmp and unpack
  2. unpack war to /app/releases/20130322201903-v1.0/ROOT
  3. create/change symlink /app/current_app to point to /app/releases/20130322201903-v1.0
  4. unpack jar to /app/config/20130322201904-v2.3.1
  5. create/change symlink /app/current_config to /app/config/20130322201904-v2.3.1
  6. delete /app/tmp
  7. restart tomcat

In case of an error i would do a rollback by just changing the symlinks to point to the folders to which they were linked before by reverse sorting the folder names.
As I understand capistrano uses a similar mechanism like this to have a fast and secure rollback.

Maybe I’m getting it all wrong. So please feel free to make suggestions

Regards,

Clifford

Regards,

"Does this mean that it would be called twice per server in the
example above and there would be the possiblity of different values
for 'timestamp'?"

Yes.

BTW, the super easiest way to do this would be assigning the timestamp
in a bash wrapper script and then using

--extra-vars="timestamp=foo"

I'm also not against making some more statistics based times available
as magic variables, like $ansible_play_start_time or something like
that.

Patches would be considered.

Doesn’t seem to work for me:

failed: [ec2-23-20-215-207.compute-1.amazonaws.com] => {“changed”: true, “cmd”: “tar -cf $PIPE(date +%Y%m%d-%H%M%S).tar file1”, “delta”: “0:00:00.007156”, “end”: “2014-08-26 08:46:56.146550”, “rc”: 2, “start”: “2014-08-26 08:46:56.139394”, “warnings”: [“Consider using unarchive module rather than running tar”]}
stderr: /bin/sh: 1: Syntax error: “(” unexpected

I’ve got this in the playbook :

  • name: Create timestamped backup
    hosts: all
    sudo: no
    gather_facts: False
    vars:
    timestamp: $PIPE(date +%Y%m%d%H%M%S)
    tasks:
  • name: backup existing files

shell: tar -cf {{ timestamp }}.tar file1
args:
executable: /bin/bash
register: backup
ignore_errors: true

Ansible is putting the verbatim contents of the timestamp var into the tar command. I would’ve hoped those contents got evaluated first, into a timestamp.

Ps: why is the latest ansible checkout showing me cowsays instead of regular play/task/… titles? :smiley:

e.g.

Yeah that’s an easy one, fortunately!

That above thread that is well over a year and a half old, using some syntax in Ansible that is quite out of date, and legacy syntaxes like that have been pruned from Ansible in that time (after deprecating over the course of several releases with notes about how to upgrade)

change the $PIPE(…) to:

{{ lookup(‘pipe’, ‘date +%Y%m%d%H%M%S’ }}

Should be good to go!

Wouldn’t the value change in the course of a play?

Michael DeHaan michael@ansible.com napisał:

Yep.

The trick would be to set it via set_fact…

set_fact:
var: {{ lookup(‘pipe’, ‘foo’) }}

And then refer to it consistently from one host via hostvars, or not care that it was different.

Ps: why is the latest ansible checkout showing me cowsays instead of regular play/task/… titles? :smiley:

hmm… I always have the nocows=1 in my ansible.cfg
otherwise, if ansible finds the cowsay package, it will use it by default.

That would be a question for a new thread, but this topic hasn’t changed.

Sorry: big list, do need to play thread-cop.

this topic → this behavior.

Probably your config file has it in the wrong section.

Just saw the responses. Thanks, Michael, for the workaround (syntax update). The cowsay thing was just an offhand question, as I didn’t, for the life of me, know why Ansible would start doing that all of a sudden :stuck_out_tongue:

It’s because cows make people happy! :slight_smile: