# 機能設計書 98-EC2ディスカバリ

## 概要

本ドキュメントは、AWS EC2環境でのノード自動検出プラグイン（EC2 Discovery Plugin）の設計を記述する。EC2ディスカバリプラグインは、Amazon EC2のAPIを使用してクラスタメンバーのシードホストを自動検出する。

### 本機能の処理概要

EC2ディスカバリプラグインは、AWS EC2 APIのDescribeInstancesを呼び出してEC2インスタンスの情報を取得し、クラスタのシードホストとして使用可能なノードのアドレスリストを生成する。

**業務上の目的・背景**：AWS EC2環境ではインスタンスのIPアドレスが動的に変わるため、静的な設定ファイルによるノードディスカバリは困難である。EC2ディスカバリプラグインにより、EC2 APIを使った動的なノード検出が可能となり、Auto Scaling Groupと連携した弾力的なクラスタ運用を実現する。

**機能の利用シーン**：AWS EC2上でOpenSearchクラスタを運用する場合に使用される。特にAuto Scaling Groupによるインスタンスの動的な増減が発生する環境で有用。

**主要な処理内容**：
1. EC2クライアントの初期化 - AWSクレデンシャルを使用したEC2クライアントの生成
2. インスタンス情報の取得 - DescribeInstances APIによるEC2インスタンスリストの取得
3. フィルタリング - タグ、セキュリティグループ、アベイラビリティゾーン等によるフィルタリング
4. ホストアドレス解決 - プライベートIP、パブリックIP、DNS名等からホストアドレスを決定
5. シードホストリスト提供 - SeedHostsProviderインターフェースを通じてホストリストを返却

**関連システム・外部連携**：AWS EC2 API（DescribeInstances）。AWS SDK for Javaを使用。

**権限による制御**：EC2のDescribeInstances API権限（ec2:DescribeInstances）がIAMロールまたはクレデンシャルに必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | EC2ディスカバリに直接対応する画面はない |

## 機能種別

データ連携（AWS EC2ノード検出）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| discovery.ec2.host_type | String | No | ホストタイプ（private_ip/public_ip/private_dns/public_dns/tag:XXX） | デフォルトprivate_ip |
| discovery.ec2.any_group | Boolean | No | いずれかのセキュリティグループに属すれば対象とするか | デフォルトtrue |
| discovery.ec2.groups | List<String> | No | フィルタ対象のセキュリティグループID/名前 | - |
| discovery.ec2.availability_zones | List<String> | No | フィルタ対象のアベイラビリティゾーン | - |
| discovery.ec2.tag.* | String | No | フィルタ対象のEC2タグ | キーバリュー形式 |
| discovery.seed_providers | String | No | "ec2"を指定して有効化 | - |

### 入力データソース

opensearch.yml設定ファイル。AWS EC2 DescribeInstances APIのレスポンス。AWSクレデンシャル（IAMロール、環境変数、設定ファイル等）。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| List<TransportAddress> | List | 検出されたシードホストのトランスポートアドレスリスト |

### 出力先

ディスカバリモジュール（SeedHostsProvider経由）。

## 処理フロー

### 処理シーケンス

```
1. Ec2DiscoveryPlugin初期化
   └─ AwsEc2ServiceImplの生成
   └─ クレデンシャルの初期ロード
2. getSeedHostProviders()で"ec2"プロバイダを登録
   └─ AwsEc2SeedHostsProviderのインスタンスを返却
3. AwsEc2SeedHostsProvider.getSeedAddresses()呼び出し
   └─ DescribeInstancesRequestの構築
   └─ フィルタの設定（タグ、グループ、AZ等）
   └─ EC2 APIの呼び出し
4. レスポンスの処理
   └─ Reservation/Instance情報の走査
   └─ セキュリティグループフィルタリング
   └─ host_type設定に基づくアドレス抽出
5. TransportAddressリストの生成
   └─ ホスト名/IPをTransportAddressに変換
```

### フローチャート

