Blog

Enterprise-Scale PCI DSS Compliance Automation with Ansible

· 6 min read
Enterprise-Scale PCI DSS Compliance Automation with Ansible

When enterprises in regulated industries talk about compliance automation, it sounds straightforward: write a few playbooks, run them regularly, generate a report, done. Reality looks different, especially when it comes to PCI DSS compliance for virtualization estates.

What follows is my approach to automating PCI DSS audits and remediations with Ansible: which architecture decisions matter, which pitfalls to expect, and why Ansible can handle compliance automation at this scale only if you treat it as a software engineering project, not a scripting exercise.

The Problem

A virtualization estate in a regulated industry has to be audited against hardening standards on a repeating cycle, host by host: SSH configuration, NTP settings, syslog forwarding, lockdown mode, firewall rules, password policies, directory integration, and more.

The requirements are clear:

  • Audit all hosts against defined hardening controls
  • Remediate deviations, as automated as possible
  • Audit-ready reports that auditors can understand and accept
  • Repeatability, so the whole process runs regularly and reliably

Manual auditing does not survive contact with a repeating cycle. But naive automation quickly hits its limits too.

Start With the Inventory

Where hosts are provisioned and decommissioned continuously, a static inventory is not an option. And once an environment spans more than one management domain, an inventory plugin per vCenter becomes unwieldy fast.

Use a single, aggregated data source as the inventory instead. In VMware environments, VCF Operations (formerly vRealize Operations / Aria Operations) is ideal for this, because it already collects data from all vCenters. From there you can develop a custom Ansible inventory plugin that generates the entire ESXi inventory via the VCF Operations API, with automatic grouping by vCenter, cluster, ESXi version, and location.

The payoff is that new hosts appear in the inventory on their own, decommissioned hosts drop out on their own, and the grouping lets you point an audit run at a single cluster or a single ESXi version.

Package the plugin as an Ansible Collection, with unit tests and code quality checks. For a system of this importance, that isn’t optional.

One Playbook, Two Modes

A common mistake is separating audit and remediation logic into different playbooks. This inevitably leads to drift: what gets checked and what gets fixed diverge over time.

A single playbook can cover both modes. Ansible’s --check mode is powerful and often underestimated:

  • ansible-playbook compliance.yml --check → audit mode, checks without changing
  • ansible-playbook compliance.yml → remediation mode, fixes deviations

The prerequisite is a consistently idempotent implementation of all tasks. Every module first checks the current state and only makes changes when an actual deviation exists. Run the playbook a second time and nothing happens, unless there are new deviations.

The result is no drift between audit and remediation logic, an audit or remediation an operator can trigger with a single click in AWX/AAP, and a system that non-developers can use.

Why I Write Custom Modules

For enterprise-scale compliance, community modules (community.vmware) often aren’t sufficient. You need full control over API calls, error handling, and return values.

So: custom Ansible modules in Python that talk directly to the vSphere and ESXi APIs. A VMware hardening implementation works out at one custom module per control.

Writing them yourself is what gives you full control over --check mode behavior, precise error handling and return values for the audit report, and the ability to cover your own code with unit tests (pytest). It also means no dependency on external collections that may change underneath you.

Recording the Results

All task results should be captured automatically and in a structured format, not just in the Ansible console but in a database. ARA (ARA Records Ansible) is excellent for this: an open-source tool that records all playbook results via an Ansible callback and makes them searchable.

The Report Is the Deliverable

Auditors don’t want to scroll through a long spreadsheet. They want answers to questions like: “Which hosts running ESXi version X are still outstanding?” or “Which controls are failing in cluster Y?”

A self-contained HTML report with embedded JavaScript (jQuery + DataTables) answers that. The audit data is embedded as JSON directly in the HTML, and a Python script generates the document from the ARA database.

What that gives the auditor: color-coding, green for compliant hosts and red for pending remediation; real-time filtering by ESXi version, vCenter, cluster, or compliance status; summaries whose statistics adapt as the filters change; and no setup at all, since it’s a single HTML file you open.

An interactive report is more useful in an audit setting than a static table, because the relevant data can be filtered and presented live.

Architecture Overview

Where the Time Goes

Execution time is the constant design constraint. Even with well-tuned forks and batching, a full audit run is measured in hours rather than minutes, and the reasons are structural:

  • The nature of Ansible: for each task, the Python interpreter is started per host, and an API call is initiated
  • Unresponsive hosts: a host that doesn’t answer holds a fork open for the full timeout
  • Connectivity issues: unreachable hosts block progress
  • AWX/AAP ceilings: output log size and job runtime both have practical limits, and a full-estate run can approach them

There are ways to work within that. Split audits by location or cluster and process them sequentially. Run complete audits overnight, with automatic continuation only after the previous segment finishes without errors. Treat critical systems as a separate risk class with their own change window. And identify unreachable hosts beforehand with separate connectivity playbooks, repairing them automatically where that’s possible.

Byproducts Worth Planning For

Handling connectivity problems properly calls for dedicated diagnostic and repair playbooks. Those are worth designing as a standalone automation tool rather than as a scratch fix, because their value extends well beyond the compliance context.

Infrastructure Automation at This Scale Is Software Engineering

Treat a project like this as a scripting exercise and it collapses under its own complexity. What the alternative looks like in practice:

  • Ansible Collection as the packaging unit for inventory plugin and custom modules
  • Unit tests (pytest) for all Python components, inventory plugin and custom modules alike
  • SonarQube integration for static code analysis, covering both Python modules and Ansible YAML
  • Idempotent implementation as the fundamental principle for all modules
  • Clean API abstraction, with custom modules encapsulating the complexity of vSphere/ESXi APIs
  • Versioning and CI/CD, so the collection goes through a pipeline like any other software

Without this, a project spanning a module per control, an inventory plugin, and a report generator simply becomes unmaintainable.

The approach transfers. Whether it’s PCI DSS, SOX, ISO 27001, or another compliance framework, the tools and the patterns stay the same, and so does the need for engineering discipline behind them.

Tags

Ansible PCI DSS VMware Compliance Infrastructure Automation

Originally published on LinkedIn in March 2026.

Facing a similar challenge?

Get in touch to discuss your requirements and how I can help.

Get in touch