Key Protect サービスを使用して IBM Clouid DevOpsツールチェーンで使用する秘密情報を効率的に共有する 

# シナリオ
IBM Cloud の Toolchain および Continuous Delivery サービスを使用してデリバリー・パイプラインを構成している。パイプラインが多数あるため複数のエンジニアで分担してパイプラインを構成したり編集したりしているが、パイプラインの構成の中で必要となる秘密情報をエンジニアの間で共有する方法に不満がある。たとえばデプロイ先のOpenShiftクラスターにアクセスするための IBM Cloud API Key など、一度だけ生成して参照するタイプの秘密情報を安全に共有しようとすると非効率となってしまう。


# 環境および関連するサービス
- IBM Cloud (cloud.ibm.com)
- Key Protect
- Continuous Delivery
- Toolchain
- Red Hat OpenShift on IBM Cloud


# 解決策
Toolchain と Key Protect の連携機能を使用する。Key Protect に秘密情報を格納し、その値を参照できるようにToolchainを構成するエンジニアとToolchainサービスにアクセス権限を割り当て、ツールチェーンと Key Protect のツール統合を構成する。
ツールチェーンを編集するエンジニアは Key Protect に登録された秘密鍵を使用してパイプラインを構成する。パイプラインの構成の際にはKey Protectから参照した秘密鍵は中身をマスクした状態でそのまま利用することができるため、APIキーのように本来は作成した１ユーザーのみが知るべき情報を隠した状態で、その秘密情報を複数のエンジニアで共有して利用することができる。

![000_dp_secret_value_retrieved_sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252650/1158476c-d15d-f775-9f2f-32b405bc65e6.png)



# 構成手順

この記事では DevOps Toolchain に Red Hat OpenShift on IBM Cloudへのデプロイメントを行うことができるデリバリー・パイプラインを構築するために、
OpenShiftクラスターへの適度なアクセス権を持つサービスIDを生成し、そのAPIキーを秘密情報として Key Protect サービスに格納し、エンジニアがそれを利用する手順を説明する。

1. Toolchainで利用するKey Protectサービスのインスタンスをオーダーする
1. 「アクセス(IAM)」設定で Key Protect サービスのインスタンスへのアクセス権をエンジニアに割り当てる
1. Red Hat OpenShift on IBM CloudにデプロイするためのサービスIDを作成し、権限を割り当てる
1. サービスIDとして認証するためのAPI Keyを生成する
1. API Key を Key Protect に格納する
1. DevOps Toolchainのインスタンスを作成して、Key Protectの連携を構成する
1. Delivery Pipelineを作成して、Key Protect から秘密情報を利用する


## 1. Toolchainで利用するKey Protectサービスのインスタンスをオーダーする

IBM Cloud カタログから [Key Protect](https://cloud.ibm.com/catalog/services/key-protect) サービスを選択して新しいインスタンスをオーダーする。
ツールチェーンを構成するエンジニアチームにはこのKey Protectインスタンスへの管理権限を与えることになるためツールチェーンで利用するための専用のインスタンスを作成することを推奨。
加えて、ツールチェーン用のインスタンスを独自に作ることで、無償枠（2021/01/01 現在、キー数が20までは無償で利用可能)の範囲で利用することもできる。

- リージョン: _<ツールチェーンを利用するリージョン>_
- サービス名: 任意 (KeyProtect-toolchain など)
- リソース・グループ: _<ツールチェーンを配置するリソースグループ)_
- タグ: <任意>
- Allowed network policy: Public and private (Private only にした場合は後続の手順であるWebブラウザーからの鍵登録ができないため当記事ではPublic and privateを使用する) 

![001_order_keyprotect.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252650/b77ff3f3-3cae-b468-dd00-0c5e0a347465.png)



## 2. 「アクセス(IAM)」設定で Key Protect サービスのインスタンスへのアクセス権をエンジニアに割り当てる

a. IBMの管理画面から「管理」>「アクセス(IAM)」を選択して、Key Protectを利用するエンジニア個々人、あるいはそのエンジニアが属するIBM CloudのIAMアクセス・グループにアクセス権を設定する。

- IAM サービス
- どのタイプのアクセス権限を...: Key Protect
- どのリソースにアクセス権限を...: 選択された属性に基づくリソース
- Instance ID: _Step 1 で作成した Key Protect インスタンスを選択_

![002_keyprotect_access_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252650/e6110480-a38c-d924-371b-41b59102b129.png)

b. 権限としては以下を指定する。
- プラットフォーム・アクセス: 管理者 
- サービス・アクセス: 管理者

なお、Key Protectから秘密情報を参照するだけであれば以下の権限を構成することでも対応可能ではある。
ただしこの権限ではツールチェーンと Key Protectサービスの連携の構成においてアクセスポリシーの構成が保存できずに連携の構成は失敗するため、管理者権限を持つユーザーが統合を構成する必要がある。
- プラットフォーム・アクセス: ビューアー
- サービス・アクセス: ReaderPlus


