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.
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 {
TeamSelectFieldExtension,
AppStackNameFieldExtension,
TemplateAppStackSelectFieldExtension,
VaultSecretSelectFieldExtension,
ExporterGitConfigSelectFieldExtension,
ExporterBaseBranchFieldExtension,
ExporterPushBranchFieldExtension,
UserGroupSelectFieldExtension,
RoleSelectFieldExtension,
stackGenPlugin,
} from '@stackgenhq/backstage-plugin-stackgen';
// createApp({ plugins: [stackGenPlugin], ... })
<Route path="/create" element={<ScaffolderPage />}>
<ScaffolderFieldExtensions>
<TeamSelectFieldExtension />
<AppStackNameFieldExtension />
<TemplateAppStackSelectFieldExtension />
<VaultSecretSelectFieldExtension />
<ExporterGitConfigSelectFieldExtension />
<ExporterBaseBranchFieldExtension />
<ExporterPushBranchFieldExtension />
<UserGroupSelectFieldExtension />
<RoleSelectFieldExtension />
</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,
assignProjectMembersAction,
exportAppStackToGitAction,
stackgenUiProxiesModule,
} from '@stackgenhq/backstage-plugin-stackgen-backend';
scaffolder.addActions(
createProjectAction(config, logger),
createAppStackAction(config, logger),
downloadIaCAction(config, logger),
setStateBackendAction(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 |
|---|---|---|
TeamSelect | string (team/project Id) | none |
AppStackSelect | string (appstack name) | teamId |
TemplateAppStackSelect | string (template Id) | none |
VaultSecretSelect | secret identifier string | orgId / teamId, category, subcategory |
UserGroupSelect | { type: 'user' or 'group', id, label? }[] | groupFilterRegex, userFilterRegex, lockCurrentUser |
RoleSelect | string (role Id) | none |
ExporterGitConfigSelect | string (config id) | teamId / orgId, appstackName |
ExporterBaseBranch | string | teamId / orgId, configId |
ExporterPushBranch | { branch?, useSameBranch? } | teamId / orgId, appstackName |
How ui:options resolve
| Resolution style | Fields | Behavior |
|---|---|---|
| Form field or Id | VaultSecretSelect, UserGroupSelect | Option may name another form field, or be a literal Id. Waits until a form field has a value. |
| Form field name only | AppStackSelect, ExporterGitConfigSelect, ExporterBaseBranch, ExporterPushBranch | Option must be the name of another parameter; literal Ids are not supported. |
| No options | TeamSelect, TemplateAppStackSelect, RoleSelect | — |
orgId and teamId are aliases where both are read: if both are set, orgId is preferred.
What each field does with each option
TeamSelect
No ui:options. Loads allowed teams and returns the selected team Id.
AppStackSelect
| Option | What it does |
|---|---|
teamId | Form field name. When that field has a value, loads AppStacks for that team. When missing/empty, loads all AppStacks. |
TemplateAppStackSelect
No ui:options. Loads template AppStacks.
VaultSecretSelect
| Option | What it does |
|---|---|
orgId / teamId | Form field name or Id. Omit both → enterprise (shared) secrets, no org filter. |
category | Filter by category |
subcategory | Filter by subcategory |
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 |
ExporterGitConfigSelect
| Option | What it does |
|---|---|
teamId / orgId | Form field name only. Resolved value sent as orgId to list configs. Required. |
appstackName | Form field name only. Resolved value sent as appstackName query param. Required. |
Waits until both team and appstack deps resolve. Auto-selects when exactly one config exists.
ExporterBaseBranch
| Option | What it does |
|---|---|
teamId / orgId | Form field name only → orgId 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 |
|---|---|
teamId / orgId | Form field name only → orgId for export-history suggestion. |
appstackName | Form field name only → appstackName for history lookup. Prefills branch from history |
Example parameter blocks
teamId:
title: Team / Project
type: string
ui:field: TeamSelect
appstackName:
title: AppStack
type: string
ui:field: AppStackSelect
ui:options:
teamId: teamId
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"
vaultSecret:
title: Vault secret
type: string
ui:field: VaultSecretSelect
ui:options:
teamId: teamId
category: scm
subcategory: credentials
existingExporterConfigId:
type: string
ui:field: ExporterGitConfigSelect
ui:options:
teamId: teamId
appstackName: appstackName
baseBranch:
type: string
ui:field: ExporterBaseBranch
ui:options:
teamId: teamId
configId: existingExporterConfigId
pushBranch:
type: object
ui:field: ExporterPushBranch
ui:options:
teamId: teamId
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: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 | Project Id |
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.teamId | string | yes | Destination team/project |
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 |
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 |
- id: create-appstack
action: stackGen:createAppStack
input:
appstack:
name: ${{ parameters.appstackName }}
teamId: ${{ steps['create-project'].output.teamId }}
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 → teamId |
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.teamId }}
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 |
|---|---|---|---|
teamId | string | yes | |
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:
teamId: ${{ steps.createProject.output.teamId }}
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:downloadIaC
Downloads IaC ZIP for a topology into the scaffolder workspace.
Inputs
| Field | Type | Required |
|---|---|---|
teamId | string | yes |
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 }}
teamId: ${{ parameters.teamId }}
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 | |
teamId | string | yes | |
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:
teamId: ${{ parameters.teamId }}
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 (team) 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 }}
teamId: ${{ steps['create-project'].output.teamId }}
templateAppstackId: ${{ parameters.templateAppstackId }}
cloudProvider: ${{ parameters.cloudProvider }}
resources: []
- id: assign-groups
name: Assign Groups to Project
action: stackGen:assignProjectMembers
input:
projectId: ${{ steps['create-project'].output.teamId }}
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 TeamSelect, 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 team and AppStack;
topology and exporter appstackId are resolved when omitted.
spec:
owner: user:guest
type: service
parameters:
- title: Stack context
required:
- teamId
- appstackName
properties:
teamId:
type: string
title: Team / project
ui:field: TeamSelect
appstackName:
type: string
title: AppStack
ui:field: AppStackSelect
ui:options:
teamId: teamId
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:
teamId: teamId
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:
teamId: teamId
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:
teamId: teamId
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:
teamId: ${{ parameters.teamId }}
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:
- teamId
- appstackName
- exporterConfigMode
properties:
teamId:
type: string
title: Team / project
ui:field: TeamSelect
appstackName:
type: string
title: AppStack
ui:field: AppStackSelect
ui:options:
teamId: teamId
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:
teamId: teamId
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:
teamId: teamId
category: scm
- title: Git export options
properties:
baseBranch:
type: string
title: Base branch
ui:field: ExporterBaseBranch
ui:options:
teamId: teamId
configId: existingExporterConfigId
pushBranch:
type: object
title: Push branch
ui:field: ExporterPushBranch
ui:options:
teamId: teamId
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:
teamId: ${{ parameters.teamId }}
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 }}