How to Generate and Set Locale Using Ansible

ansible

I am looking for an idempotent ansible role/task to ensure a certain locale (like en_US.UTF-8) is set as default. It should generate the locale (only if necessary) and set it as a default (also only if necessary).

For the first part I'd register the output of locale -a | grep "{{ locale_name }}" and generate if needed.

For the second part I'm wondering if running update-locale every time is good enough because that command itself is idempotent anyway.

Best Answer

The localectl command from @mniess answer will always report as "changed" even if the new values are the equal to the current ones. Here's what I personally ended up to set both LANG and LANGUAGE and solve that issue:

- name: Ensure localisation files for '{{ config_system_locale }}' are available
  locale_gen:
    name: "{{ config_system_locale }}"
    state: present

- name: Ensure localisation files for '{{ config_system_language }}' are available
  locale_gen:
    name: "{{ config_system_language }}"
    state: present

- name: Get current locale and language configuration
  command: localectl status
  register: locale_status
  changed_when: false

- name: Parse 'LANG' from current locale and language configuration
  set_fact:
    locale_lang: "{{ locale_status.stdout | regex_search('LANG=([^\n]+)', '\\1') | first }}"

- name: Parse 'LANGUAGE' from current locale and language configuration
  set_fact:
    locale_language: "{{ locale_status.stdout | regex_search('LANGUAGE=([^\n]+)', '\\1') | default([locale_lang], true) | first }}"

- name: Configure locale to '{{ config_system_locale }}' and language to '{{ config_system_language }}'
  become: yes
  command: localectl set-locale LANG={{ config_system_locale }} LANGUAGE={{ config_system_language }}
  changed_when: locale_lang != config_system_locale or locale_language != config_system_language

Also, this what I have at group_vars/main.yml:

config_system_locale: 'pt_PT.UTF-8'
config_system_language: 'en_US.UTF-8'