2024年12月3日火曜日

S3コピー

#!/bin/bash

# S3バケットのパス指定
S3_PATH="s3://your-bucket/path"

# ファイル一覧取得とコマンド生成
aws s3 ls --recursive $S3_PATH | while read -r line; do
   filename=$(echo "$line" | awk '{print $4}')
   case "$filename" in
       *.html)
           echo "aws s3 cp ${S3_PATH}/${filename} ${S3_PATH}/${filename} --content-type \"text/html; charset=utf-8\" --metadata-directive REPLACE"
           ;;
       *.js)
           echo "aws s3 cp ${S3_PATH}/${filename} ${S3_PATH}/${filename} --content-type \"text/javascript; charset=utf-8\" --metadata-directive REPLACE"
           ;;
       *.css)
           echo "aws s3 cp ${S3_PATH}/${filename} ${S3_PATH}/${filename} --content-type \"text/css; charset=utf-8\" --metadata-directive REPLACE"
           ;;
   esac
done > update_content_type.sh

chmod +x update_content_type.sh
これを参照 チェック ルール phone UI Wiki.js StepFunctions MCP ### Link https://repost.aws/questions/QUzjhLe0bZQ5SdSgurjrno8g/amazon-sns%E3%81%A7%E3%83%A1%E3%83%BC%E3%83%AB%E9%80%81%E4%BF%A1%E3%81%99%E3%82%8B%E9%9A%9B%E3%81%AE%E5%AE%9B%E5%85%88%E6%95%B0%E3%81%AE%E5%88%B6%E9%99%90 ### =============================
# Cognito認証API監視Canary設計書

## 1. 概要

### 1.1 目的
AWS SyntheticsとCognito認証を使用してAPIエンドポイントの外形監視を行うCanaryシステム。Parameter StoreのSecureStringで認証情報を安全に管理し、統一インターフェースで複数のAPIテストを実行する。

### 1.2 主要機能
- Cognito User PoolからIDトークンを取得
- 複数APIエンドポイントの機能テスト
- カスタムメトリクス送信
- 統一エラーハンドリング
- スクリーンショット取得

### 1.3 技術スタック
- AWS Synthetics (Node.js + Puppeteer)
- AWS Cognito Identity Provider
- AWS Systems Manager Parameter Store
- AWS CloudWatch (Logs & Metrics)

## 2. アーキテクチャ設計

### 2.1 実行フロー
```
1. Parameter Store → 認証情報取得
2. Cognito → IDトークン取得  
3. API Tests → 各エンドポイントテスト
4. Screenshot → ドキュメントページ撮影
5. Metrics → カスタムメトリクス送信
```

### 2.2 ディレクトリ構造
```
canary-script/
├── index.js (メインハンドラー)
├── classes/
│   └── TestResult.js (結果クラス)
├── tests/
│   ├── testHealthEndpoint.js
│   ├── testUserInfoEndpoint.js
│   └── testDataEndpoint.js
└── utils/
    └── sendCustomMetrics.js
```

## 3. 環境変数・設定

### 3.1 必須環境変数
| 変数名 | 説明 | 例 |
|--------|------|-----|
| `PARAMETER_PATH` | Parameter Storeパス | `/canary/api-monitor` |
| `API_ENDPOINT` | 監視対象APIベースURL | `https://api.example.com` |
| `AWS_REGION` | AWSリージョン | `ap-northeast-1` |
| `ENVIRONMENT` | 環境名 | `production` |

### 3.2 Parameter Store設定
| パラメータ名 | 型 | 説明 |
|-------------|-----|-----|
| `{PATH}/user-pool-id` | String | Cognito User Pool ID |
| `{PATH}/client-id` | String | Cognito Client ID |
| `{PATH}/username` | SecureString | 監視用ユーザー名 |
| `{PATH}/password` | SecureString | 監視用パスワード |

## 4. クラス設計

