Terraform Infrastructure as Code สำหรับ Cloud AWS

ในยุคที่ Cloud Computing กลายเป็นหัวใจสำคัญของการดำเนินธุรกิจ การจัดการโครงสร้างพื้นฐาน (Infrastructure) บนแพลตฟอร์มคลาวด์อย่าง Amazon Web Services (AWS) ด้วยวิธีการแบบเดิมๆ เช่น การคลิกผ่าน AWS Management Console อาจกลายเป็นเรื่องที่ซับซ้อน ใช้เวลานาน และเสี่ยงต่อข้อผิดพลาดได้ง่ายครับ ลองนึกภาพการตั้งค่าเซิร์ฟเวอร์, ฐานข้อมูล, เครือข่าย, และบริการอื่นๆ อีกมากมายด้วยมือสำหรับแต่ละโปรเจกต์ หรือแม้แต่การอัปเดตระบบในอนาคต ความวุ่นวายที่เกิดขึ้นอาจทำให้คุณต้องปวดหัวเลยทีเดียวครับ

แต่ข่าวดีก็คือ เรามีแนวทางที่ทันสมัยและมีประสิทธิภาพกว่านั้นมาก นั่นคือ Infrastructure as Code (IaC) และเครื่องมือที่ได้รับความนิยมอย่างสูงในกลุ่มนักพัฒนาและวิศวกร DevOps นั่นคือ Terraform ครับ บทความนี้จะพาทุกท่านดำดิ่งสู่โลกของ Terraform และวิธีการนำไปใช้สร้าง จัดการ และปรับปรุงโครงสร้างพื้นฐานบน AWS Cloud ได้อย่างเป็นระบบ อัตโนมัติ และน่าเชื่อถือ พร้อมตัวอย่างโค้ดที่ใช้งานได้จริง และคำแนะนำเชิงลึกที่จะช่วยให้คุณปลดล็อกศักยภาพของ AWS ได้อย่างเต็มที่ครับ


สารบัญ


ทำความเข้าใจ Infrastructure as Code (IaC) คืออะไรครับ?

ก่อนที่เราจะลงลึกไปใน Terraform เรามาทำความเข้าใจแนวคิดพื้นฐานที่เป็นรากฐานของมันก่อน นั่นคือ Infrastructure as Code หรือ IaC ครับ

ปัญหาของการจัดการ Infrastructure แบบเดิม

ในอดีต การจัดการโครงสร้างพื้นฐานด้านไอทีมักจะเป็นกระบวนการที่ต้องทำด้วยมือ หรือใช้สคริปต์แบบ Shell Script ง่ายๆ ซึ่งมีข้อเสียหลายประการครับ:

  • ความผิดพลาดของมนุษย์ (Human Error): การตั้งค่าด้วยมือทำให้มีโอกาสเกิดความผิดพลาดได้ง่าย เช่น พิมพ์ผิด, ลืมตั้งค่าบางอย่าง, หรือตั้งค่าไม่ตรงกันระหว่าง Environment.
  • ความไม่สอดคล้องกัน (Inconsistency): การสร้าง Environment ที่เหมือนกันหลายๆ ชุด (เช่น Dev, Staging, Production) มักจะมีความแตกต่างเล็กน้อยเกิดขึ้น ทำให้เกิดปัญหา “มันทำงานได้ในเครื่องของฉันนะ!” (It works on my machine!) บ่อยครั้ง.
  • ใช้เวลานาน (Time-Consuming): การตั้งค่าและบำรุงรักษา Infrastructure ด้วยมือต้องใช้เวลาและแรงงานมาก โดยเฉพาะอย่างยิ่งเมื่อระบบมีขนาดใหญ่ขึ้น.
  • ตรวจสอบย้อนหลังไม่ได้ (Lack of Version Control): ไม่สามารถติดตามการเปลี่ยนแปลงหรือย้อนกลับไปยังสถานะก่อนหน้าได้ง่าย ทำให้การแก้ไขปัญหาและการอัปเดตเป็นเรื่องยาก.
  • ไม่สามารถปรับขนาดได้ (Scalability Challenges): การขยายระบบหรือการสร้าง Environment ใหม่ๆ ทำได้ช้าและยากลำบาก.

แนวคิดของ Infrastructure as Code (IaC)

Infrastructure as Code คือแนวปฏิบัติในการจัดการและจัดเตรียมโครงสร้างพื้นฐานด้านไอที (เช่น เครือข่าย, เซิร์ฟเวอร์, ฐานข้อมูล, แอปพลิเคชัน) โดยใช้ไฟล์โค้ดแทนการดำเนินการด้วยมือครับ แนวคิดหลักคือการปฏิบัติต่อ Infrastructure เหมือนกับที่เราจัดการโค้ดของแอปพลิเคชัน:

  • ใช้ภาษาที่อ่านเข้าใจง่าย (Declarative Language): แทนที่จะบอกว่า “ทำอะไร” (Imperative) IaC จะบอกว่า “ผลลัพธ์สุดท้ายควรเป็นอย่างไร” (Declarative) ซึ่งช่วยให้โค้ดเข้าใจง่ายและลดความซับซ้อน.
  • ควบคุมเวอร์ชัน (Version Control): โค้ด IaC สามารถจัดเก็บในระบบควบคุมเวอร์ชัน เช่น Git ทำให้สามารถติดตามการเปลี่ยนแปลง, ตรวจสอบย้อนหลัง, และทำงานร่วมกันเป็นทีมได้.
  • การทำซ้ำได้ (Repeatability): สามารถสร้าง Environment ที่เหมือนกันทุกประการกี่ครั้งก็ได้ตามต้องการ ลดปัญหาความไม่สอดคล้องกัน.
  • อัตโนมัติ (Automation): กระบวนการสร้างและจัดการ Infrastructure เป็นไปโดยอัตโนมัติ ลดการแทรกแซงของมนุษย์.
  • ลดความเสี่ยง (Reduced Risk): ลดโอกาสเกิดข้อผิดพลาดและเพิ่มความน่าเชื่อถือของระบบ.
  • ประหยัดค่าใช้จ่าย (Cost Efficiency): ด้วยการทำซ้ำและอัตโนมัติ ทำให้สามารถใช้ทรัพยากรได้อย่างมีประสิทธิภาพมากขึ้น และลดเวลาที่ต้องใช้ในการจัดการ.

