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.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.
- Β·The Ansible control node + inventory model
- Β·Basic YAML (tasks are YAML mappings)
- Β·Comfortable with Linux files, users, packages, services
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
π§© managed resourcesdeclare state β module converges βπ /etc/motdβ okπ€ deployβ okπ¦ httpdβ okπ firewalldβ okModules 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 copyWith 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.
$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 MODULEWhich is the idempotent way to ensure httpd is installed?
What's the difference between state=present and state=latest for a package?
On the exam, with no internet, how do you discover a module's arguments and examples?
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.
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.
Read this lesson as text6 chapters Β· quiz answers
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
02file & copy & template
filemanages a path's state β directory, touch, absent, link β plus owner, group, and mode.copypushes a local file (or inline content:) to a dest on the target.lineinfileensures a single line exists (or is replaced via regexp).templaterenders 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
03user & group
usercreates 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.groupmanages 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
04package: dnf / package
dnf(oryum) installs, removes, and updates RPMs: name takes a single package or a list, and state is present, latest, or absent.packageis 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
05service / systemd
serviceandsystemdcontrol 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 thesystemdmodule 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
06Find & trust modules
ansible-doc MODULEshows 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
dnfmodule checks whether httpd is already installed and only acts if it isn't β safe to run repeatedly. Wrappingdnf installin 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 MODULEworks 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
usermodule 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
usermodule 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')).
keep going β these pair well with what you just learned.
Ansible control node & inventory
Ansible is agentless β one control node pushes work to a fleet over SSH. Install ansible-core, write an inventory with groups, ping the fleet, and fire ad-hoc commands. RHCE-ready.
Ansible playbooks & YAML
Plays, tasks, and idempotency. Watch a playbook run task-by-task β ok, changed, skipped β then run it again and watch everything go green with 0 changed. RHCE-ready.
Ansible variables & facts
Which value wins when the same variable is set in five places? Variable precedence, gathered facts, and ansible_facts β visualized as a ladder. RHCE-ready.