1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Red Hat Developer Hub (Backstage) でGolden Pathを作ろう〜Golden Path作成編①〜

Last updated at Posted at 2024-01-18

はじめに

前回の記事では、Golden Pathの作成の事前準備として、Red Hat Developer Hub(RHDH)とGitHubの連携設定を行いました。
ここではいよいよGolden Pathの作成に入っていきます。

実現する環境

今回は以下の環境を構成します。
ScreenShot.png

章項目

今回のテーマは6つの記事で構成されています。

Golden Pathとは

Golden Pathとは、開発のベストプラクティスを実際に動作する環境と共に開発者に提供する仕組みです。
Golden Pathには、実際に動くサンプルアプリとそのソースコード、アプリの開発に必要なCIパイプラインやGitOps環境、そしてGolden Pathによって構築された環境の可観測性や、Golden Pathの価値を正しく理解して活用するためのTechDocsが含まれます。

このGolden PathをPlatform Engineering Teamから提供することで、
開発者に守ってほしいルールを付与しつつ、実際に動くアプリとコードを提供することで、開発者のノウハウ習得をサポートします。

このGolden PathこそBackstageの真価の根幹であり、全てはこのGolden Pathの実行から開発者体験は始まります。
逆にいうと、Platform EngineerはBackstageを準備しただけでは価値はあまりありません。Platform Engineerの提供価値はGolden Pathを提供して初めて発揮されます。

BackstageでGolden Pathを提供する仕組み

Backstageでは、Golden PathをSoftware Templatesとして開発者に公開します。
開発者はBackstage上で該当のSoftware Templatesを選択し、必要なパラメータを入力するだけで開発に必要な各種テンプレートを取得できます。

百聞は一見にしかず、実際にGolden Pathを作って動作を見ていきましょう。

前提条件

以下の記事の実行が完了していること

  1. Red Hat Developer Hub (Backstage) でGolden Pathを作ろう〜環境導入編〜
  2. Red Hat Developer Hub (Backstage) でGolden Pathを作ろう〜認証設定編〜
  3. Red Hat Developer Hub (Backstage) でGolden Pathを作ろう〜GitHub Integration編〜

今回作成するGolden Path

今回は以下のようなGolden Pathを作成します。
ScreenShot.png

Golden Path概要

  • 自分のOrganizationに新しいリポジトリ(AppManifest)を作成して、事前に準備したGitリポジトリのテンプレートSkeleton Repoの中のファイル群を格納する
  • Manifest RepoにあるArgoCDのApplicationリソースをデプロイして、TektonのPileline、およびGitHubからのWebhookを受けてPipelineを実行するためのEventTriggerを作成する

Golden Pathのyamlファイルを作成する

Golden Pathを作成するために、まずはGolden PathのyamlファイルやテンプレートとなるSkeleton Repoを作成します。

Gitリポジトリの作成

あらかじめRHDHに連携したGitHub Organizationにて新しいリポジトリを作成します。作成手順は割愛しますが、公開範囲はpublicにしておきます。
名前はsample-skeletonとしました。
ScreenShot.png

localにCloneしてきます。

git clone <Git Repo URL>
cd sample-skeleton

ファイルとディレクトリを作成します。

mkdir -p app-skeleton \
touch app-skeleton/catalog-info.yaml
touch template.yaml

できたディレクトリ構成はこんな感じ↓

tree
.
├── app-skeleton
│   └── catalog-info.yaml
└── template.yaml

gitにPushしておきます。

git add -A
git commit -m "fix"
git push origin main

それぞれのディレクトリの用途は以下の通りです。

  • app-skeleton: このディレクトリは主にアプリケーションのサンプルコードとDockefileを格納します。開発者がメインで扱うリポジトリのSkeletonになります。

  • template.yamlがGolden Path用のファイルになります。

template.yamlの作成

まずは以下のような内容を追記し、GitHubにPushしましょう。spec.ownerは適宜書き換えて下さい。
長いですが、後ほど中身を説明します。

