mcpField
P
pulumi-automation-api

pulumi-automation-api

github.com/pulumi云与 DevOps781.2k 次安装3 周前更新
代码仓库

关于 pulumi-automation-api

pulumi-automation-api 是一项通过代码调用 Pulumi Automation API 管理基础设施操作的技能,适用于构建部署编排、自助平台或基础设施应用。它涵盖多 Stack 协调、配置传递和输出读取等模式。

主要功能

  1. 01以编程方式执行 Pulumi 操作
  2. 02多 Stack 顺序编排与并行执行
  3. 03支持本地或内嵌程序源
  4. 04编程设置配置并读取输出
  5. 05处理部署错误

适用场景

  1. 01编排存在依赖关系的基础设施 Stack
  2. 02构建自助式资源配置工具
  3. 03在应用中嵌入基础设施配置
  4. 04替换 Bash 或 Makefile 部署脚本

安装

复制下面的命令,在终端中运行。

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

安装后在 Claude Code 中输入/pulumi-automation-api确认已加载。

附带文件agents/openai.yamluse_cases.yaml

详细介绍

Pulumi Automation API

何时使用此技能

在以下情况下调用此技能:

  • 协调多个 Pulumi 堆栈之间的部署
  • 在自定义应用程序中嵌入 Pulumi 操作
  • 构建自助式基础设施平台
  • 替换脆弱的 Bash/Makefile 编排脚本
  • 创建用于基础设施管理的自定义 CLI
  • 构建可预配基础设施的 Web 应用程序

什么是 Automation API

Automation API 提供对 Pulumi 操作的编程访问。你无需从 CLI 运行 pulumi up,而是可以在代码中调用执行相同操作的函数。

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)}`);

何时使用 Automation API

适用场景

多堆栈编排:

当你将基础设施拆分为多个专注于特定领域的项目时,Automation API 可通过协调各个堆栈之间的操作,帮助抵消由此增加的复杂性:

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

Automation API 可确保操作按正确顺序执行,无需人工干预。

自助式平台:

构建内部工具,让开发人员无需学习 Pulumi 即可申请基础设施:

  • 用于预配环境的 Web 门户
  • 可创建/销毁资源的 Slack 机器人
  • 根据组织需求定制的 CLI

嵌入式基础设施:

可为自身预配基础设施的应用程序:

  • 为每个租户创建资源的 SaaS 平台
  • 启动测试环境的测试框架
  • 需要动态基础设施的 CI/CD 系统

替换脆弱的脚本:

如果你使用 Bash 脚本或 Makefile 串联多个 pulumi 命令,Automation API 可以提供:

  • 正确的错误处理
  • 类型安全
  • 对输出的编程访问
不适用的情况
  • 单个项目且部署需求标准
  • 不需要以编程方式控制操作

架构选择

本地源代码与内嵌源代码

本地源代码 - Pulumi 程序位于独立文件中:

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

适用场景:

  • 编排器和 Pulumi 程序由不同团队维护
  • 已有 Pulumi 程序
  • 希望采用独立的版本控制和发布周期
  • 平台团队负责编排应用团队的基础设施

内嵌源代码 - Pulumi 程序嵌入在编排器中:

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 };
    },
});

适用场景:

  • 由单个团队负责所有工作
  • 希望编排与基础设施紧密耦合
  • 以编译后的二进制文件形式分发(无需源文件)
  • 部署产物更简单
语言独立性

Automation API 程序可以使用与其所编排的 Pulumi 程序不同的语言:

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

这使平台团队能够使用偏好的语言,同时应用团队也可以使用自己的语言。

常见模式

多堆栈编排

按依赖顺序部署多个堆栈:

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 });
    }
}
传递配置

以编程方式设置堆栈配置:

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();
读取输出

部署后访问堆栈输出:

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)}`);
错误处理

妥善处理部署失败:

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;
}
并行堆栈操作

如果堆栈相互独立,可并行部署:

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}`) });
}));

最佳实践

将配置与代码分离

将配置外置到文件或环境变量中:

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();
}

这样即可分发编译后的二进制文件,而不会暴露源代码。

为长时间运行的操作流式输出

使用 onOutput 回调实时获取反馈:

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

快速参考

场景方案
已有 Pulumi 项目使用 workDir 的本地源代码
新的嵌入式基础设施使用 program 函数的内嵌源代码
不同团队使用本地源代码以保持独立性
编译后的二进制文件分发使用内嵌源代码或打包的本地源代码
多堆栈依赖按顺序依次部署
相互独立的堆栈使用 Promise.all 并行部署

相关技能

  • pulumi-best-practices:Pulumi 程序的代码级模式

References

评论

支持 Markdown