### 4.1 TestResultクラス
```javascript
class TestResult {
    constructor(success, status, responseTime, data = null, error = null)
    static success(status, responseTime, data = null)
    static failure(responseTime, error, status = 0)
    toString()
}
```

#### プロパティ
- `success: boolean` - テスト成功/失敗
- `status: number` - HTTPステータスコード
- `responseTime: number` - レスポンス時間(ミリ秒)
- `data: any` - テスト固有データ(オプション)
- `error: string` - エラーメッセージ(失敗時)

#### ファクトリーメソッド
- `TestResult.success(status, responseTime, data)` - 成功結果作成
- `TestResult.failure(responseTime, error, status)` - 失敗結果作成

## 5. 関数設計

### 5.1 メイン関数
```javascript
const apiMonitoringWithCognito = async function ()
```

#### 実行ステップ
1. `getParameterStoreCredentials` - 認証情報取得
2. `authenticateWithCognito` - Cognito認証
3. `runApiTests` - APIテスト実行
4. `takeScreenshot` - スクリーンショット取得

#### エラーハンドリング
- 各ステップで例外をキャッチ
- ログ出力とCanary失敗処理
- 部分的失敗は`synthetics.addExecutionError`で記録

### 5.2 Parameter Store取得関数
```javascript
// Step 1実装詳細
const parameterResponse = await ssm.getParametersByPath({
    Path: PARAMETER_PATH,
    Recursive: true,
    WithDecryption: true,
    MaxResults: 10
}).promise();
```

#### 処理内容
- 階層パラメータの一括取得
- パラメータ名からキー抽出
- 必須パラメータの存在確認
- 取得失敗時の詳細エラー出力

### 5.3 Cognito認証関数
```javascript
// Step 2実装詳細
const command = new AdminInitiateAuthCommand({
    UserPoolId: credentials['user-pool-id'],
    ClientId: credentials['client-id'],
    AuthFlow: 'ADMIN_USER_PASSWORD_AUTH',
    AuthParameters: {
        USERNAME: credentials.username,
        PASSWORD: credentials.password
    }
});
```

#### 処理内容
- AWS SDK v3の使用
- 認証時間の測定
- IDトークンの解析と有効期限確認
- MFA/チャレンジ処理のエラーハンドリング

## 6. APIテスト関数設計

### 6.1 統一インターフェース仕様
```javascript
async function testXxxEndpoint(token): Promise
```

#### 共通実装パターン
```javascript
async function testXxxEndpoint(token) {
    const startTime = Date.now();
    
    try {
        const page = await synthetics.getPage();
        
        const response = await page.evaluate(async (authToken, baseUrl) => {
            const response = await fetch(`${baseUrl}/endpoint`, {
                method: 'GET',
                headers: {
                    'Authorization': `Bearer ${authToken}`,
                    'Content-Type': 'application/json',
                    'User-Agent': 'AWS-Synthetics-XXX'
                }
            });
            
            return {
                status: response.status,
                statusText: response.statusText,
                body: await response.text()
            };
        }, token, API_ENDPOINT);
        
        const responseTime = Date.now() - startTime;
        
        // ステータスコード検証
        if (response.status !== 200) {
            throw new Error(`API failed: ${response.status} - ${response.statusText}`);
        }
        
        // レスポンス解析
        const data = JSON.parse(response.body);
        
        // API固有の検証ロジック
        // ...
        
        // カスタムメトリクス送信
        await sendCustomMetrics('XxxResponseTime', responseTime, 'Milliseconds');
        
        return TestResult.success(response.status, responseTime, data);
        
    } catch (error) {
        const responseTime = Date.now() - startTime;
        log.error(`Xxx API test failed: ${error.message}`);
        
        return TestResult.failure(responseTime, error.message, 0);
    }
}
```

### 6.2 ヘルスチェックAPIテスト
```javascript
async function testHealthEndpoint(token): Promise
```

#### エンドポイント
- URL: `${API_ENDPOINT}/health`
- Method: GET

