> For the complete documentation index, see llms.txt.
Skip to main content

Check out Port for yourself ➜ 

Pulumi

Our integration with Pulumi allows you to combine the state of your infrastructure with the entities representing them in Port.

By using Port's Pulumi provider you make it easy to integrate Port with your existing IaC definitions, every resource provisioned by Pulumi can also be reported to the software catalog using the same definition file.

Common use cases

Our Pulumi provider makes it easy to fill the software catalog with data directly from your IaC definitions, for example:

  • Report cloud accounts.
  • Report databases.
  • Report lambdas and managed Kubernetes services (EKS, AKS, GKE, etc.).

Installation

Prerequisites

To install and use Port's Pulumi provider, you will need to install the Pulumi CLI

To install the Pulumi provider, use your preferred method of installing Pulumi providers.

pip install port_pulumi

Configuration

Follow the steps below to setup the required credentials:

  1. Find your Port credentials:

    Get your Port credentials

    To get your Port credentials, go to your Port application, click on your profile picture , and select Credentials. Here you can view and copy your CLIENT_ID and CLIENT_SECRET:

  2. Configure the credentials using the following command:

    pulumi config set port:clientId <clientId>
    pulumi config set port:secret <clientSecret> --secret
    pulumi config set port:baseUrl <baseUrl>
Selecting a Port API URL by account region

The port_region, port.baseUrl, portBaseUrl, port_base_url and OCEAN__PORT__BASE_URL parameters select which Port API instance to use:

Pulumi definition structure

Port's Pulumi provider supports the following resources:

Entity

The Entity resource defines a basic entity:

"""A Python Pulumi program"""

import pulumi
from port_pulumi import Entity,BlueprintPropertiesArgs

entity = Entity(
"myEntity",
title="My Entity",
blueprint="myBlueprint",
properties=BlueprintPropertiesArgs(),
relations={}
)

The following parameters are required:

  • blueprint - the identifier of the blueprint to create this entity from;
  • title - the title of the entity;
  • One or more properties schema definitions.

It is also possible to specify the following parameters as part of the port_entity resource:

  • identifier - the identifier of the entity; If one is not provided it will be autogenerated.
  • team - the team that owns the entity;
  • blueprint - the identifier of the blueprint from which to create this entity.
  • title - the title of the entity.
  • One or more properties schema definitions.

It is also possible to specify the following parameters as part of the port_entity resource:

  • identifier - the identifier of the entity; If one is not provided it will be autogenerated.
  • team - the team that owns the entity.
  • teams - an array of teams that own the entity.
  • run_id - the run ID of the action that created the entity.

properties schema

The properties schema assigns a specified value to one of the entity's properties.

Definition

"""A Python Pulumi program"""
from port_pulumi import Entity,EntityPropertiesArgs

entity = Entity(
"myEntity",
identifier="myEntity",
title="My Entity",
blueprint="myBlueprint",
properties=EntityPropertiesArgs(
string_props={
"myStringProp": "My string"
}
),
relations={}
)

The following parameters are required:

  • name - the name of the property in the blueprint definition;
  • value - the value of the property (for non-array properties);
  • items - an array of values (for array properties).

relations schema

The relations schema maps a target entity to the source entity definition:

"""A Python Pulumi program"""

import json
import pulumi
from port_pulumi import Entity,EntityRelationsArgs

entity = Entity(
"myEntity",
identifier="myEntity",
title="My Entity",
blueprint="myBlueprint",
properties={},
relations=EntityRelationsArgs(
many_relations={
"myManyRelation": ["myTargetEntityIdentifier", "myTargetEntityIdentifier2"]
},
single_relations={
"mySingleRelation": "myTargetEntityIdentifier"
},
),
)

The following parameters are required:

  • name - the name of the relation in the blueprint definition;
  • identifier - the identifier of the target entity.

Manage existing integrations

The Integration resource lets you manage the mapping configuration of an existing Port integration. It does not create new integrations, you must first install the integration through Port, then use this resource to manage its configuration as code.

The required installationId is assigned when you install an integration. You can find it in the Port UI under Settings → Data sources → Integrations, or via the Get integration API.

import * as pulumi from "@pulumi/pulumi";
import { Integration } from "@port-labs/port";

function stringifyWithSortedKeys(obj: object): string {
return JSON.stringify(obj, Object.keys(obj).sort());
}

const githubIntegration = new Integration("myGithubIntegration", {
installationId: "my-github-integration",
installationAppType: "GitHub",
title: "My GitHub Integration",
version: "",
config: stringifyWithSortedKeys({
createMissingRelatedEntities: false,
resources: [{
kind: "repository",
selector: {
query: ".fork == false",
},
port: {
entity: {
mappings: [{
identifier: ".name",
title: ".name",
blueprint: "'service'",
properties: {
url: ".html_url",
},
relations: {},
}],
},
},
}],
}),
});

Integration resource parameters

ParameterRequiredDescription
installationIdYesThe installation ID of the integration (lowercase letters, numbers, and dashes only).
configNoThe integration mapping configuration as a JSON string.
titleNoDisplay name for the integration.
versionNoThe integration version. Should be set to ""
installationAppTypeNoThe type of integration (e.g. GitHub, GitLab, Azure).
Avoiding unnecessary diffs on every run
  • version : Always set this to an empty string (""). If omitted, the provider reads the current version from Port on each run. Since Port may auto-update the integration, this causes Pulumi to detect a diff and force an update on every pulumi up.
  • config : Standard JSON.stringify (or equivalent) does not guarantee key order. If object keys appear in a different order between runs, Pulumi will detect a diff and trigger an unnecessary update. Use a sorted-key serialization function (shown in the examples above) to ensure consistent output.
    A custom stringifyWithSortedKeys helper in TypeScript/JavaScript, json.dumps(obj, sort_keys=True) in Python, or sorted map keys before marshalling in Go.

Import an existing integration

To begin managing an existing integration with Pulumi, first add the Integration resource to your code (as shown above), then import it into your stack:

pulumi import port:index/integration:Integration myGithubIntegration my-github-integration
  • port:index/integration:Integration is the Pulumi type token for a Port integration.
  • myGithubIntegration is the logical name you gave the resource in code.
  • my-github-integration is the integration's installationId in Port.

After importing, run pulumi up to verify there are no unexpected diffs. If you see changes related to version, ensure you have set version: "" in your resource definition.

Ingest data using the Pulumi provider

To ingest data to the software catalog using the Pulumi provider, you will create an instance of port.Entity resource in your preferred language:

To create an entity using Pulumi, create a file in your preferred language from and insert the following:

"""A Python Pulumi program"""

import pulumi
from port_pulumi import Entity

entity = Entity(
"myEntity",
title="My Entity",
blueprint="myBlueprint",
properties={},
relations={}
)

Then run the following command to apply your changes and update the catalog:

pulumi up -y

After running these commands, you will see your catalog updated with the new entities.