One playbook that runs Sansec’s eComscan against every site I manage, from a single command or from a scheduled GitHub Action. It is published on Ansible Galaxy as samjuk.ecomscan.
The detection is Sansec’s. The role gets the scanner onto each host, runs it the same way everywhere, and acts on the result. eComscan itself is a paid product: the accompanying guide puts a single installation licence at €219 a month, with agency discounts for multiple stores.
How do I run eComscan across every Magento host?
Install the role, point a playbook at your inventory, and set the licence key, report address and project root per host:
ansible-galaxy role install samjuk.ecomscan
# playbooks/scan.yml
- name: Ecomscan
hosts: all
roles:
- { role: samjuk.ecomscan, tags: ecomscan }
# host_vars/store-prod.yml
ecomscan_key: "<licence key>"
ecomscan_report_email: "[email protected]"
ecomscan_project_root: /var/www/vhosts/example.com/htdocs/current/
ecomscan_cron: true
What does it do on each host?
It downloads the eComscan binary, then scans now, on a schedule, or both:
- One-off scan (
ecomscan_run, on by default), reporting by email and optionally to a Slack webhook. The play prints eComscan’s>> Foundsummary line at the end. - Scheduled scans (
ecomscan_cron), written to/etc/cron.d/ecomscan-<inventory_hostname>, every four hours by default (0 */4 * * *), logging to/var/log/ecomscan.log.
Minimum confidence (default 50), maximum file size (default 20MB) and deep scanning are all variables.
Can it fail a deploy when it finds malware?
Yes. Two flags, ecomscan_assert_no_malware and ecomscan_assert_no_vulnerabilities, fail the play when MALWARE or VULNERABILITY appears in the scan output, so the role works as a gate in a pipeline as well as a monitor.
Here it is on 11th October 2026 against a stock Magento 2.4.8-p5 install, with an EICAR test file planted in pub/ and the minimum confidence at 0, the same setup as the role’s own Molecule tests. Role v1.0.5, eComscan 1.9.14, trial key. The summary line is eComscan’s, and the malware assert fails the play with exit code 2:

How is it tested?
Every pull request, every push to master and a weekly Monday run lint the role with ansible-lint, then converge it with Molecule on Ubuntu 22.04, Debian 12.6, Rocky Linux 9.3 and Fedora 39. The latest weekly run, on 5th October 2026, passed. The same matrix runs locally through Poetry:
MOLECULE_DISTRO=debian MOLECULE_DISTRO_VER=12.6 poetry run molecule test
Releases are tagged from v1.0.0 (20th May 2024) to v1.0.5 (28th May 2026).
What does it leave to you?
- Scheduling on a trial key. Sansec limits trial keys to three runs, so a cron on one would quietly stop working. The role refuses to set one up and says why.
- The clean-up. It reports, and with the assert flags fails the play. Removing what it finds is still a job for a person.