Template module. MODE all wrong when using loop

When using the template module within a loop, my mode comes out all weird/wrong. When using stand-alone it works:

`

  • name: test
    template:
    src: “files/sssd.conf”
    dest: “/etc/sssd/sssd.conf”
    mode: 0600
    group: root
    owner: root

  • name: Add/Update required files
    template:
    src: “{{item.src}}”
    dest: “{{item.dst}}”
    owner: root
    group: root
    mode: “{{item.mode}}”
    with_items:

  • {src: “files/sssd.conf”,
    dst: “/etc/sssd/sssd.conf”,
    mode: 0600}

  • {src: “files/krb5.conf”,
    dst: “/etc/krb5.conf”,
    mode: 0644}

  • {name: “dc1.cer”,
    src: “files/dc1.cer”,
    dst: “/etc/ssl/certs/dc1.cer”,
    mode: 0644}
    notify: restart sssd

`

Results :

`
TASK [ldap_users : test] ********************************************************************************************************************************************************************************************
changed: [ansibletest-oel6]

TASK [ldap_users : Add/Update required files] ********************************************************************************************************************************************************************************************
failed: [ansibletest-oel6] (item={u’src’: u’files/sssd.conf’, u’dst’: u’/etc/sssd/sssd.conf’, u’mode’: 384}) => {“details”: “bad symbolic permission for mode: 384”, “failed”: true, “gid”: 0, “group”: “root”, “item”: {“dst”: “/etc/sssd/sssd.conf”, “mode”: 384, “src”: “files/sssd.conf”}, “mode”: “0416”, “msg”: “mode must be in octal or symbolic form”, “owner”: “root”, “path”: “/etc/sssd/sssd.conf”, “size”: 1445, “state”: “file”, “uid”: 0}
ok: [ansibletest-oel6] => (item={u’src’: u’files/krb5.conf’, u’dst’: u’/etc/krb5.conf’, u’mode’: 420})
ok: [ansibletest-oel6] => (item={u’src’: u’files/dc1.cer’, u’dst’: u’/etc/ssl/certs/dc1.cer’, u’name’: u’dc1.cer’, u’mode’: 420})

`

As you can see from the above, the test works (confirmed that the mode is truly 0600 on the target server). From the second part of the results, you can see that it is trying to tweak the mode different than the test. The first one it bombs on (mode 0600) and the second two (0644) it changes to 420… like a umask is being applied.

Is this a bug? or am I doing something wrong?

If I do the following it works (putting quotes around the mode). Can anybody explain to my why?

Yes, Ansible interprets number starting with 0 as octal number.
0644 = 6*8^2 + 4*8^1 + 4*8^0 = 420 decimal.

So to avoid this conversion you need to use the quotes.

Perfect! Thank you Kai Stian Olstad

Actually, that brings up a follow-up question… why doesn’t it treat it that way in the first example, when I don’t use a loop?

let me explain this a little better....

You want to set the mode to octal 0600 which is the same as decimal
420. So either of these would be fine:

  mode: 0600
  mode: 420

Ansible's template module also accepts string versions of the mode.
The strings are similar to what chmod would accept on the commandline.
So this is fine:

  mode: "0600"

Since chmod accepts a string "600" as a synonym for the above, if
Ansible gets that string it will also accept it:
  mode: "600"

Now, for your second example, you aren't giving ansible any of the
above values. Let me show you what's happening.

First, the mode is set in your data structure as 0600 octal. Which is
420 decimal as Kai said. Then the value is getting substituted into
the task parameters like this:
  mode: "{{ item.mode }}"

So you end up with:
  mode: "420"

This is the string, 420. not the decimal number 420. And that's why
Ansible sets the mode to the wrong value.

-Toshio