Backstageを完全に理解した

# はじめに

[Ateam Group Manager ＆ Specialist Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ateam)の2日目は株式会社エイチームライフスタイル 執行役員CTOの @tsutorm がお送りします。例年マニアックなネタで好評を頂いておりますので、今年もマイペースで行こうと思います。 :smile:

一応 完全に理解した[^1] はネタです。

# この記事の概要

* エンジニア向けポータル [Backstage](https://backstage.io/) をうまく使って社内外サービスの "あれどこ / これ誰が見てるの / 詳しいのだれ" を減らせそうだよ
* [Spotify社が作ったOSS](https://github.com/backstage/backstage)でpluggableなreact-appとして見てもとっても勉強になるよ

# Backstageとは

![Backstage logo](https://github.com/backstage/backstage/raw/master/docs/assets/headline.png "Backstage")

開発組織が関わるサービスが少なく開発チームも小規模で、1~2サービスだけ見ていれば良い場合はそれほど問題は起きづらいですが、複数のサービスを複数の組織が連携しながら見るような開発組織規模になってきた場合、次のような問題が起きやすくなります。

- 誰がメンテナか不明なミニ社内サービス (意外と重要な事をしている)
- 標準化の不備によるノウハウ欠如
- 全体把握不良によるオンボーディングの長期化
- 車輪の再開発

ありがちですよね。

[Backstage](https://backstage.io/) とは、Spotify社で上記の課題を解消するため、4年前から開発され今年3月にOSS(Apache License, Version 2.0) として公開された、開発者向けポータルシステム[^2] で、社内のソフトウェア資産(マイクロサービス、ライブラリ、データパイプライン、Webサイト、MLモデルなど)を [サービスカタログ]() として管理することにより、開発者自身が民主的,自律的に上記問題へ対処し... **要するに快適開発ライフが維持できますというやつ** です。[^3]

[ThoughtWorks TECHNOLOGY RADAR Vol.23](Thoughhttps://www.thoughtworks.com/radar/platforms) でも今回からAssess評価に追加されて今後注目されていくかと思いますが、意外とQiita含めて日本語での触ってみた事例が少ない状況でしたので、今回はざっと触って "完全に理解した" 感を皆さんと共有できればと思います。

## 主な機能

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76630/205c237a-c9e5-4082-1b2c-f1d9ec81d697.png)

### [サービスカタログ(Backstage Service Catalog)](https://backstage.io/docs/features/software-catalog/software-catalog-overview)

開発組織が関係するサービス等を"カタログ"としてポータルへまとめることができます。一覧は上記の感じです。
後述するタイプ別に大きく区分けされ、その中で自分がオーナーのサービス、関係が深い(スターをつけた)サービス、全体での一覧化や、タグ、キーワードでの検索UIがあり、カタログ化されたサービスを素早く見つけられる様になっています。

カタログで管理される主な項目は

- 基本情報
    - 識別名と、その概要
    - ライフサイクル
        - 実験的/非production: `experimental`
        - 本番稼働: `production`
        - 廃止予定: `deprecated`
    - タイプ
        - (基本的に)APIを持つサービス `service`、 Webサイト `website`、 ライブラリ `library`
    - オーナーとなる人物(識別子としては メールアドレス), 組織
    - タグ(ex: `typescript`, `ruby` とか検索する際に使う
- ソースリポジトリ
    - github, gitlab, etc...
- API仕様
    - [OpenAPI(v2,v3)](https://swagger.io/specification/): `openapi`
    - [AsyncAPI](https://www.asyncapi.com/docs/specifications/latest/): `asyncapi`
    - [GraphQL](https://graphql.org/): `graphql`
    - [gRPC](https://grpc.io/): `grpc`
- 関連する技術文書(TechDocs)

と言ったものを kubernetesのconfigに似たyaml形式で定義することによって、以下のようなダッシュボードから扱えるようになります。

```yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: petstore
  description: Petstore
spec:
  type: service
  lifecycle: experimental
  owner: pets@example.com
  implementsApis:
    - petstore
    - streetlights
    - hello-world
```

こんな感じ ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76630/ce9ec6a5-96b3-2a5f-dd4f-ad2bf2fa97dc.png)

### [ソフトウェアテンプレート(Backstage Software Template)](https://backstage.io/docs/features/software-templates/software-templates-index)

`記事作成時点ではまだα版機能です。`

社内で新しくアプリケーションを開発し始めるときのテンプレートを管理できる機能です。ここから新規リポジトリを社内の所定リポジトリに向けて展開することで、いちいち「あのxxxってリポジトリのyyyをzzzに変えると今んとこ一番社内でいい感じの構成になるよ」みたいなのが撲滅されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76630/9201d17a-bd69-cab6-5eb7-dd747fa3f236.png)

今回はあまり触ってないので紹介としてはこの程度ですが、[Cookiecutter](https://github.com/cookiecutter/cookiecutter)を利用してテンプレート構成から所定のリポジトリに初期プロジェクトが自動展開されるような感じです。ちょっと後述します。

### [技術文書(Backstage TechDocs)](https://backstage.io/docs/features/techdocs/techdocs-overview)

Markdown形式で、技術的なドキュメントを記載できる機能です。
これも今回あまり触ってないのでさらっと公式からイメージだけ

![TechDocs](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76630/a84d48ab-b1fc-aec0-87c3-4a25723db66f.png)

## 触ってみる

まぁともあれ触ってみましょう。公式の[Getting Started](https://backstage.io/docs/getting-started/) にわかりやすく書いてますが、node(v14), npx と python と yarn と docker がセットアップされてる必要があります。

それぞれの導入は割愛します。

公式から`git clone`する手順が書いてありますが、`backstage`自体のメンテをするわけではなければ、[Create an App](https://backstage.io/docs/getting-started/create-an-app)からがBackstageを自分の所用に作っていく手順になるので、こちらで進めます。

(もちろん `git clone` の手順でも動きます)

### ローカルで動かしてみる

動作前提が揃っている状態で以下で終わりです。簡単。

```shell
$ npx @backstage/create-app
```

アプリ名とbackendに使うDB(PostgreSQLかSQLiteの二択)を指定すれば、後はスクリプトが走って終わりです。

```shell
$ npx @backstage/create-app
? Enter a name for the app [required] lifestyle
? Select database for the backend [required]
  PostgreSQL
❯ SQLite

Creating the app...

 Checking if the directory is available:
  checking      lifestyle ✔

 Creating a temporary app directory:
  creating      temporary directory ✔

 Preparing files:
  copying       .eslintrc.js ✔
  templating    .gitignore.hbs ✔
(中略)
  copying       EntityPage.tsx ✔

 Moving to final location:
  moving        lifestyle ✔

 Building the app:
  executing     yarn install ✔
  executing     yarn tsc ✔

🥇  Successfully created lifestyle

See https://backstage.io/docs/tutorials/quickstart-app-auth to know more about enabling auth providers
```

アプリケーションとしては、フロントのReactAppとバックエンドにexpressでAPIが立ってる構成ですので、実行もそれぞれ行います

```shell
$ cd lifestyle
$ yarn start & # フロントアプリの起動
# (割愛)
$ yarn workspace backend start # バックエンドアプリの起動
# (割愛)
```

あとはブラウザから `http://localhost:3000/` にアクセスすれば冒頭の画面が出てくるはずです。

アプリケーション全体の設定は `app-config.yaml` に定義されたものをロードして利用しています。
親切な事に、デモ用のexampleが豊富に入った `app-config.yaml` を配備してくれた状態になってるので、本来なら同階層の `app-config.production.yaml` を軸に自由に変えていく。というのがセオリーかと思います。

今回はさらっと触るので、このデモの環境をベースに進めます。

### サービスカタログに手動で追加してみる

任意のエディタで `app-config.yaml` を開いて、`catalog:`まで読み進めてください。

```yaml
catalog:
  rules:
    - allow: [Component, API, Group, User, Template, Location]
  locations:
    # Backstage example components
    - type: url
      target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/all-components.yaml
```

アプリ側ではAllで6つ, Ownedとして3つのアプリが表示されますが、ここでは target として githubのリンクが示されているだけです。

おもむろにリンクをブラウザで開いてもらうと、以下の yaml になっています。

```yaml
apiVersion: backstage.io/v1alpha1
kind: Location
metadata:
  name: example-components
  description: A collection of all Backstage example components
spec:
  type: github
  targets:
    - https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/components/artist-lookup-component.yaml
    - https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/components/petstore-component.yaml
    - https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/components/playback-order-component.yaml
    - https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/components/podcast-api-component.yaml
    - https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/components/queue-proxy-component.yaml
    - https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/components/searcher-component.yaml
    - https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/components/playback-lib-component.yaml
    - https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/components/www-artist-component.yaml
    - https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/components/shuffle-api-component.yaml
```

おー。なんとなく掴めましたかね。試しに、`petstore-component.yaml`を見に行きましょう。

```yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: petstore
  description: Petstore
spec:
  type: service
  lifecycle: experimental
  owner: pets@example.com
  implementsApis:
    - petstore
    - streetlights
    - hello-world
```

はい。ここで冒頭のカタログの設定が現れました。Backstageではこの単位を [Component と呼ぶようです。](https://backstage.io/docs/features/software-catalog/system-model)

`petstore-component.yaml` に相当するものを自分たちが開発しているサービスのリポジトリルートに `catalog-info.yaml` みたいにおいておいて、それを指し示してあげれば、自動的にBackstageのカタログプロセッサが解釈してリストとして表示してくれる・・・と。そういう機構になってます。

したがって、試しに[ご自身のgithubなんかに適当に上記を改変したものを突っ込んで](https://github.com/tsutorm/jwt-example/blob/master/catalog-info.yaml)、暫く待つと...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76630/098f6ed4-a79a-5b21-64af-486f00d13cde.png)


`jwt-example` 追加されましたね！

今回は触れませんが、`metadata.annotations`でTechDocsを関連付けたり、`spec.implementsApis`でOpenAPIで書いた仕様書をAPIとして公開したり、、Componentを起点に様々な情報を集約していくことができます。

### ソフトウェアテンプレートの裏側(Cookiecutters)

他にも、組織内のベストプラクティスを詰め込んだソフトウェアテンプレートを登録しておいて、新規アプリを立ち上げる時にオレオレベスト構成じゃなく、組織としてのベスト構成を標準化する機構があります。

こいつ内部でどういう動きになっているか気になりますよね？(ならないですかね？)

`./packages/backend/src/plugins/scaffolder.ts` を見てもらうとわかるのですが [cookiecutter](https://github.com/cookiecutter/cookiecutter) というプロジェクトテンプレートのツールを使っています。
[実際に動作させてる所はここですね](https://github.com/backstage/backstage/blob/c926765a2ceff1beaf7f16ffa186ac1e7023ea37/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.ts)

ちょっとまだ試せてないですが、cookiecutterの流儀に乗せればある程度いろんな環境が作れる(ためしてないですが、gem installとか走らせるならdocker側の調整も必要かな・・・)っぽいです。

[独自のtemplaterの作成](https://backstage.io/docs/features/software-templates/extending/extending-templater)もできるようなんで、頑張れば何でもって感じですかね。

### それ以外色々

コアコンポーネント以外にも [TechRadar](https://backstage.io/blog/2020/05/14/tech-radar-plugin)や[Cost Insights](https://backstage.io/blog/2020/10/22/cost-insights-plugin)など、プラグインとして機能強化可能な仕組みと、それを取り巻くマーケットプレイスエコシステムもあり、拡張性は非常に高そうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76630/b47bd935-9a6d-0f19-51ff-ec4a718b5d43.png)

またアプリケーション自体も[Lerna](https://github.com/lerna/lerna)を利用した大きなReact + Typescriptなappで、デザインについても[Backstage DesignTeamが全体設計に基づいてマテリアルUIを採用していて](https://backstage.io/docs/dls/design) 参考になるかなと感じました。

ただ、記事作成時点でまだまだ[仕様も変わるし３つのフェーズの最初が終わった段階だよ。](https://backstage.io/docs/overview/roadmap) となっています。本番利用はそれなりに人柱上等の前提で進めた方が良さそうです。

# まとめ

* ソフトウェア資産が増えてきて全体視界不良感の解消を目的として、開発者ポータル/サービスカタログツール [Backstage](https://backstage.io/) 注目してみても良いかなと思いました。
* 内部のアーキテクチャ [Lerna](https://github.com/lerna/lerna), [cookiecutter](https://github.com/cookiecutter/cookiecutter) も面白いので見てみると ○
* まだロードマップの前半だからご利用は計画的に！

# 次回告知

[Ateam Group Manager ＆ Specialist Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ateam)の3日目は @rf_p がお送りします。
ニーズを捉えてMVPを超高速リリースする彼のアドカレ、是非ご期待ください！！


[^1]: [プログラマーが使っている独特なプログラマー用語にはどんなものがありますか？ - quora.com](https://jp.quora.com/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC%E3%81%8C%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8B%E7%8B%AC%E7%89%B9%E3%81%AA%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC%E7%94%A8%E8%AA%9E)
[^2]: [Spotifyが開発者ポータル「Backstage」をオープンソース化 - ＠IT](https://www.atmarkit.co.jp/ait/articles/2003/17/news068.html)
[^3]: [Overview / What is backstage? - backstage.io](https://backstage.io/docs/overview/what-is-backstage)