APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

Backstageで独自Pluginを実装する

独自Pluginの実装

これまで何度かPlatform Engineering ToolのBackstageをご紹介してきました。 すでに多くの機能がPluginとして公開されており、そうしたものを活用することで様々な利用が可能となるのがBackstageの特徴の1つですが、さらに独自にPluginを開発して追加することができる、つまり自分たち専用のBackstageを作ることもできるのがもう一つの大きな特徴です。

backstage.io

今回、Terraform Cloudの情報をBackstage上に表示するという機能を実装しましたので、少しご紹介したいと思います。

今回の最終成果

まず最初に今回の最終成果をご覧いただこうと思います。

このような形式でBackstage上にTerraform Workspaceの一部情報を表示します。 利用者はGitHub上のPull Requestの一覧やGitHub Actionsの実行状況などとあわせて、Terraform CloudのWorkspaceの状況もあわせて確認できるようになります。Driftが発生しているなどの状況がすぐにわかるのは便利ではないでしょうか。

Plugin実装のために必要な理解

Backstageの基本

まずはじめにBackstageの基本について確認しましょう。

Backstageはソースコードを生成して利用するツールです。このため一番最初に行うことは自身用のBackstageの生成になります。次のコマンドで生成ができます。

npx @backstage/create-app@latest

作成以降の証左詳細はこちらに記載されています。

今回はこうした初期手順はすでに完了しており、あらたに機能を追加するというシナリオになります。

Backstageは大きく分けてFrontendとBackendの2つの部分から構成されています。FrontendはReactベースのSPA、BackendはExpressJSベースのAPIサーバとなっています。Backstageでは、それぞれにPluginという形で独自の機能を追加できるようになっていいます。

Pluginの構成

機能拡張は必ずしもFrontendとBackend両方を実装しなければならないというものでもありません。 例えばGitHubなど一部のソースコード管理ツールに関しては、PluginはFrontend用Pluginだけで構成されています。これはFrontendでGitHub等のユーザーアクセストークンを利用して直接GitHubのサーバーに接続して情報を取得し、それをFrontendで表示できるようにしているためです。 ユーザーアクセストークンを使用できないようなサービス等に関してはFrontendとBackendの両方のPluginを実装し、Backednからサーバーアクセストークンを利用してそれぞれの外部サービスにアクセスすることになります。 なお、この場合でもBackstageのFrontendとBackendの間のアクセスは、Backstageが独自に発行するユーザーアクセストークンを使用しますので、誰でもBackendにアクセスできるようになるというものではありません。

Pluginの命名規則

Pluginは一定の規則にしたがって命名することを期待されます(後述する初期コード自動生成ツールはこのルールに従ったものになります)。 名称は以下のようになります。機能全体の名称を terraformとした場合

  • terraform : frontend用Plugin
  • terraform-backend : backend用Plugin
  • terraform-common : frontend/backend等で利用する共通ユーティリティ

パッケージ名は /plugin-(上記の名称) となります。

その他の用途のパッケージを含むすべての命名規則は ADR011 - Architecture Decision Records 011) に記載されています。

Plugin 初期コードの生成

Frontend Pluginの作成は以下のコマンドで行います。

yarn new --select plugin

Enter the ID for the plugin [required] と表示されるので機能全体名称(さきほどの例でいえば terraform )を入力してください。 すると ローカルのbackstageの pluginsフォルダにterraformというフォルダでコードが生成されます。

Backend Pluginの作成は以下のコマンドです。

yarn new --select backend-plugin

Enter the ID for the plugin [required] と表示されるので機能全体名称(さきほどの例でいえば terraform )を入力してください。 すると ローカルのbackstageの pluginsフォルダにterraform-backendというフォルダでコードが生成されます。先程の命名規則のとおりに -backend の部分が自動的に追加されます。

この他、common 等の初期コード作成もコマンドから同様に実行できます。ドキュメントではあまり詳細に記載されていないため、ソースコードで確認していただく必要があります。

