'How do I write Ansible task for 'systemctl set-default graphical.target' without shell/command modules

I want to write a task in Ansible to perform the following command:

"systemctl set-default graphical.target" without using shell/command modules.

not sure that the "ansible.builtin.systemd" module has this option.



Solution 1:[1]

When you execute systemctl set-default graphical.target you can see this log

Removed symlink /etc/systemd/system/default.target. 
Created symlink from /etc/systemd/system/default.target to /usr/lib/systemd/system/graphical.target.

Then you can use file module to create symlink as below

- name: Change default target
  hosts: all
  become: yes
  gather_facts: no

  tasks:
  - name: Change default target to graphical.target
    file:
      src: /usr/lib/systemd/system/graphical.target
      dest: /etc/systemd/system/default.target
      state: link

Solution 2:[2]

@njh I just spotted this when looking for something else. /lib/systemd contains the systemd files installed with APT, etc., local overrides are in /etc/systemd, which includes the default target, so if you want to change the default target, change the symlink as @gary-lopez suggests.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat Oct 23 20:00:36 2021 from 192.168.1.10
pi@penguin:~ $ ls -l /etc/systemd/system/default.target 
lrwxrwxrwx 1 root root 36 Feb 13  2020 /etc/systemd/system/default.target -> /lib/systemd/system/graphical.target
pi@penguin:~ $ ls -l /lib/systemd/system/default.target
lrwxrwxrwx 1 root root 16 Aug  6 17:38 /lib/systemd/system/default.target -> graphical.target
pi@penguin:~ $ 

Solution 3:[3]

You can use the command module and use some when magic magic to have an idempotent solution for your problem. Actually there is no concrete module and the given change request for the systemd module was closed and is not merged.

- name: "Get current systemd default"
  command: "systemctl get-default"
  changed_when: false
  register: systemdefault

- name: "Set default to graphical target"
  command: "systemctl set-default graphical.target"
  when: "'graphical' not in systemdefault.stdout"

Of course this uses command. But there is no bad reason to not use command when you know, when you need to use it. It doesn't look nice - ok. But at the end a custom module would also do the same under the hood and it could be a little bit to complex for such a "single" problem. Actually the "link" solution does the same, but its necessary to explicitly know the location of the link files (see Debian).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 gary lopez
Solution 2 tsgsh
Solution 3