## 3. Red Hat OpenShift on IBM CloudにデプロイするためのサービスIDを作成し、権限を割り当てる

ツールチェーンやパイプラインを通じてOpenShiftクラスターにデプロイするコンテナをビルドしたり、デプロイしたりする場合には、OpenShiftクラスターやコンテナ・レジストリーなどへの参照、編集権限を持つユーザーが必要となる。一般の利用においては特定の個人に紐づかないサービスIDを定義して、そのサービスIDに権限を付与し、そのサービスIDを利用して認証および認可を行うようにツールチェーンを構成する。

a. [IBM Cloudドキュメント](https://cloud.ibm.com/docs/account?topic=account-serviceids)に従ってサービスIDを作成する

![003_create_service_id.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252650/ad5bc077-7fd7-020e-6266-726957a96774.png)

b. サービスIDに以下のようなIAMアクセスポリシーを付与する

- IAMサービス > Kubernetes Service
    - すべてのリソース (or 指定したクラスター)
    - プラットフォーム・アクセス: ビューアー
    - サービス・アクセス: ライター

- IAMサービス > Container Registry
    - すべてのリソース (or 指定したnamespaceなど)
    - プラットフォーム・アクセス: ビューアー
    - サービス：アクセス: リーダー、ライター (ライターにはリーダー権限が含まれないため両方とも指定) 

- IAMサービス > Toolchain
    - プラットフォーム・アクセス: エディター (DevOps Insightを使用する場合)

- IAMサービス > Key Protect
    - 選択された属性に基づくリソース > Instance ID
    - プラットフォーム・アクセス: ビューアー
    - サービス：アクセス: ReaderPlus

- アカウント管理 > IAM Identity Service
    - プラットフォーム・アクセス: エディター
    - サービス：アクセス:  なし

- IAMサービス > サービス・アクセス権限なし
    - リソース・グループ > _(アクセスさせるリソースグループを選択)_
    - リソース・グループ・アクセス: ビューアー


![004_service_id_accesspolicy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252650/efe9de11-ac9f-cb64-8262-cc4416f3467e.png)


## 4. サービスIDとして認証するためのAPI Keyを生成する

IAM 管理画面でサービスIDを選択して「APIキー」タブからAPIキーの生成を行う。生成したAPIキーをダウンロードして保存する。

![005_apikey.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252650/b32c32e7-d7c7-b91a-688e-102697c82f82.png)





## 5. API Key を Key Protect に格納する

a. 任意のbase64エンコードプログラム (Linuxのbase64コマンドなど)でAPIキーをBase64エンコードし、その値を確認する

```shell:shell
echo -n "<API Key>" | base64
```

b. Key Protect 管理画面を開き、鍵の管理タブを選択して、「鍵の追加」ボタンを押す
c. 以下のオプションを指定して、「鍵のインポート」ボタンを押して登録を行う
- 「自分の鍵のインポート」
- 鍵タイプ:「標準鍵」
- 名前: 任意
- 鍵素材: Base64エンコードした鍵の文字列

![006_add_key_to_keyprotect.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252650/8509e59d-b43b-7000-7a74-3ad5a23ab32e.png)



## 6. DevOps Toolchainのインスタンスを作成して、Key Protectの連携を構成する

a. Toolchainを作成する
b. 「ツールの追加」を選択して Key Protect を選択する
c. Step 1 で作成した Key Protect のサービスを選択して、「統合の作成」を選択する

![007_inegrate_toolchain_keyprotect.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252650/c54b0980-410d-40d3-b085-0ef88028394a.png)

統合を構成したエンジニアの権限が不足している場合は統合に失敗する(統合を行うためにはKey Protect サービスに対するアクセスポリシーの作成権限が必要)。


## 7. Delivery Pipelineを作成して、Key Protect から秘密情報を利用する

a. Delivery Pipeline をツールチェーンに追加し、Pipeline にステージを追加する
b. ステージの属性で秘密情報が必要な項目をクリックする
c. 秘密情報の入力ダイアログが表示されるため、入力欄の右に表示されている鍵のアイコンをクリックする

![008_dp_input_key.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252650/c8f111a5-6baa-1998-6c38-912c367a9861.png)

d. Key Protect の統合と Key Protect の秘密鍵名を選択して、「OK」をクリックする

![009_dp_select_key_in_keyprotect.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252650/7a2020f2-10d7-e151-3580-d851c58d7952.png)

e. Key Protect から秘密鍵の値が取り出されて入力されるため、処理を続ける

![010_dp_secret_value_retrieved.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252650/2cfbebb4-8a3a-1ff3-39b9-9af6eeed4ecd.png)



# 参考資料
IBM Cloud 資料 > Continuous Delivery
[Key Protectの構成](https://cloud.ibm.com/docs/ContinuousDelivery?topic=ContinuousDelivery-keyprotect)