#ทดลองใช้ Ansible ด้วย VirtualBox: สร้าง Lab Automation 3 เครื่องแบบ Step-by-Step

Ansible เป็นเครื่องมือ IT Automation / Configuration Management แบบ Agentless ซึ่งเหมาะสำหรับการทดลองเรื่อง Infrastructure Automation, Server Provisioning และแนวคิด Infrastructure as Code (IaC) โดยไม่จำเป็นต้องติดตั้ง Agent ของ Ansible บนเครื่องปลายทาง

บทความนี้จะสร้าง Lab บน Oracle VirtualBox จำนวน 3 Virtual Machines เพื่อทดลองควบคุม Linux Server จาก Ansible Control Node ผ่าน SSH

#สิ่งที่จะได้จาก Lab นี้

เมื่อจบบทความ เราจะสามารถ:

  1. สร้าง Ubuntu Server 3 เครื่องบน VirtualBox
  2. สร้างเครือข่ายสำหรับ Lab ด้วย Host-only Network
  3. กำหนด Static IP ให้แต่ละเครื่อง
  4. ติดตั้ง Ansible บน Control Node
  5. สร้าง SSH Key และเชื่อมต่อแบบไม่ใช้ Password
  6. สร้าง Ansible Inventory
  7. ทดสอบ ansible ping
  8. ใช้ Ad-hoc Command
  9. เขียน Ansible Playbook
  10. ใช้ Playbook ติดตั้งและเปิดใช้งาน Nginx บนหลายเครื่องพร้อมกัน

info-ansible-virtualbox-lab-automation-3-step-by-step


#1. สถาปัตยกรรมของ Lab

ใช้ Virtual Machine 3 เครื่องดังนี้

เครื่อง บทบาท IP Address
ansible-control Ansible Control Node 192.168.56.10
web01 Managed Node 192.168.56.11
web02 Managed Node 192.168.56.12

โครงสร้างโดยรวม:

                  Host Computer
               Windows/macOS/Linux
                       |
                  VirtualBox
                       |
              Host-only Network
                192.168.56.0/24
                       |
        +--------------+--------------+
        |              |              |
        v              v              v
 ansible-control     web01           web02
 192.168.56.10   192.168.56.11  192.168.56.12
      |               |               |
   Ansible          Ubuntu          Ubuntu
      |
      +---------- SSH -----------> Managed Nodes

Ansible เป็น Agentless ดังนั้น web01 และ web02 ไม่จำเป็นต้องติดตั้ง Ansible แต่ต้องสามารถรับการเชื่อมต่อ SSH และโดยทั่วไปต้องมี Python สำหรับ Ansible modules


#2. Software ที่ต้องใช้

แนะนำให้เตรียม:

  • Oracle VirtualBox
  • Ubuntu Server LTS ISO
  • RAM อย่างน้อย 8 GB สำหรับเครื่อง Host จะใช้งาน Lab ได้สะดวกกว่า
  • Disk ว่างประมาณ 30–50 GB

ตัวอย่างการจัดสรร VM:

VM CPU RAM Disk
ansible-control 2 vCPU 2 GB 15 GB
web01 1 vCPU 1–2 GB 10 GB
web02 1 vCPU 1–2 GB 10 GB

สามารถลดทรัพยากรได้ตามความสามารถของเครื่อง Host


#3. สร้าง Virtual Machine

สร้าง Ubuntu Server VM เครื่องแรกชื่อ:

ansible-control

จากนั้นสร้างอีก 2 เครื่อง:

web01
web02

วิธีที่รวดเร็วคือสร้าง VM ต้นแบบหนึ่งเครื่อง ติดตั้ง Ubuntu ให้เรียบร้อย แล้วใช้ VirtualBox Clone เพื่อสร้างอีกสองเครื่อง

หาก Clone VM ควรเปลี่ยน Hostname และตรวจสอบ Network Configuration ของแต่ละเครื่องไม่ให้ใช้ IP ซ้ำกัน


#4. ตั้งค่า Network ใน VirtualBox

เพื่อให้ VM ใช้อินเทอร์เน็ตได้และสามารถสื่อสารกันภายใน Lab ได้ง่าย แนะนำให้ใช้ Network Adapter 2 ตัว

