はじめに
近年 Platform Engineering への注目が高まり、「開発者が セルフサービス でインフラやツールを使える環境づくり」が各社のテーマになっています。
そこで本記事では、開発者ポータル Backstage と AWS Proton を組み合わせ、
- Backstage からソフトウェアテンプレートを選択
- 即座にECS Fargateの環境を作成&デプロイ
できるまでの手順を解説します。
まず、動くPlatform Engineeringの最小実装を試したい方の参考になれば幸いです。
前提知識
今回は、Backstage・AWS Protonを主に使用します。これらについて全く知らない人は以下の記事を見ていただけると良いかと思います。
Backstage
社内のソフトウェア資産(マイクロサービス、ライブラリ、データパイプライン、Webサイト、MLモデルなど)の作成・管理を一元化できるツールです。
AWS Proton
コンテナおよびサーバーレスアプリケーションのための初の完全マネージド型アプリケーションデプロイサービスです。AWS Protonを用いることで、インフラストラクチャのプロビジョニング、コードデプロイ、モニタリング等ができます。
今回作成するもの
少しわかりづらいですが、下図のようなアーキテクチャを作成していきます。
BackstageとAWS ProtonやGitHubリポジトリをプラグインで接続することで
アプリ開発用リポジトリ作成 → IaC デプロイ → サービス稼働 までBackstage上で操作が完結します。
前提環境
この記事では、以下の前提条件に基づいて実装手順を説明します。
参考記事をもとに以下3つを構築してください。
# | 項目 | 概要 | 参考記事 |
---|---|---|---|
1 | Backstage プロジェクトの作成 |
npx @backstage/create-app などで作成済み |
Backstage Getting Started |
2 | AWS Proton テンプレートと環境の作成 | 環境テンプレート + サービステンプレートを作成し、環境をプロビジョニング済み | AWS Proton 入門 (DevelopersIO) |
3 | Backstage から AWS Proton へアクセスする権限を付与 | 私の場合は、EC2にサーバーを立ててローカルのvscode上で開発しており、EC2にIAMロールを追加しました。 | IAM Permissions Guide |
1でBackstageプロジェクトを作成すると、以下のようなディレクトリ構造になっていると想定しています。
test-backstage/
├── packages/
│ ├── app/
│ │ └── src/
│ │ └── components/
│ │ └── catalog/
│ │ └── EntityPage.tsx
│ └── backend/
│ └── src/
│ ├── index.ts
│ └── plugins/
├── app-config.yaml
└── package.json
実装手順
基本的に、以下の記事を参考に実装を進めています。
1. template.yaml
の作成
Backstage上のテンプレートを選択した際に、
- どんな入力項目を設定し
- どの Scaffolder Action を呼び出すか
を定義するファイルを作成します。
ここでは、下記にて提供されているテンプレートを少し修正していきます。
1.1 テンプレートリポジトリをクローン
# (任意の場所)
git clone git@github.com:<your-org>/aws-proton-plugins-for-backstage.git
1.2 template.yaml
を微修正
以下のXXX
部分について適切な値に変更してください。その他はデフォルトの設定で良いです。
修正後、自身のGitHubリポジトリにpushしてください。
steps:
- id: template
name: Fetch Skeleton + Template
action: fetch:template
input:
url: ./skeleton
values:
#Protonで環境テンプレートから作成した環境の名前を入れてください。
aws_proton_dev_environment_name: "XXX"
aws_proton_prod_environment_name: "XXX"
#自身のAWSアカウントIDを入れてください。
aws_account_id: "XXX"
- id: create-proton-service
name: Create AWS Proton Service
action: aws:proton:create-service
input:
#Protonで作成したサービステンプレートの名前を入れてください。
templateName: XXX
#Protonでテンプレート作成時に設定したCodeStar ConnectionsのARNを設定してください。
repositoryConnectionArn: 'arn:aws:codeconnections:us-east-1:XXX:connection/XXX'
2. Backstage 設定ファイルの更新
2.1 app-config.yaml
の設定
既存のapp-config.yaml
ファイルに以下を追加してください。
ポイント
aws
セクション:リージョンの追加integration
セクション:GitHub認証情報とAWSのリージョンを追加proxy
セクション:Backstage → Proton API 用のリバースプロキシcatalog.locations
セクション:1. template.yaml の作成でfork したtemplate.yaml
への URL を登録
# AWS
aws:
region: us-east-1
# GitHub / AWS 統合
integrations:
github:
- host: github.com
apps:
- $include: github-credentials.yaml
aws:
- region: us-east-1
# Proxy
proxy:
endpoints:
"/api/aws-proton":
target: "http://localhost:7007/api/aws-proton"
changeOrigin: true
"/api/aws-proton-backend":
target: "http://localhost:7007/api/aws-proton-backend"
changeOrigin: true
# テンプレート登録
catalog:
locations:
- type: url
target: https://github.com/<your-org>/aws-proton-plugins-for-backstage/blob/main/docs/tutorial-assets/fargate-nginx-template/template.yaml
rules:
- allow: [Template]
2.2 github-credentials.yaml
の設定
github-credentials.yaml
には、GitHubで作成したGitHub Appsの情報を格納しています。
app-config.yaml
ファイルと同じディレクトリに作成してください。
appId: 111111
clientId: abcdefghi123
clientSecret: xxxxx
webhookSecret: yyyyy
privateKey: |
-----BEGIN RSA PRIVATE KEY-----
(省略)
-----END RSA PRIVATE KEY-----
2.3 ここまでの動作確認
Backstage 設定ファイルの更新まで完了したら、以下のテンプレートがBackstage上に表示されるか確認してみましょう。(テンプレートの名前や色は違うかもしれません。)
うまく表示されていれば、次に進みましょう。
3. AWS Proton プラグインをインストール
AWS Proton用のBackstageプラグインをインストールします。
yarn add @aws/aws-proton-plugin-for-backstage # frontend
yarn add @aws/aws-proton-backend-plugin-for-backstage # backend
4. Backstage バックエンド の実装
ここでは、
- 2ファイル(
awsProton.ts
・scaffolderActions.ts
)の新規作成 - 1ファイル(
index.ts
)の修正
を行います。
4.1 awsProton.ts
ファイルの作成
packages/backend/src/plugins/awsProton.ts
ファイルを新規作成し、AWS Protonサービスとの通信を行うAPIエンドポイントを実装しています。
これにより、既存のAWS Protonリソースの情報を Backstage上で取得・表示することができます。
import { createBackendPlugin, coreServices } from '@backstage/backend-plugin-api';
import express from 'express';
import Router from 'express-promise-router';
import {
ProtonClient,
ListEnvironmentsCommand,
} from '@aws-sdk/client-proton';
export default createBackendPlugin({
pluginId: 'aws-proton-backend',
register(env) {
env.registerInit({
deps: {
config: coreServices.rootConfig,
httpRouter: coreServices.httpRouter,
},
async init({ config, httpRouter }) {
const region = config.getString('aws.region');
const client = new ProtonClient({ region });
const router = Router();
router.get('/environments', async (_, res) => {
const output = await client.send(new ListEnvironmentsCommand({}));
res.json(output.environments ?? []);
});
httpRouter.use('/api/aws-proton', router);
},
});
},
});
4.2 scaffolderActions.ts
ファイルの作成
packages/backend/src/plugins/scaffolderActions.ts
を新規作成し、BackstageのテンプレートからAWS Protonサービスを作成するためのアクションを登録しています。
import { createBackendModule, coreServices } from '@backstage/backend-plugin-api';
import { createAwsProtonServiceAction } from '@aws/aws-proton-backend-plugin-for-backstage';
import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha';
export default createBackendModule({
pluginId: 'scaffolder',
moduleId: 'aws-proton-actions',
register(env) {
env.registerInit({
deps: {
actions: scaffolderActionsExtensionPoint,
config: coreServices.rootConfig,
},
async init({ actions, config }) {
actions.addActions(createAwsProtonServiceAction({ config }));
},
});
},
});
4.3 index.ts
ファイルの修正
packages/backend/src/index.ts
ファイルに、作成したプラグインを登録します。
import { createBackend } from '@backstage/backend-defaults';
import awsProtonBackendModule from './plugins/awsProton';
import scaffolderActionsModule from './plugins/scaffolderActions';
// 他のモジュールも追加
// ...
const backend = createBackend();
backend.add(awsProtonBackendModule);
backend.add(scaffolderActionsModule);
// 他のプラグインも追加
// ...
backend.start();
4.4 ここまでの動作確認
以下の動作が正常に実行できたら、次に進みましょう。
4.4.1 テンプレート選択後
4.4.2 必要項目入力&Createクリック後
5. Backstage フロントエンド の実装
5.1 フロントエンド への Proton カード追加
packages/app/src/components/catalog/EntityPage.tsx
にカードを差し込む例です。
import {
EntityAWSProtonServiceOverviewCard,
isAWSProtonServiceAvailable,
} from '@aws/aws-proton-plugin-for-backstage';
const overviewContent = (
<Grid container spacing={3}>
<EntitySwitch>
<EntitySwitch.Case if={isAWSProtonServiceAvailable}>
<Grid item md={6}>
<EntityAWSProtonServiceOverviewCard />
</Grid>
</EntitySwitch.Case>
</EntitySwitch>
</Grid>
);
5.2 ここまでの動作確認
AWS Proton Serviceカードが以下のように正しく表示されれば、連携は完了です 🎉
まとめ
今回、プラグインを用いてBackstage と AWS Proton をつなげることで、テンプレート選択 → Fargate デプロイ が簡単にできるようになりました。
Backstageには他にもあらゆるプラグインが存在しており、AWS Codepipelineと連携しCI/CD状況の可視化やGrafanaと連携しダッシュボードの表示などが簡単にできます。
時間があれば、他にもBackstageに関わる記事を書きたいと思っています!