Skip to main content
22 min read

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.

PackageRoleLatest (latest tag)
@stackgenhq/backstage-plugin-stackgenFrontend plugin. Scaffolder field extensions0.2.3
@stackgenhq/backstage-plugin-stackgen-backendBackend plugin. Scaffolder actions, UI proxies, templates0.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.

PreferDeprecated alias (still accepted)
ui:field: ProjectSelectTeamSelect
ui:options.projectIdteamId, orgId
Action input projectIdteamId (and orgId where noted)
createProject output projectIdteamId

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:

  1. Register actions via scaffolder.addActions(...).
  2. backend.add(import('@stackgenhq/backstage-plugin-stackgen-backend')) for the main plugin.
  3. 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:fieldValue shapeui:options
ProjectSelectstring (project Id)none
TeamSelect (deprecated)same as ProjectSelectnone
AppStackSelectstring (appstack name)projectId (teamId / orgId aliases)
TemplateAppStackSelectstring (template Id)none
VaultSecretSelectsecret identifier stringprojectId (teamId / orgId), category, subcategory
UserGroupSelect{ type: 'user' or 'group', id, label? }[]groupFilterRegex, userFilterRegex, lockCurrentUser
RoleSelectstring (role Id)none
EnvironmentSelectstring (environment profile Id)projectId (teamId / orgId), appstackName or topologyId
VariableSelect{ name, value }[]projectId (teamId / orgId), appstackName or topologyId
ExporterGitConfigSelectstring (config id)projectId (teamId / orgId), appstackName
ExporterBaseBranchstringprojectId (teamId / orgId), configId
ExporterPushBranch{ branch?, useSameBranch? }projectId (teamId / orgId), appstackName

How ui:options resolve​

Resolution styleFieldsBehavior
Form field or IdAppStackSelect, VaultSecretSelect, UserGroupSelect, EnvironmentSelect, VariableSelectOption may name another form field, or be a literal Id. Waits until a form field has a value.
Form field name onlyExporterGitConfigSelect, ExporterBaseBranch, ExporterPushBranchappstackName / configId must name another parameter (no literal). projectId still accepts form field or UUID.
No optionsProjectSelect, 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​

OptionWhat 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​

OptionWhat it does
projectId (teamId / orgId)Form field or Id. Omit → enterprise (shared) secrets, no project filter.
categoryLiteral filter string
subcategoryLiteral filter string

UserGroupSelect​

OptionWhat it does
lockCurrentUserBoolean (default true). When true, forces token user into the selection, and prevents removing them.
userFilterRegexKeeps users whose email (fallback name) match. Invalid regex disables the field with an error.
groupFilterRegexKeeps groups whose name match. Invalid regex disables the field with an error.

RoleSelect​

No ui:options. Static Admin / DevOps / Developer plus freeSolo custom Id.

LabelId
Admin00000000-0000-0000-0000-000000000002
DevOps00000000-0000-0000-0000-000000000003
Developer00000000-0000-0000-0000-000000000004

EnvironmentSelect​

Single-select environment profile picker. Returns the selected environment profile Id (typically passed to stackGen:setEnvironmentVariableValues as environmentId).

OptionWhat it does
projectId (teamId / orgId)Form field or Id. Scopes which profiles to load.
appstackNameForm field or Id. Loads profiles for that AppStack (usually a form field name).
topologyIdForm 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.

OptionWhat it does
topologyIdForm field or Id. Loads TF variables for that topology.
appstackNameForm 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​

OptionWhat it does
projectId (teamId / orgId)Form field or Id. Project scope when listing configs. Required.
appstackNameForm 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​

OptionWhat it does
projectId (teamId / orgId)Form field or Id. Project scope when loading the selected exporter config.
configIdForm field name only. Loads that config and prefills from parameters.target_branch / targetBranch.

ExporterPushBranch​

OptionWhat it does
projectId (teamId / orgId)Form field or Id. Project scope for export-history suggestion.
appstackNameForm 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 idFactory exportPurpose
stackGen:createProjectcreateProjectActionCreate project/git/env config
stackGen:createAppStackcreateAppStackActionCreate AppStack
stackGen:assignProjectMembersassignProjectMembersActionAssign users/groups + role
stackGen:setStateBackendsetStateBackendActionCreate/update env profile + state backend
stackGen:setEnvironmentVariableValuessetEnvironmentVariableValuesActionSet TF variable values on an existing env
stackGen:downloadIaCdownloadIaCActionDownload IaC ZIP into workspace
stackGen:exportToGitexportAppStackToGitActionExport via stackgen-exporter