#Adapter 1 — NAT

ใช้สำหรับ:

  • ออกอินเทอร์เน็ต
  • apt update
  • ดาวน์โหลด package

ตั้งค่า:

Attached to: NAT

#Adapter 2 — Host-only Adapter

ใช้สำหรับ:

  • Ansible Control Node ติดต่อ Managed Nodes
  • SSH
  • การทดสอบระบบภายใน Lab

ตัวอย่าง Network:

192.168.56.0/24

ไปที่การตั้งค่าของ VM แต่ละเครื่อง:

Settings
  -> Network
     -> Adapter 1: NAT
     -> Adapter 2: Host-only Adapter

VirtualBox รองรับ network mode หลายประเภท เช่น NAT, NAT Network, Bridged, Internal Network และ Host-only Network การใช้ Host-only เหมาะกับ Lab ที่ต้องการให้ Host และ VM สื่อสารกันโดยไม่เปิดเครื่องทดลองออกสู่ LAN ภายนอกโดยตรง


#5. ตรวจสอบชื่อ Network Interface

หลังเปิด Ubuntu Server ให้ใช้คำสั่ง:

ip addr

หรือ

ip a

อาจพบ interface เช่น:

enp0s3
enp0s8

โดยทั่วไป:

enp0s3 = NAT
enp0s8 = Host-only

แต่ชื่อ interface อาจแตกต่างกันในแต่ละระบบ จึงควรตรวจสอบจริงก่อนแก้ไข Network Configuration


#6. ตั้งค่า Static IP

ตัวอย่างสำหรับ Ubuntu Server ที่ใช้ Netplan

ตรวจสอบไฟล์:

ls /etc/netplan/

เช่น:

50-cloud-init.yaml

#ansible-control

แก้ไข:

sudo nano /etc/netplan/50-cloud-init.yaml

ตัวอย่าง:

network:
  version: 2
  ethernets:
    enp0s3:
      dhcp4: true

    enp0s8:
      dhcp4: false
      addresses:
        - 192.168.56.10/24

ใช้ configuration:

sudo netplan apply

#web01

กำหนด:

192.168.56.11/24

ตัวอย่าง:

network:
  version: 2
  ethernets:
    enp0s3:
      dhcp4: true

    enp0s8:
      dhcp4: false
      addresses:
        - 192.168.56.11/24

#web02

กำหนด:

192.168.56.12/24

หลังแก้ไขทุกเครื่องให้ใช้:

sudo netplan apply

#7. เปลี่ยน Hostname

#Control Node

sudo hostnamectl set-hostname ansible-control

#web01

sudo hostnamectl set-hostname web01

#web02

sudo hostnamectl set-hostname web02

ตรวจสอบ:

hostname

#8. ทดสอบ Network

จาก ansible-control:

ping -c 4 192.168.56.11

และ:

ping -c 4 192.168.56.12

หากได้ response แสดงว่า network ระหว่าง VM ทำงานแล้ว


#9. เตรียม Managed Nodes สำหรับ SSH

บน web01 และ web02 ติดตั้ง OpenSSH Server:

sudo apt update
sudo apt install openssh-server -y

ตรวจสอบ:

sudo systemctl status ssh

หากยังไม่ทำงาน:

sudo systemctl enable --now ssh

ตรวจสอบ IP:

ip a

#10. สร้าง User สำหรับ Ansible

ตัวอย่างนี้ใช้ user ชื่อ:

ansible

บน web01 และ web02:

sudo adduser ansible

เพิ่มสิทธิ์ sudo:

sudo usermod -aG sudo ansible

ตรวจสอบ:

groups ansible

ควรเห็น:

ansible sudo

#11. ติดตั้ง Ansible บน Control Node

Ansible ใช้แนวคิด Control Node และ Managed Nodes โดย Control Node เป็นเครื่องที่ติดตั้ง Ansible และส่งคำสั่งไปยังเครื่องปลายทาง

ตัวอย่างบน Ubuntu:

sudo apt update
sudo apt install ansible -y

ตรวจสอบ:

ansible --version

อีกแนวทางตามเอกสาร Ansible ปัจจุบันคือการติดตั้งด้วย pipx เช่น:

pipx install --include-deps ansible

