pulumi-automation-api

bởi pulumi

Điều phối lập trình các hoạt động hạ tầng Pulumi trên nhiều stack và ứng dụng. Hỗ trợ cả kiến trúc nguồn cục bộ (dự án Pulumi hiện có) và nguồn nội tuyến (chương trình nhúng), cho phép các mẫu triển khai linh hoạt từ đơn giản đến phức tạp với nhiều stack. Xử lý điều phối nhiều stack với trình tự phụ thuộc, triển khai độc lập song song và truyền đầu ra giữa các stack để cung cấp hạ tầng phối hợp. Cung cấp lập trình...

npx skills add https://github.com/pulumi/agent-skills --skill pulumi-automation-api

Pulumi Automation API

When to Use This Skill

Invoke this skill when:

  • Orchestrating deployments across multiple Pulumi stacks
  • Embedding Pulumi operations in custom applications
  • Building self-service infrastructure platforms
  • Replacing fragile Bash/Makefile orchestration scripts
  • Creating custom CLIs for infrastructure management
  • Building web applications that provision infrastructure

What is Automation API

Automation API provides programmatic access to Pulumi operations. Instead of running pulumi up from the CLI, you call functions in your code that perform the same operations.

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

// Create or select a stack
const stack = await automation.LocalWorkspace.createOrSelectStack({
    stackName: "dev",
    projectName: "my-project",
    program: async () => {
        // Your Pulumi program here
    },
});

// Run pulumi up programmatically
const upResult = await stack.up({ onOutput: console.log });
console.log(`Update summary: ${JSON.stringify(upResult.summary)}`);

When to Use Automation API

Good Use Cases

Multi-stack orchestration:

When you split infrastructure into multiple focused projects, Automation API helps offset the added complexity by orchestrating operations across stacks:

infrastructure → platform → application
     ↓              ↓            ↓
   (VPC)      (Kubernetes)   (Services)

Automation API ensures correct sequencing without manual intervention.

Self-service platforms:

Build internal tools where developers request infrastructure without learning Pulumi:

  • Web portals for environment provisioning
  • Slack bots that create/destroy resources
  • Custom CLIs tailored to your organization

Embedded infrastructure:

Applications that provision their own infrastructure:

  • SaaS platforms creating per-tenant resources
  • Testing frameworks spinning up test environments
  • CI/CD systems with dynamic infrastructure needs

Replacing fragile scripts:

If you have Bash scripts or Makefiles stitching together multiple pulumi commands, Automation API provides:

  • Proper error handling
  • Type safety
  • Programmatic access to outputs

When NOT to Use

  • Single project with standard deployment needs
  • When you don't need programmatic control over operations

Architecture Choices

Local Source vs Inline Source

Local Source - Pulumi program in separate files:

const stack = await automation.LocalWorkspace.createOrSelectStack({
    stackName: "dev",
    workDir: "./infrastructure",  // Points to existing Pulumi project
});

When to use:

  • Different teams maintain orchestrator vs Pulumi programs
  • Pulumi programs already exist
  • Want independent version control and release cycles
  • Platform team orchestrating application team's infrastructure

Inline Source - Pulumi program embedded in orchestrator:

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

const stack = await automation.LocalWorkspace.createOrSelectStack({
    stackName: "dev",
    projectName: "my-project",
    program: async () => {
        const bucket = new aws.s3.Bucket("my-bucket");
        return { bucketName: bucket.id };
    },
});

When to use:

  • Single team owns everything
  • Tight coupling between orchestration and infrastructure is desired
  • Distributing as compiled binary (no source files needed)
  • Simpler deployment artifact

Language Independence

The Automation API program can use a different language than the Pulumi programs it orchestrates:

Orchestrator (Go) → manages → Pulumi Program (TypeScript)

This enables platform teams to use their preferred language while application teams use theirs.

Common Patterns

Multi-Stack Orchestration

Deploy multiple stacks in dependency order:

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

async function deploy() {
    const stacks = [
        { name: "infrastructure", dir: "./infra" },
        { name: "platform", dir: "./platform" },
        { name: "application", dir: "./app" },
    ];

    for (const stackInfo of stacks) {
        console.log(`Deploying ${stackInfo.name}...`);

        const stack = await automation.LocalWorkspace.createOrSelectStack({
            stackName: "prod",
            workDir: stackInfo.dir,
        });

        await stack.up({ onOutput: console.log });
        console.log(`${stackInfo.name} deployed successfully`);
    }
}

async function destroy() {
    // Destroy in reverse order
    const stacks = [
        { name: "application", dir: "./app" },
        { name: "platform", dir: "./platform" },
        { name: "infrastructure", dir: "./infra" },
    ];

    for (const stackInfo of stacks) {
        console.log(`Destroying ${stackInfo.name}...`);

        const stack = await automation.LocalWorkspace.selectStack({
            stackName: "prod",
            workDir: stackInfo.dir,
        });

        await stack.destroy({ onOutput: console.log });
    }
}

Passing Configuration

Set stack configuration programmatically:

const stack = await automation.LocalWorkspace.createOrSelectStack({
    stackName: "dev",
    workDir: "./infrastructure",
});

// Set configuration values
await stack.setConfig("aws:region", { value: "us-west-2" });
await stack.setConfig("dbPassword", { value: "secret", secret: true });

// Then deploy
await stack.up();

Reading Outputs

Access stack outputs after deployment:

const upResult = await stack.up();

// Get all outputs
const outputs = await stack.outputs();
console.log(`VPC ID: ${outputs["vpcId"].value}`);

// Or from the up result
console.log(`Outputs: ${JSON.stringify(upResult.outputs)}`);

Error Handling

Handle deployment failures gracefully:

try {
    const result = await stack.up({ onOutput: console.log });

    if (result.summary.result === "failed") {
        console.error("Deployment failed");
        process.exit(1);
    }
} catch (error) {
    console.error(`Deployment error: ${error}`);
    throw error;
}

Parallel Stack Operations

When stacks are independent, deploy in parallel:

const independentStacks = [
    { name: "service-a", dir: "./service-a" },
    { name: "service-b", dir: "./service-b" },
    { name: "service-c", dir: "./service-c" },
];

await Promise.all(independentStacks.map(async (stackInfo) => {
    const stack = await automation.LocalWorkspace.createOrSelectStack({
        stackName: "prod",
        workDir: stackInfo.dir,
    });
    return stack.up({ onOutput: (msg) => console.log(`[${stackInfo.name}] ${msg}`) });
}));

Best Practices

Separate Configuration from Code

Externalize configuration into files or environment variables:

import * as fs from "fs";

interface DeployConfig {
    stacks: Array<{ name: string; dir: string; }>;
    environment: string;
}

const config: DeployConfig = JSON.parse(
    fs.readFileSync("./deploy-config.json", "utf-8")
);

for (const stackInfo of config.stacks) {
    const stack = await automation.LocalWorkspace.createOrSelectStack({
        stackName: config.environment,
        workDir: stackInfo.dir,
    });
    await stack.up();
}

This enables distributing compiled binaries without exposing source code.

Stream Output for Long Operations

Use onOutput callback for real-time feedback:

await stack.up({
    onOutput: (message) => {
        process.stdout.write(message);
        // Or send to logging system, websocket, etc.
    },
});

Quick Reference

ScenarioApproach
Existing Pulumi projectsLocal source with workDir
New embedded infrastructureInline source with program function
Different teamsLocal source for independence
Compiled binary distributionInline source or bundled local
Multi-stack dependenciesSequential deployment in order
Independent stacksParallel deployment with Promise.all

Related Skills

  • pulumi-best-practices: Code-level patterns for Pulumi programs

References

Thêm skills từ pulumi

package-usage
pulumi
Theo dõi các stack trong một tổ chức Pulumi sử dụng một gói cụ thể và ở phiên bản nào. Dùng để kiểm tra chéo giữa các stack, xác định các gói lỗi thời hoặc không được bảo trì…
official
pulumi-best-practices
pulumi
Các phương pháp hay nhất toàn diện để viết mã cơ sở hạ tầng Pulumi đáng tin cậy và dễ bảo trì. Tránh tạo tài nguyên bên trong các callback apply(); truyền trực tiếp các đối tượng Output làm đầu vào để duy trì khả năng theo dõi phụ thuộc và hiển thị xem trước. Sử dụng các lớp ComponentResource để nhóm các tài nguyên liên quan thành các đơn vị logic có thể tái sử dụng với hệ thống phân cấp cha-con phù hợp thông qua parent: this. Mã hóa bí mật ngay từ đầu bằng cờ --secret hoặc config.requireSecret() để ngăn rò rỉ thông tin xác thực trong các tệp trạng thái...
official
pulumi-component
pulumi
Các thành phần cơ sở hạ tầng có thể tái sử dụng với hỗ trợ đa ngôn ngữ, các giá trị mặc định hợp lý và các mẫu tổ hợp. Yêu cầu bốn yếu tố cốt lõi: mở rộng ComponentResource, chấp nhận các tham số tiêu chuẩn, đặt parent: this trên tất cả các thành phần con và gọi registerOutputs() ở cuối hàm tạo. Các giao diện Args phải sử dụng trình bao bọc Input<T>, tránh các kiểu union và hàm, đồng thời giữ cấu trúc phẳng để hỗ trợ tạo SDK đa ngôn ngữ. Chỉ hiển thị các đầu ra thiết yếu dưới dạng thuộc tính công khai; ẩn...
official
pulumi-debug-failed-operation
pulumi
Gỡ lỗi một bản cập nhật hoặc xem trước Pulumi bị lỗi: đọc lỗi mà Pulumi đã ghi lại, tìm nguyên nhân gây ra lỗi và sửa nó. Tải kỹ năng này khi người dùng yêu cầu…
official
pulumi-esc
pulumi
Quản lý tập trung các bí mật, cấu hình và thông tin xác thực động cho cơ sở hạ tầng và ứng dụng Pulumi. Hỗ trợ tổng hợp môi trường thông qua import và phân lớp, với các khóa dành riêng cho environmentVariables, pulumiConfig và files. Tạo thông tin xác thực ngắn hạn qua OIDC cho AWS, Azure và GCP; tích hợp với AWS Secrets Manager, Azure Key Vault, HashiCorp Vault và 1Password. Các lệnh CLI chính bao gồm pulumi env init, pulumi env edit, pulumi env open (hiển thị...
official
pulumi-neo-handoff
pulumi
Chuyển luồng hiện tại sang một tác vụ Pulumi Neo mới dưới dạng chuyển giao một chiều. Sử dụng khi người dùng yêu cầu rõ ràng việc chuyển giao, gửi, chuyển tiếp hoặc tiếp tục hiện tại…
official
pulumi-overview
pulumi
Sử dụng kỹ năng này cho bất kỳ tác vụ nào tạo, sửa đổi, kiểm tra hoặc hủy bỏ cơ sở hạ tầng đám mây hoặc cấu hình SaaS, từ các thao tác CLI đơn lẻ đến toàn bộ…
official
pulumi-terraform-to-pulumi
pulumi
Di chuyển các dự án Terraform/OpenTofu sang Pulumi, bao gồm dịch mã nguồn HCL và/hoặc nhập trạng thái Terraform vào một stack Pulumi. Sử dụng khi người dùng…
official