stackGen:createProject​

Creates a StackGen project with optional git and environment configuration. Idempotent on name conflict

Inputs (project)

FieldTypeRequiredDescription
project.namestringyesProject name
project.descriptionstringyesDescription
project.gitConfigobjectnoGit integration template
project.gitConfig.namestringnoConfig name
project.gitConfig.typestringnoe.g. git
project.gitConfig.parameters.scmTypeenumnoGITHUB
project.gitConfig.parameters.repoUrlstringnoRepo URL
project.gitConfig.parameters.targetBranchstringnoBranch
project.gitConfig.parameters.pathstringnoPath in repo
project.gitConfig.vaultReferencestringnoVault secret ref for SCM creds
project.gitConfig.defaultbooleannoMark as default
project.environmentConfigobjectnoEnv templates + variables
project.environmentConfig.namestringnoConfig name
project.environmentConfig.environmentTemplates[]objectno{ name, color, stateBackendTemplate? }
project.environmentConfig.variables[]objectno{ name, type, defaultValueJson, description }
project.environmentConfig.variableOverrides[]objectno{ variableName, environmentTemplateName, valueJson }
stateBackendTemplate.typeenumnoS3

Outputs

FieldTypeDescription
projectIdstringProject id
projectNamestringName
teamIdstringDeprecated alias of projectId
alreadyExistedbooleanTrue if project already exists
projectURLstringProject 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)

FieldTypeRequiredDescription
appstack.name or appstackNamestringone requiredAppStack name
appstack.projectIdstringyesDestination project Id (teamId deprecated alias)
appstack.cloudProviderstringif no templatee.g. aws, gcp, azure
appstack.templateAppstackIdIdnoClone from template AppStack
appstack.resources[]arraydefault []Resource objects; use [] for a blank AppStack

Resource object (simplified; full schema is on Installed actions in Backstage)

FieldNotes
resourceTypeRequired
resourcePackIdResource pack id
templateIdModules Id

Outputs

FieldTypeDescription
appstackIdstringAppStack id
appstackNamestringName
appStackURLstringStackGen 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

FieldTypeRequiredDescription
projectIdstringyesUse createProject → projectId
membersarrayno (default [])UserGroupSelect output
roleIdstringnoRole Id; defaults to Developer

Outputs

FieldTypeDescription
assignedUsers / assignedGroupsnumberCounts
assignedUsersText / assignedGroupsTextstringHelp text with users/groups added
roleIdstringRole 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

FieldTypeRequiredDescription
projectIdstringyesPreferred (teamId deprecated alias)
appstackNamestringyes
environmentNamestringyes
colorstringnodefault #000000
variables[]objectno{ name, type?, defaultValueJson?, description? }
variableValues[]{ name, value }noname/value pairs
stateBackend.typeenumyesS3
stateBackend.configRecord<string,string>yesBackend-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

FieldTypeRequiredDescription
projectIdstringyesPreferred (teamId deprecated alias)
environmentIdstringyesExisting environment profile Id
appstackNamestringyes (or topologyId)Resolve topology by AppStack name
topologyIdstringyes (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

FieldTypeDescription
updatedCountnumberHow many variables were written
updatedVariablesTextstringHuman-readable name = value lines
environmentIdstringEnvironment profile Id
topologyIdstringResolved 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

FieldTypeRequired
projectIdstringyes (teamId deprecated alias)
appstackNamestringyes
extractedIaCPathstringno (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

FieldTypeRequiredDescription
appstackNamestringyes
projectIdstringyesPreferred (teamId deprecated alias)
appstackIdstringnoResolved if omitted
configIdstringnoExisting exporter config (wins over gitConfig)
gitConfigobjectnoBootstrap if no config; needs parameters.scmType, repoUrl, vaultReference
baseBranchstringno→ target_branch
pushBranchstringno→ branch_format
useSameBranchbooleannoFrom ExporterPushBranch when suggestion kept
createPrbooleannofalse = commit only
overrides[]{ key, value }noe.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 }}