สำหรับ Lab บน Ubuntu การใช้ package manager เหมาะกับการเริ่มต้นและดูแลได้ง่าย ส่วน production environment ควรกำหนดเวอร์ชันที่ต้องการใช้งานอย่างชัดเจน


#12. สร้าง SSH Key

บน ansible-control:

ssh-keygen -t ed25519

สามารถกด Enter เพื่อใช้ path เริ่มต้น:

~/.ssh/id_ed25519

Public Key อยู่ที่:

~/.ssh/id_ed25519.pub

#13. Copy SSH Key ไป Managed Nodes

ส่ง key ไป web01:

ssh-copy-id ansible@192.168.56.11

ส่ง key ไป web02:

ssh-copy-id ansible@192.168.56.12

ทดสอบ:

ssh ansible@192.168.56.11

และ:

ssh ansible@192.168.56.12

หากสามารถ login โดยไม่ถาม password ของ SSH account แสดงว่า Public Key Authentication ทำงานแล้ว


#14. สร้าง Ansible Project

บน Control Node:

mkdir -p ~/ansible-lab
cd ~/ansible-lab

สร้าง Inventory:

nano inventory.ini

เพิ่ม:

[webservers]
web01 ansible_host=192.168.56.11
web02 ansible_host=192.168.56.12

[webservers:vars]
ansible_user=ansible

โครงสร้าง:

ansible-lab/
└── inventory.ini

Inventory คือรายการ Managed Nodes ที่ Ansible จะจัดการ และสามารถจัดกลุ่มเครื่องตามบทบาท เช่น webservers, dbservers, development หรือ production


#15. ตรวจสอบ Inventory

ใช้:

ansible-inventory -i inventory.ini --list

หรือ:

ansible-inventory -i inventory.ini --graph

ตัวอย่าง:

@all:
  |--@ungrouped:
  |--@webservers:
  |  |--web01
  |  |--web02

#16. ทดลอง Ansible Ping

ใช้คำสั่ง:

ansible webservers -i inventory.ini -m ping

ผลลัพธ์ที่ต้องการ:

web01 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

web02 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

ansible.builtin.ping ไม่ใช่ ICMP ping แบบคำสั่ง ping แต่เป็นการทดสอบว่า Ansible สามารถ login และ execute module บน Managed Node ได้


#17. ทดลอง Ad-hoc Commands

#ดู Hostname

ansible webservers -i inventory.ini -m command -a "hostname"

#ดู Disk

ansible webservers -i inventory.ini -m command -a "df -h"

#ดู Memory

ansible webservers -i inventory.ini -m command -a "free -h"

#ดู Uptime

ansible webservers -i inventory.ini -m command -a "uptime"

#18. ใช้ Privilege Escalation

งานบางอย่างต้องใช้ sudo

ตัวอย่าง:

ansible webservers \
  -i inventory.ini \
  -m apt \
  -a "name=nginx state=present update_cache=yes" \
  --become \
  --ask-become-pass

ตัวเลือก:

--become

หมายถึงให้ Ansible ยกระดับสิทธิ์ เช่น sudo

และ:

--ask-become-pass

ใช้ถาม sudo password

ใน production ไม่ควรเก็บรหัสผ่านแบบ plain text ไว้ใน Inventory ควรใช้กลไก เช่น Ansible Vault หรือระบบ secret management ที่เหมาะสม


#19. สร้าง Ansible Playbook

สร้างไฟล์:

nano install-nginx.yml

เพิ่ม:

---
- name: Configure web servers
  hosts: webservers
  become: true

  tasks:
    - name: Update apt cache
      ansible.builtin.apt:
        update_cache: true

    - name: Install Nginx
      ansible.builtin.apt:
        name: nginx
        state: present

    - name: Start and enable Nginx
      ansible.builtin.service:
        name: nginx
        state: started
        enabled: true

รัน:

ansible-playbook \
  -i inventory.ini \
  install-nginx.yml \
  --ask-become-pass

#20. อ่านผลลัพธ์ Play Recap

ตัวอย่าง:

PLAY RECAP ********************************
web01 : ok=4 changed=2 unreachable=0 failed=0
web02 : ok=4 changed=2 unreachable=0 failed=0

ความหมาย:

