unit 9 · Workplace ecosystem

ansible-lint & yamllint

The reviewer that never gets tired

essential · 6 min · linux + windows

you may want to read 13 · YAML pitfalls & the quoting rule , 24 · Roles: structure, defaults vs vars first — but nothing is locked

tl;dr

  • ansible-lint with profile: production — the strictest preset — is the bar real repos hold PRs to.
  • yamllint catches indentation and line-length slips; ansible-lint catches Ansible-specific bad practice.
  • Every skip in .ansible-lint needs a documented reason — undocumented skips get flagged in review.

why it matters Your first PR at the new job gets judged by lint before any human reads it — know what the production profile enforces and you pass review on the first push.

Lesson 4 handed you “use the FQCN or lint will fail the PR” on faith. Time to cash it out. The lint is ansible-lint. It runs in CI on every pull request. In most shops it is the first reviewer your code meets, and it never tires.

Two tools share the job. yamllint polices YAML itself — indentation, line length, trailing whitespace, lesson 13’s truthy traps — so no human ever comments on them. ansible-lint reads your playbooks and roles as Ansible, flagging patterns that parse fine but teams agree are trouble. It runs yamllint-style checks too, so one command covers both layers.

The promoted install is one bundle:

pip install ansible-dev-tools # lint + molecule + navigator, one install
ansible-lint site.yml # or run it bare to lint the whole repo
ansible-dev-tools bundles the whole dev toolchain

The bundle also delivers molecule and ansible-navigator, tools you meet in lessons 38 and 40 — which is why teams standardise on it.

The production profile

ansible-lint groups its rules into profiles of increasing strictness. profile: production is the strictest preset, and the one real repos run. It catches modules invoked without FQCN (lesson 4’s rule, enforced at last), unnamed tasks, role-name violations, missing handlers, and dozens of other issues. A first run:

$ ansible-lint site.yml
fqcn[action-core]: Use FQCN for builtin module actions (copy).
site.yml:8

name[missing]: All tasks should be named.
site.yml:12

Failed: 2 failure(s), 1 warning(s) on 1 files.
abridged output — rule id, explanation, location

Note the split: failures block, warnings don’t. A with_items: surfaces as a warning, not an error — lesson 19 told you why: legacy, not deprecated.

The config file is a contract

Configuration lives in .ansible-lint at the repo root, checked in so every laptop and CI runner enforces the same bar:

# .ansible-lint — repo root, version-controlled
profile: production
skip_list:
  # OPS-1123: inherited role names predate our convention;
  # renaming breaks live playbooks, tracked for Q4 cleanup.
  - role-name
a minimal .ansible-lint — profile plus one documented skip

Look at that skip. The reason sits next to it, with a ticket. That’s the norm. Skips are legitimate — repos carry history you can’t fix in one PR — but every skip must be documented in the config. An undocumented skip is one of the most common PR review flags. It reads as “I made the error go away”, not “we decided this rule doesn’t apply.”

Run it twice: locally before you push (seconds spent, a failed pipeline saved) and in CI on every PR. When you wire Ansible into Jenkins in lesson 41, a lint stage is the first thing the pipeline runs. But lint reads code without executing it, so it proves style, never behaviour. Proving a role actually converges takes a harness that runs it for real — that’s lesson 38.

at work, this sounds like

“Lint is red.”
The CI ansible-lint job failed — fix the violations or add a documented skip before anyone bothers reviewing the PR.
“Add it to the skip list — with a comment.”
Suppress the rule in .ansible-lint, but write down why: an undocumented skip is one of the most common PR review flags.

self-check — recall, not a test

  1. 1 Which ansible-lint profile do real repos run in CI, and name three things it catches.

  2. 2 Lint hits a with_items in a role you inherited. Does the build break?

  3. 3 A teammate adds a rule to skip_list with no comment. What happens in review, and why?

lab (optional — never required)

Run ansible-lint against lesson 12's site.yml, read every violation it reports, and fix them until the run exits clean.

needs: The control node from lesson 5, with ansible-dev-tools installed.

next up 38 · Molecule, conceptually 6 min · unit 9