Infrastructure as Code (IaC) เป็นแนวทางสำคัญในการบริหารจัดการ Cloud Infrastructure ในปี 2026 แต่เครื่องมือยอดนิยมอย่าง Terraform บังคับให้เราเรียนรู้ภาษาเฉพาะทาง (HCL) ที่ไม่มีที่ไหนใช้นอกจาก Terraform คำถามคือ ทำไมเราต้องเรียนภาษาใหม่เพื่อจัดการ Infrastructure ในเมื่อเรามีภาษาโปรแกรมที่ทรงพลังอยู่แล้ว?
Pulumi คือคำตอบ — เครื่องมือ IaC ที่ให้คุณเขียน Infrastructure ด้วยภาษาโปรแกรมจริงที่คุณใช้อยู่แล้ว ไม่ว่าจะเป็น TypeScript, Python, Go, C#, Java หรือ YAML บทความนี้จะพาคุณรู้จัก Pulumi ตั้งแต่แนวคิดพื้นฐาน เปรียบเทียบกับ Terraform และลงมือสร้าง Infrastructure จริงบน AWS และ Azure
Pulumi คืออะไร?
Pulumi คือ Open-Source Infrastructure as Code Platform ที่ให้คุณสร้าง จัดการ และ Deploy Cloud Infrastructure ด้วยภาษาโปรแกรมที่คุณรู้จักดีอยู่แล้ว แทนที่จะเขียน Configuration File แบบ Declarative อย่าง HCL ของ Terraform คุณเขียน Code จริงที่มี Loop, Condition, Function, Class และทุกอย่างที่ภาษาโปรแกรมมีให้
Pulumi ก่อตั้งโดย Joe Duffy (อดีต Microsoft, ทีม .NET) ในปี 2018 ด้วยวิสัยทัศน์ว่า Infrastructure ควรจัดการด้วยเครื่องมือเดียวกับ Application Code ไม่ควรมี "ภาษาพิเศษ" ที่ต้องเรียนใหม่ Pulumi รองรับ Cloud Provider หลักทุกราย ทั้ง AWS, Azure, Google Cloud, Kubernetes, DigitalOcean และอีกกว่า 100 Provider
สิ่งที่ทำให้ Pulumi แตกต่างจาก IaC Tool อื่นๆ คือคุณได้ใช้ทุกความสามารถของภาษาโปรแกรม ตั้งแต่ IDE autocomplete, type checking, unit testing, code review ไปจนถึง package management ทำให้ Infrastructure Code มีคุณภาพสูงและบำรุงรักษาง่ายเหมือน Application Code
Pulumi vs Terraform — เปรียบเทียบละเอียด
| คุณสมบัติ | Pulumi | Terraform |
|---|---|---|
| ภาษา | TypeScript, Python, Go, C#, Java, YAML | HCL (HashiCorp Configuration Language) |
| Type Safety | มี (TypeScript, Go) | จำกัด |
| IDE Support | ดีเยี่ยม (autocomplete, type checking) | จำกัด |
| Testing | Unit Test, Integration Test ด้วยภาษาเดียวกัน | terraform test (จำกัด) |
| Loops/Conditions | Native (for, if, map, filter) | count, for_each, dynamic (ซับซ้อน) |
| State Management | Pulumi Cloud, S3, Azure Blob, Local | Terraform Cloud, S3, Local |
| Secrets | Built-in encryption | ต้องใช้ Vault หรือ external |
| Providers | 100+ (ใช้ Terraform providers ได้ด้วย) | 3000+ |
| Pricing | Free (self-hosted) / Paid (Cloud) | Free (CLI) / Paid (Cloud) |
| Learning Curve | ต่ำ (ถ้ารู้ภาษาอยู่แล้ว) | ต้องเรียน HCL ใหม่ |
| Community | เติบโตเร็ว | ใหญ่ที่สุด |
| License | Apache 2.0 | BSL (เปลี่ยนจาก MPL) |
Pulumi Concepts — แนวคิดหลัก
Project
Project คือโฟลเดอร์ที่มี Pulumi.yaml ซึ่งกำหนด Runtime (TypeScript, Python, Go) และ Description
Stack
Stack คือ Instance ของ Project ที่มี Configuration เฉพาะ เช่น dev, staging, production แต่ละ Stack มี State แยกกัน
Resource
Resource คือ Cloud Resource ที่ Pulumi จัดการ เช่น S3 Bucket, EC2 Instance, Lambda Function ทุกอย่างที่สร้างบน Cloud คือ Resource
Output
Output คือค่าที่ได้จาก Resource หลังจากสร้างเสร็จ เช่น URL ของ S3 Bucket, IP Address ของ VM ใช้สำหรับส่งค่าระหว่าง Resource หรือแสดงผลลัพธ์
Provider
Provider คือ Plugin ที่เชื่อมต่อ Pulumi กับ Cloud Provider เช่น AWS Provider, Azure Provider, Kubernetes Provider
# โครงสร้างโปรเจกต์ Pulumi
my-infra/
├── Pulumi.yaml # Project config
├── Pulumi.dev.yaml # Stack config (dev)
├── Pulumi.prod.yaml # Stack config (prod)
├── index.ts # Infrastructure code
├── package.json
└── tsconfig.json
เริ่มต้นกับ Pulumi
ติดตั้ง Pulumi CLI
# macOS / Linux
curl -fsSL https://get.pulumi.com | sh
# Windows (PowerShell)
iwr https://get.pulumi.com/install.ps1 -UseBasicParsing | iex
# Homebrew
brew install pulumi
# ตรวจสอบ
pulumi version
# Login (ใช้ Pulumi Cloud ฟรี หรือ Local)
pulumi login # Pulumi Cloud
pulumi login --local # Local state
pulumi login s3://my-bucket # S3 backend
สร้างโปรเจกต์ใหม่
# TypeScript
pulumi new aws-typescript
# Python
pulumi new aws-python
# Go
pulumi new aws-go
# เลือก template
pulumi new --list-templates
Pulumi with TypeScript — ตัวอย่าง AWS S3 + Lambda
TypeScript เป็นภาษาที่ได้รับความนิยมมากที่สุดกับ Pulumi เพราะมี Type Safety ที่ดีเยี่ยม IDE autocomplete ทำงานได้สมบูรณ์ และ Error จะถูกจับตั้งแต่ตอนเขียน ไม่ต้องรอ Plan/Apply
// index.ts — สร้าง S3 Bucket + Lambda Function
import * as pulumi from "@pulumi/pulumi"
import * as aws from "@pulumi/aws"
// สร้าง S3 Bucket
const bucket = new aws.s3.Bucket("my-bucket", {
website: {
indexDocument: "index.html",
errorDocument: "error.html",
},
tags: {
Environment: pulumi.getStack(), // "dev" หรือ "prod"
ManagedBy: "Pulumi",
},
})
// อัพโหลดไฟล์
const indexHtml = new aws.s3.BucketObject("index", {
bucket: bucket.id,
key: "index.html",
content: "<h1>Hello from Pulumi!</h1>",
contentType: "text/html",
})
// สร้าง IAM Role สำหรับ Lambda
const lambdaRole = new aws.iam.Role("lambda-role", {
assumeRolePolicy: JSON.stringify({
Version: "2012-10-17",
Statement: [{
Action: "sts:AssumeRole",
Effect: "Allow",
Principal: { Service: "lambda.amazonaws.com" },
}],
}),
})
// Attach Policy
new aws.iam.RolePolicyAttachment("lambda-basic", {
role: lambdaRole.name,
policyArn: aws.iam.ManagedPolicy.AWSLambdaBasicExecutionRole,
})
// สร้าง Lambda Function
const lambda = new aws.lambda.Function("my-function", {
runtime: "nodejs20.x",
handler: "index.handler",
role: lambdaRole.arn,
code: new pulumi.asset.AssetArchive({
"index.js": new pulumi.asset.StringAsset(`
exports.handler = async (event) => {
return {
statusCode: 200,
body: JSON.stringify({ message: "Hello from Lambda!" }),
};
};
`),
}),
environment: {
variables: {
BUCKET_NAME: bucket.id,
},
},
})
// Export outputs
export const bucketUrl = bucket.websiteEndpoint
export const lambdaArn = lambda.arn
export const stackName = pulumi.getStack()
JSON.stringify(), template literals, และ variables ได้ตามปกติ ไม่มี DSL พิเศษ IDE จะ autocomplete ทุก property ของทุก Resource ให้คุณ
Pulumi with Python — ตัวอย่าง Azure VM
# __main__.py — สร้าง Azure VM
import pulumi
import pulumi_azure_native as azure
# สร้าง Resource Group
resource_group = azure.resources.ResourceGroup("my-rg",
location="southeastasia",
tags={
"Environment": pulumi.get_stack(),
"ManagedBy": "Pulumi",
}
)
# สร้าง Virtual Network
vnet = azure.network.VirtualNetwork("my-vnet",
resource_group_name=resource_group.name,
location=resource_group.location,
address_space=azure.network.AddressSpaceArgs(
address_prefixes=["10.0.0.0/16"],
),
)
# สร้าง Subnet
subnet = azure.network.Subnet("my-subnet",
resource_group_name=resource_group.name,
virtual_network_name=vnet.name,
address_prefix="10.0.1.0/24",
)
# สร้าง Public IP
public_ip = azure.network.PublicIPAddress("my-ip",
resource_group_name=resource_group.name,
location=resource_group.location,
public_ip_allocation_method="Dynamic",
)
# สร้าง NIC
nic = azure.network.NetworkInterface("my-nic",
resource_group_name=resource_group.name,
location=resource_group.location,
ip_configurations=[azure.network.NetworkInterfaceIPConfigurationArgs(
name="ipconfig1",
subnet=azure.network.SubnetArgs(id=subnet.id),
public_ip_address=azure.network.PublicIPAddressArgs(id=public_ip.id),
)],
)
# สร้าง VM
vm = azure.compute.VirtualMachine("my-vm",
resource_group_name=resource_group.name,
location=resource_group.location,
vm_size="Standard_B2s",
network_profile=azure.compute.NetworkProfileArgs(
network_interfaces=[azure.compute.NetworkInterfaceReferenceArgs(
id=nic.id,
primary=True,
)],
),
os_profile=azure.compute.OSProfileArgs(
computer_name="myvm",
admin_username="azureuser",
admin_password="P@ssw0rd1234!",
),
storage_profile=azure.compute.StorageProfileArgs(
image_reference=azure.compute.ImageReferenceArgs(
publisher="Canonical",
offer="0001-com-ubuntu-server-jammy",
sku="22_04-lts",
version="latest",
),
os_disk=azure.compute.OSDiskArgs(
create_option="FromImage",
managed_disk=azure.compute.ManagedDiskParametersArgs(
storage_account_type="Standard_LRS",
),
),
),
)
# Export
pulumi.export("resource_group_name", resource_group.name)
pulumi.export("vm_name", vm.name)
pulumi.export("public_ip", public_ip.ip_address)
Pulumi with Go
// main.go — สร้าง AWS S3 Bucket ด้วย Go
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
// สร้าง S3 Bucket
bucket, err := s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{
Website: &s3.BucketWebsiteArgs{
IndexDocument: pulumi.String("index.html"),
},
Tags: pulumi.StringMap{
"Environment": pulumi.String(ctx.Stack()),
"ManagedBy": pulumi.String("Pulumi"),
},
})
if err != nil {
return err
}
// Export
ctx.Export("bucketName", bucket.Bucket)
ctx.Export("bucketUrl", bucket.WebsiteEndpoint)
return nil
})
}
Pulumi CLI — คำสั่งสำคัญ
# Preview — ดูว่าจะเปลี่ยนอะไรบ้าง (เหมือน terraform plan)
pulumi preview
# Up — สร้าง/อัพเดท Infrastructure (เหมือน terraform apply)
pulumi up
# Destroy — ลบ Infrastructure ทั้งหมด
pulumi destroy
# Stack management
pulumi stack ls # ดู Stacks ทั้งหมด
pulumi stack select dev # เลือก Stack
pulumi stack init staging # สร้าง Stack ใหม่
pulumi stack rm old-stack # ลบ Stack
# Config management
pulumi config set aws:region ap-southeast-1
pulumi config set dbPassword secret123 --secret
pulumi config get aws:region
# Outputs
pulumi stack output # ดู Outputs ทั้งหมด
pulumi stack output bucketUrl # ดู Output เฉพาะตัว
# Import existing resources
pulumi import aws:s3:Bucket my-bucket existing-bucket-name
# Refresh state
pulumi refresh
# History
pulumi stack history
State Management
Pulumi ต้องเก็บ State เพื่อ Track ว่า Infrastructure ปัจจุบันมีอะไรบ้าง มี Backend หลายแบบให้เลือก:
Pulumi Cloud (ค่าเริ่มต้น)
# ฟรีสำหรับ Individual
pulumi login
# State เก็บบน app.pulumi.com
# มี UI Dashboard, Audit Log, Team Management
Self-Managed Backends
# AWS S3
pulumi login s3://my-pulumi-state
# Azure Blob Storage
pulumi login azblob://my-container
# Google Cloud Storage
pulumi login gs://my-pulumi-state
# Local filesystem
pulumi login --local
# State เก็บใน ~/.pulumi
Secrets Management — จัดการข้อมูลลับ
Pulumi มี Built-in Secrets Management ที่เข้ารหัส Secrets ในทุก State file โดยอัตโนมัติ ไม่ต้องใช้ External Tool อย่าง HashiCorp Vault
# ตั้งค่า Secret
pulumi config set dbPassword "my-secret-password" --secret
pulumi config set apiKey "sk-1234567890" --secret
# ใช้ใน Code
const config = new pulumi.Config()
const dbPassword = config.requireSecret("dbPassword")
// dbPassword เป็น Output<string> ที่เข้ารหัส
// ไม่แสดงค่าจริงใน logs หรือ state
# เลือก Encryption Provider
pulumi stack init dev --secrets-provider="awskms://alias/my-key"
pulumi stack init dev --secrets-provider="gcpkms://projects/my-proj/locations/global/keyRings/my-ring/cryptoKeys/my-key"
Testing Pulumi Programs
หนึ่งในข้อดีที่สำคัญที่สุดของ Pulumi คือความสามารถในการเขียน Test สำหรับ Infrastructure Code ด้วยเครื่องมือ Testing ที่ใช้กันทั่วไป เช่น Jest, pytest, go test
Unit Tests (TypeScript + Jest)
// infra.test.ts
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) => ({}),
})
describe("Infrastructure", () => {
let infra: typeof import("./index")
beforeAll(async () => {
infra = await import("./index")
})
it("S3 bucket should have website config", (done) => {
pulumi.all([infra.bucketUrl]).apply(([url]) => {
expect(url).toBeDefined()
done()
})
})
it("Lambda should have correct runtime", (done) => {
// ตรวจสอบ Lambda configuration
pulumi.all([infra.lambdaArn]).apply(([arn]) => {
expect(arn).toContain("my-function")
done()
})
})
})
Property Tests (Policy as Code)
// ตรวจสอบว่า S3 Bucket ต้องเปิด encryption เสมอ
import * as policy from "@pulumi/policy"
new policy.PolicyPack("aws-best-practices", {
policies: [
{
name: "s3-encryption-required",
description: "S3 buckets must have encryption enabled",
enforcementLevel: "mandatory",
validateResource: policy.validateResourceOfType(
aws.s3.Bucket,
(bucket, args, reportViolation) => {
if (!bucket.serverSideEncryptionConfiguration) {
reportViolation("S3 bucket must have encryption enabled")
}
}
),
},
{
name: "no-public-s3",
description: "S3 buckets must not be publicly accessible",
enforcementLevel: "mandatory",
validateResource: policy.validateResourceOfType(
aws.s3.BucketPublicAccessBlock,
(block, args, reportViolation) => {
if (!block.blockPublicAcls) {
reportViolation("S3 bucket must block public ACLs")
}
}
),
},
],
})
Pulumi Automation API — Programmatic IaC
Automation API เป็นฟีเจอร์ที่ทรงพลังของ Pulumi ที่ทำให้คุณสามารถควบคุม Pulumi ผ่าน Code แทนที่จะใช้ CLI เหมาะสำหรับสร้าง Internal Developer Platform, Self-Service Portal หรือ Custom CI/CD Pipeline
// automation.ts — สร้าง Infrastructure ผ่าน Code
import { LocalWorkspace, Stack } from "@pulumi/pulumi/automation"
async function createInfra(stackName: string, region: string) {
// กำหนด Pulumi program inline
const program = async () => {
const aws = require("@pulumi/aws")
const bucket = new aws.s3.Bucket("auto-bucket", {
tags: { Stack: stackName },
})
return { bucketName: bucket.id }
}
// สร้างหรือเลือก Stack
const stack = await LocalWorkspace.createOrSelectStack({
stackName,
projectName: "auto-infra",
program,
})
// ตั้งค่า
await stack.setConfig("aws:region", { value: region })
// Preview
const preview = await stack.preview()
console.log("Changes:", preview.changeSummary)
// Deploy
const result = await stack.up({ onOutput: console.log })
console.log("Outputs:", result.outputs)
return result.outputs
}
// ใช้ใน Express/Hono API
app.post('/api/create-env', async (req, res) => {
const { name, region } = req.body
const outputs = await createInfra(name, region)
res.json({ success: true, outputs })
})
Pulumi AI — Natural Language to IaC
Pulumi AI เป็นฟีเจอร์ใหม่ในปี 2025-2026 ที่ใช้ AI เพื่อสร้าง Infrastructure Code จากคำอธิบายภาษาธรรมชาติ คุณเพียงแค่บอกว่าต้องการอะไร แล้ว Pulumi AI จะสร้าง Code ให้
# ใช้ Pulumi AI ผ่าน CLI
pulumi ai "Create an S3 bucket with encryption and a Lambda function that processes uploaded files"
# หรือใช้ผ่านเว็บ
# https://www.pulumi.com/ai
Pulumi AI สร้าง Code ที่ถูกต้องตาม Best Practices และรองรับหลาย Cloud Provider ช่วยให้เริ่มต้นโปรเจกต์ได้เร็วขึ้นมาก แม้จะยังต้อง Review และปรับแต่ง Code ที่ได้ แต่ก็ช่วยลดเวลาในการเขียน Boilerplate อย่างมาก
Pulumi CrossGuard — Policy as Code
CrossGuard เป็นระบบ Policy as Code ของ Pulumi ที่ให้คุณกำหนดกฎเกณฑ์ว่า Infrastructure ต้องเป็นไปตาม Standard อะไรบ้าง เช่น ห้ามสร้าง Public S3 Bucket ต้องเปิด Encryption เสมอ ห้ามใช้ Instance ที่ใหญ่เกินไป
// policy/index.ts
import * as policy from "@pulumi/policy"
new policy.PolicyPack("company-policies", {
policies: [
{
name: "required-tags",
description: "All resources must have required tags",
enforcementLevel: "mandatory",
validateResource: (args, reportViolation) => {
if (args.props.tags) {
const tags = args.props.tags
if (!tags.Environment) {
reportViolation("Resource must have 'Environment' tag")
}
if (!tags.Team) {
reportViolation("Resource must have 'Team' tag")
}
}
},
},
{
name: "max-instance-size",
description: "EC2 instances must not exceed t3.xlarge",
enforcementLevel: "advisory",
validateResource: policy.validateResourceOfType(
aws.ec2.Instance,
(instance, args, reportViolation) => {
const allowed = ["t3.micro", "t3.small", "t3.medium", "t3.large", "t3.xlarge"]
if (!allowed.includes(instance.instanceType)) {
reportViolation(`Instance type ${instance.instanceType} exceeds maximum allowed size`)
}
}
),
},
],
})
# ใช้ Policy Pack
# pulumi up --policy-pack ./policy
Pulumi vs CDK
AWS CDK (Cloud Development Kit) เป็นอีกเครื่องมือ IaC ที่ใช้ภาษาโปรแกรมจริง แต่ต่างจาก Pulumi ตรงที่ CDK ผูกติดกับ AWS เท่านั้น ในขณะที่ Pulumi รองรับทุก Cloud Provider
| คุณสมบัติ | Pulumi | AWS CDK |
|---|---|---|
| Cloud Provider | ทุก Provider (AWS, Azure, GCP, K8s, ...) | AWS เท่านั้น |
| ภาษา | TypeScript, Python, Go, C#, Java | TypeScript, Python, Java, C#, Go |
| State | Pulumi-managed | CloudFormation (ช้า) |
| Deploy Speed | เร็ว (Direct API calls) | ช้า (ผ่าน CloudFormation) |
| Multi-Cloud | รองรับ | ไม่รองรับ |
| Drift Detection | pulumi refresh | CloudFormation drift detection |
Pulumi for Kubernetes
Pulumi จัดการ Kubernetes ได้ดีเยี่ยม ทั้งการสร้าง Cluster และ Deploy Application ด้วย Code เดียวกัน ไม่ต้องสลับระหว่าง Terraform กับ kubectl/Helm
import * as k8s from "@pulumi/kubernetes"
import * as pulumi from "@pulumi/pulumi"
// Deploy Nginx
const appLabels = { app: "nginx" }
const deployment = new k8s.apps.v1.Deployment("nginx", {
spec: {
replicas: 3,
selector: { matchLabels: appLabels },
template: {
metadata: { labels: appLabels },
spec: {
containers: [{
name: "nginx",
image: "nginx:1.25",
ports: [{ containerPort: 80 }],
resources: {
requests: { cpu: "100m", memory: "128Mi" },
limits: { cpu: "250m", memory: "256Mi" },
},
}],
},
},
},
})
const service = new k8s.core.v1.Service("nginx-svc", {
spec: {
type: "LoadBalancer",
selector: appLabels,
ports: [{ port: 80, targetPort: 80 }],
},
})
export const serviceUrl = service.status.apply(
s => `http://${s?.loadBalancer?.ingress?.[0]?.hostname || "pending"}`
)
CI/CD Integration
Pulumi รองรับ CI/CD Pipeline ยอดนิยมทั้งหมด ทำให้ Infrastructure Deployment เป็น Automated Pipeline เหมือน Application Code
# GitHub Actions
# .github/workflows/infra.yml
name: Pulumi Deploy
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm install
# Preview on PR
- uses: pulumi/actions@v5
if: github.event_name == 'pull_request'
with:
command: preview
stack-name: dev
comment-on-pr: true
env:
PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
# Deploy on merge
- uses: pulumi/actions@v5
if: github.event_name == 'push'
with:
command: up
stack-name: prod
env:
PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
เมื่อไหร่ควรเลือก Pulumi แทน Terraform?
Pulumi เหมาะที่สุดในสถานการณ์เหล่านี้:
- ทีมเขียน TypeScript/Python/Go อยู่แล้ว — ไม่ต้องเรียน HCL ใหม่ ใช้ภาษาเดิมที่ชำนาญ
- ต้องการ Testing ที่ดี — Unit Test, Integration Test ด้วยเครื่องมือที่ใช้อยู่ (Jest, pytest, go test)
- ต้องการ Type Safety — TypeScript + Pulumi = IDE autocomplete ทุก property ของทุก Resource
- Logic ซับซ้อน — Loop, Condition, Function ของภาษาจริงง่ายกว่า HCL count/for_each มาก
- Multi-Cloud — จัดการ AWS + Azure + GCP ด้วย Code ชุดเดียว
- Internal Platform — Automation API ทำให้สร้าง Self-Service Portal ได้ง่าย
- Secrets Management — Built-in encryption ไม่ต้องพึ่ง External tool
- ต้องการ Open Source แท้ — Pulumi เป็น Apache 2.0 ในขณะที่ Terraform เปลี่ยนเป็น BSL
ยังใช้ Terraform ได้ถ้า:
- ทีมใช้ Terraform อยู่แล้วและมี HCL จำนวนมาก การย้ายไม่คุ้ม
- ต้องการ Provider ที่หลากหลายที่สุด (Terraform มี 3000+ providers)
- ทีม Ops ที่ไม่เขียน Code เป็นหลัก HCL อาจเรียนง่ายกว่า
สรุป
Pulumi เป็นเครื่องมือ Infrastructure as Code ที่เปลี่ยนแนวคิดการจัดการ Cloud Infrastructure ในปี 2026 ด้วยการใช้ภาษาโปรแกรมจริงแทน DSL เฉพาะทาง ทำให้ Developer สามารถจัดการ Infrastructure ด้วยเครื่องมือและทักษะที่มีอยู่แล้ว ไม่ต้องเรียนภาษาใหม่ ไม่ต้องใช้เครื่องมือใหม่
ถ้าคุณกำลังเริ่มต้น IaC ในปี 2026 หรือกำลังมองหาทางเลือกจาก Terraform ลองติดตั้ง Pulumi และเขียน Infrastructure ด้วย TypeScript หรือ Python ที่คุณรู้จัก คุณจะพบว่า Infrastructure Code สามารถมี Type Safety, Unit Test, Code Review และทุกอย่างที่ Application Code มีได้ เริ่มต้นวันนี้ด้วย pulumi new แล้วคุณจะเข้าใจว่าทำไม Pulumi ถึงเติบโตเร็วที่สุดใน IaC space