#### 期待レスポンス
```json
{
    "status": "healthy|ok|UP",
    "timestamp": "2025-01-01T00:00:00Z",
    "checks": {
        "database": { "status": "healthy" }
    }
}
```

#### 検証ロジック
- ステータスコード200確認
- `status`フィールドが"healthy"/"ok"/"UP"
- `checks.database.status`が"healthy"/"UP"(存在する場合)
- 異常時は警告レベルで記録

### 6.3 ユーザー情報APIテスト
```javascript
async function testUserInfoEndpoint(token): Promise
```

#### エンドポイント
- URL: `${API_ENDPOINT}/api/v1/user`
- Method: GET

#### 期待レスポンス
```json
{
    "username": "synthetics-monitor",
    "sub": "12345678-1234-1234-1234-123456789012",
    "email": "monitor@example.com",
    "roles": ["monitor", "readonly"]
}
```

#### 検証ロジック
- ユーザー識別子フィールド存在確認(username/sub/user_id)
- 期待ユーザー名との照合(設定されている場合)
- ロール確認(monitor/readonly権限)
- 権限不足時は警告レベルで記録

### 6.4 データAPIテスト
```javascript
async function testDataEndpoint(token): Promise
```

#### エンドポイント
- URL: `${API_ENDPOINT}/api/v1/data`
- Method: GET

#### 期待レスポンス
```json
{
    "data": [
        { "id": 1, "name": "Item 1", "value": 100 }
    ],
    "total": 1
}
```

#### 検証ロジック
- データ配列の存在確認(data/items/results/直接配列)
- データ件数の記録
- レスポンス時間の妥当性チェック(基本2秒+データ件数×5ms)
- 空データ時は警告レベルで記録

## 7. ユーティリティ関数

### 7.1 カスタムメトリクス送信
```javascript
async function sendCustomMetrics(metricName, value, unit)
```

#### 実装詳細
```javascript
await cloudwatch.putMetricData({
    Namespace: 'CustomCanary/CognitoAPI',
    MetricData: [{
        MetricName: metricName,
        Value: value,
        Unit: unit,
        Dimensions: [{
            Name: 'CanaryName',
            Value: synthetics.getCanaryName()
        }, {
            Name: 'Environment',
            Value: process.env.ENVIRONMENT || 'production'
        }],
        Timestamp: new Date()
    }]
}).promise();
```

#### 送信メトリクス
- `AuthenticationLatency` - 認証時間(ミリ秒)
- `HealthCheckResponseTime` - ヘルスチェック応答時間
- `UserInfoResponseTime` - ユーザー情報API応答時間
- `DataApiResponseTime` - データAPI応答時間
- `DataRecordCount` - データ件数
- `ApiSuccessRate` - API成功率(パーセント)
- `ApiTestCount` - 実行テスト数
- `ApiSuccessCount` - 成功テスト数

## 8. エラーハンドリング設計

### 8.1 エラーレベル分類
| レベル | 処理 | 例 |
|--------|------|-----|
| 致命的エラー | Canary失敗 | 認証失敗、Parameter Store接続失敗 |
| 機能エラー | addExecutionError | API応答エラー、データ異常 |
| 警告 | ログ出力のみ | パフォーマンス低下、データ品質問題 |

### 8.2 エラーハンドリングパターン
```javascript
try {
    // メイン処理
} catch (error) {
    log.error(`処理名 failed: ${error.message}`);
    
    // エラーレベルに応じた処理
    if (isCriticalError(error)) {
        throw error; // Canary失敗
    } else {
        synthetics.addExecutionError('処理名 failed', error);
    }
}
```

### 8.3 タイムアウト処理
- Parameter Store: デフォルトタイムアウト
- Cognito認証: 測定対象のためタイムアウト設定なし
- API呼び出し: page.evaluateで個別制御
- スクリーンショット: 30秒タイムアウト

## 9. IAM権限設計

