Fix lỗi Ansible 'Missing sudo password' (fatal: FAILED! msg: Missing sudo password)

beginner🔧 Ansible2026-03-18| Ansible 2.9+, Ubuntu/Debian/RHEL/CentOS, bất kỳ remote host nào yêu cầu mật khẩu sudo để leo thang đặc quyền

Error Message

fatal: [host]: FAILED! => {"msg": "Missing sudo password"}
#ansible#sudo#become#permission

Mô tả lỗi

Playbook của bạn đã có become: true. SSH kết nối bình thường. Rồi dòng này xuất hiện trên terminal:

fatal: [host]: FAILED! => {"msg": "Missing sudo password"}

Play dừng hẳn. Ansible đã kết nối tới host, xác thực qua SSH xong, rồi bị chặn — sudo yêu cầu mật khẩu nhưng Ansible không có gì để cung cấp.

Lưu ý: đây không phải lỗi kết nối. SSH đang hoạt động tốt. Remote user tồn tại. Vấn đề cụ thể là tài khoản này cần mật khẩu để leo thang lên root, và Ansible không biết mật khẩu đó là gì.

Nguyên nhân

Khi một task chạy với become: true, Ansible gọi sudo (hoặc bất kỳ become_method nào bạn đã cấu hình) trên remote host. Nếu user đó không thuộc nhóm sudoers NOPASSWD, sudo sẽ hỏi mật khẩu.

Ansible có thể cung cấp mật khẩu — nhưng chỉ khi bạn cho nó biết mật khẩu là gì. Nếu không có ansible_become_pass, Ansible truyền chuỗi rỗng. Sudo từ chối. Lỗi phát sinh.

Bạn thường gặp lỗi này trong các tình huống sau:

  • Thêm host mới mà remote user có sudo thông thường, không phải passwordless
  • Hardening bảo mật đã xóa NOPASSWD khỏi sudoers trên các host hiện tại
  • Playbook chạy tốt ở local nhưng fail trong CI — không có mật khẩu được truyền qua pipeline
  • Deploy với service account yêu cầu mật khẩu sudo

Sửa nhanh: Nhập mật khẩu tại runtime

Cần giải quyết ngay? Yêu cầu Ansible hỏi mật khẩu become trước khi chạy:

ansible-playbook site.yml -i inventory --ask-become-pass

Bạn sẽ được hỏi một lần, và mật khẩu đó áp dụng cho tất cả host trong lần chạy. Phù hợp cho thực thi một lần hoặc kiểm thử tương tác. Dạng rút gọn là -K:

ansible-playbook site.yml -i inventory -K

Kiểm tra kết quả: Chạy thử nhanh với inventory của bạn:

ansible all -i inventory -m command -a "whoami" --become -K

Kết quả mong đợi: root cho mỗi host. Nếu thấy vậy, leo thang đặc quyền đang hoạt động đúng.

Sửa vĩnh viễn 1: Đặt become_pass trong Inventory

Với lab cá nhân hoặc môi trường không phải production, bạn có thể khai báo mật khẩu become trực tiếp trong inventory. Cấu hình theo từng host trong inventory/hosts.ini:

[webservers]
192.168.1.10 ansible_user=deploy ansible_become_pass=matkhaucuaban
192.168.1.11 ansible_user=deploy ansible_become_pass=matkhaucuaban

Hoặc đặt là biến nhóm trong inventory/group_vars/webservers.yml:

ansible_user: deploy
ansible_become_pass: matkhaucuaban

Quy tắc bắt buộc: không commit mật khẩu plaintext lên Git. Cách này chỉ chấp nhận được với thông tin xác thực tạm thời trong môi trường dev local. Bất cứ thứ gì liên quan đến server thật cần dùng Vault — xem Cách 2 bên dưới.

Sửa vĩnh viễn 2: Mã hóa bằng Ansible Vault

Với môi trường production, đây là cách làm đúng đắn. Mã hóa mật khẩu become bằng Ansible Vault để có thể lưu vào version control mà không lộ bí mật.

Bước 1: Tạo file vars được mã hóa

ansible-vault create group_vars/webservers/vault.yml

Thêm mật khẩu vào trong file:

vault_become_pass: "MatKhauSudoCuaBan"

Bước 2: Tham chiếu trong file vars thông thường

Trong group_vars/webservers/vars.yml:

ansible_become_pass: "{{ vault_become_pass }}"

Bước 3: Chạy với vault password

# Nhập mật khẩu lúc chạy (dùng tương tác)
ansible-playbook site.yml -i inventory --ask-vault-pass

# Dùng file mật khẩu (pipeline CI/CD)
ansible-playbook site.yml -i inventory --vault-password-file ~/.vault_pass

Kiểm tra cấu hình:

ansible-vault view group_vars/webservers/vault.yml

Nhập vault password khi được hỏi. Bạn sẽ thấy nội dung đã giải mã. Nếu thấy được, mọi thứ đã được kết nối đúng.

Sửa vĩnh viễn 3: Sudo không mật khẩu (khi chính sách cho phép)

Một số team cấp cho service account của Ansible quyền sudo không mật khẩu trên các host được quản lý. Cách này loại bỏ hoàn toàn vấn đề mật khẩu — không cần lưu thông tin xác thực, không cần nhập mật khẩu, không cần entry trong Vault.

Trên remote host, chỉnh sửa sudoers an toàn bằng visudo:

sudo visudo -f /etc/sudoers.d/ansible

Cấp quyền đầy đủ cho user deploy:

deploy ALL=(ALL) NOPASSWD: ALL

Hoặc giới hạn ở các lệnh cụ thể nếu chính sách bảo mật yêu cầu:

deploy ALL=(ALL) NOPASSWD: /usr/bin/apt, /usr/bin/systemctl

Sau khi cấu hình xong, xóa ansible_become_pass khỏi vars và kiểm tra:

ansible all -i inventory -m command -a "whoami" --become

Kết quả phải là root — không hỏi mật khẩu, không có lỗi.

Kiểm tra cấu hình become

Không chắc become được đặt ở đâu trong stack playbook của bạn? Bắt đầu từ đây:

# Tìm tất cả tham chiếu become
grep -r "become" site.yml roles/

# Kiểm tra become_method đang dùng
ansible-config dump | grep BECOME

Một playbook tối giản có become:

---
- hosts: webservers
  become: true
  become_method: sudo   # mặc định — có thể bỏ qua
  tasks:
    - name: Cài đặt nginx
      apt:
        name: nginx
        state: present

Mẹo hay

Với mật khẩu của service account Ansible, đừng dùng mật khẩu dễ nhớ. Hãy tạo mật khẩu ngẫu nhiên 32 ký tự — loại bạn sẽ không bao giờ gõ tay. Password Generator trên ToolCraft chạy hoàn toàn trên trình duyệt, không gửi dữ liệu lên server nào, nên an toàn để tạo thông tin xác thực cho service. Lưu kết quả vào Ansible Vault là xong.

Đang quản lý quyền file trong các playbook có dùng become? Unix Permissions Calculator trên cùng trang đó giúp bạn tính giá trị chmod đúng mà không cần thử đi thử lại.

Tóm tắt

  • Chạy một lần: dùng -K hoặc --ask-become-pass
  • Team/production: mã hóa ansible_become_pass bằng Ansible Vault
  • Service account: cấu hình NOPASSWD trong sudoers cho Ansible user
  • Không bao giờ commit mật khẩu plaintext lên version control

Related Error Notes