// learn Β· linux Β· rhce Β· 10 min

Ansible core modules.

Modules are the verbs that do Ansible's real work β€” and they're idempotent. Instead of running commands, you declare a desired state (`state: present`, `enabled: true`) and the module figures out whether to act. Walk through file/copy/template, user/group, dnf/package, and service/systemd.

Ansible core modules animated tutorial. The idempotent desired-state model, file copy lineinfile and template for files, user and group for accounts, dnf and package for software, service and systemd for daemons, and reading ansible-doc to find any module's arguments, return values, and examples offline. RHCE EX294 ready.
// ansible Β· core modules

Modules are the verbs that do Ansible's real work β€” and they're idempotent. Watch a file, a user, a package, and a service each get brought to a declared state by the module that manages it.

// before you start
you should know
  • Β·The Ansible control node + inventory model
  • Β·Basic YAML (tasks are YAML mappings)
  • Β·Comfortable with Linux files, users, packages, services
by the end you'll

Reach for the right core module for files, accounts, software, and services β€” file/copy/template, user/group, dnf/package, service/systemd β€” declaring desired state instead of running commands, and read ansible-doc to find any module's args.

pace: 10 minutes

ansible β€” step 1 / 6 Β· the idea
🧩 managed resourcesdeclare state β†’ module converges β†’
πŸ“„ /etc/motd● ok
missing→present
πŸ‘€ deploy● ok
absent→present
πŸ“¦ httpd● ok
not installed→installed
πŸ”Œ firewalld● ok
stopped→running

Modules are the verbs β€” and they're idempotent

A module is a self-contained unit of work that brings ONE kind of resource to a declared state. Instead of running a command, you set `state:` and let Ansible check the resource first and act only if it isn't already there. That's idempotency: the same task is safe to run a hundred times. Always reach for the fully-qualified name β€” ansible.builtin.MODULE (FQCN) β€” so there's no ambiguity about which collection a module comes from.

$ansible-doc -l
$ansible-doc ansible.builtin.file
$ansible-doc -s copy
// key insight

With modules you declare the desired STATE (state: present, enabled: true) and Ansible figures out whether to act. That's why the same task is safe to run a hundred times β€” and why command/shell should be your last resort, not your first.

// exam-ready Β· core modules & ansible-doc
$ansible.builtin.file
$ansible.builtin.copy
$ansible.builtin.lineinfile
$ansible.builtin.blockinfile
$ansible.builtin.template
$ansible.builtin.user
$ansible.builtin.group
$ansible.builtin.dnf
$ansible.builtin.package
$ansible.builtin.service
$ansible.builtin.systemd
$ansible-doc -l
$ansible-doc MODULE
$ansible-doc -s MODULE
// check yourself
4 quick questions
Q1

Which is the idempotent way to ensure httpd is installed?

Q2

What's the difference between state=present and state=latest for a package?

Q3

On the exam, with no internet, how do you discover a module's arguments and examples?

Q4

You set a user's password with the `user` module by passing the plaintext, but login fails. Why?

These aren't graded β€” they're just for active recall, which is what actually makes the lesson stick.

πŸ”’
// next: data

Ansible variables & facts

Modules need values β€” where do they come from? Play vars, group_vars/host_vars, the command line, and the facts Ansible gathers automatically from every managed node.

open β†’