### 9.1 必須権限
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cognito-idp:AdminInitiateAuth",
                "cognito-idp:AdminRespondToAuthChallenge"
            ],
            "Resource": "arn:aws:cognito-idp:region:account:userpool/pool-id"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ssm:GetParameter",
                "ssm:GetParameters", 
                "ssm:GetParametersByPath"
            ],
            "Resource": "arn:aws:ssm:region:account:parameter/canary/canary-name/*"
        },
        {
            "Effect": "Allow",
            "Action": "kms:Decrypt",
            "Resource": "arn:aws:kms:region:account:key/*",
            "Condition": {
                "StringEquals": {
                    "kms:ViaService": "ssm.region.amazonaws.com"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": "cloudwatch:PutMetricData",
            "Resource": "*"
        }
    ]
}
```

## 10. 依存関係

### 10.1 AWS SDK依存
```javascript
// AWS SDK v2 (Synthetics標準)
const AWS = require('aws-sdk');
const ssm = new AWS.SSM();
const cloudwatch = new AWS.CloudWatch();

// AWS SDK v3 (Cognito用)
const { CognitoIdentityProviderClient, AdminInitiateAuthCommand } = require('@aws-sdk/client-cognito-identity-provider');
```

### 10.2 Synthetics依存
```javascript
const synthetics = require('Synthetics');
const log = require('SyntheticsLogger');
```

## 11. カスタマイズポイント

### 11.1 新APIエンドポイント追加
1. 統一インターフェースに従った関数作成
2. `runApiTests`ステップに呼び出し追加
3. 固有の検証ロジック実装
4. カスタムメトリクス追加

### 11.2 検証ロジックカスタマイズ
- レスポンス形式の変更対応
- ビジネスルール検証追加
- パフォーマンス閾値調整
- セキュリティチェック追加

### 11.3 メトリクス拡張
- 新しいメトリクス種別追加
- ディメンション追加
- アラート条件調整

## 12. 運用考慮事項

### 12.1 ログ設計
- 構造化ログ出力
- 機密情報のマスキング
- デバッグ情報の適切なレベル設定

### 12.2 モニタリング
- Canary成功率監視
- レスポンス時間監視
- エラー率監視
- カスタムメトリクス監視

### 12.3 保守性
- 設定値の外部化
- テスト関数の独立性
- エラーメッセージの標準化
- ドキュメント更新

## 13. 実装チェックリスト

### 13.1 基本実装
- [ ] TestResultクラス定義
- [ ] メイン関数の4ステップ実装
- [ ] Parameter Store取得処理
- [ ] Cognito認証処理
- [ ] 統一インターフェースAPI関数3個
- [ ] カスタムメトリクス送信
- [ ] エラーハンドリング

### 13.2 設定・環境
- [ ] 環境変数設定
- [ ] Parameter Store設定
- [ ] IAM権限設定
- [ ] CloudWatch設定

### 13.3 テスト・検証
- [ ] 認証テスト
- [ ] API接続テスト
- [ ] エラーシナリオテスト
- [ ] メトリクス送信確認
- [ ] ログ出力確認

## 14. トラブルシューティング

### 14.1 よくある問題
| 問題 | 原因 | 解決策 |
|------|------|--------|
| 認証エラー | Cognito設定/権限 | ユーザー状態・Pool設定確認 |
| Parameter Store エラー | パス・権限 | パラメータ名・IAM権限確認 |
| API接続エラー | ネットワーク・CORS | エンドポイント・SSL確認 |
| メトリクス送信失敗 | CloudWatch権限 | IAMポリシー確認 |

### 14.2 デバッグ手順
1. CloudWatch Logsでエラー詳細確認
2. Parameter Store設定確認
3. Cognitoユーザー状態確認
4. API手動テスト実行
5. IAM権限詳細確認

この設計書により、他の生成AIが同等の機能を持つCanaryスクリプトを実装できる詳細な仕様が提供されます。