본문 바로가기
WIKI 기술 지식 베이스

소프트웨어 템플릿 구성

원문 보기 위키 갱신

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) 구현을 보여줍니다.

더 알아보기 (Learn more)