คำถามสัมภาษณ์งาน Terraform: คู่มือฉบับสมบูรณ์สำหรับ Infrastructure as Code

เตรียมความพร้อมสำหรับการสัมภาษณ์งาน Terraform ด้วยคำถามและคำตอบที่ครอบคลุมทุกหัวข้อสำคัญ ตั้งแต่พื้นฐาน State Management ไปจนถึง Modules และ CI/CD

คำถามสัมภาษณ์งาน Terraform และ Infrastructure as Code

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

ผู้สัมภาษณ์มักประเมินทั้งความเข้าใจในแนวคิดพื้นฐานและประสบการณ์การใช้งานจริง การตอบคำถามควรแสดงให้เห็นถึงความเข้าใจในหลักการทำงานของ Terraform รวมถึงประสบการณ์ในการแก้ไขปัญหาที่เกิดขึ้นจริงในการทำงาน

แนวคิดพื้นฐานของ Terraform

Terraform คืออะไร

Terraform เป็นเครื่องมือ Infrastructure as Code (IaC) แบบ Open Source ที่พัฒนาโดย HashiCorp ใช้ภาษา HCL (HashiCorp Configuration Language) ในการประกาศ Infrastructure ที่ต้องการ Terraform ทำงานตามหลักการ Declarative ซึ่งหมายความว่าผู้ใช้งานจะประกาศสถานะที่ต้องการให้ Infrastructure เป็น และ Terraform จะคำนวณว่าต้องทำอะไรบ้างเพื่อให้ถึงสถานะนั้น

จุดเด่นของ Terraform คือความสามารถในการจัดการ Infrastructure ข้าม Cloud Provider หลายรายได้พร้อมกัน ไม่ว่าจะเป็น AWS, Azure, Google Cloud หรือแม้แต่ On-Premise Infrastructure โดยใช้ไวยากรณ์เดียวกัน

คำสั่ง Workflow หลักของ Terraform

Terraform มีคำสั่งหลัก 4 คำสั่งที่ใช้ในการทำงานประจำวัน ได้แก่ init, plan, apply และ destroy

bash
# 1. Initialize - downloads providers and modules
terraform init

# 2. Plan - shows what will change without modifying anything
terraform plan -out=tfplan

# 3. Apply - executes the planned changes
terraform apply tfplan

# 4. Destroy - tears down all managed resources
terraform destroy

คำสั่ง terraform init จะดาวน์โหลด Provider และ Module ที่จำเป็น รวมถึงตั้งค่า Backend สำหรับเก็บ State คำสั่ง terraform plan จะแสดงการเปลี่ยนแปลงที่จะเกิดขึ้นโดยไม่ทำการแก้ไขจริง ซึ่งเป็นขั้นตอนสำคัญในการตรวจสอบก่อนการ Deploy คำสั่ง terraform apply จะทำการเปลี่ยนแปลงจริงตาม Plan ที่กำหนด และคำสั่ง terraform destroy จะลบทรัพยากรทั้งหมดที่ Terraform จัดการอยู่

การจัดการ State

State คืออะไรและทำไมถึงสำคัญ

Terraform State เป็นไฟล์ที่เก็บข้อมูลความสัมพันธ์ระหว่าง Configuration ที่เขียนไว้กับทรัพยากรจริงบน Cloud Provider State ทำหน้าที่เป็นแหล่งข้อมูลความจริง (Source of Truth) ที่ Terraform ใช้ในการเปรียบเทียบว่าสถานะปัจจุบันของ Infrastructure แตกต่างจากสถานะที่ต้องการอย่างไร

State มีความสำคัญอย่างยิ่งเนื่องจากเก็บข้อมูล Metadata ของทรัพยากร เช่น ID ของทรัพยากรบน Cloud, ความสัมพันธ์ระหว่างทรัพยากร และค่าที่ Terraform คำนวณได้ หากไม่มี State Terraform จะไม่สามารถทราบว่าทรัพยากรใดที่จัดการอยู่และต้องเปลี่ยนแปลงอะไรบ้าง

การจัดการ State ใน Production

