Using Codefresh with Pulumi
Codefresh is a CI/CD platform for Kubernetes and Argo CD, now part of Octopus Deploy. Its CI pipelines run each step as a container, so you run Pulumi in a pipeline step that uses the official pulumi/pulumi container image. That image ships the Pulumi CLI and every language runtime, so the same pipeline works with a Pulumi program written in any supported language and targeting any cloud provider Pulumi supports.
How Pulumi works with Codefresh
To apply infrastructure changes, Pulumi runs your program with the Pulumi CLI. A Codefresh freestyle step provides that environment: it runs a set of commands inside a container image you choose. Point the step at pulumi/pulumi and it can run any pulumi command — install, preview, up — exactly as you would on your own machine.
No special setup is required on the Codefresh side, and Pulumi runs on both free and paid accounts. You wire up authentication through pipeline variables, described below.
Prerequisites
Before you begin, make sure you have:
- A Pulumi Cloud account and organization.
- A Codefresh account with a pipeline connected to your Git repository.
- A Pulumi program in that repository. If you don’t have one yet, follow a Get started guide.
Authenticate with Pulumi Cloud
When your pipeline uses Pulumi Cloud as its backend, it needs only a single Pulumi access token to operate. Pulumi reads the token from the PULUMI_ACCESS_TOKEN environment variable and authenticates without an interactive login.
Store the token outside of source control. Add it as an encrypted variable on the pipeline itself, or — to reuse it across pipelines — create a shared configuration context and import it. Prefer an organization or team token over a personal token so the pipeline’s identity isn’t tied to an individual.
Pulumi ESC (Environments, Secrets, and Configuration) then supplies cloud credentials, secrets, and configuration to your Pulumi program. Because ESC delivers those values the same way whether the consumer is a pipeline or a developer’s machine, a single environment definition works in both places.
You can remove the static token entirely with OpenID Connect (OIDC): the pipeline exchanges a short-lived OIDC token issued by Codefresh for a temporary Pulumi access token, so no long-lived credential is stored anywhere.
Provide cloud credentials
When Pulumi runs, your program also needs credentials for the cloud provider it manages. You can supply them in one of two ways:
- Pulumi ESC (recommended). Configure an ESC environment to broker short-lived cloud credentials through OIDC. Your program receives temporary credentials scoped to exactly what it needs, and the pipeline stores nothing but its Pulumi access token.
- Pipeline variables. Set the provider’s credentials as encrypted pipeline variables — for example,
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEYfor AWS — and expose them to the freestyle step.
Configure a Codefresh pipeline
A Codefresh pipeline is defined in a codefresh.yml file. The following pipeline clones your repository and runs Pulumi against a stack:
version: '1.0'
stages:
- clone
- deploy
steps:
clone:
title: Clone repository
type: git-clone
stage: clone
repo: '${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}'
revision: '${{CF_REVISION}}'
deploy:
title: Deploy with Pulumi
type: freestyle
stage: deploy
image: pulumi/pulumi
working_directory: '${{clone}}/infra'
environment:
- PULUMI_ACCESS_TOKEN=${{PULUMI_ACCESS_TOKEN}}
commands:
- pulumi install
- pulumi stack select acme/website/staging
- pulumi up --yes
The example assumes a Pulumi program in an infra/ directory. pulumi install installs the program’s language dependencies and required plugins, so the same step works for a program written in any supported language.
Build a trunk-based CI/CD workflow
The most common way to run Pulumi in CI/CD follows a trunk-based development model: work merges into a single main branch, and deployments flow outward from there. Codefresh Git triggers distinguish pull request, branch, and tag events, so you can map each stage of the workflow to its own trigger.
Preview infrastructure changes in a pull request
When a pull request is opened, run a dry run instead of a deployment. Attach a Git trigger that fires on pull request events and have the freestyle step run pulumi preview:
commands:
- pulumi install
- pulumi stack select acme/website/staging
- pulumi preview
pulumi preview reports the proposed changes without modifying any resources, giving reviewers a summary of what the merge would do. To let reviewers exercise the change in a live environment, use a Review Stack, which provisions an ephemeral stack for the pull request and destroys it when the pull request closes.
Deploy to staging on merge to the main branch
When a pull request merges, run pulumi up against an environment that receives continuous delivery, such as a shared development or staging environment. Attach a Git trigger that fires on pushes to the main branch:
commands:
- pulumi install
- pulumi stack select acme/website/staging
- pulumi up --yes
Promote to production with a git tag
Production updates should be deliberate. Keep production on its own stack and deploy it only when you push a release tag — for example, a moving production tag that you advance to a commit already validated in staging:
commands:
- pulumi install
- pulumi stack select acme/website/production
- pulumi up --yes
Configure this pipeline’s Git trigger to fire on tag push events rather than branch pushes. Promotion then becomes a single, traceable Git operation, and production never deploys from an untested commit.
Additional resources
- Continuous delivery — overview of running Pulumi in CI/CD.
- CI/CD troubleshooting guide — diagnose common failures when running Pulumi in a pipeline.
- Pulumi ESC — deliver credentials, secrets, and configuration to pipelines and developers consistently.
- OIDC Issuers — eliminate static tokens with short-lived, exchanged credentials.
- Review Stacks — ephemeral environments for pull requests.
- Argo CD — deploy Pulumi stacks with Argo CD, which underpins Codefresh GitOps.
Thank you for your feedback!
If you have a question about how to use Pulumi, reach out in Community Slack.
Open an issue on GitHub to report a problem or suggest an improvement.