Policy as Code
Relevant source files
The following files were used as context for generating this wiki page:
- pkg/cmd/pulumi/policy/policy_new.go
- pkg/backend/httpstate/client/client.go
- pkg/backend/httpstate/client/client_publish_policy_pack_test.go
- pkg/cmd/pulumi/policy/policy_publish_test.go
- pkg/resource/analyzer/summary_test.go
- sdk/go/common/workspace/templates.go
- pkg/engine/lifecycletest/testdata/output/TestSimpleAnalyzeResourceMultipleViolations/progress.stdout.txt
Pulumi's Policy as Code feature allows organizations to define, enforce, and manage policies for their cloud infrastructure. These policies act as guardrails to ensure compliance, security, and best practices across all Pulumi-managed resources. Policies are written in familiar programming languages and are packaged into "Policy Packs," which can be published and applied to stacks within a Pulumi organization.
This system is managed through a set of pulumi policy CLI commands for creating and publishing policies, and a backend API for managing their lifecycle. When a Pulumi program is run (e.g., with pulumi up), enabled policies are evaluated against the resources in the stack, and any violations are reported. Depending on the enforcement level, these violations can either serve as warnings or block the update entirely.
Core Concepts
Policy Pack
A Policy Pack is a collection of individual policies, packaged as a Pulumi project. It is the unit of distribution and management for policies. A new Policy Pack can be created from a template using the pulumi policy new command.
The structure of a Policy Pack is defined by a PulumiPolicy.yaml file, which is loaded as a PolicyPackProject object. This file specifies metadata about the pack, such as its name, runtime, and description.
Sources: pkg/cmd/pulumi/policy/policy_new.go:193-196, sdk/go/common/workspace/templates.go:299-313
Policy
A policy is a single rule that validates a resource. Each policy within a pack has several configurable attributes.
| Attribute | Description |
|---|---|
Name | The unique name of the policy. |
DisplayName | A user-friendly name for the policy. |
Description | A detailed explanation of what the policy does. |
EnforcementLevel | Determines the action taken upon violation. |
Message | The message displayed when a policy is violated. |
Severity | The severity of the violation (e.g., critical, high). |
ConfigSchema | A JSON schema for configuring the policy's behavior. |
Framework | The compliance framework the policy relates to (e.g., SOC2). |
Tags | Keywords for categorizing the policy. |
RemediationSteps | Instructions on how to fix a violation. |
URL | A link to more detailed documentation about the policy. |
Sources: pkg/backend/httpstate/client/client.go:1012-1025, pkg/backend/httpstate/client/client_publish_policy_pack_test.go:37-75
Enforcement Levels & Severities
Policies can have different enforcement levels, which dictate the outcome of a violation during a pulumi up.
| Enforcement Level | Behavior |
|---|---|
mandatory | A violation will fail the update. |
advisory | A violation will be reported as a warning but will not fail the update. |
remediate | The system will attempt to automatically remediate the violation. |
disabled | The policy is not evaluated. |
Policy violations can also be assigned a severity level to help prioritize fixes.
| Severity | Description |
|---|---|
critical | A critical issue that must be addressed immediately. |
high | A high-priority issue. |
medium | A medium-priority issue. |
low | A low-priority issue. |
unspecified | Severity is not specified. |
Sources: pkg/resource/analyzer/summary_test.go:94-98, pkg/engine/lifecycletest/testdata/output/TestSimpleAnalyzeResourceMultipleViolations/progress.stdout.txt:11-29
CLI Commands
The pulumi policy command group provides tools for managing the lifecycle of Policy Packs.
pulumi policy new
This command creates a new Policy Pack project from a template.
The following diagram illustrates the workflow for creating a new Policy Pack.
The command supports several flags to customize its behavior:
| Flag | Shorthand | Description |
|---|---|---|
--dir | The directory to create the Policy Pack in. Defaults to the current directory. | |
--force | -f | Force content generation even if it overwrites existing files. |
--generate-only | -g | Generate the Policy Pack files only; do not install dependencies. |
--offline | -o | Use locally cached templates without making network requests. |
Sources: pkg/cmd/pulumi/policy/policy_new.go:76-91
pulumi policy publish
This command publishes a Policy Pack to a Pulumi organization, making it available to be enabled on stacks.
The publishing process involves three main steps:
- The CLI sends the Policy Pack's metadata (name, version, policy definitions) to the Pulumi service.
- The service responds with a pre-signed URL for uploading the policy code.
- The CLI uploads a compressed archive of the Policy Pack directory to the provided URL.
- The CLI signals to the service that the upload is complete, finalizing the publication.
The following sequence diagram shows the interaction between the CLI and the Pulumi service during publishing.
During publishing, VCS metadata (e.g., Git commit hash, repository owner) is also collected and sent to the service if available. This links the published policy to its source code version.
Sources: pkg/cmd/pulumi/policy/policy_publish_test.go:100-143
Other Management Commands
The Pulumi service API provides endpoints for managing policies, which are exposed through the CLI.
| Command | API Endpoint (PATCH) | Description |
|---|---|---|
pulumi policy enable | /api/orgs/{org}/policygroups/{group} | Enables a Policy Pack for a specified Policy Group. |
pulumi policy disable | /api/orgs/{org}/policygroups/{group} | Disables a Policy Pack for a specified Policy Group. |
Additionally, there are commands for removing packs:
| Command | API Endpoint (DELETE) | Description |
|---|---|---|
pulumi policy rm | /api/orgs/{org}/policypacks/{pack} | Removes all versions of a Policy Pack. |
pulumi policy rm --version | /api/orgs/{org}/policypacks/{pack}/versions/{ver} | Removes a specific version of a Policy Pack. |
Sources: pkg/backend/httpstate/client/client.go:1143-1215
Policy Pack Structure and Metadata
When a Policy Pack is published, a CreatePolicyPackRequest is sent to the Pulumi service. This request contains all the necessary metadata about the pack and its policies.
The following diagram shows the relationship between the main data structures involved in publishing a policy pack.
This diagram illustrates the CreatePolicyPackRequest and its nested structures, which are sent to the Pulumi service during the pulumi policy publish command.
Sources: pkg/backend/httpstate/client/client.go:1012-1040, pkg/backend/httpstate/client/client_publish_policy_pack_test.go:37-75
Policy Evaluation and Reporting
When pulumi up is executed, any enabled Policy Packs are loaded and their policies are evaluated against the resources being deployed. The results are streamed to the CLI and displayed in a dedicated "Policies" section.
An example of the output for multiple policy violations is shown below:
Policies:
❌ analyzerA@v1.0.0
- [mandatory] [severity: critical] always-fails-critical (pkgA:m:typA: resA)
a policy failed
- [mandatory] [severity: high] always-fails-high (pkgA:m:typA: resA)
a policy failed
- [advisory] [severity: medium] always-fails-advisory-medium (pkgA:m:typA: resA)
a policy failed
Internally, the results of a policy analysis are compiled into a PolicySummary for each resource. This summary tracks which policies passed and which failed for that resource.
Sources: pkg/resource/analyzer/summary_test.go:28-44
Conclusion
Pulumi's Policy as Code provides a powerful mechanism for enforcing organizational standards and security best practices directly within the infrastructure as code workflow. By allowing policies to be written in general-purpose programming languages and managed as versioned, publishable artifacts (Policy Packs), it offers a flexible and developer-friendly approach to cloud governance. The integration with the Pulumi CLI and service ensures that policies are consistently applied and that violations are clearly reported, helping teams build more secure and compliant cloud infrastructure.