- Tác giả

- Name
- Nguyễn Đức Xinh
- Ngày xuất bản
- Ngày xuất bản
Ansible Vault: Hướng dẫn bảo mật Secrets và quản lý mật khẩu trong Automation - Part 1
Giới Thiệu
Khi làm việc với Ansible, bạn thường xuyên phải lưu trữ thông tin nhạy cảm như:
- Database passwords
- API keys và tokens
- SSH private keys
- SSL certificates
- Cloud credentials (AWS, Azure, GCP)
Ansible Vault giúp bạn mã hóa các thông tin này một cách an toàn ngay trong Git repository.
Trong bài học này, bạn sẽ học:
- Cách encrypt/decrypt files và variables
- Quản lý vault passwords
- Best practices cho production
- Integration với CI/CD
Tại Sao Cần Ansible Vault?
❌ Vấn Đề: Plain Text Secrets
# vars/database.yml - NGUY HIỂM!
db_host: prod-mysql.example.com
db_user: admin
db_password: SuperSecret123! # ← Ai cũng thấy được
api_key: sk-1234567890abcdef # ← Lộ trên Git
Hậu quả:
- Ai có access Git repository đều thấy passwords
- Secrets bị lộ trong Git history
- Vi phạm security compliance
- Rủi ro bị tấn công
✅ Giải Pháp: Ansible Vault
# vars/database.yml - ĐÃ MÃ HÓA
$ANSIBLE_VAULT;1.1;AES256
66386439653231363937303466326534643938316334363761623566633038366235373334613934
6231373537346435643538386264613961633738356265380a666437343932383264633831326437
37373435326634323564346365633866643837653565393037313239333464613736343636343965
3736346338353264300a356531356634383735343031363937653565363261386665303666333632
6234
Chỉ người có vault password mới decrypt được!
Các Lệnh Cơ Bản
1. Encrypt File
# Mã hóa toàn bộ file
ansible-vault encrypt vars/secrets.yml
# Sẽ hỏi password 2 lần
New Vault password:
Confirm New Vault password:
Encryption successful
2. View Encrypted File
# Xem nội dung file đã mã hóa
ansible-vault view vars/secrets.yml
# Nhập password để xem
Vault password:
db_password: SuperSecret123!
api_key: sk-1234567890abcdef
3. Edit Encrypted File
# Sửa file đã mã hóa (mở editor)
ansible-vault edit vars/secrets.yml
# File sẽ được decrypt tạm thời, sau khi save sẽ encrypt lại
4. Decrypt File
# Giải mã file về plain text
ansible-vault decrypt vars/secrets.yml
# CHÚ Ý: Cẩn thận khi commit sau khi decrypt!
5. Rekey - Đổi Password
# Thay đổi vault password
ansible-vault rekey vars/secrets.yml
Vault password: [old password]
New Vault password: [new password]
Confirm New Vault password: [new password]
Rekey successful
Encrypt String - Inline Encryption
Thay vì mã hóa cả file, bạn có thể mã hóa từng biến:
# Mã hóa một string
ansible-vault encrypt_string 'SuperSecret123!' --name 'db_password'
Output:
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
66386439653231363937303466326534643938316334363761623566633038366235373334613934
6231373537346435643538386264613961633738356265380a666437343932383264633831326437
37373435326634323564346365633866643837653565393037313239333464613736343636343965
3736346338353264300a356531356634383735343031363937653565363261386665303666333632
6234
Ví Dụ Thực Tế
# Encrypt database password
ansible-vault encrypt_string 'MyDBPass456' --name 'db_password' >> vars/database.yml
# Encrypt API key
ansible-vault encrypt_string 'sk-abc123xyz' --name 'api_key' >> vars/api.yml
File vars/database.yml:
# Các biến bình thường
db_host: mysql.example.com
db_port: 3306
db_name: production
# Biến đã mã hóa
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
66386439653231363937303466326534643938316334363761623566633038366235373334613934
6231373537346435643538386264613961633738356265380a666437343932383264633831326437
37373435326634323564346365633866643837653565393037313239333464613736343636343965
3736346338353264300a356531356634383735343031363937653565363261386665303666333632
6234
Lợi ích: Chỉ secret được mã hóa, các biến khác vẫn readable!
Chạy Playbook Với Vault
Cách 1: Nhập Password Mỗi Lần
ansible-playbook deploy.yml --ask-vault-pass
Sẽ hỏi password mỗi khi chạy:
Vault password:
Cách 2: Password File
Tạo file chứa password:
# Tạo password file
echo 'MyVaultPassword123' > ~/.vault_pass.txt
# Phân quyền bảo mật
chmod 600 ~/.vault_pass.txt
Chạy playbook:
ansible-playbook deploy.yml --vault-password-file ~/.vault_pass.txt
Cách 3: Cấu Hình ansible.cfg
# ansible.cfg
[defaults]
vault_password_file = ~/.vault_pass.txt
Bây giờ chạy bình thường:
ansible-playbook deploy.yml
# Không cần --vault-password-file
Cách 4: Environment Variable
export ANSIBLE_VAULT_PASSWORD_FILE=~/.vault_pass.txt
ansible-playbook deploy.yml
Multiple Vault IDs - Nhiều Vault Passwords
Trong thực tế, bạn có thể cần nhiều passwords cho các môi trường khác nhau.
Scenario
- dev environment: dev vault password
- staging environment: staging vault password
- production environment: production vault password
Tạo Encrypted Files Với Vault ID
# Encrypt file cho dev
ansible-vault encrypt vars/dev_secrets.yml --encrypt-vault-id dev
# Encrypt file cho prod
ansible-vault encrypt vars/prod_secrets.yml --encrypt-vault-id prod
Tạo Vault Password Files
# ~/.vault_passwords/dev.txt
DevVaultPass123
# ~/.vault_passwords/prod.txt
ProdVaultPass789
Chạy Playbook Với Multiple Vault IDs
ansible-playbook deploy.yml \
--vault-id dev@~/.vault_passwords/dev.txt \
--vault-id prod@~/.vault_passwords/prod.txt
Cấu Hình ansible.cfg
[defaults]
vault_identity_list = dev@~/.vault_passwords/dev.txt, prod@~/.vault_passwords/prod.txt
Vault Password Scripts
Thay vì lưu password trong file, bạn có thể dùng script để lấy password từ secret manager.
Script Lấy Password Từ AWS Secrets Manager
#!/bin/bash
# ~/.vault_scripts/aws_secrets.sh
aws secretsmanager get-secret-value \
--secret-id ansible-vault-password \
--query SecretString \
--output text
Phân quyền:
chmod +x ~/.vault_scripts/aws_secrets.sh
Sử dụng:
ansible-playbook deploy.yml --vault-password-file ~/.vault_scripts/aws_secrets.sh
Script Lấy Password Từ HashiCorp Vault
#!/bin/bash
# ~/.vault_scripts/hashicorp_vault.sh
vault kv get -field=password secret/ansible/vault
Thực Hành: Deploy WordPress Với Vault
Bước 1: Tạo Project Structure
wordpress-deploy/
├── ansible.cfg
├── inventory.yml
├── deploy.yml
├── vars/
│ ├── common.yml
│ └── secrets.yml (encrypted)
└── roles/
├── mysql/
└── wordpress/
Bước 2: Tạo Secrets File
# Tạo file secrets
cat > vars/secrets.yml << EOF
---
# Database credentials
mysql_root_password: RootPass123!
mysql_wordpress_password: WPPass456!
# WordPress admin
wp_admin_user: admin
wp_admin_password: AdminPass789!
wp_admin_email: admin@example.com
# API Keys
sendgrid_api_key: SG.1234567890abcdef
cloudflare_api_key: cf_1234567890xyz
EOF
# Mã hóa file
ansible-vault encrypt vars/secrets.yml
Bước 3: Common Variables
# vars/common.yml (không mã hóa)
---
mysql_host: localhost
mysql_port: 3306
mysql_database: wordpress
wp_version: "6.4"
wp_site_url: "https://example.com"
wp_site_title: "My WordPress Site"
Bước 4: Playbook
# deploy.yml
---
- name: Deploy WordPress với MySQL
hosts: webservers
become: yes
vars_files:
- vars/common.yml
- vars/secrets.yml # File đã encrypt
tasks:
- name: Install MySQL Server
apt:
name: mysql-server
state: present
- name: Create WordPress database
mysql_db:
name: "{{ mysql_database }}"
state: present
login_unix_socket: /var/run/mysqld/mysqld.sock
- name: Create WordPress user
mysql_user:
name: wordpress
password: "{{ mysql_wordpress_password }}" # Từ vault
priv: "{{ mysql_database }}.*:ALL"
state: present
login_unix_socket: /var/run/mysqld/mysqld.sock
- name: Download WordPress
get_url:
url: "https://wordpress.org/wordpress-{{ wp_version }}.tar.gz"
dest: /tmp/wordpress.tar.gz
- name: Extract WordPress
unarchive:
src: /tmp/wordpress.tar.gz
dest: /var/www/html
remote_src: yes
- name: Configure wp-config.php
template:
src: templates/wp-config.php.j2
dest: /var/www/html/wordpress/wp-config.php
mode: '0640'
Bước 5: Template File
<!-- templates/wp-config.php.j2 -->
<?php
define('DB_NAME', '{{ mysql_database }}');
define('DB_USER', 'wordpress');
define('DB_PASSWORD', '{{ mysql_wordpress_password }}');
define('DB_HOST', '{{ mysql_host }}');
// Security keys - từ vault
define('AUTH_KEY', '{{ wp_auth_key | default("put your unique phrase here") }}');
define('SECURE_AUTH_KEY', '{{ wp_secure_auth_key | default("put your unique phrase here") }}');
?>
Bước 6: Chạy Deployment
# Chạy với vault password
ansible-playbook deploy.yml --ask-vault-pass
# Hoặc với password file
ansible-playbook deploy.yml --vault-password-file ~/.vault_pass.txt
Best Practices
1. Tách Secrets Ra File Riêng
✅ TỐT:
vars/
├── common.yml # Public variables
└── secrets.yml # Encrypted secrets
❌ KHÔNG TỐT:
vars/
└── all.yml # Mixed public + secrets
2. Git Ignore Plain Text Passwords
# .gitignore
*.vault_pass.txt
.vault_pass
vault-password.txt
*_decrypted.yml
3. Đặt Tên Biến Rõ Ràng
✅ TỐT:
db_password: !vault |...
api_key_production: !vault |...
ssl_certificate_password: !vault |...
❌ KHÔNG TỐT:
pass: !vault |...
key: !vault |...
secret: !vault |...
4. Encrypt Inline Thay Vì Whole File
✅ TỐT (dễ review changes):
# vars/database.yml
db_host: mysql.example.com # Plain text
db_port: 3306 # Plain text
db_password: !vault | # Chỉ secret mới encrypt
$ANSIBLE_VAULT;1.1;AES256
...
❌ KHÔNG TỐT (khó review):
# Toàn bộ file encrypted - không biết gì thay đổi
5. Rotate Passwords Định Kỳ
# Đổi vault password mỗi quý
ansible-vault rekey vars/secrets.yml
# Backup trước khi rekey
cp vars/secrets.yml vars/secrets.yml.backup
Tiếp tục phần sau...
