Sửa lỗi Jinja2 'template error while templating string' trong Ansible

beginner🔧 Ansible2026-04-21| Ansible 2.9+, Python 3.x, Linux/macOS

Error Message

AnsibleError: template error while templating string: expected token ':', got '}'. String: {{ myvar }
#ansible#jinja2#template#biến#cú pháp

TL;DR: Cách sửa nhanh

Lỗi này hầu như luôn do lỗi cú pháp trong biểu thức Jinja2 của bạn. Nguyên nhân phổ biến nhất là thiếu dấu ngoặc nhọn đóng } hoặc câu lệnh if/else nội tuyến bị viết sai.

Kiểm tra dòng được đề cập trong thông báo lỗi và đảm bảo biến của bạn trông như sau:

# Sai
msg: "{{ myvar }"

# Đúng
msg: "{{ myvar }}"

Nếu bạn đang dùng điều kiện nội tuyến, hãy đảm bảo có đủ cả if lẫn else:

# Sai (thiếu else)
msg: "{{ 'active' if enabled }}"

# Đúng
msg: "{{ 'active' if enabled else 'inactive' }}"

Nguyên nhân gốc rễ

Ansible sử dụng Jinja2 templating engine để xử lý mọi thứ bên trong {{ ... }}. Khi bạn thấy lỗi expected token ':', got '}', có nghĩa là trình phân tích cú pháp Jinja2 đang chờ một ký tự cụ thể theo sau biến hoặc biểu thức của bạn, nhưng lại gặp dấu ngoặc nhọn đóng (hoặc kết thúc chuỗi) thay vào đó.

Trình phân tích cú pháp bị "nhầm lẫn" tùy theo ngữ cảnh. Ví dụ, nếu nó cho rằng bạn đang bắt đầu một ánh xạ từ điển hoặc phép toán kiểu ternary, nó sẽ tìm kiếm dấu hai chấm :. Nếu bạn cung cấp một dấu } đơn thay vì }} như mong đợi, trình phân tích sẽ thất bại vì biểu thức chưa hoàn chỉnh về mặt cú pháp.

Các tình huống thường gặp và cách sửa

1. Thiếu dấu ngoặc nhọn (Lỗi đánh máy)

Đây là nguyên nhân phổ biến nhất. Bạn mở biến với {{ nhưng chỉ đóng bằng một dấu }.

# Lỗi: expected token ':', got '}'
- name: In ra một biến
  ansible.builtin.debug:
    msg: "Giá trị là {{ web_server_port }"

Cách sửa: Luôn đảm bảo bạn có các cặp dấu ngoặc nhọn kép khớp với nhau.

- name: In ra một biến
  ansible.builtin.debug:
    msg: "Giá trị là {{ web_server_port }}"

2. Biểu thức ternary nội tuyến chưa hoàn chỉnh

Jinja2 hỗ trợ cú pháp value_if_true if condition else value_if_false. Khác với một số ngôn ngữ khác, phần else là bắt buộc trong biểu thức Jinja2 khi dùng bên trong {{ ... }}.

# Sai
- name: Đặt trạng thái
  ansible.builtin.set_fact:
    app_status: "{{ 'running' if service_up }}"

Cách sửa: Thêm mệnh đề else.

- name: Đặt trạng thái
  ansible.builtin.set_fact:
    app_status: "{{ 'running' if service_up else 'stopped' }}"

3. Dấu ngoặc kép trong YAML không đúng

Đôi khi trình phân tích YAML và Jinja2 xung đột với nhau. Nếu chuỗi của bạn bắt đầu bằng {{, YAML yêu cầu toàn bộ dòng phải được đặt trong dấu ngoặc kép. Nếu bạn bỏ quên dấu ngoặc hoặc dùng sai, chuỗi Jinja2 truyền vào engine có thể bị cắt ngắn hoặc bị méo.

# Có thể gây lỗi
- name: Dấu ngoặc không đúng
  shell: echo {{ my_var }

Cách sửa: Luôn đặt biểu thức Jinja2 trong dấu ngoặc kép khi chúng đứng đầu một giá trị.

- name: Dấu ngoặc đúng cách
  shell: "echo {{ my_var }}"

4. Cú pháp từ điển bên trong biểu thức

Nếu bạn đang cố truy cập khóa của từ điển hoặc định nghĩa từ điển ngay trong biểu thức, việc thiếu dấu hai chấm hoặc dấu ngoặc sẽ gây ra lỗi này.

# Lỗi nếu quên dấu hai chấm trong dict
- name: Truy cập dict bị lỗi
  ansible.builtin.set_fact:
    config: "{{ {'port' 8080} }}"  # Thiếu dấu hai chấm sau 'port'

Các bước xác minh

Để xác nhận đã sửa xong, hãy chạy playbook với cờ kiểm tra cú pháp. Cách này nhanh hơn chạy toàn bộ quá trình triển khai.

ansible-playbook my_playbook.yml --syntax-check

Nếu kiểm tra cú pháp thành công, hãy dùng module debug để xác minh biểu thức được render đúng:

- name: Debug sau khi sửa
  ansible.builtin.debug:
    msg: "Biến có giá trị: {{ myvar }}"

Mẹo phòng tránh lỗi

  • Dùng extension cho IDE: VS Code với extension "Ansible" hoặc "Jinja2" sẽ tô đỏ các dấu ngoặc nhọn không khớp.
  • Khoảng trắng giúp dễ đọc hơn: Dùng {{ variable }} thay vì {{variable}}. Cách này giúp bạn dễ phát hiện dấu ngoặc bị thiếu ở cuối hơn nhiều.
  • Linter: Chạy ansible-lint. Công cụ này thường phát hiện các lỗi cú pháp cấp thấp như thế này trước khi bạn thử chạy code.

Related Error Notes