{"id":24041836,"url":"https://github.com/pulumi/pulumi-backstage-plugin","last_synced_at":"2025-04-19T19:51:44.811Z","repository":{"id":187535045,"uuid":"676453361","full_name":"pulumi/pulumi-backstage-plugin","owner":"pulumi","description":"Pulumi plugin for Backstage","archived":false,"fork":false,"pushed_at":"2025-02-19T11:56:56.000Z","size":2821,"stargazers_count":22,"open_issues_count":4,"forks_count":3,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-14T07:09:46.836Z","etag":null,"topics":["backstage","pulumi"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pulumi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-09T08:29:34.000Z","updated_at":"2025-03-06T20:29:04.000Z","dependencies_parsed_at":"2024-04-22T11:26:50.277Z","dependency_job_id":"3ebdcf4d-eb1e-46a4-baa0-a3c5dbca37c3","html_url":"https://github.com/pulumi/pulumi-backstage-plugin","commit_stats":null,"previous_names":["dirien/pulumi-backstage-plugin"],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pulumi%2Fpulumi-backstage-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pulumi%2Fpulumi-backstage-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pulumi%2Fpulumi-backstage-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pulumi%2Fpulumi-backstage-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pulumi","download_url":"https://codeload.github.com/pulumi/pulumi-backstage-plugin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249785954,"owners_count":21325559,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backstage","pulumi"],"created_at":"2025-01-08T22:12:43.846Z","updated_at":"2025-04-19T19:51:44.779Z","avatar_url":"https://github.com/pulumi.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"doc/pulumi-backstage.png\" width=\"300\"\u003e\n\n# Pulumi\n\nThis repository contains plugins and modules for [Backstage](https://backstage.io/) to\nsupport [Pulumi](https://www.pulumi.com/).\n\n\u003e [!NOTE]  \n\u003e This is a work in progress and happy to receive feedback and contributions.\n\n\u003e [!IMPORTANT]   \n\u003e The Pulumi Scaffolder Backend Module and the Pulumi Catalog Backend Module in version \u003e `v0.6.0` are now supporting\n\u003e the new [Backstage Backend System](https://backstage.io/docs/backend-system/building-backends/index).\n\nThis repository contains the following Backstage plugins and modules:\n\n- [Pulumi Scaffolder Backend Module](#pulumi-scaffolder-backend-module)\n- [Pulumi Plugin](#pulumi-plugin)\n- [Catalog Backend Module for Pulumi](#catalog-backend-module-for-pulumi)\n\n## Pulumi Scaffolder Backend Module\n\n### Requirements\n\n#### Pulumi CLI\n\nYou need to have the Pulumi CLI installed on the Backstage server.\n\nIf you use the Backstage Dockerfile, add following lines before the `USER node` line:\n\n```Dockerfile\nRUN --mount=type=cache,target=/var/cache/apt,sharing=locked \\\n    --mount=type=cache,target=/var/lib/apt,sharing=locked \\\n    apt-get update \u0026\u0026 \\\n    apt-get install -y --no-install-recommends curl ca-certificates\n```\n\nand add following lines after the `USER node` line:\n\n```Dockerfile\nRUN \u003c\u003cEOF\n## Install pulumi and set to PATH\ncurl -fsSL https://get.pulumi.com | sh\nEOF\n\nENV PATH=\"/node/.pulumi/bin:${PATH}\"\n````\n\nThis will install the latest Pulumi CLI to your Backstage container.\n\n#### Pulumi Personal Access Token (PAT)\n\nTo authenticate to the Pulumi cloud service, you need to provide additionally the Pulumi Personal Access Token via the\nenvironment variable `PULUMI_ACCESS_TOKEN``\n\n#### Programming languages runtimes\n\nIf you're not going to use the [Pulumi Deployment](https://www.pulumi.com/docs/pulumi-cloud/deployments/) service, you need\nto be sure that all the programming language runtimes are installed on your Backstage service\n\n### Getting Started\n\nYou need to configure the action in your backend:\n\n### From your Backstage root directory\n\n```bash\n# From your Backstage root directory\nyarn add --cwd packages/backend @pulumi/backstage-scaffolder-backend-pulumi\n```\n\nConfigure the action (you can check\nthe [docs](https://backstage.io/docs/features/software-templates/writing-custom-actions#registering-custom-actions) to\nsee all options):\n\n```typescript\n// packages/backend/src/index.ts\nconst backend = createBackend();\nbackend.add(import('@pulumi/backstage-scaffolder-backend-pulumi'));\n```\n\n### PULUMI_ACCESS_TOKEN\n\nYou need to set the `PULUMI_ACCESS_TOKEN` environment variable to be able to use the Pulumi action.\n\n### Pulumi New Action\n\nThe Pulumi New Action is a custom action that allows you to create a new Pulumi project from a template.\n\n`pulumi:new`\n\n| Input        | Description                                                                        | Type          | Required |\n|--------------|------------------------------------------------------------------------------------|---------------|----------|\n| stack        | The Pulumi stack to use                                                            | string        | Yes      |\n| organization | The Pulumi organization to use for the Pulumi commands                             | string        | Yes      |\n| name         | The Pulumi project name to use                                                     | string        | Yes      |\n| template     | The Pulumi template to use, this can be a built-in template or a URL to a template | string        | Yes      |\n| description  | The Pulumi project description to use                                              | string        | Yes      |\n| config       | The Pulumi project config to use                                                   | object        | No       |\n| secretConfig | The Pulumi project secret config to use                                            | object        | No       |\n| args         | The Pulumi command arguments to run                                                | array(string) | No       |\n| folder       | The folder to run Pulumi in                                                        | string        | Yes      |\n\n```yaml\napiVersion: scaffolder.backstage.io/v1beta3\nkind: Template\nmetadata:\n  name: kubernetes-template\n  title: Kubernetes Cluster\n  description: |\n    A template for creating a new Kubernetes Cluster.\n  tags:\n  - pulumi\n  - kubernetes\nspec:\n  steps:\n  - id: pulumi-new-component\n    name: Cookie cut the component Pulumi project\n    action: pulumi:new\n    input:\n      name: \"${{ parameters.component_id }}-infrastructure\"\n      description: ${{ parameters.description | dump }}\n      organization: ediri\n      stack: ${{ parameters.stack }}\n      template: \"https://github.com/my-silly-organisation/microservice-civo/tree/main/infrastructure-${{ parameters.cloud }}-${{ parameters.language }}\"\n      config:\n        \"node:node_count\": \"${{ parameters.nodeCount }}\"\n      folder: .\n```\n\n### Pulumi Up Action\n\nThe Pulumi Up Action is a custom action that allows you to run the `pulumi up` command.\n\n`pulumi:up`\n\n| Input                      | Description                                                         | Type          | Required |\n|----------------------------|---------------------------------------------------------------------|---------------|----------|\n| stack                      | The Pulumi stack to use                                             | string        | Yes      |\n| organization               | The Pulumi organization to use for the Pulumi commands              | string        | Yes      |\n| name                       | The Pulumi project name to use                                      | string        | Yes      |\n| deployment                 | This flag indicates that Pulumi Deployment will be used             | boolean       | Yes      |\n| config                     | The Pulumi project config to use                                    | object        | No       |\n| secretConfig               | The Pulumi project secret config to use                             | object        | No       |\n| outputs                    | The Pulumi project outputs to return                                | array(string) | No       |\n| repoUrl                    | The Pulumi project repo URL to use, when using Pulumi Deployment    | string        | No       |\n| repoBranch                 | The Pulumi project repo branch to use, when using Pulumi Deployment | string        | No       |\n| repoProjectPath            | The Pulumi project repo path to use, when using Pulumi Deployment   | string        | No       |\n| providerCredentialsFromEnv | The Pulumi project provider credentials to use                      | array(string) | No       |\n| preRunCommands             | The Pulumi project pre-run commands to run                          | array(string) | No       |\n| suppressProgress           | Suppress progress output                                            | boolean       | No       |\n\nThe action offers also Pulumi deployment support, to use it you need to set the `deployment` input to `true`. If you did\nnot set any `config` or `secretConfig`, during the `pulumi:new` action, you need to set them here. If you have any\nprovider related credentials, you need to set the `providerCredentialsFromEnv` input.\n\n```yaml\napiVersion: scaffolder.backstage.io/v1beta3\nkind: Template\nmetadata:\n  name: kubernetes-template\n  title: Kubernetes Cluster\n  description: |\n    A template for creating a new Kubernetes Cluster.\n  tags:\n  - pulumi\n  - kubernetes\nspec:\n  steps:\n  - id: pulumi-deploy-infrastructure\n    name: Deploy the infrastructure using Pulumi CLI\n    action: pulumi:up\n    input:\n      deployment: false\n      name: \"${{ parameters.component_id }}-infrastructure\"\n      repoUrl: \"https://github.com/${{ (parameters.repoUrl | parseRepoUrl)['owner'] }}/${{ (parameters.repoUrl | parseRepoUrl)['repo'] }}\"\n      repoProjectPath: .\n      organization: ediri\n      outputs:\n      - kubeconfig\n      - ClusterId\n      stack: ${{ parameters.stack }}\n```\n\n\u003e [!NOTE]\n\u003e If you run `pulumi:up` via CLI and with a local Pulumi template you may need to install the required dependencies for\n\u003e the Pulumi SDK to work. This can now be done via the `preRunCommands` input.\n\u003e For example for a node based Pulumi project you need to run `npm install` before running `pulumi up`.\n\n## Pulumi Plugin\n\n- Display relevant Pulumi information about an entity within Backstage, such as the Pulumi stack, organization, project\n  name, and project description.\n- Show the Pulumi activity view for an entity within Backstage.\n\n### Requirements\n\n- Setup of the Pulumi plugin for Backstage requires a Pulumi Organization admin to generate a Pulumi access token for\n  the Backstage application.\n\n### Feature Overview\n\n#### Pulumi Card (Component Overview)\n\n\u003cimg src=\"plugins/backstage-plugin-pulumi/doc/component.png\" width=\"500\"\u003e\n\n#### Pulumi Card (System Overview)\n\n\u003cimg src=\"plugins/backstage-plugin-pulumi/doc/system.png\" width=\"500\"\u003e\n\n#### Pulumi Activity View\n\n\u003cimg src=\"plugins/backstage-plugin-pulumi/doc/activity.png\" width=\"500\"\u003e\n\n### Support\n\nIf you need any help with this plugin, feel free to reach out to me!\n\n### Integration Walk-through\n\n#### Install the plugin\n\nThe file paths mentioned in the following steps are relative to your app's root directory — for example, the directory\ncreated by following the [Getting Started](https://backstage.io/docs/getting-started/) guide and creating your app with\n`npx @backstage/create-app`.\n\nFirst, install the Pulumi plugin via a CLI:\n\n```bash\n# From your Backstage root directory\nyarn add --cwd packages/app @pulumi/backstage-plugin-pulumi\n```\n\nNext, add the plugin to `EntityPage.tsx` in `packages/app/src/components/catalog` by adding the following code snippets.\n\nAdd the following imports to the top of the file:\n\n```tsx\nimport {\n    isPulumiAvailable,\n    EntityPulumiCard,\n    EntityPulumiMetdataCard,\n    PulumiComponent\n} from '@pulumi/backstage-plugin-pulumi';\n```\n\nThen create a new constant for the Pulumi Component:\n\n```tsx\nconst pulumiContent = (\n    \u003cEntitySwitch\u003e\n        \u003cEntitySwitch.Case if={isPulumiAvailable}\u003e\n            \u003cPulumiComponent/\u003e\n        \u003c/EntitySwitch.Case\u003e\n    \u003c/EntitySwitch\u003e\n);\n```\n\nFind const `overviewContent` in `EntityPage.tsx`, and add the following snippet inside the outermost Grid defined there,\njust before the closing `\u003c/Grid\u003e` tag:\n\n```tsx\n\u003cEntitySwitch\u003e\n    \u003cEntitySwitch.Case if={isPulumiAvailable}\u003e\n        \u003cGrid item md={6}\u003e\n            \u003cEntityPulumiCard variant=\"gridItem\"/\u003e\n        \u003c/Grid\u003e\n    \u003c/EntitySwitch.Case\u003e\n\u003c/EntitySwitch\u003e\n```\n\nNow find the `serviceEntityPage` constant in `EntityPage.tsx`, and add the following snippet inside:\n\n```tsx\n\u003cEntityLayout.Route path=\"/pulumi\" title=\"Pulumi\" if={isPulumiAvailable}\u003e\n    {pulumiContent}\n\u003c/EntityLayout.Route\u003e\n```\n\nLastly, find the `systemPage` constant in `EntityPage.tsx`, and add the following snippet inside after the\nclosing `\u003c/Grid\u003e` tag of the `\u003cEntityAboutCard variant=\"gridItem\" /\u003e`:\n\n```tsx\n  \u003cEntitySwitch\u003e\n    \u003cEntitySwitch.Case if={isPulumiAvailable}\u003e\n        \u003cGrid item md={6}\u003e\n            \u003cEntityPulumiMetdataCard/\u003e\n        \u003c/Grid\u003e\n    \u003c/EntitySwitch.Case\u003e\n\u003c/EntitySwitch\u003e\n```\n\n#### Configure the plugin\n\nFirst, annotate your component/resource entity with the following:\n\n```yaml\nannotations:\n  pulumi.com/project-slug: [Pulumi Cloud Name: org/stackname/stack]\n```\n\nAnd your system entity with the following:\n\n```yaml\nannotations:\n  pulumi.com/orga-slug: [Pulumi Cloud: org]\n```\n\nNext, provide the API token that the client will use to make requests to the Pulumi Cloud API.\n\nAdd the proxy configuration in `app-config.yaml`:\n\n```yaml\nproxy:\n  '/pulumi':\n    target: 'https://api.pulumi.com/api'\n    changeOrigin: true\n    headers:\n      Authorization: token ${PULUMI_ACCESS_TOKEN}\n      Accept: application/vnd.pulumi+8\n      Content-Type: application/json\n```\n\nThen, start the backend, passing the Pulumi Access Token as an environment variable:\n\n```bash\nexport PULUMI_ACCESS_TOKEN='\u003cPULUMI_ACCESS_TOKEN\u003e' \nyarn start\n```\n\nThis will proxy the request by adding an `Authorization` header with the provided token.\n\n#### How to Uninstall\n\n1. Remove any configuration added in Backstage yaml files, such as the proxy configuration in `app-config.yaml` and the\n   integration key in an entity's annotations.\n1. Remove the added code snippets from `EntityPage.tsx`\n1. Remove the plugin package:\n\n```bash\n# From your Backstage root directory\nyarn remove --cwd packages/app @pulumi/backstage-plugin-pulumi\n```\n\n## Catalog Backend Module for Pulumi\n\nThis is an extension module to the `plugin-catalog-backend` plugin, providing an `PulumiEntityProvider` that can be used to ingest\n[Resource entities](https://backstage.io/docs/features/software-catalog/descriptor-format#kind-resource) from the\n[Pulumi Cloud](https://app.pulumi.com/). This provider is useful if you want to import Pulumi stacks into Backstage.\n\n### Installation\n\nThe provider is not installed by default, therefore you have to add a dependency to `@pulumi/plugin-catalog-backend-module-pulumi`\nto your backend package:\n\n```bash\n# From your Backstage root directory\nyarn add --cwd packages/backend @pulumi/plugin-catalog-backend-module-pulumi\n```\n\nUpdate the catalog plugin initialization in your backend to add the provider and schedule it:\n\n```typescript\n//packages/backend/src/index.ts\nbackend.add(import('@pulumi/plugin-catalog-backend-module-pulumi/alpha'));\n```\n\nAfter this, you also have to add some configuration in your app-config that describes what you want to import for that target.\n\n### Configuration\n\nThe following configuration is an example of how a setup could look for importing stacks from Pulumi Cloud:\n\n```yaml\ncatalog:\n  providers:\n    pulumi:\n      default:\n        api: https://api.pulumi.com\n        organization: \u003cyour organization\u003e\n        pulumiAccessToken: ${PULUMI_ACCESS_TOKEN}\n        schedule:\n          frequency: PT10M\n          timeout: PT50M\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpulumi%2Fpulumi-backstage-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpulumi%2Fpulumi-backstage-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpulumi%2Fpulumi-backstage-plugin/lists"}