【IBM Cloud】Virtual Server for VPC上のPrivate Path機能を使ってサービスを公開する流れ

## はじめに
今回は2024年末にGAされたVPCのPrivate Path機能を使ってサービスを公開する流れについて検証しましたので、その内容を整理しています。
Private Pathを使用することで、コンシューマー（エンドユーザー）はインターネットを経由せずに、直接IBM Cloudを介してサービスにアクセスすることが可能になるため、セキュアなサービス利用が可能になります。
本来はプロバイダーがIBM Cloud上にアプリやサービスを公開し、コンシューマーが利用することを想定していますが、検証の中でプロバイダー役として直接サービスを作成し、それをコンシューマー役としてアクセスする全体の流れが含まれています。
![スクリーンショット 2025-02-14 16.07.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/42479705-412b-4f15-8c27-0fb3bac3ddba.png)


## 前提条件
今回の検証には以下の前提条件があります。
- プロバイダーとコンシューマーの両方のリソースをホストするためのIBM Cloud有料アカウントが必要です。
- プロビジョニングされたVirtual Server Instance（VSI）に接続するためのVPC用の[SSH Key](https://cloud.ibm.com/docs/vpc?topic=vpc-ssh-keys&interface=ui)が必要です。
- サービスの作成やアクセスには、Infrastructure as Code（IaC）を実現するためのTerraformベースの自動化ツールである「IBM Cloud Schematics（Schematics）」を利用します。それによってPrivate Pathサービスを含むプロバイダー側の環境、およびコンシューマー側の環境を自動的に構築して接続の確認します。
    - Schematicsのリージョンは2025年現在、`ダラス（us-south）`、`ワシントン（us-east）`、`フランクフルト（eu-de）`、`ロンドン（eu-gb）`の４箇所のみとなりますが、今回は`フランクフルト（eu-de）で実施しました。`
- 今回使用するサービスはnginxベースのWebアプリサーバーです。
:::note warn
検証に使用するSSH KeyとVSIインスタンスは同じリージョンである必要があります。そのため、SSH Keyも`フランクフルト（eu-de）`に作成ください。
:::

## プロバイダーとしてのサービス作成の流れ
まずは上記の通りプロバイダーとしてIBM Cloudにサービスを公開するため、Schematicsでワークスペースの作成、テンプレートの指定を行います。
`コンソール`→`ナビゲーション・メニュー`→`Platform Automation`→`Schematics`→`Terraform`にアクセスします。
![スクリーンショット 2025-02-14 16.11.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/dcbf338c-cab4-410e-9356-1d97d9e279f7.png)
Terraform画面が表示されたら、`ワークスペースの作成`をクリックします。
![スクリーンショット 2025-02-14 16.12.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/545e95ec-cdd8-4141-85a8-acb46cd100be.png)
ワークスペース作成画面にてテンプレートを指定します。今回はすでにGithubに公開されているTerraformテンプレートのURLを使用しますので以下のURLを入力ください。
また、Terraformのバージョンを指定しますが、今回は`terraform_v1.5`で実施しています。
設定が終わったら`次へ`をクリックします。
```shell:プロバイダー用リポジトリのURL
https://github.com/IBM-Cloud/vpc-tutorials/tree/master/vpc-pps-basics/provider
```
![スクリーンショット 2025-02-14 16.18.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/5d645b13-ce6a-46e8-b47d-de3f32d848ce.png)

::: note warn
`完全リポジトリーを使用する`には必ずチェックを入れてください。
:::
次は詳細を入力しますが、ここでワークスペース名とリソースグループ、リージョンを選択しいます。
ワークスペース名はなんでも大丈夫ですが、今回はプロバイダー役のワークスペースだとわかりやすくするために`pps-provider`にしています。
また、リージョンも前提で記載した通り、フランクフルトにしています。
設定が完了したら`次へ`をクリックします。
![スクリーンショット 2025-02-14 16.28.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/1ec88557-3321-4b8c-a94c-7dbb9a19e0ef.png)
全ての設定が完了したら`作成`をクリックします。
![スクリーンショット 2025-02-14 16.35.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/986e3b63-ff51-49bd-a12f-a18de7dd9570.png)
作成されたワークスペースの`設定`→`変数`項目にて変数の修正を行います。前提条件として作成したSSH Keyやリージョンなどを指定します。デフォルトで値が設定されていますが、項目の右側の`︙`にて編集を行います。
SSH Keyの値は`existing_ssh_key_name`にて設定できますが、ここではSSH KeyのIDや指紋、公開鍵などではなく、SSH Keyのインスタンス名をそのまま入力する必要があります。
Schematicsのワークスペースが作成されたら、テンプレートの設定を行います。
![スクリーンショット 2025-02-14 16.38.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/7a37a09e-dcd4-4d8e-b0e6-aa5dc1f82552.png)
![スクリーンショット 2025-02-14 16.38.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/1844a796-7018-45fc-a634-9be6162aab9c.png)

:::note warn
繰り返しとなりますが、SSH Keyのリージョンとワークスペースのリージョンは同じリージョンである必要があります。もし別のリージョンの場合、プランの適用が失敗になります。
なお、今回使ったアカウントの事情上、リソースグループの設定も行う必要がありました。似てような状況の方は必要に応じてリソースグループの変更も実施ください。
:::

変数を全て設定したら、上端の`プランの適用`をクリックします。
プランを適用することによって、スクリプト化されたコードが走り、変数で設定した項目通りにインスタンスがデプロイされるようになります。
なお、この作業にはデプロイのため数分ほど時間がかかる場合があります。
![スクリーンショット 2025-02-14 14.09.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/76cf02f7-20fd-45ff-833f-f743f23ab697.png)
デプロイが完了したらリソース・リストに`pps`という名前やタグでインスタンスがデプロイされていることがわかりますが、主に次のリソースが作成されます。
- 1つの仮想プライベートクラウド（VPC）
- 3つのサブネット（各ゾーンに1つずつ）
- 各サブネットに少なくとも1つの仮想サーバーインスタンス
- すべての仮想サーバーインスタンスを含むバックエンドプールで構成されたプライベートパスNLB
- Private Path Service
![スクリーンショット 2025-02-14 14.11.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/e9905d9c-74f0-4938-ae45-c524112ff98e.png)
なお、作成されたVSIにアクセスし、ロードバランサーやPrivate Pass、SSH鍵がうまく紐づいたか確認ください。
![スクリーンショット 2025-02-14 14.11.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/ded5b72d-58a4-493f-812d-fbc7e118e33c.png)
![スクリーンショット 2025-02-14 14.13.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/4caf0049-a547-4685-9e86-c070364eb2a1.png)
Private Passの詳細に入るとCRNとサービス・エンドポイントを確認することができます。後ほどサービス公開の際に使用することになるので別途メモしてください。
![スクリーンショット 2025-02-14 14.13.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/acda816e-72e2-4e8e-bfc3-881227f68335.png)
ここまで実施したらプロバイダーとしてのサービス作成の流れは完了です。

## コンシューマーとしてのサービスへアクセスの流れ
次はコンシューマーとしてのSchematicsワークスペースを作成します。全体的な流れはプロバイダー用のワークスペース作成と同じです。
以下のコンシューマー用リポジトリやTerraformのバージョン（terraform_v1.5）、ワークスペース名はコンシューマー用とわかりやすく`pps-consumer`、リージョン（フランクフルト）などを入力し、`作成`ボタンにてワークスペースを作成ください。
```shell:コンシューマー用リポジトリのURL
https://github.com/IBM-Cloud/vpc-tutorials/tree/master/vpc-pps-basics/consumer
```

![スクリーンショット 2025-02-14 16.58.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/7d068677-3bc3-49b8-8b58-03a9af681150.png)
![スクリーンショット 2025-02-14 16.58.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/aa14489d-afc4-41fe-a17b-db7769638b27.png)

また、ワークスペースが作成されたら、プロバイダー用ワークスペースと同様、SSH Keyやリージョン、リソースグループなどを入力します。
なお、その際に`provider_crn`変数にて、上でメモしたCRNを入力します。
![スクリーンショット 2025-02-14 17.06.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/c0c61c48-0457-4b86-b58c-3339c1617c1c.png)

その後、`プランを適用`をクリックし、インスタンスデプロイを待ちます。
デプロイが完了したら、リソース・リストに名前やタグが`consumer`になったインスタンスが追加されていることがわかります。
なお、コンシューマー用インスタンスにはいかが作成されます。
- 1つの仮想プライベートクラウド（VPC）
- 2つのサブネット
- 各サブネットに1つのVSI
- プライベート パス サービス CRN と各サブネットに 1 つの IP アドレスが構成された 1 つのVirtual Private Endpoint（VPE）
![スクリーンショット 2025-02-14 14.30.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/d345c16b-0c08-4574-8721-d34d4e029d66.png)

この段階ではまだコンシューマーがプロバイダー提供のアプリにアクセスできない状況です。
Private Path サービスへの接続要求が審査され、許可されるのを待機している段階となります。
そのため、VPC用の仮装プライベート・エンドポイント・ゲートウェイにアクセスしたら`状況`が`処理待ち`になっていることを確認ください。
![スクリーンショット 2025-02-14 14.31.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/2a1d1d54-8c9d-46c0-a9b7-d78670d0d4ee.png)
ここまでできたらコンシューマー用の作業は完了です。

## コンシューマーのリクエストの承認
次はプロバイダー役に戻り、前の段階でコンシューマーが設定したアクセス申請を承認する必要があります。
Private Path Serviceリストに移動し、Schematicsで作成されたPrivate Pathの詳細画面にアクセスします。
その後`接続要求`カテゴリーにて新たに入った承認待ちのリクエストを確認し、`︙`にて許可をクリックします。
![スクリーンショット 2025-02-14 14.32.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/a59e833e-1f5c-4403-8b43-af69ef5d0b1c.png)
![スクリーンショット 2025-02-14 14.32.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/63f1a6e6-b5ec-42e5-865b-e3518ae4358a.png)
接続要求画面が表示されたら、再度`許可`をクリックします。
![スクリーンショット 2025-02-14 14.33.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/d31667b5-3d6e-4a5d-9cea-f935528bfea6.png)
その後、先ほどのVPC用の仮装プライベート・エンドポイント・ゲートウェイにアクセスすると`処理待ち`が`安定`に変わっていることがわかります。
![スクリーンショット 2025-02-14 14.33.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/ef5a427b-07cd-4315-a503-8424cdeb8381.png)

## コンシューマーからプロバイダーへの接続テストの流れ
プロバイダーから接続承認を行い、プライベートエンドポイントが有効になったら、最後にテストを行います。
仮装サーバーインスタンス（VSI）にアクセスし、割り当てられているFloating IP（浮動IP）を見つけます。
上記の通りVSIは３台作成されますが、その中で２台にFloating IPが割り当てられています。その二つのFloating IPをpingコマンドにて確認し、通信できるFloating IPを使用します。
私の場合は、以下の画面の中、`vpc-pps-consumer-vsi-eu-de-2`がpingが飛んでいました。
```shell:Floating IPの確認
ping <floating-ip>
```
![スクリーンショット 2025-02-14 14.38.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/1efaf6fa-7948-4776-a4a3-e8c066c2266f.png)

pingコマンドにて通信できるFloating IPを見つけたら、次はSSH Keyで仮装サーバーにログインします。
```shell:SSH Keyを使った仮装サーバーへのログイン
ssh root@<floating-ip>
```
ログインできたら、サービスエンドポイントを呼び出してプロバイダー提供のアプリにアクセスします。
```
curl http://vpc-pps.example.com
```
```shell:結果
Hello world from vpc-pps-provider-vsi-eu-de-1
```
:::note
もし以下のようにアクセスが失敗する場合、VSIに登録したSSH Keyが正しく指定されていない可能性があります。その時は以下の -i コマンドにてSSH Keyを指定する必要があります。
```shell:ログイン失敗結果 ①
moonsy@moon ~ % ssh root@xxx.xxx.xxx.x
root@161.156.168.6: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
```
``` shell:結果 ① の対処法：-i コマンドにてSSH Keyの指定
ssh -i ~/.ssh/key-moon-de_rsa.prv root@xxx.xxx.xxx.x
```
なお、上記のコマンドを入力しても再度以下のようなエラーが表示されることがあります。これはSSH KeyのPermissionが緩すぎるため、SSHが鍵を無視している状況です。
その場合には`chmod 600`コマンドにて解決できますが、こちらはSSH Keyの読み書きは所有者のみ可能にするPermissionを強化するコマンドです。
```shell:ログイン失敗結果 ②
moonsy@moon ~ % ssh -i ~/.ssh/key-moon-de_rsa.prv root@xxx.xxx.xxx.x
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/Users/moonsungyun/.ssh/key-moon-de_rsa.prv' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "/Users/moonsungyun/.ssh/key-moon-de_rsa.prv": bad permissions
root@xxx.xxx.xxx.x: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
```
```shell:結果 ② の対処法：chmod 600コマンドにてPermission強化
moonsy@moon ~ % chmod 600 ~/.ssh/key-moon-de_rsa.prv

moonsy@moon ~ % ssh -i ~/.ssh/key-moon-de_rsa.prv root@xxx.xxx.xxx.x
Last login: Thu Jul 11 05:47:22 2024 from xxx.xxx.xx.xxx
[root@vpc-pps-consumer-vsi-eu-de-2 ~]#
```
:::
ここまで実施したら、コンシューマーがプロバイダー提供のアプリにアクセスする流れは完了です。

## 全体公開の流れ
今回の検証は同一アカウント内、同一VPC内のコンシューマーに提供する検証でしたが、最後に別のVPCにいるコンシューマーに公開する流れは以下となります。
再度`ナビゲーション・メニュー`→`Infrastructure`→`Network`→`Private Path Service`にアクセスすると、先ほど作成されたPrivate Pathがあり、「公開済み」項目に`いいえ`となっていることがわかります。右側の`︙`にて`公開`をクリックします。
![スクリーンショット 2025-02-14 15.50.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/e81fc20a-efe8-4f64-8655-94cc0658c109.png)
再度`公開`をクリックします。
![スクリーンショット 2025-02-14 15.50.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/d5b3db67-f911-41d6-aeb5-d65de2d18530.png)
すると、「公開済み」項目が`はい`に変更になり、他のアカウントが仮想プライベート・エンドポイント (VPE) ゲートウェイを介してサービスに接続することができるようになります。
![スクリーンショット 2025-02-14 15.50.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/1ecd38fc-23c1-413d-92e4-0c07f7bd8fd1.png)

## リソースの削除
最後にリソース削除についても簡単にご紹介したいと思います。
もしインスタンスが不要になった場合、本来であれば一つずつ削除を行う必要がありますが、Schematicsワークスペースで作成した場合には削除も一気に行うことができます。右上の`アクション`ボタンをプルダウンし、`リソースの破棄`をクリックし、インスタンスの削除を行います。

一つ注意点としては、こちらの画面で`リソースの破棄`ではなく`ワークスペースの削除`をクリックしてもリソースは削除されません。あくまでもSchematicsのワークスペースはリソースをオーダーして削除する命令を行う道具であるため、ワークスペースを削除してしまうと一気に削除するように命令する道具がなくなることになります。そのため、もしリソース削除の前にワークスペースを削除した場合、手作業で一つずつリソースインスタンスを削除する必要があります。
![スクリーンショット 2023-07-12 17.21.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/5e8bf8c5-bc73-404e-82ed-5d4c60f7d309.png)
![スクリーンショット 2023-07-12 17.23.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/633777bc-f240-5a4c-64e1-ffd7341eedfe.png)
リソースを破棄が完了したとのジョブメッセージが表示されると、リソースリストを確認してみます。ワークスペースインスタンス以外、全てのリソースが削除されたことがわかります。
![スクリーンショット 2023-07-12 17.27.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/8d28f3cf-e5df-cf03-589a-a83597db97c8.png)
![スクリーンショット 2023-07-12 17.28.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/0842a883-c9a1-aebb-1f58-edafe47fcacf.png)
その後最終的に`アクション`→`ワークスペースの削除`をクリックして、Schematicsのワークスペースを削除します。
![スクリーンショット 2023-07-12 17.30.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/0481a1c5-e6a5-f485-5b56-78c8947b7082.png)

## 参考
- IBM Cloud Docs
    - [プライベート接続を通じて消費者にサービスを公開する](https://cloud.ibm.com/docs/vpc?topic=vpc-vpc-pps-basics&locale=en)
    - [プライベート・パス・サービスの公開と非公開](https://cloud.ibm.com/docs/vpc?topic=vpc-pps-activating&interface=ui)