การนำ IaC มาใช้ช่วยให้องค์กรสามารถปรับปรุงกระบวนการพัฒนาซอฟต์แวร์ได้อย่างก้าวกระโดด ทำให้การส่งมอบแอปพลิเคชันรวดเร็วขึ้น ปลอดภัยขึ้น และมีคุณภาพสูงขึ้นครับ

ทำไมต้อง Terraform? เจาะลึกถึงหัวใจของ Multi-Cloud IaC

Terraform คืออะไร?

Terraform เป็นเครื่องมือ Infrastructure as Code (IaC) แบบ Open-source ที่พัฒนาโดย HashiCorp ครับ มันช่วยให้คุณสามารถกำหนดและจัดเตรียมโครงสร้างพื้นฐานด้านไอทีได้อย่างปลอดภัยและมีประสิทธิภาพ ไม่ว่าจะเป็นเซิร์ฟเวอร์, ฐานข้อมูล, เครือข่าย, หรือบริการอื่นๆ โดยใช้ภาษาการกำหนดค่าที่เรียกว่า HashiCorp Configuration Language (HCL) หรือ JSON ครับ

สิ่งที่ทำให้ Terraform โดดเด่นคือความสามารถในการจัดการ Infrastructure ได้หลากหลายแพลตฟอร์ม (Multi-Cloud) ไม่ว่าจะเป็น AWS, Azure, Google Cloud, Oracle Cloud Infrastructure, หรือแม้แต่แพลตฟอร์ม On-premise เช่น VMware, OpenStack รวมถึงบริการ SaaS ต่างๆ เช่น Kubernetes, Datadog และอื่นๆ อีกมากมาย ด้วยหลักการ “Write, Plan, Apply” ครับ

คุณสมบัติเด่นของ Terraform

Terraform มีคุณสมบัติหลายอย่างที่ทำให้เป็นเครื่องมือ IaC ที่ทรงพลังและเป็นที่นิยมอย่างมากครับ:

  • Declarative Language (HCL):

    Terraform ใช้ภาษา HCL ที่ถูกออกแบบมาให้อ่านง่ายและเขียนง่ายสำหรับการกำหนดโครงสร้างพื้นฐาน คุณเพียงแค่ระบุว่าต้องการ Infrastructure แบบใด (เช่น ต้องการ EC2 instance กี่ตัว, S3 bucket แบบไหน) ไม่ต้องเขียนขั้นตอนการสร้างทีละขั้นเหมือนการเขียนสคริปต์ครับ

    resource "aws_s3_bucket" "my_bucket" {
      bucket = "siamlancard-unique-bucket-12345"
      acl    = "private"
    
      tags = {
        Name        = "SiamLancard Terraform Bucket"
        Environment = "Dev"
      }
    }
  • State Management:

    Terraform จะเก็บสถานะของ Infrastructure ที่สร้างขึ้นในไฟล์ที่เรียกว่า `terraform.tfstate` ครับ ไฟล์นี้มีความสำคัญอย่างยิ่ง เพราะมันช่วยให้ Terraform ทราบว่าทรัพยากรใดบ้างที่ถูกจัดการโดย Terraform และสถานะปัจจุบันของมันเป็นอย่างไร ทำให้ Terraform สามารถเปรียบเทียบสถานะปัจจุบันกับโค้ดที่คุณเขียนไว้ เพื่อวางแผนการเปลี่ยนแปลงได้อย่างแม่นยำครับ

  • Provider Ecosystem (Multi-Cloud, SaaS, On-prem):

    Terraform มี “Providers” จำนวนมากที่ทำหน้าที่เป็นตัวกลางในการเชื่อมต่อและจัดการกับแพลตฟอร์มหรือบริการต่างๆ ทำให้ Terraform สามารถทำงานได้กับเกือบทุกระบบ ไม่ว่าจะเป็น Public Cloud (AWS, Azure, GCP), Private Cloud, หรือแม้แต่บริการระดับแอปพลิเคชัน เช่น GitHub, Datadog ครับ

  • Modularity:

    คุณสามารถจัดกลุ่มโค้ด Terraform ที่ใช้สร้างทรัพยากรหลายๆ อย่างเข้าด้วยกันเป็น “Module” ซึ่งทำให้โค้ดสามารถนำกลับมาใช้ใหม่ได้, จัดการง่ายขึ้น, และลดความซ้ำซ้อน ช่วยให้การสร้าง Infrastructure ที่ซับซ้อนเป็นไปอย่างมีระเบียบครับ

  • Execution Plan:

    ก่อนที่จะทำการเปลี่ยนแปลงใดๆ กับ Infrastructure จริง Terraform จะสร้าง “Execution Plan” ที่แสดงให้เห็นว่า Terraform จะสร้าง, แก้ไข, หรือลบทรัพยากรใดบ้างครับ สิ่งนี้ช่วยให้คุณสามารถตรวจสอบแผนการเปลี่ยนแปลงได้อย่างละเอียดก่อนที่จะ “Apply” ซึ่งช่วยลดความเสี่ยงในการเกิดความผิดพลาดได้เป็นอย่างมาก

Terraform vs. AWS CloudFormation: การเปรียบเทียบในโลก AWS

สำหรับผู้ที่ทำงานบน AWS มักจะเจอเครื่องมือ IaC อีกตัวที่ AWS พัฒนาขึ้นมาเอง นั่นคือ AWS CloudFormation ครับ ทั้งสองเครื่องมือมีจุดประสงค์คล้ายกัน แต่มีข้อดีข้อเสียที่แตกต่างกันไป ดังตารางเปรียบเทียบนี้ครับ

คุณสมบัติ Terraform AWS CloudFormation
ผู้พัฒนา HashiCorp (Open-source) Amazon Web Services
แพลตฟอร์มที่รองรับ Multi-Cloud (AWS, Azure, GCP, On-prem, SaaS อื่นๆ) AWS อย่างเดียว (AWS-specific)
ภาษาที่ใช้ HashiCorp Configuration Language (HCL), JSON YAML, JSON
การจัดการ State จัดการโดย Terraform (local หรือ remote backend) จัดการโดย AWS Service (อยู่ใน Stack)
การเรียนรู้ มี Learning Curve เล็กน้อย แต่ HCL เข้าใจง่าย ค่อนข้างง่ายสำหรับผู้ที่คุ้นเคยกับ AWS แต่มีข้อจำกัดในการใช้งานข้าม AWS Account/Region
Ecosystem & Modules มี Providers และ Modules จำนวนมากจาก HashiCorp Registry และชุมชน มี Resource Types และ Extensions ที่รองรับ AWS Service ล่าสุด
การนำกลับมาใช้ใหม่ ใช้ Modules และ Remote State สำหรับการนำกลับมาใช้ใหม่และการทำงานข้าม Account/Region ใช้ Nested Stacks หรือ Custom Resources สำหรับการนำกลับมาใช้ใหม่
ราคา ฟรี (สำหรับ Terraform CLI), มี Terraform Cloud/Enterprise สำหรับฟีเจอร์เพิ่มเติม ฟรี (จ่ายเฉพาะค่าทรัพยากรที่สร้างขึ้น)
ข้อดีหลัก ยืดหยุ่นสูง, Multi-Cloud, ชุมชนใหญ่, State Management ที่ทรงพลัง ผสานรวมกับ AWS ได้อย่างราบรื่น, รองรับ AWS Service ใหม่ๆ เร็ว, การจัดการ Stack ง่าย

