Tamás Juhász
Tamás Juhász

Reputation: 699

Overwrite Property of Default Variable in Ansible

I'm trying to figure out if there is any way to overwrite a property of a variable declared in defaults by group_vars.
The exact issue is, that I automate the deployment of MySQL servers, and I created the default configuration options in the playbook's defaults as a list of key-value pairs, but sometimes some value needs to be changed, but not necessarily all.

I have the following YAML code in defaults/main/mysql_config.yml and this is parsed by a Jinja2 template into my.cnf file.:

performance_tuning:
  query_cache_type: 1
  query_cache_size: 512M
  query_cache_limit: 2M
  query_cache_strip_comments: 1
  thread_pool_size: "{{ ansible_processor_vcpus  }}"
  wait_timeout: 15
  interactive_timeout: 15
  max_connections: 151

And I would like to change one of these properties in the group_vars/all without repeating the whole code.

I tried the following, but seems it is not the way to do it, the template still uses the default value:

performance_tuning.query_cache_size: 128M

Also, if I add the performance_tuning variable to group_vars with that only one property, then it obviously deploys that only one property into the configuration file:

performance_tuning:
  query_cache_size: 128M

Jinja2 template:

{% if performance_tuning is defined and performance_tuning|length %}
{% for key, value in performance_tuning.items() %}
{{ key }}={{ value }}
{% endfor %}
{% endif %}

Upvotes: 1

Views: 1188

Answers (2)

Tamás Juhász
Tamás Juhász

Reputation: 699

Final solution based on @BinaryBulletin's suggestions:
defaults/mariadb_config.yml

default_performance_tuning:
  query_cache_type: 1
  query_cache_size: 128M
  query_cache_limit: 2M
  query_cache_strip_comments: 1
  thread_pool_size: "{{ ansible_processor_vcpus  }}"
  wait_timeout: 15
  interactive_timeout: 15
  max_connections: 151

group_vars/all

cluster_performance_tuning:
  query_cache_size: 64M

templates/my.cnf.j2

[mysqld]
{% for key, value in default_performance_tuning.items() %}
{% if cluster_performance_tuning is defined %}
{% if key in cluster_performance_tuning %}
{{ key }}={{ cluster_performance_tuning[key] }}
{% else %}
{{ key }}={{ value }}
{% endif %}
{% else %}
{{ key }}={{ value }}
{% endif %}
{% endfor %}

Template picks up the 'query_cache_size: 64M' from the cluster_performance_tuning variable properly.

Upvotes: 0

BinaryMonster
BinaryMonster

Reputation: 1218

Well you could do this several ways. Here are few of them.

1. Logic within Jinga template, this is very simple

{% for x in performance_tuning %}
{% if x == 'query_cache_size' and env == 'dev'%}
{{x}} : 128M
{% elif x == 'query_cache_size' and env == 'uat'%}
{{x}} : 256M
{% else %}
{{ x }} : {{performance_tuning[x]}}
{% endif %}
{% endfor %}

2. Through variables

Different variables for different clusters or different environments.

env: "dev"

query_cache_dev_size: "128M"
query_cache_uat_size: "256M"
query_cache_prod_size: "512M"


performance_tuning:
  query_cache_size: "{{ vars['query_cache_'+ env + '_size'] }}"
  ...
  ...

Something like this.

Like I said there are several other ways. Hope this helps.

Edited 3.Using group_vars

Like you said it only loads one configuration if we include the parent and child. But I found a way around it, maybe this helps.

Your normal vars file

performance_tuning:
  query_cache_type: 1
  query_cache_size: 512M
  query_cache_limit: 2M
  query_cache_strip_comments: 1
  thread_pool_size: "{{ ansible_processor_vcpus  }}"
  wait_timeout: 15
  interactive_timeout: 15
  max_connections: 151

Your group_vars/all

---
query_cache_size: "128M"

Your Jinga template should have a if condition to pick the normal query_cache_size from group_vars, something like this

{% for x in performance_tuning %}
{% if x == 'query_cache_size'%}
{{x}} : {{query_cache_size}}
{% else %}
{{ x }} : {{performance_tuning[x]}}
{% endif %}
{% endfor %}

So when the loop iterates, it keeps checking if the key is query_cache_size then it will pick the normal variable defined in group_vars which you might already know by looking at the template.

Hope this helps.

Edit(Improvised 3rd method)

Based on the comments, I can suggest something. Again it is hackie, not the concrete answer you might be looking for.

vars file


performance_tuning:
  query_cache_type: 1
  query_cache_size: 512M
  query_cache_limit: 2M
  query_cache_strip_comments: 1
  thread_pool_size: 10
  wait_timeout: 15
  interactive_timeout: 15
  max_connections: 151

group_vars


new_performance_tuning:
  query_cache_type: 10
  query_cache_size: 256M
  query_cache_limit: 12M

Jinga template


{% for x in performance_tuning %}
{% if x in new_performance_tuning %}
{{ x }} : {{ new_performance_tuning[x] }}
{% else %}
{{ x }} : {{performance_tuning[x]}}
{% endif %}
{% endfor %}

This is more logical if you don't want to use if condition for every variable you want to reuse.

Hope this helps. :)

Upvotes: 1

Related Questions