Cross-language Components
Cross-language components support consumption in any Pulumi language. You implement the component once in your preferred language, and Pulumi automatically generates SDKs for other languages.
Adding multi-language support
By default, components are authored and consumed in the same programming language by extending the ComponentResource class. The class can then be imported or referenced using the language’s applicable pattern. To support consuming components in other languages, Pulumi can introspect your component class and generate the necessary SDKs. To support multi-language consumption, a couple additional steps are required.
Define a PulumiPlugin.yaml file
In your component directory, create a PulumiPlugin.yaml file and specify the runtime the component is authored in.
runtime: nodejs
runtime: python
runtime: go
runtime: dotnet
runtime: java
Define an entry point
The entrypoint analyzes components to automatically build a schema, and interact with the Pulumi engine to manage the component lifecycle.
Not required for TypeScript.
- Create a
__main__.pyfile in your component directory - In the
mainfunction, add a call tocomponent_provider_host, specifying a list of components for thecomponentsargument
from pulumi.provider.experimental import Metadata, component_provider_host
from staticpage import MyComponent
if __name__ == "__main__":
component_provider_host(name="python-components", components=[MyComponent])
- Define a
main.gofile - Declare an instance of
NewProviderBuilder, passing in a name, namespace and the components being built
github.com/pulumi/pulumi-go-provider.package main
import (
"context"
"log"
"github.com/pulumi/pulumi-go-provider/infer"
)
func main() {
prov, err := infer.NewProviderBuilder().
WithNamespace("your-org-name").
WithComponents(
infer.ComponentF(MyComponent),
).
Build()
if err != nil {
log.Fatal(err.Error())
}
_ = prov.Run(context.Background(), "go-components", "v0.0.1")
}
- Create a
Program.csfile - Add an entry point that calls the
ComponentProviderHost
using System.Threading.Tasks;
class Program
{
public static Task Main(string []args) =>
Pulumi.Experimental.Provider.ComponentProviderHost.Serve(args);
}
- Create an
App.javafile - Create a new instance of
ComponentProviderHostin the entry point
package com.example.components;
import java.io.IOException;
import com.pulumi.provider.internal.Metadata;
import com.pulumi.provider.internal.ComponentProviderHost;
public class App {
public static void main(String[] args) throws IOException, InterruptedException {
new ComponentProviderHost("java-components", App.class.getPackage()).start(args);
}
}
Distribution
Sharing via Git
Storing a component in a Git repository allows for version control, collaboration, and easier integration into multiple projects. Developers can add the component to their Pulumi projects using the command:
pulumi package add <repo_url>[/path/to/component]@<release-version>
The only steps necessary to enable this are to push your component project to a git repo, and create a release tag for the versioning. Pulumi supports referencing both GitHub and GitLab releases. You can also target a standard internally hosted git service, just by providing the repo URL without the <release-version> portion.
Pulumi will automatically generate the needed language-specific end user SDK for your project. For example, if the Pulumi project was written in Python, the pulumi package add command would detect this and generate the Python SDK on-the-fly, as well as adding the dependency to your requirements.txt and running pip install -r requirements.txt for you. The output will also give you an example of the correct import statement to use the component.
$ pulumi package add https://github.com/pulumi/staticpagecomponent@v0.1.0
Downloading provider: github.com_pulumi_staticpagecomponent.git
Successfully generated a Python SDK for the staticpagecomponent package at /example/use-static-page-component/sdks/staticpagecomponent
[...]
You can then import the SDK in your Python code with:
import pulumi_static_page_component as static_page_component
GITHUB_TOKEN and GITLAB_TOKEN if available in order to authenticate access to a private repo during pulumi package add.Publishing to Pulumi IDP Private Registry
Once a component is authored, it can be published to the IDP Private Registry or consumed directly from a git repo.
Pulumi Private Registry is the source of truth for an organization’s infrastructure building blocks like components and templates – the same components and templates that power golden path workflows in Pulumi. To learn more about publishing packages to the private registry, check out the Pulumi Private Registry guide.
Generating local SDKs with pulumi install
Once you’ve added an entry to the packages section of your Pulumi.yaml file, you can run pulumi install to generate a local SDK in your project. This command will process all packages listed in your Pulumi.yaml and create the necessary SDK files. Check in these files if you want fully reproducible builds, or add them to .gitignore if you prefer to regenerate them on each checkout. When using .gitignore, team members will need to run pulumi install after checkout to regenerate the SDK.
SDKs are usually generated locally and committed to version control. Alternatively, you can pre-publish SDKs using a CI/CD process, for example:
git tag v1.0.0
git push origin v1.0.0
pulumi package publish github.com/myorg/my-component@1.0.0
pulumi package gen-sdk . --language nodejs --out sdk/nodejs
npm publish
Repeat the pulumi package gen-sdk and publish steps for each language you want to support. Consumers can then install the SDK directly via their package manager (e.g., npm install my-component) without needing to generate the SDK themselves.
Consumption
How you consume a cross-language component depends on whether the component author pre-published SDKs for your language.
Without pre-published SDKs
If the component author did not pre-publish SDKs, use pulumi package add to add the component. Pulumi will generate the SDK on-the-fly:
pulumi package add github.com/myorg/my-component@1.0.0
Under the hood, Pulumi:
- Fetches your code from GitHub
- Generates a local package SDK from the component’s schema
- Makes the generated SDK available to your Pulumi program in your chosen language
With pre-published SDKs
If the component author pre-published SDKs for your language, you can install the SDK directly via your package manager without needing to generate it:
npm install my-component
pip install my-component
go get github.com/myorg/my-component/sdk/go/my-component
dotnet add package MyComponent
<dependency>
<groupId>com.myorg</groupId>
<artifactId>my-component</artifactId>
<version>1.0.0</version>
</dependency>
Referencing components locally
For scenarios like monorepos, rapid development iterations, or when you’re working with components that don’t need to be published to a repository, you can reference local source code directly:
pulumi package add /path/to/local/secure-s3-component
Pulumi will identify the folder as a Pulumi component project, generate a local package SDK, and make it available for import in your program—even if your consumer program is in a different language.
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.