pulumi/pkg/codegen/pcl
Zaid Ajaj f146c2e688
[PCL] Implement package descriptor blocks to support parameterized packages (#17589)
### Description

As part of fixing
https://github.com/pulumi/pulumi-converter-terraform/issues/186 we need
to be able to express resources and packages in PCL that are coming from
parameterized providers.

Today in PCL we will extract the package name from the token of a
resource definition and load that package based on the name (using
`LoadReference`) . For parameterized packages, this will not work
because the schema of the parameterized resource is only available after
we figure out which base provider is being parameterized and what the
parameters are.

In this PR we fix this problem by implementing top-level `package`
blocks that are full package descriptors that contain sufficient
information to load both classic resource plugins and parameterized
packages. The block will looks like:
```tf
package <name> {
  baseProviderName = <name>
  baseProviderVersion = <version>
  baseProviderDownloadUrl = <url>
  parameterization {
      name = <name>
      version = <version>
      value = <base64-encoded-value>
  }
}
```
Example of a package descriptors for a `terraform-provider` provider
parameterized with `hashicorp/random`:
```tf
package "random" {
    baseProviderName = "terraform-provider"
    baseProviderVersion = "0.0.27"
    parameterization {
        name = "random"
        version = "3.6.2"
        value = "eyJyZW1vdGUiOnsidXJsIjoicmVnaXN0cnkub3BlbnRvZnUub3JnL2hhc2hpY29ycC9yYW5kb20iLCJ2ZXJzaW9uIjoiMy42LjIifX0="
    }
}

resource "randomPet" "random:index/pet:Pet" { 
    length = 10 
}
``` 
Now when we extract the package name from `random:index/pet:Pet =>
random` we check if there is a package descriptor for it and use that
descriptor to load the package, parameterizing the base provider when
necessary. Otherwise if the package name doesn't have a descriptor, we
fallback to old package loader that expects plugin
`pulumi-resource-<packageName>` to be available in the plugin cache or
PATH.

These blocks are not mapped to specific `Program` nodes, they are read
from the AST after the PCL files have been parsed.
This information can be easily made available to `pcl.Program` if needed
since it has access to the source binder.

### Conformance Tests

With the ability to parameterize packages from a PCL program, we can
support conformance testing parameterized providers! I've implemented a
new test `l2-parameterized-resource` which implements a parameterized
provider that has a schema and runtime behaviour dictated by the values
it was parameterized with.


### Test this locally
You can test this locally with different parameterized providers, you
will need their parameter values which you can retrieve from the schema:
```
pulumi package get-schema terraform-provider hashicorp/random > random-schema.json
```
In `random-schema.json` you will find values you need in
`$.parameterization`

### Converted Code

The program above can be successfully converted to TypeScript for
example and generates the following:
```ts
import * as pulumi from "@pulumi/pulumi";
import * as random from "@pulumi/random";

const randomPet = new random.Pet("randomPet", {length: 10});
```
This program loaded the parameterized schema and used it to generate the
resource definition correctly.

However the following still need to be addressed:
- The `pulumi convert` doesn't generate the local SDKs are part of the
conversion. Doing this might make
https://github.com/pulumi/pulumi-converter-terraform/issues/186 a lot
easier than expected. cc @brandonpollack23
- Program generators do not understand parameterized packages so they
reference them like any of our provider sdk `"@pulumi/random": "3.6.2"`
(this is wrong because there is not such sdk on npm). They should expect
the SDK to be available locally and reference it via a relative path
 - ~We need a good way to (conformance) test these~ DONE 
2024-11-05 00:58:48 +00:00
..
README.md Document code generation concepts (#17162) 2024-09-05 13:12:59 +00:00
binder.go [PCL] Implement package descriptor blocks to support parameterized packages (#17589) 2024-11-05 00:58:48 +00:00
binder_component.go [PCL] Implement package descriptor blocks to support parameterized packages (#17589) 2024-11-05 00:58:48 +00:00
binder_nodes.go Enable some more linting rules (#17456) 2024-10-03 17:37:13 +00:00
binder_resource.go [PCL] Implement package descriptor blocks to support parameterized packages (#17589) 2024-11-05 00:58:48 +00:00
binder_resource_test.go Support loading parameterized schemas in the schema loader (#17108) 2024-08-30 14:25:29 +00:00
binder_schema.go [PCL] Implement package descriptor blocks to support parameterized packages (#17589) 2024-11-05 00:58:48 +00:00
binder_schema_test.go Enable goheader rule and add missing license headers (#15473) 2024-09-09 12:05:45 +00:00
binder_test.go [PCL] Implement package descriptor blocks to support parameterized packages (#17589) 2024-11-05 00:58:48 +00:00
component.go lint 2023-07-27 16:32:06 +02:00
config.go Implement description as comments or docstring for config variables in program-gen 2023-03-21 15:01:16 +01:00
diagnostics.go Enable goheader rule and add missing license headers (#15473) 2024-09-09 12:05:45 +00:00
functions.go Add an `organization` intrinsic to PCL (#16948) 2024-08-19 03:58:19 +00:00
functions_test.go Enable goheader rule and add missing license headers (#15473) 2024-09-09 12:05:45 +00:00
intrinsics.go all: Assert => Assertf 2023-03-03 14:37:43 -08:00
invoke.go Update golangci-lint (#14624) 2023-11-21 15:16:13 +00:00
local.go Do not panic when the type of PCL local variable isn't known 2023-04-13 20:05:16 +02:00
output.go codegen: preserve externally visible names of a resources and outputs (#9464) 2022-04-25 15:07:25 -07:00
program.go Use slice.Prealloc instead of make([]T, 0, ...) 2023-06-29 11:27:50 +01:00
resource.go Add support for `DeletedWith` to `pulumi convert` (#12011) 2024-07-19 14:17:45 +00:00
rewrite_apply.go Vendor the inflector library (#16421) 2024-06-20 09:04:33 +00:00
rewrite_apply_test.go Enable goheader rule and add missing license headers (#15473) 2024-09-09 12:05:45 +00:00
rewrite_convert.go Enable goheader rule and add missing license headers (#15473) 2024-09-09 12:05:45 +00:00
rewrite_convert_test.go Enable goheader rule and add missing license headers (#15473) 2024-09-09 12:05:45 +00:00
rewrite_properties.go Enable goheader rule and add missing license headers (#15473) 2024-09-09 12:05:45 +00:00
type.go [codegen] simplify opaque types to string newtype (#9770) 2022-06-13 11:13:03 -07:00
utilities.go lint 2023-07-28 20:47:36 +02:00
utilities_test.go Enable goheader rule and add missing license headers (#15473) 2024-09-09 12:05:45 +00:00

README.md

(pcl)=

Pulumi Configuration Language (PCL)

Pulumi Configuration Language (PCL) is an internal representation of Pulumi programs which supports all core concepts of the Pulumi programming model in a minimal form. Although not exposed directly to users today, this intermediate representation is used to support a variety of program conversion tasks, from and to various supported Pulumi languages.