Configuring the GitOps Manifest Updater Frontend Plugin#
This guide covers the configuration options available for the GitOps Manifest Updater frontend plugin.
New Frontend System Configuration (Alpha)#
When using the new frontend system through the /alpha
export, the plugin is configured automatically with sensible defaults. The plugin will be automatically integrated into the appropriate locations without requiring manual route configuration.
Example Configuration for GitHub based SCM#
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: update-kubernetes-manifest
title: Update Kubernetes Manifest
labels:
target: component
description: A template to update a claim manifest in Git based on the registered OpenAPI Schema of the XRD
spec:
owner: user:guest
type: service
parameters:
- title: Entity Selection
required:
- entity
properties:
entity:
title: Entity
type: string
description: Select the entity to update
ui:field: EntityPicker
ui:options:
catalogFilter:
- kind: Component
sourceFileUrl:
title: Source File URL
type: string
description: Override the source file URL (optional - only needed if entity doesn't have terasky.backstage.io/source-file-url annotation)
- title: GitOps Manifest Updater
required:
- gitOpsManifestUpdater
properties:
gitOpsManifestUpdater:
title: GitOps Manifest Updater
type: object
ui:field: GitOpsManifestUpdater
steps:
- id: get-entity
name: Get Entity
action: catalog:fetch
input:
entityRef: ${{ parameters.entity }}
- id: get-annotation-url
name: Get Annotation URL
action: roadiehq:utils:jsonata
input:
data:
annotations: ${{ steps['get-entity'].output.entity.metadata.annotations }}
expression: |
annotations."terasky.backstage.io/source-file-url"
- id: resolve-url
name: Resolve URL
action: roadiehq:utils:jsonata
input:
data:
sourceFileUrl: ${{ parameters.sourceFileUrl }}
annotationUrl: ${{ steps['get-annotation-url'].output.result }}
expression: |
$exists(sourceFileUrl) ? sourceFileUrl : annotationUrl
- id: validate-url
name: Validate URL
action: roadiehq:utils:jsonata
input:
data: ${{ steps['resolve-url'].output.result }}
expression: |
$string($) ? $ : $error("No source URL provided. Please either add the terasky.backstage.io/source-file-url annotation to the entity or provide a sourceFileUrl parameter")
- id: get-filepath
name: Get File Path
action: roadiehq:utils:jsonata
input:
data: ${{ steps['validate-url'].output.result }}
expression: |
$join($filter($split($, "/"), function($v, $i) { $i >= 7}), "/")
- id: fetch-base
name: Fetch Current Manifest
action: fetch:plain:file
input:
url: ${{ steps['validate-url'].output.result }}
targetPath: ${{ steps['get-filepath'].output.result }}
- id: serialize-patch
name: Evaluate Changes
action: roadiehq:utils:serialize:yaml
input:
data:
spec: ${{ parameters.gitOpsManifestUpdater }}
- id: merge-patch
name: Merge Changes
action: roadiehq:utils:merge
input:
path: ${{ steps['get-filepath'].output.result }}
content: ${{ steps['serialize-patch'].output.serialized }}
- id: read-file
name: Read File
action: roadiehq:utils:fs:parse
input:
path: ${{ steps['get-filepath'].output.result }}
- id: parse-url
name: Parse URL for PR
action: roadiehq:utils:jsonata
input:
data: ${{ steps['validate-url'].output.result }}
expression: |
{
"owner": $split($, "/")[3],
"repo": $split($, "/")[4],
"branch": $split($, "/")[6]
}
- id: format-branch-name
name: Format Branch Name
action: roadiehq:utils:jsonata
input:
data: ${{ steps['validate-url'].output.result }}
expression: |
"backstage-sourced-update-" & $join($filter($split($, "/"), function($v, $i) { $i >= 7}), "-")
- id: create-pull-request
name: create-pull-request
action: publish:github:pull-request
input:
repoUrl: ${{ 'github.com?owner=' + steps['parse-url'].output.result.owner + '&repo=' + steps['parse-url'].output.result.repo }}
branchName: ${{ steps['format-branch-name'].output.result }}
title: Updating Kubernetes YAML for ${{ steps['get-entity'].output.entity.metadata.name }}
description: Updating Kubernetes YAML for ${{ steps['get-entity'].output.entity.metadata.name }}
targetBranchName: ${{ steps['parse-url'].output.result.branch }}
output:
links:
- title: Pull Request
url: ${{ steps['create-pull-request'].output.remoteUrl }}
- title: Download YAML Manifest
url: data:application/yaml;charset=utf-8,${{ steps['read-file'].output.content }}
Example Configuration for Gitlab based SCM#
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: update-kubernetes-manifest-gitlab
title: Update Kubernetes Manifest From Gitlab
labels:
target: component
description: A template to update a claim manifest in Git based on the registered OpenAPI Schema of the XRD
spec:
owner: user:guest
type: service
parameters:
- title: Entity Selection
required:
- entity
properties:
entity:
title: Entity
type: string
description: Select the entity to update
ui:field: EntityPicker
ui:options:
catalogFilter:
- kind: Component
sourceFileUrl:
title: Source File URL
type: string
description: Override the source file URL (optional - only needed if entity doesn't have terasky.backstage.io/source-file-url annotation)
- title: GitOps Manifest Updater
required:
- gitOpsManifestUpdater
properties:
gitOpsManifestUpdater:
title: GitOps Manifest Updater
type: object
ui:field: GitOpsManifestUpdater
steps:
- id: get-entity
name: Get Entity
action: catalog:fetch
input:
entityRef: ${{ parameters.entity }}
- id: get-annotation-url
name: Get Annotation URL
action: roadiehq:utils:jsonata
input:
data:
annotations: ${{ steps['get-entity'].output.entity.metadata.annotations }}
expression: |
annotations."terasky.backstage.io/source-file-url"
- id: resolve-url
name: Resolve URL
action: roadiehq:utils:jsonata
input:
data:
sourceFileUrl: ${{ parameters.sourceFileUrl }}
annotationUrl: ${{ steps['get-annotation-url'].output.result }}
expression: |
$exists(sourceFileUrl) ? sourceFileUrl : annotationUrl
- id: validate-url
name: Validate URL
action: roadiehq:utils:jsonata
input:
data: ${{ steps['resolve-url'].output.result }}
expression: |
$string($) ? $ : $error("No source URL provided. Please either add the terasky.backstage.io/source-file-url annotation to the entity or provide a sourceFileUrl parameter")
- id: get-filepath
name: Get File Path
action: roadiehq:utils:jsonata
input:
data: ${{ steps['validate-url'].output.result }}
expression: |
$join($filter($split($, "/"), function($v, $i) { $i >= 8}), "/")
- id: fetch-base
name: Fetch Current Manifest
action: fetch:plain:file
input:
url: ${{ steps['validate-url'].output.result }}
targetPath: ${{ steps['get-filepath'].output.result }}
- id: serialize-patch
name: Evaluate Changes
action: roadiehq:utils:serialize:yaml
input:
data:
spec: ${{ parameters.gitOpsManifestUpdater }}
- id: merge-patch
name: Merge Changes
action: roadiehq:utils:merge
input:
path: ${{ steps['get-filepath'].output.result }}
content: ${{ steps['serialize-patch'].output.serialized }}
- id: read-file
name: Read File
action: roadiehq:utils:fs:parse
input:
path: ${{ steps['get-filepath'].output.result }}
- id: parse-url
name: Parse URL for PR
action: roadiehq:utils:jsonata
input:
data: ${{ steps['validate-url'].output.result }}
expression: |
{
"owner": $split($, "/")[3],
"repo": $split($, "/")[4],
"branch": $split($, "/")[7]
}
- id: format-branch-name
name: Format Branch Name
action: roadiehq:utils:jsonata
input:
data: ${{ steps['validate-url'].output.result }}
expression: |
"backstage-sourced-update-" & $join($filter($split($, "/"), function($v, $i) { $i >= 8}), "-")
- id: create-merge-request
name: create-merge-request
action: publish:gitlab:merge-request
input:
repoUrl: ${{ 'gitlab.com?owner=' + steps['parse-url'].output.result.owner + '&repo=' + steps['parse-url'].output.result.repo }}
branchName: ${{ steps['format-branch-name'].output.result }}
title: Updating Kubernetes YAML for ${{ steps['get-entity'].output.entity.metadata.name }}
description: Updating Kubernetes YAML for ${{ steps['get-entity'].output.entity.metadata.name }}
targetBranchName: ${{ steps['parse-url'].output.result.branch }}
output:
links:
- title: Merge Request
url: ${{ steps['create-merge-request'].output.mergeRequestUrl }}
- title: Download YAML Manifest
url: data:application/yaml;charset=utf-8,${{ steps['read-file'].output.content }}
Component Configuration#
Integration Examples#
Basic Integration#
Advanced Integration#
<ScaffolderFieldExtensions>
<GitOpsManifestUpdaterExtension
defaultBranch="develop"
defaultPath="k8s/"
schemaValidator={customValidator}
pullRequestCreator={customPRCreator}
/>
</ScaffolderFieldExtensions>
Template Examples#
Kubernetes Resource Update#
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: update-kubernetes-manifest
title: Update Kubernetes Manifest
labels:
target: component
description: A template to update a claim manifest in Git based on the registered OpenAPI Schema of the XRD
spec:
owner: user:guest
type: service
parameters:
- title: Entity Selection
required:
- entity
properties:
entity:
title: Entity
type: string
description: Select the entity to update
ui:field: EntityPicker
ui:options:
catalogFilter:
- kind: Component
sourceFileUrl:
title: Source File URL
type: string
description: Override the source file URL (optional - only needed if entity doesn't have terasky.backstage.io/source-file-url annotation)
- title: GitOps Manifest Updater
required:
- gitOpsManifestUpdater
properties:
gitOpsManifestUpdater:
title: GitOps Manifest Updater
type: object
ui:field: GitOpsManifestUpdater
steps:
- id: get-entity
name: Get Entity
action: catalog:fetch
input:
entityRef: ${{ parameters.entity }}
- id: get-annotation-url
name: Get Annotation URL
action: roadiehq:utils:jsonata
input:
data:
annotations: ${{ steps['get-entity'].output.entity.metadata.annotations }}
expression: |
annotations."terasky.backstage.io/source-file-url"
- id: resolve-url
name: Resolve URL
action: roadiehq:utils:jsonata
input:
data:
sourceFileUrl: ${{ parameters.sourceFileUrl }}
annotationUrl: ${{ steps['get-annotation-url'].output.result }}
expression: |
$exists(sourceFileUrl) ? sourceFileUrl : annotationUrl
- id: validate-url
name: Validate URL
action: roadiehq:utils:jsonata
input:
data: ${{ steps['resolve-url'].output.result }}
expression: |
$string($) ? $ : $error("No source URL provided. Please either add the terasky.backstage.io/source-file-url annotation to the entity or provide a sourceFileUrl parameter")
- id: get-filepath
name: Get File Path
action: roadiehq:utils:jsonata
input:
data: ${{ steps['validate-url'].output.result }}
expression: |
$join($filter($split($, "/"), function($v, $i) { $i >= 7}), "/")
- id: fetch-base
name: Fetch Current Manifest
action: fetch:plain:file
input:
url: ${{ steps['validate-url'].output.result }}
targetPath: ${{ steps['get-filepath'].output.result }}
- id: serialize-patch
name: Evaluate Changes
action: roadiehq:utils:serialize:yaml
input:
data:
spec: ${{ parameters.gitOpsManifestUpdater }}
- id: merge-patch
name: Merge Changes
action: roadiehq:utils:merge
input:
path: ${{ steps['get-filepath'].output.result }}
content: ${{ steps['serialize-patch'].output.serialized }}
- id: read-file
name: Read File
action: roadiehq:utils:fs:parse
input:
path: ${{ steps['get-filepath'].output.result }}
- id: parse-url
name: Parse URL for PR
action: roadiehq:utils:jsonata
input:
data: ${{ steps['validate-url'].output.result }}
expression: |
{
"owner": $split($, "/")[3],
"repo": $split($, "/")[4],
"branch": $split($, "/")[6]
}
- id: format-branch-name
name: Format Branch Name
action: roadiehq:utils:jsonata
input:
data: ${{ steps['validate-url'].output.result }}
expression: |
"backstage-sourced-update-" & $join($filter($split($, "/"), function($v, $i) { $i >= 7}), "-")
- id: create-pull-request
name: create-pull-request
action: publish:github:pull-request
input:
repoUrl: ${{ 'github.com?owner=' + steps['parse-url'].output.result.owner + '&repo=' + steps['parse-url'].output.result.repo }}
branchName: ${{ steps['format-branch-name'].output.result }}
title: Updating Kubernetes YAML for ${{ steps['get-entity'].output.entity.metadata.name }}
description: Updating Kubernetes YAML for ${{ steps['get-entity'].output.entity.metadata.name }}
targetBranchName: ${{ steps['parse-url'].output.result.branch }}
output:
links:
- title: Pull Request
url: ${{ steps['create-pull-request'].output.remoteUrl }}
- title: Download YAML Manifest
url: data:application/yaml;charset=utf-8,${{ steps['read-file'].output.content }}
Best Practices#
-
Template Design
- Use clear, descriptive titles
- Provide helpful descriptions
- Set appropriate default values
- Include validation rules
-
Repository Structure
- Organize manifests logically
- Use consistent file paths
- Follow GitOps practices
- Maintain clear documentation
-
Pull Requests
- Use descriptive titles
- Provide detailed descriptions
- Apply appropriate labels
- Follow team conventions
For installation instructions, refer to the Installation Guide.