template.yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: sample-app-template
  title: Create a sample application with a CI pipeline
  description: Provides the sample code and CI pipeline to build and deploy a sample application on OpenShift.
  tags:
    - recommended
spec:
  owner: user:default/<自分のGitHub ID>
  type: service

  parameters:
    - title: Provide information about the new component
      required:
        - app_name
        - owner
        - system
      properties:
        app_name:
          title: Repository Name
          type: string
          default: "sample-app"
        description:
          title: Description
          type: string
          description: Help others understand what this component is for
        owner:
          title: Owner
          type: string
          description: Owner of the component
          ui:field: OwnerPicker
          ui:options:
            catalogFilter:
              kind:
                - Group
        system:
          title: System
          type: string
          ui:field: EntityPicker
          ui:options:
            catalogFilter:
              kind:
                - System

    - title: Provide information about the git to used
      required:
        - git
        - git_host_url
        - git_owner_name
      properties:
        git:
          title: Git of Destination
          type: string
          description: This action will store the application source code on the selected Git server
          enum:
            - github
          enumNames:
            - GitHub
      dependencies:
        git:
          oneOf:
            - properties:
                git:
                  enum:
                    - github
                git_host_url:
                  title: Git Host URL
                  type: string
                  default: github.com
                  description: Specify the GitHub or GitLab host URL(e.g., github.com)
                git_owner_name:
                  title: GitHub Organization Name or User Name
                  type: string
                  description: Specify the GitHub Organization or User to register the repository
  steps:
    - id: app_template
      name: Generating the Application Source Code Component
      action: fetch:template
      input:
        url: ./app-skeleton
        values:
          git: ${{ parameters.git }}
          git_host_url: ${{ parameters.git_host_url }}
          git_owner_name: ${{ parameters.git_owner_name }}
          app_name: ${{ parameters.app_name }}
          owner: ${{ parameters.owner }}
          system: ${{ parameters.system }}
          description: ${{ parameters.description }}
        targetPath: ./tenant-app

    - id: publish-app-to-github
      if: ${{ parameters.git == "github" }}
      name: Publish App Repository to GitHub
      action: publish:github
      input:
        repoUrl: ${{ parameters.git_host_url }}?owner=${{ parameters.git_owner_name }}&repo=${{ parameters.app_name }}-app
        repoVisibility: public
        sourcePath: ./tenant-app
        defaultBranch: develop
        protectDefaultBranch: false

    - id: register-to-github
      if: ${{ parameters.git == "github" }}
      name: Registering the Catalog Info Component to GitHub
      action: catalog:register
      input:
        repoContentsUrl: ${{ steps['publish-app-to-github'].output.repoContentsUrl }}
        catalogInfoPath: "/catalog-info.yaml"
  output:
    links:
      - title: Open the Source Code Repository
        if: ${{ parameters.git == "github" }}
        url: ${{ steps['publish-app-to-github'].output.remoteUrl }}
      - title: Open the Catalog Info Component
        if: ${{ parameters.git == "github" }}
        icon: catalog
        entityRef: ${{ steps['register-to-github'].output.entityRef }}

次にapp-skeleton/catalog-info.yamlにも追記を行います。

app-skeleton/catalog-info.yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: ${{ values.app_name }}
  {%- if values.description %}
  description: ${{ values.description }}
  {%- endif %}
spec:
  type: service
  system: ${{ values.system }}
  lifecycle: production
  owner: ${{ values.owner }}
  git: ${{ values.git }}
  git_host_url: ${{ values.git_host_url }}
  git_owner_name: ${{ values.git_owner_name }}

そしてtemplate.yamlをRHDHが読み込むように、app-config-rhdh.yamlを変更します。

(一部抜粋)app-config-rhdh.yaml
    catalog:
      providers:
        githubOrg:
          default:
            id: production
            orgUrl: 'https://github.com/${GITHUB_ORG_NAME}'
      # ここから
      locations:
      - type: url
        rules:
        - allow:
          - Template
        target: https://github.com/<作成したOrg名>/sample-skeleton/blob/main/template.yaml
      # ここまで

スクリプトを実行して設定を反映させます。

 ./create-secret.sh

