#008: KeyVaultでVMパスワードを管理

※本記事は、個人の意見および個人的活動を記したものであり、会社を代表するものではありません

VMローカルアカウントの運用を辞めてEntraID認証にしたいのだが、様々な制約があるため、せめてパスワードの管理をもう少し改善したい。少なくとも、手元で複数VMローカルの管理アカウントとパスワードを共有フォルダー＋パスワード付きExcelとかで管理するのはもう辞めたい。Excelのパスワードの管理も必要になる。ダサい、ダサすぎる。。。

今回の内容を実施することで、パスワードだけは手元で管理するということをしないくても済む。

- KeyVaultに権限のあるユーザーしかパスワードを参照＆更新できない
- VMに権限のあるユーザーしかVMにアクセスできない
- VMログイン時にはパスワードを知らなくても良い

パスワード管理をKeyVaultに任せ、各リソースへのアクセス権限はEntraで管理できる。ちょっと幸せになれる。

# 1. KeyVaultは対象システムとは別管理にする方針

KeyVaultはとても慎重に取り扱う必要があるリソースの１つ。

各システムで構築するリソースとは別で管理した方が良いと思ったので、今回は「ManagedResources」というリソースグループを作成し、そこにデプロイする。

別管理にした方が良いと思う理由は以下の通り。

- 各システムのデプロイ時にキー、シークレット、証明書の安全な参照が必要になるケースを想定（デプロイ時には既にKey Vaultに登録され、各値が参照できる状態）
- 永続保管対象であるため、システムリソースのスクラップ＆ビルドのサイクルに向かない（システムリソースのスクラップ＆ビルドはリソースグループ単位であることが多い）
- システム構築チームとは別のチーム（例えばオーナー組織のIT部門など）が管理する情報になる可能性がある（通常のシステムリソースとは明確にアクセス権限を分けて管理）

まずはKey Vaultを管理するためのリソースグループを作成する。

::: note infor
ここもBicepでIaC化しておきたいが、注力すべきは他にあるため、一旦手動でPortalから作成し、今後の検証時には「既に用意されているリソース」という前提で進める。
:::

## 1-1. 管理用リソースグループ（管理用RG）の定義

以下のパラメータで管理用RGを作成

- RG名: ManagedResources
- Tags: システム共通のリソースであることがわかるタグを指定

## 1-2. Azure Portalでの構築手順

リソースグループはこれだけ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/2999e20a-c6fa-4341-548c-99f4de454e15.png)


# 2. 管理用RGに個別システム用Key Vaultを構築

## 2-1. KeyVaultリソースの定義

今回はVMのローカルユーザーのパスワード管理用に構築するのが目的なので、その他の不要なオプションは外し、後で必要になった時に追加設定する方針。たたし、データリテンションのポリシーだけは作成時の設定から変更できない。今回はデフォルト90日の削除保護有効化で構築することにした。

Key Vaultの推奨は、システム・環境・リージョン毎に分けて管理するというのがMS推奨のようだが、私は今回リージョンは不要だと思ったのでシステム名と環境名をリソース名に付与することにした。

https://learn.microsoft.com/ja-jp/azure/key-vault/general/best-practices#use-separate-key-vaults

リージョンはシステム要件に合わせて設定すれば良いと思う。

- 基本設定
    - リソース名：RagSystem-Vault-dev（システム名-Vault-環境略称）
    - リージョン:  east us 2
    - Sku: standard
    - 削除データの保持期間: 90日
    - 永続的な削除保護: enabled
- アクセス設定
    - 権限モデル: RBAC
    - リソースアクセス: 全てdisabled（必要が発生した時に後で有効化）
- ネットワーク設定
    - パブリックアクセス: enabled
    - 有効なアクセス元: 選択した仮想ネットワークからのみ（FirewallをONにする）
    - アクセスを許可する仮想ネットワーク: なし（どこからもアクセスできない状態で構築し、後で変更する）
    - MSサービスのFirewallバイパスを許可: enabled（MSサービスからのアクセスはFirewallをバイパスするよう設定されるが、KeyVaultにアクセスするためには各MSサービスに別途権限の付与が必要）
    - Private Endpointの設定: なし

