How to override child element of default paramter in ansible? - ansible

I have following parameter set in role/downloader/defaults/main.yml
download:
location: "/tmp/download"
file: "EXAMPLE.tar.gz"
url: "http://<url>/repo//"
file_permission: '755'
checksum: md5:e207d015e0a435193afbc82e15bba19c
force_download: False
And in another role I tried to override few parameter like below
meta/main.yml
---
dependencies:
- role: downloader
vars:
download:
file: LINUX_X86-64.tar.gz
location: "/tmp/download"
But it resulted in disctionary value undefined error. Is there any way to handle this?

I believe you're interested in default_hash_behavior setting, see https://docs.ansible.com/ansible/latest/reference_appendices/config.html#default-hash-behaviour.
I can't help with an example as I haven't used before.
However, I have seen recommendations for keeping variables separated basically for this reason.
For example, instead of defining the variable as a hash,
download:
location: "/tmp/download"
file: "EXAMPLE.tar.gz"
it may be simpler to make each a unique variable.
download_location: "/tmp/download"
download_file: "EXAMPLE.tar.gz"
Hope that helps!
EDIT: As suggested from the link at the top of my post, perhaps the combine filter could also solve this for you: https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#combining-hashes-dictionaries

Related

Determine return type for object returned from a task

I have a playbook which should retrieve atrifacts from maven repo, extract them to temp dir and copy some file to destinatiom folder. Currently it works pretty fine - artifacts are downloaded using maven_artifact task. But some requirements have changed and I need to use get_url task now. After changing to get_url the whole rest of the playbook is broken because object returned from maven_artifact and get_url are of different types. How to determine what type with what fields is getting returned from a task?
Best regards
No matter which ansible module you use there is the option to create variables from the output of the task by using register.
The ansible documentation states which return values are available to you when doing so. Here for example are the return values for the get_url module: https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html
In that case you may do something like the following to retrieve the status code of the get_url module:
- name: Download foo.conf
get_url:
url: http://example.com/path/file.conf
dest: /etc/foo.conf
mode: '0440'
register: my_result
- name: Print status code of get_url
debug:
var: my_result.status_code
Each module returns an object of a different type.
There Is no way within Ansible to identify the type of a registered variable (i.e. what attributes you can read from it) however, a module will always return an object of the same type.
The return values of a module are listed at the bottom of that modules documentation page.

Ansible - Could not find imported module support code for 'Ansible.ModuleUtils.PrivilegeUtil'

I'm for some reason unable to create registry keys using the win_regedit module.
The weird thing is that it has previously worked but now I'm stuck with the following error message:
{"msg": "Could not find imported module support code for 'Ansible.ModuleUtils.PrivilegeUtil'."}
Currently running ansible-playbook 2.4.3.0.
I've tried to locate the module named 'ModuleUtils.PrivilegeUtil' with no luck.
Playbook
- name: Add or update registry path, with entry 'ForceAutoLogon'
win_regedit:
path: HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
name: ForceAutoLogon
data: 0
type: string
I'm quite new to Ansible I might add, is there something obvious that I'm missing?
Best regards
Issue resolved after updating ansible.

Are there any vars that Ansible can merge?

Today I noticed that Ansible won't merge vars.
For example when I have something like
---
lvm_roles:
postgresql:
size: '10g'
path: '/var/lib/postgresql'
And in another place I have for example
---
lvm_roles:
sonarqube:
size: '10g'
path: '/opt/sonarqube'
Ansible won't merge these facts. I am not sure about precedence but I think the first one wins. Without errors or warnings. IMHO a dangerous feature for a configuration management tool.
Are there any vars that Ansible can merge? Lists and hash won't work. Is there a workaround of some sort for this?
This is a significant shortcoming of Ansible. Because "facts" can be dependent on what you are provisioning. The inability to merge "facts" make it necessary to hard code and duplicate the stuff that you wan't to be configurable.
For example when I create one file with
lvm_roles:
postgresql:
size: '10g'
path: '{{ postgresql_home }}'
sonarqube:
size: '10g'
path: '{{ sonar_home }}'
This will not work because sonar_home is not defined on de postgresql node. On the the sonarqube node, postgresql_home is not defined. The ability to flexibly use vars is greatly impacted if merging is not possible.
Extract of a default ansible.cfg file:
# if inventory variables overlap, does the higher precedence one win
# or are hash values merged together? The default is 'replace' but
# this can also be set to 'merge'.
#hash_behaviour = replace
You can therefore change this behavior by setting hash_behaviour = merge.
I would not change that on a system wide basis as it might break other projects/roles that would rely on a default behavior. You can distribute the ansible.cfg at the root of your specific project that really needs this.
Meanwhile, as #dgw pointed out with a specific example, I've always been able to keep the default behavior by carefully choosing where to place my variables (group or host in inventory, included file, playbook...) and eventually merge them myself if needed.

