Ansible Vault: Quản Lý Bí Mật

K
Kai··4 min read

Mọi dự án thật đều có bí mật: mật khẩu database, khóa API, chứng chỉ. Nhưng playbook và biến thường đưa vào Git — và để bí mật trần trong Git là lỗi bảo mật nghiêm trọng (nhớ series Docker Bài 9 — không nhúng secret). Ansible Vault giải quyết: mã hóa bí mật ngay trong dự án, giải mã tự động lúc chạy.

Vấn đề và lời giải

Bạn có group_vars/web.yml chứa db_password: "SieuBiMat123!". Commit lên Git → ai xem repo cũng thấy mật khẩu. Tách secret ra môi trường thì khó quản lý phiên bản.

Ansible Vault mã hóa file/giá trị bằng AES256: file mã hóa vẫn nằm trong repo (an toàn để commit vì đã mã), Ansible giải mã trong bộ nhớ lúc chạy nếu bạn cung cấp vault password. Bí mật được version-control mà không lộ.

Mã hóa một file bí mật

Tạo file bí mật rồi mã hóa:

ansible-vault encrypt secrets.yml

(Nó hỏi và đặt một mật khẩu vault.) File sau khi mã hóa:

head -2 secrets.yml
$ANSIBLE_VAULT;1.1;AES256
65346263623637653437663938653262356666323362626432623136...

Dòng đầu $ANSIBLE_VAULT;1.1;AES256 là dấu hiệu file đã mã hóa Vault, phần dưới là dữ liệu mã hóa (hex). Nội dung gốc hoàn toàn không đọc được — an toàn để commit.

Làm việc với file đã mã hóa

ansible-vault view secrets.yml      # xem nội dung (giải mã ra màn hình, không sửa)
ansible-vault edit secrets.yml      # mở editor, sửa (tự giải mã rồi mã lại khi lưu)
ansible-vault decrypt secrets.yml   # giải mã VĨNH VIỄN ra file thường (cẩn thận!)
ansible-vault rekey secrets.yml     # đổi mật khẩu vault
ansible-vault create secrets.yml    # tạo mới file đã mã hóa luôn

view:

db_password: "SieuBiMat123!"
api_key: "sk-abc123xyz"

edit là lệnh hay dùng nhất: nó giải mã vào một file tạm, mở editor (Bài 4 series Linux), rồi mã lại khi bạn lưu — bạn không bao giờ thấy file giải mã trên đĩa.

encrypt_string: mã hóa một giá trị lẻ

Đôi khi bạn chỉ muốn mã hóa một biến, đặt nó cạnh các biến thường (không cần file riêng). Dùng encrypt_string:

ansible-vault encrypt_string "secret-token" --name "my_token"
my_token: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          32393835343465623936353162333664316233646337663261...

Dán khối !vault | ... này thẳng vào file YAML biến thường — chỉ giá trị đó được mã, các biến khác để rõ. Tiện khi đa số biến không nhạy cảm, chỉ vài cái cần giấu.

Dùng vaulted vars trong playbook

Vaulted file dùng như file biến thường (vars_files), chỉ cần cung cấp mật khẩu lúc chạy:

- hosts: web
  vars_files:
    - group_vars/web_secrets.yml      # file đã mã hóa
  tasks:
    - ansible.builtin.debug:
        msg: "db_password dài {{ db_password | length }} ký tự"

Chạy, cung cấp mật khẩu:

ansible-playbook vault-demo.yml --ask-vault-pass         # gõ mật khẩu tương tác
# hoặc:
ansible-playbook vault-demo.yml --vault-password-file .vault_pass   # đọc từ file
"msg": "db_password dài 13 ký tự"

Ansible tự giải mã web_secrets.yml trong bộ nhớ và db_password dùng được như biến thường. (Ở đây ta chỉ in độ dài để không lộ giá trị — thói quen tốt khi demo/log.)

Vault password: cung cấp thế nào

  • --ask-vault-pass — gõ mật khẩu mỗi lần chạy. An toàn nhất cho thao tác thủ công.
  • --vault-password-file <file> — đọc mật khẩu từ một file. Tiện cho tự động hóa/CI — nhưng file đó phải nằm ngoài Git (thêm vào .gitignore), quyền 600, và lý tưởng là sinh ra từ một secret manager lúc chạy.
  • Đặt sẵn trong ansible.cfg: vault_password_file = .vault_pass để khỏi gõ cờ.

Vault id (nâng cao): nhiều môi trường nhiều mật khẩu khác nhau — --vault-id prod@prompt --vault-id dev@dev-pass. Cho phép tách bí mật prod/dev với khóa riêng.

Best practices

  • Chỉ mã hóa thứ cần mã: tách bí mật vào group_vars/<nhóm>/vault.yml (mã hóa) và biến thường vào group_vars/<nhóm>/vars.yml (rõ). Để cả file biến thường bị mã hóa làm khó đọc/diff.
  • Mật khẩu vault KHÔNG vào Git: gitignore file password; không hard-code trong playbook.
  • Diff thân thiện: cấu hình git để hiện diff vaulted file (ansible-vault hỗ trợ), hoặc chấp nhận diff là dữ liệu mã hóa.
  • Cân nhắc secret manager ngoài: ở quy mô lớn, dùng HashiCorp Vault / AWS Secrets Manager (qua lookup plugin — Bài 12) thay vì lưu secret mã hóa trong repo. Ansible Vault hợp cho bí mật cấu hình tĩnh; secret manager hợp cho bí mật xoay vòng/động.

🧹 Dọn dẹp

File web_secrets.yml (đã mã hóa) an toàn để commit vào repo nghiadaulau/ansible-series thư mục 10-vault; file mật khẩu .vault_pass thì không (đã gitignore).

Tổng kết

Ansible Vault mã hóa bí mật bằng AES256 để version-control an toàn — file mã hóa ($ANSIBLE_VAULT;...) commit được, giải mã tự động lúc chạy. Thao tác: encrypt/view/edit/rekey, và encrypt_string cho giá trị lẻ. Dùng vaulted file như vars_files, cung cấp mật khẩu qua --ask-vault-pass hoặc --vault-password-file (file này phải ngoài Git). Best practice: tách bí mật khỏi biến thường, giữ mật khẩu vault an toàn, cân nhắc secret manager ngoài ở quy mô lớn.

Tới giờ ta dùng module có sẵn. Bài 11 là deep-dive thực thụ: tự viết một module bằng Python — hiểu được điều này thì bạn nắm trọn cơ chế Ansible từ Bài 1.