Utilizing timestamps within filenames

Hello,

In my deployments, I tend to do db backups and dump them into filenames containing a timestamp like so:

mysqldump dbname | gzip -9c > ~/dbname.date +%Y-%m-%d.%H%M.sql.gz ; ls -la ~/ | grep date +%Y-%m-%d`

`

As you can see, when the dump is done, I want to see the resulting file just to eyeball it and make everything looks right.

(To answer future questions: we date time stamp our backup files so that we can keep them for an extended period of time.)

I would like to write something like this:

`

  • hosts: dbserver
    remote_user: jlouthan
    tasks:

  • name: Backup Prod Database
    shell: mysqldump dbdump | gzip -9c > ~jlouthan/dbdump.date +%Y-%m-%d.sql.gz
    become: yes
    become_method: sudo

  • name: Check to see if the dbdump has been successfully created
    wait_for: path=~jlouthan/dbdump.date +%Y-%m-%d.sql.gz

`

Is there any chance that Ansible would be able to pick up on backticks or is there a better way?

Hi Joe,

you could add a task

- name: Get current timestamp
  local_action: command bash -c "date +%Y-%m-%d.%H%M"
  register: now
  run_once: true

(or something similar adapted to your local environment) before your
dump task and then use {{ now }} in the next tasks to always get the
same timestamp.

Best,
Felix

You can use a lookup or create a var based on it:

​datestring: ​"{{lookup(‘pipe’, “date +%Y-%m-%d.%H%M”)}}"

Apart form the other answers, I avoid using backticks and use the
$(date ...) syntax instead (a leading dollar sign and brackets instead
of backticks). Have you tried this?

Johannes

$() depends on shell, I prefer it as it is stackable and cleaner than the backticks, but not always available.

I ran this:

`

  • hosts: dbserver
    remote_user: jlouthan
    tasks:

  • name: Get current timestamp
    local_action: command bash -c “date +%Y-%m-%d.%H%M”
    register: timestamp
    run_once: true

  • debug: var=timestamp.stdout

  • name: Get current datestamp
    local_action: command bash -c “date +%Y-%m-%d”
    register: datestamp
    run_once: true

  • debug: var=datestamp.stdout

  • name: Backup Stag Database
    mysql_db: state=dump name=dbname target=~jlouthan/dbname.{{ datestamp }}.sql
    become: yes
    become_method: sudo

  • name: See the the Stag DB backup
    shell: ls -la ~jlouthan/ | grep {{ timestamp }}
    register: dumpstag

  • debug: var=dumpstag.stdout_lines

  • name: Make sure that the Stag DB Backups look good before you continue
    pause:

`

And got this:

`

[jlouthan@ansible-server Playbooks]$ ansible-playbook test-backup-Client-staging-db.yml
SUDO password:

PLAY [dbserver] **************************************************************

GATHERING FACTS ***************************************************************

ok: [dbserver]

TASK: [Get current timestamp] *************************************************
changed: [dbserver → 127.0.0.1]

TASK: [debug var=timestamp.stdout] ********************************************
ok: [dbserver] => {
“var”: {
“timestamp.stdout”: “2016-04-22.1507”
}
}

TASK: [Get current datestamp] *************************************************
changed: [dbserver → 127.0.0.1]

TASK: [debug var=datestamp.stdout] ********************************************
ok: [dbserver] => {
“var”: {
“datestamp.stdout”: “2016-04-22”
}
}

TASK: [Backup Stag Database] **************************************************
failed: [dbserver] => {“failed”: true}
msg: this module requires key=value arguments ([‘state=dump’, ‘name=dbname’, ‘target=~jlouthan/dbname.{changed:’, ‘True,’, ‘end:’, ‘2016-04-22 15:07:30.816204,’, ‘stdout:’, ‘2016-04-22,’, ‘cmd:’, ‘[bash,’, ‘-c,’, ‘date +%Y-%m-%d],’, ‘rc:’, ‘0,’, ‘start:’, ‘2016-04-22 15:07:30.810278,’, ‘stderr:’, ‘,’, ‘delta:’, ‘0:00:00.005926,’, ‘invocation:’, ‘{module_name:’, ‘ucommand,’, ‘module_complex_args:’, ‘{},’, ‘module_args:’, ‘ubash -c “date +%Y-%m-%d”},’, ‘stdout_lines:’, ‘[2016-04-22],’, ‘warnings:’, ‘}.sql’])

FATAL: all hosts have already failed – aborting

PLAY RECAP ********************************************************************
to retry, use: --limit @/home/jlouthan/test-backup-Client-staging-db.retry

dbserver : ok=5 changed=2 unreachable=0 failed=1

`

What am I doing wrong?

that the module name in the error is ‘ucommand’ and the spacing you posted, lends me to believe you are not matching the error to the actual play.

Hi Joe,

I ran this:
- hosts: dbserver
  remote_user: jlouthan
  tasks:
      - name: Get current timestamp
        local_action: command bash -c "date +%Y-%m-%d.%H%M"
        register: timestamp
        run_once: true

      - debug: var=timestamp.stdout

as you correctly note here, the variable you need is not timestamp, but
timestamp.stdout.

(I forgot the .stdout in my original mail.)

      - name: Backup Stag Database
        mysql_db: state=dump name=dbname target=~jlouthan/dbname.{{
datestamp }}.sql

Here you have to write {{ datestamp.stdout }} instead of
{{ datestamp }}; otherwise, instead of just the datestamp, the whole
dict will be appended, which results in the error message you get below.

TASK: [Backup Stag Database]
**************************************************
failed: [dbserver] => {"failed": true}
msg: this module requires key=value arguments (['state=dump',
'name=dbname', 'target=~jlouthan/dbname.{changed:', 'True,', 'end:',
'2016-04-22 15:07:30.816204,', 'stdout:', '2016-04-22,', 'cmd:',
'[bash,', '-c,', 'date +%Y-%m-%d],', 'rc:', '0,', 'start:',
'2016-04-22 15:07:30.810278,', 'stderr:', ',', 'delta:',
'0:00:00.005926,', 'invocation:', '{module_name:', 'ucommand,',
'module_complex_args:', '{},', 'module_args:', 'ubash -c "date
+%Y-%m-%d"},', 'stdout_lines:', '[2016-04-22],', 'warnings:',
'}.sql'])

Here you can see that {{ datestamp }} was replaced by:

{changed:', 'True,', 'end:', '2016-04-22 15:07:30.816204,', 'stdout:',
'2016-04-22,', 'cmd:', '[bash,', '-c,', 'date +%Y-%m-%d],', 'rc:',
'0,', 'start:', '2016-04-22 15:07:30.810278,', 'stderr:', ',',
'delta:', '0:00:00.005926,', 'invocation:', '{module_name:',
'ucommand,', 'module_complex_args:', '{},', 'module_args:', 'ubash -c
"date +%Y-%m-%d"}

which is NOT what you want :slight_smile:

Best,
Felix

That’s it! Thank you!

To avoid being “that guy”, here is the working playbook:

`

Also, just as an FYI, this can be achieved without calling the date command: