#บทนำ

Pulumi เป็นเครื่องมือ Infrastructure as Code (IaC) ที่ช่วยสร้างและจัดการโครงสร้างพื้นฐาน Cloud ด้วยภาษาโปรแกรม เช่น TypeScript, Python และ Go ใน Workshop นี้จะใช้ TypeScript สร้าง DigitalOcean Droplet และ Firewall พร้อมแสดง IP Address ของเครื่อง

ค่าใช้จ่าย: DigitalOcean คิดค่าบริการตามทรัพยากรที่ใช้งาน ตรวจสอบราคาปัจจุบันก่อนสร้าง Droplet และลบทรัพยากรหลังทดลอง

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

flowchart LR
  A[Developer] --> B[Pulumi CLI]
  B --> C[DigitalOcean API]
  C --> D[Droplet Ubuntu]
  C --> E[Cloud Firewall]
  E --> D
  D --> F[Public IPv4]

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

  • บัญชี DigitalOcean และ API Token ที่มีสิทธิ์จัดการ Droplets และ Firewalls
  • Node.js และ npm
  • Pulumi CLI
  • SSH public key ที่สร้างไว้ในเครื่อง

#ขั้นตอนที่ 1: สร้างโปรเจกต์

mkdir pulumi-do-droplet && cd pulumi-do-droplet
pulumi new typescript
npm install @pulumi/digitalocean

เลือกชื่อโปรเจกต์และ stack เช่น dev จากนั้นกำหนด token เป็น secret ของ Pulumi:

pulumi config set --secret digitalocean:token "$DIGITALOCEAN_TOKEN"

กำหนดตัวแปร DIGITALOCEAN_TOKEN ใน shell ก่อนเรียกคำสั่ง และหลีกเลี่ยงการบันทึก token ลงใน Git

#ขั้นตอนที่ 2: ตั้งค่า SSH Key

ssh-keygen -t ed25519 -C "pulumi-do-workshop"

เพิ่ม public key (~/.ssh/id_ed25519.pub) ไปยัง DigitalOcean → Settings → Security → SSH Keys แล้วคัดลอก fingerprint ของ key มาใช้เป็น config:

pulumi config set sshFingerprint "YOUR_SSH_KEY_FINGERPRINT"

#ขั้นตอนที่ 3: เขียน Infrastructure ด้วย TypeScript

แทนที่ไฟล์ index.ts ด้วยโค้ดต่อไปนี้:

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

const config = new pulumi.Config();
const sshFingerprint = config.require("sshFingerprint");

const droplet = new digitalocean.Droplet("web-droplet", {
    name: "pulumi-web-dev",
    region: "sgp1",
    size: "s-1vcpu-1gb",
    image: "ubuntu-24-04-x64",
    sshKeys: [sshFingerprint],
    tags: ["pulumi", "workshop"],
});

const firewall = new digitalocean.Firewall("web-firewall", {
    name: "pulumi-web-firewall",
    dropletIds: [droplet.id.apply(Number)],
    inboundRules: [
        {
            protocol: "tcp",
            portRange: "22",
            sourceAddresses: ["YOUR_PUBLIC_IP/32"],
        },
        {
            protocol: "tcp",
            portRange: "80",
            sourceAddresses: ["0.0.0.0/0", "::/0"],
        },
    ],
    outboundRules: [
        {
            protocol: "tcp",
            portRange: "1-65535",
            destinationAddresses: ["0.0.0.0/0", "::/0"],
        },
        {
            protocol: "udp",
            portRange: "1-65535",
            destinationAddresses: ["0.0.0.0/0", "::/0"],
        },
        {
            protocol: "icmp",
            destinationAddresses: ["0.0.0.0/0", "::/0"],
        },
    ],
});

export const dropletIp = droplet.ipv4Address;
export const dropletName = droplet.name;
export const firewallId = firewall.id;

สำคัญ: เปลี่ยน YOUR_PUBLIC_IP/32 เป็น public IPv4 ของผู้ดูแลระบบก่อน deploy เพื่อจำกัดการเชื่อมต่อ SSH และตรวจสอบว่า slug ของ image/size มีให้ใช้ใน region ที่เลือก

#ขั้นตอนที่ 4: ตรวจสอบและ Deploy

pulumi preview
pulumi up

ตรวจสอบรายการทรัพยากรและยืนยันการสร้าง หลัง deploy เสร็จ ดู IP ด้วย:

pulumi stack output dropletIp

#ขั้นตอนที่ 5: เชื่อมต่อ Droplet

ssh root@$(pulumi stack output dropletIp)

เมื่อเชื่อมต่อได้แล้ว สามารถติดตั้งเว็บเซิร์ฟเวอร์ เช่น Nginx เพื่อให้มีบริการตอบกลับที่พอร์ต 80:

sudo apt update
sudo apt install -y nginx
sudo systemctl enable --now nginx

เปิด http://<DROPLET_IP> ในเบราว์เซอร์เพื่อตรวจสอบผลลัพธ์

#ขั้นตอนที่ 6: แก้ไข Infrastructure

ลองเปลี่ยนชื่อหรือขนาด Droplet ใน index.ts แล้วใช้:

pulumi preview
pulumi up

การเปลี่ยนบางคุณสมบัติอาจทำให้ Pulumi ต้องแทนที่ Droplet ซึ่งอาจกระทบข้อมูลหรือบริการ ตรวจสอบ preview ทุกครั้ง

#ขั้นตอนที่ 7: ลบทรัพยากร

pulumi destroy

ยืนยันว่า Droplet และ Firewall ถูกลบจาก DigitalOcean Console เพื่อลดค่าใช้จ่ายที่ไม่จำเป็น หากต้องการลบ stack ด้วย ใช้ pulumi stack rm หลัง destroy

#แนวปฏิบัติที่แนะนำ

  1. ใช้ Pulumi secrets สำหรับ token และข้อมูลสำคัญ
  2. จำกัด SSH ด้วย CIDR ของผู้ดูแลระบบ ไม่เปิด 0.0.0.0/0 โดยไม่จำเป็น
  3. ใช้ pulumi preview ก่อนทุกการเปลี่ยนแปลง
  4. แยก stack dev, staging, prod และตรวจสอบค่าใช้จ่าย
  5. ใช้ CI/CD และ secret manager สำหรับงาน Production
  6. สำรองข้อมูลก่อนแก้ไขทรัพยากรที่มี state

#สรุป

Pulumi ช่วยให้กำหนด DigitalOcean Droplet และ Firewall ด้วย TypeScript ทำให้ Infrastructure สามารถตรวจสอบเวอร์ชัน ทำซ้ำ และจัดการผ่านกระบวนการ CI/CD ได้ง่ายขึ้น Workshop นี้เป็นจุดเริ่มต้นสำหรับต่อยอดไปสู่ Load Balancer, Managed Database และ Kubernetes

#แหล่งข้อมูล