The reliable pattern is simple: let Test Kitchen create an isolated machine, let Ansible converge your playbook or role on it, and let Chef InSpec verify the machine against the deployment contract. The kitchen-inspec verifier connects those stages. You can run one target with kitchen verify or execute the complete create, converge, setup, verify, and destroy lifecycle with kitchen test.
Antihost offers Linux VPS plans with full root access, unlimited traffic on a 1 Gbps port and a 14-day free trial.
What this testing stack does
Each tool has a distinct responsibility, so failures are easier to diagnose when the boundaries stay clear.
As an Amazon Associate I earn from qualifying purchases.
Recommended Free Tools
Ansible applies the change
Your playbook or role is the system under test. It installs packages, writes configuration, creates users, enables services, opens or closes ports, and performs any other deployment work. Ansible should be responsible for changing the target, not for declaring that the resulting machine is correct.
Test Kitchen supplies repeatable targets
Test Kitchen is a harness for executing infrastructure code on one or more platforms in isolation. Its configuration is organized around four units:
#1 Best Overall
- Driver: creates and removes a target, such as a container, virtual machine, or cloud instance.
- Provisioner: runs Ansible against that target.
- Platform: identifies the operating-system image or other target definition.
- Suite: groups the playbook inputs and verification profile for a scenario.
A Kitchen instance is the combination of a suite and a platform. That makes it possible to test the same role against several operating systems without changing the test contract.
kitchen-inspec connects verification
The kitchen-inspec plugin allows Kitchen to run Chef InSpec after convergence. Set verifier: name: inspec in kitchen.yml. The verifier can use Kitchen’s host and port information automatically, or you can provide explicit connection settings when the target requires them.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →InSpec describes the expected state
Chef InSpec expresses compliance, security, and policy expectations in a human- and machine-readable language. It can evaluate the local machine or connect to a remote host over SSH. Its resources let you test packages, services, ports, files, users, ownership, permissions, configuration values, and application responses without coupling the test to the Ansible task names that produced them.
Start with a deployment contract
Before writing YAML or controls, list what a successful deployment must make true. These are observable outcomes, not implementation details.
Record required packages
Specify each package and, when it matters, the expected version or version range. A test that only checks for a package name can pass while an incompatible version is installed.
Define service behavior
For every daemon, decide whether it must be installed, enabled at boot, running now, and listening on a particular address or port. Treat those as separate requirements where they have different failure modes.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesSpecify files and permissions
Identify configuration and data paths, required content, owner, group, and mode. A file with correct text but world-writable permissions is not a successful deployment.
Define accounts and access
Document service users, shells, supplementary groups, home directories, and ownership of application files. If the account must not permit interactive login, make that an explicit assertion.
Test externally visible behavior
Where possible, verify an endpoint’s status code, response header, or other stable contract. An HTTP check catches failures that package and process checks miss, such as a broken listener, invalid configuration, or an application that starts but cannot serve requests.
Rank #2
Keep idempotence separate
Final-state controls answer “is the machine correct?” Idempotence answers “does a second run leave it unchanged?” Run the playbook twice and inspect the second run’s changes separately from InSpec verification. Mixing both questions into one control makes a failure ambiguous.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCreate the Kitchen project
Install compatible versions of Test Kitchen, the Ansible provisioner, the driver you intend to use, and the kitchen-inspec verifier. Pin those dependencies in the project and run the same versions in CI so a plugin upgrade does not silently change the test environment.
Use a clear directory layout
A small role-oriented project can look like this:
.
├── kitchen.yml
├── converge.yml
├── roles/
│ └── webapp/
│ ├── tasks/
│ ├── templates/
│ └── defaults/
└── test/
└── integration/
└── default/
└── controls/
└── webapp.rb
The default kitchen-inspec convention is test/integration/%suite%. A suite can override that location with inspec_tests. Keeping controls next to the suite makes it obvious which contract belongs to which scenario.
Configure a minimal instance
This configuration shows the essential shape. The exact driver options depend on the driver plugin and your target environment.
provisioner:
name: ansible
driver:
name: docker
platforms:
- name: ubuntu
verifier:
name: inspec
suites:
- name: default
provisioner:
playbook: converge.yml
verifier:
inspec_tests:
- test/integration/default
The driver creates an isolated Ubuntu target, the Ansible provisioner runs converge.yml, and the InSpec verifier reads controls below test/integration/default. Replace the driver and platform with the operating systems and images your deployment supports.
Free tools Windows power users keep installed
One-click scans. No signup required.
Make inventory and variables explicit
Do not hide test inputs in a developer’s shell profile. Put role variables in suite or playbook configuration, identify the inventory used for the Kitchen instance, and record secrets through the CI secret mechanism rather than committing them. Explicit inputs let you tell whether a failure came from inventory, variable precedence, provisioning, or verification.
Write InSpec controls around outcomes
Controls should prove the contract while remaining independent of task ordering. The following example checks a web deployment without assuming which Ansible module created each resource.
control 'webapp-package' do
impact 1.0
title 'Web server package is installed'
describe package('nginx') do
it { should be_installed }
end
end
control 'webapp-service' do
impact 1.0
title 'Web server is enabled and running'
describe service('nginx') do
it { should be_enabled }
it { should be_running }
end
end
control 'webapp-listener' do
impact 1.0
title 'Only the intended HTTP service listens on port 80'
describe port(80) do
it { should be_listening }
its('processes') { should include 'nginx' }
end
end
control 'webapp-config' do
impact 1.0
title 'Configuration has the required ownership and mode'
describe file('/etc/nginx/nginx.conf') do
it { should exist }
its('owner') { should eq 'root' }
its('group') { should eq 'root' }
its('mode') { should cmp '0644' }
its('content') { should match /worker_processes/ }
end
end
control 'webapp-account' do
impact 1.0
title 'The service account has the intended login policy'
describe user('www-data') do
it { should exist }
end
end
Use stable assertions. Matching an exact generated timestamp or a temporary path creates brittle tests. If a value is security-sensitive, assert the precise value and permissions; if it is implementation-specific, test the behavior that matters instead.
Check application responses
For a service reachable from the verifier, add an HTTP contract that reflects the supported interface. For example, assert that the endpoint returns the expected status and a required header. Keep network assumptions explicit: a container-only test may use the container’s interface, while an SSH-based test may need a routable address and port forwarded by the driver.
Rank #3
Control severity deliberately
InSpec impact values communicate the consequence of a failure. Mark a missing security control or unavailable production endpoint as high impact, and use lower impact for advisory hardening checks. The value does not change whether a control runs, but it helps CI and compliance consumers prioritize failures.
Run the Kitchen lifecycle
Kitchen’s documented lifecycle is create, converge, setup, verify, and destroy. Running each phase separately is useful while developing controls; running kitchen test is convenient for a clean, disposable check.
Create an isolated target
kitchen create default-ubuntu
Kitchen asks the configured driver to create the target for the selected suite and platform. If this fails, inspect the driver, image name, runtime permissions, network access, and local resource limits. An InSpec control cannot diagnose a target that never started.
Converge with Ansible
kitchen converge default-ubuntu
This runs the configured playbook against the Kitchen instance. Provisioning errors belong here: syntax failures, missing variables, unreachable repositories, failed package installation, and task errors should be fixed before interpreting verification results.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Run setup when required
kitchen setup default-ubuntu
The setup phase prepares the target for verification, including any transport or verifier prerequisites required by the configured plugins. If setup fails, check SSH credentials, the remote user, privilege escalation, and whether the image contains the expected shell and package manager.
Verify the machine
kitchen verify default-ubuntu
The verifier executes the InSpec profile and reports each control as passed or failed. Read the resource output rather than treating the final exit code as the diagnosis. A failed service control may be caused by a package failure, a disabled unit, a bad configuration, or a process that crashed after starting.
Destroy the instance
kitchen destroy default-ubuntu
Destroy ephemeral targets after a run, especially in CI. Leaving instances behind can consume storage, addresses, and credentials and can make a later run appear to pass because it reused stale state.
Run the complete flow
kitchen test default-ubuntu
This command executes the create, converge, setup, verify, and destroy sequence for the instance. During debugging, use the individual commands so you can preserve a failed machine for inspection. Once the test is stable, the complete flow gives CI a clean start and deterministic cleanup.
Test more than one platform
A role that passes on one image may fail elsewhere because package names, service managers, filesystem locations, default users, or security policies differ. Add platforms that represent the supported deployment boundary rather than every image you can find.
Rank #4
| Decision axis | Questions to answer |
|---|---|
| Isolation | Does the driver provide a clean target for every run, or can state leak between tests? |
| Operating-system fidelity | Does the image match the distributions, versions, and base hardening used in production? |
| Startup and provisioning time | Can the target be created quickly enough for pull requests, or should slower coverage run on a scheduled pipeline? |
| Transport and authentication | Will verification use local execution, SSH, a forwarded port, or another connection path? |
| CI availability | Is the driver supported and permitted on every CI runner that must execute it? |
| Parallelism and cleanup | Can multiple instances run concurrently without colliding over names, ports, networks, or credentials? |
| Production parity | Does the test image reproduce the important kernel, init system, filesystem, and network behaviors? |
Use a separate suite when the deployment contract genuinely differs, such as a database-backed installation versus a standalone node. Use multiple platforms in one suite when the same contract should hold across operating systems.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Choose where profiles live
The verifier can consume controls from several sources. A local directory is usually easiest for a role’s unit and integration tests. A Git repository is useful when several projects share a versioned security profile. A Supermarket or compliance profile can centralize controls for teams that need a common policy endpoint.
| Profile source | Best fit | Trade-off |
|---|---|---|
| Local directory | Controls owned and reviewed with the deployment code | Reuse across repositories requires copying or packaging |
| Git repository | Shared controls with normal code review and version tags | Runs may need network access or a cached checkout |
| Supermarket profile | Reusable community or organization profile | External availability and version changes must be managed |
| Compliance profile | Central governance and audit-oriented policy distribution | Requires agreement on profile ownership and access |
Pin a profile revision when reproducibility matters. A moving branch or unpinned external profile can change verification results without any change to the Ansible code.
Separate provisioning failures from verification failures
Use the first failing lifecycle phase as your initial branch.
If create fails
- Confirm the driver plugin is installed and compatible with Test Kitchen.
- Verify the image exists locally or is reachable from the runner.
- Check container, hypervisor, or cloud permissions.
- Look for host port, network, disk, and memory collisions.
If converge fails
- Run the playbook with the same inventory and variables outside Kitchen to isolate Ansible logic.
- Check package repositories, interpreter discovery, privilege escalation, and missing role dependencies.
- Inspect the failed task’s module output before changing InSpec controls.
If setup or verification cannot connect
- Confirm the verifier is configured as
inspecand that thekitchen-inspecplugin is available. - Check the remote host, port, user, key, and sudo settings.
- Ensure the driver exposes the address that Kitchen reports rather than an internal-only address.
- Test the connection with the same credentials from the CI runner.
If a control fails after convergence
- Read the actual resource value printed by InSpec.
- Decide whether Ansible produced the wrong state or the control encoded the wrong contract.
- Inspect the target directly before destroying it; rerun verification after a focused fix.
- Do not weaken a security assertion merely to make the pipeline green.
Verify idempotence and re-runs
A deployment should normally converge without changing already-correct resources. Run:
kitchen create INSTANCEto obtain a clean target.kitchen converge INSTANCEand save the Ansible change summary.kitchen converge INSTANCEagain with identical inputs.- Investigate unexpected changes in the second run, such as regenerated files, unstable ordering, timestamps, permissions, or handlers firing repeatedly.
- Run
kitchen verify INSTANCEafter the second convergence to ensure the final state still meets the contract.
Keep this check separate from the InSpec profile’s final-state controls. A role can be idempotent yet deploy the wrong port, and a role can reach the right final state while making destructive changes on every run.
Produce useful CI evidence
Run the complete Kitchen flow for pull requests when the driver is fast enough, and schedule broader platform coverage when it is slower or more expensive. Execute independent platform instances in parallel only when the driver and CI runner can isolate their networks, names, ports, and credentials.
Retain the InSpec result as a machine-readable artifact. The InSpec command set supports machine-readable formats, including JSON, which allows CI systems to archive control results, trend failures, and feed audit tooling. Also retain the Kitchen and Ansible logs for the failed lifecycle phase; a JSON verification report alone cannot explain a package repository timeout during convergence.
Destroy instances in a cleanup step that runs even when verification fails. For shared or cloud drivers, add a second cleanup safeguard so abandoned resources do not survive a cancelled CI job.
Security and reliability practices
- Use disposable credentials with the minimum privileges needed to converge and verify.
- Keep secrets out of
kitchen.yml, control source, and CI logs. - Do not expose a test service to a public network unless the scenario requires it.
- Pin driver, provisioner, verifier, platform image, and profile revisions.
- Make timeouts explicit for package installation and endpoint checks so a network stall fails clearly.
- Use assertions for both positive and negative requirements, such as the required port listening and an administrative port not listening.
- Review controls when the deployment contract changes; stale controls are a maintenance failure, not a reason to ignore red results.
An end-to-end working sequence
For a new role, follow this order:
- Write a short contract covering packages, services, ports, files, accounts, permissions, and endpoint behavior.
- Create a Kitchen suite and select a driver and platform that resemble the supported deployment.
- Add the Ansible playbook used to converge the role, with explicit inventory and variables.
- Set
verifier: name: inspecand pointinspec_testsat the suite’s control directory. - Write one focused control per contract area instead of one large control that hides the failing assertion.
- Run
kitchen create, thenkitchen converge, and fix provisioning errors. - Run
kitchen verifyand correct either the deployment or the contract when a control fails. - Converge a second time and inspect idempotence independently.
- Add the other supported platforms and repeat the same contract checks.
- Run
kitchen testin CI, archive JSON results and logs, and guarantee destruction on every exit path.
Practical checklist
- Every required outcome has an observable assertion.
- The suite’s platform image matches a supported operating system.
- The Ansible inventory, variables, and credentials are explicit and reproducible.
- The
kitchen-inspecverifier is configured and version-pinned. - Controls check package, service, port, file, user, permission, and endpoint requirements where applicable.
- Idempotence is tested with a second converge rather than inferred from a passing verification.
- CI preserves machine-readable InSpec output and lifecycle logs.
- Ephemeral targets are destroyed after success, failure, and cancellation.
Using Kitchen for isolation, Ansible for convergence, and InSpec for independent assertions gives each failure a clear owner. The result is a repeatable test of what the deployment actually creates, across the platforms your role claims to support.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.