```mermaid
flowchart TD
    A[getSeedAddresses呼び出し] --> B[DescribeInstancesRequest構築]
    B --> C[フィルタ設定]
    C --> D[EC2 API呼び出し]
    D --> E{成功?}
    E -->|Yes| F[レスポンス走査]
    E -->|No| G[エラー処理/空リスト]
    F --> H[セキュリティグループフィルタ]
    H --> I[host_typeに基づくアドレス抽出]
    I --> J[TransportAddressリスト生成]
    J --> K[キャッシュ更新]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-98-01 | ホストタイプ | private_ip/public_ip/private_dns/public_dns/tag:XXXから選択 | 常時 |
| BR-98-02 | セキュリティグループフィルタ | any_group=trueの場合、いずれかのグループに属すれば対象 | グループフィルタ設定時 |
| BR-98-03 | キャッシュ | SingleObjectCacheでインスタンスリストをキャッシュ | 常時 |
| BR-98-04 | クレデンシャルリロード | ReloadablePluginにより設定のリロードが可能 | セキュア設定変更時 |

### 計算ロジック

特になし。

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

### テーブル別操作詳細

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| SdkException | AWS APIエラー | EC2 API呼び出し失敗 | AWSクレデンシャルとIAM権限を確認 |
| IOException | ネットワークエラー | AWS APIへの接続失敗 | VPC/ネットワーク設定を確認 |

### リトライ仕様

AWS SDK内部のリトライメカニズムに依存する。ディスカバリ層では定期的にシードホストのリフレッシュが行われる。

## トランザクション仕様

該当なし。

## パフォーマンス要件

- SingleObjectCacheでEC2 APIレスポンスをキャッシュし、API呼び出し頻度を抑制
- EC2 APIのレート制限に注意が必要

## セキュリティ考慮事項

- AWSクレデンシャル（IAMロール推奨）が必要
- ec2:DescribeInstances権限のみ必要（最小権限原則）
- セキュアキーストアでクレデンシャルを管理可能（ReloadablePlugin対応）

## 備考

- SpecialPermission.check()によるセキュリティマネージャの権限チェックが行われる
- Ec2NameResolverで"_ec2_"プレフィックスのネットワーク名解決が可能
- pluginsディレクトリに配置される

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Ec2ClientSettings.java | `plugins/discovery-ec2/src/main/java/org/opensearch/discovery/ec2/Ec2ClientSettings.java` | EC2クライアントの設定（クレデンシャル、エンドポイント等） |
| 1-2 | AwsEc2Service.java | `plugins/discovery-ec2/src/main/java/org/opensearch/discovery/ec2/AwsEc2Service.java` | EC2サービスのインターフェース |

**読解のコツ**: HostTypeの列挙値（PRIVATE_IP, PUBLIC_IP, PRIVATE_DNS, PUBLIC_DNS, TAG_PREFIX）がアドレス解決の選択肢を定義している。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Ec2DiscoveryPlugin.java | `plugins/discovery-ec2/src/main/java/org/opensearch/discovery/ec2/Ec2DiscoveryPlugin.java` | プラグインのエントリーポイント |

**主要処理フロー**:
1. **67行目**: Ec2DiscoveryPluginクラス定義 - DiscoveryPlugin, ReloadablePluginを実装
2. **80-88行目**: コンストラクタ - AwsEc2ServiceImplの生成、クレデンシャルの初期ロード
3. **92-95行目**: getCustomNameResolver() - _ec2_ネットワーク名解決の登録
4. **98-99行目**: getSeedHostProviders() - "ec2"プロバイダの登録

#### Step 3: シードホスト検出処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AwsEc2SeedHostsProvider.java | `plugins/discovery-ec2/src/main/java/org/opensearch/discovery/ec2/AwsEc2SeedHostsProvider.java` | シードホスト検出の実装 |

**主要処理フロー**:
- **69行目**: SeedHostsProviderを実装
- **77-79行目**: bindAnyGroup、groupsフィールド - セキュリティグループフィルタ設定

### プログラム呼び出し階層図

```
Ec2DiscoveryPlugin
    |
    +-- getSeedHostProviders()
         +-- AwsEc2SeedHostsProvider(settings, transportService, ec2Service)
              |
              +-- getSeedAddresses()
                   +-- DescribeInstancesRequest構築
                   +-- awsEc2Service.client().describeInstances()
                   +-- フィルタリング（グループ、AZ、タグ）
                   +-- ホストアドレス解決（host_type設定に基づく）
                   +-- TransportAddressリスト生成
```

### データフロー図

```
[入力]                          [処理]                           [出力]

AWS EC2 API ──────> AwsEc2SeedHostsProvider ──────> List<TransportAddress>
  (DescribeInstances)   フィルタリング                      |
  レスポンス            アドレス解決               ディスカバリモジュール
                                                  (クラスタ参加処理)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Ec2DiscoveryPlugin.java | `plugins/discovery-ec2/src/main/java/org/opensearch/discovery/ec2/Ec2DiscoveryPlugin.java` | ソース | プラグインメインクラス |
| AwsEc2SeedHostsProvider.java | `plugins/discovery-ec2/src/main/java/org/opensearch/discovery/ec2/AwsEc2SeedHostsProvider.java` | ソース | シードホスト検出 |
| AwsEc2Service.java | `plugins/discovery-ec2/src/main/java/org/opensearch/discovery/ec2/AwsEc2Service.java` | ソース | EC2サービスインターフェース |
| AwsEc2ServiceImpl.java | `plugins/discovery-ec2/src/main/java/org/opensearch/discovery/ec2/AwsEc2ServiceImpl.java` | ソース | EC2サービス実装 |
| Ec2ClientSettings.java | `plugins/discovery-ec2/src/main/java/org/opensearch/discovery/ec2/Ec2ClientSettings.java` | ソース | クライアント設定 |
| Ec2NameResolver.java | `plugins/discovery-ec2/src/main/java/org/opensearch/discovery/ec2/Ec2NameResolver.java` | ソース | EC2ネットワーク名解決 |
| AmazonEc2ClientReference.java | `plugins/discovery-ec2/src/main/java/org/opensearch/discovery/ec2/AmazonEc2ClientReference.java` | ソース | EC2クライアント参照管理 |
