-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move the /pkg/pf/README.md
user facing docs into /docs
#2734
Merged
Merged
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
# Developing a New Plugin Framework Provider | ||
|
||
Follow these steps to bridge a Terraform Provider to Pulumi. | ||
|
||
1. You will need a Provider value from the `github.com/hashicorp/terraform-plugin-framework/provider` | ||
package. You can build it yourself as part of developing a Terraform Provider, or find it in published | ||
Terraform sources. | ||
|
||
For example, `terraform-provider-random` [exposes](https://github.com/hashicorp/terraform-provider-random/blob/main/internal/provider/provider.go#L13) a `func New() provider.Provider` call. Since this | ||
definition lives in an `internal` package it cannot easily be referenced in an external Go project, but it | ||
is still possible to reference it using Go linker tricks. See [pulumi-random](https://github.com/pulumi/pulumi-random/tree/48c0b3014aeaa0cb95fd6419d631cb2555ce89ac/provider/shim) for a full example. | ||
|
||
2. Populate a `ProviderInfo` struct, mapping Terraform resource names to Pulumi tokens. Replace `myprovider` | ||
with your provider name. | ||
|
||
```go | ||
package myprovider | ||
|
||
import ( | ||
_ "embed" | ||
"github.com/hashicorp/terraform-plugin-framework/provider" | ||
pf "github.com/pulumi/pulumi-terraform-bridge/v3/pf/tfbridge" | ||
"github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfbridge" | ||
) | ||
|
||
//go:embed cmd/pulumi-resource-myprovider/bridge-metadata.json | ||
var bridgeMetadata []byte | ||
|
||
func MyProvider() tfbridge.ProviderInfo { | ||
info := tfbridge.ProviderInfo{ | ||
P: pf.ShimProvider(<TODO fill in Terraform Provider from Step 1>), | ||
Name: "myprovider", | ||
Version: "1.2.3", | ||
Resources: map[string]*tfbridge.ResourceInfo{ | ||
"myresource": {Tok: "myprovider::MyResource"}, | ||
}, | ||
MetadataInfo: tfbridge.NewProviderMetadata(bridgeMetadata), | ||
} | ||
return info | ||
} | ||
``` | ||
|
||
3. Build a `pulumi-tfgen-myprovider` binary. | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"github.com/pulumi/pulumi-terraform-bridge/v3/pf/tfgen" | ||
// import myprovider | ||
) | ||
|
||
func main() { | ||
tfgen.Main("myprovider", myprovider.MyProvider()) | ||
} | ||
``` | ||
|
||
4. Generate a [Pulumi Package Schema](https://www.pulumi.com/docs/guides/pulumi-packages/schema/) and bridge metadata. | ||
|
||
```bash | ||
mkdir -p ./schema | ||
pulumi-tfgen-myprovider schema --out ./schema | ||
jq . ./schema/schema.json | ||
jq . ./schema/bridge-metadata.json | ||
``` | ||
|
||
5. Build the Pulumi provider binary `pulumi-resource-myprovider`, embedding the generated `schema.json` and | ||
`bridge-metadata.json` from Step 4. | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"context" | ||
_ "embed" | ||
|
||
"github.com/pulumi/pulumi-terraform-bridge/v3/pf/tfbridge" | ||
// import myprovider | ||
) | ||
|
||
//go:embed schema.json | ||
var schema []byte | ||
|
||
func main() { | ||
meta := tfbridge.ProviderMetadata{PackageSchema: schema} | ||
tfbridge.Main(context.Background(), "myprovider", myprovider.MyProvider(), meta) | ||
} | ||
``` | ||
|
||
6. To try out the provider, place `pulumi-resource-myprovider` in PATH and create a new Pulumi YAML project to | ||
instantiate the provider's resources, and run `pulumi up` on that project: | ||
|
||
``` | ||
name: basicprogram | ||
runtime: yaml | ||
resources: | ||
r1: | ||
type: myprovider::MyResource | ||
properties: | ||
prop1: x | ||
prop2: y | ||
``` | ||
|
||
7. If you want to test using the provider from other languages such as TypeScript, you can generate the SDKs | ||
for each language by running `pulumi-tfgen-myprovider` binary (see `--help` for all the options). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
# Upgrading a Bridged Provider to Plugin Framework | ||
|
||
Follow these steps if you have a Pulumi provider that was bridged from a Terraform provider built against | ||
[Terraform Plugin SDK](https://github.com/hashicorp/terraform-plugin-sdk) and you want to upgrade it to a version that has migrated to the Plugin Framework. | ||
|
||
1. Ensure you have access to the [`github.com/hashicorp/terraform-plugin-framework/provider.Provider`](https://pkg.go.dev/github.com/hashicorp/[email protected]/provider#Provider) from | ||
the upstream provider. Make sure the module is now depending on | ||
`"github.com/hashicorp/terraform-plugin-framework"` instead of | ||
`"github.com/hashicorp/terraform-plugin-sdk/v2"`. If the provider is shimmed (or needs to be), update the | ||
source code accordingly. For example, a `shim.go` that looked like this: | ||
|
||
```go | ||
package shim | ||
|
||
import ( | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
"github.com/hashicorp/terraform-provider-tls/internal/provider" | ||
) | ||
|
||
func NewProvider() *schema.Provider { | ||
p, _ := provider.New() | ||
return p | ||
} | ||
``` | ||
|
||
Becomes: | ||
|
||
```go | ||
package shim | ||
|
||
import ( | ||
"github.com/hashicorp/terraform-plugin-framework/provider" | ||
p "github.com/hashicorp/terraform-provider-tls/internal/provider" | ||
) | ||
|
||
func NewProvider() provider.Provider { | ||
return p.New() | ||
} | ||
``` | ||
|
||
Make sure the module builds: | ||
|
||
``` | ||
cd provider/shim | ||
go mod tidy | ||
go build | ||
``` | ||
|
||
2. Find tfgen binary `main` that calls `tfgen.Main` from `github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfgen` | ||
and update it to call `tfgen.Main` from `github.com/pulumi/pulumi-terraform-bridge/v3/pf/tfgen`. | ||
|
||
Note that the extra verson parameter is removed from `tfgen.Main`, so this code: | ||
|
||
```go | ||
tfgen.Main("tls", version.Version, tls.Provider()) | ||
``` | ||
|
||
Becomes: | ||
|
||
``` | ||
tfgen.Main("tls", tls.Provider()) | ||
``` | ||
|
||
3. Find the provider binary `main` that calls `tfbridge.Main` from | ||
`github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfbridge` and update it to `Main` from | ||
`github.com/pulumi/pulumi-terraform-bridge/v3/pf/tfbridge`. Note the signature changes: version parameter is removed, | ||
`Context` is now required, and there is a new `bridge-metadata.json` blob that needs to be embedded: | ||
|
||
```go | ||
... | ||
|
||
func main() { | ||
meta := tfbridge.ProviderMetadata{PackageSchema: schema} | ||
tfbridge.Main(context.Background(), "myprovider", myprovider.MyProvider(), meta) | ||
} | ||
``` | ||
|
||
4. Update code declaring `tfbridge.ProviderInfo` (typically in `provider/resources.go`): | ||
|
||
```go | ||
|
||
//go:embed cmd/pulumi-resource-myprovider/bridge-metadata.json | ||
var bridgeMetadata []byte | ||
|
||
func Provider() tfbridge.ProviderInfo { | ||
info := tfbridge.ProviderInfo{ | ||
// Replace P (abbreviated for Provider): | ||
P: pf.ShimProvider(shim.NewProvider()). | ||
|
||
// Make sure Version is set, as it is now required. | ||
Version: ..., | ||
|
||
// This is now required. | ||
MetadataInfo: tfbridge.NewProviderMetadata(bridgeMetadata), | ||
|
||
// Keep the rest of the code as before. | ||
} | ||
return info | ||
} | ||
``` | ||
|
||
5. From this point the update proceeds as a typical upstream provider update. Build and run the tfgen binary to compute | ||
the Pulumi Package Schema. It will now also compute a new metadata file `bridge-metadata.json`, build the provider | ||
binary, re-generate language-specific SDKs and run tests. | ||
|
||
``` | ||
make tfgen | ||
make provider | ||
make build_sdks | ||
``` |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was broken before.