pulumi-automation-api

Par pulumi · agent-skills

Chargez cette compétence lorsqu'un utilisateur demande comment exécuter Pulumi de façon programmatique, intégrer Pulumi dans une application, orchestrer plusieurs stacks en code, créer un portail d'infrastructure en libre-service, remplacer des scripts shell CLI Pulumi par du code, ou utiliser l'Automation API Pulumi (`LocalWorkspace`, `createOrSelectStack`, programmes inline). Chargez-la également pour les questions concernant le séquençage multi-stack, les déploiements parallèles ou le passage d'outputs entre stacks via du code.

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

Pulumi Automation API

Quand Utiliser Cette Skill

Invoquez cette skill quand :

  • Orchestrer des déploiements sur plusieurs stacks Pulumi
  • Intégrer des opérations Pulumi dans des applications personnalisées
  • Créer des plateformes d'infrastructure en libre-service
  • Remplacer des scripts d'orchestration fragiles en Bash/Makefile
  • Créer des CLIs personnalisées pour la gestion d'infrastructure
  • Construire des applications web qui provisionent l'infrastructure

Qu'est-ce que l'Automation API

L'Automation API fournit un accès programmatique aux opérations Pulumi. Au lieu d'exécuter pulumi up depuis le CLI, vous appelez des fonctions dans votre code qui effectuent les mêmes opérations.

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

// Créer ou sélectionner une stack
const stack = await automation.LocalWorkspace.createOrSelectStack({
    stackName: "dev",
    projectName: "my-project",
    program: async () => {
        // Votre programme Pulumi ici
    },
});

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

Quand Utiliser l'Automation API

Bons Cas d'Usage

Orchestration multi-stack :

Quand vous divisez l'infrastructure en plusieurs projets ciblés, l'Automation API aide à compenser la complexité ajoutée en orchestrant les opérations sur les stacks :

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

L'Automation API garantit un séquençage correct sans intervention manuelle.

Plateformes en libre-service :

Créez des outils internes où les développeurs demandent l'infrastructure sans apprendre Pulumi :

  • Portails web pour le provisionnement d'environnements
  • Bots Slack qui créent/détruisent des ressources
  • CLIs personnalisées adaptées à votre organisation

Infrastructure intégrée :

Applications qui provisionent leur propre infrastructure :

  • Plateformes SaaS créant des ressources par tenant
  • Frameworks de test créant des environnements de test
  • Systèmes CI/CD avec des besoins d'infrastructure dynamiques

Remplacer des scripts fragiles :

Si vous avez des scripts Bash ou des Makefiles assemblant plusieurs commandes pulumi, l'Automation API fournit :

  • Une gestion d'erreur appropriée
  • La sécurité des types
  • Un accès programmatique aux sorties

Quand NE PAS L'Utiliser

  • Projet unique avec des besoins de déploiement standards
  • Quand vous n'avez pas besoin de contrôle programmatique sur les opérations

Choix Architecturaux

Source Locale vs Source Inline

Source Locale - Programme Pulumi dans des fichiers séparés :

const stack = await automation.LocalWorkspace.createOrSelectStack({
    stackName: "dev",
    workDir: "./infrastructure",  // Pointe vers un projet Pulumi existant
});

Quand l'utiliser :

  • Des équipes différentes maintiennent l'orchestrateur vs les programmes Pulumi
  • Les programmes Pulumi existent déjà
  • Vouloir des cycles de contrôle de version et de publication indépendants
  • L'équipe de plateforme orchestrant l'infrastructure de l'équipe d'application

Source Inline - Programme Pulumi intégré dans l'orchestrateur :

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

Quand l'utiliser :

  • Une seule équipe possède tout
  • L'étroite liaison entre l'orchestration et l'infrastructure est désirée
  • Distribution comme binaire compilé (aucun fichier source nécessaire)
  • Artefact de déploiement plus simple

Indépendance de Langage

Le programme Automation API peut utiliser un langage différent des programmes Pulumi qu'il orchestre :

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

Cela permet aux équipes de plateforme d'utiliser leur langage préféré tandis que les équipes d'application utilisent le leur.

Patterns Courants

Orchestration Multi-Stack

Déployer plusieurs stacks dans l'ordre des dépendances :

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

Passer la Configuration

Définissez la configuration de stack programmatiquement :

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

// Définir les valeurs de configuration
await stack.setConfig("aws:region", { value: "us-west-2" });
await stack.setConfig("dbPassword", { value: "secret", secret: true });

// Puis déployer
await stack.up();

Lire les Sorties

Accédez aux sorties de stack après le déploiement :

const upResult = await stack.up();

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

// Ou à partir du résultat de up
console.log(`Outputs: ${JSON.stringify(upResult.outputs)}`);

Gestion d'Erreurs

Gérez les échecs de déploiement gracieusement :

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

Opérations Parallèles sur les Stacks

Quand les stacks sont indépendantes, déployez en parallèle :

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

Bonnes Pratiques

Séparer la Configuration du Code

Externalisez la configuration dans des fichiers ou des variables d'environnement :

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

Cela permet de distribuer des binaires compilés sans exposer le code source.

Diffuser la Sortie pour les Opérations Longues

Utilisez le callback onOutput pour un retour en temps réel :

await stack.up({
    onOutput: (message) => {
        process.stdout.write(message);
        // Ou envoyer à un système de journalisation, websocket, etc.
    },
});

Référence Rapide

Scénario Approche
Projets Pulumi existants Source locale avec workDir
Infrastructure intégrée nouvelle Source inline avec fonction program
Équipes différentes Source locale pour l'indépendance
Distribution de binaire compilé Source inline ou locale groupée
Dépendances multi-stack Déploiement séquentiel dans l'ordre
Stacks indépendantes Déploiement parallèle avec Promise.all

Skills Associées

  • pulumi-best-practices: Patterns au niveau du code pour les programmes Pulumi

Références

Skills similaires