IaC Terraform Ansible DevOps

Infrastructure as Code — จัดการ Server ด้วย Terraform & Ansible

By Anirach Mingkhwan DevOps & Vibe Coding 2026
Infrastructure as Code — dog with Terraform and Ansible

จากโพสต์ที่แล้วเราเรียนรู้ Networking พื้นฐาน — DNS, Firewall, Load Balancer, SSH

แต่ลองนึกภาพว่าต้อง setup server 50 เครื่อง... จะ SSH เข้าไปตั้งค่าทีละเครื่องจริงเหรอ? 😰

นี่คือที่มาของ Infrastructure as Code (IaC) — เขียน code เพื่อสร้างและจัดการ infrastructure ทั้งหมด แทนที่จะทำด้วยมือ เหมือนเขียนสูตรอาหารแทนที่จะจำในหัว 📝🐕


IaC คืออะไร?

Infrastructure as Code คือแนวคิดที่ว่า — infrastructure (server, network, database, firewall) ควรถูก กำหนดด้วย code ไม่ใช่การคลิกบน console หรือพิมพ์คำสั่งทีละบรรทัด

ข้อดีของ IaC: repeatable (ทำซ้ำได้เหมือนเดิมทุกครั้ง), version controlled (เก็บใน Git ดู history ได้), reviewable (review infrastructure changes เหมือน code review), testable (ทดสอบก่อน apply ได้) — เปรียบเทียบก่อนและหลัง IaC:

ก่อน IaC (Manual) 😩

  1. Login เข้า AWS Console
  2. คลิก "Create EC2 Instance"
  3. เลือก Ubuntu, t3.medium, 50GB disk...
  4. SSH เข้าไปติดตั้ง Nginx, Node.js, PostgreSQL...
  5. ทำ 50 ครั้ง ❌

หลัง IaC (Automated) 🚀

  1. เขียน Terraform → สร้าง 50 servers
  2. เขียน Ansible → ติดตั้ง software ทั้ง 50 เครื่อง
  3. รัน 1 คำสั่ง ✅
💡 หลักการสำคัญ:
Repeatable — ทำซ้ำได้ผลเหมือนเดิมทุกครั้ง
Version-controlled — เก็บใน Git, ดู history ได้
Reviewable — ทีม review ก่อน apply
Testable — ทดสอบก่อน deploy ได้

Terraform vs Ansible — ใช้ตัวไหน?

คำตอบคือ ใช้ทั้งคู่! เพราะทำหน้าที่ต่างกัน — Terraform "สร้าง" infrastructure (VMs, networks, databases, load balancers) ส่วน Ansible "ตั้งค่า" สิ่งที่สร้างมา (install software, configure services, deploy apps) Terraform เป็น declarative (บอกว่า "ต้องการอะไร") Ansible เป็น procedural (บอกว่า "ทำอะไรทีละขั้น"):

📐 Terraform
สร้าง Infrastructure
⚙️ Ansible
ตั้งค่า Software
🚀 Production
พร้อมใช้งาน!
Feature Terraform Ansible
หน้าที่หลัก สร้าง/จัดการ infrastructure ตั้งค่า/ติดตั้ง software
ประเภท Provisioning tool Configuration Management tool
ภาษา HCL (HashiCorp Config Language) YAML (Playbooks)
วิธีทำงาน Declarative — บอก "ต้องการอะไร" Procedural + Declarative
State ✅ มี state file ติดตาม ❌ Agentless, ไม่มี state
ตัวอย่าง สร้าง EC2, VPC, RDS, S3 ติดตั้ง Nginx, Deploy app
Cloud Support AWS, GCP, Azure, DigitalOcean, +100 providers SSH เข้าเครื่องไหนก็ได้
💡 จำง่ายๆ: Terraform = สร้างเครื่อง | Ansible = ตั้งค่าเครื่อง

Terraform — สร้าง Infrastructure ด้วย Code

