IBM Cloud Open Toolchainテンプレートの作成方法まとめ

# 背景
IBM CloudにはプロジェクトのDevOpsライフサイクルに合わせてIBMクラウドサービスとオープンソース・ツールやサードパーティのツールを組み合わせてDevOpsのためのToolchainの環境を簡単に構築するための仕組みがあります。
https://www.ibm.com/cloud/architecture/toolchains

今回の案件ではIBM Cloud Kubernetes service(IKS)を実行環境としたコンテナ・アプリケーション開発用のToolchainを構築することになり、手始めにToolchainのカタログで用意されている[Kubernetesアプリ開発のToolchain](https://www.ibm.com/cloud/architecture/toolchains/develop-kubernetes-app-toolchain)がそのまま適用可能かを確認しました。

Kubernatesアプリ開発のToolchainでは以下のツールがセットアップされます。

| ツールまたはサービス | 説明 |
|:-----------------|:-------------------|
| [GitリポジトリとIssue Tracking(GitLab)](https://www.ibm.com/garage/method/practices/code/tool_git_repos_and_issue_tracking)| コードを保存および管理し、不具合、拡張、タスクなどの作業を追跡します。 |
| [Eclipse Orion Web IDE](https://www.ibm.com/garage/method/practices/code/tool_eclipse_orion_web_ide) | コードを変更し、Webブラウザーからパイプラインを介してコードをデプロイします。 |
| [PIPELINE](https://www.ibm.com/garage/method/practices/deliver/tool_delivery_pipeline)| 自動的にビルドしてIBM Cloudにデプロイします。|
| [IBM Cloud Kubernetes Service （Kubernetesクラスター）](https://www.ibm.com/garage/method/practices/run/tool_ibm_container/) | IBM Cloud Kubernetes Service によって管理され、セキュリティを強化するための脆弱性アドバイザーを含むKubernetesクラスターにデプロイします。 |	 	

![alt](https://www.ibm.com/cloud/architecture/images/toolchain_icons/secure_kube_tc_diagram.svg)

Toolchainは以下のようにIBM CloudのToolchainのカタログから**Kubernetesアプリの開発**を選択して簡単にセットアップすることが出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5259/7a18234a-bd4c-88ba-1cf7-bfecb09d7b3b.png)

実際にToolchainをセットアップして、今回の案件でそのまま使用することが可能かDelivery Pipelineの内容を精査した結果以下の点が要件に合わないことがわかりました。

- Web IDEは使用しない
- ソースコードとIKSにデプロイに使用するマニフェストファイルのどちらも同一のGitリポジトリから取得する前提のPipelineとなっている

Web IDEに関しては利用しなければいいだけなのでまだ良かったのですが、二点目が以下の要件から許容できませんでした。

- 今回の案件ではソースコードは開発者、マニフェストファイルは運用担当者が管理する
- 開発者の方ではマニフェストファイルの変更が出来ないように権限分離したいので、アプリ用のリポジトリと運用用のリポジトリに分割してそれぞれのファイルを管理する

これに伴い、当初はKubernetesアプリ開発のパイプラインを作成して手動でカスタマイズする想定で考えていたのですが、案件が進んでいくにつれてIKSで稼働するサービスが複数必要であることが判明し、毎回この作業を手動で実施するとなると無駄なコストがかかる上に作業ミスが必ず発生するのでToolchainのカスタマイズ自体を自動化することを考えました。

幸い、IBM Cloud ToolchainはカスタムToolchainのためのテンプレートを作成することが可能だと以下のチュートリアルからわかりました。
https://www.ibm.com/cloud/architecture/tutorials/create-a-template-for-a-custom-toolchain

そこで、このチュートリアルやチュートリアルで言及している[Open Toolchainテンプレートのマニュアル](https://github.com/open-toolchain/sdk/wiki#open-toolchain-templates-sdk)を参照しながら、前述した要件を満たすToolchainテンプレートを開発しました。

この記事では実際にToolchainテンプレートを開発した際の知見を整理し、開発の手順をまとめます。
実際に作成したテンプレートについては以下の記事で触れますのでぜひそちらもご覧ください。
[IBM Cloud Open ToolchainテンプレートをカスタマイズしてGitOps的なToolchainを作ってみた！](https://qiita.com/strada/items/2b7d70d5de677692157f)

# はじめに
本資料はIBM Cloud Open Toolchain・テンプレートの開発時に使用します。本資料を含めた下記アセットの活用により、IBM CloudOpen Toolchain環境構築における設計、実装、構築の作業を効率的に進めることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5259/6e1f0f3a-f645-10aa-2098-497f9421ab67.png)

# Open Toolchainテンプレートとは
Open ToolchainテンプレートはプロジェクトのDevOpsプロセスのために必要なツールの組み合わせを選択することでプロジェクトに合わせてカスタマイズが可能なツール・セットです。

開発プロセスにおけるコードの作成、ビルド、テストおよびコードのデプロイを１ページで設定可能です。

Open Toolchainテンプレート（OTCテンプレート）はカスタマイズ可能であるため、チームは、組織に固有の一連のテンプレートを作成できます。これにより、適切に統合された一連の既知のツール・セットを使用して、新しいプロジェクトをすばやく立ち上げて稼働できるようになります。

IBM Cloud DevOpsには、初めてOpen Toolchainを作成するためにコンセプトを理解するのに役立ついくつかのビルト・インテンプレートが付属しています。[Open Toolchain GitHubリポジトリ](https://github.com/open-toolchain)で、既存のテンプレートを確認することが出来ます。
# Open Toolchainテンプレートの構成要素
Open Toolchainテンプレートを構成するコンポーネントは以下のセクションで説明する以下の要素になります。
## Toolchain.yml
各Open Toolchainテンプレートには、少なくとも1つのメインとなるtoolchain.ymlファイルが含まれている必要があります。このファイルには統合するツールの記述をします。toolchain.ymlファイルには、テンプレートがレンダリングされて画面に表示される際のデフォルト値も記述します。
## 各種ツールとの統合、UIカスタマイズと国際化対応用のファイル群
テンプレート全体をtoolchain.ymlファイルだけに書き込むことも可能ですが、さまざまなツールを個別のファイルに分けてメインtoolchain.ymlファイルに含める方が便利な場合があります。テンプレートの任意の部分を別のファイルに分割し、file:ディレクティブを使用して参照させることができます。

以下は、toolchain.ymlをより小さなファイルに分割することを検討する必要がある2つの一般的な例です。

1. ツールのデフォルトUIをオーバーライドするカスタムUIを作成しているとき
2. テンプレートを国際化対応したい場合

## Githubリポジトリと.bluemixフォルダー
テンプレートをレンダリングするには、公開されているgitリポジトリにテンプレートを配置する必要があります。
リポジトリ内では、すべてのファイルが.bluemixと呼ばれる最上位フォルダの下に配置する必要があります。
# Open Toolchainテンプレートの開発の流れ
新しいプロジェクト用のOpen Toolchainテンプレートを開発する流れとして最も簡単な方法は、[Open Toolchain GitHubリポジトリ](https://github.com/open-toolchain)で、新しいプロジェクトで実装したいToolchainに最も親しい既存のテンプレートをカスタマイズして作成する方法です。
この章では[Kubernetes アプリの開発用Toolchainテンプレート](https://github.com/open-toolchain/secure-kube-toolchain)を元にプロジェクト用にカスマイズする手順をテンプレート開発の流れの一例として説明します。
※GitリポジトリにGitlabを選択した場合は既存リポジトリからのImport Code機能がないので[Kubernetes アプリの開発用Toolchainテンプレート](https://github.com/open-toolchain/secure-kube-toolchain)をローカルにCloneしてから取得したコンテンツを新規リポジトリにcommit&pushしてください。
## Gitリポジトリの準備
### 既存のToolchainテンプレートを元に新規のGitリポジトリを構築
1. リポジトリの作成画面アクセスし、以下の様に新規のリポジトリを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5259/b38819f8-b91d-b3dc-0062-95ede11574e0.png)

2. 新規リポジトリが作成された最下部のimport codeをクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5259/dc3f898f-c260-a4ad-bca6-91d1a6c95bbf.png)

3. **Your old repository’s clone URL**にKubernetes アプリの開発用ToolchainテンプレートのURL(https://github.com/open-toolchain/secure-kube-toolchain)を入力し、**Begin import**をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5259/1ca3d5d3-0826-3f95-64f0-9b097240b3f2.png)

4. メッセージに**Importing complete!**が表示されたらリンクをクリックしてリポジトリに戻る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5259/8af03ad5-9c00-9d8e-b72e-2b9371ce8ad7.png)

5. 以下のようにKubernetes アプリの開発用Toolchainテンプレートの内容がコピーされる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5259/34a5c0d3-9ec5-2dcc-888a-f452791c9b6e.png)

## テンプレートの作成方法
### 国際化対応言語の対象言語の選定と設定
国際化対応の仕組みは以下の流れで実現しています。

1. 対象となるロケールと各ロケールのメッセージが定義されたメッセージ・ファイルのパスが**toolchain.yml**の**messagesセクション**に定義する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5259/4ad9f248-4482-36f6-6b50-88a688ca861e.png)

2. **toolchain.yml**の**templateセクション**の各種設定の値にメッセージを直接記述せずに$refで読み込むメッセージのKeyを指定する。

```toolchain.yml
template:
  name:
    $ref: "#/messages/template.name"
``` 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5259/b1aceb42-b7f7-9572-6595-34c266a3ee49.png)

クライアントのブラウザの言語設定に設定されているロケールがlocale.ymlに存在しない場合はrootで指定されたメッセージ・ファイルが使用されるので、**root**は必ず設定する必要があります。

```locale.yml
---
root:
  $ref: ./nls/messages.yml
```

locale.ymlでインポートされたメッセージ・ファイルのメッセージは以下の3か所で使用することができます。

- toolchain.ymlの文字列
    - template.name
        - Toolchainの作成画面のテンプレート名として使用される
    - template.description
        - Toolchainの作成画面のテンプレートの説明として情報タブの説明欄で使用される
    - toolchain.template.getting_started
        - Toolchain作成後のGetting Startedエリアで使用される
- toolchain.ymlのformセクションで使用するUI表示
- toolchain.ymlのheaderセクションで指定するSVGファイル内のテキスト
    - 当SVGファイルはToolchain作成画面のToolchainの構成図として情報タブに表示される
    - SVGファイル内のテキストの国際化対応はheaderセクションでSVGファイルのlocalizeが有効になっている時だけ実施される。詳細は以下のマニュアルを参照。
        - https://github.com/open-toolchain/sdk/wiki/Template-File-Format#localizing-the-header-image

メッセージを国際化対応しない場合は各メッセージを以下のように直接記述することもできます。

```toolchain.yml
template:
  name: "Kubernetes アプリの開発"
```

### テンプレート・メタデータの更新
まず初めに**toolchain.yml**のテンプレート・メタデータの更新をします。対象は以下の通りです。

| # |	項目 | 変更箇所 |
|:--|:-------|:--------|
|1|テンプレート名|template.nameのメッセージ|
|2|テンプレートの説明|template.descriptionのメッセージ|
|3|テンプレートのアイコン|	template.iconのファイル名と画像そのもの|
|4|テンプレートのGetting Started文言|toolchain.template.getting_startedのメッセージ|
|5|テンプレートのToolchain構成図のSVGファイル|template.headerで指定しているSVGファイル|

### Toolchainで使用するツールの設定
続いてToolchainで使用するツールの設定を行います。
使用するツールの設定は以下のように**toolchain.yml**の**servicesセクション**で定義します。

```toolchain.yml	
services:
  sample-repo:
      service_id: githubpublic
      parameters:
        repo_name: "sample-{{name}}"
        repo_url: https://github.com/open-toolchain/node-hello-world
        type: clone
        has_issues: true
```

servicesセクションで設定する各項目の説明は以下の通りです。

|#|項目|説明|備考|
|:--|:--|:--|:--|
|1|名前|servicesセクション直下の要素|上記の例の場合はsample-repo|
|2|service_id|使用するサービスを識別するID文字列|使用可能なサービスは[こちら](https://github.com/open-toolchain/sdk/wiki/services.md)を参照|
|3|parameters|使用するサービスのパラメータ|各サービスのパラメータは[こちら](https://github.com/open-toolchain/sdk/wiki/services.md)を参照|


また、servicesセクションで指定したサービスが必須である場合は**toolchain.yml**の**templateセクション**の**requiredプロパティ**に以下のようにサービス名を設定します。

```toolchain.yml	
template:
  name:
    $ref: "#/messages/template.name"
  description:
    $ref: "#/messages/template.description"
  header: '![](toolchain.svg?localize)'
  icon: secure-lock-kubernetes.svg
  required:
    - build
    - repo
```
 
### UIカスタマイズ
パラメータを必要とするすべてのサービスには、セットアップページによって提供されるデフォルトのUIがあります。デフォルトのUIをそのまま使用できる場合UIカスタマイズは必要ありませんが、サービスとその組み合わせによってはデフォルトのUIをそのまま使用することができません。
例えば以下の図で示されるDelivery PipelineサービスのデフォルトのUIのままではパイプライン名とパイプライン・タイプを選択することしかできません。したがって、このToolchainで作成されるパイプラインではパラメータを使用することができません。今回作成するパイプラインがIKSクラスターにアプリケーションをデプロイするパイプラインだった場合、Toolchain作成時に対象のクラスターを選択させるようなシナリオでテンプレートを使用する場合は対象となるIKSクラスターを選択できるようにUIをカスタマイズする必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5259/b3e64f44-2d1a-e50c-e4e9-fd647ad78f01.png)

UIをカスタマイズする場合はtoolchain.ymlのformセクションに以下の項目を定義する必要があります。

|#|項目|説明|備考|
|:--|:--|:--|:--|
|1|service_id|使用するサービスを識別するID文字列|使用可能なサービスは[こちら](https://github.com/open-toolchain/sdk/wiki/services.md)を参照|
|2|schema|カスタムUIを提供するためのJSONファイルを$refで指定|JSONファイルの記述形式は[こちら](https://github.com/open-toolchain/sdk/wiki/Template-Custom-UI)を参照|
|3|parameters|カスタムUIで使用されるデフォルト値||

以下のtoolchain.ymlの例ではDelivery PipelineサービスのUIをschemaで参照しているdeploy.jsonでカスタマイズしています。

```toolchain.yml
form:
  pipeline:
    parameters:
      app-name: '{{services.repo.parameters.repo_name}}'
      prod-cluster-namespace: prod
    schema:
      $ref: deploy.json
```

## テンプレートの確認方法と公開方法
作成したテンプレートについてはIBM Cloud Toolchainのセットアップ用のURLに対して、パラメータでテンプレートのGitリポジトリのURLを渡すことで、ToolchainがGitリポジトリ内のテンプレートをレンダリングしてToolchainのセットアップページを表示してくれます。
ここではIBM Cloud　GitリポジトリのPrivateリポジトリにあるテンプレートを確認・公開する方法を説明します。

### Personal Access Tokenの作成（Privateリポジトリの場合）
Privateリポジトリの場合IBM Cloud Toolchainがテンプレートをレンダリングする際にGitリポジトリの認証が必要になるためPersonal Access Tokenの発行が必要です。

1. IBM Cloud GitにPersonal Access Tokenを発行したいユーザーでログインする

2. ログイン後に以下のようにアカウントの**Settings**をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5259/9d5c943c-872c-b2fb-e61b-066050303608.png)

3. 左メニューの**User Settings**より**Access Tokens**を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5259/77df6020-0f13-0cf3-05ce-a804222ff920.png)

4. **Name**にAccess Tokensの名前を入力し、Scopesに**api**、**read_repository**を設定し、**Create personal access token**をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5259/e90c3fc9-b06b-b705-0d65-7d070a94c5a9.png)

※Personal Access Tokenには最低限**api**、**read_repository**の権限が必要。
※Toolchain作成ボタンをGitリポジトリのREADMEに埋め込む場合はPersonal Access TokenをURLパラメータとして埋め込む必要があるため、TokenをREADME.mdに記述することになり、リポジトリにアクセスできるユーザーはだれでもTokenを取得できてしまうのでセキュリティの観点からPersonal Access Tokenは**write_repository**権限が付与されていないものを設定したほうが良い。

### テンプレートの確認
作成したテンプレートについてはIBM Cloud Toolchainのセットアップ用の以下のURLに対して、パラメータでテンプレートのGitリポジトリのURLを渡すことで、ToolchainがGitリポジトリ内のテンプレートをレンダリングしてToolchainのセットアップページを表示してくれます。

`https://console.ng.bluemix.net/devops/setup/deploy?repository=YOUR_GIT_REPO_URL`

GitリポジトリのURL部分はURLのクエリ文字列なのでURLエンコードする必要があります。
具体例は以下のようなURLになります。
`https://cloud.ibm.com/devops/setup/deploy?repository=https%3A%2F%2Fgithub.com%2Fstrada501%2Fkube-toolchain-gitops`


IBM Cloud Toolchainのセットアップ用のURLにはその他にも指定可能なパラメータがあります。
詳細は以下のマニュアルを参照してください。
https://github.com/open-toolchain/sdk/wiki/Toolchain-Creation-page-parameters

なお、作成したテンプレートをGitのPrivateリポジトリで管理している場合、IBM Cloud Toolchainがテンプレートをレンダリングする際にGitリポジトリの認証が必要になるためrepository_tokenパラメータに3.3.1で作成したPersonal Access Tokenを指定する必要があります。
具体例は以下となります。
`https://cloud.ibm.com/devops/setup/deploy?repository=https%3A%2F%2Fjp-tok.git.cloud.ibm.com%2FSTRADA%2Fkube-toolchain-gitops.git&repository_token=xxxxxxxxxxxxxxxxxxxx`

### Toolchain作成ボタンの埋め込み
既存のOpen Toolchainテンプレートには下図のようにREADMEにToolchain作成ボタンが配置されており、Gitリポジトリのトップページからボタンをクリックすることで簡単にテンプレートを使用したToolchainの作成ができるようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5259/64f435b6-3399-c9a7-a082-28a3b71cb3ff.png)


README.mdの以下の部分を変更することでボタンのリンク先を変更します。

```README.md
### To get started, click this button:
[![Create toolchain](https://cloud.ibm.com/devops/graphics/create_toolchain_button.png)](https://cloud.ibm.com/devops/setup/deploy?repository=https%3A%2F%2Fgithub.com%2Fstrada501%2Fkube-toolchain-gitops&env_id=ibm:yp:jp-tok)
```

# 参考資料
- Open Toolchainテンプレートのマニュアル
    - Open Toolchain Templates SDK
        - https://github.com/open-toolchain/sdk/wiki#open-toolchain-templates-sdk
- Open Toolchainカスタム・テンプレート開発のチュートリアル
    - Create a template for a custom toolchain
        - https://www.ibm.com/cloud/architecture/tutorials/create-a-template-for-a-custom-toolchain