โดยสรุป ถ้าคุณต้องการโซลูชัน IaC ที่สามารถทำงานได้กับหลายแพลตฟอร์ม (Multi-Cloud) และต้องการความยืดหยุ่นในการจัดการ Infrastructure ที่หลากหลาย Terraform คือตัวเลือกที่ยอดเยี่ยมครับ แต่ถ้าคุณผูกติดอยู่กับ AWS เพียงอย่างเดียว CloudFormation ก็เป็นทางเลือกที่ดีที่ผสานรวมกับ AWS ได้อย่างลึกซึ้งครับ

เริ่มต้นกับ Terraform: การติดตั้งและการตั้งค่าเบื้องต้น

ก่อนที่เราจะเริ่มเขียนโค้ด Terraform เพื่อสร้าง Infrastructure บน AWS เราต้องทำการติดตั้งและตั้งค่าบางอย่างก่อนครับ

การติดตั้ง Terraform

Terraform เป็นเครื่องมือแบบ Command Line Interface (CLI) ที่คุณสามารถดาวน์โหลดและติดตั้งได้ง่ายๆ บนระบบปฏิบัติการต่างๆ ครับ

  • สำหรับ Windows:

    ดาวน์โหลดไฟล์ `.zip` ที่เหมาะสมกับสถาปัตยกรรมของคุณจาก Terraform Downloads Page แตกไฟล์ และเพิ่มพาธของโฟลเดอร์ที่แตกไฟล์ (ที่มีไฟล์ `terraform.exe` อยู่) เข้าไปใน Environment Variable `Path` ของระบบครับ

  • สำหรับ macOS (แนะนำ Homebrew):

    brew tap hashicorp/tap
    brew install hashicorp/tap/terraform
  • สำหรับ Linux (แนะนำ `apt` หรือ `yum`):

    สำหรับ Debian/Ubuntu:

    sudo apt update && sudo apt install -y gnupg software-properties-common
    wget -O- https://apt.releases.hashicorp.com/gpg | \
        gpg --dearmor | \
        sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg
    gpg --no-default-keyring \
        --keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg \
        --fingerprint
    echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
        https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \
        sudo tee /etc/apt/sources.list.d/hashicorp.list
    sudo apt update
    sudo apt install terraform

    สำหรับ CentOS/RHEL:

    sudo yum install -y yum-utils
    sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
    sudo yum install terraform

หลังจากติดตั้งเสร็จแล้ว ลองเปิด Terminal/Command Prompt และรันคำสั่งเพื่อตรวจสอบเวอร์ชันครับ:

terraform --version

คุณควรจะเห็นผลลัพธ์ประมาณนี้ครับ:

Terraform v1.x.x
on linux_amd64

การตั้งค่า AWS CLI และ IAM User/Role

Terraform จำเป็นต้องมีสิทธิ์ในการเข้าถึง AWS Account ของคุณเพื่อสร้างและจัดการทรัพยากรครับ วิธีที่ปลอดภัยที่สุดคือการใช้ AWS CLI เพื่อตั้งค่า Credentials หรือใช้ IAM Role สำหรับ EC2 instances หรือ CI/CD pipelines ครับ

  1. ติดตั้ง AWS CLI:

    ดาวน์โหลดและติดตั้ง AWS CLI จาก เว็บไซต์ทางการของ AWS ครับ

  2. สร้าง IAM User (สำหรับผู้เริ่มต้น หรือเครื่อง local):

    ใน AWS Management Console ไปที่ IAM Service > Users > Add user. กำหนดชื่อผู้ใช้และเลือก “Programmatic access” เพื่อสร้าง Access Key ID และ Secret Access Key ครับ

    แนะนำ: จำกัดสิทธิ์ (Permissions) ของ IAM User นี้ให้แคบที่สุดเท่าที่จำเป็น (Principle of Least Privilege) แทนที่จะให้ AdministratorAccess ครับ

  3. ตั้งค่า Credentials ด้วย AWS CLI:

    เปิด Terminal/Command Prompt แล้วรันคำสั่ง:

    aws configure

    จากนั้นป้อน Access Key ID, Secret Access Key, Default region name (เช่น `ap-southeast-1` สำหรับสิงคโปร์), และ Default output format (เช่น `json`) ครับ

    AWS CLI จะบันทึกข้อมูลเหล่านี้ไว้ในไฟล์ `~/.aws/credentials` และ `~/.aws/config` ซึ่ง Terraform สามารถอ่านเพื่อใช้งานได้อัตโนมัติครับ

    สำหรับ Production Environment: แนะนำให้ใช้ IAM Role สำหรับ EC2 หรือบริการอื่นๆ ที่รัน Terraform เพื่อหลีกเลี่ยงการเก็บ Access Key/Secret Key ในเครื่องครับ

ไฟล์โครงสร้างพื้นฐานของ Terraform (Directory Structure)

โดยทั่วไป โครงสร้างไฟล์สำหรับโปรเจกต์ Terraform จะจัดเป็นระเบียบตามวัตถุประสงค์ครับ คุณสามารถสร้างไฟล์ `.tf` กี่ไฟล์ก็ได้ในไดเรกทอรีเดียวกัน Terraform จะอ่านไฟล์ทั้งหมดที่มีนามสกุล `.tf` ในไดเรกทอรีนั้นครับ

  • `main.tf`: ไฟล์หลักสำหรับกำหนดทรัพยากร (Resources)
  • `variables.tf`: ไฟล์สำหรับกำหนดตัวแปร (Variables)
  • `outputs.tf`: ไฟล์สำหรับกำหนดผลลัพธ์ (Outputs)
  • `versions.tf`: (ไม่บังคับ) สำหรับกำหนดเวอร์ชันของ Terraform และ Providers
  • `terraform.tfvars`: (ไม่บังคับ) ไฟล์สำหรับระบุค่าเริ่มต้นของตัวแปร

