iT邦幫忙

2026 iThome 鐵人賽

DAY 23
0
IT Operation

寫完微服務然後呢?走向平台工程的黃金路徑系列 第 23 篇

Day 23 - 用 Backstage Software Templates 收集服務設定

  • 分享至 

  • xImage
  •  

前一篇讓 Operator 回報 Todo API 的新版是否就緒。不過,要更新版本,開發者仍得先準備 Microservice YAML。假設這次只是換一個 image,服務名稱、Namespace 和 port 都沒變,還需要每次重新填寫整份設定嗎?

Day 17 介紹過 Backstage 的 Software Catalog(軟體目錄)與 Software Templates(軟體範本):Catalog 讓我們找到服務與負責團隊,Templates 則收集輸入、執行指定的工作。今天集中在後者,替 todo-api 準備一個換版模板,讓開發者只填 CI 產出的 digest,再由模板產生 Microservice 設定。

先決定模板要產生什麼設定

既然要減少重複填寫,我們先把這次不會改變的值固定下來:服務是 todo-api,Dev 沿用既有的 todo Namespace,port 是 8080,image repository 是 ghcr.io/yrw9281/it30-todo-api。唯一要從表單取得的,就是新版 digest。

將這些值寫進 microservice.yaml,在 digest 的位置留下變數,這份檔案就能重複用來產生每次換版的設定:

apiVersion: platform.example.io/v1alpha1
kind: Microservice
metadata:
  name: todo-api
  namespace: todo
spec:
  image: ghcr.io/yrw9281/it30-todo-api@sha256:${{ values.digest }}
  port: 8080

${{ values.digest }} 是待替換的部分。模板執行時會將它換成使用者填入的字串,這個過程稱為渲染(render)。替換後,spec.image 就會指向新的 digest;服務名稱、Namespace 和 port 則維持原值。含有變數的檔案不能直接提交 Kubernetes,要使用渲染後的 YAML。

這次的檔案還包含一份 kustomization.yaml,與 microservice.yaml 一起放在 skeleton 目錄。它列出 Kustomize 要讀取的資源,沒有需要替換的值,產生後會原樣出現在任務 log 裡:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - microservice.yaml

知道要產生什麼內容後,我們就可以回頭定義表單,以及產生這些檔案的步驟。

用同一份 Template 定義表單與產生步驟

我們希望開發者填完 digest,就能在任務頁面看到產生的設定。這些工作都定義在同一份 Template 裡:spec.parameters 決定表單要收集什麼,spec.steps 負責產生檔案與顯示內容,spec.output 則設定任務完成後的結果說明。以下是這次操作使用的完整 template.yaml:

apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: todo-api-dev-preview
  title: Todo API Dev Config Preview (D23)
  description: Render Microservice YAML from an image digest without creating a PR or deploying the service.
  tags:
    - todo
    - preview
spec:
  owner: todo
  type: service
  parameters:
    - title: Todo API image update
      required:
        - digest
      additionalProperties: false
      properties:
        digest:
          title: Image digest
          description: "Enter the 64 lowercase hex characters after sha256:, without the prefix."
          type: string
          minLength: 64
          maxLength: 64
          pattern: "^[0-9a-f]{64}$"
  steps:
    - id: render
      name: Render Microservice YAML
      action: fetch:template
      input:
        url: ./skeleton
        values:
          digest: ${{ parameters.digest }}
    - id: inspect
      name: Inspect rendered files (no deployment)
      action: debug:log
      input:
        message: Preview only. No Git changes or Kubernetes writes were performed.
        listWorkspace: with-contents
  output:
    text:
      - title: Config preview complete
        content: |
          The Todo API Dev configuration has been rendered. Open the logs for
          "Inspect rendered files (no deployment)" to view the actual
          `microservice.yaml` and `kustomization.yaml` contents.

          This task only renders and displays files. No PR was created and no service was deployed.

表單只收集 digest,因此我們用 required 要求必填,再用 minLength、maxLength 和 pattern 限制它必須是 64 位的小寫十六進位字串。additionalProperties: false 則不接受額外的參數,所以使用者不能透過多送一個參數來指定 Namespace 或 port。

