Assess Ansible Playbook Security with cnspec
Scan Ansible playbooks for security misconfigurations using cnspec.
Validate Ansible playbooks against security policies before they run against your infrastructure. cnspec parses playbook YAML and exposes tasks, roles, and configuration as queryable MQL resources, so you can check for insecure module options, missing privilege escalation controls, and other configuration issues in code review and CI before a single play executes.
Prerequisites
To scan Ansible playbooks with cnspec, you must have:
- cnspec installed on your workstation
- Ansible playbook files (
.yml) to scan
Scan an Ansible playbook
Scan a playbook file:
cnspec scan ansible playbook.ymlScan a directory containing playbook files:
cnspec scan ansible /path/to/playbooks/Scan options
| Option | Description |
|---|---|
--asset-name | Override the asset name |
--annotation | Add an annotation to the asset (key=value) |
--incognito | Run in incognito mode (do not report results to Mondoo Platform) |
-o, --output | Set the output format (compact, full, json, junit, summary, yaml) |
-f, --policy-bundle | Path to a policy file (local path, s3:// URI, or http(s):// URL) |
--policy | Specify policies to execute (requires --policy-bundle) |
--risk-threshold | Exit with status 1 if any risk meets or exceeds this value (0-100) |
Explore Ansible playbooks
Run cnspec shell ansible playbook.yml to open the interactive shell and explore your playbooks.
List all plays
cnspec> ansible.plays
ansible.plays: [
0: ansible.play name="Configure web servers"
1: ansible.play name="Configure database servers"
...
]Retrieve play details
Get hosts, roles, and privilege escalation settings for each play:
cnspec> ansible.plays { name hosts roles become becomeUser strategy }
ansible.plays: [
0: {
name: "Configure web servers"
hosts: "webservers"
roles: ["nginx", "certbot"]
become: 1
becomeUser: "root"
strategy: "linear"
}
...
]Retrieve play variables
cnspec> ansible.plays { name vars }
ansible.plays: [
0: {
name: "Configure web servers"
vars: {
http_port: "80"
max_clients: "200"
}
}
...
]List tasks within each play
cnspec> ansible.plays { name tasks }
ansible.plays: [
0: {
name: "Configure web servers"
tasks: [
0: ansible.task name="Install nginx"
1: ansible.task name="Copy nginx config"
2: ansible.task name="Start nginx service"
]
}
...
]Retrieve task details
Get the action and conditions for each task:
cnspec> ansible.plays { tasks { name action when notify } }
ansible.plays: [
0: {
tasks: [
0: {
name: "Install nginx"
action: {
module: "apt"
args: {
name: "nginx"
state: "present"
}
}
when: ""
notify: ["restart nginx"]
}
...
]
}
...
]Find tasks with conditional execution
cnspec> ansible.plays { tasks.where(when != "") { name when } }
ansible.plays: [
0: {
tasks.where: [
0: {
name: "Install nginx"
when: "ansible_os_family == 'Debian'"
}
]
}
]Retrieve block and rescue tasks
cnspec> ansible.plays { tasks { name block rescue } }
ansible.plays: [
0: {
tasks: [
0: {
name: "Deploy application"
block: [
0: ansible.task name="Pull latest code"
1: ansible.task name="Run migrations"
]
rescue: [
0: ansible.task name="Rollback deployment"
]
}
]
}
...
]List handlers
cnspec> ansible.plays { name handlers }
ansible.plays: [
0: {
name: "Configure web servers"
handlers: [
0: ansible.handler name="restart nginx"
1: ansible.handler name="reload nginx"
]
}
...
]Retrieve handler actions
cnspec> ansible.plays { handlers { name action } }
ansible.plays: [
0: {
handlers: [
0: {
name: "restart nginx"
action: {
module: "service"
args: {
name: "nginx"
state: "restarted"
}
}
}
...
]
}
...
]Get full details for all plays
cnspec> ansible.plays { * }Example security checks
Ensure yum tasks validate certificates
A common misconfiguration is disabling certificate validation when installing packages. Check that no ansible.builtin.yum tasks have validate_certs set to false:
ansible.plays.all(
tasks.where(action["ansible.builtin.yum"] != empty).all(
action["ansible.builtin.yum"]["validate_certs"] != false
)
)Ensure no plays run as root
ansible.plays.all(remoteUser != "root")Check that privilege escalation uses a specific method
ansible.plays.where(become == true).all(
becomeMethod == "sudo"
)Learn more
-
For the full MQL resource reference, see the MQL Ansible provider documentation.
-
To learn more about how the MQL query language works, read Write Effective MQL.