สร้างโฟลเดอร์สำหรับโปรเจกต์แรกของคุณ เช่น `my-first-terraform-aws` ครับ

mkdir my-first-terraform-aws
cd my-first-terraform-aws

Terraform Core Concepts: ส่วนประกอบสำคัญที่ควรรู้

มาทำความเข้าใจส่วนประกอบหลักๆ ของ Terraform ที่คุณจะต้องใช้งานเป็นประจำกันครับ

Providers: ตัวเชื่อมต่อสู่โลกภายนอก

Providers เป็นปลั๊กอินที่ Terraform ใช้เพื่อสื่อสารกับ API ของบริการต่างๆ เช่น AWS, Azure, GCP, หรือแม้แต่ GitHub ครับ คุณต้องกำหนด Provider ที่ต้องการใช้งานในไฟล์ `.tf` ของคุณเสมอ

# versions.tf หรือ main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0" # กำหนดเวอร์ชันของ AWS Provider
    }
  }
  required_version = "~> 1.0" # กำหนดเวอร์ชันของ Terraform CLI
}

provider "aws" {
  region = "ap-southeast-1" # กำหนด AWS Region ที่ต้องการใช้งาน
  # profile = "my-aws-profile" # หากใช้ AWS Profile อื่นๆ นอกเหนือจาก default
}

ในตัวอย่างนี้ เรากำหนดให้ใช้ AWS Provider เวอร์ชัน 5.0 ขึ้นไป และตั้งค่า Default Region เป็น `ap-southeast-1` (สิงคโปร์) ครับ

Resources: สร้างสรรค์สิ่งต่างๆ ใน Cloud

resource block เป็นหัวใจของการสร้าง Infrastructure ด้วย Terraform ครับ มันใช้สำหรับกำหนดว่าคุณต้องการสร้างทรัพยากรใดบน Cloud และมีคุณสมบัติอะไรบ้าง

รูปแบบทั่วไปคือ resource "type" "name" {}

  • type: ชนิดของทรัพยากรที่ Provider นั้นๆ รองรับ (เช่น aws_vpc, aws_instance, aws_s3_bucket)
  • name: ชื่อเชิงตรรกะ (Local Name) ที่คุณกำหนดให้กับทรัพยากรนั้นๆ ภายในโค้ด Terraform เพื่อใช้อ้างอิง
  • ภายใน {}: กำหนด Attributes/Arguments ที่จำเป็นสำหรับทรัพยากรนั้นๆ

ตัวอย่าง: การสร้าง AWS VPC, Subnet, Internet Gateway, และ Route Table

# main.tf

# 1. สร้าง Virtual Private Cloud (VPC)
resource "aws_vpc" "main" {
  cidr_block       = "10.0.0.0/16"
  instance_tenancy = "default"

  tags = {
    Name = "siamlancard-main-vpc"
  }
}

# 2. สร้าง Public Subnet
resource "aws_subnet" "public" {
  vpc_id                  = aws_vpc.main.id # อ้างอิง VPC ID จาก resource ด้านบน
  cidr_block              = "10.0.1.0/24"
  availability_zone       = "ap-southeast-1a"
  map_public_ip_on_launch = true # ทำให้ EC2 ใน Subnet นี้ได้รับ Public IP อัตโนมัติ

  tags = {
    Name = "siamlancard-public-subnet"
  }
}

# 3. สร้าง Internet Gateway (IGW) เพื่อให้ VPC ออกอินเทอร์เน็ตได้
resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "siamlancard-main-igw"
  }
}

# 4. สร้าง Route Table สำหรับ Public Subnet
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = "0.0.0.0/0"        # เส้นทางไปยังทุกที่
    gateway_id = aws_internet_gateway.main.id # ผ่าน Internet Gateway
  }

  tags = {
    Name = "siamlancard-public-rt"
  }
}

# 5. เชื่อม Route Table เข้ากับ Public Subnet
resource "aws_route_table_association" "public" {
  subnet_id      = aws_subnet.public.id
  route_table_id = aws_route_table.public.id
}

จะเห็นได้ว่าเราสามารถอ้างอิงคุณสมบัติของทรัพยากรหนึ่งไปยังอีกทรัพยากรหนึ่งได้โดยใช้รูปแบบ resource_type.resource_name.attribute (เช่น aws_vpc.main.id) ครับ

Variables: พารามิเตอร์ที่ปรับเปลี่ยนได้

Variables ช่วยให้โค้ด Terraform ของคุณมีความยืดหยุ่นมากขึ้น โดยคุณสามารถกำหนดค่าต่างๆ ที่อาจมีการเปลี่ยนแปลง (เช่น Region, ชื่อ Environment, CIDR block) เป็นตัวแปร แทนที่จะ Hardcode ไว้ในโค้ดโดยตรงครับ

คุณสามารถกำหนดตัวแปรได้ในไฟล์ variables.tf:

# variables.tf

variable "aws_region" {
  description = "The AWS region to deploy resources into."
  type        = string
  default     = "ap-southeast-1"
}

variable "project_name" {
  description = "Name of the project."
  type        = string
  default     = "siamlancard"
}

variable "vpc_cidr_block" {
  description = "CIDR block for the VPC."
  type        = string
  default     = "10.0.0.0/16"
}

แล้วนำตัวแปรเหล่านี้ไปใช้ใน main.tf ได้ดังนี้:

# main.tf (ส่วนที่ใช้ variables)

provider "aws" {
  region = var.aws_region # ใช้ตัวแปร
}

resource "aws_vpc" "main" {
  cidr_block       = var.vpc_cidr_block # ใช้ตัวแปร
  instance_tenancy = "default"

  tags = {
    Name = "${var.project_name}-main-vpc" # ใช้ตัวแปรใน string interpolation
  }
}

# ... ทรัพยากรอื่นๆ ที่ใช้อ้างอิง var.project_name ...

คุณสามารถกำหนดค่าของตัวแปรได้หลายวิธี:

  • Default Value: กำหนด default ใน variable block (ดังตัวอย่างด้านบน)
  • ไฟล์ `terraform.tfvars`: สร้างไฟล์ชื่อ terraform.tfvars ในไดเรกทอรีเดียวกัน แล้วกำหนดค่าตัวแปรในรูปแบบ key = "value". Terraform จะโหลดไฟล์นี้อัตโนมัติครับ
  • Command Line: ใช้ -var "key=value" เมื่อรัน terraform plan หรือ terraform apply
  • Environment Variables: ใช้ TF_VAR_key="value"

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

