Stage 4 · Provision
Ansible Fundamentals
Modules & Idempotency
Why re-running is safe, changed vs ok, and check mode (--check).
What Are Modules?
Modules are discrete units of code that Ansible executes on managed nodes. Each module handles a specific task — installing a package, managing a file, configuring a service. Ansible has thousands of built-in modules and the community contributes more continuously.
# Using the package module to install nginx
- name: Install nginx
package:
name: nginx
state: present
# Using the service module to start it
- name: Start nginx
service:
name: nginx
state: started
enabled: yesEach task uses a module. The module name becomes the task key. The module parameters are specified as key-value pairs underneath.
Idempotency Explained
Idempotency means running the same task multiple times produces the same result. If nginx is already installed and running, running the playbook again does nothing — no changes, no errors, no side effects.
# NON-IDEMPOTENT — runs every time, regardless of state
- name: Install nginx (shell)
shell: apt-get install -y nginx
# IDEMPOTENT — checks state first, skips if already present
- name: Install nginx (module)
package:
name: nginx
state: presentThe shell command runs every time. The package module checks if nginx is installed first. If it is, the task reports ok instead of changed.
Idempotency makes playbooks safe to re-run. You can run them in CI, in production, or repeatedly without worrying about duplicate changes. This is the foundation of reliable automation.
Changed vs Ok
Ansible reports task results as ok (nothing changed), changed (a change was made), or failed (an error occurred). Understanding these states helps you verify playbook behavior.
PLAY [webservers] *************************************************************
TASK [Gathering Facts] *******************************************************
ok: [web1.example.com]
TASK [Install nginx] *********************************************************
changed: [web1.example.com] # nginx was installed
TASK [Install nginx] *********************************************************
ok: [web1.example.com] # already installed — nothing to do
PLAY RECAP *******************************************************************
web1.example.com : ok=3 changed=1 unreachable=0 failed=0First run: changed. Second run: ok. This confirms idempotency. The task did not re-install nginx.
Check Mode
Check mode (--check) performs a dry run — Ansible evaluates what would change without actually making changes. It is invaluable for testing playbooks safely.
# Dry run — see what would change
ansible-playbook site.yml --check
# Dry run with verbose output
ansible-playbook site.yml --check -v
# Dry run a single task
ansible-playbook site.yml --check --tags "install"Check mode is not foolproof — some modules do not support it fully. Always combine it with code review for critical changes.
Not all modules support check mode. Shell and command modules execute by default unless they have creates/removes parameters. Test check mode against staging before relying on it in production.
Designing Idempotent Tasks
- Use declarative modules instead of shell/command when possible
- Set state parameters — present, absent, started, stopped
- Use creates/removes parameters to skip tasks when conditions are met
- Avoid shell commands that run every time without state checks
- Test with --check before running in production
# Good: uses creates to skip if file exists
- name: Generate config
command: /usr/local/bin/generate-config
args:
creates: /etc/app/config.yml
# Good: declarative file management
- name: Ensure config file exists
file:
path: /etc/app/config.yml
state: file
owner: root
group: root
mode: "0644"The creates parameter makes command tasks idempotent by skipping execution when the specified path already exists.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.