Golden Pathの実行

ではRHDHにアクセスして、Create...を選択しましょう。するとTemplatesに先程GitHubにアップしたtemplate.yamlをもとにひとつ追加されていることがわかります。
このTemplateのCHOOSEを選択します。
ScreenShot 173.png

すると入力項目が表示されるので、そこで必要事項を入力します。Repository Nameはデフォルトのままsample-appに、Onwerはプルダウンで表示されたGitHub Team名を選択します。Systemはいったんtest-systemとしましょう。
ScreenShot 164.png

Next Stepを選択すると今度はGitの情報を入力します。
これはこのGolden Pathによって作成されるコピー先のGitHub情報になります。
GitHub Organization Name or Use NameにはGitHub Organization名か、自分のGitHub IDを入力します。
ScreenShot 165.png

情報が正しく入力されていることを確認し、CREATEを選択します。
ScreenShot 166.png

するとパイプラインっぽいものが実行され、全てチェックが完了します。
ScreenShot.png

この状態で左メニューのCatalogを選択すると、さきほど入力した情報をもとにCatalogが払い出されました。
ScreenShot 169.png

選択してみると、払い出されたCatalogの情報が表示されます。
Aboutの中のVIEW SOURCEを選択してみます。
ScreenShot 170.png

すると別タブで、Golden Pathの実行によって作成されたappリポジトリが表示されます。中にはapp-skeletonに予め作成したcatalog-info.yamlが格納されていることがわかります。
ScreenShot 171.png

template.yamlを読み解く

とりあえずポチポチやってGolden Pathの実行が完了しましたが、その大元となるtemplate.yamlの記載内容が理解できないと、何をしているのかピンとこないので、順番に読み解いていきましょう。

冒頭部分

(抜粋)template.yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: sample-app-template
  title: Create a sample application with a CI pipeline
  description: Provides the sample code and CI pipeline to build and deploy a sample application on OpenShift.
  tags:
    - recommended
spec:
  owner: user:default/<自分のGitHub ID>
  type: service

...

まずは冒頭部分ですが、これはこのGolden Pathの概要が記述されています。
どのパラメータがどこに紐づいているかは、上記のコードとRHDHの画面を見比べると分かりやすいかと思います。
ScreenShot 173.png

  • metadata.name : このGolden Pathの名前です。画面には反映されませんが、URLのPathとして使われます。
  • metadata.title : このGolden Pathのタイトルです。画面ではこちらがGolden Path名になります。
  • metadata.description : このGolden Pathの説明です。こちらも画面で確認できます。
  • metadata.tags : このGolden Pathを検索する際に活用できるキーワードを設定します。
  • spec.owner : このGolden Pathの管理者の名前です。
  • type: service : このGolden Pathの属性を定義できます。任意の値を設定可能ですが、serviceapiがメジャーのようです。これもタイトルの上部に表示されます。

parameters部分①

(抜粋)template.yaml
  parameters:
    - title: Provide information about the new component
      required:
        - app_name
        - owner
        - system
      properties:
        app_name:
          title: Repository Name
          type: string
          default: "sample-app"
        description:
          title: Description
          type: string
          description: Help others understand what this component is for
        owner:
          title: Owner
          type: string
          description: Owner of the component
          ui:field: OwnerPicker
          ui:options:
            catalogFilter:
              kind:
                - Group
        system:
          title: System
          type: string
          ui:field: EntityPicker
          ui:options:
            catalogFilter:
              kind:
                - System

parametersでは、基本的にリスト形式で利用者側に入力してほしい項目を書いていきます。
上記の記述範囲は以下の画面を構成しています。
ScreenShot 164.png

  • title : Stepごとの入力画面のタイトルになります。
  • required : この入力画面で必須項目となるパラメータkeyを指定します。
  • properties.xxx : properties配下に入力項目を並べていきます。xxxの部分がパラメータkeyになります。
    • xxx.title : 画面に表示するパラメータ名です。
    • xxx.type : パラメータの型を定義します。
    • xxx.description : このパラメータの説明です。こちらは画面に表示されるため、パラメータの補足として利用します。
    • xxx.default : このパラメータのデフォルト値です。