Outputs ใช้สำหรับแสดงข้อมูลสำคัญของ Infrastructure ที่ถูกสร้างขึ้น เช่น VPC ID, Public IP ของ EC2 instance, หรือชื่อ S3 bucket ครับ ข้อมูลเหล่านี้มีประโยชน์สำหรับการตรวจสอบ หรือส่งต่อไปยังโมดูลหรือโปรเจกต์ Terraform อื่นๆ

สร้างไฟล์ outputs.tf:

# outputs.tf

output "vpc_id" {
  description = "The ID of the main VPC."
  value       = aws_vpc.main.id
}

output "public_subnet_id" {
  description = "The ID of the public subnet."
  value       = aws_subnet.public.id
}

output "s3_bucket_name" {
  description = "The name of the created S3 bucket."
  value       = aws_s3_bucket.my_bucket.bucket # สมมติว่ามี aws_s3_bucket.my_bucket ถูกสร้างไว้ใน main.tf
}

เมื่อรัน terraform apply หรือ terraform output คุณจะเห็นค่าของ Outputs เหล่านี้ครับ

Data Sources: ดึงข้อมูลจาก Existing Infrastructure

data block ใช้สำหรับดึงข้อมูลจากทรัพยากรที่มีอยู่แล้วบน Cloud หรือจาก Provider โดยไม่ต้องสร้างทรัพยากรใหม่ครับ สิ่งนี้มีประโยชน์มากเมื่อคุณต้องการอ้างอิงทรัพยากรที่ไม่ได้ถูกสร้างโดย Terraform ปัจจุบัน หรือต้องการใช้ข้อมูลแบบไดนามิก เช่น การค้นหา AMI ล่าสุด

# main.tf

# ดึงข้อมูล AMI ID ล่าสุดของ Amazon Linux 2
data "aws_ami" "amazon_linux_2" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}

# ดึงข้อมูล Availability Zones ทั้งหมดใน Region ปัจจุบัน
data "aws_availability_zones" "available" {
  state = "available"
}

# ตัวอย่างการนำไปใช้: สร้าง EC2 instance โดยใช้ AMI ID ที่ดึงมา
resource "aws_instance" "web_server" {
  ami           = data.aws_ami.amazon_linux_2.id # ใช้ AMI ID ที่ดึงมา
  instance_type = "t2.micro"
  subnet_id     = aws_subnet.public.id # อ้างอิงจาก subnet ที่สร้างไว้ก่อนหน้า

  tags = {
    Name = "siamlancard-web-server"
  }
}

Terraform State: บันทึกสถานะของ Infrastructure

ไฟล์ terraform.tfstate เป็นไฟล์สำคัญที่ Terraform ใช้บันทึกสถานะปัจจุบันของ Infrastructure ที่มันกำลังจัดการครับ

  • ความสำคัญ: ไฟล์นี้ช่วยให้ Terraform ทราบว่าทรัพยากรใดบ้างที่ถูกสร้างขึ้น, มี ID อะไรบ้าง, และมีคุณสมบัติอย่างไรบ้าง ทำให้ Terraform สามารถเปรียบเทียบสถานะจริงกับโค้ดของคุณเพื่อวางแผนการเปลี่ยนแปลงได้อย่างถูกต้อง.
  • Local State vs. Remote State:
    • Local State: โดยค่าเริ่มต้น ไฟล์ terraform.tfstate จะถูกสร้างขึ้นในไดเรกทอรีเดียวกับโค้ด Terraform ของคุณ ซึ่งเหมาะสำหรับโปรเจกต์ขนาดเล็กหรือการทดสอบส่วนตัว.
    • Remote State: สำหรับโปรเจกต์ขนาดใหญ่, การทำงานเป็นทีม, หรือ Production Environment การเก็บ State file ไว้ใน Backend ระยะไกล (Remote Backend) เป็นสิ่งจำเป็นอย่างยิ่งครับ เช่น ใน AWS S3 Bucket, Azure Blob Storage, HashiCorp Consul หรือ Terraform Cloud.

ข้อดีของ Remote State (เช่น S3 Bucket):

  • การทำงานร่วมกัน (Collaboration): สมาชิกในทีมทุกคนเห็น State ล่าสุดเดียวกัน
  • ความปลอดภัย (Security): สามารถเข้ารหัส (Encrypt) State file ได้
  • ความคงทน (Durability): State file ไม่สูญหายหากเครื่องของคุณพัง
  • State Locking: ป้องกันไม่ให้หลายคนพยายามแก้ไข Infrastructure พร้อมกัน ซึ่งจะทำให้ State file เสียหายได้ (สำหรับ S3 มักจะใช้ DynamoDB สำหรับ Locking)

ตัวอย่าง: การตั้งค่า Remote Backend ด้วย AWS S3

# main.tf (หรือ versions.tf)

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  required_version = "~> 1.0"

  # กำหนด Remote Backend เป็น S3
  backend "s3" {
    bucket         = "siamlancard-terraform-state-bucket" # ต้องสร้าง bucket นี้ไว้ล่วงหน้า
    key            = "dev/network/terraform.tfstate"      # พาธของ state file ภายใน bucket
    region         = "ap-southeast-1"
    encrypt        = true                               # เข้ารหัส state file
    dynamodb_table = "siamlancard-terraform-state-lock" # ต้องสร้าง DynamoDB table นี้ไว้ล่วงหน้า
  }
}

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

# ... ทรัพยากรอื่นๆ ...

สำคัญ: ก่อนที่คุณจะรัน terraform init ด้วยการตั้งค่า Backend นี้ คุณต้องสร้าง S3 bucket และ DynamoDB table (`siamlancard-terraform-state-lock` โดยมี Partition key ชื่อ `LockID` เป็น String) ไว้ล่วงหน้าใน AWS Management Console หรือด้วย Terraform อีกโปรเจกต์หนึ่งครับ

อ่านเพิ่มเติมเกี่ยวกับการจัดการ Terraform State

ลงมือปฏิบัติจริง: สร้าง AWS Infrastructure ด้วย Terraform

มาลองสร้าง Infrastructure จริงๆ บน AWS ด้วย Terraform กันครับ!

สร้าง AWS S3 Bucket ง่ายๆ

เราจะเริ่มต้นด้วยการสร้าง S3 bucket ที่ง่ายที่สุดครับ