因為 microservice.yaml 的 image 已經包含 @sha256:,填表時只需貼上 CI 輸出中 sha256: 後面的 64 位字元。若連前綴一起填入,就不符合欄位的長度與格式,無法繼續建立任務。

表單的輸入通過檢查後,render 步驟會執行 fetch:template。這是 Backstage 用來讀取檔案模板、填入變數的 action。url: ./skeleton 告訴它要處理模板旁的 skeleton 目錄,也就是前面放置 microservice.yaml 與 kustomization.yaml 的地方。

讀取檔案時,fetch:template 也會取得 input.values 裡的值。我們用 ${{ parameters.digest }} 取出表單的 digest,放進 input.values.digest,讓 microservice.yaml 中的 ${{ values.digest }} 能使用它。兩種寫法的差別在於讀取的位置:parameters 是表單輸入,values 是傳給檔案模板的值。

檔案產生後,我們還需要在 Backstage 裡看見內容,所以接上 inspect 步驟。它執行 debug:log,並用 listWorkspace: with-contents 把工作目錄裡的檔名與內容寫進 log。這個步驟只顯示檔案,不會部署它們。

output.text 則負責任務完成後的結果說明。畫面上的 Config preview complete 與下方文字都來自這裡,讓使用者知道設定已產生,以及要開啟 Inspect rendered files (no deployment) 的 log 查看內容。

表單輸入如何變成 YAML?

把前面的設定串起來:開發者填入 digest,fetch:template 讀取 microservice.yaml,替換其中的變數,再把產生的檔案放進這次任務的工作目錄。完成這個步驟後,工作目錄裡會有一份 image 已帶入 digest 的 Microservice YAML:

Developer enters an image digest in the Template form; fetch:template combines it with fixed values to render Microservice YAML in the task workspace

在 Backstage 操作一次設定預覽

表單的欄位限制與產生邏輯沿用前面的設定,今天的操作只產生檔案,不會提交 Git 或更新叢集。

在 Backstage 的 Create 頁面可以看到我們擁有的 Templates:

Backstage Create 頁面右側的 Todo API Dev Config Preview D23 模板卡片

選好今天做好的模板後,只會要求填寫 Image digest。貼上 digest 的 64 位小寫十六進位字元,不包含 sha256:,再點 Review 確認輸入,確認後建立任務。服務名稱、Namespace 和 port 不需要在這裡重填:

Todo API Dev 設定預覽表單只收集 Image digest,欄位說明要求省略 sha256 前綴

如果輸入 AAA 再點 Review,表單會同時提示長度不足 64 位、字元不符合小寫十六進位格式,讓我們留在這一頁修正輸入。換回符合格式的 digest 後,才能繼續確認並建立任務:

Image digest 填入 AAA 後,Backstage 表單顯示長度不足 64 位與不符合小寫十六進位格式的錯誤提示

建立任務後,Backstage 會依序執行產生檔案與顯示內容的步驟。如果離開了執行畫面,可以從頁面上的 Tasks 找回這次任務。畫面中的 completed 表示模板任務已完成,還不代表 Todo API 已更新:

Backstage Tasks 列出 Todo API Dev Config Preview D23 任務,狀態為 completed

點進任務,查看 Inspect rendered files (no deployment) 的 log,就能看到實際產生的 microservice.yaml。畫面中 spec.image 已帶入表單的 digest,而服務名稱仍是 todo-api、Namespace 仍是 todo、port 仍是 8080:

Backstage 預覽任務完成,log 顯示已帶入 digest 的 Microservice YAML,結果說明未建立 PR 或部署服務

這樣就能從表單一路對照到產物。不過,欄位限制只會擋下長度或字元不符的輸入,不會查詢 image 是否存在,也不會確認它來自哪次 CI;填寫時仍要使用 Todo API 的 CI 輸出。

今天把換版時需要重複填寫的內容收進模板,開發者只提供 digest,Template 就能依設定產生 Microservice YAML。下一篇接著處理這份產物:讓模板用 Git Pull Request(PR)提出變更,經過設定檢查與人工 review,再進入部署來源。


上一篇
Day 22 - 讓 Operator 回報新版是否就緒
下一篇
Day 24 - 用 Backstage 提出 GitOps 設定 Pull Request
系列文
寫完微服務然後呢?走向平台工程的黃金路徑 共 25 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言