Have ansible role retrieve its files from external location as part of its own role

So one thing we've encountered in our project is that we do not want to store our large files in our git repo for our ansible roles because it slows down cloning (and git limits files to 100 mb anyways).
What we've done is store our files in a separate internal location, where our files can sit statically and have no size restrictions. Our roles are written so that they first pull these static files to their local files folder and then continue like normal.
i.e.
roles/foo/tasks/main.yml
- name: Create role's files directory
file:
path: "{{roles_files_directory}}"
state: directory
- name: Copy static foo to local
get_url:
url: "{{foo_static_gz}}"
dest: "{{roles_files_directory}}/{{foo_gz}}"
#....Do rest of the tasks...
roles/foo/vars/main.yml
roles_files_directory: "/some/path/roles/foo/files"
foo_static_gz: "https://internal.foo.tar.gz"
foo_gz: "foo.tar.gz"
The main thing I don't find really sound is the hard coded path to the role's files directory. I preferably would like to dynamically look up the path when running ansible, but I haven't been able to find documentation on that. The issue can arise because different users may check roles to a different root paths. Does anyone know how to dynamically know the role path, or have some other pattern that solves the overall problem?
Edit:
I discovered there's actually a {{playbook_dir}} variable that would return "/some/path", which might be dynamic enough in this case. Still isn't safe against the situation where the role name might change, but that's a way rarer occurrence and can be handled through version control.
What about passing values from the command line?
---
- hosts: '{{ hosts }}'
remote_user: '{{ user }}'
tasks:
- ...
ansible-playbook release.yml --extra-vars "hosts=vipers user=starbuck"
http://docs.ansible.com/playbooks_variables.html#passing-variables-on-the-command-line
I just want to add another possible solution: you can try to add custom "facter".
Here is a link to official documentation: http://docs.ansible.com/setup_module.html
And I found this article that might be useful: http://serverascode.com/2015/01/27/ansible-custom-facts.html

How do I setup the Date URLs Plugin for DocPad?

I've recently converted from Octopress to Docpad and couldn't be happier. I like everything, but one thing bothers me. At the moment all paths on my site are built directly from the filename, e.g. www.site.com/posts/yyyy-mm-dd-title/. What I want to get is www.site.com/posts/yyyy/title. I found the Date URLs plugin, but cannot understand how to set it up. I tried inserting the relevant part into docpad.coffee as follows:
docpadConfig =
plugins:
dateurls:
cleanurl: true
trailingSlashes: true
collectionName: 'posts'
dateFormat: '/YYYY'
templateData:
site:
But nothing seems to change. The collection is defined as follows:
posts: ->
#getCollection("html").findAllLive({relativeOutDirPath:'blog'},[date:-1]).on "add", (model) ->
model.setMetaDefaults({layout:"post"})
--
EDIT (in response to Lukasz Gornicki)
A sample of metadata from the blog folder:
---
title: "Les Sapeurs"
date: 2014-09-25 07:39
comments: false
language: english
tags: video
keywords: anton zujev, antzoo, zujev, sapeurs, style, congo
description: Les Sapeurs are fashionistas from Congo, whose style is a political and social outcry.
---
A sample of metadata from the cast folder:
---
title: "Utan 7"
date: 2015-02-27 06:52
podfeed: utan
comments: true
---
I didn't try the debug mode before. Now I did, but I don't see anything special in the log. Here's the log file.
I've installed the plugin on my blog to check it out. I think there is a bug in documentation or it is just supper misleading. Documentation doesn't explicitly say that the url is build against the date metadata with dateFormat configuration and file basename without the date. I copied your configuration use it agains my blog with post 2015-02-16-test-test.html.md with metadata: date: 2014-09-25 9:49.
result url: http://localhost:9778/2014/test-test/
So the plugin works. Do you think that docpad doesn't pick up any configuration for the plugin? If you are configuring docpad with docpad.coffee I suggest you to validate the file, if it is created according to coffeescript rules and you have right indentation. Some time ago I had a situation that my config file grew a lot and some of the config was not picked up because of indentation.
Or just give access to the project so I can see and tell you what is wrong.
MORE DETAILS TO THE ANSWER AFTER CHECKING THE PROJECT:
Filename can have a date. The plugin uses regex to take just the string out of the filename - basename.
Locally I've commented out your hook into the renderBefore event, installed the plugin, added your config and all works as expected if it comes to the urls. So I get a URL like /2014/movie-quotes/
On the other hand it works when the server is started, but when I look on the out dir and try to generate the static content, it looks like the plugin doesn't work. Is this what you mean when saying that plugin doesn't work?

Resources