HashiCorp Vault HA Cluster構築

# 概要

HashiCorp Vault（OSS版）にて、HA Clusterを構成します

# 前提条件

- HashiCorp Vault 1.13.2 を使って確認した内容です。
- AWS にて、AmazonLinux 2023 3台を使用します。
- Vaultは、Auto-Unseal を利用できるものとします。（未設定の場合は利用できる状態まで済ませてください）
- AWSやEC2、ALB、DNSまわりの細かな設定は省略しますので、ご利用の環境にあわせて設定を行ってください。

上記以外の環境でも利用可能ですので、必要に応じて読み替えてください。

まだauto-unsealを利用していない場合は、こちらで切り替え方法のメモやリンクを載せてます
[unseal - auto-unseal 切り替え](https://qiita.com/saitamanokusa/items/24888fdcabaa7b153be5#unseal---auto-unseal-%E5%88%87%E3%82%8A%E6%9B%BF%E3%81%88)
PC上で検証環境を作る場合でも、Transit Keyを使ったAuto-Unsealが利用可能です。 ※追加でvaultがもう1台必要
[seal Stanza](https://developer.hashicorp.com/vault/docs/configuration/seal)
[Auto Unseal(Tutorial)](https://developer.hashicorp.com/vault/tutorials/auto-unseal)

# はじめに

## 全体の構成

大雑把にですが、下図のような構成を作ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529537/60270826-04ae-790a-3826-7f6a0248c523.png)

- Vault 3台 を 3つのAZに分散して配置し、1つのClusterを構成します（IPは説明の都合上、連番にしています）
  - vault-01  192.168.11.101
  - vault-02  192.168.11.102
  - vault-03  192.168.11.103
- 外部からは、ALB経由でvault cluster にアクセスします
- clusterの各node間通信、およびALBから各node宛ての通信はhttpsに対応します

## ストレージタイプについて

Vault ver 1.13 においては、ストレージにRaftを利用することで、シンプルにCluster構成を組むことができます。
RaftはVaultに統合されているため、Vaultのインストールのみで利用でき、追加機能のインストールは不要です。

Raftを利用して初期構成を行うことで、あとはメンバー追加するのみで、容易にClusterを構成できます。

:::note warn
HA Cluster構成は、ストレージタイプ Fileでは利用できません。
Fileですでに稼働中の場合は、データの変換をする必要があります。
※本記事にて、FileからRaftへの移行手段も紹介しています。
:::

## Raftの利用時の注意点

- Raftでは、最低3台での構成が必要です。（1台の障害まで許容）
※2台構成では、1台の障害のみでRaftストレージのRead/Writeが一切できなくなります。
- Raft利用時は、バースト可能なCPUの利用は避けることを推奨されています。
  本記事ではt2.micro を利用しますが、負荷のかかる環境で利用する場合は、適切なインスタンスタイプを選択してください。
[Vault with Integrated Storage Reference Architecture](https://developer.hashicorp.com/vault/tutorials/day-one-raft/raft-reference-architecture)

> For predictable performance on cloud providers, it's recommended to avoid "burstable" CPU and storage options (such as AWS `t2` and `t3` instance types) whose performance may degrade rapidly under continuous load.

## OSS版でのクラスタ構成の動作制限

- OSS版のVaultでは、Clusterの台数を増やしても、性能の向上はありません。
  （Standby Node 宛ての処理は、すべてActive Node に転送される）
  ※HCP Vault や、Enterprise版では、Standby NodeでもRead処理を行う機能があるようです。
- その他、機能の違いについては、下記をご参照ください。
  - [What is HCP Vault](https://developer.hashicorp.com/vault/tutorials/cloud/vault-introduction) Self Managed と HCP Vaultの比較あり
  - [Vault pricing](https://www.hashicorp.com/products/vault/pricing) HCP Vaultや、Enterprise版のコスト、機能比較

# 事前準備

## EC2の用意

EC2 を3台作成し、vaultをインストールします。
（本例では、AmazonLinux 2023、 InstanceType t2.micro を使用します）

```shell
sudo hostnamectl set-hostname vault-01
sudo timedatectl set-timezone Asia/Tokyo

# vault インストール ※この時点ではまだ起動しない
sudo dnf install -y yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo
sudo dnf -y install vault
sudo systemctl enable vault

# vault auto complete と、必要環境変数追加
cat <<EOF | sudo tee /etc/profile.d/vault.sh
complete -C /usr/bin/vault vault
export VAULT_SKIP_VERIFY=true
EOF

source /etc/profile

# rsyslog が入ってないので追加
sudo dnf -y install rsyslog
sudo systemctl enable rsyslog
sudo systemctl start rsyslog

```

## SecurityGroup

下記のようなSecurityGroupを定義し、EC2に割り当ててください。

- 同一SecurityGroup内の通信を許可 (Cluster node間の通信用)
- ALBからの tcp 8200 の通信を許可
- その他管理に必要な任意の通信を許可

## 証明書の用意(https対応時のみ)

node間の通信をhttpsに対応させるために、SSL証明書を用意します。
本例では、証明書作成を簡単にするために、自己署名証明書を利用します。

証明書作成処理  ※要openssl 1.1.1 または 3.0

```shell
# 自己署名でSANに vault-cluster を含めた証明書を生成
openssl req -x509 -days 7300 -nodes -newkey rsa:2048 -out vault-cluster.crt -keyout vault-cluster.key -config - <<EOF
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no

[req_distinguished_name]
CN = vault-cluster

[v3_req]
keyUsage = digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1 = vault-cluster
EOF
```

説明の都合上、CA証明書も同一ファイルをコピーして使用します。
※ファイル名が同じだとサーバー証明書とCA証明書の設定を混同しそうなので・・・
（みなさんは同じファイル名のままでも構いません）

```shell
cp vault-cluster.crt ca.crt
```

用意した証明書、秘密鍵、CA証明書を、vault の設定に合わせて配置します
※証明書ファイルは、3台ともに同一ファイルを使用してください。

```shell
# 証明書の配置
sudo cp vault-cluster.crt vault-cluster.key ca.crt /opt/vault/tls/
sudo chown -R vault: /opt/vault/tls
```

:::note
もし、ご自身でCA証明を利用している場合は、そちらを使って作成してください。
ただし、SANの登録は必須ですので、適切な値（本例では vault-cluster )を登録してください。
:::

## Tagの割り当て（auto-join に対応する場合のみ）

3台のEC2に、Vault-Clusterのメンバーであることを示すタグを設定します。
本記事では、 Tag名 `Project`  値  `vault-dev-cluster` とします。
※タグ名、値は任意です

## IAM Roleの設定（auto-join に対応する場合のみ）

IAM Roleを作成し、必要なPolicyを追加します。（auto-join に対応する場合のみ）

```json:vault_autojoin
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "ec2:DescribeInstances",
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
```

このIAM Roleを、上記で作成した3台のEC2に割り当ててください。

### 【参考】Vault関連のPolicy

aws 上でvaultを稼働させる場合、ほとんどの場合、aws auth や、aws secret は利用するかと思います。
その場合に必要となるPolicyの一例です。※必要に応じて修正してください。

```json:vault_aws_auth
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "iam:ListRoles",
        "iam:GetUser",
        "iam:GetRole",
        "iam:GetInstanceProfile",
        "ec2:DescribeInstances"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
```

```json:vault_aws_secret
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "iam:RemoveUserFromGroup",
        "iam:PutUserPolicy",
        "iam:ListUserPolicies",
        "iam:ListGroupsForUser",
        "iam:ListAttachedUserPolicies",
        "iam:ListAccessKeys",
        "iam:GetUser",
        "iam:DetachUserPolicy",
        "iam:DeleteUserPolicy",
        "iam:DeleteUser",
        "iam:DeleteAccessKey",
        "iam:CreateUser",
        "iam:CreateAccessKey",
        "iam:AttachUserPolicy",
        "iam:AddUserToGroup"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:iam::*:user/*",
        "arn:aws:iam::*:group/*"
      ]
    },
    {
      "Action": "iam:ListUsers",
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
```

```json:vault_aws_secret_assumerole
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Effect": "Allow",
      "Resource": "arn:aws:iam::*:role/*"
    }
  ]
}
```

# 構成ファイル指定によるCluster構成

おおよそ下記の順番で進めます

- vault-01 にて、Raft構成、Auto-Unseal の設定を行う。
- vault-01 で、vault サービスを起動。`vault operator init`で初期化を行う
- vault-02, 03 も、Raft構成を行ったうえでサービス起動
- 3台ともRaftのメンバーとなったことを確認

## vaultの設定 (設定項目の説明)

vault-01, 02, 03 それぞれで、構成ファイル `/etc/vault.d/vault.hcl`に設定を追加します。
※設定が終わっても、この時点ではまだ起動しないでください。

```shell:/etc/vault.d/vault.hcl
ui = true

api_addr      = "https://192.168.11.101:8200"
cluster_addr  = "https://192.168.11.101:8201"
disable_mlock = true

enable_response_header_hostname = true
enable_response_header_raft_node_id = true

storage "raft" {
  path    = "/opt/vault/raft"
  node_id = "vault-01"

  retry_join {
    leader_tls_servername   = "vault-cluster"
    leader_api_addr         = "https://192.168.11.101:8200"
    leader_ca_cert_file     = "/opt/vault/tls/ca.crt"
    leader_client_cert_file = "/opt/vault/tls/vault-cluster.crt"
    leader_client_key_file  = "/opt/vault/tls/vault-cluster.key"
  }
  retry_join {
    leader_tls_servername   = "vault-cluster"
    leader_api_addr         = "https://192.168.11.102:8200"
    leader_ca_cert_file     = "/opt/vault/tls/ca.crt"
    leader_client_cert_file = "/opt/vault/tls/vault-cluster.crt"
    leader_client_key_file  = "/opt/vault/tls/vault-cluster.key"
  }
  retry_join {
    leader_tls_servername   = "vault-cluster"
    leader_api_addr         = "https://192.168.11.103:8200"
    leader_ca_cert_file     = "/opt/vault/tls/ca.crt"
    leader_client_cert_file = "/opt/vault/tls/vault-cluster.crt"
    leader_client_key_file  = "/opt/vault/tls/vault-cluster.key"
  }
}

# HTTP listener
#listener "tcp" {
#  address = "0.0.0.0:8200"
#  cluster_address = "0.0.0.0:8201"
#  tls_disable = 1
#}

# HTTPS listener
listener "tcp" {
  address       = "0.0.0.0:8200"
  cluster_address = "0.0.0.0:8201"
  tls_cert_file = "/opt/vault/tls/vault-cluster.crt"
  tls_key_file  = "/opt/vault/tls/vault-cluster.key"
  tls_client_ca_file = "/opt/vault/tls/ca.crt"
}

# AWS KMS auto unseal
seal "awskms" {
  region = "ap-northeast-1"
  kms_key_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```

| 項目 | 説明 |
| ---- | ---- |
| api_addr  | Clusterのメンバーに対して、自身のアドレスとして通知する値 <br />Private IPや、内部DNSの登録がある場合はDNS名で指定|
| cluster_addr  | Clusterのメンバーに対して、自身のアドレスとして通知する値 <br />Private IPや、内部DNSの登録がある場合はDNS名で指定 |
| disable_mlock | Raft利用時は mlock 無効を推奨 |
| enable_response_header_hostname |  httpヘッダーにhost名を出力（任意） |
| enable_response_header_raft_node_id | httpヘッダーにnode_idを出力（任意） |

※api_addr, cluster_addr は、サーバーごとに適切な値を指定

[Vault Configuration](https://developer.hashicorp.com/vault/docs/configuration)

| raft 設定項目           | 説明                                                                                                                                     |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| path                    | raft データを配置する場所                                                                                                                |
| node_id                 | node_id をわかりやすい名前で指定 <br />省略時はUUIDとなる                                                                                |

※ node_id は、サーバーごとに適切な値を指定（省略でも可）

| raft retry_join 設定項目           | 説明                                                                                                                                     |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| leader_tls_servername   | 接続先ノードの証明書中のSANに登録されている値を指定<br />接続先が適切であるかチェックに使用<br />※この値は名前解決できる必要はありません |
| leader_api_addr         | 接続先 api_addr を指定                                                                                                                   |
| leader_ca_cert_file     | 接続先のサーバー証明書チェックに使うCA証明書                                                                                                     |
| leader_client_cert_file | 自身のクライアント証明書                                                                                                                 |
| leader_client_key_file  | クライアント証明書のキー                                                                                                                 |

※retry_join 部分の設定は、3台とも共通設定で問題ありません

[Integrated Storage (Raft) Backend](https://developer.hashicorp.com/vault/docs/configuration/storage/raft)

listener の設定

| lister 設定項目 | 説明 |
| ---- | ---- |
| address | vault のAPIを受けるアドレス指定 |
| cluster_address | vault のCluste関連通信を受けるアドレス指定<br />（省略時は address のポートに1足した値） |
| tls_cert_file | 自身のサーバー証明書 |
| tls_key_file | サーバー証明書のキー |
| tls_client_ca_file | クライアント証明書のチェックに使うCA証明書 |

[tcp Listener](https://developer.hashicorp.com/vault/docs/configuration/listener/tcp)

## vault-01 起動、raft 、HA の状態チェック

まず1台のホストで、Raftを使った構成で、vaultを起動し、初期化します

```shell
# Raftデータ用のディレクトリを作成
[ ! -d /opt/vault/raft ] && sudo mkdir /opt/vault/raft
sudo chown -R vault: /opt/vault/raft

# vault が raft ストレージで正常に起動することを確認
sudo systemctl start vault
vault status
Key                      Value
---                      -----
Recovery Seal Type       awskms
Initialized              false
Sealed                   true
(省略)
Storage Type             raft
HA Enabled               true

# 初期化を行う（発行された 情報は大切に保管）
vault operator init
vault login ******

# raft に、単一ノードで追加されていることを確認
vault operator raft list-peers
Node        Address                State       Voter
----        -------                -----       -----
vault-01    192.168.11.101:8201    leader      true


vault operator members
Host Name    API Address                  Cluster Address              Active Node    Version    Upgrade Version    Redundancy Zone    Last Echo
---------    -----------                  ---------------              -----------    -------    ---------------    ---------------    ---------
vault-01     https://192.168.11.101:8200  https://192.168.11.101:8201  true           1.13.2     1.13.2             n/a                n/a


# auto unseal で起動できることを確認
sudo systemctl restart vault
vault status

```

## vault-02 起動、raft 、HA の状態チェック

2台目以降は、vaultを起動すれば、自動でClusterに参加できます。

```shell
# Raftデータ用のディレクトリを作成
[ ! -d /opt/vault/raft ] && sudo mkdir /opt/vault/raft
sudo chown -R vault: /opt/vault/raft

# vault を起動すると、自動的にRaftに追加され、すでに初期化済みとなる　※反映に数秒かかる
sudo systemctl start vault
vault status
Key                      Value
---                      -----
Recovery Seal Type       shamir
Initialized              true
Sealed                   false
（省略）
HA Enabled               true
HA Cluster               https://192.168.11.101:8201
HA Mode                  standby
Active Node Address      https://192.168.11.101:8200


# vault-01 で取得した root token でログイン
vault login ******

# raft 追加されていることを確認
vault operator raft list-peers
Node        Address                State       Voter
----        -------                -----       -----
vault-01    192.168.11.101:8201    leader      true
vault-02    192.168.11.102:8201    follower    false


vault operator members
Host Name    API Address                  Cluster Address              Active Node    Version    Upgrade Version    Redundancy Zone    Last Echo
---------    -----------                  ---------------              -----------    -------    ---------------    ---------------    ---------
vault-01     https://192.168.11.101:8200  https://192.168.11.101:8201  true           1.13.2     1.13.2             n/a                n/a
vault-02     https://192.168.11.102:8200  https://192.168.11.102:8201  false          1.13.2     1.13.2             n/a                2023-05-18T03:15:24+09:00
```

## vault-03 起動、raft 、HA の状態チェック

```shell
# Raftデータ用のディレクトリを作成
[ ! -d /opt/vault/raft ] && sudo mkdir /opt/vault/raft
sudo chown -R vault: /opt/vault/raft

# vault を起動すると、自動的にRaftに追加される
sudo systemctl start vault
vault status

# vault-01 で取得した root token でログイン
vault login ******

# raft 追加されていることを確認
vault operator raft list-peers
Node        Address                State       Voter
----        -------                -----       -----
vault-01    192.168.11.101:8201    leader      true
vault-02    192.168.11.102:8201    follower    true
vault-03    192.168.11.103:8201    follower    false

vault operator members
Host Name    API Address                  Cluster Address              Active Node    Version    Upgrade Version    Redundancy Zone    Last Echo
---------    -----------                  ---------------              -----------    -------    ---------------    ---------------    ---------
vault-01     https://192.168.11.101:8200  https://192.168.11.101:8201  true           1.13.2     1.13.2             n/a                n/a
vault-02     https://192.168.11.102:8200  https://192.168.11.102:8201  false          1.13.2     1.13.2             n/a                2023-05-18T03:15:24+09:00
vault-03     https://192.168.11.103:8200  https://192.168.11.103:8201  false          1.13.2     1.13.2             n/a                2023-05-18T03:15:24+09:00

```

# auto-joinを利用したCluster構成

上記の手段では、各メンバーホストのIPアドレス情報をあらかじめ入手する必要がありました。

別の手段として、auto-join 機能を用いることで、特定のタグの付いたメンバーホスト検出し、Raftに自動追加することも可能です。
例えば下記の設定ならば、各ホストとも完全に共通の設定とすることが可能です。

```shell:/etc/vault.d/vault.hcl
ui = true

api_addr      = "https://{{ GetPrivateIP }}:8200"
cluster_addr  = "https://{{ GetPrivateIP }}:8201"
disable_mlock = true

enable_response_header_hostname = true
enable_response_header_raft_node_id = true

storage "raft" {
  path    = "/opt/vault/raft"

  retry_join {
    auto_join = "provider=aws addr_type=private_v4 tag_key=Project tag_value=vault-dev_cluster region=ap-northeast-1"
    auto_join_scheme = "https"
    auto_join_port = 8200
    leader_ca_cert_file     = "/opt/vault/tls/ca.crt"
    leader_client_cert_file = "/opt/vault/tls/vault-cluster.crt"
    leader_client_key_file  = "/opt/vault/tls/vault-cluster.key"
  }
}

# HTTP listener
#listener "tcp" {
#  address = "0.0.0.0:8200"
#  cluster_address = "0.0.0.0:8201"
#  tls_disable = 1
#}

# HTTPS listener
listener "tcp" {
  address       = "0.0.0.0:8200"
  cluster_address = "0.0.0.0:8201"
  tls_cert_file = "/opt/vault/tls/vault-cluster.crt"
  tls_key_file  = "/opt/vault/tls/vault-cluster.key"
  tls_client_ca_file = "/opt/vault/tls/ca.crt"
}

# AWS KMS auto unseal
seal "awskms" {
  region = "ap-northeast-1"
  kms_key_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```

| 項目 | 説明 |
| ---- | ---- |
| api_addr<br />cluster_addr | `{{ GetPrivateIP }}`で、自身のPrivateIPを割り当てます |
| auto_join  | AWS利用時の設定例  EC2に割り当てたTagやregion を指定することで、該当EC2のPrivateIPを検出します |
| auto_join_scheme<br />auto_join_port | https, port 8200 での接続を試みます |

[Vault HA Cluster with Integrated Storage on AWS](https://developer.hashicorp.com/vault/tutorials/raft/raft-storage-aws)
[go-sockaddr template](https://pkg.go.dev/github.com/hashicorp/go-sockaddr/template)
[Integrated Storage (Raft) Backend](https://developer.hashicorp.com/vault/docs/configuration/storage/raft#retry_join-stanza)
[hashicorp/go-discover](https://github.com/hashicorp/go-discover/blob/master/README.md)

:::note
auto-join を利用する場合も、マニュアル設定時と同様に、初回は1台のnodeのみ起動し、初期化を行った後、順次メンバーを追加してください。
:::

# ALBからのヘルスチェック

target group は下記のように設定してください。

- Protocol: HTTPS
- Port 8200
- Health Check Path: `/v1/sys/health`

※ヘルスチェックは、Active Node の場合、200を返します。

https://developer.hashicorp.com/vault/api-docs/system/health

# 【参考】FileからRaftへの移行

冒頭で説明したとおり、HA Cluster構成は、File ストレージでは利用できません。
既にFileストレージで利用中の場合は、File → Rafrへのデータ変換が必要です。

あらかじめ、上記マニュアル構成もしくはauto-join構成などを利用して、Raftの設定が追加済みであることを前提とします。
また、root token を使っての操作を前提とします。もしRoot Tokenを削除している場合は、RecoveryKeyから再生成してください。
OS側の操作は、rootユーザー で行います。（パーミッションがややこしいため）

```shell
# サービスは停止しておく
systemctl stop vault.service

# もしRaft path が存在しない場合はディレクトリ作成
[ ! -d /opt/vault/raft ] && mkdir /opt/vault/raft
chown -R vault: /opt/vault/raft

# もし既存のRaftデータが存在する場合は、削除しておく
rm -rf /opt/vault/raft/*
```

現在のディレクトリに、データ変換用ファイル`migrate.hcl`を作成します。

既存のFileストレージのデータが`/opt/vault/data`、Raft のデータが `/opt/vault/raft`の場合、下記のようになります。
（もし他サーバーで稼働していた場合は、Fileデータを、Clusterを構成するサーバーにコピーしてください）

```shell:migrate.hcl
# 変換元のFileデータのpath指定
storage_source "file" {
  path = "/opt/vault/data"
}

# 変換先のRaftデータのpath指定
storage_destination "raft" {
  path    = "/opt/vault/raft"
  node_id = "vault-01"
}

# 自ホストのcluster_addr
cluster_addr = "https://192.168.11.101:8201"
```

vaultコマンドで、上記ファイルを指定し、データ変換処理を行います。
※vault のサービスは停止状態のままにしてください。

```shell
vault operator migrate -config migrate.hcl
(省略)
Success! All of the keys have been migrated.
```

:::note
vaultのサービスではなく、コマンド実行ユーザー(本例ではrootユーザー)によるデータ変換操作です。
したがって、サービス停止状態で問題ありません
:::

ファイルのownerが、root（変換コマンドを実行したユーザー）となっているため、ownerをvault(サービス起動ユーザー)に修正

```shell
# 変換されたデータを確認
ls -l /opt/vault/raft
# owner ユーザー/グループを vault に修正
chown -R vault: /opt/vault/raft
```

サービス起動、Raft で起動したことを確認

```shell
systemctl start vault.service

# 起動状態を確認
# データが格納されているため、Initialized true , Auto-unseal 設定により Sealed  false となっていることを確認
vault status

Key                      Value
---                      -----
Recovery Seal Type       shamir
Initialized              true
Sealed                   false
（省略）
Storage Type             raft
HA Enabled               true
HA Cluster               https://192.168.11.101:8201
HA Mode                  active
（省略）

```

もとのFileストレージのデータが移行されたことを確認

```shell
# もとのFileストレージで使用していた認証でログイン
vault login *****

# Raftが単一ノードで起動していることを確認
vault operator raft list-peers

# データ移行ができたことを確認
vault auth list
vault secrets list
```

あとは、Raft初期構成時と同様に、他のメンバーを追加してください。

```shell
# 他のノードも起動し、複数 node 構成となったことを確認
vault operator raft list-peers
Node        Address                State       Voter
----        -------                -----       -----
vault-01    192.168.11.101:8201    leader      true
vault-02    192.168.11.102:8201    follower    true
vault-03    192.168.11.103:8201    follower    true

```

:::note
root token や、recovery key も含め、まるごと移行できます
:::

[operator migrate](https://developer.hashicorp.com/vault/docs/commands/operator/migrate)

# 最後に

vault のclusterは、最初から必要機能がすべて備わっているため、設定のみで簡単に構築できます。
耐障害性を確保するためにも、Cluster構成を検討されてはいかがでしょうか？