StackGen Backstage scaffolder reference
StackGen Backstage scaffolder reference
Catalog of scaffolder actions (stackGen:*) and field extensions (ui:field) from
@stackgenhq/backstage-plugin-stackgen + @stackgenhq/backstage-plugin-stackgen-backend.
Published packages (npm)
Packages are published to the public npm registry (https://registry.npmjs.org) under the @stackgenhq scope.
| Package | Role | Latest (latest tag) |
|---|---|---|
| @stackgenhq/backstage-plugin-stackgen | Frontend plugin. Scaffolder field extensions | 0.2.3 |
| @stackgenhq/backstage-plugin-stackgen-backend | Backend plugin. Scaffolder actions, UI proxies, templates | 0.3.8 |
Deprecated: teamId / orgId
Use projectId for the StackGen project Id in templates, field options, and actions.
Older names teamId and orgId still work as aliases for the same value.
| Prefer | Deprecated alias (still accepted) |
|---|---|
ui:field: ProjectSelect | TeamSelect |
ui:options.projectId | teamId, orgId |
Action input projectId | teamId (and orgId where noted) |
createProject output projectId | teamId |
Wiring into Backstage
Selectors (frontend)
Import field extensions from @stackgenhq/backstage-plugin-stackgen and mount them under
<ScaffolderFieldExtensions> (typically packages/app/src/App.tsx). Also register
stackGenPlugin in createApp({ plugins: [...] }).
import {
ProjectSelectFieldExtension,
AppStackNameFieldExtension,
TemplateAppStackSelectFieldExtension,
VaultSecretSelectFieldExtension,
ExporterGitConfigSelectFieldExtension,
ExporterBaseBranchFieldExtension,
ExporterPushBranchFieldExtension,
UserGroupSelectFieldExtension,
RoleSelectFieldExtension,
EnvironmentSelectFieldExtension,
VariableSelectFieldExtension,
stackGenPlugin,
} from '@stackgenhq/backstage-plugin-stackgen';
// createApp({ plugins: [stackGenPlugin], ... })
<Route path="/create" element={<ScaffolderPage />}>
<ScaffolderFieldExtensions>
<ProjectSelectFieldExtension />
<AppStackNameFieldExtension />
<TemplateAppStackSelectFieldExtension />
<VaultSecretSelectFieldExtension />
<ExporterGitConfigSelectFieldExtension />
<ExporterBaseBranchFieldExtension />
<ExporterPushBranchFieldExtension />
<UserGroupSelectFieldExtension />
<RoleSelectFieldExtension />
<EnvironmentSelectFieldExtension />
<VariableSelectFieldExtension />
</ScaffolderFieldExtensions>
</Route>
Actions (backend)
In packages/backend/src/index.ts:
- Register actions via
scaffolder.addActions(...). backend.add(import('@stackgenhq/backstage-plugin-stackgen-backend'))for the main plugin.backend.add(stackgenUiProxiesModule)so scaffolder fields can load data.
import {
createProjectAction,
createAppStackAction,
downloadIaCAction,
setStateBackendAction,
setEnvironmentVariableValuesAction,
assignProjectMembersAction,
exportAppStackToGitAction,
stackgenUiProxiesModule,
} from '@stackgenhq/backstage-plugin-stackgen-backend';
scaffolder.addActions(
createProjectAction(config, logger),
createAppStackAction(config, logger),
downloadIaCAction(config, logger),
setStateBackendAction(config, logger),
setEnvironmentVariableValuesAction(config, logger),
assignProjectMembersAction(config, logger),
exportAppStackToGitAction(config, logger),
);
backend.add(import('@stackgenhq/backstage-plugin-stackgen-backend'));
backend.add(stackgenUiProxiesModule);
Field extensions (ui:field)
ui:field | Value shape | ui:options |
|---|---|---|
ProjectSelect | string (project Id) | none |
TeamSelect (deprecated) | same as ProjectSelect | none |
AppStackSelect | string (appstack name) | projectId (teamId / orgId aliases) |
TemplateAppStackSelect | string (template Id) | none |
VaultSecretSelect | secret identifier string | projectId (teamId / orgId), category, subcategory |
UserGroupSelect | { type: 'user' or 'group', id, label? }[] | groupFilterRegex, userFilterRegex, lockCurrentUser |
RoleSelect | string (role Id) | none |
EnvironmentSelect | string (environment profile Id) | projectId (teamId / orgId), appstackName or topologyId |
VariableSelect | { name, value }[] | projectId (teamId / orgId), appstackName or topologyId |
ExporterGitConfigSelect | string (config id) | projectId (teamId / orgId), appstackName |
ExporterBaseBranch | string | projectId (teamId / orgId), configId |
ExporterPushBranch | { branch?, useSameBranch? } | projectId (teamId / orgId), appstackName |
How ui:options resolve
| Resolution style | Fields | Behavior |
|---|---|---|
| Form field or Id | AppStackSelect, VaultSecretSelect, UserGroupSelect, EnvironmentSelect, VariableSelect | Option may name another form field, or be a literal Id. Waits until a form field has a value. |
| Form field name only | ExporterGitConfigSelect, ExporterBaseBranch, ExporterPushBranch | appstackName / configId must name another parameter (no literal). projectId still accepts form field or UUID. |
| No options | ProjectSelect, TeamSelect, TemplateAppStackSelect, RoleSelect | — |
Prefer ui:options.projectId. Deprecated aliases teamId / orgId still work. Preference order: projectId → teamId → orgId.
What each field does with each option
ProjectSelect
No ui:options. Loads allowed projects and returns the selected project Id.
TeamSelect is a deprecated alias of ProjectSelect (same field, same value).
AppStackSelect
| Option | What it does |
|---|---|
projectId (teamId / orgId) | Form field or Id. When set, loads AppStacks for that project. When missing/empty, loads all AppStacks. |
TemplateAppStackSelect
No ui:options. Loads template AppStacks.
VaultSecretSelect
| Option | What it does |
|---|---|
projectId (teamId / orgId) | Form field or Id. Omit → enterprise (shared) secrets, no project filter. |
category | Literal filter string |
subcategory | Literal filter string |
UserGroupSelect
| Option | What it does |
|---|---|
lockCurrentUser | Boolean (default true). When true, forces token user into the selection, and prevents removing them. |
userFilterRegex | Keeps users whose email (fallback name) match. Invalid regex disables the field with an error. |
groupFilterRegex | Keeps groups whose name match. Invalid regex disables the field with an error. |
RoleSelect
No ui:options. Static Admin / DevOps / Developer plus freeSolo custom Id.
| Label | Id |
|---|---|
| Admin | 00000000-0000-0000-0000-000000000002 |
| DevOps | 00000000-0000-0000-0000-000000000003 |
| Developer | 00000000-0000-0000-0000-000000000004 |
EnvironmentSelect
Single-select environment profile picker. Returns the selected environment profile Id
(typically passed to stackGen:setEnvironmentVariableValues as environmentId).
| Option | What it does |
|---|---|
projectId (teamId / orgId) | Form field or Id. Scopes which profiles to load. |
appstackName | Form field or Id. Loads profiles for that AppStack (usually a form field name). |
topologyId | Form field or Id. Loads profiles for that topology (alternative to appstackName). |
Waits until deps resolve. Clears the selection if the previous Id is no longer in the loaded list.
VariableSelect
Pick existing Terraform variables on a topology and set string values. Returns an array of
{ name, value } pairs (typically passed to stackGen:setEnvironmentVariableValues).
Requires either topologyId, or appstackName plus a project Id.
| Option | What it does |
|---|---|
topologyId | Form field or Id. Loads TF variables for that topology. |
appstackName | Form field or Id. Used with projectId when topologyId is omitted. |
projectId (teamId / orgId) | Form field or Id. Required with appstackName when resolving by AppStack name. |
Waits until scope deps resolve. Does not create new variable definitions; it only picks variables that already exist.
ExporterGitConfigSelect
| Option | What it does |
|---|---|
projectId (teamId / orgId) | Form field or Id. Project scope when listing configs. Required. |
appstackName | Form field name only. Sent as appstackName query param. Required. |
Waits until both project and appstack deps resolve. Auto-selects when exactly one config exists.
ExporterBaseBranch
| Option | What it does |
|---|---|
projectId (teamId / orgId) | Form field or Id. Project scope when loading the selected exporter config. |
configId | Form field name only. Loads that config and prefills from parameters.target_branch / targetBranch. |
ExporterPushBranch
| Option | What it does |
|---|---|
projectId (teamId / orgId) | Form field or Id. Project scope for export-history suggestion. |
appstackName | Form field name only. Used for history lookup. Prefills branch from history. |
Example parameter blocks
projectId:
title: Project
type: string
ui:field: ProjectSelect
appstackName:
title: AppStack
type: string
ui:field: AppStackSelect
ui:options:
projectId: projectId
templateAppstackId:
title: Template AppStack
type: string
ui:field: TemplateAppStackSelect
members:
title: Members
type: array
ui:field: UserGroupSelect
ui:options:
lockCurrentUser: true
items:
type: object
required: [type, id]
properties:
type: { type: string, enum: [user, group] }
id: { type: string }
label: { type: string }
roleId:
title: Role
type: string
ui:field: RoleSelect
default: "00000000-0000-0000-0000-000000000004"
environmentId:
title: Environment
type: string
ui:field: EnvironmentSelect
ui:options:
projectId: projectId
appstackName: appstackName
variableValues:
title: Variable Values
type: array
ui:field: VariableSelect
ui:options:
projectId: projectId
appstackName: appstackName
items:
type: object
properties:
name: { type: string }
value: { type: string }
vaultSecret:
title: Vault secret
type: string
ui:field: VaultSecretSelect
ui:options:
projectId: projectId
category: scm
subcategory: credentials
existingExporterConfigId:
type: string
ui:field: ExporterGitConfigSelect
ui:options:
projectId: projectId
appstackName: appstackName
baseBranch:
type: string
ui:field: ExporterBaseBranch
ui:options:
projectId: projectId
configId: existingExporterConfigId
pushBranch:
type: object
ui:field: ExporterPushBranch
ui:options:
projectId: projectId
appstackName: appstackName
properties:
branch: { type: string }
useSameBranch: { type: boolean }
Actions (stackGen:*)
| Action id | Factory export | Purpose |
|---|---|---|
stackGen:createProject | createProjectAction | Create project/git/env config |
stackGen:createAppStack | createAppStackAction | Create AppStack |
stackGen:assignProjectMembers | assignProjectMembersAction | Assign users/groups + role |
stackGen:setStateBackend | setStateBackendAction | Create/update env profile + state backend |
stackGen:setEnvironmentVariableValues | setEnvironmentVariableValuesAction | Set TF variable values on an existing env |
stackGen:downloadIaC | downloadIaCAction | Download IaC ZIP into workspace |
stackGen:exportToGit | exportAppStackToGitAction | Export via stackgen-exporter |
stackGen:createProject
Creates a StackGen project with optional git and environment configuration. Idempotent on name conflict
Inputs (project)
| Field | Type | Required | Description |
|---|---|---|---|
project.name | string | yes | Project name |
project.description | string | yes | Description |
project.gitConfig | object | no | Git integration template |
project.gitConfig.name | string | no | Config name |
project.gitConfig.type | string | no | e.g. git |
project.gitConfig.parameters.scmType | enum | no | GITHUB |
project.gitConfig.parameters.repoUrl | string | no | Repo URL |
project.gitConfig.parameters.targetBranch | string | no | Branch |
project.gitConfig.parameters.path | string | no | Path in repo |
project.gitConfig.vaultReference | string | no | Vault secret ref for SCM creds |
project.gitConfig.default | boolean | no | Mark as default |
project.environmentConfig | object | no | Env templates + variables |
project.environmentConfig.name | string | no | Config name |
project.environmentConfig.environmentTemplates[] | object | no | { name, color, stateBackendTemplate? } |
project.environmentConfig.variables[] | object | no | { name, type, defaultValueJson, description } |
project.environmentConfig.variableOverrides[] | object | no | { variableName, environmentTemplateName, valueJson } |
stateBackendTemplate.type | enum | no | S3 |
Outputs
| Field | Type | Description |
|---|---|---|
projectId | string | Project id |
projectName | string | Name |
teamId | string | Deprecated alias of projectId |
alreadyExisted | boolean | True if project already exists |
projectURL | string | Project URL |
- id: create-project
name: Create StackGen Project
action: stackGen:createProject
input:
project:
name: ${{ parameters.projectName }}
description: ${{ parameters.projectDescription }}
stackGen:createAppStack
Creates an AppStack with explicit resources, or clones appstack template via templateAppstackId
(mutually exclusive with a non-empty resources array).
Inputs (appstack)
| Field | Type | Required | Description |
|---|---|---|---|
appstack.name or appstackName | string | one required | AppStack name |
appstack.projectId | string | yes | Destination project Id (teamId deprecated alias) |
appstack.cloudProvider | string | if no template | e.g. aws, gcp, azure |
appstack.templateAppstackId | Id | no | Clone from template AppStack |
appstack.resources[] | array | default [] | Resource objects; use [] for a blank AppStack |
Resource object (simplified; full schema is on Installed actions in Backstage)
| Field | Notes |
|---|---|
resourceType | Required |
resourcePackId | Resource pack id |
templateId | Modules Id |
Outputs
| Field | Type | Description |
|---|---|---|
appstackId | string | AppStack id |
appstackName | string | Name |
appStackURL | string | StackGen UI URL |
# Blank AppStack (no resources)
- id: create-appstack
action: stackGen:createAppStack
input:
appstack:
name: ${{ parameters.appstackName }}
projectId: ${{ steps['create-project'].output.projectId }}
cloudProvider: aws
resources: []
stackGen:assignProjectMembers
Assigns users/groups to a project with one role for all selected members.
Inputs
| Field | Type | Required | Description |
|---|---|---|---|
projectId | string | yes | Use createProject → projectId |
members | array | no (default []) | UserGroupSelect output |
roleId | string | no | Role Id; defaults to Developer |
Outputs
| Field | Type | Description |
|---|---|---|
assignedUsers / assignedGroups | number | Counts |
assignedUsersText / assignedGroupsText | string | Help text with users/groups added |
roleId | string | Role applied |
- id: assign-members
action: stackGen:assignProjectMembers
input:
projectId: ${{ steps['create-project'].output.projectId }}
members: ${{ parameters.members }}
roleId: ${{ parameters.roleId }}
stackGen:setStateBackend
Creates/updates an environment profile with a state backend (and optional TF variable definitions).
Inputs
| Field | Type | Required | Description |
|---|---|---|---|
projectId | string | yes | Preferred (teamId deprecated alias) |
appstackName | string | yes | |
environmentName | string | yes | |
color | string | no | default #000000 |
variables[] | object | no | { name, type?, defaultValueJson?, description? } |
variableValues[] | { name, value } | no | name/value pairs |
stateBackend.type | enum | yes | S3 |
stateBackend.config | Record<string,string> | yes | Backend-specific keys |
Outputs: success, environmentId?
- id: setBackendProd
action: stackGen:setStateBackend
input:
projectId: ${{ steps.createProject.output.projectId }}
topologyId: ${{ steps.createAppStack.output.topologyId }}
environmentName: production
color: "#FF0000"
variables:
- name: region
type: string
defaultValueJson: '"us-east-1"'
stateBackend:
type: S3
config:
bucket: my-tf-state
key: production
region: us-west-1
encrypt: "true"
dynamodb_table: TerraformLocks
stackGen:setEnvironmentVariableValues
Sets Terraform variable values on an existing environment profile. Pair with EnvironmentSelect + VariableSelect
for the form values.
Inputs
| Field | Type | Required | Description |
|---|---|---|---|
projectId | string | yes | Preferred (teamId deprecated alias) |
environmentId | string | yes | Existing environment profile Id |
appstackName | string | yes (or topologyId) | Resolve topology by AppStack name |
topologyId | string | yes (or appstackName) | Topology Id when not resolving by AppStack name |
variableValues[] | { name, value } | no (default []) | From VariableSelect; empty skips updates |
String value entries are JSON-parsed when they are valid JSON literals; otherwise they are
kept as plain strings.
Outputs
| Field | Type | Description |
|---|---|---|
updatedCount | number | How many variables were written |
updatedVariablesText | string | Human-readable name = value lines |
environmentId | string | Environment profile Id |
topologyId | string | Resolved topology Id |
- id: setEnvVars
name: Apply Variable Values to Environment
action: stackGen:setEnvironmentVariableValues
input:
projectId: ${{ parameters.projectId }}
appstackName: ${{ parameters.appstackName }}
environmentId: ${{ parameters.environmentId }}
variableValues: ${{ parameters.variableValues }}
stackGen:downloadIaC
Downloads IaC ZIP for a topology into the scaffolder workspace.
Inputs
| Field | Type | Required |
|---|---|---|
projectId | string | yes (teamId deprecated alias) |
appstackName | string | yes |
extractedIaCPath | string | no (default ./) |
Outputs: extractedIacPath
Often paired with publish:github:pull-request (Backstage built-in), not exportToGit.
- id: stackGenIaCDownload
action: stackGen:downloadIaC
input:
appstackName: ${{ parameters.name }}
projectId: ${{ parameters.projectId }}
extractedIaCPath: ${{ parameters.path }}
stackGen:exportToGit
Exports via stack-exporter: resolve topology, pick/bootstrap git config, open PR or commit.
Inputs
| Field | Type | Required | Description |
|---|---|---|---|
appstackName | string | yes | |
projectId | string | yes | Preferred (teamId deprecated alias) |
appstackId | string | no | Resolved if omitted |
configId | string | no | Existing exporter config (wins over gitConfig) |
gitConfig | object | no | Bootstrap if no config; needs parameters.scmType, repoUrl, vaultReference |
baseBranch | string | no | → target_branch |
pushBranch | string | no | → branch_format |
useSameBranch | boolean | no | From ExporterPushBranch when suggestion kept |
createPr | boolean | no | false = commit only |
overrides[] | { key, value } | no | e.g. pr_title, commit_msg |
Outputs: pullRequestUrl?, externalLink?, committedBranch?, notes?
- id: exportToGit
action: stackGen:exportToGit
input:
projectId: ${{ parameters.projectId }}
appstackName: ${{ parameters.appstackName }}
configId: ${{ parameters.existingExporterConfigId }}
baseBranch: ${{ parameters.baseBranch }}
pushBranch: ${{ parameters.pushBranch.branch }}
useSameBranch: ${{ parameters.pushBranch.useSameBranch }}
createPr: ${{ parameters.createPr }}
overrides:
- key: pr_title
value: ${{ parameters.prTitle }}
- key: commit_msg
value: ${{ parameters.commitMessage }}
Example templates
1. Create a Basic project
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: stackgen-project-basic
title: Create Project (Basic)
description: Create an empty StackGen project
spec:
owner: user:guest
type: service
parameters:
- title: Project Information
required:
- projectName
properties:
projectName:
title: Project Name
type: string
ui:autofocus: true
steps:
- id: create-project
name: Create StackGen Project
action: stackGen:createProject
input:
project:
name: ${{ parameters.projectName }}
description: Project created via Backstage
output:
links:
- title: View Created Project
url: ${{ steps['create-project'].output.projectURL }}
2. Create a Project, assign members and create AppStack from template in the Project
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: stackgen-project-appstack-groups
title: Create Project, AppStack, and Groups
description: >
Create a StackGen project, provision an AppStack from a template, and
assign groups (or users) to the project.
tags:
- stackgen
- project
- infrastructure
- groups
spec:
owner: user:guest
type: service
parameters:
- title: Project
required:
- projectName
- members
properties:
projectName:
title: Project Name
type: string
description: Name of the StackGen project to create
ui:autofocus: true
projectDescription:
title: Description
type: string
default: Project created via Backstage
members:
title: Groups / Members
type: array
description: >
Select one or more groups (and optional users) to associate with
the project.
ui:field: UserGroupSelect
ui:options:
lockCurrentUser: false
minItems: 1
items:
type: object
required:
- type
- id
properties:
type:
type: string
enum: [user, group]
id:
type: string
label:
type: string
roleId:
title: Project role
type: string
description: >
Role applied to every selected user/group. Pick Admin, DevOps, or
Developer. Leave blank to use the action default (developer).
ui:field: RoleSelect
default: "00000000-0000-0000-0000-000000000004"
- title: AppStack
required:
- appstackName
- templateAppstackId
properties:
appstackName:
title: AppStack Name
type: string
description: Name for the new AppStack in the created project
minLength: 4
cloudProvider:
title: Cloud Provider (optional)
type: string
description: Overrides provider from the template when set
enum:
- aws
- gcp
- azure
templateAppstackId:
title: Template AppStack
type: string
description: StackGen template AppStack whose topology is cloned
ui:field: TemplateAppStackSelect
steps:
- id: create-project
name: Create StackGen Project
action: stackGen:createProject
input:
project:
name: ${{ parameters.projectName }}
description: ${{ parameters.projectDescription }}
- id: create-appstack
name: Create AppStack from Template
action: stackGen:createAppStack
input:
appstack:
name: ${{ parameters.appstackName }}
projectId: ${{ steps['create-project'].output.projectId }}
templateAppstackId: ${{ parameters.templateAppstackId }}
cloudProvider: ${{ parameters.cloudProvider }}
resources: []
- id: assign-groups
name: Assign Groups to Project
action: stackGen:assignProjectMembers
input:
projectId: ${{ steps['create-project'].output.projectId }}
members: ${{ parameters.members }}
roleId: ${{ parameters.roleId }}
output:
links:
- title: View Created Project
url: ${{ steps['create-project'].output.projectURL }}
- title: View Created AppStack in StackGen
url: ${{ steps['create-appstack'].output.appStackURL }}
text:
- title: Assigned groups
content: ${{ steps['assign-groups'].output.assignedGroupsText }}
- title: Assigned users
content: ${{ steps['assign-groups'].output.assignedUsersText }}
- title: Role used
content: ${{ steps['assign-groups'].output.roleId }}
3. Export to Git (existing exporter config)
Uses stackGen:exportToGit with ProjectSelect, AppStackSelect, and the Exporter* fields.
If no config exists and configId is blank, the action bootstraps from the project default git template.
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: stackgen-git-export-exporter
title: Push IaC via StackGen exporter
description: >
Export an existing AppStack to Git via stack-exporter. Pick project and AppStack;
topology and exporter appstackId are resolved when omitted.
spec:
owner: user:guest
type: service
parameters:
- title: Stack context
required:
- projectId
- appstackName
properties:
projectId:
type: string
title: Project
ui:field: ProjectSelect
appstackName:
type: string
title: AppStack
ui:field: AppStackSelect
ui:options:
projectId: projectId
existingExporterConfigId:
type: string
title: Existing exporter config
description: >
Optional. Auto-selected when there is only one config. Leave blank to
create from the project default if none exist.
ui:field: ExporterGitConfigSelect
ui:options:
projectId: projectId
appstackName: appstackName
- title: Git export options
properties:
baseBranch:
type: string
title: Base branch
description: Prefills from the selected config target branch.
ui:field: ExporterBaseBranch
ui:options:
projectId: projectId
configId: existingExporterConfigId
pushBranch:
type: object
title: Push branch
description: >
Prefills from export history. Leaving the suggestion unchanged
reuses that branch (useSameBranch).
ui:field: ExporterPushBranch
ui:options:
projectId: projectId
appstackName: appstackName
properties:
branch:
type: string
useSameBranch:
type: boolean
createPr:
type: boolean
title: Create pull request
description: >
When on, opens a PR against the base branch. When off, commits
directly without a pull request.
default: true
- title: Pull request
required:
- prTitle
- commitMessage
properties:
prTitle:
type: string
title: Pull request title
default: StackGen IaC export
commitMessage:
type: string
title: Commit message
default: Export IaC from StackGen
steps:
- id: exportToGit
name: Export AppStack to Git
action: stackGen:exportToGit
input:
projectId: ${{ parameters.projectId }}
appstackName: ${{ parameters.appstackName }}
configId: ${{ parameters.existingExporterConfigId }}
baseBranch: ${{ parameters.baseBranch }}
pushBranch: ${{ parameters.pushBranch.branch }}
useSameBranch: ${{ parameters.pushBranch.useSameBranch }}
createPr: ${{ parameters.createPr }}
overrides:
- key: pr_title
value: ${{ parameters.prTitle }}
- key: commit_msg
value: ${{ parameters.commitMessage }}
output:
links:
- title: View pull request
url: ${{ steps.exportToGit.output.pullRequestUrl }}
text:
- title: Export result
content: ${{ steps.exportToGit.output.notes }}
4. Export to Git (bootstrap gitConfig)
Same action, but creates an appstack-scoped git exporter config when you pass gitConfig
(SCM type, repo URL, vault credential). configId still wins when set.
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: stackgen-git-export-with-gitconfig
title: Push IaC via StackGen exporter (with gitConfig)
description: >
Export an AppStack to Git. Use an existing exporter config, or create one
via gitConfig fields (VaultSecretSelect for SCM credentials).
spec:
owner: user:guest
type: service
parameters:
- title: Stack context
required:
- projectId
- appstackName
- exporterConfigMode
properties:
projectId:
type: string
title: Project
ui:field: ProjectSelect
appstackName:
type: string
title: AppStack
ui:field: AppStackSelect
ui:options:
projectId: projectId
exporterConfigMode:
type: string
title: Git exporter config
enum:
- existing
- create
enumNames:
- Use existing
- Create new
default: existing
dependencies:
exporterConfigMode:
oneOf:
- properties:
exporterConfigMode:
const: existing
existingExporterConfigId:
type: string
title: Existing exporter config
ui:field: ExporterGitConfigSelect
ui:options:
projectId: projectId
appstackName: appstackName
- required:
- scmType
- repoUrl
- vaultReference
properties:
exporterConfigMode:
const: create
gitConfigName:
type: string
title: Config name
default: default-git-config
scmType:
type: string
title: SCM type
enum:
- GITHUB
- GITLAB
- BITBUCKET
- AZUREDEV
default: GITHUB
repoUrl:
type: string
title: Repository URL
description: e.g. https://github.com/org/repo.git
targetBranch:
type: string
title: Default target branch
default: main
path:
type: string
title: Path in repository
default: /
vaultReference:
type: string
title: SCM credential (vault secret)
ui:field: VaultSecretSelect
ui:options:
projectId: projectId
category: scm
- title: Git export options
properties:
baseBranch:
type: string
title: Base branch
ui:field: ExporterBaseBranch
ui:options:
projectId: projectId
configId: existingExporterConfigId
pushBranch:
type: object
title: Push branch
ui:field: ExporterPushBranch
ui:options:
projectId: projectId
appstackName: appstackName
properties:
branch:
type: string
useSameBranch:
type: boolean
createPr:
type: boolean
title: Create pull request
default: true
- title: Pull request
required:
- prTitle
- commitMessage
properties:
prTitle:
type: string
title: Pull request title
default: StackGen IaC export
commitMessage:
type: string
title: Commit message
default: Export IaC from StackGen
steps:
- id: exportToGit
name: Export AppStack to Git
action: stackGen:exportToGit
input:
projectId: ${{ parameters.projectId }}
appstackName: ${{ parameters.appstackName }}
configId: ${{ parameters.existingExporterConfigId }}
gitConfig:
name: ${{ parameters.gitConfigName }}
type: git
parameters:
scmType: ${{ parameters.scmType }}
repoUrl: ${{ parameters.repoUrl }}
targetBranch: ${{ parameters.targetBranch }}
path: ${{ parameters.path }}
vaultReference: ${{ parameters.vaultReference }}
default: true
baseBranch: ${{ parameters.baseBranch }}
pushBranch: ${{ parameters.pushBranch.branch }}
useSameBranch: ${{ parameters.pushBranch.useSameBranch }}
createPr: ${{ parameters.createPr }}
overrides:
- key: pr_title
value: ${{ parameters.prTitle }}
- key: commit_msg
value: ${{ parameters.commitMessage }}
output:
links:
- title: View pull request
url: ${{ steps.exportToGit.output.pullRequestUrl }}
text:
- title: Export result
content: ${{ steps.exportToGit.output.notes }}
5. Advanced project (git + env templates on create)
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: stackgen-project-advanced
title: Create Project (Advanced)
description: Create a project with Git integration, environments, variables, and overrides
spec:
owner: user:guest
type: service
parameters:
- title: Project Information
required:
- projectName
- repoUrl
properties:
projectName:
title: Project Name
type: string
ui:autofocus: true
repoUrl:
title: Repository URL
type: string
default: https://github.com/org/repo.git
steps:
- id: create-project
name: Create StackGen Project
action: stackGen:createProject
input:
project:
name: ${{ parameters.projectName }}
description: Project created via Backstage with Advanced Config
gitConfig:
name: default-git-config
type: git
parameters:
scmType: GITHUB
repoUrl: ${{ parameters.repoUrl }}
targetBranch: main
default: true
environmentConfig:
name: default-env-config
environmentTemplates:
- name: dev
color: "#1cbb9b"
- name: production
color: "#FF0000"
variables:
- name: region
type: string
defaultValueJson: '"us-east-1"'
description: AWS region for deployment
variableOverrides:
- variableName: region
environmentTemplateName: production
valueJson: '"us-west-2"'
output:
links:
- title: View Created Project
url: ${{ steps['create-project'].output.projectURL }}
6. Set environment variable values on an existing AppStack
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: stackgen-appstack-configure-environment
title: Configure AppStack Environment
description: Set Terraform variable values on an existing AppStack environment
tags:
- stackgen
- environment
- variables
spec:
owner: user:guest
type: service
parameters:
- title: Target AppStack
required:
- projectId
- appstackName
- environmentId
properties:
projectId:
title: Project
type: string
ui:field: ProjectSelect
appstackName:
title: AppStack
type: string
ui:field: AppStackSelect
ui:options:
projectId: projectId
environmentId:
title: Environment
type: string
description: Existing environment to configure
ui:field: EnvironmentSelect
ui:options:
projectId: projectId
appstackName: appstackName
- title: Variable Values
properties:
variableValues:
title: Variable Values
type: array
description: Pick TF variables and set values for the selected environment
ui:field: VariableSelect
ui:options:
projectId: projectId
appstackName: appstackName
items:
type: object
properties:
name:
type: string
value:
type: string
steps:
- id: setEnvVars
name: Apply Variable Values to Environment
action: stackGen:setEnvironmentVariableValues
input:
projectId: ${{ parameters.projectId }}
appstackName: ${{ parameters.appstackName }}
environmentId: ${{ parameters.environmentId }}
variableValues: ${{ parameters.variableValues }}
output:
text:
- title: Environment ID
content: ${{ steps.setEnvVars.output.environmentId }}
- title: Updated variables
content: ${{ steps.setEnvVars.output.updatedVariablesText }}