上記までが一般的な記述内容になります。一方で、例えばすでにRHDHに登録済みのパラメータ(GroupUserSystemなど)を参照してプルダウン形式で選択させたい場合は、ui:field:ui:options:を活用します。

  • xxx.ui:field : EntityPicker OwnerPicker RepoUrlPickerの3種類から選択できます。それぞれパラメータの属性に応じて適切なものを選択します。詳細はこちらを参照下さい。
    • xxx.ui:field.OwnerPicker.catalogFilter : ここでプルダウンで表示させる値をフィルタリングしています。ownerの場合はRHDH内に登録してあるgroup、すなわちGitHubのTeam名がここに表示されることになります。

このtemplateでは、このui:fieldonwersystemというパラメータで使用しています。
onwerについては上記で説明したOwnerPickerでRHDH上に登録してあるkind: onwerの情報を取得しています。
systemではEntityPickerでRHDH上に登録してあるkind: systemの情報を取得します。


parameters部分②

(抜粋)template.yaml
    - title: Provide information about the git to used
      required:
        - git
        - git_host_url
        - git_owner_name
      properties:
        git:
          title: Git of Destination
          type: string
          description: This action will store the application source code on the selected Git server
          enum:
            - github
          enumNames:
            - GitHub
      dependencies:
        git:
          oneOf:
            - properties:
                git:
                  enum:
                    - github
                git_host_url:
                  title: Git Host URL
                  type: string
                  default: github.com
                  description: Specify the GitHub or GitLab host URL(e.g., github.com)
                git_owner_name:
                  title: GitHub Organization Name or User Name
                  type: string
                  description: Specify the GitHub Organization or User to register the repository

この部分では主にGolden Pathをもとにユーザーに払い出されるGitHubの情報を入力する画面を設定しています。
基本的な記述方法は全画面と同様ですが、ここでは新しい記述方法があります。

  • properties.git.enum : これは、ユーザーに設定する選択肢を耐える場合に利用します。プルダウンで表示するためui:fieldと似ていますが、RHDH上のリソースを選択するのではなく、純粋にパラメータ(ここではgitというパラメータ)に設定したい文字列や数値をリストで記載できます。今回はgithubという値のみしか選択肢に表示されない記述となっていますが、例えばgitlabという選択肢を増やして、作成先のGitサービスを選択させるといった使い方もできます。(その際は別途app-configでGitLabとの連携設定が必要です。)

  • properties.git.enumNames : これはenumで設定した値を設定する際、画面上ではどんな文字列にするかを指定できます。今回の場合はgithubという値をgitに設定する場合、GitHubという選択肢を画面上で指定する、といった意味になります。enumの記載順序と合わせておく必要があります。

  • dependencies : これは、ある値によって画面に表示させる入力画面を分けたい場合に使用します。画面で入力する際、Git of DetinationGitHubにしたタイミングでGit Host URLGitHub Organization Name or User Nameの入力欄が表示されたかと思います。その挙動はこの記述によって実現されています。

  • dependencies.git.oneOf : ここではgitの入力値によって表示画面を使い分けることを記述しています。oneOf配下にリスト形式で使い分ける画面の情報を記述します。

  • dependencies.git.oneOf.properties.git.enum:[github] : この記述によって、"git=githubの時にこの入力画面を表示させる"ことができます。

ユーザーに入力させる画面を生成するparameters部分の説明は以上です。
次にGolden Pathの実行部分であるstepsを見ていきます。

steps.id: app_template

(抜粋)template.yaml
  steps:
    - id: app_template
      name: Generating the Application Source Code Component
      action: fetch:template
      input:
        url: ./app-skeleton
        values:
          git: ${{ parameters.git }}
          git_host_url: ${{ parameters.git_host_url }}
          git_owner_name: ${{ parameters.git_owner_name }}
          app_name: ${{ parameters.app_name }}
          owner: ${{ parameters.owner }}
          system: ${{ parameters.system }}
          description: ${{ parameters.description }}
        targetPath: ./tenant-app