ในสภาพแวดล้อม Production การเก็บ State ไว้ในเครื่องท้องถิ่นไม่เหมาะสม เนื่องจากหลายคนในทีมต้องการเข้าถึง State เดียวกัน และต้องมีกลไกป้องกันการแก้ไขพร้อมกัน (Locking) การใช้ Remote Backend เช่น S3 พร้อม DynamoDB สำหรับ Locking เป็นแนวปฏิบัติที่แนะนำ

hcl
# backend.tf
terraform {
  backend "s3" {
    bucket         = "company-terraform-state"
    key            = "prod/networking/terraform.tfstate"
    region         = "eu-west-1"
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}

การตั้งค่านี้มีองค์ประกอบสำคัญหลายอย่าง ได้แก่ bucket สำหรับเก็บไฟล์ State, key สำหรับกำหนดตำแหน่งไฟล์ภายใน Bucket, dynamodb_table สำหรับทำ Locking ป้องกันการแก้ไขพร้อมกัน และ encrypt สำหรับเข้ารหัสไฟล์ State เนื่องจากอาจมีข้อมูลสำคัญอยู่

ไฟล์ State อาจมีข้อมูลสำคัญเช่น Password หรือ Secret ควรเปิดใช้งานการเข้ารหัสเสมอ และจำกัดการเข้าถึง Bucket เฉพาะผู้ที่จำเป็นต้องใช้งานเท่านั้น นอกจากนี้ควรเปิดใช้งาน Versioning บน S3 Bucket เพื่อให้สามารถกู้คืน State เวอร์ชันก่อนหน้าได้หากเกิดปัญหา

Modules

Module ทำงานอย่างไร

Module ใน Terraform คือกลุ่มของทรัพยากรที่จัดเป็นหน่วยเดียวกัน สามารถนำกลับมาใช้ซ้ำได้ Module ช่วยให้สามารถแบ่งปัน Infrastructure Pattern ระหว่างโปรเจกต์หรือทีมได้อย่างมีประสิทธิภาพ ลดการเขียนโค้ดซ้ำซ้อน และทำให้การบำรุงรักษาง่ายขึ้น

hcl
# main.tf - calling a module
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "5.16.0"

  name = "production-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["eu-west-1a", "eu-west-1b", "eu-west-1c"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]

  enable_nat_gateway = true
  single_nat_gateway = true
}

ตัวอย่างนี้แสดงการเรียกใช้ Module จาก Terraform Registry ซึ่งเป็น Module สำเร็จรูปที่ผ่านการทดสอบแล้ว การระบุ version เป็นสิ่งสำคัญเพื่อให้แน่ใจว่า Infrastructure สามารถสร้างซ้ำได้เหมือนเดิมทุกครั้ง

หลักการออกแบบ Module ที่ดี

Module ที่ออกแบบมาอย่างดีควรมีคุณสมบัติดังนี้:

  • มีจุดประสงค์เดียว: Module ควรทำหน้าที่เดียวอย่างชัดเจน เช่น สร้าง VPC หรือสร้าง EKS Cluster
  • มี Input Variables ที่เหมาะสม: ควรมีค่า Default ที่สมเหตุสมผล และอนุญาตให้ปรับแต่งได้ตามความจำเป็น
  • มี Output ที่จำเป็น: ควรส่งออกค่าที่ Module อื่นหรือ Root Module ต้องการใช้งาน
  • มี Documentation ครบถ้วน: ควรมีคำอธิบายการใช้งาน ตัวอย่าง และ README ที่ชัดเจน

พร้อมที่จะพิชิตการสัมภาษณ์ DevOps แล้วหรือยังครับ?

ฝึกฝนด้วยตัวจำลองแบบโต้ตอบ, flashcards และแบบทดสอบเทคนิคครับ

Workspaces, Environments และโครงสร้างโปรเจกต์

รูปแบบการจัดการหลาย Environment

การจัดการ Infrastructure หลาย Environment เช่น Development, Staging และ Production เป็นความท้าทายที่พบบ่อย มีหลายวิธีในการจัดการ แต่ละวิธีมีข้อดีข้อเสียแตกต่างกัน