Terraform โดย HashiCorp เป็น IaC tool ที่ได้รับความนิยมสูงสุด — รองรับ cloud providers ทุกเจ้า (AWS, Azure, GCP, DigitalOcean, etc.) ด้วย provider plugins ใช้ภาษา HCL (HashiCorp Configuration Language) ที่อ่านง่าย และจัดการ state ของ infrastructure ให้อัตโนมัติ

Terraform ทำงานยังไง?

Terraform workflow มี 3 ขั้นตอนหลัก: Write (เขียน .tf files), Plan (ดูว่าจะเปลี่ยนอะไร — เหมือน dry run), Apply (สร้าง/แก้ infrastructure จริง) สิ่งสำคัญคือ terraform plan แสดง diff ก่อน apply เสมอ — ไม่มีเซอร์ไพรส์!

📝 Write
เขียน .tf files
📋 Plan
ดู preview การเปลี่ยนแปลง
🚀 Apply
สร้างจริง!
💾 State
บันทึกสถานะ

ตัวอย่าง: สร้าง AWS EC2 Instance

ตัวอย่าง main.tf ด้านล่างสร้าง EC2 instance บน AWS — สังเกตว่า HCL อ่านง่ายมาก: กำหนด provider (AWS, region), resource (instance type, AMI, security group), และ output (IP address) ทุกอย่างเป็น declarative:

# กำหนด provider (Cloud ที่จะใช้)
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "ap-southeast-1"    # Singapore
}

# สร้าง EC2 Instance
resource "aws_instance" "web_server" {
  ami           = "ami-0c55b159cbfafe1f0"   # Ubuntu 22.04
  instance_type = "t3.medium"

  tags = {
    Name        = "web-server-01"
    Environment = "production"
    ManagedBy   = "terraform"
  }

  # Security Group
  vpc_security_group_ids = [aws_security_group.web_sg.id]
}

# สร้าง Security Group
resource "aws_security_group" "web_sg" {
  name        = "web-sg"
  description = "Allow HTTP and SSH"

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]     # HTTP จากทุกที่
  }

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["10.0.0.0/8"]    # SSH จาก private network เท่านั้น
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

# Output — แสดง IP ที่ได้
output "server_ip" {
  value = aws_instance.web_server.public_ip
}
# Terraform commands
terraform init      # ดาวน์โหลด provider plugins
terraform plan      # ดู preview ว่าจะสร้างอะไร
terraform apply     # สร้างจริง! (ถาม yes/no)
terraform destroy   # ลบทั้งหมด (ระวัง!)

# ตัวอย่าง output ของ terraform plan:
# + aws_instance.web_server
#     ami:           "ami-0c55b159cbfafe1f0"
#     instance_type: "t3.medium"
#
# Plan: 2 to add, 0 to change, 0 to destroy.

Terraform สร้างหลายเครื่องพร้อมกัน

พลังของ IaC เห็นชัดเมื่อต้องสร้างหลายเครื่อง — แค่ใช้ count หรือ for_each ก็สร้าง 10, 50, 100 เครื่องได้ในคำสั่งเดียว ลองทำแบบ manual ดู!

# ใช้ count สร้าง 5 เครื่องรวด!
resource "aws_instance" "web_cluster" {
  count         = 5
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.medium"

  tags = {
    Name = "web-server-${count.index + 1}"
  }
}

# Output ทุก IP
output "server_ips" {
  value = aws_instance.web_cluster[*].public_ip
}
# → ["10.0.1.1", "10.0.1.2", "10.0.1.3", "10.0.1.4", "10.0.1.5"]

Ansible — ตั้งค่า Server อัตโนมัติ

Ansible โดย Red Hat เป็น configuration management tool ที่ใช้ง่ายที่สุด — เขียน playbooks ด้วย YAML ธรรมดา ไม่ต้องเรียนภาษาใหม่ เหมาะกับ: install packages, configure services, deploy applications, manage users/permissions

Ansible ทำงานยังไง?

