IBM Cloud：Certificate ManagerからSecrets ManagerへのSSL証明書移行方法

# 概要
本記事では、Certificate Managerにてデプロイ/アップデート自動化登録していたSSL証明書をSecrets Managerへ移行する手順について記載します。手順は以下のIBM Cloud docsに従います。
[証明書を Certificate Manager からマイグレーションする方法](https://cloud.ibm.com/docs/secrets-manager?topic=secrets-manager-migrate-from-certificate-manager)



Certificate Manager/Secrets Managerの概要については以下をを参照ください。
[IBM Cloud：Secrets Managerの概要](https://qiita.com/takason/items/3860854b54e0dd4550d7)

# Secrets Manager の制限と考慮事項

開始する前に、以下の項目とサービスの制限をよく確認してください。これらは、Secrets Manager への統合を実行する時の操作に影響する可能性があります。

> - 現時点で、Secrets Manager は、1 つの IBM Cloud アカウントにつき 1 インスタンスという制限が適用されている無料のサービスです。Secrets Manager の価格設定とサービス制限は変更される可能性があります。移行期間に、Secrets Manager サービス・インスタンスを作成して、Certificate Manager から既存の証明書をマイグレーションする作業を開始できます。Secrets Manager では、インスタンスごとに保管できるシークレットまたは証明書の総数に対する制限が適用されることはありません。
>
>- Secrets Manager インスタンスのプロビジョニングの完了までに、5 分から 8 分かかります。 Certificate Manager とは異なり、Secrets Manager はシングルテナントのオファリングです。インスタンスのプロビジョニング中に、Secrets Manager によって、そのサービス・インスタンスだけに割り当てられるさまざまな専用リソースが作成されます。Certificate Manager のインスタンスを動的にプロビジョンしている場合に、Secrets Manager インスタンスでも同じことを計画しているのであれば、Secrets Manager のプロビジョニングは非同期で、完了までに 5 分から 8 分かかることに留意してください。
>
>- Secrets Manager では、シークレット・グループを使用して、シークレットへのアクセス権限をきめ細かく管理します。 Certificate Manager では、個々の証明書に対してアクセス・ポリシーを作成できます。Secrets Manager では、1 つ以上の証明書が含まれているシークレット・グループに対してアクセス・ポリシーを設定できます。さらに、Secrets Manager では、証明書をダウンロードするための読み取り専用アクセスを提供する SecretsReader IAM 役割がサポートされています。
>
 >- Secrets Manager は、サービス・インスタンスごとに固有のエンドポイント URL を提供します。 Certificate Manager とは異なり、Secrets Manager はサービス・インスタンスの固有のエンドポイント URL を構成します。Secrets Manager のエンドポイントは `appdomain.cloud` ドメインを使用するのに対し、Certificate Manager は `cloud.ibm.com` ドメインを使用します。詳しくは、Certificate Manager と Secrets Manager の API の資料を参照してください。
Certificate Manager の API と Secrets Managerの API は構造が異なります。 Certificate Manager を使用して証明書をプログラマチックに管理している場合は、[Secrets Manager の API](https://cloud.ibm.com/apidocs/secrets-manager) の資料を確認して、証明書の移動が現在の操作環境に与える影響を把握してください。

# 移行手順について
Certificate ManagerからSecrets ManagerへのSSL証明書移行手順は以下の大きく3つで構成されます。
本記事では手順3から実施します。
1. Secrets Managerインスタンスの作成
1. シークレット・グループによるアクセス階層の決定
1. マイグレーション・スクリプトの実行

## 前提条件
- Macbook Air Retina にて実行しました。
- 適切な権限が付与されたユーザーのIBM Cloud API キーを発行している必要があります。
Certificate Managerサービスにおいて、`Viewer platform role`と `Reader service role`が最低限必要になります。
現在割り当てられている権限は、https://cloud.ibm.com/iam/roles にて「Certificate Manager」で検索すると確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2199676/7b659a05-ea74-dec9-63ba-22de18417a45.png)

API Keyの発行手順については以下を参照ください。
[IBM Cloud APIKEYの作成(取得)方法](https://qiita.com/nishikyon/items/fa8b951267efbe911fe7)

# 手順1：Secrets Managerインスタンスの作成
本記事では省略します。以下をご覧ください。
[IBM Cloud：Secrets Managerの概要](https://qiita.com/takason/items/3860854b54e0dd4550d7)

# 手順2：シークレットグループの作成
本記事では省略します。以下をご覧ください。
[IBM Cloud：Secrets Managerの概要](https://qiita.com/takason/items/3860854b54e0dd4550d7)

# 手順3：マイグレーション・スクリプトの実行
## 移行前の準備
### 1. Node.jsをダウンロード
以下のサイトより、Node.jsをダウンロードします。
https://nodejs.org/en/download/

### 2. リポジトリをダウンロード
以下を実行し、リポジトリをダウンロードします。
```
$ git clone https://github.com/ibm-cloud-security/certificate-manager-to-secrets-manager.git
$ cd git clone certificate-manager-to-secrets-manage
```

### 3. 必要なパッケージをインストール
npmを使用しパッケージインストールします。
```
$ npm install
```
## マイグレーション・スクリプトの実行
マイグレーションスクリプトには以下の5種類があります。
1. Certificate Managerをリスト
2. 証明書をSecrets Managerインスタンスへコピー
3. 全てのインポートされた証明書を、Certificate ManagerインスタンスからSecrets Managerインスタンスへコピー
4. Certificate ManagerでマッチするLet’s Encrypt証明書をSecrets Managerでオーダー
5. Certificate Managerでマッチする全てのLet’s Encrypt証明書をSecrets Managerでオーダー

### 1. Certificate Managerインスタンスをリスト
スクリプトのディレクトリに移動後に環境変数を設定、スクリプトを実行します。
```
$ cd [cm_migration.jsのあるディレクトリ]
$ export CM_APIKEY=[API Key]
$ npm run cm_inventory

> secrets-manager-cm-migration-scripts@1.0.0 cm_inventory
> node -e 'require("./cm_migration.js").main({"SCRIPT_NAME":"cm_inventory"})'

1/25 instances completed
{
  'crn:v1:bluemix:public:cloudcerts:jp-tok:a/xxxxxxxxxxxxxxxx::': {
    region: 'jp-tok',
    resource_group_id: 'xxxxxxxxxxxxxxxxxxxxxxx',
    name: 'Certificate Manager-xx',
    crn: 'crn:v1:bluemix:public:cloudcerts:jp-tok:a/xxxxxxxxxxxxxxxxxx::',
    is_private_only: false,
    BYOK: { kms_info: 'none', tek_id: 'none' },
    managed_certs_count: 1,
    notification_channels_count: 0,
    list_certs_ids: [
      'crn:v1:bluemix:public:cloudcerts:jp-tok:a/xxxxxxxxxxxxxxxx:certificate:xxxxxxxxxxxxxxxxxxx'
    ]
  },
.
.
.

}

$
```

### 2. 単一証明書をCertificate ManagerインスタンスからSecrets Managerインスタンスへコピー
`cm_migration.js`スクリプトは単一の証明書を、Certificate Managerインスタンスから指定されたSecrets Managerインスタンスにコピーします。

#### 注意事項 (スクリプト2〜4で共通)
- Secrets Managerはスペースを含むSecrets名をサポートしていません。コピー対象の証明書名にスペースが含まれている場合、ダッシュ (-) に置き換えます。
- このスクリプトは、プライベート・サービス・エンドポイントを通じてのみアクセス可能なインスタンスに対して実行することはできません。
- 正しいアクセス権限のIBM Cloud APIキーを持っていることを確認してください。
    - 最低限必要なアクセス権
        - Certificate Managerサービスの Writer サービス・ロール
        - Secrets Managerサービスの Writer サービス・ロール。

#### スクリプト実行
以下の環境変数を設定し、npmを実行します。

```
$ export CM_APIKEY=<certificate managerにアクセス可能なAPIキー>
$ export SM_APIKEY=<secrets managerにアクセス可能なAPIキー>
$ export CM_INSTANCE_CRN=<certificate_managerインスタンスのCRN>
$ export SM_INSTANCE_CRN=<secrets_managerインスタンスのCRN>
$ export CERTIFICATE_ID=<証明書のUUID>
$ (option) export SECRET_GROUP_NAME=<Secrets group名>
```

それぞれのCRNはポータルのサービス詳細画面 → Settings より確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2199676/e25b7ace-1265-8c02-bb6c-0d1f14b4d324.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2199676/d594d620-f333-27ba-d4d2-73dee27918ce.png)
証明書のUUIDは、ポータルのサービス詳細画面 → 証明書一覧にて対象証明書をクリック → 証明書CRNの最後のコロンから後ろ を使用します。（画像赤線部分）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2199676/5e3ddbb5-6af9-0770-3c86-7a45ce7e4540.png)


スクリプトを実行します。
```
$ npm run cm_cert_copy

> secrets-manager-cm-migration-scripts@1.0.0 cm_cert_copy
> node -e 'require("./cm_migration.js").main({"SCRIPT_NAME":"cm_cert_copy"})'

Certificate migrated successfully!
$
```
無事コピーできました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2199676/5a174a7d-357f-1c4d-0145-b278c1941148.png)


### 3. 全てのインポートされた証明書をCertificate ManagerインスタンスからSecrets Managerインスタンスへコピー
このスクリプトを使用して、Certificate Managerインスタンスで管理されているインポートされたすべての証明書を、アカウント内の宛先Secrets Managerインスタンスにコピーします。


#### スクリプト実行
スクリプト1と同様に環境変数を設定します。
```
$ export CM_APIKEY=<certificate managerにアクセス可能なAPIキー>
$ export SM_APIKEY=<secrets managerにアクセス可能なAPIキー>
$ export CM_INSTANCE_CRN=<certificate_managerインスタンスのCRN>
$ export SM_INSTANCE_CRN=<secrets_managerインスタンスのCRN>
$ (option) export SECRET_GROUP_NAME=<Secrets group名>
```

スクリプトを実行します。
```
$ npm run cm_instance_copy
```
### 4. Certificate Managerでマッチする単一Let’s Encrypt証明書をSecrets Managerでオーダー
このスクリプトは、対象の Secrets Manager インスタンスに 1 つのパブリック証明書をオーダーします。この証明書は、指定されたCertificate ManagerインスタンスおよびIBM Cloudアカウントにある既存のLet's Encrypt証明書と一致する必要があります。


#### スクリプト実行
```
$ export CM_APIKEY=<certificate managerにアクセス可能なAPIキー>
$ export SM_APIKEY=<secrets managerにアクセス可能なAPIキー>
$ export CM_INSTANCE_CRN=<certificate_managerインスタンスのCRN>
$ export SM_INSTANCE_CRN=<secrets_managerインスタンスのCRN>
$ export CERTIFICATE_ID=<証明書のUUID>
$ export CA_CONFIGURATION_NAME=<CA構成名>
$ export DNS_PROVIDER_CONFIGURATION_NAME=<DNSプロバイダー構成名>
$ (option) export SECRET_GROUP_NAME=<Secrets group名>
```
```
$ npm run sm_public_cert
```

### 5. Certificate Managerでマッチする全てのLet’s Encrypt証明書をSecrets Managerでオーダー
このスクリプトは、対象のSecrets Managerインスタンスにあるすべてのパブリック証明書をオーダーします。証明書は、指定されたCertificate ManagerインスタンスおよびIBM Cloudアカウントにある既存のLet's Encrypt証明書と一致する必要があります。


#### スクリプト実行
```
$ export SCRIPT_NAME=sm_instance_public_cert
$ export CM_APIKEY=<certificate managerにアクセス可能なAPIキー>
$ export SM_APIKEY=<secrets managerにアクセス可能なAPIキー>
$ export CM_INSTANCE_CRN=<certificate_managerインスタンスのCRN>
$ export SM_INSTANCE_CRN=<secrets_managerインスタンスのCRN>
$ export CERTIFICATE_ID=<証明書のUUID>
$ export CA_CONFIGURATION_NAME=<CA構成名>
$ export DNS_PROVIDER_CONFIGURATION_NAME=<DNSプロバイダー構成名>
$ (option) export SECRET_GROUP_NAME=<Secrets group名>
```
```
$ npm run sm_instance_public_cert
```