Ansible Vault เป็นฟีเจอร์ในตัวของ Ansible สำหรับเข้ารหัส sensitive data เช่น passwords, API keys, private keys และ database credentials — แทนที่จะเก็บข้อมูลเหล่านี้เป็น plain text ใน playbook หรือ inventory, Vault เข้ารหัสด้วย AES-256 ทำให้ commit ไว้ใน git ได้อย่างปลอดภัย
บทความนี้ครอบคลุมการสร้างและเข้ารหัสไฟล์ด้วย ansible-vault create และ encrypt, การเข้ารหัส string เดี่ยวด้วย encrypt_string, การใช้ vault password file และ password prompt, การ decrypt เพื่อดูข้อมูล และ pattern สำหรับ vault ใน production project
Ansible Vault คืออะไรและทำงานอย่างไร
Vault ใช้ AES-256-CBC encryption พร้อม PBKDF2 key derivation — ไฟล์ที่เข้ารหัสแล้วขึ้นต้นด้วย $ANSIBLE_VAULT; บอก Ansible ว่าต้อง decrypt ก่อนใช้งาน
# ตัวอย่างไฟล์ที่เข้ารหัสด้วย Vault
$ANSIBLE_VAULT;1.1;AES256
66386439653236336462626566653131623064656263353735303136
33626262396430383933353831346631623831656437656463643339
...
# Vault ทำงานได้กับ:
# - ไฟล์ทั้งไฟล์ (เช่น group_vars/all/vault.yml)
# - ตัวแปรเดี่ยวในไฟล์ YAML (inline encrypted string)
# - ไฟล์ทุกประเภท (binary, certs, keys)
# การทำงานเมื่อ run playbook:
# ansible-playbook site.yml --ask-vault-pass
# ansible-playbook site.yml --vault-password-file .vault_pass
สร้างและเข้ารหัสไฟล์ด้วย ansible-vault create
ansible-vault create เปิด text editor เพื่อให้เขียนเนื้อหา แล้วบันทึกเป็น encrypted file ทันที — เหมาะสำหรับสร้างไฟล์ vault ใหม่ที่เก็บ credentials หลายตัว
# สร้างไฟล์ vault ใหม่ (เปิด $EDITOR)
ansible-vault create group_vars/all/vault.yml
# เนื้อหาที่เขียนใน editor (plain text ก่อน encrypt):
---
vault_db_password: "MySecretPass123!"
vault_api_key: "sk-abc123xyz789"
vault_redis_password: "RedisSecret456"
vault_smtp_password: "MailSecret789"
vault_ssl_cert_key: |
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA...
-----END RSA PRIVATE KEY-----
# ผลลัพธ์: group_vars/all/vault.yml จะเป็น encrypted text
# เมื่อ save และออกจาก editor
# ดู structure ที่แนะนำ:
group_vars/
all/
main.yml # plain variables (references vault vars)
vault.yml # encrypted secrets
เข้ารหัสไฟล์ที่มีอยู่แล้ว
ansible-vault encrypt เข้ารหัสไฟล์ที่มีอยู่แล้ว — ใช้เมื่อมีไฟล์ plain text อยู่แล้วและต้องการ encrypt ก่อน commit ใน git
# เข้ารหัสไฟล์ที่มีอยู่
ansible-vault encrypt group_vars/production/secrets.yml
# เข้ารหัสหลายไฟล์พร้อมกัน
ansible-vault encrypt \
group_vars/production/secrets.yml \
host_vars/db01/credentials.yml \
files/ssl/private.key
# เข้ารหัสด้วย vault ID (สำหรับ multiple vault passwords)
ansible-vault encrypt --vault-id prod@prompt secrets.yml
# ตรวจสอบว่าไฟล์ถูกเข้ารหัสแล้ว
head -1 group_vars/production/secrets.yml
# Output: $ANSIBLE_VAULT;1.1;AES256
# ดูเนื้อหาที่เข้ารหัสโดยไม่ decrypt
cat group_vars/production/secrets.yml
เข้ารหัส String เดี่ยวด้วย encrypt_string
ansible-vault encrypt_string เข้ารหัสเฉพาะ string เดียวและได้ output ที่ใส่ inline ใน YAML file ได้ทันที — เหมาะสำหรับเมื่อต้องการเข้ารหัสแค่ค่าเดียวในไฟล์ที่เหลือเป็น plain text
# เข้ารหัส string เดี่ยว (จะ prompt ขอ vault password)
ansible-vault encrypt_string 'MySecretPass123!' --name 'db_password'
# Output ที่ได้:
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
66386439653236336462626566653131623064656263
35353032366162363138653234386334396536316239
...
# นำ output ไปใส่ใน variables file โดยตรง
# group_vars/all/main.yml:
---
app_name: myapp
app_port: 8080
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
66386439653236336462626566...
# เข้ารหัสหลาย strings ต่อเนื่อง
ansible-vault encrypt_string 'secret1' --name 'var1'
ansible-vault encrypt_string 'secret2' --name 'var2'
# Pipe ค่าเข้า (ไม่ต้อง type บน command line)
echo -n 'MySecretPass' | ansible-vault encrypt_string --stdin-name db_password
Vault Password: Prompt vs Password File
Ansible Vault รองรับ 2 วิธีหลักในการระบุ password — --ask-vault-pass สำหรับ interactive use, และ --vault-password-file สำหรับ automation และ CI/CD
# วิธีที่ 1: Prompt ขอ password ทุกครั้ง
ansible-playbook site.yml --ask-vault-pass
# วิธีที่ 2: อ่านจากไฟล์ (สำหรับ automation)
ansible-playbook site.yml --vault-password-file .vault_pass
# สร้าง vault password file
echo "MyVaultPassword" > .vault_pass
chmod 600 .vault_pass
# !!!สำคัญ: เพิ่ม .vault_pass ใน .gitignore เสมอ!!!
echo ".vault_pass" >> .gitignore
# กำหนด default ใน ansible.cfg เพื่อไม่ต้องระบุทุกครั้ง
# ansible.cfg:
[defaults]
vault_password_file = .vault_pass
# วิธีที่ 3: Script ที่ return password (สำหรับ secrets manager)
ansible-playbook site.yml --vault-password-file /opt/scripts/get_vault_pass.sh
# ตัวอย่าง script ดึงจาก environment variable:
#!/bin/bash
echo "$VAULT_PASSWORD"
Multiple Vault Passwords ด้วย Vault ID
Vault ID ช่วยแยก passwords สำหรับ environment ต่าง ๆ — เช่น production ใช้ password ต่างจาก staging โดย label ไว้ในตัว encrypted string เลย
# สร้างไฟล์ vault ด้วย vault ID
ansible-vault create --vault-id prod@prompt group_vars/production/vault.yml
ansible-vault create --vault-id staging@prompt group_vars/staging/vault.yml
# เข้ารหัส string ด้วย vault ID
ansible-vault encrypt_string --vault-id prod@prompt \
'ProdPassword!' --name db_password
# Output จะมี vault ID label:
db_password: !vault |
$ANSIBLE_VAULT;1.2;AES256;prod
...
# รัน playbook ที่มีหลาย vault IDs
ansible-playbook site.yml \
--vault-id [email protected]_pass_prod \
--vault-id [email protected]_pass_staging
# ใช้ prompt สำหรับบาง ID, file สำหรับบาง ID
ansible-playbook site.yml \
--vault-id prod@prompt \
--vault-id [email protected]_pass_dev
ดูและแก้ไขไฟล์ที่เข้ารหัส
ใช้ ansible-vault view ดูเนื้อหาโดยไม่บันทึกเป็น plain text, และ ansible-vault edit เปิด editor เพื่อแก้ไขโดยตรง — ทั้งสองคำสั่งไม่ decrypt ไฟล์ค้างไว้
# ดูเนื้อหาโดยไม่บันทึก plaintext
ansible-vault view group_vars/all/vault.yml
# แก้ไขโดยตรงใน editor
ansible-vault edit group_vars/all/vault.yml
# Decrypt ไฟล์ (สร้าง plaintext file) — ระวัง: ไม่ควรทำบน production
ansible-vault decrypt group_vars/all/vault.yml
# Re-encrypt หลังแก้ไข (ถ้า decrypt ไปแล้ว)
ansible-vault encrypt group_vars/all/vault.yml
# เปลี่ยน vault password (rekey)
ansible-vault rekey group_vars/all/vault.yml
# จะ prompt ขอ old password และ new password
# เปลี่ยน password โดยระบุทั้งสองใน command
ansible-vault rekey \
--vault-password-file .old_vault_pass \
--new-vault-password-file .new_vault_pass \
group_vars/all/vault.yml
Pattern: Vault ใน Production Project
โครงสร้างที่แนะนำสำหรับ production project — แยกไฟล์ vault ออกจาก plain variables, ใช้ naming convention ชัดเจน และอ้างอิง vault variables ใน main.yml แทนที่จะใช้ตรงจาก vault
# โครงสร้าง project พร้อม vault
myproject/
├── .gitignore # ต้องมี .vault_pass และ *.vault_pass*
├── .vault_pass # ห้าม commit! — เพิ่มใน .gitignore
├── ansible.cfg # vault_password_file = .vault_pass
├── site.yml
├── group_vars/
│ ├── all/
│ │ ├── main.yml # plain vars ที่ reference vault vars
│ │ └── vault.yml # encrypted secrets
│ └── production/
│ ├── main.yml
│ └── vault.yml # production-specific secrets
└── host_vars/
└── db01/
├── main.yml
└── vault.yml # host-specific credentials
# group_vars/all/vault.yml (encrypted — เนื้อหาก่อน encrypt)
---
vault_db_password: "ProdDBPass123!"
vault_app_secret_key: "long-random-secret-key-here"
vault_smtp_password: "SMTPpass456"
vault_api_token: "Bearer abc123xyz"
# group_vars/all/main.yml (plain text — reference vault vars)
---
app_name: myapp
app_port: 8080
# ตั้งชื่อโดยไม่มี vault_ prefix เพื่อ simplicity ใน tasks
db_password: "{{ vault_db_password }}"
app_secret_key: "{{ vault_app_secret_key }}"
smtp_password: "{{ vault_smtp_password }}"
api_token: "{{ vault_api_token }}"
# ใช้ตัวแปรใน task โดยตรง (ผ่าน main.yml reference)
---
- name: Configure application database
template:
src: database.conf.j2
dest: /etc/myapp/database.conf
mode: '0640'
# template ใช้ {{ db_password }} ซึ่งมาจาก main.yml → vault.yml
# ตัวอย่างใน template:
# templates/database.conf.j2:
# [database]
# host = {{ db_host }}
# password = {{ db_password }} ← ค่ามาจาก vault โดยอัตโนมัติ
# รัน playbook พร้อม vault
ansible-playbook site.yml --vault-password-file .vault_pass
# หรือถ้า set ansible.cfg แล้ว:
ansible-playbook site.yml
สรุป
Ansible Vault ให้วิธีเก็บ sensitive data ใน git อย่างปลอดภัยโดยใช้ AES-256 encryption — สร้างไฟล์ vault ด้วย create, เข้ารหัสไฟล์เดิมด้วย encrypt, เข้ารหัส string เดี่ยวด้วย encrypt_string และดูหรือแก้ไขด้วย view/edit
Pattern ที่ควรจำ: เพิ่ม .vault_pass ใน .gitignore เสมอ, ตั้งชื่อ vault variables ด้วย prefix vault_ และ reference ผ่าน group_vars/all/main.yml แทนการใช้ตรงจาก vault, ใช้ vault_password_file ใน ansible.cfg เพื่อไม่ต้อง type password ทุกครั้ง และใช้ encrypt_string เมื่อต้องการ encrypt แค่ค่าเดียวในไฟล์ที่เหลือเป็น plain text

