Ansible ubuntu locale & keyboard-configuration

[I can’t believe my questions haven’t been asked here previously, am I using search properly?]

OK, so my current challenge is to configure my Ubuntu 22 boxes for GB keyboard & locale [en_GB.UTF-8].

This is my code:-

   - name: Update and upgrade apt packages
     become: true
     apt:
       update_cache: yes
       upgrade: 'yes'
     when: ansible_distribution == 'Ubuntu'

   - name: Apply localectl settings to Ubuntu
     community.general.locale_gen:
       name: en_GB.UTF8
       state: present
     when: ansible_distribution == 'Ubuntu'

   - name: set as default locale
     command: localectl set-locale LANG=en_GB.UTF-8 LC_ALL=en_GB.UTF-8
     when: ansible_distribution == 'Ubuntu'

These are the errors encountered:-

fatal: [hostname]: FAILED! => {“changed”: false, “msg”: “The locale you’ve entered is not available on your system.”}

and

fatal: [hostname]: FAILED! => {“changed”: true, “cmd”: [“localectl”, “set-locale”, “LANG=en_GB.UTF-8”, “LC_ALL=en_GB.UTF-8”], “delta”: “0:00:00.125000”, “end”: “2023-09-15 09:58:17.548654”, “msg”: “non-zero return code”, “rc”: 1, “start”: “2023-09-15 09:58:17.423654”, “stderr”: “Failed to issue method call: Locale assignment LC_ALL=en_GB.UTF-8 not valid, refusing.”, “stderr_lines”: [“Failed to issue method call: Locale assignment LC_ALL=en_GB.UTF-8 not valid, refusing.”], “stdout”: “”, “stdout_lines”: }

[My script works for RedHat by following the following guidance:-

though that only applies to RHEL and clones.]

2 Likes

We don’t (yet) have the archives from the mailing-lists available to search over, so you’re working with a very fresh support site (it’s only been live for a week!). We’ll be able to fix that in the future, but for now search is not going to return much, indeed. Thanks for asking, it means the next person will find it in search :slight_smile:

3 Likes

I’ve a role that does this for Debian, I’ve not tested it on Ubuntu but next time I do any work on it I’ll update the GitLab CI to run it using Molecule on several Debian versions and Ubuntu, it might work without adjustments!

2 Likes

Hey @Nesbit7

Your playbook should work if you remove the LC_ALL=en_GB.UTF-8 from the last task, this is not actually related to Ansible itself, LC_ALL is not supported in the locale.conf file. Try:

   - name: set as default locale
     command: localectl set-locale LANG=en_GB.UTF-8
     when: ansible_distribution == 'Ubuntu'

Using a role as stated above if you intend to do more complex set-ups is also a good idea!

You could use /etc/profile or the .bashrc file for LC_ALL.

2 Likes

If the locales package is not already present on the machine try adding the following after updating and upgrading apt packages:

- name: Debconf set default locale
  ansible.builtin.debconf:
    name: locales 
    question: locales/default_environment_locale
    value: en_GB.UTF-8
    vtype: select

- name: Locales package present 
  ansible.builtin.apt:
    pkg:
      - locales

This will ensure that en_GB.UTF-8 is available on your system before you try to set it as the default locale.

2 Likes

Hi Leo & Chris,

thanks for your help thus far, I’m not sure about the ansible ‘role’ method, it’s currently a stretch too far for my ansible experience, I have not tackled ‘roles’ yet, though I’m sure in time I may be able to incorporate it.

I don’t like using ‘command’, as it kind of is obviating the use of ansible modules, but as it works, I’ll run with the proposed solution for the time being and I’ve confirmed the following works for my current config:-

   - name: Debconf set default locale Ubuntu
     ansible.builtin.debconf:
       name: locales
       question: locales/default_environment_locale
       value: en_GB.UTF-8
       vtype: select
     when: ansible_distribution == 'Ubuntu'

   - name: Locales package present Ubuntu
     ansible.builtin.apt:
       pkg:
         - locales
     when: ansible_distribution == 'Ubuntu'

   - name: set as default locale Ubuntu
     command: localectl set-locale LANG=en_GB.UTF-8
     when: ansible_distribution == 'Ubuntu'

   - name: set as default x11-keymap Ubuntu
     command: localectl --no-convert set-x11-keymap gb
     when: ansible_distribution == 'Ubuntu'

   - name: create vconsole.conf for VC Keymap Ubuntu
     ansible.builtin.copy:
       dest: /etc/vconsole.conf
       content: |
         KEYMAP=gb
     when: ansible_distribution == 'Ubuntu'

These settings now result in the desired outputs:-