stepsでは、Golden Pathの実行部分を記述します。このstepsはリスト形式で各処理を記述していき、その順番通りに実行されていきます。その実行される内容を指定しているのがactionになります。

Templateのactionについて

このactionが実質RHDHで自動化するタスクを表しています。
actionの種類はプラグインの導入によって増やすことが可能です。
https://<RHDHのURL>/create/actionsにアクセスすることで、現在の状態で利用可能なactionを確認することができます。
今回はaction: fetch:templateを指定しているので、その部分を見てみましょう。
ScreenShot 178.png
Downloads a skeleton, templates variables into file and directory names and content, and places the result in the workspace, or optionally in a subdirectory specified by the targetPath input option.
とあるように、テンプレート元から情報を取得して、変数を代入してワークスペースに格納するactionになります。

まずはパラメータを確認していきましょう。

  • input.url : 取得するテンプレートの相対パスになります。このtemplate.yamlsample-skeletonリポジトリ直下にあるため、そこからの相対パスとして./app-skeletonを指定しています。
  • input.values : この値が変数に代入するパラメータになります。
  • input.targetPath : これはローカル(RHDH Pod内)のワークスペースを指定します。ディレクトリがなければ/tmp配下に作成されます。今回はtenant-appapp-skeletonのファイル群を一時的に格納します。

"変数を代入"というところについては、すでに皆さんも作成済のcatalog-info.yamlで記述しています。

app-skeleton/catalog-info.yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: ${{ values.app_name }}
  {%- if values.description %}
  description: ${{ values.description }}
  {%- endif %}
spec:
  type: service
  system: ${{ values.system }}
  lifecycle: production
  owner: ${{ values.owner }}
  git: ${{ values.git }}
  git_host_url: ${{ values.git_host_url }}
  git_owner_name: ${{ values.git_owner_name }}

このファイルはapp-skeletonディレクトリ配下に作成したので、これもfetch:templateactionにて取得されています。そして${{ values.app_name }}というような形で記述すると、input.valuesで渡した値に書き換えてくれます。
たいていのGolden Pathは、GitにあるSkeletonを取得して変数を代入してPushする、という処理になるかと思うので、このactionの記述方法は理解しておきましょう。

steps.id: publish-app-to-github

(抜粋)template.yaml
    - id: publish-app-to-github
      if: ${{ parameters.git == "github" }}
      name: Publish App Repository to GitHub
      action: publish:github
      input:
        repoUrl: ${{ parameters.git_host_url }}?owner=${{ parameters.git_owner_name }}&repo=${{ parameters.app_name }}-app
        repoVisibility: public
        sourcePath: ./tenant-app
        defaultBranch: develop
        protectDefaultBranch: false

ここではpublish:githubというactionを指定しています。
これはローカルにあるデータをもとに、GitHubに新しいリポジトリとしてPushするものです。
パラメータを見ていきましょう。

  • if : これはこのactionを実行する際の条件を指定します。ここではparameters.gitgithubの場合のみ実行するよう指定しています。
  • input.repoUrl : Pushする先のGitHubのURLです。これでPushできる先は前回の記事で連携設定を行ったOrganizationに限られます。ただ、parameters.git_owner_nameはGitHubのTeamから取得したTeam名をプルダウンで選択させているため、今回はユーザーは気にせず設定可能です。
  • input.repoVisibility : GitHubのリポジトリの公開設定です。PublicPrivateを設定できます。
  • input.sourcePath : GitHubにPushするデータが格納されているパスを指定します。ここでは前のfetch:templateactionでskeletonから取得&変数代入を行った./tenant-appを指定します。
  • input.defaultBranch : Pushする際のデフォルトのBranchになります。今回はdevelopをデフォルトのブランチとしています。
  • input.protectDefaultBranch : GitHubはデフォルトブランチが保護されています。今回はデモ実行する際に保護していない方がラクなのでfalseにします。

steps.id: register-to-github