| รูปแบบ | ข้อดี | ข้อเสีย | เหมาะกับ | |--------|-------|---------|----------| | Workspaces | ง่าย ใช้ Code ชุดเดียว | State อยู่ใน Backend เดียว | ทีมเล็ก Environment คล้ายกัน | | Directory ต่าง ๆ | แยก State ชัดเจน ปลอดภัย | โค้ดซ้ำซ้อน | Environment แตกต่างกันมาก | | Terragrunt | DRY ยืดหยุ่น | ต้องเรียนรู้เครื่องมือเพิ่ม | โปรเจกต์ขนาดใหญ่ |

Workspace vs Directory Isolation

Terraform Workspaces ช่วยให้สามารถใช้ Configuration ชุดเดียวกับหลาย Environment ได้ โดยแต่ละ Workspace จะมี State แยกกัน อย่างไรก็ตาม Workspaces ไม่ได้แยก Backend ดังนั้นหากมีปัญหากับ Backend จะกระทบทุก Environment

การใช้ Directory แยกสำหรับแต่ละ Environment ให้การแยกที่ชัดเจนกว่า แต่ต้องจัดการกับการซ้ำซ้อนของโค้ด วิธีที่นิยมคือการใช้ Module ร่วมกัน และมี Configuration เฉพาะสำหรับแต่ละ Environment

Providers, Data Sources และ Resource Lifecycle

การตั้งค่า Provider

Provider เป็นตัวเชื่อมต่อระหว่าง Terraform กับ API ของ Cloud Provider หรือบริการต่าง ๆ การตั้งค่า Provider อย่างเหมาะสมเป็นพื้นฐานที่สำคัญ

hcl
# providers.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.80"
    }
  }
}

provider "aws" {
  region = var.aws_region

  default_tags {
    tags = {
      Environment = var.environment
      ManagedBy   = "terraform"
      Team        = var.team_name
    }
  }
}

การระบุ Version Constraint เช่น ~> 5.80 หมายความว่าจะใช้ Version 5.80 หรือสูงกว่า แต่ต่ำกว่า 6.0 ซึ่งช่วยป้องกันการอัพเกรดที่อาจทำให้เกิดปัญหา การใช้ default_tags ช่วยให้ทุกทรัพยากรที่สร้างมี Tag มาตรฐานโดยอัตโนมัติ

Data Sources vs Resources

Data Sources ใช้สำหรับอ่านข้อมูลจากทรัพยากรที่มีอยู่แล้ว โดยไม่สร้างหรือแก้ไขอะไร ในขณะที่ Resources ใช้สำหรับสร้างและจัดการทรัพยากรใหม่

hcl
# Data source - reads an existing AMI, does not create anything
data "aws_ami" "ubuntu" {
  most_recent = true
  owners      = ["099720109477"] # Canonical

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-*"]
  }
}

# Resource - creates an EC2 instance using the data source
resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t3.micro"
}

ในตัวอย่างนี้ Data Source aws_ami ค้นหา AMI ของ Ubuntu ที่มีอยู่แล้ว และ Resource aws_instance ใช้ ID ของ AMI นั้นในการสร้าง EC2 Instance ใหม่

Lifecycle Meta-Arguments เช่น create_before_destroy, prevent_destroy และ ignore_changes ช่วยควบคุมพฤติกรรมการสร้างและลบทรัพยากร การใช้ prevent_destroy = true กับทรัพยากรสำคัญเช่น Database จะป้องกันการลบโดยไม่ตั้งใจ

หัวข้อขั้นสูง

การ Import ทรัพยากรที่มีอยู่

บางครั้งต้องการนำทรัพยากรที่สร้างไว้แล้วด้วยมือมาอยู่ภายใต้การจัดการของ Terraform Terraform 1.5 ขึ้นไปรองรับการ Import แบบ Declarative ด้วย import Block

hcl
# import.tf
import {
  to = aws_s3_bucket.legacy_data
  id = "my-legacy-bucket-name"
}

resource "aws_s3_bucket" "legacy_data" {
  bucket = "my-legacy-bucket-name"
}

วิธีนี้ช่วยให้การ Import เป็นส่วนหนึ่งของ Configuration และสามารถ Review ใน Pull Request ได้ก่อนการ Apply

Moved Blocks สำหรับการ Refactor

