Pulumi GitHub Actions

repository·main·Indexed 43 days ago

https://github.com/pulumi/actions

Automate Pulumi deployments, previews, and infrastructure management directly within GitHub workflows. Supports executing Pulumi commands like up, preview, refresh, and destroy, or installing the Pulumi CLI. Features include PR commenting, stack output access, and configurable secrets providers. Version 7 updates the NodeJS runtime to Node 24.

Tokens
5.1K
Snippets
16
Records
25
Agent score
54%

What's inside Pulumi GitHub Actions

  1. Migrate from GitHub Action v1 and v2 to newer versions

    main

    When migrating from v1 or v2 to current versions of the Pulumi GitHub Action, note the following breaking changes:

    Input Name Changes

    Several configuration options have moved from environment variables to explicit action inputs:

    • PULUMI_ROOT $\rightarrow$ work-dir
    • PULUMI_BACKEND_URL $\rightarrow$ cloud-url
    • COMMENT_ON_PR $\rightarrow$ comment-on-pr
    • GITHUB_TOKEN $\rightarrow$ github-token

    Removed Inputs

    • IS_PR_WORKFLOW has been removed. The action now automatically detects if a workflow is a pull_request based on the GitHub Action type.

    Native Execution and Dependency Management

    The action now runs natively. This means you are responsible for setting up the required environment (e.g., Node.js, Python) and installing dependencies before running Pulumi commands. The action no longer automatically runs npm ci, npm install, pip3 install, or pipenv install.

    To ensure your environment is ready, use standard setup actions and manual installation steps in your workflow file.

    # Example: Setting up Node.js environment
    - uses: actions/setup-node@v1
      with:
        node-version: 14.x
    
    # Example: Installing Python dependencies manually
    - run: pip install -r requirements
      working-directory: infra
  2. Get started with Pulumi GitHub Actions

    main

    To use Pulumi GitHub Actions, create a workflow file that checks out your repository and uses pulumi/actions@v7. You must provide a command (e.g., preview or up) and a stack-name. Authentication is typically handled by providing a PULUMI_ACCESS_TOKEN via environment variables.

    Example workflow for running a preview on the main branch:

    name: Pulumi
    on:
      push:
        branches:
          - main
    jobs:
      up:
        name: Preview
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - uses: pulumi/actions@v7
            with:
              command: preview
              stack-name: org-name/stack-name
            env:
              PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
  3. Retrieve stack outputs using the `output` command

    main

    If you need to fetch stack outputs (e.g., to pass them to subsequent steps in a GitHub workflow) without running a full Pulumi command, use the output command.

    When using output, the action uses LocalWorkspace.stackOutputs() which does not require a Pulumi.yaml file to be present in the working directory. The action will automatically set each stack output as a GitHub Action output variable. If an output is marked as a secret in Pulumi, the action will also call core.setSecret() to mask it in the logs.

  4. Configure Pulumi GitHub Actions

    main

    The action can be configured using the with block in your workflow. Key configuration arguments include:

    • command (optional): The Pulumi command to run. Accepted values: up (alias: update), refresh, destroy, preview, and output. If omitted, the action only installs the CLI.
    • stack-name (optional): The name of the stack. Use the fully qualified org-name/stack-name for stacks outside your individual account. Required if command is specified.
    • work-dir (optional): Location of Pulumi files. Defaults to ./.
    • cloud-url (optional): The Pulumi backend to login to (equivalent to pulumi login).
    • comment-on-pr (optional): If true, adds results to the Pull Request. Requires pull_request event type.
    • comment-on-summary (optional): If true, adds results to the GitHub step summary.
    • github-token (optional): Token for commenting on PRs. Defaults to ${{ github.token }}.
    • refresh (optional): If true, adds the --refresh flag to preview and up commands.
    • secrets-provider (optional): The encryption provider (e.g., default, passphrase, awskms, azurekeyvault, gcpkms, hashivault).
    • pulumi-version (optional): Specific version of Pulumi CLI to install (e.g., latest, dev, or a version range). Defaults to ^3.
    • pulumi-version-file (optional): Path to a file containing the Pulumi version (e.g., .pulumi.version).
  5. How Pulumi GitHub Action job summaries are formatted

    main

    The Pulumi GitHub Action automatically generates a job summary in the GitHub Actions UI to display results. The summary follows these rules:

    • Formatting: ANSI control codes are stripped to ensure compatibility with GitHub Step Summaries. Leading spaces in lines are replaced with non-breaking spaces ( ) to preserve indentation.
    • Size Limits: To avoid exceeding GitHub's 1 MiB limit, the summary is capped at 1,000,000 bytes.
    • Trimming Behavior: If the output exceeds the size limit, it is trimmed. The direction of trimming depends on the alwaysIncludeSummary configuration:
      • If alwaysIncludeSummary is true: The output is trimmed from the front (keeping the most recent/end part of the output).
      • If alwaysIncludeSummary is false: The output is trimmed from the end.
    • Warnings: If trimming occurs, a warning is appended to the summary heading (e.g., Pulumi <projectName>/<stackName> results :warning: **Warn**: The output was too long and trimmed from the front.).
    • Display: The summary is rendered as a heading followed by a diff language code block containing the output.
  6. Use Pulumi GitHub Action for installation only

    main

    If you only want to download the Pulumi CLI without executing any Pulumi commands, you must provide a pulumi-version (or pulumi-version-file) and must not provide a command input.

    Supported inputs for installation mode:

    • pulumi-version: The version of Pulumi to install.
    • pulumi-version-file: Path to a file containing the version string.
  7. Access Stack Outputs in GitHub Actions

    main

    Stack outputs defined in your Pulumi code are available as named outputs of the action step. To access them, assign an id to the action step and reference the output using ${{ steps.<id>.outputs.<output-name> }}.

    Example: If your Pulumi code exports pet-name, you can access it in a subsequent step.

    - uses: pulumi/actions@v7
      id: pulumi
      env:
        PULUMI_CONFIG_PASSPHRASE: ${{ secrets.PULUMI_CONFIG_PASSPHRASE }}
      with:
        command: up
        cloud-url: gs://my-bucket
        stack-name: org-name/stack-name
    - run: echo "My pet name is ${{ steps.pulumi.outputs.pet-name }}"
  8. Configure Pulumi GitHub Action behavior

    main

    The action's behavior is controlled via configuration (typically passed through GitHub Action inputs). Key configuration areas include:

    • Command & Stack: Specify the command (e.g., up, preview) and the stackName to operate on.
    • Workspace: Set the workDir (resolved relative to GITHUB_WORKSPACE) and secretsProvider.
    • Configuration Mapping: Use configMap to set Pulumi configuration values for the stack before running the command.
    • Logging & Errors: Control how stderr is handled via options.logToStdErr.
    • PR & Summary Integration:
      • commentOnPr: Automatically comment on Pull Requests if a PR context is detected.
      • commentOnPrNumber: Comment on a specific PR number.
      • commentOnSummary: Post a summary of the Pulumi operation to the GitHub Action summary page.
    • Cleanup: Use remove with the destroy command to remove the stack from the workspace after destruction.
  9. Use extra options in Pulumi GitHub Actions

    main

    Advanced configuration can be passed via extra options:

    • config-map: Stack configuration in YAML string format: {<key | string>: {value: <value | string>, secret: <is_secret | boolean> },}.
    • diff: Displays operation as a rich diff.
    • edit-pr-comment: If true (default since 3.2.0), edits the previous PR comment instead of posting a new one.
    • expect-no-changes: Returns an error if changes occur during an update.
    • policyPacks: Run one or more policy packs (one per line).
    • policyPackConfigs: Path(s) to JSON config files for policy packs.
    • remove: Removes the target stack if all resources are destroyed (used with destroy).
    • replace: Specify resources to replace (one per line).
    • target: Specify a single resource URN to update (one per line).
    • target-dependents: Updates dependent targets discovered via the target.
    • upsert: Creates the stack if it doesn't exist (creates a Pulumi.<stack-name>.yaml file).
    • exclude-protected: Skip destroying protected resources (used with destroy).
    • suppress-outputs: Suppress display of stack outputs.
    • plan: Used for update plans. On preview, specifies where to save the plan; on up, specifies where to read it from.
  10. Install the Pulumi CLI

    main

    The downloadCli function manages the installation of the Pulumi CLI on the GitHub runner. It handles version resolution, platform detection, downloading, and extraction.

    Key Behaviors:

    • Version Resolution: It accepts a version range (e.g., 'latest', '3.0.0', or dynamic ranges like 'dev' or 'pr#123').
    • Optimization: If the requested version (or a compatible version) is already installed on the runner, it skips the download to save time.
    • Safety: It automatically detects and bypasses known bad versions (e.g., 3.66.0, 3.67.0, 3.67.1, 3.120.0) that have regressions with specific flags.
    • Platform Support: Supports Darwin (x64, arm64), Linux (x64, arm64), and Windows (x64).
    • Dynamic Versions: For PR builds (e.g., pr#123), it uses the GITHUB_TOKEN for authentication and extracts the artifact from a zip file.
    • Path Management: After installation, it adds the Pulumi binary directory to the system PATH using core.addPath.
    import { downloadCli } from './libs/pulumi-cli';
    
    // Install the latest version
    await downloadCli('latest');
    
    // Install a specific version range
    await downloadCli('^3.0.0');
    
    // Install a specific PR build
    await downloadCli('pr#123');