Read this lesson as text6 chapters Β· quiz answers

  1. 01Modules are the verbs β€” and they're idempotent

    A module is a self-contained unit of work that brings ONE kind of resource to a declared state. Instead of running a command, you set state: and let Ansible check the resource first and act only if it isn't already there. That's idempotency: the same task is safe to run a hundred times. Always reach for the fully-qualified name β€” ansible.builtin.MODULE (FQCN) β€” so there's no ambiguity about which collection a module comes from.

    • $ ansible-doc -l β€” list every module available
    • $ ansible-doc ansible.builtin.file β€” read a module's full docs
    • $ ansible-doc -s copy β€” snippet of a module's args
  2. 02file & copy & template

    file manages a path's state β€” directory, touch, absent, link β€” plus owner, group, and mode. copy pushes a local file (or inline content:) to a dest on the target. lineinfile ensures a single line exists (or is replaced via regexp). template renders a Jinja2 .j2 file with your variables before placing it β€” that's a lesson of its own.

    • $ - ansible.builtin.file:\n path: /opt/app\n state: directory\n mode: "0755" β€” make a directory with a mode
    • $ - ansible.builtin.copy:\n src: motd\n dest: /etc/motd\n owner: root\n mode: "0644" β€” push a file to the target
    • $ - ansible.builtin.lineinfile:\n path: /etc/selinux/config\n regexp: "^SELINUX="\n line: SELINUX=enforcing β€” ensure one line
  3. 03user & group

    user creates and removes accounts: name, uid, groups, append=true (add to groups without dropping the rest), shell, home, and password β€” which must be a HASH, never plaintext. Set state=absent to remove the account. group manages groups the same way, with name and gid. Pair both with become for root.

    • $ - ansible.builtin.group:\n name: web\n gid: 1500 β€” ensure a group exists
    • $ - ansible.builtin.user:\n name: deploy\n groups: wheel\n append: true β€” add user to a group, keep others
    • $ - ansible.builtin.user:\n name: olduser\n state: absent\n remove: true β€” remove the account + home
  4. 04package: dnf / package

    dnf (or yum) installs, removes, and updates RPMs: name takes a single package or a list, and state is present, latest, or absent. package is the distro-agnostic wrapper that picks the right manager for you. Software changes need root, so pair these with -b / become.

    • $ - ansible.builtin.dnf:\n name:\n - httpd\n - mod_ssl\n state: present β€” install a list of packages
    • $ - ansible.builtin.dnf:\n name: httpd\n state: latest β€” upgrade to the newest version
    • $ - ansible.builtin.package:\n name: tmux\n state: present β€” distro-agnostic wrapper
  5. 05service / systemd

    service and systemd control daemons: name, state (started, stopped, restarted, reloaded), and enabled=true to start it at boot. started + enabled is the common pairing β€” running now AND after a reboot. Use the systemd module when you need daemon_reload after dropping in a new unit file.

    • $ - ansible.builtin.service:\n name: firewalld\n state: started\n enabled: true β€” run now + at boot
    • $ - ansible.builtin.systemd:\n name: myapp\n daemon_reload: true\n state: started β€” reload units, then start
    • $ - ansible.builtin.service:\n name: httpd\n state: restarted β€” bounce a service
  6. 06Find & trust modules

    ansible-doc MODULE shows the arguments, return values, and runnable EXAMPLES for any module β€” offline, on the exam. Many modules support check_mode for a dry run, and you can register a task's output to inspect what it returned. Prefer real modules over command/shell, because command and shell aren't idempotent and report changed every single time.

    • $ ansible-doc -s ansible.builtin.service β€” args snippet for service
    • $ ansible-doc -l | grep -i user β€” find modules by keyword
    • $ register: result # then debug var=result β€” inspect a module's return

Quiz β€” answers

Which is the idempotent way to ensure httpd is installed?
β†’ansible.builtin.dnf with name=httpd and state=presentThe dnf module checks whether httpd is already installed and only acts if it isn't β€” safe to run repeatedly. Wrapping dnf install in command/shell runs unconditionally and reports changed every time.
What's the difference between state=present and state=latest for a package?
β†’present installs it only if missing and leaves the version alone; latest upgrades it to the newest available.state=present means "make sure it's installed" without touching the version of an already-installed package. state=latest means "install it, and upgrade it to the newest available version."
On the exam, with no internet, how do you discover a module's arguments and examples?
β†’Run ansible-doc MODULE β€” it ships with the args, return values, and examples offline.ansible-doc MODULE works entirely offline and is the canonical exam reference: it lists every argument, the return values, and copy-paste EXAMPLES.
You set a user's password with the user module by passing the plaintext, but login fails. Why?
β†’The password field expects a pre-hashed value, not plaintext β€” pass a hash, e.g. via the password_hash filter.The user module writes the password straight into /etc/shadow, which stores a HASH. Feed it plaintext and the stored "hash" never matches a real login. Generate one with the password_hash filter (e.g. mypw | password_hash('sha512')).
// more in systems

keep going β€” these pair well with what you just learned.

see all systems β†’

See also

back to RHCSA / RHCE trackall lessons