#บทนำ

Pulumi เป็นเครื่องมือ Infrastructure as Code (IaC) ที่ช่วยกำหนดและจัดการทรัพยากร Cloud ด้วยภาษาโปรแกรม เช่น TypeScript, Python, Go และ C# ใน Workshop นี้ใช้ TypeScript เพื่อสร้าง Google Compute Engine VM พร้อม Firewall สำหรับ HTTP และ SSH

ข้อควรระวัง: การสร้าง VM, Persistent Disk และ External IP อาจมีค่าใช้จ่าย ควรใช้โปรเจกต์ทดลองและสั่ง pulumi destroy หลังเสร็จสิ้น

#สถาปัตยกรรม

flowchart LR
  Developer[Developer / Pulumi CLI] --> GCP[Google Cloud API]
  GCP --> VPC[VPC Network]
  VPC --> Firewall[Firewall TCP 80 / 22]
  VPC --> VM[Compute Engine VM]
  VM --> Web[Nginx Web Server]

#สิ่งที่ต้องเตรียม

  • Google Cloud Project ที่เปิด Billing และ Compute Engine API
  • Google Cloud CLI (gcloud), Node.js LTS, Pulumi CLI
  • สิทธิ์สำหรับสร้าง Compute Engine, VPC และ Firewall

#1. เข้าสู่ระบบและเลือกโปรเจกต์

gcloud auth login
gcloud auth application-default login
gcloud config set project YOUR_PROJECT_ID
gcloud services enable compute.googleapis.com
pulumi login

#2. สร้างโปรเจกต์ Pulumi

mkdir pulumi-gcp-vm && cd pulumi-gcp-vm
pulumi new gcp-typescript
npm install
pulumi config set gcp:project YOUR_PROJECT_ID
pulumi config set gcp:region asia-southeast1
pulumi config set gcp:zone asia-southeast1-b

#3. เขียน Infrastructure ใน index.ts

import * as gcp from "@pulumi/gcp";

const config = new gcp.config.Config();
const zone = config.zone || "asia-southeast1-b";

const network = new gcp.compute.Network("workshop-vpc", {
  autoCreateSubnetworks: true,
});

const firewall = new gcp.compute.Firewall("workshop-web-fw", {
  network: network.id,
  allows: [
    { protocol: "tcp", ports: ["80"] },
    { protocol: "tcp", ports: ["22"] },
  ],
  sourceRanges: ["0.0.0.0/0"],
  targetTags: ["workshop-web"],
});

const startupScript = `#!/bin/bash
apt-get update
apt-get install -y nginx
systemctl enable --now nginx
echo '<h1>Hello from Pulumi on Google Compute Engine</h1>' > /var/www/html/index.html
`;

const vm = new gcp.compute.Instance("workshop-vm", {
  zone,
  machineType: "e2-micro",
  bootDisk: {
    initializeParams: { image: "debian-cloud/debian-12", size: 10 },
  },
  networkInterfaces: [{
    network: network.id,
    accessConfigs: [{}],
  }],
  tags: ["workshop-web"],
  metadataStartupScript: startupScript,
  labels: { environment: "workshop" },
});

export const vmName = vm.name;
export const externalIp = vm.networkInterfaces.apply(
  interfaces => interfaces[0].accessConfigs?.[0]?.natIp
);
export const webUrl = vm.networkInterfaces.apply(
  interfaces => `http://${interfaces[0].accessConfigs?.[0]?.natIp}`
);

หมายเหตุ: ตัวอย่างเปิด SSH จากทุก IP เพื่อความสะดวกในการทดลองเท่านั้น งานจริงควรจำกัด sourceRanges สำหรับพอร์ต 22 ให้เป็น IP ผู้ดูแล หรือใช้ Identity-Aware Proxy (IAP) แทน และควรใช้ HTTPS สำหรับระบบจริง

#4. ตรวจสอบแผนและ Deploy

pulumi preview
pulumi up
pulumi stack output webUrl

เปิด URL ที่ได้ในเบราว์เซอร์ อาจต้องรอ startup script ติดตั้ง Nginx สักครู่

#5. ตรวจสอบ VM

gcloud compute instances list
pulumi stack output vmName
curl "$(pulumi stack output webUrl)"

#6. อัปเดต Infrastructure

แก้ machineType หรือเนื้อหา startupScript ใน index.ts จากนั้นเรียก:

pulumi preview
pulumi up

Pulumi จะแสดงความเปลี่ยนแปลงก่อนยืนยันการ Deploy

#7. ลบทรัพยากรเพื่อหยุดค่าใช้จ่าย

pulumi destroy
pulumi stack rm

ตรวจสอบใน Google Cloud Console ว่าไม่มี VM, Disk หรือ IP ที่ไม่ต้องการหลงเหลือ

#แนวทาง Production

  • ใช้ Custom VPC และ Subnet พร้อม Firewall แบบ Least Privilege
  • จำกัด SSH หรือใช้ IAP; ใช้ HTTPS และ Load Balancer เมื่อเปิดบริการสาธารณะ
  • ใช้ Service Account เฉพาะงานและสิทธิ์ IAM เท่าที่จำเป็น
  • แยก Pulumi Stack สำหรับ dev/staging/prod และจัดการ Secrets อย่างปลอดภัย
  • ใช้ CI/CD รัน pulumi preview ก่อนอนุมัติ pulumi up
  • ติดตามค่าใช้จ่ายและตั้ง Budget Alerts

#สรุป

Pulumi ทำให้การสร้างและปรับปรุง Google Compute Engine เป็นกระบวนการที่ตรวจสอบย้อนหลังได้ ใช้โค้ดซ้ำได้ และต่อยอดเป็น CI/CD ได้ง่าย โดย Workshop นี้สาธิตการสร้าง VPC, Firewall และ VM ที่ให้บริการเว็บผ่าน Nginx

#เอกสารอ้างอิง