1. สร้างไฟล์ main.tf ในโฟลเดอร์โปรเจกต์ของคุณ:

# main.tf

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  required_version = "~> 1.0"
}

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

resource "aws_s3_bucket" "my_bucket" {
  # ชื่อ bucket ต้องไม่ซ้ำกันทั่วโลก (globally unique)
  bucket = "siamlancard-example-bucket-123456789" 
  acl    = "private" # กำหนดสิทธิ์การเข้าถึงเป็นส่วนตัว

  tags = {
    Name        = "SiamLancard Terraform Bucket"
    Environment = "Dev"
  }
}

output "s3_bucket_name" {
  description = "The name of the created S3 bucket."
  value       = aws_s3_bucket.my_bucket.bucket
}

output "s3_bucket_arn" {
  description = "The ARN of the created S3 bucket."
  value       = aws_s3_bucket.my_bucket.arn
}

2. เปิด Terminal ในโฟลเดอร์โปรเจกต์ของคุณ และรันคำสั่ง:

  • terraform init:

    คำสั่งนี้จะเริ่มต้นไดเรกทอรีการทำงานของ Terraform โดยการดาวน์โหลด Provider ที่จำเป็น (ในกรณีนี้คือ AWS Provider) และตั้งค่า Backend ครับ

    terraform init

    คุณควรจะเห็นข้อความว่า “Terraform has been successfully initialized!”

  • terraform plan:

    คำสั่งนี้จะสร้าง “Execution Plan” ซึ่งแสดงให้เห็นว่า Terraform จะทำอะไรบ้าง (สร้าง, แก้ไข, ลบ) โดยไม่ทำการเปลี่ยนแปลงใดๆ กับ Infrastructure จริงครับ นี่เป็นขั้นตอนที่สำคัญมากในการตรวจสอบความถูกต้องของแผนก่อนที่จะ Apply

    terraform plan

    คุณจะเห็นผลลัพธ์ที่แสดงว่า Terraform จะ “add” (สร้าง) `aws_s3_bucket.my_bucket` 1 รายการครับ

  • terraform apply:

    คำสั่งนี้จะดำเนินการตาม Execution Plan ที่สร้างขึ้น และทำการเปลี่ยนแปลง Infrastructure จริงบน AWS ของคุณครับ Terraform จะถามการยืนยันก่อนเสมอ

    terraform apply

    พิมพ์ yes เพื่อยืนยัน หลังจากนั้น S3 bucket ของคุณก็จะถูกสร้างขึ้น คุณสามารถตรวจสอบได้ใน AWS Management Console ครับ

  • terraform destroy:

    เมื่อคุณต้องการลบ Infrastructure ที่สร้างโดย Terraform ทั้งหมด (หรือบางส่วน) คุณสามารถใช้คำสั่งนี้ได้ครับ โปรดระมัดระวังในการใช้คำสั่งนี้ใน Production Environment!

    terraform destroy

    พิมพ์ yes เพื่อยืนยัน S3 bucket ของคุณจะถูกลบออกครับ

สร้าง EC2 Instance พร้อม Security Group

คราวนี้เรามาสร้าง Infrastructure ที่ซับซ้อนขึ้นอีกนิด ด้วยการสร้าง EC2 Instance พร้อม Security Group เพื่อเปิดพอร์ต HTTP (80) และ SSH (22) ครับ

สร้างไฟล์ main.tf, variables.tf, outputs.tf ในโฟลเดอร์ใหม่ เช่น `my-ec2-project`

variables.tf:

variable "aws_region" {
  description = "The AWS region to deploy resources into."
  type        = string
  default     = "ap-southeast-1"
}

variable "vpc_cidr_block" {
  description = "CIDR block for the VPC."
  type        = string
  default     = "10.0.0.0/16"
}

variable "public_subnet_cidr_block" {
  description = "CIDR block for the public subnet."
  type        = string
  default     = "10.0.1.0/24"
}

variable "instance_type" {
  description = "EC2 instance type."
  type        = string
  default     = "t2.micro"
}

variable "ssh_key_name" {
  description = "Name of the SSH Key Pair to use for EC2 instances."
  type        = string
  default     = "my-ssh-key" # ต้องสร้าง Key Pair นี้ไว้ใน AWS ล่วงหน้า
}

variable "allowed_ips_ssh" {
  description = "List of IP addresses allowed to SSH into instances."
  type        = list(string)
  default     = ["0.0.0.0/0"] # ควรจำกัดให้เฉพาะ IP ของคุณใน Production
}

main.tf:

# กำหนด Provider
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  required_version = "~> 1.0"
}

provider "aws" {
  region = var.aws_region
}

# Data Source เพื่อดึง AMI ID ของ Amazon Linux 2 ล่าสุด
data "aws_ami" "amazon_linux_2" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}

# 1. สร้าง Virtual Private Cloud (VPC)
resource "aws_vpc" "main" {
  cidr_block       = var.vpc_cidr_block
  instance_tenancy = "default"

  tags = {
    Name = "siamlancard-ec2-vpc"
  }
}

# 2. สร้าง Internet Gateway (IGW)
resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "siamlancard-ec2-igw"
  }
}

# 3. สร้าง Public Subnet
resource "aws_subnet" "public" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = var.public_subnet_cidr_block
  availability_zone       = "${var.aws_region}a" # ใช้ AZ แรกของ Region
  map_public_ip_on_launch = true

  tags = {
    Name = "siamlancard-ec2-public-subnet"
  }
}

# 4. สร้าง Route Table สำหรับ Public Subnet
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main.id
  }

  tags = {
    Name = "siamlancard-ec2-public-rt"
  }
}

# 5. เชื่อม Route Table เข้ากับ Public Subnet
resource "aws_route_table_association" "public" {
  subnet_id      = aws_subnet.public.id
  route_table_id = aws_route_table.public.id
}

# 6. สร้าง Security Group สำหรับ Web Server
resource "aws_security_group" "web_sg" {
  name        = "siamlancard-web-sg"
  description = "Allow HTTP and SSH access"
  vpc_id      = aws_vpc.main.id

  # Ingress rule for HTTP (Port 80)
  ingress {
    description = "HTTP from anywhere"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  # Ingress rule for SSH (Port 22)
  ingress {
    description = "SSH from specified IPs"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = var.allowed_ips_ssh # ใช้ตัวแปร
  }

  # Egress rule (Allow all outbound traffic)
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1" # -1 หมายถึงทุกโปรโตคอล
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "siamlancard-web-sg"
  }
}

