Review Ansible roles and playbooks for idempotency, structure, security posture, and testability — without modifying any files.
Reviews a role or playbook directory for correctness and operational safety.
Expected output sections:
- Findings — specific task names, file paths, and line numbers
- Risk level — Low / Medium / High / Critical
- Affected files — role paths, playbook names, var files
- Remediation — concrete module substitutions, task rewrites, vault steps
/ansible-review review the webserver role in roles/webserver for idempotency, structure, and security
Role layout:
roles/webserver/
tasks/
main.yml
install.yml
configure.yml
service.yml
handlers/
main.yml
templates/
nginx.conf.j2
vars/
main.yml <- contains plaintext passwords
defaults/
main.yml
molecule/ <- missing
meta/
main.yml
## Findings
**F1 — shell module used instead of package module (install.yml:8)**
```yaml
# Current (not idempotent):
- name: Install nginx
shell: apt-get install -y nginxshell is not idempotent — re-running the playbook will always mark this task
as "changed" and may produce unexpected output in check mode. Use the package
(or apt) module with state: present.
- Severity: High
- Idempotency impact: Yes
F2 — shell module for service enable (service.yml:14)
# Current:
- name: Enable nginx service
shell: systemctl enable nginxUse ansible.builtin.service with enabled: true. The shell call also
silently succeeds if systemctl is not available (containers, WSL).
- Severity: High
- Idempotency impact: Yes
F3 — Plaintext secrets in vars/main.yml
# vars/main.yml (line 3):
db_password: "hunter2"Secrets committed in plaintext are exposed in version control and Ansible logs.
Encrypt with ansible-vault encrypt_string and reference via vault lookup, or
move to a vault-encrypted var file.
- Severity: Critical
- Security impact: Yes
F4 — No Molecule tests
The molecule/ directory is absent. There is no automated idempotency or
convergence test. Changes to the role cannot be validated without a live target.
- Severity: Medium
F5 — configure.yml copies template without a handler notify
# configure.yml:22:
- name: Deploy nginx config
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.confThe task does not notify the Restart nginx handler. Config changes will not
take effect until the next manual service restart.
- Severity: High
- Operational impact: Config drift between deployed template and running config.
F6 — meta/main.yml missing galaxy_info.min_ansible_version
galaxy_info block exists but omits min_ansible_version. Operators on older
Ansible versions will silently use the role with unpredictable results.
- Severity: Low
Critical — plaintext secrets in version control (F3) and two non-idempotent
shell tasks (F1, F2) that will mark every run as changed and may fail in
check mode or CI pipelines.
roles/webserver/tasks/install.yml— F1roles/webserver/tasks/service.yml— F2roles/webserver/vars/main.yml— F3roles/webserver/tasks/configure.yml— F5roles/webserver/meta/main.yml— F6roles/webserver/molecule/— F4 (missing)
Immediate (Critical/High):
-
Rotate
db_password— it is compromised. After rotation:ansible-vault encrypt_string 'new_password' --name 'db_password'
Store the result in
vars/vault.ymland addvars/main.ymlto.gitignore(or encrypt the whole file withansible-vault encrypt vars/main.yml). -
Replace
shell: apt-get install -y nginxwith:- name: Install nginx ansible.builtin.package: name: nginx state: present
-
Replace
shell: systemctl enable nginxwith:- name: Enable and start nginx ansible.builtin.service: name: nginx enabled: true state: started
-
Add
notify: Restart nginxto the template task inconfigure.yml:22.
Medium term:
-
Initialise Molecule:
cd roles/webserver molecule init scenario --driver-name dockerAdd a convergence test and an idempotency assertion to the scenario.
-
Add
min_ansible_version: "2.14"tometa/main.ymlundergalaxy_info.
Validation commands:
ansible-lint roles/webserver/
ansible-playbook site.yml --check --diff
molecule test -s default
---
### Step 2 — Plan the remediation
After reviewing, use the unified `/plan-change` command to create a
remediation plan:
/plan-change create a remediation plan for the webserver role findings
This produces the same structured plan output as any other change workflow,
with the Ansible-specific context automatically detected from the file types.
---
## Notes
- `/ansible-review` is read-only. No playbook or role file is modified.
- Always run `ansible-lint` as the first validation step after applying
remediation — it catches idempotency and module-usage issues not visible
from a static review.
- Vault findings are always Critical; surface them first in the output
regardless of ordering in the original file scan.