(抜粋)template.yaml
    - id: register-to-github
      if: ${{ parameters.git == "github" }}
      name: Registering the Catalog Info Component to GitHub
      action: catalog:register
      input:
        repoContentsUrl: ${{ steps['publish-app-to-github'].output.repoContentsUrl }}
        catalogInfoPath: "/catalog-info.yaml"

catalog:registeractionは、指定のGitリポジトリに存在するRHDHのcatalog用yamlファイルをRHDHに登録することができます。
これによって、今回新たに作成されたgitリポジトリ上のcatalog-info.yamlをRHDHから確認できる状況になります。このactionのおかげでRHDHの画面上からComponentを確認できるようになります。
ScreenShot 176.png

output

(抜粋)template.yaml
  output:
    links:
      - title: Open the Source Code Repository
        if: ${{ parameters.git == "github" }}
        url: ${{ steps['publish-app-to-github'].output.remoteUrl }}
      - title: Open the Catalog Info Component
        if: ${{ parameters.git == "github" }}
        icon: catalog
        entityRef: ${{ steps['register-to-github'].output.entityRef }}

ここは、Golden Pathの実行結果の画面に表示する内容を記述します。
主にGolden Pathで生成されたGitリポジトリのURLやcatalog-info.yamlのURLなどを貼るケースが多いかと思います。

おわりに

以上が今回のTemplateすなわちGolden Pathの全貌になります。
次回はさらにこのTemplateを拡充していき、実践的なものに仕上げていきます。

【番外編】Catalogって何なんだ?

RHDH(Backstage)はUserGroup、などいくつかのkindを持っています。そしてそれらのkindは、RHDH上ではすべてCatalogという親コンポーネントの配下に存在する形になります。実は今回作成したGolden PathもTemplateというkindであり、これもCatalogのひとつです。またこのGolden Pathによってデプロイされた環境を管理するために作成したcatalog-info.yamlも、中身を見てみるとkind: Componentとなっています。これも実はCatalogの一種です。

catalog-info.yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: sample-app
  description: test description
spec:
  type: service 
  system: sample-system
  lifecycle: production
  owner: group:default/skitamura-team
  git: github
  git_host_url: github.com
  git_owner_name: rhdh-skitamura-org

本編ではスルーしていましたが、実はSystemTemplateComponentと同様にCatalogとして事前にyamlで定義することができます。

ためしに、今の状態でCatalog一覧のOwned componentsにあるtest-systemを選択してみます。
ScreenShot 176.png

するとWarningが出てきます。これは、RHDH上でtest-systemというsystemが登録されていないことが原因です。

ここで以下のようなcatalog-info.yamlsample-skeleton配下に置きます。

apiVersion: backstage.io/v1alpha1
kind: System
metadata:
  name: test-system
  description: test-system
spec:
  owner: <GitHubのTeam名>

これをGitHubにPushしておきます。

そして、app-config-rhdh.yamllocationにこのyamlファイルを読み込むように設定します。

(抜粋)app-config-rhdh.yaml
      locations:
      - type: url
        rules:
        - allow:
          - Template
        target: https://github.com/<作成したOrg名>/sample-skeleton/blob/main/template.yaml
      # ここから
      - type: url
        rules:
        - allow:
          - System
        target: https://github.com/<作成したOrg名>/sample-skeleton/blob/main/system.yaml
      # ここまで

設定を反映させます。

./create-secret.sh

この状態で先程と同様にtest-systemを選択すると、以下のようにtest-systemの画面が表示されます。
ScreenShot 180.png
システムによっては、いくつかのマイクロサービスの集合体となっている場合があります。このSystemをうまく使うことで、それぞれのGolden Pathがどのシステムの一部なのかを効率よく管理することができます。

ちなみにCatalog画面左のkindのプルダウンを開くと、これまで色々設定・作成したリソース種別が確認できます。このようにRHDH(Backstage)においては、様々なコンポーネント(User,Group,System,Templeteなど)をCatalogとして管理します。そして基本的にそのCatalogの元となる情報はGitHubやGitLabに格納されたyamlファイルを参照して管理されることを把握しておきましょう。
ScreenShot 181.png

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?