소프트웨어 템플릿 구성
Backstage 소프트웨어 템플릿은 소스 코드를 만들므로, 여러분의 Backstage 애플리케이션이 저장소 생성을 허용하도록 설정되어야 합니다.
출처: 문서
본문
Backstage 소프트웨어 템플릿은 소스 코드를 만들므로, 여러분의 Backstage 애플리케이션이 저장소 생성을 허용하도록 설정되어야 합니다.
이것은 app-config.yaml에 여러분의 조직에 맞는 소스 코드 저장소에 대한 Backstage 통합을 추가함으로써 이루어집니다.
참고
통합은 이미
app-config.yaml의 일부로 설정되어 있을 수 있습니다.
다음 단계는 여러분의 Backstage 앱에 템플릿을 추가하는 것입니다.
게시 기본값
소프트웨어 템플릿은 publish:github 같은 게시 액션을 정의해 새 저장소를 만들거나 기존 저장소에 풀/머지 요청을 제출할 수 있습니다. app-config.yaml의 scaffolder 구성을 통해 작성자와 커밋 메시지를 구성할 수 있습니다.
scaffolder: defaultAuthor: name: M.C. Hammer # Defaults to `Scaffolder` email: [email protected] # Defaults to `[email protected]` defaultCommitMessage: "U can't touch this" # Defaults to 'Initial commit'
소프트웨어 템플릿에서 생성된 새 저장소를 누가 볼 수 있는지 구성하려면, 소프트웨어 템플릿 안에 repoVisibility 키를 추가하세요.
- id: publish name: Publish action: publish:github input: repoUrl: '{{ parameters.repoUrl }}' repoVisibility: public # or 'internal' or 'private'
기본 환경 (Default Environment)
스캐폴더는 모든 템플릿에 기본 매개변수와 비밀을 제공하는 defaultEnvironment 구성을 지원합니다. 이것은 공통 값을 중앙화함으로써 템플릿 복잡성을 줄이고 보안을 개선합니다.
scaffolder: defaultEnvironment: parameters: region: eu-west-1 organizationName: acme-corp defaultRegistry: registry.acme-corp.com secrets: AWS_ACCESS_KEY: ${AWS_ACCESS_KEY} GITHUB_TOKEN: ${GITHUB_TOKEN} DOCKER_REGISTRY_TOKEN: ${DOCKER_REGISTRY_TOKEN}
기본 매개변수
기본 매개변수는 템플릿에서 ${{ environment.parameters.* }}로 접근할 수 있습니다. 기본 매개변수는 이름 충돌을 피하기 위해 자신만의 컨텍스트에 격리되어 있습니다.
parameters: - title: Fill in some steps required: - organizationName properties: organizationName: title: organizationName type: string description: Unique name of the organization ui:autofocus: true ui:options: rows: 5 steps: - id: deploy name: Deploy Application action: aws:deploy input: region: ${{ environment.parameters.region }} # Resolves to defaultEnvironment.parameters.region organization: ${{ parameters.organizationName }} # Resolves to frontend input value otherOrganization: ${{ environment.parameters.organizationName }} # Resolves to defaultEnvironment.parameters.organizationName
비밀 (Secrets)
기본 비밀은 환경 변수에서 해석되며 템플릿 액션에서 ${{ environment.secrets.* }}로 접근할 수 있습니다. 비밀은 액션 실행 중에만 사용할 수 있고, 프론트엔드 폼에서는 사용할 수 없습니다.
- id: deploy name: Deploy with credentials action: aws:deploy input: accessKey: ${{ environment.secrets.AWS_ACCESS_KEY }} # Resolves to defaultEnvironment.secrets.AWS_ACCESS_KEY
보안 참고: 비밀은 로그에서 자동으로 마스킹되며 백엔드 액션에만 사용할 수 있고, 결코 프론트엔드에 노출되지 않습니다.
작업 복구 (Task Recovery)
스캐폴더는 작업자가 재시작되거나 크래시할 때 자동 작업 복구를 지원합니다. 활성화하면 processing 상태였던 작업이 복구되어 중단된 지점부터 재개될 수 있습니다.
scaffolder: taskRecovery: enabled: true staleTimeout: { seconds: 30 } # Optional, defaults to 30 seconds
작업 복구가 활성화되면:
- 오래된 하트비트를 가진
processing상태의 작업은 자동으로open상태로 복구됩니다. - 비밀은 작업이 종료 상태(완료/실패)에 도달할 때까지 보존됩니다.
- 완료된 단계는 재시도 시 건너뛰고, 마지막 미완료 단계부터 재개합니다.
- 단계 출력이 복원되어 이후 단계가 이전 결과에 접근할 수 있습니다.
멱등(idempotent) 액션 사용
작업이 복구되거나 재시도되면 액션이 두 번 이상 실행될 수 있습니다. 이것은 액션이 성공했지만 워크스페이스 직렬화가 실패할 때 발생할 수 있는데, 그 워크스페이스가 저장되기 전까지는 단계가 완료된 것으로 기록되지 않기 때문입니다. 따라서 복구 가능한 템플릿에 사용되는 액션은 멱등이어야 합니다. 이를 달성하려면 커스텀 액션에서 체크포인트를 사용할 수 있습니다.
워크스페이스 직렬화
기본적으로 작업 복구는 작업 워크스페이스(파일시스템)를 영속화하지 않습니다. 작업이 파일로 작업하고 재시작 후에도 워크스페이스가 유지되길 원한다면, 워크스페이스 제공자 모듈을 설치해 별도로 구성해야 합니다.
워크스페이스 직렬화는 기본적으로 활성화되지 않습니다 — workspaceProvider를 설정해 명시적으로 동의해야 합니다.
scaffolder: taskRecovery: enabled: true workspaceProvider: database # or 'gcpBucket' for GCS
사용 가능한 워크스페이스 제공자:
database—@backstage/plugin-scaffolder-backend-module-workspace-database를 통해 워크스페이스를 데이터베이스에 저장합니다. 50MB 제한이 있으며 프로덕션 사용에는 권장되지 않습니다.gcpBucket—@backstage/plugin-scaffolder-backend-module-gcp를 통해 워크스페이스를 GCS 버킷에 저장합니다. 워크로드 신원(workload identity) 구성이 필요합니다. 버킷 이름은scaffolder.taskRecovery.gcsBucket.name으로 구성됩니다.
제공자를 사용하려면 백엔드에 해당 모듈을 설치하세요.
# For database storage (development only)yarn --cwd packages/backend add @backstage/plugin-scaffolder-backend-module-workspace-database# For GCS storage (production)yarn --cwd packages/backend add @backstage/plugin-scaffolder-backend-module-gcp
그런 다음 packages/backend/src/index.ts에서 백엔드에 모듈을 추가하세요.
backend.add( import('@backstage/plugin-scaffolder-backend-module-workspace-database'),);
실험적 플래그에서 마이그레이션
이전의 실험적 구성을 사용하고 있었다면, 새 구성이 그것을 대체합니다.
| Old (Experimental) | New | |
|---|---|---|
scaffolder.EXPERIMENTAL_recoverTasks |
scaffolder.taskRecovery.enabled |
|
scaffolder.EXPERIMENTAL_recoverTasksTimeout |
scaffolder.taskRecovery.staleTimeout |
|
scaffolder.EXPERIMENTAL_workspaceSerialization |
scaffolder.taskRecovery.workspaceProvider |
|
scaffolder.EXPERIMENTAL_workspaceSerializationProvider |
scaffolder.taskRecovery.workspaceProvider |
|
scaffolder.EXPERIMENTAL_workspaceSerializationGcpBucketName |
scaffolder.taskRecovery.gcsBucket.name |
템플릿별 spec.EXPERIMENTAL_recovery 필드는 더 이상 필요하지 않습니다. taskRecovery.enabled가 true로 설정되면 모든 작업이 복구 대상이 됩니다.
이전의 실험적 플래그는 폴백으로 여전히 지원되지만 더 이상 사용되지 않으며, 향후 릴리스에서 제거될 것입니다. EXPERIMENTAL_workspaceSerialization을 사용한다면, 해당 워크스페이스 제공자 모듈을 설치하고 등록하세요. 데이터베이스 제공자 모듈은 처음 시작할 때 기존 데이터베이스 워크스페이스 스냅샷을 기존 작업 저장소에서 마이그레이션합니다. EXPERIMENTAL_workspaceSerializationProvider 설정은 EXPERIMENTAL_workspaceSerialization이 true로 설정된 경우에만 계속 제공자를 선택합니다.
SCM 사용자 자격 증명 요구
지원되는 SCM 액션이 로그인한 사용자가 명시적으로 제공한 자격 증명으로만 작동하도록 요구할 수 있습니다.
scaffolder: requireScmUserCredentials: true
활성화하면, 지원되는 내장 GitHub, GitLab, Bitbucket Cloud, Bitbucket Server, Azure DevOps 변형(mutation) 액션은 사용자가 제공한 토큰을 포함하지 않는 요청을 거부합니다. fetch:plain, fetch:plain:file, fetch:template, fetch:template:file 액션은 GitHub와 GitLab 읽기에 대해 같은 요구 사항을 적용합니다. 사용자 토큰 입력을 받지 않는 커스텀 액션과 SCM 읽기는 영향을 받지 않습니다.
GitLab publish:gitlab 액션의 setUserAsOwner와 ownerUsername 입력은 GitLab 통합의 특권 자격 증명을 요구하므로 이 설정과 함께 사용할 수 없습니다.
그룹화와 필터링으로 ScaffolderPage 커스터마이즈
아래 섹션들은 기존(JSX) 프론트엔드 시스템을 다룹니다. 새 프론트엔드 시스템에 대해서는 아래의 새 프론트엔드 시스템에서 템플릿 페이지 커스터마이즈를 참조하세요.
소프트웨어 템플릿이 몇 개 이상이 되면, 특정 템플릿을 그룹화하고 표면화해 ScaffolderPage를 커스터마이즈하고 싶을 수 있습니다. 아래처럼 groups를 만들어 ScaffolderPage에 전달함으로써 이를 달성할 수 있습니다.
<ScaffolderPage groups={[ { title: 'Recommended', filter: entity => entity?.metadata?.tags?.includes('recommended') ?? false, }, ]}/>
이 코드는 'recommended' 태그가 있는 모든 템플릿을 페이지 상단에, 이 그룹이나 다른 그룹으로 필터링되지 않은 다른 템플릿 위에 함께 그룹화합니다.
title 대신 titleComponent를 전달해 그룹을 더 커스터마이즈할 수도 있습니다. 이는 기본값 ContentHeader에 title을 값으로 설정하는 대신 헤더로 사용할 컴포넌트가 됩니다.
또한 일부 템플릿을 숨기는 옵션도 있습니다. 여러 사용 사례가 있을 수 있습니다.
- 여전히 실험 단계라서 예를 들어 기능 플래그와 결합할 수 있음.
- 템플릿 목록에서 접근할 수 없게 하고, 미리 채워진 데이터로 어떤 액션에서만 열고 싶음.
- 대상 환경에 따라 다른 템플릿 집합을 표시.
<ScaffolderPage templateFilter={entity => entity?.metadata?.tags?.includes('experimental') ?? false }/>
새 프론트엔드 시스템에서 템플릿 페이지 커스터마이즈
새 프론트엔드 시스템에서 템플릿 페이지는 확장으로 구축되므로, 커스터마이즈는 JSX props로 전달되는 대신 구성으로 설정됩니다.
app-config.yaml에서 템플릿 그룹 정의
sub-page:scaffolder/templates 확장은 groups 구성 필드를 받아들입니다. 각 그룹은 title과 filter 조건자(엔티티 조건자 쿼리 사용)를 가집니다.
어떤 그룹에도 일치하지 않는 템플릿은 자동으로 추가되는 "Other Templates" 그룹에 들어갑니다. 그룹이 구성되지 않으면 페이지는 단일 "Templates" 그룹을 렌더링합니다.
app: extensions: - sub-page:scaffolder/templates: config: groups: - title: Recommended Services filter: spec.type: service - title: Documentation filter: spec.type: documentation
조건자 값은 대소문자를 구분하지 않고 일치됩니다. $exists, $in, $contains, $hasPrefix 매처와 논리 연산자 $all, $any, $not도 지원됩니다 — 전체 문법은 entity predicate queries 참조를 보세요.
app-config.yaml에서 템플릿 필터링
sub-page:scaffolder/templates 확장은 templateFilter 구성 필드를 받아들입니다. 그것은 표시되기 전에 모든 템플릿에 적용되는 엔티티 조건자 쿼리입니다. 예를 들어 wip 태그가 있는 템플릿을 제외합니다.
app: extensions: - sub-page:scaffolder/templates: config: templateFilter: $not: metadata.tags: $contains: wip
기본 TemplateCard 교체
@backstage/plugin-scaffolder-react/alpha에서 export된 TemplateCard는 교체 가능한(swappable) 컴포넌트입니다. 앱은 TemplateCard를 대상으로 하는 SwappableComponentBlueprint 확장을 등록해 그것을 교체할 수 있습니다.
// packages/app/src/modules/appModuleScaffolder.tsximport { createFrontendModule } from '@backstage/frontend-plugin-api';import { SwappableComponentBlueprint } from '@backstage/plugin-app-react';import { TemplateCard } from '@backstage/plugin-scaffolder-react/alpha';export const appModuleScaffolder = createFrontendModule({ pluginId: 'app', extensions: [ SwappableComponentBlueprint.make({ name: 'scaffolder-template-card', params: defineParams => defineParams({ component: TemplateCard, loader: () => import('./MyTemplateCard').then(m => m.MyTemplateCard), }), }), ],});
packages/app/src/App.tsx의 createApp의 features 배열에 appModuleScaffolder를 추가해 모듈을 앱에 연결하세요.
MyTemplateCard는 TemplateCardComponentProps({ template, additionalLinks?, onSelected? })를 받습니다. 목록이 템플릿을 onSelected에 바인딩하는 일을 처리하므로, 카드는 스스로 선택하도록 props.onSelected?.()를 호출하기만 하면 됩니다. packages/app/src/modules/BuiTemplateCard.tsx 아래의 예제 앱은 출발점으로 사용할 수 있는 Backstage UI(BUI) 구현을 보여줍니다.