Resource และ Data Source

📖 text • 12 นาที

Resource และ Data Source

Resource

Resource คือสิ่งที่ Terraform สร้างและจัดการ บน cloud

resource "<PROVIDER>_<TYPE>" "<NAME>" {
  argument1 = value1
  argument2 = value2
}

ตัวอย่าง: EC2 Instance

resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  tags = {
    Name = "web-server"
  }
}
  • aws_instance = resource type (EC2 instance จาก AWS provider)
  • "web" = local name (ใช้อ้างอิงภายใน Terraform)
  • ami, instance_type = arguments (ค่าที่ต้องกำหนด)

Argument Types

ประเภท คำอธิบาย ตัวอย่าง
Required ต้องใส่ ไม่ใส่ = error ami, instance_type
Optional ใส่หรือไม่ก็ได้ มี default tags, monitoring
Computed Terraform คำนวณให้ อ่านได้อย่างเดียว id, arn, public_ip

อ้างอิง Resource อื่น

Resource สามารถอ้างอิง attribute ของ resource อื่นได้:

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "public" {
  vpc_id     = aws_vpc.main.id          # อ้างอิง id ของ VPC
  cidr_block = "10.0.1.0/24"
}

Format: <resource_type>.<name>.<attribute>

Terraform จะเข้าใจว่า subnet ขึ้นอยู่กับ VPC และจะสร้าง VPC ก่อนอัตโนมัติ — นี่คือ implicit dependency

Resource Lifecycle

ควบคุมพฤติกรรมการสร้าง/ลบ resource:

resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  lifecycle {
    create_before_destroy = true   # สร้างตัวใหม่ก่อน แล้วค่อยลบตัวเก่า
    prevent_destroy       = true   # ห้ามลบ (terraform destroy จะ error)
    ignore_changes        = [tags] # ไม่สนใจการเปลี่ยนแปลง tags
  }
}
Option ใช้เมื่อไร
create_before_destroy Resource ที่ต้องมี zero-downtime
prevent_destroy Resource สำคัญเช่น database
ignore_changes Attribute ที่ถูกแก้ภายนอก Terraform

Data Source

Data Source คือการ อ่านข้อมูล จาก infrastructure ที่มีอยู่แล้ว — ไม่สร้าง ไม่แก้ไข ไม่ลบ

data "<PROVIDER>_<TYPE>" "<NAME>" {
  filter_argument = value
}

ตัวอย่าง: หา AMI ล่าสุด

data "aws_ami" "ubuntu" {
  most_recent = true
  owners      = ["099720109477"]  # Canonical

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
  }
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id   # ใช้ AMI ที่หาได้
  instance_type = "t2.micro"
}

ตัวอย่าง: หา VPC ที่มีอยู่

data "aws_vpc" "default" {
  default = true
}

resource "aws_subnet" "new" {
  vpc_id     = data.aws_vpc.default.id
  cidr_block = "172.31.48.0/20"
}

ตัวอย่าง: หา Availability Zones

data "aws_availability_zones" "available" {
  state = "available"
}

resource "aws_subnet" "public" {
  count             = 2
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.${count.index}.0/24"
  availability_zone = data.aws_availability_zones.available.names[count.index]
}

Resource vs Data Source

Resource Data Source
Keyword resource data
หน้าที่ สร้าง/แก้ไข/ลบ อ่านอย่างเดียว
ใน State มี (tracked) มี (cached)
อ้างอิง aws_instance.web.id data.aws_ami.ubuntu.id
ตัวอย่าง สร้าง EC2 ใหม่ หา AMI ID ล่าสุด

Practical Pattern: ใช้ Resource + Data Source ร่วมกัน

# Data: หา VPC ที่มีอยู่แล้ว
data "aws_vpc" "existing" {
  tags = {
    Name = "production-vpc"
  }
}

# Data: หา AMI ล่าสุด
data "aws_ami" "amazon_linux" {
  most_recent = true
  owners      = ["amazon"]

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

# Resource: สร้าง EC2 ใน VPC ที่มีอยู่ ด้วย AMI ล่าสุด
resource "aws_instance" "app" {
  ami           = data.aws_ami.amazon_linux.id
  instance_type = "t3.micro"
  subnet_id     = data.aws_vpc.existing.id

  tags = {
    Name = "app-server"
  }
}

Pattern นี้ใช้บ่อยมาก — ดึงข้อมูลที่มีอยู่ แล้วใช้สร้าง resource ใหม่

สรุป

Concept Keyword หน้าที่
Resource resource สร้าง/จัดการ infrastructure
Data Source data อ่านข้อมูลที่มีอยู่
Reference type.name.attr อ้างอิง attribute ข้าม resource
Lifecycle lifecycle {} ควบคุมพฤติกรรม create/update/delete
Dependency implicit/explicit Terraform จัดลำดับการสร้างอัตโนมัติ

บทถัดไปเรามา Lab สร้าง EC2 + Security Group จริงๆ กัน