Ansible เป็น agentless — ไม่ต้องติดตั้งอะไรบนเครื่องเป้าหมาย ใช้ SSH เข้าไปรันคำสั่งเลย! ต่างจาก Chef/Puppet ที่ต้องติดตั้ง agent บนทุกเครื่อง ทำให้ setup ง่ายและ maintain น้อยกว่า มี 2 ส่วนหลัก: Inventory (รายชื่อ servers) และ Playbook (สิ่งที่ต้องทำ):

Ansible Architecture
Control Node (เครื่องเรา)
Playbook (YAML)
Inventory (host list)
Ansible Engine
SSH ↓ ↓ ↓
Server 1
ไม่ต้องติดตั้งอะไร!
Server 2
ไม่ต้องติดตั้งอะไร!
Server 3
ไม่ต้องติดตั้งอะไร!

Step 1: Inventory — บอกว่ามี server อะไรบ้าง

Inventory คือไฟล์ที่บอก Ansible ว่า "มี server อะไรบ้าง แบ่งเป็นกลุ่มอะไร" สามารถจัดกลุ่มเป็น webservers, databases, monitoring ได้ — แล้วรัน playbook เฉพาะกลุ่ม:

all:
  children:
    webservers:
      hosts:
        web1:
          ansible_host: 10.0.1.1
        web2:
          ansible_host: 10.0.1.2
        web3:
          ansible_host: 10.0.1.3
    databases:
      hosts:
        db1:
          ansible_host: 10.0.2.1
  vars:
    ansible_user: deploy
    ansible_ssh_private_key_file: ~/.ssh/id_ed25519

Step 2: Playbook — บอกว่าต้องทำอะไร

Playbook คือ YAML file ที่อธิบาย "ต้องทำอะไรบ้าง" ทีละ task — Ansible จะรันตามลำดับ แต่ละ task ใช้ module (เช่น apt, copy, service, template) ที่เป็น idempotent คือรันกี่ครั้งก็ได้ผลเหมือนกัน ตัวอย่าง setup web server:

---
- name: Setup Web Servers
  hosts: webservers
  become: yes          # ใช้ sudo

  tasks:
    # อัพเดท system
    - name: Update apt cache
      apt:
        update_cache: yes
        cache_valid_time: 3600

    # ติดตั้ง Nginx
    - name: Install Nginx
      apt:
        name: nginx
        state: present

    # ติดตั้ง Node.js 20
    - name: Add NodeSource repository
      shell: curl -fsSL https://deb.nodesource.com/setup_20.x | bash -

    - name: Install Node.js
      apt:
        name: nodejs
        state: present

    # Copy config file
    - name: Deploy Nginx config
      template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/sites-available/myapp
      notify: Restart Nginx

    # เปิด firewall
    - name: Allow HTTP through firewall
      ufw:
        rule: allow
        port: "80"
        proto: tcp

    # ตรวจสอบว่า Nginx ทำงาน
    - name: Ensure Nginx is running
      service:
        name: nginx
        state: started
        enabled: yes

  handlers:
    - name: Restart Nginx
      service:
        name: nginx
        state: restarted
# รัน playbook
ansible-playbook -i inventory.yml setup-webserver.yml

# ดูผลลัพธ์:
# PLAY [Setup Web Servers] *************************************
# TASK [Install Nginx] *****************************************
# changed: [web1]
# changed: [web2]
# changed: [web3]
#
# PLAY RECAP ***************************************************
# web1: ok=7  changed=5  unreachable=0  failed=0
# web2: ok=7  changed=5  unreachable=0  failed=0
# web3: ok=7  changed=5  unreachable=0  failed=0

Ansible Ad-hoc Commands — ไม่ต้องเขียน playbook

สำหรับงานเร็วๆ ที่ไม่ต้องเขียน playbook — ใช้ ad-hoc commands รันคำสั่งเดียวบนหลายเครื่องพร้อมกัน เช่น check uptime ทุกเครื่อง, restart service, copy file:

# Ping ทุกเครื่อง
ansible all -i inventory.yml -m ping

# ดู disk space ทุก webserver
ansible webservers -i inventory.yml -a "df -h"