เมื่อต้องการเปลี่ยนชื่อ Resource หรือย้าย Resource เข้า Module สามารถใช้ moved Block เพื่อบอก Terraform ว่าไม่ต้องลบและสร้างใหม่ แต่ให้ Update State แทน

hcl
# Renamed a resource from "web" to "app"
moved {
  from = aws_instance.web
  to   = aws_instance.app
}

การทดสอบ Terraform

Terraform 1.6 ขึ้นไปมี Native Testing Framework ที่ช่วยให้เขียน Test สำหรับ Configuration ได้

hcl
# tests/vpc.tftest.hcl
run "creates_vpc_with_correct_cidr" {
  command = plan

  assert {
    condition     = aws_vpc.main.cidr_block == "10.0.0.0/16"
    error_message = "VPC CIDR block does not match expected value"
  }
}

run "creates_three_private_subnets" {
  command = plan

  assert {
    condition     = length(aws_subnet.private) == 3
    error_message = "Expected 3 private subnets"
  }
}

การทดสอบช่วยให้มั่นใจว่า Configuration ทำงานถูกต้องก่อนการ Deploy และช่วยป้องกันการเปลี่ยนแปลงที่อาจทำให้เกิดปัญหา

Terraform ใน CI/CD Pipeline

การรวม Terraform เข้ากับ CI/CD Pipeline เป็นแนวปฏิบัติที่สำคัญสำหรับทีมที่ต้องการจัดการ Infrastructure อย่างเป็นระบบ ขั้นตอนที่แนะนำมีดังนี้:

  1. Validate และ Format: รัน terraform validate และ terraform fmt -check เพื่อตรวจสอบ Syntax และ Formatting
  2. Security Scan: ใช้เครื่องมืออย่าง tfsec หรือ Checkov เพื่อตรวจหาปัญหาด้านความปลอดภัย
  3. Plan: รัน terraform plan และบันทึก Plan File สำหรับ Review
  4. Review: ให้ทีมตรวจสอบ Plan ก่อน Apply โดยเฉพาะการเปลี่ยนแปลงใน Production
  5. Apply: รัน terraform apply หลังจากได้รับการอนุมัติแล้วเท่านั้น

การแยก Plan และ Apply ออกจากกันช่วยให้มีการตรวจสอบก่อนการเปลี่ยนแปลงจริง ลดความเสี่ยงในการเกิดปัญหา

สรุป

การเตรียมตัวสำหรับการสัมภาษณ์งาน Terraform ต้องครอบคลุมหลายหัวข้อสำคัญ ตั้งแต่แนวคิดพื้นฐานอย่างคำสั่ง Workflow และ State Management ไปจนถึงหัวข้อขั้นสูงอย่าง Modules และการ Testing ประเด็นสำคัญที่ควรจดจำมีดังนี้:

  • State เป็นหัวใจของ Terraform: เข้าใจวิธีการจัดการ State ใน Production ด้วย Remote Backend และ Locking
  • Module ช่วยให้โค้ดสามารถนำกลับมาใช้ซ้ำได้: ออกแบบ Module ให้มีจุดประสงค์เดียวและมี Interface ที่ชัดเจน
  • Provider และ Version Constraint: ระบุ Version เสมอเพื่อให้ Infrastructure สร้างซ้ำได้
  • CI/CD Integration: การรวม Terraform เข้ากับ Pipeline ช่วยให้มีการควบคุมและตรวจสอบที่ดี

สำหรับผู้ที่ต้องการศึกษาเพิ่มเติมเกี่ยวกับ DevOps สามารถอ่านบทความ คำถามสัมภาษณ์งาน DevOps ที่ควรรู้ และ การ Deploy แอปพลิเคชันบน Kubernetes เพื่อเตรียมความพร้อมให้ครบถ้วนยิ่งขึ้น

เริ่มฝึกซ้อมเลย!

ทดสอบความรู้ของคุณด้วยตัวจำลองสัมภาษณ์และแบบทดสอบเทคนิคครับ

แท็ก

#terraform
#infrastructure-as-code
#devops
#interview
#iac
#hcl

แชร์

บทความที่เกี่ยวข้อง