Lately I’ve been tidying up my Ansible playbook scripts ahead of a forthcoming project deployment. Lots of change, including upgrading to PHP7 across the board.
Pretty cool, and exciting, but quite a lot of work all the same.
I decided to take the opportunity to restructure my log files. I mean, that’s a good way to spend a Friday night, right? Of course it is.
The relevant part of the nginx playbook is:
- name: "create access log file" file: dest="/var/log/nginx/{{ item.directory }}-access.log" mode=644 state=file owner="{{ nginx_user }}" group="{{ nginx_group }}" with_items: "{{ website_directories }}"
It’s admittedly been a while since I’ve been regularly hands-on with my Ansible setup, so I was a little rusty. See if you can spot the error in the above.
The with_items section lives in my host_vars/my-symfony-3.dev file, and looks like:
website_directories: - { name: "Root", directory: "{{ website_domain_name }}" } - { name: "API", directory: "api.{{ website_domain_name }}" }
So, anyway the error that was being spat out was as follows:
TASK [create access log file] ************************************************** failed: [my-symfony-3.dev] (item={u'stat': {u'exists': False}, '_ansible_item_result': True, '_ansible_no_log': False, u'changed': False, 'item': {u'directory': u'my-symfony-3.dev', u'name': u'Root'}, 'invocation': {'module_name': u'stat', u'module_args': {u'checksum_algorithm': u'sha1', u'mime': False, u'get_checksum': True, u'path': u'/var/www/my-symfony-3.dev', u'follow': False, u'get_md5': True}}}) => {"failed": true, "item": {"changed": false, "invocation": {"module_args": {"checksum_algorithm": "sha1", "follow": false, "get_checksum": true, "get_md5": true, "mime": false, "path": "/var/www/my-symfony-3.dev"}, "module_name": "stat"}, "item": {"directory": "my-symfony-3.dev", "name": "Root"}, "stat": {"exists": false}}, "msg": "file (/var/log/nginx/my-symfony-3.dev-access.log) is absent, cannot continue", "path": "/var/log/nginx/my-symfony-3.dev-access.log", "state": "absent"} failed: [my-symfony-3.dev] (item={u'stat': {u'exists': False}, '_ansible_item_result': True, '_ansible_no_log': False, u'changed': False, 'item': {u'directory': u'api.my-symfony-3.dev', u'name': u'API'}, 'invocation': {'module_name': u'stat', u'module_args': {u'checksum_algorithm': u'sha1', u'mime': False, u'get_checksum': True, u'path': u'/var/www/api.my-symfony-3.dev', u'follow': False, u'get_md5': True}}}) => {"failed": true, "item": {"changed": false, "invocation": {"module_args": {"checksum_algorithm": "sha1", "follow": false, "get_checksum": true, "get_md5": true, "mime": false, "path": "/var/www/api.my-symfony-3.dev"}, "module_name": "stat"}, "item": {"directory": "api.my-symfony-3.dev", "name": "API"}, "stat": {"exists": false}}, "msg": "file (/var/log/nginx/api.my-symfony-3.dev-access.log) is absent, cannot continue", "path": "/var/log/nginx/api.my-symfony-3.dev-access.log", "state": "absent"}
Hopefully it make it easier to Google for this for someone in the future.
Anyway, the solution will make you kick yourself. I can’t imagine that many people will make this typo, but you never know:
- name: "create access log file" file: dest="/var/log/nginx/{{ item.directory }}-access.log" mode=644 state=touch owner="{{ nginx_user }}" group="{{ nginx_group }}" with_items: "{{ website_directories }}" - name: "create error log file" file: dest="/var/log/nginx/{{ item.directory }}-error.log" mode=644 state=touch owner="{{ nginx_user }}" group="{{ nginx_group }}" with_items: "{{ website_directories }}"
Yeah… d’oh. RTFM.
Though to be fair, I had RTFM, it was just a long time ago, and I guess I rely too heavily on IDE code completion. When it comes to Sublime + YAML, I am going to make mistakes 🙂
If this looks interesting to you, and you want to know more about Ansible, be sure to check out the tutorial series I did here at Code Review Videos.
It’s shameless self promotion, I know, but hey, it is free. And hopefully you find it useful.
Thank you dude, saved me hours.
Happy to help 🙂
WOW thank you!
I was unable to find any typos.
Might want to rephrase this as “setting the ‘state’ parameter to ‘file’ will generate a ‘file absent’ error if the file does not exist. Use ‘touch’ to create a file. Use ‘file’ to get status of an existing file.”
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/file_module.html
I agree with Richard O’Shea that it would be better to bluntly say: hey, “state: file” does not work, you just should use “state: touch” as state.
I don’t use Ansible anymore. Haven’t done in a long while now – no recent experience with it, so wouldn’t be surprised if this stuff is incorrect at this stage. It’s a 4 year old post and tech moves fast. Sorry if it’s misleading.
I ran into this issue today so yes it’s still relevant. It’s just hard to spot the difference in the two code examples you gave. It would help to highlight the “state: touch” change.