How do you use a variable inside a task, and why must name: {{ service }} be written as name: "{{ service }}"?
Reference it in double curly braces, {{ variable }}; Ansible replaces it with the value when the task runs. If the braces start the value, quote the whole value, because YAML would otherwise read the { as the start of a dictionary.
vars:
web_package: httpd
tasks:
- name: Install the web server
ansible.builtin.dnf:
name: "{{ web_package }}"
state: present
The {{ }} syntax comes from Jinja2, the template engine Ansible runs every string through. YAML, however, is parsed first, and in YAML { at the start of a value opens an inline dictionary ({a: 1}). So name: {{ service }} is a YAML error before Jinja2 ever sees it, and Ansible answers with "this one looks like it might be an issue with missing quotes".
The rule is about the start of the value:
| Written | Result |
|---|---|
name: {{ web_package }} |
YAML error |
name: "{{ web_package }}" |
works |
dest: "{{ web_root }}/index.html" |
works (quoted anyway, it starts with {) |
msg: Installing {{ web_package }} now |
works: the value starts with a letter, so no quotes are needed |
Tip: Quoting every value that contains {{ is a safe habit and costs nothing.
Go deeper:
YAML Syntax: gotchas (official docs) — the missing-quotes error and the other common YAML traps.
Templating (Jinja2) (official docs) — what happens inside the braces.
Jinja (template engine) (Wikipedia) — the engine behind the double curly braces.