Course outline

Ansible / Basic: execution, inventory, and typed state / Lesson 1

Understand Ansible’s automation model

Separate controller decisions, inventory selection, module execution, desired state, and proof of useful results before authoring automation.

About 4 min readContent reviewed
On this page

Lesson goals

  • Distinguish ansible-core from the community package and collections.
  • Explain control-node and managed-node responsibilities.
  • Treat target selection, privileges, and verification as explicit boundaries.

The engine and content have different release boundaries

ansible-core supplies the execution engine, language, and builtin plugins. The Ansible community package adds a selected collection set and follows another release numbering scheme. A collection packages modules, plugins, roles, and supporting content; installing the engine does not imply that every collection is present. This course uses the documented ansible-core 2.21 family as its reference baseline, not a claim that an engine was run locally. Record engine, Python, and collection versions together because their compatibility determines which syntax and plugins a project can actually use.

Controller and managed targets do different work

The control node reads inventory and playbooks, evaluates variables and templates, and coordinates tasks. Depending on the connection and module, work can execute on a managed host, through an API, or on the controller. Agentless does not mean dependency-free: a target may need a supported interpreter or platform transport. A module result returns structured evidence such as changed, failed, and data fields. The controller’s successful task result is not automatically proof that the complete application is healthy. Keep orchestration, target effects, and application verification separate in the design.

Desired state is a contract, not a universal property

A state-oriented module can compare observed and requested state and change only what is needed. Idempotence means repeating an operation under the relevant assumptions does not keep producing additional intended effects. It is not guaranteed merely because YAML is declarative-looking. A shell command, unstable template, or changing external system can report changes every run. Choose modules with documented semantics and define what a second run should prove. Also distinguish configuration convergence from application acceptance: a file can match its template while the service still rejects its contents.

python Separate a synthetic state comparison from health
desired = {'mode': 'review', 'workers': 2}
observed = {'mode': 'review', 'workers': 2}
print('synthetic_changed=' + str(observed != desired))
print('application_health=not-tested')
Expected output
synthetic_changed=False
application_health=not-tested

The dictionary comparison is an offline model only. It does not execute Ansible or inspect a host, and equal dictionaries do not prove application behavior.

A play’s scope can be more important than its task text

Inventory, host patterns, limits, delegation, connection variables, and privilege escalation determine where and with whose authority a task acts. A harmless-looking task aimed at an unintended host is still incorrect automation. Review the selected population and credentials independently from the module arguments. A localhost name alone does not establish every safety property; connection configuration, facts, lookups, and included content can still matter. All Ansible examples here are illustrative and non-runnable. Offline models and YAML parsing are the only performed checks, with no SSH, configured inventory, services, or credentials accessed.

Read a minimal play before adding effects

A playbook is an ordered list of plays, and each play selects hosts and defines work. Use fully qualified collection names so module selection is explicit. Disable fact gathering in an illustration when facts are not needed, rather than hiding an implicit managed-node operation in a supposedly empty example. Meaningful task names describe intent and improve result review. The following play only illustrates structure and a debug message for a fictional group. Parsing this YAML confirms data syntax, not inventory resolution, plugin compatibility, or actual Ansible execution.

yaml Illustrative play structure for a fictional group
- name: Describe a synthetic lab
  hosts: lab_nodes
  gather_facts: false
  tasks:
    - name: Explain the planned target
      ansible.builtin.debug:
        msg: Synthetic lab only

The play remains non-runnable and was parsed as YAML only. No inventory, target connection, debug action, or fact gathering was executed.

Common errors and fixes

The community package version is called the core version

Why it happens
Two release systems were conflated.
How to fix it
Record engine and collection versions separately.
Prevent it next time
Keep an explicit execution dependency manifest.

changed=false is called application health

Why it happens
State comparison was mistaken for useful service verification.
How to fix it
Add independent application acceptance evidence.
Prevent it next time
Define convergence and health as separate checks.

Agentless is assumed to need no platform dependencies

Why it happens
Connection and module requirements were ignored.
How to fix it
Read control and managed-node support requirements.
Prevent it next time
Validate the declared platform matrix before rollout.

Check your understanding

1. What does an offline YAML parse establish about a playbook?

Show worked solution

It establishes that the parser can represent the document as data. It does not prove Ansible keywords, inventory, module availability, connection safety, or idempotence. Those require additional scoped checks and, when authorized, execution in a disposable environment.

2. Why should a design record both task scope and desired state?

Show worked solution

Correct state on the wrong target is still a failure. Scope defines the affected population and authority, while desired state defines the intended result. Review and test both independently before accepting a change.

Key takeaways

  • Separate engine, content, controller, target, and acceptance.
  • Treat execution scope and safety as explicit design inputs.

Official references