Permissions when adding a custom cron job on deploy (permission denied)

Howdy everyone,

I created a bash script which I want to run at a certain interval and I’ve used some pointers from here, here, and here but I end up with permissions issues either way I attempt this.

I first add my bash script to my project in a new dir, sites/scripts/.

Then in one of my deploy hooks, build-after.yml, I added this:

- name: Setup cron to update GeoIP.dat
  cron:
    name: "{{ item.key }} site cron"
    hour: "*"
    minute: "*/2"
    user: "{{ web_user }}"
    job: "cd {{ www_root }}/{{ item.key }}/{{ item.value.current_path | default('current') }}/scripts && chmod +x geoip_update.sh && ./geoip_update.sh"
    cron_file: "custom-{{ item.key | replace('.', '_') }}"
  with_dict: "{{ wordpress_sites }}"

My deploy fails with this output:

TASK [deploy : Setup cron to update GeoIP.dat] *********************************
task path: /Users/cfx/Sites/mysite/trellis/deploy-hooks/build-after.yml:26
Using module file /usr/local/lib/python2.7/site-packages/ansible/modules/core/system/cron.py
<67.205.170.35> ESTABLISH SSH CONNECTION FOR USER: web
<67.205.170.35> SSH: EXEC ssh -o ForwardAgent=yes -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=web -o ConnectTimeout=10 -o ControlPath=/Users/cfx/.ansible/cp/ansible-ssh-%h-%p-%r 67.205.170.35 '/bin/sh -c '"'"'/usr/bin/python && sleep 0'"'"''
System info:
  Ansible 2.2.0.0; Darwin
  Trellis at "Add `SKIP_GALAXY` env var to skip galaxy install in Vagrant"
---------------------------------------------------
MODULE FAILURE
Traceback (most recent call last):
  File "/tmp/ansible_mvwt0q/ansible_module_cron.py", line 703, in <module>
    main()
  File "/tmp/ansible_mvwt0q/ansible_module_cron.py", line 671, in main
    crontab.write()
  File "/tmp/ansible_mvwt0q/ansible_module_cron.py", line 281, in write
    fileh = open(self.cron_file, 'w')
IOError: [Errno 13] Permission denied: '/etc/cron.d/custom-mysite'

An exception occurred during task execution. The full traceback is:
Traceback (most recent call last):
  File "/tmp/ansible_mvwt0q/ansible_module_cron.py", line 703, in <module>
    main()
  File "/tmp/ansible_mvwt0q/ansible_module_cron.py", line 671, in main
    crontab.write()
  File "/tmp/ansible_mvwt0q/ansible_module_cron.py", line 281, in write
    fileh = open(self.cron_file, 'w')
IOError: [Errno 13] Permission denied: '/etc/cron.d/custom-mysite'

failed: [67.205.170.35] (item={'key': u'mysite', 'value': {u'repo_subtree_path': u'site', u'multisite': {u'enabled': False}, u'cache': {u'duration': u'30s', u'skip_cache_cookie': u'comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in', u'skip_cache_uri': u'/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml/store.*|/cart.*|/my-account.*|/checkout.*|/addons.*|/product.*|/payments.*', u'enabled': True}, u'repo': u'git@bitbucket.org:silber/mysite.git', u'ssl': {u'enabled': True, u'provider': u'letsencrypt'}, u'local_path': u'../site', u'branch': u'master', u'site_hosts': [{u'redirects': [u'www.mysite.com'], u'canonical': u'mysite.com'}]}}) => {
    "failed": true,
    "invocation": {
        "module_name": "cron"
    },
    "item": {
        "key": "mysite",
        "value": {
            "branch": "master",
            "cache": {
                "duration": "30s",
                "enabled": true,
                "skip_cache_cookie": "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in",
                "skip_cache_uri": "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml/store.*|/cart.*|/my-account.*|/checkout.*|/addons.*|/product.*|/payments.*"
            },
            "local_path": "../site",
            "multisite": {
                "enabled": false
            },
            "repo": "",
            "repo_subtree_path": "site",
            "site_hosts": [
                {
                    "canonical": "mysite.com",
                    "redirects": [
                        "www.mysite.com"
                    ]
                }
            ],
            "ssl": {
                "enabled": true,
                "provider": "letsencrypt"
            }
        }
    },
    "module_stdout": ""
}

If I remove this line from my playbook:

cron_file: "custom-{{ item.key | replace('.', '_') }}"

then the deploy succeeds, but the cron job fails and dispatches an email, which reads:

Subject: Cron <web@jamiesrescue> cd /srv/www/jamies/current/scripts && chmod +x geoip_update.sh && ./geoip_update.sh
cp: cannot create regular file '/usr/share/GeoIP/GeoIP.dat.bak.2017-05-26_15:26': Permission denied
cp: cannot create regular file '/usr/share/GeoIP/GeoIPv6.dat.bak.2017-05-26_15:26': Permission denied
./geoip_update.sh: line 12: /usr/share/GeoIP/GeoIP.dat: Permission denied

This is the bash script I want to run (it keeps GeoIP.dat updated):

#!/bin/bash

DAT_DIR=/usr/share/GeoIP
DAT_URLS="http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz"

for FILE in $DAT_DIR/*.dat; do
    cp $FILE $FILE.bak.$(date +%F_%R)
done;

for URL in $DAT_URLS; do
    FILE=${URL##*/}
    curl $URL | gunzip > $DAT_DIR/${FILE%.gz}
    #echo $URL $DAT_DIR/${FILE%.gz}
done;

When I login to my server and I run grep -i CRON /var/log/syslog I see that the cron job appears to be run as the web user as specified in my playbook.

May 26 15:26:01 mysite CRON[25413]: (web) CMD (cd /srv/www/mysite/current/scripts && chmod +x geoip_update.sh && ./geoip_update.sh)

When I run the script manually as root it works just fine.

I’m unsure where to go and what to try from here.