# Pulumi vs Terraform 2026: Infrastructure as Code ด้วย TypeScript และคำถามสัมภาษณ์ > เปรียบเทียบเชิงลึก Pulumi vs Terraform สำหรับ Infrastructure as Code ในปี 2026 เรียนรู้ความแตกต่างด้านการรองรับ TypeScript การจัดการ state และคำถามสัมภาษณ์ DevOps ที่พบบ่อย - Published: 2026-09-21 - Updated: 2026-09-21 - Author: Anthony Fillion-Maillet - Reading time: 5 min --- Pulumi vs Terraform เป็นการตัดสินใจหลักด้าน Infrastructure as Code สำหรับทีม DevOps ในปี 2026 เครื่องมือทั้งสองจัดเตรียม cloud resources แบบ declarative แต่แตกต่างกันในด้านการรองรับภาษาโปรแกรม การจัดการ state และความสมบูรณ์ของระบบนิเวศ บทความนี้ครอบคลุมการแลกเปลี่ยนทางเทคนิค ตัวอย่างโค้ดใน TypeScript และ HCL รวมถึงคำถามสัมภาษณ์ที่มักปรากฏเมื่อผู้สมัครพูดคุยเกี่ยวกับทางเลือก IaC > **บริบทเวอร์ชัน: กันยายน 2026** > > การเปรียบเทียบนี้ใช้ Pulumi v3.263.0 (เผยแพร่ 15 กันยายน 2026) และ Terraform 1.16.3 (เผยแพร่ 26 สิงหาคม 2026) CDKTF เลเยอร์ TypeScript ของ HashiCorp สำหรับ Terraform ถูกยกเลิกในเดือนธันวาคม 2025 และ repository ถูกเก็บถาวร ## สถาปัตยกรรมหลัก: Engine ของ Pulumi vs วงจร Plan-Apply ของ Terraform Terraform ใช้ภาษาเฉพาะโดเมน (HCL) และเวิร์กโฟลว์สองขั้นตอน: `terraform plan` สร้าง execution plan และ `terraform apply` ดำเนินการ State file ติดตาม resource metadata และถูกจัดเก็บในเครื่องหรือบน remote backend เช่น S3 หรือ Terraform Cloud Pulumi ฝัง engine ไว้ใน runtime ของภาษาโปรแกรมทั่วไป โปรแกรมที่เขียนด้วย TypeScript Python Go หรือ C# ดำเนินการโดยตรงกับ cloud API ผ่าน provider ของ Pulumi State ถูกจัดเก็บบน Pulumi Cloud โดยค่าเริ่มต้น พร้อมตัวเลือกสำหรับ self-managed backend รวมถึง S3 Azure Blob Storage และไฟล์ในเครื่อง ความแตกต่างทางสถาปัตยกรรมปรากฏทันทีในวิธีที่แต่ละเครื่องมือจัดการลูป เงื่อนไข และการนามธรรม `for_each` และ `count` ของ Terraform ทำงานภายในข้อจำกัดของ HCL โปรแกรม Pulumi ใช้โครงสร้างภาษาดั้งเดิม: `for...of` ใน TypeScript list comprehension ใน Python และ `range` ใน Go ```typescript // infra/index.ts - ตัวอย่าง Pulumi TypeScript import * as aws from "@pulumi/aws"; import * as pulumi from "@pulumi/pulumi"; // เมธอดอาร์เรย์ TypeScript ดั้งเดิมทำงานได้โดยตรง const environments = ["dev", "staging", "prod"]; const buckets = environments.map(env => new aws.s3.BucketV2(`data-${env}`, { bucket: `myapp-data-${env}-${pulumi.getStack()}`, tags: { Environment: env, ManagedBy: "pulumi", }, }) ); // ส่งออก bucket ARN เป็น stack output export const bucketArns = buckets.map(b => b.arn); ``` การกำหนดค่า Terraform ที่เทียบเท่าต้องใช้ไวยากรณ์ HCL สำหรับการวนซ้ำ: ```hcl # main.tf - ตัวอย่าง Terraform HCL variable "environments" { type = list(string) default = ["dev", "staging", "prod"] } resource "aws_s3_bucket" "data" { for_each = toset(var.environments) bucket = "myapp-data-${each.key}-${terraform.workspace}" tags = { Environment = each.key ManagedBy = "terraform" } } output "bucket_arns" { value = [for b in aws_s3_bucket.data : b.arn] } ``` ทั้งสอง snippet สร้าง S3 bucket สามตัว เวอร์ชัน Terraform กระชับและอ่านง่ายสำหรับทุกคนที่คุ้นเคยกับ HCL เวอร์ชัน Pulumi ใช้ TypeScript มาตรฐาน ซึ่งหมายความว่า IDE autocompletion การตรวจสอบชนิด และการรวมเข้ากับ codebase ที่มีอยู่โดยไม่ต้องเรียนรู้ภาษาใหม่ ## การรองรับ TypeScript: ภาษาดั้งเดิม vs CDKTF (ยกเลิกแล้ว) Pulumi รองรับ TypeScript ตั้งแต่การเผยแพร่สาธารณะครั้งแรก SDK เปิดเผย typed resource class และ `pulumi.Output` ห่อหุ้มค่าอะซิงโครนัสที่ resolve ระหว่างการ deploy เครื่องมือ refactoring linter และ test framework จากระบบนิเวศ TypeScript สามารถนำมาใช้ได้โดยตรง คำตอบของ Terraform สำหรับการรองรับภาษาโปรแกรมทั่วไปคือ [CDKTF (Cloud Development Kit for Terraform)](https://developer.hashicorp.com/terraform/cdktf) CDKTF อนุญาตให้ทีมเขียน TypeScript หรือ Python ที่คอมไพล์เป็น Terraform JSON HashiCorp ยกเลิก CDKTF ในเดือนธันวาคม 2025 และเก็บถาวร repository โปรเจกต์ CDKTF ที่มีอยู่ยังคงทำงานได้ แต่ไม่มีการอัปเดตสำหรับเวอร์ชัน Terraform ใหม่หรือการเปลี่ยนแปลง provider สำหรับทีมที่ต้องการ TypeScript IaC ในปี 2026 Pulumi เป็นตัวเลือกที่ได้รับการดูแลอย่างแข็งขัน ทีมที่ลงทุนใน CDKTF แล้วสามารถดำเนินการ stack ของตนต่อไปได้ แต่การย้ายไปยัง HCL หรือ Pulumi คือเส้นทางข้างหน้าสำหรับการพัฒนาใหม่ ```typescript // infra/vpc.ts - Pulumi component สำหรับ VPC abstraction ที่นำกลับมาใช้ใหม่ได้ import * as aws from "@pulumi/aws"; import * as pulumi from "@pulumi/pulumi"; // Custom component ที่ห่อหุ้ม VPC subnet และ routing export class StandardVpc extends pulumi.ComponentResource { public readonly vpcId: pulumi.Output; public readonly publicSubnetIds: pulumi.Output[]; constructor(name: string, args: { cidr: string; azCount: number }, opts?: pulumi.ComponentResourceOptions) { super("mycompany:network:StandardVpc", name, {}, opts); const vpc = new aws.ec2.Vpc(`${name}-vpc`, { cidrBlock: args.cidr, enableDnsHostnames: true, tags: { Name: name }, }, { parent: this }); this.vpcId = vpc.id; // สร้าง public subnet ข้าม availability zone const azs = aws.getAvailabilityZones({ state: "available" }); this.publicSubnetIds = []; for (let i = 0; i < args.azCount; i++) { const subnet = new aws.ec2.Subnet(`${name}-public-${i}`, { vpcId: vpc.id, cidrBlock: `10.0.${i}.0/24`, availabilityZone: azs.then(az => az.names[i]), mapPublicIpOnLaunch: true, tags: { Name: `${name}-public-${i}` }, }, { parent: this }); this.publicSubnetIds.push(subnet.id); } this.registerOutputs({ vpcId: this.vpcId }); } } ``` Pulumi component นี้สร้าง VPC abstraction ที่นำกลับมาใช้ใหม่ได้ ผู้ใช้สร้างอินสแตนซ์ด้วย `new StandardVpc("prod", { cidr: "10.0.0.0/16", azCount: 3 })` สิ่งที่เทียบเท่าใน Terraform คือไดเรกทอรี module พร้อม variables outputs และไฟล์ HCL ทั้งสองแนวทางเปิดใช้งานการนำกลับมาใช้ใหม่ เวอร์ชัน Pulumi สืบทอด tooling TypeScript สำหรับเอกสาร การทดสอบ และการจัดเวอร์ชัน ## การจัดการ State และตัวเลือก Backend การจัดการ state คือจุดที่ความแตกต่างในการดำเนินงานปรากฏ State ของ Terraform มี resource ID provider metadata และ sensitive values ทีมต้องกำหนดค่า remote backend เพื่อการทำงานร่วมกันและใช้งาน locking เพื่อป้องกันการแก้ไขพร้อมกัน [การกำหนดค่า backend ของ Terraform](https://developer.hashicorp.com/terraform/language/settings/backends/configuration) รองรับ S3 Azure Blob Google Cloud Storage Terraform Cloud และอื่นๆ แต่ละ backend ต้องการการตั้งค่าการยืนยันตัวตนของตัวเอง State locking ใช้ DynamoDB สำหรับ S3 backend blob lease สำหรับ Azure หรือ native locking ใน Terraform Cloud Pulumi Cloud จัดการ state storage locking และประวัติโดยค่าเริ่มต้น ทีมสร้างบัญชีฟรี รัน `pulumi login` และการจัดการ state ก็กำหนดค่าเรียบร้อย สำหรับทีมที่ต้องการ self-managed state Pulumi รองรับ S3 Azure Blob GCS และ file backend ในเครื่องด้วยคำสั่ง `pulumi login` ```bash # Pulumi: เข้าสู่ระบบ self-managed S3 backend pulumi login s3://my-pulumi-state-bucket # Terraform: กำหนดค่า S3 backend ใน HCL # backend.tf terraform { backend "s3" { bucket = "my-terraform-state" key = "prod/terraform.tfstate" region = "us-east-1" dynamodb_table = "terraform-locks" encrypt = true } } ``` Pulumi Cloud มี web UI สำหรับประวัติ stack การแสดงภาพ resource และสิทธิ์ทีม Terraform Cloud เสนอฟีเจอร์ที่คล้ายกันพร้อมการบังคับใช้นโยบายผ่าน Sentinel ตัวเลือก self-hosted มีให้สำหรับทั้งคู่: self-hosted backend ของ Pulumi และ Terraform Enterprise ## ระบบนิเวศ Provider และการรองรับ Multi-Cloud ระบบนิเวศ provider ของ Terraform ใหญ่ที่สุดใน IaC [Terraform Registry](https://registry.terraform.io/) แสดงรายการมากกว่า 4,000 provider ครอบคลุม AWS Azure GCP Kubernetes และแพลตฟอร์ม SaaS หลายร้อยรายการ คุณภาพ provider แตกต่างกัน: provider อย่างเป็นทางการของ HashiCorp และ cloud vendor ได้รับการอัปเดตเป็นประจำ ในขณะที่ community provider อาจล้าหลังการเปลี่ยนแปลง API Provider ของ Pulumi ห่อหุ้ม provider ของ Terraform โดยใช้ bridge ที่สร้าง typed SDK [Pulumi Registry](https://www.pulumi.com/registry/) เปิดเผย provider สำหรับ cloud หลัก Kubernetes database และบริการ monitoring เนื่องจาก Pulumi bridge provider ของ Terraform ขอบเขตระบบนิเวศจึงเทียบเท่ากัน แม้ว่าเวอร์ชัน provider ของ Terraform ใหม่ต้องการการอัปเดต bridge ก่อนที่ SDK ของ Pulumi จะสะท้อนการเปลี่ยนแปลง Pulumi ยังเสนอ native provider ที่เขียนโดยตรงกับ cloud API Native provider สำหรับ AWS Azure และ Kubernetes ให้การสนับสนุนในวันเดียวกันสำหรับฟีเจอร์ API ใหม่ การแลกเปลี่ยนคือ native provider มีเฉพาะสำหรับ cloud หลัก บริการที่พบน้อยใช้ bridged provider ```typescript // ใช้ native AWS provider ของ Pulumi สำหรับ Lambda import * as aws from "@pulumi/aws"; import * as pulumi from "@pulumi/pulumi"; const role = new aws.iam.Role("lambda-role", { assumeRolePolicy: aws.iam.assumeRolePolicyForPrincipal({ Service: "lambda.amazonaws.com", }), }); const lambdaFunction = new aws.lambda.Function("api-handler", { runtime: aws.lambda.Runtime.NodeJS20dX, handler: "index.handler", role: role.arn, code: new pulumi.asset.AssetArchive({ "index.js": new pulumi.asset.StringAsset( `exports.handler = async () => ({ statusCode: 200, body: "OK" });` ), }), }); export const functionArn = lambdaFunction.arn; ``` ## การทดสอบ Infrastructure Code การทดสอบคือจุดที่การเลือกภาษาสร้างความแตกต่าง โปรแกรม Pulumi เป็นโค้ดมาตรฐาน ดังนั้น unit test ใช้ framework ที่คุ้นเคย โมดูล `@pulumi/pulumi/runtime` มี mocking สำหรับการสร้าง resource อนุญาตให้ test ตรวจสอบการกำหนดค่าโดยไม่ต้อง deploy resource ```typescript // __tests__/infra.test.ts - Unit testing resource Pulumi ด้วย Vitest import { describe, it, expect, beforeAll } from "vitest"; import * as pulumi from "@pulumi/pulumi"; // Mock Pulumi runtime pulumi.runtime.setMocks({ newResource: (args: pulumi.runtime.MockResourceArgs) => { return { id: `${args.name}-id`, state: args.inputs }; }, call: (args: pulumi.runtime.MockCallArgs) => { return args.inputs; }, }); describe("S3 Bucket Configuration", () => { let bucketTags: Record; beforeAll(async () => { // นำเข้าโปรแกรม Pulumi หลังจากตั้งค่า mock const infra = await import("../infra/index"); // ดึง output สำหรับการทดสอบ bucketTags = await new Promise(resolve => { infra.buckets[0].tags.apply(tags => resolve(tags as Record)); }); }); it("should tag buckets with Environment", () => { expect(bucketTags).toHaveProperty("Environment"); }); it("should tag buckets with ManagedBy", () => { expect(bucketTags.ManagedBy).toBe("pulumi"); }); }); ``` การทดสอบ Terraform ใช้ `terraform test` (เปิดตัวใน Terraform 1.6) หรือเครื่องมือภายนอกเช่น Terratest `terraform test` รันไฟล์ test HCL ที่สร้าง resource จริงในการกำหนดค่าที่แยก Terratest เป็นไลบรารี Go ที่ห่อหุ้มคำสั่ง Terraform และมี assertion ```hcl # tests/bucket.tftest.hcl - Test native ของ Terraform run "bucket_tags" { command = plan assert { condition = aws_s3_bucket.data["dev"].tags["Environment"] == "dev" error_message = "Bucket ต้องติดแท็ก Environment" } assert { condition = aws_s3_bucket.data["dev"].tags["ManagedBy"] == "terraform" error_message = "Bucket ต้องติดแท็ก ManagedBy" } } ``` ทั้งสองแนวทางตรวจสอบการกำหนดค่า infrastructure ข้อได้เปรียบของ Pulumi คือการรวมเข้ากับ test runner และ coverage tool ของ TypeScript Test native ของ Terraform ทำงานโดยไม่ต้องพึ่งพาภายนอกแต่ต้องการไวยากรณ์ HCL ## คำถามสัมภาษณ์: Pulumi vs Terraform การสัมภาษณ์ DevOps ในปี 2026 มักรวมการเปรียบเทียบเครื่องมือ IaC ต่อไปนี้คือคำถามที่แยกแยะผู้สมัครที่ใช้ทั้งสองเครื่องมือใน production **"เกิดอะไรขึ้นเมื่อ state ของ Terraform drift จาก infrastructure จริง?"** คำตอบที่คาดหวัง: `terraform plan` ตรวจจับ drift โดยเปรียบเทียบ state กับ infrastructure จริง Plan แสดง resource ที่ต้องอัปเดต สร้าง หรือทำลาย Drift เกิดขึ้นเมื่อมีการเปลี่ยนแปลงนอก Terraform (console CLI เครื่องมืออื่น) ตัวเลือกรวมถึง `terraform refresh` เพื่ออัปเดต state `terraform import` เพื่อนำ resource เข้าสู่การจัดการ หรือยอมรับ plan เพื่อกู้คืน desired state **"Pulumi จัดการ secret ต่างจาก Terraform อย่างไร?"** คำตอบที่คาดหวัง: Pulumi เข้ารหัส secret ใน state โดยค่าเริ่มต้นโดยใช้ passphrase หรือ cloud KMS ฟังก์ชัน `pulumi.secret()` ทำเครื่องหมายค่าว่าละเอียดอ่อน และยังคงเข้ารหัสเมื่อจัดเก็บ Terraform จัดเก็บ secret เป็น plaintext ในไฟล์ state ทีมพึ่งพาการเข้ารหัส backend (การเข้ารหัสฝั่งเซิร์ฟเวอร์ S3) และ access control Terraform 1.4 เพิ่มการทำเครื่องหมายตัวแปร `sensitive` แต่ค่ายังคงปรากฏโดยไม่เข้ารหัสใน state **"ทำไม HashiCorp ถึงยกเลิก CDKTF และตัวเลือกการย้ายคืออะไร?"** คำตอบที่คาดหวัง: CDKTF เพิ่มภาระการบำรุงรักษาโดยไม่ตรงกับจังหวะการอัปเดตของ Terraform เวอร์ชัน provider ใหม่และฟีเจอร์ Terraform ต้องการการอัปเดต CDK binding ด้วยตนเอง HashiCorp เลือกที่จะมุ่งเน้นไปที่ HCL และ Terraform Cloud ตัวเลือกการย้ายคือ: แปลงเป็น HCL โดยใช้ `cdktf convert` เขียนใหม่ใน Pulumi หากต้องการ TypeScript หรือดำเนินการ stack CDKTF ที่มีอยู่ต่อไปโดยไม่มีการอัปเดต **"เมื่อใดควรเลือก Pulumi แทน Terraform สำหรับโปรเจกต์ใหม่?"** คำตอบที่คาดหวัง: เลือก Pulumi เมื่อทีมใช้ TypeScript/Python/Go อยู่แล้วและต้องการ IaC ในภาษาเดียวกับโค้ดแอปพลิเคชัน เมื่อการนามธรรมที่ซับซ้อนต้องการโครงสร้างการเขียนโปรแกรมจริง (generic interface testing framework) หรือเมื่อการเข้ารหัส secret ในตัวเป็นข้อกำหนด เลือก Terraform เมื่อทีมรู้จัก HCL เมื่อระบบนิเวศ provider ต้องรวม provider เฉพาะทางหรือ community หรือเมื่อ tooling องค์กร (Atlantis Spacelift) รวมเข้ากับ Terraform สำหรับการเตรียมสัมภาษณ์ infrastructure as code เพิ่มเติม ดู [คำถามสัมภาษณ์ Terraform: คู่มือครบถ้วน Infrastructure as Code](/blog/devops/terraform-interview-questions-infrastructure-as-code) และ [โมดูล Terraform Advanced](/technologies/devops/interview-questions/terraform-advanced) ## กลยุทธ์การย้าย: Terraform ไปยัง Pulumi Pulumi มี `pulumi import` เพื่อนำ cloud resource ที่มีอยู่เข้าสู่การจัดการโดยไม่ต้องสร้างใหม่ สำหรับทีมที่มี state Terraform `pulumi convert` แปล HCL เป็นโปรแกรม Pulumi การแปลงไม่สมบูรณ์แบบ: module ที่ซับซ้อนและ dynamic block ต้องการการปรับแต่งด้วยตนเอง ```bash # แปลง Terraform HCL เป็น Pulumi TypeScript pulumi convert --from terraform --language typescript # นำเข้า resource AWS ที่มีอยู่เข้าสู่ state Pulumi pulumi import aws:s3/bucketV2:BucketV2 my-bucket my-existing-bucket-name ``` การย้ายแบบเป็นขั้นตอนอนุญาตให้ทีมรันทั้งสองเครื่องมือระหว่างการเปลี่ยนผ่าน Terraform จัดการ stack ที่มีอยู่ในขณะที่ Pulumi จัดเตรียม infrastructure ใหม่ เมื่อทีมได้รับประสบการณ์ Pulumi พวกเขาแปลง stack Terraform ทีละน้อย State ไม่ได้แชร์ระหว่างเครื่องมือ ดังนั้นการจัดการ resource ต้องแบ่งอย่างชัดเจนเพื่อหลีกเลี่ยงความขัดแย้ง ## กรอบการตัดสินใจสำหรับปี 2026 | ปัจจัย | Terraform | Pulumi | |--------|-----------|--------| | ภาษา | HCL (DSL) | TypeScript Python Go C# Java YAML | | การจัดการ state | Self-managed หรือ Terraform Cloud | Pulumi Cloud (ค่าเริ่มต้น) หรือ self-managed | | การจัดการ secret | Plaintext ใน state การเข้ารหัส backend | เข้ารหัสโดยค่าเริ่มต้น | | การทดสอบ | `terraform test` Terratest | Framework test ภาษาดั้งเดิม | | ขอบเขต provider | 4,000+ ใน registry | Bridge provider Terraform + SDK native | | การรองรับ TypeScript | CDKTF (ยกเลิกธันวาคม 2025) | First-class ดูแลอย่างแข็งขัน | | ความยากในการเรียนรู้ | HCL สร้างมาเพื่อวัตถุประสงค์ เรียนรู้เร็วสำหรับ IaC | ต้องการความรู้ภาษาที่มีอยู่ | | ฟีเจอร์ enterprise | Terraform Cloud/Enterprise | Pulumi Cloud/self-hosted | > **เคล็ดลับสัมภาษณ์** > > เมื่อถูกถามเกี่ยวกับ Pulumi vs Terraform หลีกเลี่ยงการระบุว่าอันใดอันหนึ่ง "ดีกว่า" อธิบายการแลกเปลี่ยน: Terraform มีระบบนิเวศที่ใหญ่กว่าและข้อจำกัดของ HCL ป้องกัน runtime error Pulumi เสนอฟีเจอร์ภาษาจริงและ typed SDK แสดงให้เห็นว่าการเลือกขึ้นอยู่กับทักษะทีม tooling ที่มีอยู่ และข้อกำหนดโปรเจกต์ ## ประเด็นสำคัญสำหรับ Infrastructure as Code ในปี 2026 - Terraform 1.16 เป็นตัวเลือกที่มั่นคงสำหรับ IaC ที่ใช้ HCL พร้อมระบบนิเวศ provider ที่ใหญ่ที่สุดและ tooling ที่สมบูรณ์ (Atlantis Spacelift env0) - Pulumi v3.263 เสนอ TypeScript Python Go และ C# พร้อมการทดสอบภาษาดั้งเดิม การรวม IDE และการเข้ารหัส secret ในตัว - CDKTF ยกเลิกตั้งแต่ธันวาคม 2025 ทีมที่ต้องการ TypeScript IaC ควรประเมิน Pulumi แทนที่จะเริ่มโปรเจกต์ CDKTF ใหม่ - ทั้งสองเครื่องมือรองรับการ deploy multi-cloud remote state backend และการทำงานร่วมกันของทีม การเลือกขึ้นอยู่กับความชอบภาษาและความเชี่ยวชาญของทีมที่มีอยู่ - การสนทนาในการสัมภาษณ์ควรแสดงความเข้าใจเกี่ยวกับการจัดการ state การตรวจจับ drift ระบบนิเวศ provider และการแลกเปลี่ยนระหว่างความเรียบง่ายของ DSL และพลังของภาษาโปรแกรมทั่วไป - การย้ายจาก Terraform ไปยัง Pulumi เป็นไปได้โดยใช้ `pulumi convert` และ `pulumi import` แต่ต้องการการวางแผนอย่างรอบคอบและการเปิดตัวแบบเป็นขั้นตอน --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/th/blog/devops/pulumi-vs-terraform-2026-infrastructure-as-code-typescript-interview-questions