## 2-2. Azure Portalでの構築手順

### 2-2-1. 基本設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/b2dc864f-15d8-c90f-7598-af12c48fdc99.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/d3788c72-dc47-f1c8-83b5-eb667671f5e3.png)

### 2-2-2. アクセス設定

今は最低限の設定として、権限モデルにRBACを設定するだけとし、後から必要に応じて設定を追加する方針。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/9edf7f0d-a6a2-6471-0c57-6f2bdff2b14a.png)

### 2-2-3. ネットワーク設定

パブリックアクセスは許可するものの、指定したネットワーク（VNet or 特定のIPレンジ）からのみアクセスできるように設定。

ここではまだVNetもIPレンジも指定しない。（＝結果的にFirewallだけは有効にするが、まだ誰もアクセスできない状態で構築）

MSのサービスはKey VaultのFirewallを通過できるようにするが、あくまでもFirewallの通過のみであり、各リソースに対して適切なアクセス権限を付与しないとKey Vaultのデータにはアクセスできない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/ad6f5723-01e9-5932-dbba-1047a6f8df5e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/d69c42d2-34bb-90a7-6b61-f758e8b13af4.png)

### 2-2-4. タグ設定

tagには、このVaultが所属するシステム名を登録しておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/498321c5-9206-7a72-c4c7-500516c9c62e.png)

### 2-2-5. 設定サマリー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/cf34b012-72c0-a872-b4dc-d21d0ab42938.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/f3abb681-dd3c-7efe-d2f2-f78ab118122c.png)

## 2-3. ロールの割り当て

Key Vaultを構築した直後はデータに対するアクセス権がないため、リソースを作成した所有者であってもキー、シークレット、証明書にはアクセスできない。

::: note
リソースを作成したユーザーは、あくまでもリソースに対する権限で構築しており、Key Vaultの各データへのアクセス権限は別途必要。
:::

適切なロールを割り当てないとこうなる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/4a006733-8fa1-bfff-13db-be1bb7411647.png)

Permission modelはRBACモデルで構築しているので、操作を行うEntraユーザーに対して適切なRBACの付与が必要。

::: note
本来はユーザーではなくSGもしくは管理グループに割り当てるのが良いと思うが、ここでは気にせず自分にKey Vault Administratorを付与。
:::

以下「アクセス設定」画面で、Permission modelがRBACになっていることを確認して、IAMの画面に遷移。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/b6b507e3-c1c0-cc50-0128-547c304303b1.png)

IAMの画面では、数あるロールからKey Vault Administratorを選択。自分に権限を付与する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/28ece16e-f6e4-5697-53e9-6bd2561b40a5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/8e7cfd46-b8f9-a21c-694a-46660e8e4458.png)

## 2-4. ネットワーク設定の追加

再度Keyやsecretやcertificatesにアクセスすると、今度はFirewallが効いていてアクセスできず。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/546f9621-1551-8511-0337-f48ac4900d3f.png)

ネットワークの設定画面で、自分のグローバルIPを追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/fd0c9a06-4908-a9da-2a95-5c08d2ec85b6.png)

ようやくkey、secrets、certificatesを追加できるようになった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/f77e32b5-4ce2-3704-592d-29e83a911836.png)

# 3. KeyVaultのSecretに管理者パスワードを登録

早速VMの管理者パスワードをSecretsに追加。

こんな感じで、シークレットを利用するシステム名、リソース名、利用目的がわかるような名前にすると良いかも。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/630745df-36af-c6ba-2e70-468b84939451.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/c1dc323b-a71b-f194-da0d-9518af6317d6.png)

# 4. VMログイン時にKey Vaultに登録したVM用パスワードを指定

BastionからVM接続時に、「Password from Azure Key Vault」を選択すると、リストから目的のKeyVaultとSecretが選択できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/09078701-412c-9666-ff50-ef443baac2a8.png)

これでBasion経由のアクセス時に毎回パスワードを入力する必要がなくなった。
今回はBicepも書いておらず、バージョン管理するものがないのでGithubのリンクはなし。