なお、パッケージ名のPrefixに関しては--scopeというコマンドラインオプションで変更することができます。 手元の例では package.jsonで以下のように --scope 指定を書き換えて対応しました。

  "scripts": {
    〜〜
    "create-plugin": "backstage-cli create-plugin --scope myplugin",
    "new": "backstage-cli new --scope myplugin"

これにより作成するPluginのパッケージ名は @myplugin/plugn-terraform(-xxx) といった名称になります。

Terraform Cloud用Pluginの導入

それでは実際にTerraform Cloud用のPluginを作成します。今回はサーバーアクセストークンを利用するため、FrontendとBackend両方を実装します。 構成は以下のようなイメージとなります。

実装する要素

<<Backendの実装>>

実装するものとしては以下の2つがあります

  • frontendからリクエストを受信し応答を返す処理
  • Terraform Cloudへのアクセス処理

<<Frontendの実装>>

  • Overview用のカードやカタログのタブページで表示する画面
  • Backendにリクエストを送信する部分

文字にすると当たり前の要素ですが、実はそれほど簡単ではないところがあります。

気をつけるところ/大変なところ

デザイン

Backstageでは複数の開発者が開発したPluginを1つの環境で実行するため、frontendのデザイン指針が整備されています。 この指針に沿って画面構成を考えたほうがよいでしょう。Backstage全体で利用するコンポーネントについては、Storybookで公開されているのでそちらも確認してください。

なお、Backstageは material-uiをベースに開発しています。こうした部分もある程度基礎知識があったほうがよいです。

コンフィグレーションの読み込み

Backstageでは app-confiig.yaml というファイルでコンフィグレーションを指定します。 Pluginで独自にコンフィグレーションを追加する場合は、事前にPlugin ソースコードにスキーマを定義しなければなりません。

書き方の公式ドキュメントはこちら、スキーマの定義の方法はこちらです。

簡単にいうと Pluginのソースコードに config.d.ts というファイルを作成し、そこにConfigというインターフェースでスキーマ定義を行います。

export interface Config {
  app: {
    /**
     * Frontend root URL
     * @visibility frontend
     */
    baseUrl: string;

    // Use @items.<name> to assign annotations to primitive array items
    /** @items.visibility frontend */
    myItems: string[];
  };
}

ポイントは各要素に @visibilityを指定することです。visibilityには次の3つがあります。

  • backend : 無指定の場合のデフォルト backend pluginでのみ読み取ることができます。
  • secret : backendで読み取ることができます。またログ出力からも除外されます。
  • frontend : frontend および backendの両方で読み取ることができます。

frontendをつけ忘れるとfrontend pluginで読み取ることはできませんのでご注意ください( yarn dev で起動するときはつけなくても読み取れてしまうので注意してください)。またSecretTokenなどについては secret visibilityを必ずつけるようにしましょう。

このファイルを作成したら package.json のfilesconfigSchemaの2箇所でファイル名を追加します。

{
  // ...
  "files": [
    // ...
    "config.d.ts"
  ],
  "configSchema": "config.d.ts"
}
Backstage本体のソースコードはいつでも確認可能に

BackstageはPluginで様々な機能を拡張できるようになっています。実は主要な機能もすべてPluginとして実装されています。それらがすべて npm packageとして公開されているわけですが、逆にいうと手元に作成したソースコードには、利用したいPluginや表示コンポーネントなどのソースコードはありません。そしてつらいことにドキュメントが十分に整備されていないと感じます。このため、Backstage本体のソースコードを直接あたり、どういったオプションがあるのか、どういったことが実現できるのかをコードから読み取ることが多くなります。また、自分が実現したいこともそうしたソースコードからヒントを得るといったことも多く発生します。 このため、自分が開発しているコードとは別にBackstage本体のコードも参照可能にしておくことをお勧めします。

実はこのあたりが結構苦労するところで、どうやればいいのかを理解するために、最初は結構な時間を本体のソースコード理解に費やしました。

github.com

(あらためて)結果

上記に示した2つのPluginを実装し、Terraform CloudからWorkspace(とRunsやAssessmentのデータ)を取得し、表示することができました。

画面全体をお見せすることはできませんが、OverviewとしてBackstageのデモのこちらの画面に 以下のような表示が追加されるイメージです。

そして冒頭にご覧頂いた画面(以下に再掲)がタブとして追加されるイメージになります。

BackstageだけでなくTerraformのAPIも含めて、いろいろ調べつつ、そしてテストコードを記述しつつ、ここまで実現するのに概ね2週間程度かかりました。。 しかし、ここまでできてしまえばあとは追加修正で機能拡張できるので、今後は修正なども加速していくものと思います(加速しやすいようにきちんと実装しておくことも重要です)。何事もスタートが大変で、重要な部分ですね。

まとめ

今回はBackstageに独自Pluginを追加する際のやり方、そして細かいけれど注意しておいたほうがいいことなどをご紹介しました。

Backstageは様々なPluginを導入することができ、それぞれの開発組織にあったInternal Developer Portal(IDP)を提供できるものです。このように開発チームの負荷を少しでも下げるような環境を作り上げることがPlatform Engineeringの1つの目的だと思います。ただ、Backstageでその自由さを享受しようと思うと、ソースコードの修正が必要になるなど、ちょっと面倒な作業が発生します。私たちはこうした「ちょっと面倒」な部分を少しでもかんたんに実現できるよう、IDPの実現のためのお手伝いをさせて頂いております。ご興味のある方はぜひ、以下の事業部のご紹介のリンクからぜひ音合わせいただければと思います。

ACS事業部のご紹介

私たちACS事業部はAzure・AKSなどのクラウドネイティブ技術を活用した内製化のご支援をしております。 Platform Engineering/Backstage導入支援もこうした内製化支援の一部と考えております。ぜひお声がけください。

www.ap-com.co.jp