localectl
   System Locale: LANG=en_GB.UTF-8
       VC Keymap: gb
      X11 Layout: gb

The VC Keymap eluded me for a while until I found a solution;
the way I was configuring those settings manually was with the command: dpkg-reconfigure …

Once again, I’ve marked your contributions as Solutions to my question, thanks for your help.

3 Likes

Ah, spoke too soon,
my code isn’t idempotent.

I see yours is by use of the ‘question:’

So my next question is how do you find what ‘question’ to ask?

‘locales/default_environment_locale’ isn’t listed in the ansible_facts, so how do I know what question to ask to prevent my changes happening again ?

thanks,

You can get the questions via the command line:

debconf-show locales
  locales/locales_to_be_generated: en_GB.UTF-8 UTF-8
* locales/default_environment_locale: en_GB.UTF-8

So try something like this with locale_lang set to en_GB.UTF-8:

- name: Get existing debconf values for locales 
  ansible.builtin.debconf:
    name: locales 
  register: locale_dcnf

- name: Set a variable for the current locales
  ansible.builtin.set_fact:
    locale_dcnf_locale: "{{ locale_dcnf | community.general.json_query(locale_dcnf_jpq) }}"
  vars:
    locale_dcnf_jpq: 'current.["locales/default_environment_locale"]|[0]'
  
- name: Debug existing debconf value for locales/default_environment_locale
  ansible.builtin.debug:
    var: locale_dcnf_locale
  
- name: Debconf set default locale
  ansible.builtin.debconf:
    name: locales 
    question: locales/default_environment_locale
    value: "{{ locale_lang }}"
    vtype: select
  when: locale_dcnf_locale != locale_lang
1 Like

sorry may I appear to have gone ‘cold’ on this, but I’m currently off work sick.
I’ll run with it when I’m back at work in hopefully a couple of weeks.

2 Likes

update on that and to keep this ticket ‘live’, I’m not likely to return to work until next month now.

1 Like

Thanks @Nesbit7 I’ve removed the topic timer so you don’t have to “ping” it. Get well soon!

Hi,

pleased to say I’m back at work [have been for a couple of months, but with the backlog of work not had a chance to revisit ansible until now.]

I have attempted Chris’s solution, but unfortunately get the following error, but I’m unfamiliar with the constructs used, I’ve tried to get my head round them, but thought I’d paste the error here just i case someone rolls their eyes and goes, “yeah that’s because…!”:-

fatal: [ansiblemasterhost]: FAILED! => {“msg”: “The conditional check ‘locale_dcnf_locale != locale_lang and ansible_distribution == ‘Ubuntu’ and ansible_distribution_version == ‘22.04’’ failed. The error was: error while evaluating conditional (locale_dcnf_locale != locale_lang and ansible_distribution == ‘Ubuntu’ and ansible_distribution_version == ‘22.04’): ‘locale_lang’ is undefined. ‘locale_lang’ is undefined\n\nThe error appears to be in ‘/home/sisroot/ansible/ansiblescript.yml’: line 270, column 6, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: Debconf set default locale Ubuntu 22\n ^ here\n”}

Here’s the relevant excerpt from my script:-

   - name: Get existing debconf values for locales Ubuntu 22
     ansible.builtin.debconf:
       name: locales
     register: locale_dcnf

   - name: Set a variable for the current locales Ubuntu 22
     ansible.builtin.set_fact:
       locale_dcnf_locale: "{{ locale_dcnf | community.general.json_query(locale_dcnf_jpq) }}"
     vars:
       locale_dcnf_jpq: 'current.["locales/default_environment_locale"]|[0]'
     when: ansible_distribution == 'Ubuntu' and ansible_distribution_version == '22.04'

   - name: Debug existing debconf value for locales/default_environment_locale Ubuntu 22
     ansible.builtin.debug:
       var: locale_dcnf_locale
     when: ansible_distribution == 'Ubuntu' and ansible_distribution_version == '22.04'

   - name: Debconf set default locale Ubuntu 22
     ansible.builtin.debconf:
       name: locales
       question: locales/default_environment_locale
       value: "{{ locale_lang }}"
       vtype: select
     when: locale_dcnf_locale != locale_lang and ansible_distribution == 'Ubuntu' and ansible_distribution_version == '22.04'

:point_up: Try setting locale_lang or hard code it and then run the tasks?

Hi Chris,

thanks, that worked a treat.

When I was looking at the code, I couldn’t see where the variable was set, and that was the crux of my issue, it wasn’t set.

I’ve now learned how to define ansible variables, so that’s another day at school for me this week, testing complete on this.

happy for closure of this request now I’m sorted.

thanks very much for everyone’s guidance.

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.