# 7. สร้าง EC2 Instance
resource "aws_instance" "web_server" {
  ami           = data.aws_ami.amazon_linux_2.id
  instance_type = var.instance_type # ใช้ตัวแปร
  subnet_id     = aws_subnet.public.id
  key_name      = var.ssh_key_name # ใช้ตัวแปรชื่อ Key Pair
  vpc_security_group_ids = [aws_security_group.web_sg.id] # อ้างอิง Security Group

  user_data = <<EOF
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<h1>Hello from Terraform!</h1>" > /var/www/html/index.html
EOF

  tags = {
    Name = "siamlancard-web-server"
  }
}

outputs.tf:

output "vpc_id" {
  description = "The ID of the main VPC."
  value       = aws_vpc.main.id
}

output "web_server_public_ip" {
  description = "The public IP address of the web server."
  value       = aws_instance.web_server.public_ip
}

output "web_server_public_dns" {
  description = "The public DNS name of the web server."
  value       = aws_instance.web_server.public_dns
}

ขั้นตอนการ Deploy:

  1. ตรวจสอบให้แน่ใจว่าคุณได้สร้าง SSH Key Pair ใน AWS Region เดียวกันกับที่ระบุใน variables.tf (เช่น my-ssh-key) แล้วครับ
  2. เปิด Terminal ในโฟลเดอร์ `my-ec2-project`
  3. รัน terraform init
  4. รัน terraform plan เพื่อตรวจสอบแผนการสร้าง
  5. รัน terraform apply และพิมพ์ yes เพื่อยืนยัน

หลังจาก terraform apply สำเร็จ คุณจะได้ Public IP และ Public DNS ของ EC2 instance ออกมาทาง Output คุณสามารถลองเข้าถึง IP นั้นผ่านเว็บเบราว์เซอร์ (Port 80) หรือ SSH เข้าไป (Port 22) ได้ครับ

เมื่อทดสอบเสร็จแล้ว อย่าลืมรัน terraform destroy เพื่อลบทรัพยากรทั้งหมดเพื่อหลีกเลี่ยงค่าใช้จ่ายที่ไม่จำเป็นครับ

Terraform Modules: การนำกลับมาใช้ใหม่และความเป็นระเบียบ

ทำไมต้องใช้ Modules?

เมื่อโปรเจกต์ของคุณเติบโตขึ้น การจัดการโค้ด Terraform ในไฟล์เดียวหรือหลายไฟล์ในไดเรกทอรีเดียวอาจกลายเป็นเรื่องที่ยุ่งยากครับ นี่คือเหตุผลที่เราควรใช้ Modules:

  • การนำกลับมาใช้ใหม่ (Reusability): คุณสามารถสร้างชุดของทรัพยากร (เช่น VPC พร้อม Subnets และ Route Tables) เป็น Module เดียว แล้วนำไปใช้ซ้ำในหลายๆ โปรเจกต์ หรือหลาย Environment ได้.
  • ความเป็นระเบียบ (Organization): ช่วยให้โครงสร้างโค้ดของคุณเป็นระเบียบและเข้าใจง่ายขึ้น โดยการแบ่งโค้ดออกเป็นส่วนย่อยๆ ที่จัดการได้.
  • ลดความซ้ำซ้อน (Reduced Duplication): หลีกเลี่ยงการคัดลอกและวางโค้ดเดิมซ้ำๆ.
  • การทำงานร่วมกัน (Collaboration): ทีมสามารถพัฒนา Modules แยกกันได้ ทำให้การทำงานพร้อมกันมีประสิทธิภาพมากขึ้น.
  • การ Encapsulation: Module จะซ่อนรายละเอียดการสร้างทรัพยากรภายใน และเปิดเผยเฉพาะ Input Variables และ Output ที่จำเป็น.

การสร้างและใช้งาน Modules

Module คือไดเรกทอรีที่มีไฟล์ Terraform configuration (.tf) อยู่ภายในครับ

โครงสร้าง Module:

.
├── main.tf           # ไฟล์หลักสำหรับกำหนดทรัพยากรของ Module
├── variables.tf      # ไฟล์สำหรับกำหนด Input Variables ของ Module
├── outputs.tf        # ไฟล์สำหรับกำหนด Output ของ Module
└── README.md         # เอกสารประกอบ (แนะนำ)

ตัวอย่าง: การสร้าง VPC Module

1. สร้างโฟลเดอร์สำหรับ Module เช่น modules/vpc

2. ใน modules/vpc/variables.tf:

variable "vpc_cidr_block" {
  description = "CIDR block for the VPC."
  type        = string
}

variable "public_subnet_cidr_blocks" {
  description = "List of CIDR blocks for public subnets."
  type        = list(string)
}

variable "private_subnet_cidr_blocks" {
  description = "List of CIDR blocks for private subnets."
  type        = list(string)
}

variable "project_name" {
  description = "Name prefix for resources."
  type        = string
}

variable "aws_region" {
  description = "The AWS region."
  type        = string
}

3. ใน modules/vpc/main.tf:

# Resource สำหรับ VPC
resource "aws_vpc" "this" {
  cidr_block       = var.vpc_cidr_block
  instance_tenancy = "default"

  tags = {
    Name = "${var.project_name}-vpc"
  }
}

# Resource สำหรับ Internet Gateway
resource "aws_internet_gateway" "this" {
  vpc_id = aws_vpc.this.id

  tags = {
    Name = "${var.project_name}-igw"
  }
}

# Resource สำหรับ Public Subnets (ใช้ count เพื่อสร้างหลายๆ Subnet)
resource "aws_subnet" "public" {
  count                   = length(var.public_subnet_cidr_blocks)
  vpc_id                  = aws_vpc.this.id
  cidr_block              = var.public_subnet_cidr_blocks[count.index]
  availability_zone       = "${var.aws_region}${element(["a", "b", "c"], count.index)}"
  map_public_ip_on_launch = true

  tags = {
    Name = "${var.project_name}-public-subnet-${count.index}"
  }
}

# Resource สำหรับ Private Subnets (ใช้ count เพื่อสร้างหลายๆ Subnet)
resource "aws_subnet" "private" {
  count             = length(var.private_subnet_cidr_blocks)
  vpc_id            = aws_vpc.this.id
  cidr_block        = var.private_subnet_cidr_blocks[count.index]
  availability_zone = "${var.aws_region}${element(["a", "b", "c"], count.index)}"

  tags = {
    Name = "${var.project_name}-private-subnet-${count.index}"
  }
}