# ติดตั้ง package ด่วน
ansible webservers -i inventory.yml -m apt -a "name=htop state=present" --become

# Restart service
ansible webservers -i inventory.yml -m service -a "name=nginx state=restarted" --become

Terraform + Ansible ทำงานร่วมกัน

Workflow ที่ดีที่สุดคือใช้ ทั้งคู่ร่วมกัน — Terraform สร้าง infrastructure (VMs, VPC, Load Balancer) แล้วส่ง output (IP addresses) ให้ Ansible ไปตั้งค่า (install Docker, deploy app, configure monitoring) เหมือน Terraform "สร้างบ้าน" แล้ว Ansible "ตกแต่งภายใน":

Complete IaC Pipeline
Terraform
สร้าง VPC
สร้าง EC2 × 5
สร้าง RDS
สร้าง Load Balancer
Ansible
ติดตั้ง Docker
Deploy Application
ตั้งค่า Monitoring
Harden Security
Production
✅ Ready!
🔒 Secured
📊 Monitored
# 1. Terraform สร้าง infrastructure
cd terraform/
terraform apply -auto-approve

# 2. Export IP ที่ได้ เป็น Ansible inventory
terraform output -json server_ips | \
  jq -r '.[] | "  " + . ' > ../ansible/hosts.txt

# 3. Ansible ตั้งค่าทุกเครื่อง
cd ../ansible/
ansible-playbook -i inventory.yml setup-all.yml

IaC Tools อื่นๆ ที่น่ารู้

นอกจาก Terraform + Ansible ยังมี IaC tools อื่นๆ ที่น่าสนใจ — แต่ละตัวมีจุดแข็งต่างกัน เลือกตามความเหมาะสมของทีมและ use case:

Tool ประเภท จุดเด่น
Terraform Provisioning HCL, multi-cloud, state management
Ansible Config Management YAML, agentless, simple
Pulumi Provisioning เขียนด้วย Python/TypeScript/Go แทน HCL
CloudFormation Provisioning AWS native, JSON/YAML
Chef / Puppet Config Management Enterprise-grade, agent-based
OpenTofu Provisioning Terraform fork (open-source)

Best Practices

IaC ทำให้ infrastructure เป็น code ดังนั้นต้อง treat เหมือน code จริงๆ — version control, code review, testing, modularization หลักการสำคัญที่ต้องทำ:

  1. เก็บ IaC ใน Git — ทุก infrastructure change ต้องผ่าน PR review
  2. ใช้ modules — แยก code เป็น module ที่ reuse ได้
  3. แยก environment — dev / staging / production ใช้ config คนละชุด
  4. อย่าเก็บ secrets ใน code — ใช้ Vault, AWS Secrets Manager, หรือ environment variables
  5. ใช้ remote state — Terraform state เก็บใน S3 + DynamoDB lock ไม่ใช่ local
  6. Plan ก่อน Apply เสมอ — อ่าน plan ให้ดีก่อนกด yes!
  7. Idempotent — รันกี่ครั้งก็ได้ผลเหมือนเดิม
# Terraform remote state (best practice)
terraform {
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "prod/terraform.tfstate"
    region         = "ap-southeast-1"
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}
🐕 กฎทอง: ถ้า infrastructure ไม่ได้อยู่ใน code = มันไม่มีอยู่จริง ทุกอย่างต้อง reproducible!

สรุป

Infrastructure as Code เปลี่ยนวิธีจัดการ infrastructure จาก "จำในหัว + ทำด้วยมือ" เป็น "เขียน code + automate ทั้งหมด" ผลลัพธ์คือ: สร้าง environment ใหม่ได้ในนาที, disaster recovery เร็วขึ้น 100 เท่า, ทุกการเปลี่ยนแปลงมี audit trail ใน Git:

บทความจากซีรีส์ DevOps & Vibe Coding 2026
← Previous
Networking พื้นฐานสำหรับ DevOps — รู้จักเครือข่ายก่อน Deploy
Next →
Monitoring & Observability — รู้ทุกอย่างที่เกิดขึ้นใน System