ปรับปรุงล่าสุด: กุมภาพันธ์ 2026

Pulumi - Modern Infrastructure as Code

Code-First Infrastructure ด้วย TypeScript, Python & Go

เรียนรู้การใช้ Pulumi เทคโนโลยี Infrastructure as Code สมัยใหม่ที่ใช้โค้ดด้วยภาษา TypeScript, Python และ Go เพื่อสร้างและจัดการโครงสร้างพื้นฐานในหลายคลาวด์

TypeScript
Python
Go
Multi-cloud

1. บทนำ: Pulumi คืออะไร?

Infrastructure as Code สมัยใหม่

Pulumi เป็น Platform สำหรับ Infrastructure as Code (IaC) ที่แตกต่างจากเครื่องมืออื่นๆ ตรงที่คุณสามารถใช้ภาษาโปรแกรมจริง เช่น TypeScript, Python, Go, C#, และ Java เพื่อสร้างและจัดการโครงสร้างพื้นฐานในคลาวด์

จุดเด่นของ Pulumi

  • ใช้ภาษาโปรแกรมจริง - ไม่ต้องเรียนรู้ Domain-Specific Language ใหม่
  • Component Architecture - สร้าง reusable components ได้
  • Built-in Secrets Management - จัดการ secrets อย่างปลอดภัย
  • Multi-cloud Support - รองรับ AWS, Azure, GCP, Kubernetes

ทำไมถึงได้รับความนิยม?

  • เร็วและมีประสิทธิภาพ: ใช้ภาษาโปรแกรมจริงทำให้เขียน logic ซับซ้อนได้ง่าย
  • Type Safety: TypeScript และ Go มี type checking
  • DevOps Culture: เหมาะสมกับ CI/CD และ GitOps workflows
  • Tooling: ใช้ editor และ IDE ที่คุ้นเคยได้เลย

ความแตกต่างกับเครื่องมืออื่น

ต่างจาก Terraform (HCL) หรือ AWS CloudFormation (YAML/JSON) ที่ใช้ declarative syntax การเขียนด้วย Pulumi คุณสามารถใช้ loop, function, class และ all programming constructs ที่คุณคุ้นเคยได้ ทำให้โครงสร้างพื้นฐานมีความยืดหยุ่นและ maintain ได้ง่ายขึ้น

2. สิ่งที่ต้องเตรียม (Prerequisites)

รายการที่ต้องมี

1

ความรู้พื้นฐาน

ความรู้พื้นฐานเกี่ยวกับ Cloud Computing (AWS/Azure/GCP), container, และ Infrastructure concepts

2

ภาษาโปรแกรม

พื้นฐานการเขียนโปรแกรมในภาษาที่เลือกใช้ (TypeScript, Python, หรือ Go)

3

บัญชี Cloud

AWS, Azure, หรือ GCP account และ IAM credentials ที่มีสิทธิ์สร้างทรัพยากร

4

Node.js (สำหรับ TypeScript)

Node.js version 16 หรือใหม่กว่า (สำหรับผู้ที่จะใช้ TypeScript)

5

CLI ที่ติดตั้งแล้ว

ติดตั้ง AWS CLI, Azure CLI, หรือ GCloud CLI (ไม่บังคับแต่แนะนำ)

หมายเหตุสำคัญ

ถ้าคุณไม่แน่ใจว่าจะเลือกภาษาใด ขอแนะนำว่าเริ่มต้นด้วย TypeScript หรือ Python เพราะมี ecosystem และ documentation ที่สมบูรณ์ที่สุด รวมถึง community ที่ใหญ่ที่สุด

3. การติดตั้งและตั้งค่าเบื้องต้น (Installation & Setup)

การติดตั้ง Pulumi CLI

Pulumi CLI สามารถติดตั้งได้หลายวิธี ทั้งผ่าน npm, package manager หรือ direct download

การติดตั้งด้วย curl (Linux/Mac)
curl -fsSL 'https://get.pulumi.com' | sh
ตรวจสอบการติดตั้ง
# ตรวจสอบเวอร์ชัน
pulumi version

# ดูคำสั่งทั้งหมด
pulumi help

หมายเหตุ: หลังติดตั้งเสร็จ คุณอาจต้อง restart terminal หรือ sourcing shell configuration (เช่น source ~/.bashrc)

เลือกภาษาสำหรับ Project

ตอนสร้าง project ใหม่ คุณต้องเลือกภาษาที่จะใช้ในการเขียน infrastructure code

TypeScript (Node.js)

typescript-new-project
# สร้าง directory สำหรับ project
mkdir my-pulumi-app && cd my-pulumi-app

# สร้าง project ใหม่ด้วย TypeScript
pulumi new typescript

# ติดตั้ง dependencies
npm install

Python

python-new-project
# สร้าง directory สำหรับ project
mkdir my-pulumi-app && cd my-pulumi-app

# สร้าง project ใหม่ด้วย Python
pulumi new python

# สร้าง virtual environment (แนะนำ)
python -m venv .venv
source .venv/bin/activate

# ติดตั้ง dependencies
pip install -r requirements.txt

Go

go-new-project
# สร้าง directory สำหรับ project
mkdir my-pulumi-app && cd my-pulumi-app

# สร้าง project ใหม่ด้วย Go
pulumi new go

# ติดตั้ง dependencies
go mod tidy

การตั้งค่า Cloud Provider

ก่อนใช้งาน Pulumi กับ cloud provider คุณต้อง set credentials ให้กับ Pulumi CLI

AWS

aws-configure
# Option 1: ใช้ AWS CLI
aws configure

# Option 2: ตั้งค่าด้วย environment variables
export AWS_ACCESS_KEY_ID="YOUR_ACCESS_KEY"
export AWS_SECRET_ACCESS_KEY="YOUR_SECRET_KEY"
export AWS_DEFAULT_REGION="us-west-2"

Azure

azure-configure
# ใช้ Azure CLI
az login

# หรือใช้ service principal
export ARM_CLIENT_ID="YOUR_CLIENT_ID"
export ARM_CLIENT_SECRET="YOUR_CLIENT_SECRET"
export ARM_TENANT_ID="YOUR_TENANT_ID"
export ARM_SUBSCRIPTION_ID="YOUR_SUBSCRIPTION_ID"

Google Cloud

gcp-configure
# ใช้ GCloud CLI
gcloud auth application-default login

# หรือใช้ service account key
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/service-account-key.json"

4. แนวคิดหลักของ Pulumi (Core Concepts)

Stack

Stack คือ deployment instance หรือ environment หนึ่งๆ เช่น dev, staging, prod หรือ environment ตามภูมิภาค

stack-commands
# ดู stack ทั้งหมด
pulumi stack ls

# สร้าง stack ใหม่
pulumi stack init dev

# เลือก stack ที่จะใช้
pulumi stack select prod

# ดูค่าปัจจุบัน
pulumi stack
Tip: แต่ละ stack มี state ของตัวเองแยกกัน ทำให้สามารถ test บน dev stack ก่อน deploy จริง บน prod stack ได้

Resource

Resource คือ unit ของ infrastructure ที่ Pulumi จัดการ เช่น EC2 instance, S3 bucket, VPC, หรือ Kubernetes pods

resource-definition
import * as aws from "@pulumi/aws";

// S3 Bucket Resource
const bucket = new aws.s3.Bucket("my-bucket", {
    bucket: "my-unique-bucket-name",
});

// Lambda Function Resource
const lambdaFunc = new aws.lambda.Function("my-function", {
    code: new pulumi.AssetArchive({
        ".": new pulumi.FileArchive("./lambda"),
    }),
    runtime: "nodejs14.x",
    handler: "index.handler",
    role: lambdaRole.arn,
});
Tip: Pulumi จับคู่ resource ด้วยชื่อที่คุณกำหนด ทำให้สามารถ update หรือ destroy ได้ถูกต้อง

Config & Secrets

Pulumi มี built-in secrets management ที่เข้ากับ cloud provider ของคุณ คุณสามารถระบุ secrets ได้โดยใช้ flag --secret

config-management
# ตั้งค่า config ทั่วไป
pulumi config set databaseHost db.example.com

# ตั้งค่า secrets (จะถูกเข้ารหัส)
pulumi config set --secret awsSecretKey "YOUR_SECRET_KEY"

# ดูค่า config ทั้งหมด
pulumi config

# ดูค่า secrets อย่างปลอดภัย
pulumi config get awsSecretKey --secret

Provider

Provider คือ Pulumi package ที่ให้ resource types สำหรับ cloud service และ services ต่างๆ

provider-setup
import * as aws from "@pulumi/aws";

// ตั้งค่า provider
const provider = new aws.Provider("myProvider", {
    region: "us-west-2",
    profile: "my-profile",
});

// ใช้ provider บน resource
const bucket = new aws.s3.Bucket("my-bucket", {}, { provider });

Pulumi Architecture Overview

Pulumi ใช้ architecture แบบ client-server ที่ CLI ทำหน้าที่เป็น client ที่ส่งคำสั่งไปยัง Pulumi Service (หรือ state backend อื่นๆ) และใช้ cloud provider APIs ในการสร้าง infrastructure

Developer Terminal / IDE Pulumi CLI pulumi up / preview Pulumi Service State Backend Lock Management AWS API PutObject, CreateBucket S3 Bucket EC2 Instance RDS Database pulumi up state store API calls

Developer เขียนโค้ดและรันคำสั่ง pulumi up

Pulumi CLI ส่งคำสั่งไปยัง Pulumi Service และ cloud provider APIs

Cloud Provider สร้าง infrastructure ตามที่ต้องการ

5. ตัวอย่างโค้ด (Real-World Examples)

ตัวอย่าง AWS Deployment (TypeScript)

ตัวอย่างการสร้างโครงสร้างพื้นฐานบน AWS แบบง่ายด้วย Pulumi และ TypeScript

1. โครงสร้างไฟล์

file-structure
my-pulumi-app/
|-- Pulumi.yaml          # Project configuration
|-- tsconfig.json        # TypeScript configuration
|-- package.json         # Node.js dependencies
`-- index.ts            # Main infrastructure code

2. main/index.ts - สร้าง S3 Bucket และ Lambda

index.ts
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

// Configuration
const config = new pulumi.Config();
const environment = config.get("environment") || "dev";

// Create Security Group for Lambda
const lambdaSecurityGroup = new aws.ec2.SecurityGroup("lambda-sg", {
    description: "Security group for Lambda functions",
    ingress: [{
        protocol: "-1",
        fromPort: 0,
        toPort: 0,
        cidrBlocks: ["0.0.0.0/0"],
    }],
});

// Create S3 Bucket
const bucket = new aws.s3.Bucket(`my-${environment}-app-bucket`, {
    bucket: `my-${environment}-app-bucket-${pulumi.getStack()}`,
    tags: {
        Environment: environment,
        ManagedBy: "Pulumi",
    },
});

// Create IAM Role for 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 basic policy to role
new aws.iam.RolePolicyAttachment("lambda-basic", {
    role: lambdaRole.name,
    policyArn: aws.iam.ManagedPolicies.AWSLambdaBasicExecutionRole,
});

// Create Lambda Function
const lambdaFunction = new aws.lambda.Function("my-function", {
    code: new pulumi.asset.AssetArchive({
        ".": new pulumi.asset.FileArchive("./lambda"),
    }),
    runtime: "nodejs14.x",
    handler: "index.handler",
    role: lambdaRole.arn,
    vpcConfig: {
        securityGroupIds: [lambdaSecurityGroup.id],
    },
    environment: {
        variables: {
            S3_BUCKET: bucket.bucket,
            ENVIRONMENT: environment,
        },
    },
});

// Export outputs
export const bucketName = bucket.bucket;
export const lambdaArn = lambdaFunction.arn;

3. Pulumi config (pulumi.yaml)

Pulumi.yaml
name: aws-lambda-app
runtime: nodejs
description: AWS Lambda and S3 application with Pulumi

config:
  aws:region:
    value: us-west-2
  environment:
    value: dev

4. รันและ deploy

create-stack
# สร้าง stack ใหม่
pulumi new typescript --name aws-lambda-app

# ติดตั้ง dependencies
npm install @pulumi/aws

# ตั้งค่า configuration
pulumi config set environment prod

# Preview changes
pulumi preview

# Deploy
pulumi up

# ลบ infrastructure
pulumi destroy

ตัวอย่าง Kubernetes Deployment (Python)

ตัวอย่างการ deploy แอปพลิเคชันบน Kubernetes ด้วย Pulumi และ Python

1. โครงสร้างไฟล์

k8s-file-structure
kubernetes-app/
|-- Pulumi.yaml
|-- requirements.txt
`-- __main__.py    # Main Python code

2. __main__.py - Kubernetes Deployment

__main__.py
import pulumi
import pulumi_aws as aws
import pulumi_kubernetes as k8s
from pulumi_kubernetes.apps.v1 import Deployment
from pulumi_kubernetes.core.v1 import Service, PodTemplateSpec, PodSpec, Container

# Configuration
config = pulumi.Config()
app_name = config.get("appName") or "my-app"

# Create EKS Cluster
cluster = aws.eks.Cluster(
    f"{app_name}-cluster",
    name=f"{app_name}-cluster",
    role_arn=aws.iam.Role("eks-role").arn,
    vpc_config=aws.eks.ClusterVpcConfigArgs(
        public_access_cidrs=["0.0.0.0/0"],
    ),
)

# Create Kubeconfig
kubeconfig = pulumi.Output.all(cluster.name, cluster.endpoint, cluster.certificate_authority.apply(lambda cp: cp.data)).apply(
    lambda args: f"""{{"apiVersion": "v1","kind": "ConfigMap","clusters": [{{"cluster": {{"server": "{args[1]}","certificate-authority-data": "{args[2]}"}},"name": "eks"}}],"contexts": [{{"context": {{cluster": "eks","user": "eks"}},"name": "eks"}}],"current-context": "eks"}}"""
)

# Create Kubernetes Provider
k8s_provider = k8s.Provider(
    f"{app_name}-k8s",
    kubeconfig=kubeconfig,
)

# Kubernetes Deployment
deployment = Deployment(
    f"{app_name}-deployment",
    metadata=k8s.meta.v1.ObjectMetaArgs(
        name=f"{app_name}-deployment",
        labels={"app": app_name},
    ),
    spec=k8s.apps.v1.DeploymentSpecArgs(
        selector=k8s.meta.v1.LabelSelectorArgs(
            match_labels={"app": app_name},
        ),
        replicas=3,
        template=k8s.meta.v1.PodTemplateSpecArgs(
            metadata=k8s.meta.v1.ObjectMetaArgs(
                labels={"app": app_name},
            ),
            spec=k8s.core.v1.PodSpecArgs(
                containers=[Container(
                    name=app_name,
                    image="nginx:latest",
                    ports=[k8s.core.v1.ContainerPortArgs(container_port=80)],
                )],
            ),
        ),
    ),
    opts=pulumi.ResourceOptions(provider=k8s_provider),
)

# Kubernetes Service
service = Service(
    f"{app_name}-service",
    metadata=k8s.meta.v1.ObjectMetaArgs(
        name=f"{app_name}-service",
        labels={"app": app_name},
    ),
    spec=k8s.core.v1.ServiceSpecArgs(
        selector={"app": app_name},
        ports=[k8s.core.v1.ServicePortArgs(port=80, target_port=80)],
        type="LoadBalancer",
    ),
    opts=pulumi.ResourceOptions(provider=k8s_provider),
)

# Export outputs
pulumi.export("cluster_name", cluster.name)
pulumi.export("cluster_endpoint", cluster.endpoint)
pulumi.export("deployment_name", deployment.metadata["name"])

Component Architecture (Reuse)

Pulumi อนุญาตให้สร้าง components ที่สามารถ reuse ได้โดยการสร้างคลาสที่สืบทอดจาก pulumi.ComponentResource

1. สร้าง component ชื่อ WebApp

components/web_app.py
import pulumi
from pulumi import ResourceOptions
from pulumi_aws import s3, lambda_, iam, apigatewayv2
from typing import Optional, Mapping, Any


class WebApp(pulumi.ComponentResource):
    def __init__(
        self,
        name: str,
        opts: Optional[ResourceOptions] = None,
        **kwargs: Any,
    ):
        super().__init__("myorg:components:WebApp", name, opts)
        
        # S3 Bucket for static files
        self.bucket = s3.Bucket(
            f"{name}-bucket",
            bucket=f"{name}-{pulumi.get_stack()}-{pulumi.get_project()}",
            tags={"Component": "WebApp"},
        )
        
        # IAM Role for Lambda
        self.lambda_role = iam.Role(
            f"{name}-lambda-role",
            assume_role_policy="""{
                "Version": "2012-10-17",
                "Statement": [{
                    "Action": "sts:AssumeRole",
                    "Effect": "Allow",
                    "Principal": {"Service": "lambda.amazonaws.com"}
                }]
            }""",
        )
        
        # Lambda Function
        self.function = lambda_.Function(
            f"{name}-function",
            runtime="python3.9",
            handler="index.handler",
            role=self.lambda_role.arn,
            code=pulumi.asset.FileArchive("./lambda"),
            environment={
                "variables": {
                    "S3_BUCKET": self.bucket.bucket,
                }
            },
        )
        
        # API Gateway
        self.api = apigatewayv2.Api(
            f"{name}-api",
            name=f"{name}-api",
            protocol_type="HTTP",
        )
        
        #Export outputs
        self.bucket_url = self.bucket.bucket_domain_name
        self.api_url = self.api.api_endpoint
        
        # Register resources
        self.register_outputs({
            "bucket_url": self.bucket_url,
            "api_url": self.api_url,
        })

2. ใช้งาน component

usage-example.py
import pulumi
from components.web_app import WebApp

# Create two different web apps
dev_app = WebApp(
    "dev-web-app",
    opts=pulumi.ResourceOptions(parent=self),
)

prod_app = WebApp(
    "prod-web-app",
    opts=pulumi.ResourceOptions(parent=self),
)

# Export outputs
pulumi.export("dev_app_url", dev_app.api_url)
pulumi.export("prod_app_url", prod_app.api_url)

6. Pulumi vs Terraform: เปรียบเทียบและเลือกใช้ให้เหมาะสม

ข้อมูลเปรียบเทียบแบบละเอียด

หัวข้อ Pulumi Terraform
ภาษาโปรแกรม TypeScript, Python, Go, C#, Java HCL (HashiCorp Language)
Syntax Imperative & Object-oriented Declarative
Logic Support Full programming logic Limited (for/each only)
Type Safety Strong typing (TypeScript/Go) Weak typing (HCL)
State Management Pulumi Service / S3 / Azure Blob Terraform Cloud / S3 / Consul
Pricing Free tier (5 users) Free tier (unlimited users)
Multi-cloud AWS, Azure, GCP, Kubernetes AWS, Azure, GCP, 300+ providers
Learning Curve ต้องรู้ภาษาโปรแกรม เรียนรู้ HCL ง่ายกว่า
Component Reuse มี Built-in support สำหรับ Component Resource ผ่าน modules (ต้องตั้งค่าเพิ่ม)
Secrets Management Built-in (encrypted at rest) ผ่าน Terraform Cloud / Vault

เลือก Pulumi ถ้าคุณ...

  • สามารถเขียนโปรแกรมได้และต้องการใช้ logic ซับซ้อนใน infrastructure
  • ต้องการ type safety (TypeScript/Go) สำหรับ infrastructure code
  • ใช้ TypeScript หรือ Python อยู่แล้วใน team
  • ต้องการ reuse infrastructure components ได้ง่าย
  • ต้องการ built-in secrets management
  • ต้องการใช้ programming patterns เช่น inheritance, composition

เลือก Terraform ถ้าคุณ...

  • ชอบ declarative approach หรือยังไม่เขียนโปรแกรมเก่ง
  • ต้องการ community modules ที่หลากหลาย (TF Registry)
  • มี existing infrastructure เขียนด้วย Terraform
  • ต้องการFree tier ที่ไม่จำกัด user count
  • ต้องการ provider ecosystem ที่ใหญ่ที่สุด (300+ providers)

สรุป

Pulumi และ Terraform ต่างก็เป็นเครื่องมือ IaC ที่ยอดเยี่ยม ความต่างหลักอยู่ที่ syntax และ philosophy ของแต่ละ tool

ถ้าคุณเป็น developer ที่เขียนโปรแกรมเก่ง หรือ team ของคุณใช้ TypeScript/Python/Go อยู่แล้ว Pulumi เป็นตัวเลือกที่ดี เพราะคุณสามารถใช้ skills ที่มีอยู่แล้วได้เลย แต่ถ้าคุณต้องการ approach ที่ declarative และมี community ใหญ่ที่สุด Terraform อาจเหมาะกว่า

7. Best Practices: แนวทางปฏิบัติที่ดี

ความปลอดภัย (Security)

อย่า commit secrets!

ห้าม เก็บ AWS access keys, passwords, API keys ใน code หรือ commit ลง git!

[ERROR] ห้าม:

aws_secret_key = "AKIAIOSFODNN7EXAMPLE"  # BAD!

[OK] ทำ:

from pulumi import get_config
aws_secret_key = get_config("aws:secretKey", secret=True)

ใช้ IAM roles แทน access keys

ใช้ IAM roles ที่ผูกกับ EC2 instance, Lambda function หรือ Service account แทนการใช้ access keys เพื่อลดความเสี่ยงในการรั่วไหลของ credentials

Enable encryption

เปิด encryption สำหรับ S3 buckets, RDS instances และ secrets store ทุกครั้ง

หลัก minimal privilege

ให้สิทธิ์น้อยที่สุดเท่าที่จะทำได้ (least privilege principle) ตัวอย่าง: ใช้ custom IAM policies แทน built-in policies

การจัดการ State

Remote Backend

ใช้ remote backend (Pulumi Service, S3, Azure Blob) แทน local state สำหรับทีมงาน

backend-init
# Pulumi Service
pulumi login --local

#AWS S3
pulumi login s3://my-pulumi-state-bucket

#Azure Blob Storage
pulumi login azblob://mystatecontainer

#Google Cloud Storage
pulumi login gs://my-pulumi-state-bucket

State Encryption

สำหรับ S3 backend ให้ใช้ S3 server-side encryption (SSE-KMS) และ versioning

Team Collaboration

[RECOMMENDED] แนะนำ:

  • ใช้ Pulumi Service พร้อม RBAC
  • สร้าง stack ตาม environment (dev/staging/prod)
  • ตั้ง policy ให้ทีมงานแต่ละคน only เห็น stack ของตัวเอง
  • ทำ CI/CD ด้วย automation token

[BLOCKED] ห้าม:

  • Share state files ผ่าน email/slack
  • Commit state files ลง git
  • ใช้ local backend บน development machine

CI/CD Integration

ใช้ Pulumi ใน CI/CD pipelines เพื่อทำ infrastructure provisioning อัตโนมัติ

GitHub Actions Example

.github/workflows/pulumi.yaml
name: Pulumi Deploy
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
      
      - name: Install Pulumi
        uses: pulumi/action-setup@v2
        with:
          version: v3
      
      - name: Install dependencies
        run: npm ci
      
      - name: Configure AWS
        run: |
          aws configure set aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws configure set aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      
      - name: Pulumi login
        run: pulumi login --local
      
      - name: Pulumi preview
        if: github.event_name == 'pull_request'
        run: pulumi preview
      
      - name: Pulumi up
        if: github.event_name == 'push'
        run: pulumi up --non-interactive --yes

GitLab CI Example

.gitlab-ci.yml
stages:
  - preview
  - deploy

variables:
  PULUMI_STACK: "prod"

preview:
  stage: preview
  script:
    - curl -fsSL https://get.pulumi.com | sh
    - source $HOME/.pulumi/env
    - npm ci
    - pulumi preview
  only:
    - branches

deploy:
  stage: deploy
  script:
    - curl -fsSL https://get.pulumi.com | sh
    - source $HOME/.pulumi/env
    - npm ci
    - pulumi login --local
    - pulumi up --non-interactive --yes
  only:
    - main

8. แก้ไขปัญหา (Troubleshooting)

ปัญหาที่พบบ่อยและวิธีแก้ไข

Error: Credential Providers not found

ปัญหา: Pulumi ไม่สามารถหา AWS credentials

วิธีแก้:

# ตั้งค่า credentials ผ่าน AWS CLI
aws configure

# หรือตั้งค่า environment variables
export AWS_ACCESS_KEY_ID="YOUR_KEY"
export AWS_SECRET_ACCESS_KEY="YOUR_SECRET"
export AWS_DEFAULT_REGION="us-west-2"

# Validate
aws sts get-caller-identity

Error: Stack 'xxx' not found

ปัญหา: Stack ที่ระบุไม่พบใน Pulumi Service

วิธีแก้:

# ดู stack ที่มีอยู่
pulumi stack ls

# สร้าง stack ใหม่
pulumi stack init my-stack

# เลือก stack ที่จะใช้
pulumi stack select my-stack

Error: Invalid Terraform Configuration

ปัญหา: Terraform provider versions ไม่สามารถเข้ากันได้

วิธีแก้:

# ลบ node_modules และ install ใหม่
rm -rf node_modules package-lock.json
npm install

# หรือสำหรับ Python
rm -rf .venv
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Error: State Locked

ปัญหา: State file ถูกล็อคโดย process อื่น

วิธีแก้:

# ดู lock ปัจจุบัน
pulumi stack ls --show-locks

# ยกเลิก lock (ระวังใช้เมื่อ process ไม่ตอบสนอง)
pulumi cancel --yes

# หรือถ้าใช้ local backend ให้ลบ lock file ด้วยตนเอง
rm .pulumi/locks/*.json

Error: Resource already exists

ปัญหา: Resource มีอยู่แล้วใน cloud provider แต่ไม่อยู่ใน state

วิธีแก้:

# Import resource เข้า state
pulumi import aws:s3/bucket:Bucket my-bucket my-existing-bucket-name

# หรือใช้ CLI
pulumi import aws:s3/bucket:Bucket my-bucket --file import.json

Tools และ Commands ที่จำเป็น

Commands ที่ต้องรู้

pulumi up - Deploy resources (preview + apply)

pulumi preview - Show what will change

pulumi destroy - Remove all resources

pulumi stack ls - List all stacks

pulumi config - Manage configuration

pulumi logs - View resource logs

Debug Commands

pulumi preview --diff - Show detailed diff

pulumi up --color=always - Force colored output

pulumi refresh - Sync state with real resources

pulumi cancel - Cancel long-running operation

pulumi version - Check CLI version

pulumi plugin ls - List installed plugins