pulumi/pulumi
PCL package
Active contributors: Fraser Waters, Ian Wahbe
Purpose
PCL — Pulumi Configuration Language — is the HCL-derived intermediate representation that pulumi convert runs through. It is not intended as a user-facing language for writing infrastructure (despite being a "language"). It's the IR every converter targets, and the IR every emitter consumes.
Where it lives
The PCL implementation is split across the repo:
| Concern | Path |
|---|---|
| Parser (HCL2 substrate) | pkg/codegen/hcl2/ |
| PCL binder + checker | pkg/codegen/pcl/ |
| PCL host binary | sdk/pcl/cmd/pulumi-language-pcl/ |
| Library / public API | sdk/pcl/ |
| Per-language emitters that consume PCL | pkg/codegen/{go,nodejs,python}/gen_program.go (and equivalents in external repos) |
| Tests / fixtures | pkg/codegen/testdata/programs/ |
What PCL looks like
config myBucketName string {
default = "my-bucket"
}
resource bucket "aws:s3/bucket:Bucket" {
options {
protect = true
}
bucket = myBucketName
}
resource role "aws:iam/role:Role" {
name = "${myBucketName}-role"
assumeRolePolicy = "..."
}
output bucketArn {
value = bucket.arn
}PCL maps cleanly to Pulumi's data model:
config→pulumi.Config.resource <name> "<type>"→RegisterResource.${expr}→ string interpolation, lifts throughOutput.output <name>→ stack output.component <name> "<path>"→ component reference (multi-language components).
Pipeline
graph LR
External[Other IaC<br/>Terraform/CFN/K8s YAML] -->|converter plugin| PCL
PCL[PCL program] -->|hcl2.Parse| AST
AST -->|pcl.BindProgram| Bound[Bound *Program]
Bound -->|GenerateProgram| Go[Go source]
Bound -->|GenerateProgram| Node[TS source]
Bound -->|GenerateProgram| Python[Python source]
Bound -->|GenerateProgram| DotNet[C# source]
Bound -->|GenerateProgram| Java[Java source]
Bound -->|GenerateProgram| YAML[Pulumi YAML source]The bound program is the canonical in-memory representation. Every emitter (in pkg/codegen/<lang>/gen_program.go) walks it.
Type system
PCL has a Pulumi-flavored type system layered on HCL2:
- Primitive types:
string,number,bool,int. - Compound:
list(<T>),map(<T>),union(<T>...),option(<T>),set(<T>). - Pulumi types:
Output<T>,Input<T>, resource type tokens (aws:s3/bucket:Bucket). - Dynamic:
any(escape hatch).
pcl.Type (pkg/codegen/pcl/types.go) is the in-memory type. Unification, type narrowing, and inference happen during BindProgram.
Function calls
PCL supports a small set of built-in invokes plus everything the schema declares. Built-ins include:
| Function | Purpose |
|---|---|
invoke(fn, args) |
Call a provider data-source |
secret(value) |
Mark a value secret |
singleOrNone(seq) |
Assert at-most-one |
entries(map) |
Convert to list of key/value pairs |
range(n) |
Numeric range |
length(...), keys(...), values(...) |
Standard collection helpers |
fileAsset(...), remoteAsset(...), stringAsset(...), fileArchive(...), remoteArchive(...), assetArchive(...) |
Asset / Archive constructors |
The full list lives in pkg/codegen/pcl/functions.go.
PCL as a runnable language
sdk/pcl/cmd/pulumi-language-pcl/ ships a language host so that PCL programs can — in principle — be run directly:
runtime: pclIn practice this is rarely useful for end users; it's primarily a testing harness for converters and emitters.
Tests
pkg/codegen/pcl/binder_test.goetc. — type-checker tests.pkg/codegen/testdata/programs/— golden corpus of PCL programs that every emitter must round-trip.
Entry points for modification
- A new built-in function —
pkg/codegen/pcl/functions.go(registration + type signature) and update every emitter (pkg/codegen/<lang>/gen_program.go). - A new HCL syntax —
pkg/codegen/hcl2/. Try not to. PCL stays close to HCL on purpose. - A type-system change —
pkg/codegen/pcl/types.goand the binder. High-impact; review carefully.
See also
- Codegen
- Features: import — uses programgen to generate source.
- Apps: language hosts → PCL
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.