ค่า ความหมาย
ok Task ทำงานสำเร็จ
changed มีการเปลี่ยนแปลงระบบ
unreachable ติดต่อ Host ไม่ได้
failed Task ล้มเหลว
skipped Task ถูกข้าม

#21. ทดสอบ Nginx

จาก Host Computer หรือ Control Node:

curl http://192.168.56.11

และ:

curl http://192.168.56.12

หาก Nginx ทำงานจะได้รับ HTML ของหน้า Welcome Page

หากเปิดจาก Web Browser ของเครื่อง Host:

http://192.168.56.11
http://192.168.56.12

#22. Deploy หน้าเว็บด้วย Ansible

สร้าง Playbook:

nano deploy-web.yml

ตัวอย่าง:

---
- name: Deploy sample web page
  hosts: webservers
  become: true

  tasks:
    - name: Install Nginx
      ansible.builtin.apt:
        name: nginx
        state: present
        update_cache: true

    - name: Create home page
      ansible.builtin.copy:
        dest: /var/www/html/index.html
        mode: "0644"
        content: |
          <!DOCTYPE html>
          <html>
          <head>
              <meta charset="UTF-8">
              <title>Ansible Lab</title>
          </head>
          <body>
              <h1>Deployed by Ansible</h1>
              <p>Server: {{ inventory_hostname }}</p>
          </body>
          </html>

    - name: Ensure Nginx is running
      ansible.builtin.service:
        name: nginx
        state: started
        enabled: true

รัน:

ansible-playbook \
  -i inventory.ini \
  deploy-web.yml \
  --ask-become-pass

จากนั้นเปิด:

http://192.168.56.11

และ:

http://192.168.56.12

หน้าเว็บแต่ละเครื่องจะระบุชื่อ Host ตาม Inventory


#23. ทดลอง Idempotency

หนึ่งในคุณสมบัติสำคัญของ Ansible คือ Idempotency

ทดลองรัน Playbook เดิมอีกครั้ง:

ansible-playbook \
  -i inventory.ini \
  deploy-web.yml \
  --ask-become-pass

หากสถานะของระบบตรงกับ Playbook อยู่แล้ว Task ส่วนใหญ่ควรไม่จำเป็นต้องเปลี่ยนแปลงระบบ

แนวคิดคือ:

Desired State == Current State
             |
             v
        No Change

ต่างจากการเขียน Shell Script แบบ imperative ที่มักสั่งดำเนินการตามลำดับโดยตรง


#24. เพิ่ม ansible.cfg

เพื่อไม่ต้องระบุ Inventory ทุกครั้ง สามารถสร้าง:

nano ansible.cfg

ตัวอย่าง:

[defaults]
inventory = ./inventory.ini
host_key_checking = False
interpreter_python = auto_silent

หลังจากนั้นสามารถใช้:

ansible webservers -m ping

แทน:

ansible webservers -i inventory.ini -m ping

การปิด host_key_checking สะดวกสำหรับ Lab แต่ไม่ควรใช้แบบไม่พิจารณาใน production เพราะ SSH host key verification มีหน้าที่ช่วยตรวจสอบตัวตนของเครื่องปลายทาง


#25. โครงสร้าง Project ที่แนะนำ

เมื่อ Lab เริ่มใหญ่ขึ้น:

ansible-lab/
├── ansible.cfg
├── inventory.ini
├── install-nginx.yml
├── deploy-web.yml
├── group_vars/
│   └── webservers.yml
├── host_vars/
│   ├── web01.yml
│   └── web02.yml
└── roles/

ต่อไปสามารถพัฒนาไปสู่ Ansible Roles ได้


#26. Workflow ของ Ansible Lab

Developer / DevOps
       |
       v
Ansible Playbook
       |
       v
Control Node
192.168.56.10
       |
       | SSH
       |
  +----+----+
  |         |
  v         v
web01     web02
.11       .12
  |         |
  +----+----+
       |
       v
Desired Configuration

#27. Lab Exercise เพิ่มเติม

หลังจากติดตั้ง Nginx แล้ว สามารถทดลองเพิ่มหัวข้อดังนี้

#Exercise 1 — Install Common Packages

ติดตั้งพร้อมกัน:

git
curl
htop
unzip

#Exercise 2 — User Management

สร้าง user:

developer

พร้อม SSH Public Key

#Exercise 3 — Deploy Application

Deploy:

  • Static HTML
  • Node.js
  • Laravel
  • Spring Boot

#Exercise 4 — Install Docker

สร้าง Playbook สำหรับ:

Docker Engine
Docker Compose Plugin

#Exercise 5 — Docker Deployment

ใช้ Ansible:

Git Clone
   ↓
Docker Compose
   ↓
Application Deployment

#Exercise 6 — Ansible Roles

แยก configuration เป็น:

roles/
├── common/
├── nginx/
└── docker/

#28. Troubleshooting

#Problem: UNREACHABLE

ตัวอย่าง:

Failed to connect to the host via ssh

ตรวจสอบ:

ping 192.168.56.11

และ:

ssh ansible@192.168.56.11

#Problem: Permission denied

ตรวจสอบ SSH Key:

ssh-copy-id ansible@192.168.56.11

ตรวจสอบ Public Key:

cat ~/.ssh/id_ed25519.pub

#Problem: sudo password required

ใช้:

ansible-playbook playbook.yml --ask-become-pass

#Problem: Python not found

ตรวจสอบบน Managed Node:

python3 --version

หากไม่มี:

sudo apt install python3 -y

#Problem: VM ติดต่อกันไม่ได้

ตรวจสอบ:

ip a

จากนั้นตรวจสอบว่า Adapter 2 ของทั้ง 3 VM เชื่อมกับ Host-only Network เดียวกัน


#29. แนวทางนำไปต่อยอด

VirtualBox Lab เป็นจุดเริ่มต้นที่ดีเพราะสามารถจำลอง server หลายเครื่องได้โดยไม่ต้องเช่า Cloud Server

หลังจากเข้าใจพื้นฐาน สามารถนำ Playbook เดิมไปปรับใช้กับ:

  • DigitalOcean Droplets
  • AWS EC2
  • Google Compute Engine
  • Azure Virtual Machines
  • Private Cloud
  • On-premises Linux Servers

แนวคิดการทำงานแทบเหมือนเดิม:

Inventory
   +
Playbook
   +
SSH
   ↓
Automated Infrastructure

#30. สรุป

Lab นี้จำลองโครงสร้าง Ansible ที่ใกล้เคียงการใช้งานจริงในระดับพื้นฐาน:

VirtualBox
   |
   +-- ansible-control
   |
   +-- web01
   |
   +-- web02

โดย Ansible Control Node ใช้ SSH ไปจัดการ Managed Nodes และสามารถสั่งงานหลายเครื่องด้วยคำสั่งหรือ Playbook ชุดเดียว

หัวใจสำคัญที่ควรเข้าใจจาก Lab นี้คือ:

  • Control Node — เครื่องที่ติดตั้งและรัน Ansible
  • Managed Node — เครื่องที่ Ansible เข้าไปจัดการ
  • Inventory — รายการและการจัดกลุ่ม Managed Nodes
  • Module — หน่วยคำสั่งที่ Ansible ใช้ทำงาน
  • Playbook — Desired State ที่เขียนด้วย YAML
  • SSH — ช่องทางหลักในการจัดการ Linux Managed Nodes
  • Idempotency — รันซ้ำได้โดยไม่สร้างการเปลี่ยนแปลงที่ไม่จำเป็น

เมื่อเข้าใจ Lab นี้แล้ว ขั้นต่อไปที่เหมาะสมคือ Ansible Roles + Docker + Deployment Pipeline ซึ่งจะเชื่อมแนวคิด Configuration Management เข้ากับ DevOps และ CI/CD ได้ชัดเจนมากขึ้น


#Quick Command Reference

# ตรวจสอบ Ansible
ansible --version

# ตรวจสอบ inventory
ansible-inventory -i inventory.ini --graph

# ทดสอบ node
ansible webservers -i inventory.ini -m ping

# ดู hostname
ansible webservers -i inventory.ini -m command -a "hostname"

# ดู disk
ansible webservers -i inventory.ini -m command -a "df -h"

# รัน playbook
ansible-playbook -i inventory.ini install-nginx.yml --ask-become-pass

# Deploy web
ansible-playbook -i inventory.ini deploy-web.yml --ask-become-pass

#References