# Resource สำหรับ Public Route Table
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.this.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.this.id
  }

  tags = {
    Name = "${var.project_name}-public-rt"
  }
}

# การเชื่อม Route Table กับ Public Subnets
resource "aws_route_table_association" "public" {
  count          = length(aws_subnet.public)
  subnet_id      = aws_subnet.public[count.index].id
  route_table_id = aws_route_table.public.id
}

4. ใน modules/vpc/outputs.tf:

output "vpc_id" {
  description = "The ID of the created VPC."
  value       = aws_vpc.this.id
}

output "public_subnet_ids" {
  description = "List of public subnet IDs."
  value       = aws_subnet.public.*.id
}

output "private_subnet_ids" {
  description = "List of private subnet IDs."
  value       = aws_subnet.private.*.id
}

การเรียกใช้ Module:

ในไฟล์ main.tf ของโปรเจกต์หลักของคุณ:

# root/main.tf

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  required_version = "~> 1.0"
}

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

module "network" {
  source = "./modules/vpc" # ระบุพาธไปยังโฟลเดอร์ Module

  vpc_cidr_block            = "10.0.0.0/16"
  public_subnet_cidr_blocks = ["10.0.1.0/24", "10.0.2.0/24"]
  private_subnet_cidr_blocks = ["10.0.10.0/24", "10.0.11.0/24"]
  project_name              = "siamlancard-app"
  aws_region                = "ap-southeast-1"
}

output "app_vpc_id" {
  value = module.network.vpc_id
}

output "app_public_subnets" {
  value = module.network.public_subnet_ids
}

เมื่อรัน terraform init, terraform plan, terraform apply ในไดเรกทอรีหลัก (`root/`) Terraform จะดาวน์โหลดและเรียกใช้ VPC Module ของคุณครับ

Terraform Registry: แหล่งรวม Modules ที่พร้อมใช้งาน

Terraform Registry (registry.terraform.io) เป็นแหล่งรวม Providers และ Modules ที่ HashiCorp และชุมชนสร้างขึ้นครับ คุณสามารถค้นหา Modules คุณภาพสูงที่พร้อมใช้งานสำหรับบริการต่างๆ เช่น VPC, EKS, RDS บน AWS เพื่อนำมาใช้ในโปรเจกต์ของคุณได้ทันที ช่วยประหยัดเวลาและรับประกันคุณภาพของโค้ด

ตัวอย่างการใช้ Module จาก Terraform Registry:

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws" # ชื่อ Module จาก Registry
  version = "5.0.0" # กำหนดเวอร์ชัน

  name = "siamlancard-prod-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["ap-southeast-1a", "ap-southeast-1b"]
  public_subnets  = ["10.0.1.0/24", "10.0.2.0/24"]
  private_subnets = ["10.0.10.0/24", "10.0.11.0/24"]

  enable_nat_gateway = true
  single_nat_gateway = true

  tags = {
    Environment = "Production"
  }
}

จะเห็นว่าการใช้ Module จาก Registry ช่วยให้เราสร้าง VPC ที่ซับซ้อนได้อย่างรวดเร็วด้วยโค้ดเพียงไม่กี่บรรทัดครับ

Best Practices ในการใช้ Terraform สำหรับ AWS

เพื่อให้การใช้ Terraform ของคุณมีประสิทธิภาพ ปลอดภัย และสามารถบำรุงรักษาได้ในระยะยาว ควรปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุดเหล่านี้ครับ

การจัดการ State File ที่ปลอดภัยและมีประสิทธิภาพ

State file คือข้อมูลสำคัญที่ Terraform ใช้ติดตามสถานะของ Infrastructure ครับ การจัดการอย่างถูกต้องจึงเป็นสิ่งจำเป็น

  • ใช้ Remote Backend เสมอ:

    อย่างที่กล่าวไปแล้ว การเก็บ State file ใน Remote Backend เช่น AWS S3 Bucket (พร้อมกับการล็อก State ด้วย DynamoDB) เป็นสิ่งจำเป็นสำหรับการทำงานเป็นทีมและความปลอดภัยครับ

    # main.tf หรือ versions.tf
    terraform {
      backend "s3" {
        bucket         = "your-company-terraform-state-bucket"
        key            = "environments/production/my-app/terraform.tfstate"
        region         = "ap-southeast-1"
        encrypt        = true
        dynamodb_table = "terraform-state-lock" # ตรวจสอบให้แน่ใจว่า DynamoDB table นี้มี Partition Key ชื่อ 'LockID' (String)
      }
    }
  • State Locking:

    ตรวจสอบให้แน่ใจว่า Backend ของคุณรองรับ State Locking เพื่อป้องกันไม่ให้ผู้ใช้สองคน (หรือ CI/CD pipeline) พยายามรัน terraform apply พร้อมกัน ซึ่งอาจทำให้ State file เสียหายได้ครับ S3 Backend รองรับการล็อกโดยใช้ DynamoDB ครับ

  • การเข้ารหัส (Encryption):

    เข้ารหัส State file ทั้งในส่วนที่จัดเก็บ (at-rest) และระหว่างการส่งข้อมูล (in-transit) S3 รองรับการเข้ารหัสที่จัดเก็บข้อมูลโดยอัตโนมัติ (SSE-S3) หรือใช้ KMS ครับ

  • จำกัดการเข้าถึง State File:

    ใช้ IAM Policies เพื่อจำกัดผู้ที่สามารถเข้าถึง S3 bucket ที่เก็บ State file ได้ เฉพาะผู้ที่จำเป็นเท่านั้นครับ

การจัดการ Secrets และ Sensitive Data

ไม่ควรเก็บข้อมูลที่ละเอียดอ่อน เช่น รหัสผ่าน, API Keys ในโค้้ด Terraform หรือใน State file โดยตรงครับ

จัดส่งรวดเร็วส่งด่วนทั่วประเทศ
รับประกันสินค้าเคลมง่าย มีใบรับประกัน
ผ่อนชำระได้บัตรเครดิต 0% สูงสุด 10 เดือน
สะสมแต้ม รับส่วนลดส่วนลดและคะแนนสะสม

© 2026 SiamLancard — จำหน่ายการ์ดแลน อุปกรณ์ Server และเครื่องพิมพ์ใบเสร็จ

SiamLancard
Logo
Free Forex EA Download — XM Signal · EA Forex ฟรี
iCafeForex.com - สอนเทรด Forex | SiamCafe.net
Shopping cart