2025/12/18

GPT‑5.2(Responses API)利用の流れ

GPT‑5.2(Responses API)利用の流れ
## 利用手順
- OpenAI アカウントを作成
- APIキー を取得
- リクエストヘッダーに設定
  - Authorization: Bearer YOUR_API_KEY
  - Content-Type: application/json

## エンドポイント
```
POST https://api.openai.com/v1/responses
```

## 公式ドキュメントURL
- [OpenAI API Docs – Responses](https://platform.openai.com/docs/api-reference/responses)

## Pythonコード例
### requests を使った直接呼び出し
```
import requests

API_KEY = "YOUR_API_KEY"
url = "https://api.openai.com/v1/responses"
headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
}

# ユーザー質問
user_question = "この製品はISO規格に適合していますか?"

# RAGで取得した外部情報(例: 構造データ+PDF抜粋)
retrieved_context = """
構造データ:
{
  "製品名": "ABCセンサー",
  "測定範囲": "0-100℃",
  "精度": "±0.5℃"
}

規格PDF抜粋:
ISO 12345:2023 セクション 4.2
温度センサーは測定範囲0-100℃、精度±1.0℃以内であること。
"""

# API呼び出し
data = {
    "model": "gpt-5.2",
    "input": f"質問: {user_question}\n\n追加情報:\n{retrieved_context}"
}

response = requests.post(url, headers=headers, json=data)
print(response.json()["output"][0]["content"][0]["text"])
```
「"""」は三連引用符。複数行にわたる文字列を定義する。

### 公式Python SDKを使った呼び出し
```
from openai import OpenAI

client = OpenAI(api_key="YOUR_API_KEY")

# ユーザー質問
user_question = "この製品はISO規格に適合していますか?"

# RAGで取得した外部情報(例: 構造データ+PDF抜粋)
retrieved_context = """
構造データ:
{
  "製品名": "ABCセンサー",
  "測定範囲": "0-100℃",
  "精度": "±0.5℃"
}

規格PDF抜粋:
ISO 12345:2023 セクション 4.2
温度センサーは測定範囲0-100℃、精度±1.0℃以内であること。
"""

# API呼び出し
resp = client.responses.create(
    model="gpt-5.2",
    input=f"質問: {user_question}\n\n追加情報:\n{retrieved_context}"
)

print(resp.output[0].content[0].text)
```

### API呼出し時のinputの指定パターン
#### 文字列形式
```
resp = client.responses.create(
    model="gpt-5.2",
    input=f"質問: {user_question}\n\n追加情報:\n{retrieved_context}"
)
```
「f」は変数展開の指定

#### 構造化形式
```
resp = client.responses.create(
    model="gpt-5.2",
    input=[
        {
            "role": "user",
            "content": [
                {"type": "input_text", "text": f"質問: {user_question}"},
                {"type": "input_text", "text": f"追加情報:\n{retrieved_context}"}
            ]
        }
    ]
)
```
#### roleの種類
1. role: "system"
  - 用途: モデルの振る舞いや出力ルールを事前に定義する
  - 関係性:
    - スキーマで「構造」を保証するだけでは不十分
    - 「このプロパティはこういう意味で、この範囲の値を返す」といった 意味付けや利用方法を指示する場所が system

2. role: "user"
  - 用途: 実際の質問や指示を与える
  - 関係性: プロパティの意味付けはここではなく、質問内容を渡す場所

3. role: "assistant"
  - 用途: 過去の応答を含めて会話の流れを維持する
  - 関係性: プロパティの意味付けとは直接関係しない

例:
```
"response_format": {
  "type": "json_schema",
  "json_schema": {
    "name": "iso_check_schema",
    "schema": {
      "type": "object",
      "properties": {
        "compliance": { "type": "boolean" },
        "standard": { "type": "string" },
        "explanation": { "type": "string" }
      },
      "required": ["compliance", "standard"]
    }
  }
}

"input": [
  {
    "role": "system",
    "content": [
      {
        "type": "text",
        "text": "あなたは品質管理の専門家です。必ず以下のスキーマに従って返答してください。\n- compliance: 製品が指定されたISO規格に適合している場合はtrue、そうでなければfalse。\n- standard: 対象となるISO規格番号を文字列で返す。\n- explanation: 適合/非適合の理由を簡潔に説明する。"
      }
    ]
  },
  {
    "role": "user",
    "content": [
      {
        "type": "input_text",
        "text": "この製品はISO 9001に適合していますか?"
      }
    ]
  }
]
```
#### system 指示の有効範囲
- リクエスト単位で有効
  → そのリクエストの中で指定した role: "system" の内容は、そのリクエスト全体に効きます。
- 次のリクエストには引き継がれない
  → 別の呼び出しをするときには、再度 system を含めて渡さないとルールは維持されません。
- 継続利用したい場合
  → 会話履歴を再現する形で、毎回 system を含めて送る必要があります。
  → 例えば「必ずJSON Schemaに従って返答する」「confidenceは0.0〜1.0で返す」といったルールは、毎回 system に書いて渡すのが正しい使い方です。

#### typeの種類
- input_text
  - 通常のテキスト入力
  - 例: ユーザーの質問や補足情報
- input_image
  - 画像入力
  - 例: 画像ファイルを渡して「この図を説明して」と指示する
- input_audio
  - 音声入力
  - 例: 音声ファイルを渡して「文字起こしして」と指示する

### file_searchの使い方
file_searchはResponses API に組み込まれたビルトインツール。Vector Store 内のファイルを検索し、回答生成に利用する仕組み。

1. Vector Store を作成

	```
	vs = client.vector_stores.create(name="my_store")
	```
    
2. ファイルをアップロードして Vector Store に追加
	```
	client.vector_stores.files.upload(
    	vector_store_id=vs.id,
   		file=open("manual.md", "rb")
	)
	```
    
3. Responses API 呼び出し時に tools と vector_store_ids を指定
```
resp = client.responses.create(
   	model="gpt-5.2",
   	input="この製品はISO 9001に適合していますか?",
   	tools=[{"type": "file_search"}],
   	vector_store_ids=[vs.id]
)
```

## GPT‑5.2 Responses API パラメータ一覧
1. 出力制御系
  - temperature
    - 出力のランダム性を制御(0〜2)
    - 低いほど安定・事実寄り、高いほど創造的
  - top_p
    - 確率分布の累積で候補範囲を制限(0〜1)
    - 低いほど一貫性が高く、高いほど多様性が増す
  - max_output_tokens
    - 出力の最大トークン数を指定
    - 長文生成や要約の長さを調整可能

2. 応答形式系
  - input
    - ユーザーからの質問や指示(必須)
  - modalities
    - 出力形式を指定(例: "text", "json", "audio")
    - JSON構造や音声出力を求める場合に利用
  - response_format
    - 出力の形式をさらに細かく指定
    - 例: "json_schema" を指定して構造化データを返す

3. 応答数・多様性系
  - n
    - 応答の候補数を指定(例: 2なら2通りの回答を返す)
  - presence_penalty
    - 新しいトピックや単語を使う傾向を強める(-2〜2)
    - 高い値 → 繰り返しを避け、新しい語彙を導入
  - frequency_penalty
    - 同じ単語の繰り返しを抑制(-2〜2)
    - 高い値 → 冗長な繰り返しを減らす

4. ストリーミング系
  - stream
    - 出力を逐次受け取るかどうか(True/False)
    - チャットUIなどで「少しずつ表示」したい場合に利用

5. システム制御系
  - model
    - 使用するモデルを指定(例: "gpt-5.2", "gpt-5.2-pro", "gpt-5.2-mini")
  - metadata
    - リクエストに付随するメタ情報(ログやトラッキング用)

## モデルバリエーション比較

|モデル名|特徴|用途例|
|----|----|----|
|gpt-5.2-mini| 軽量・低コスト   | チャットボット、リアルタイム応答|
|gpt-5.2| 標準精度・速度   | 一般的なテキスト生成、要約|
|gpt-5.2-pro| 長文脈・高精度   | 複雑な推論、研究支援、コード生成|

## GPT‑5.2 Responses API 価格(2025年12月時点)
|モデル名|入力 (1M tokens)|キャッシュ入力 (1M tokens)|出力 (1M tokens)|特徴|
|----|---:|---:|---:|----|
|GPT‑5.2|$1.75|$0.175|$14.00|標準モデル。複雑な推論やコーディングに強い|
|GPT‑5.2 Pro|$21.00| – |$168.00|最も精度が高い。専門的タスク向け|
|GPT‑5 Mini|$0.25|$0.025|$2.00|軽量・高速。コスト効率重視|

# RAGについて
## RAGは設計パターン
RAG(Retrieval‑Augmented Generation)は、LLMに渡す前処理の仕組み。「検索(Retriever)で外部情報を取得し、それをLLM(Generator)に渡して回答を生成する」という仕組みのこと。

## 実装パターン
実装の仕方は以下2パターン、或いはハイブリッド方式。

1. 利用者側で追加情報を与える方式
  - 特徴
   - ユーザーが自分で検索・抽出した情報を input に含めて渡す
   - GPT‑5.2(Responses API)は「質問+追加情報」を受け取り回答するだけ
  - メリット
   - シンプルで制御しやすい
   - どの情報を根拠にするか利用者が明示できる
  - デメリット
   - ユーザーが毎回情報を準備する必要がある
   - 自動化には不向き

2. システム側で追加情報を付加する方式
  - 特徴
   - ユーザーは質問だけを投げる
   - システムが裏側で Retriever を動かし、関連情報を検索して input に自動で付加
  - メリット
   - ユーザーは「質問するだけ」で済む
   - 一貫した検索・根拠付けが可能
  - デメリット
   - 検索精度がシステム依存になる
   - どの情報が根拠に使われたかユーザーが見えにくい

3. 補足
  - GPT‑5.2(Responses API)は 与えられた input のテキストだけを処理します。
  - 「RAGで検索して付加して」と指示しても、API単体では外部データベースやPDFを勝手に検索する機能はありません。
  - RAGは 設計パターンなので、Retriever(検索部分)は利用者やシステム側で実装し、その結果を input に含める必要があります。

## CopilotのWeb検索統合 vs RAG設計パターン
| 項目         | CopilotのWeb検索統合                     | RAG設計パターン                          |
|--------------|------------------------------------------|------------------------------------------|
| 検索の実装   | Copilot内部で自動呼び出し                | 利用者/システムが外部で実装             |
| ユーザー操作 | 検索を意識せずに利用可能                 | 検索結果を明示的に input に含める必要あり |
| 出典提示     | CopilotがURLを提示                       | 開発者が出典を含める設計にする            |
| 設計思想     | 機能統合型(検索+生成が一体)           | パターン分離型(RetrieverとGeneratorを分離) |

2025/12/10

OpenSSL コマンド チートシート (PEM形式中心)

# OpenSSL コマンド チートシート (PEM形式中心)

## 証明書の表示
```bash
openssl x509 -in cert.pem -text -noout
```
- -in cert.pem : 入力する証明書ファイルを指定(PEM形式)
- -text : 証明書の詳細情報をテキスト形式で表示(Subject, Issuer, 有効期限, SANなど)
- -noout : 証明書本体(Base64エンコード部分)を出力しない

## CSR (証明書署名要求) の内容確認
```
openssl req -in request.csr -text -noout
```

## 秘密鍵の内容確認
```
openssl rsa -in private.key -check -noout
```
- -check : 秘密鍵の整合性を検証

## サーバー証明書の確認
```
openssl s_client -connect example.com:443 -servername example.com
```
- -connect host:port : 接続先ホストとポートを指定(HTTPSなら443)
- -servername host : SNI (Server Name Indication) を指定。複数ドメインを持つサーバーで正しい証明書を取得するために必要

証明書部分だけ抽出して詳細表示:
```
openssl s_client -connect example.com:443 -servername example.com /dev/null | openssl x509 -text -noout
```

## 秘密鍵とCSR作成
```
openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr
```
- -new : 新しいCSRを作成
- -newkey rsa:2048 : 新しいRSA秘密鍵を生成(2048bit)
- -nodes : 秘密鍵を暗号化せずに保存(パスフレーズなし)
- -keyout server.key : 秘密鍵の出力先ファイル
- -out server.csr : CSRの出力先ファイル

## 証明書の検証
```
openssl verify -CAfile ca.pem cert.pem
```
- -CAfile ca.pem : 信頼するCA証明書を指定

## 形式変換 (PEM中心)
#### PEM → DER
```
openssl x509 -in cert.pem -outform der -out cert.der
```
- -outform der : 出力形式をDER (バイナリ) に指定
- -out cert.der : 出力ファイル名

#### DER → PEM
```
openssl x509 -in cert.der -inform der -out cert.pem
```
- -inform der : 入力形式がDERであることを指定
- -out cert.pem : PEM形式で出力

#### PFX (PKCS#12) → PEM
```
openssl pkcs12 -in cert.pfx -out cert.pem -nodes
```
- -in cert.pfx : 入力ファイル(PKCS#12形式)
- -out cert.pem : PEM形式で出力
- -nodes : 秘密鍵を暗号化せずに出力

## 自己署名証明書
### ダミー証明書の作成(自己署名証明書を一度に生成)
```
openssl req -x509 -newkey rsa:2048 -nodes -keyout dummy.key -out dummy.crt -days 365 -subj "/CN=example.com"
```
- 秘密鍵と自己署名証明書を同時に生成
- -x509 : CSRではなく自己署名証明書を直接出力
- -days 365 : 有効期限を365日に設定
- -subj : 対話入力を省略してDNを指定(例: CN=example.com)

### 通常の3ステップの流れ
```
# (1) 秘密鍵を生成
openssl genrsa -out server.key 2048

# (2) CSRを生成
openssl req -new -key server.key -out server.csr -subj "/CN=example.com"

# (3) CSRを秘密鍵で署名して自己署名証明書を作成
openssl x509 -req -in server.csr -signkey server.key -out server.crt -days 365
```

2025/12/09

curlコマンドチートシート

## 基本操作
- **GETリクエスト**
  ```bash
  curl https://example.com
  ```


- レスポンスをファイル保存
  ```
  curl https://example.com -o output.txt
  ```

- 詳細表示(デバッグ用)
  ```
  curl -v https://example.com
  ```

---
## ヘッダー関連
- レスポンスヘッダーのみ表示
  ```
  curl -I https://example.com
  ```

- リクエストヘッダー追加
  ```
  curl -H "Authorization: Bearer TOKEN" https://example.com
  ```

---
## 認証
- BASIC認証
  ```
  curl -u user:password https://example.com
  ```

- Cookie認証
  ```
  curl -c cookie.txt -d "id=user&pw=pass" https://example.com/login
  curl -b cookie.txt https://example.com/data
  ```

---
## HTTPメソッド指定
- POSTリクエスト
  ```
  curl -X POST -d "key=value" https://example.com
  ```

- JSONデータ送信
  ```
  curl -X POST -H "Content-Type: application/json" -d '{"key":"value"}' https://example.com/api
  ```

- PUTリクエスト
  ```
  curl -X PUT -d @file.json https://example.com/api
  ```

---
## ファイル操作
- ダウンロード(元のファイル名を保持)
  ```
  curl -O https://example.com/file.zip
  ```

- 複数ファイルダウンロード
  ```
  curl -O URL1 -O URL2
  ```

---
## その他便利オプション
- リダイレクトを追跡
  ```
  curl -L https://short.url
  ```

- 通信内容をダンプ
  ```
  curl --trace-ascii - https://example.com
  ```

- 処理時間を表示
  ```
  curl -w "%{time_total}\n" https://example.com
  ```

- SSL検証を無視(テスト用途のみ推奨)
  ```
  curl -k https://example.com
  ```

2025/11/12

PowerShellコマンド:Test-NetConnection 使用例

## 基本構文
```
Test-NetConnection [-ComputerName] <string> [-Port <int>] [-InformationLevel <string>] [-TraceRoute]
```

## 使用例一覧
### 1. ホストへの接続確認(Ping相当)
```
Test-NetConnection www.google.com
```

- ホスト名の名前解決と ICMP 通信確認
- PingSucceeded が True なら疎通可能

### 2. TCPポートの疎通確認(例:443)
```
Test-NetConnection -ComputerName 192.168.1.10 -Port 443
```

- 指定IPの443番ポートにTCP接続できるか確認
- TcpTestSucceeded が True ならポートが開いている

### 3. ホスト名+ポート確認(DNS解決付き)
```
Test-NetConnection -ComputerName example.com -Port 80
```

- ホスト名をDNSで解決し、HTTPポート(80)への接続確認

### 4. トレースルート付きで確認
```
Test-NetConnection www.microsoft.com -TraceRoute
```

- 通信経路(ルーターのホップ)を表示

### 5. LAN内のIPに対して443ポート確認(スクリプト)
```
$subnet = "192.168.1"
1..254 | ForEach-Object {
    $ip = "$subnet.$_"
    $result = Test-NetConnection -ComputerName $ip -Port 443 -WarningAction SilentlyContinue
    if ($result.TcpTestSucceeded) {
        Write-Host "$ip is listening on port 443"
    }
}
```

- サブネット内の全ホストに対して443ポートの疎通確認
- 成功したIPのみ表示

## 出力例
```
ComputerName     : 192.168.1.10
RemoteAddress    : 192.168.1.10
RemotePort       : 443
InterfaceAlias   : Ethernet
TcpTestSucceeded : True
```

2025/10/13

決算書を俯瞰する

## PL
> * PLの基本は、収益ー費用=利益

### 売上総利益率でビジネスモデルをイメージする
> * ビジネスモデルの違いが売上総利益率に表れる。
> * 売上総利益(粗利)は、付加価値、希少性を表す。


### 本業の収益力を如実に表す営業利益
> * 同業他社間での利益率を比較することには意義がある。
> * 営業利益が赤字になると会社の継続性が問題になる可能性が生じる。

### 本業の収益力+財務の収益力=会社の収益力
> * 経常利益は、本業の収益力に財務の収益力が加わった会社の収益力を表す。

### 特別利益と特別損失
> * 経常利益+特別利益ー特別損失=税引前当期純利益(税引等調整前当期純利益)
> * 特別利益、特別損失は企業が構造改革(リストラクチャリング)を断行する際につきまとう項目。

### PLを2期比較する
> * PLは数期間の推移を取ることで会社のトレンドが把握できる。
> * 当期純利益が最終利益と呼ばれ投資家視点で見た場合の利益と言える。
> * それまでの4つの利益は段階利益と言われ過程の利益に過ぎない。
## BS
### 自己資本比率は高いほど良い
> * 資産=負債+純資産
> * 純資産が最も重要な数値を示す。
> * 負債は返さなければならないもの。純資産は返さなくていいもの。
自己資本比率=69.9%

> * BSを見る時は、自己資本比率(純資産/純資産+負債)を最初にチェックする。
> * 自己資本比率は高いほど良い。(25%以下だと低く、40%以上だと高いくらいの目安)

### 資産の中身
> * 流動資産は、現金あるいは現金に近いもの
> * 固定資産は、工場や工場設備といった会社で使うもので、現金を投下して購入したもの
> * 自己資本比率が高いということは
>   * お金を借りる必要がなかった
>   * 多額の固定資産を購入する必要がなかった
> * 自己資本比率が低いということは
>   * お金を借りる必要があった
>   * 多額の固定資産を購入する必要があった(製造業と推定される)

### BSの右側と左側の関係
> * BSの右側は「会社の元手」=お金をどうやって集めたか?
> * BSの左側は「会社の財産」=お金をどう使ったか?
> * BSの規模が大きく変化した場合には、それが「負債」によって調達されたものか?「純資産」によって調達されたものか?を見る必要がある。
### BSの右側と左側の関係
> * BSの右側は「会社の元手」=お金をどうやって集めたか?
> * BSの左側は「会社の財産」=お金をどう使ったか?
> * BSの規模が大きく変化した場合には、それが「負債」によって調達されたものか?「純資産」によって調達されたものか?を見る必要がある。

### BSのタイプ
> * 流動負債は、1年以内に支払わなくてはいけない負債
> * 固定負債は、1年を超えて支払えばいい負債

#### 安泰型
#### 安定型
#### 不安型
## CF
> * 営業活動によるCFは、プラスであることが会社継続の前提。営業活動自体から得られるCFを示す。
> * 投資活動によるCFは、設備投資や有価証券の取得でマイナスとなり、それらの処分・売却でプラスとなる。
> * 財務活動によるCFは、借入金の返済でマイナスとなり、借入金・社債・株式発行などの資金調達でプラスとなる。
### 減価償却は実際の現金の支出を伴わない費用
|CF|PL|
|---:|---:|
|売上 100|売上 100|
||**減価償却** △30|
|その他の費用 △20|その他の費用 △20|
|差額 80|差額 50|
|(キャッシュの増加)|(利益)|

> * 現金の増加 80 = 利益 50 + 減価償却 30

### CFのタイプ

2025/10/11

CodePipelineによるCI/CD

# CodeCommit
## HTTPS方式でアクセスする場合
予め、~/.aws/configファイルにプロファイルを作成し、リージョンや、アクセスキーを設定しておく。
```
[profile git]
region = us-east-1
output = json
aws_access_key_id = xxxxxxxxxxxxxx
aws_secret_access_key = xxxxxxxxxxxxxxxxx
```

以下のコマンドでローカルにあるIAMのクレデンシャル情報を用いてGitリポジトリに接続(git clone等)できるようになる。
```
$ git config --global credential.helper "!aws --profile git codecommit credential-helper $@"
$ git config --global credential.UseHttpPath true
```

## index.html, buildspec.yml, appspec.ymlをリポジトリへ格納
* buildspec.yaml
```
version: 0.2
phases:
  build:
    commands:
      - echo "Build step (optional)"
artifacts:
  files:
    - index.html
    - appspec.yml
```

* appspec.yml
```
version: 0.0
os: linux
files:
  - source: index.html
    destination: /var/www/html
```

# EC2設定
## EC2インスタンス作成
- AMI:Amazon Linux 2
- インスタンスタイプ:t2.micro
- セキュリティグループ:
- ポート 22(SSH)
- ポート 80(HTTP)

## Apache設定
```
sudo yum update -y
sudo yum install -y httpd
sudo systemctl start httpd
sudo systemctl enable httpd

curl http://localhost
```

## CodeDeployエージェント
[Amazon Linux または RHEL 用の CodeDeploy エージェントをインストールする](https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/codedeploy-agent-operations-install-linux.html)

```
sudo yum install -y ruby wget
cd /home/ec2-user
wget https://aws-codedeploy-ap-northeast-1.s3.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto
sudo systemctl start codedeploy-agent
sudo systemctl enable codedeploy-agent
sudo systemctl status codedeploy-agent
```

## IAMロール
- EC2にアタッチするIAMロールに以下のポリシーを付与:
  - AmazonEC2RoleforAWSCodeDeploy

## 次のステップ
- EC2がApacheで /var/www/html/index.html を表示できる状態にあること
- CodeDeploy Agentが起動していること
- EC2にタグ(例:Name=ATDemoInstance)を付けて、CodeDeployのデプロイグループでターゲットに指定できるようにする

# CodeBuildの設定
## CodeBuildに与えるロール
[CodeBuild が他の AWS のサービスとやり取りすることを許可](https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/setting-up-service-role.html)

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Resource": [
                "arn:aws:logs:us-east-1:123456789012:log-group:/aws/codebuild/TestSiteBuild",
                "arn:aws:logs:us-east-1:123456789012:log-group:/aws/codebuild/TestSiteBuild:*"
            ],
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ]
        },
        {
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::codepipeline-us-east-1-*"
            ],
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:GetBucketAcl",
                "s3:GetBucketLocation"
            ]
        },
        {
            "Effect": "Allow",
            "Resource": [
                "arn:aws:codecommit:us-east-1:123456789012:repos_tmp"
            ],
            "Action": [
                "codecommit:GitPull"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "codebuild:CreateReportGroup",
                "codebuild:CreateReport",
                "codebuild:UpdateReport",
                "codebuild:BatchPutTestCases",
                "codebuild:BatchPutCodeCoverages"
            ],
            "Resource": [
                "arn:aws:codebuild:us-east-1:123456789012:report-group/TestSiteBuild-*"
            ]
        }
    ]
}
```

1. プロジェクト作成
  - AWSコンソール → CodeBuild → 「プロジェクトを作成」
  - 名前:TestSiteBuild
  - ソースプロバイダー:CodeCommit
    - リポジトリ:先ほど作成したもの
    - ブランチ:main(または使用中のブランチ)
2. 環境設定
  - 環境イメージ:マネージド型イメージ
    - OS:Amazon Linux 2
    - ランタイム:Standard
    - イメージ:aws/codebuild/standard:7.0(または最新)
  - ビルド仕様:buildspec.yml を使用
3. アーティファクト
- アーティファクトタイプ:Amazon S3
  - 新しいS3バケットを作成するか、既存のものを選択
  - 出力場所:TestSiteBuildArtifact(任意)

> このステージでアーティファクトをS3に出力する。

# CodeDeployの設定
[CodeDeployのサービスのロールを作成する](https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/getting-started-create-service-role.html)

1. アプリケーション作成
  - AWSコンソール → CodeDeploy → 「アプリケーションを作成」
  - 名前:TestSiteDeploy
  - コンピューティングプラットフォーム:EC2/オンプレミス
2. デプロイグループ作成
  - 名前:TestSiteGroup
  - サービスロール:CodeDeployServiceRole(必要なら新規作成)
    - ポリシー:AWSCodeDeployRole
  - ターゲット:EC2インスタンスのタグ
    - 例:Name=ATDemoInstance
  - デプロイタイプ:インプレース
  - アプリケーションのリビジョン場所:Amazon S3

> S3に保存されたCodeBuildの出力(アーティファクト)をCodeDeployが取得してEC2に配置する。

## CodeDeploy時のEC2側のログ
```
sudo less /opt/codedeploy-agent/deployment-root/deployment-logs//log

sudo less /var/log/aws/codedeploy-agent/codedeploy-agent.log
```

# CodePipelineの設定
[CodePipeline サービスロールを管理する](https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/how-to-custom-role.html)

1. パイプライン作成
  - AWSコンソール → CodePipeline → 「パイプラインを作成」
  - 名前:TestSitePipeline
  - サービスロール:新規作成(自動でOK)

ソースステージ(CodeCommit)
  - ソースプロバイダー:CodeCommit
  - リポジトリ:先ほど作成したもの
  - ブランチ:main(または使用中のブランチ)
  - 変更検出:Amazon CloudWatch Events(自動トリガー)

ビルドステージ(CodeBuild)
  - ビルドプロバイダー:AWS CodeBuild
  - プロジェクト:TestSiteBuild(先ほど作成したもの)
  - 出力アーティファクト名:例)BuildArtifact

デプロイステージ(CodeDeploy)
  - デプロイプロバイダー:AWS CodeDeploy
  - アプリケーション名:TestSiteDeploy
  - デプロイグループ:TestSiteGroup
  - 入力アーティファクト名:CodeBuildの出力名と一致させる(例:BuildArtifact)

# push時にCodePipelineをトリガーする
[Create an EventBridge rule for a CodeCommit source](https://docs.aws.amazon.com/codepipeline/latest/userguide/pipelines-trigger-source-repo-changes-console.html)

## EventBridgeに与えるロールを作成
```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Action": "codepipeline:StartPipelineExecution",
            "Resource": "arn:aws:codepipeline:us-east-1:123456789012:TestSitePipeline"
        }
    ]
}
```

## EventBridgeを作成
イベントパターン:対象ブランチのpushイベントを指定(下記)
ターゲット:CodePipelineのARNを指定
```
{
  "source": ["aws.codecommit"],
  "detail-type": ["CodeCommit Repository State Change"],
  "resources": ["arn:aws:codecommit:us-east-1:123456789012:repos_tmp"],
  "detail": {
    "event": ["referenceUpdated"],
    "referenceType": ["branch"],
    "referenceName": ["master"]
  }
}
```

2025/09/06

EventBridge

## EventBridgeの動作概要
### EC2とRDSインスタンスを停止・起動する例
Update: [Amazon EventBridge が IAM 実行ロールのサポートをすべてのターゲットに拡大](https://aws.amazon.com/jp/about-aws/whats-new/2025/03/amazon-eventbridge-iam-execution-role-all-targets/)

現在は、ターゲット側のリソースベースポリシーによる制御( AWS::Lambda::Permission )でなく、イベントソース側のロール指定で制御可能となっている。

```
AWSTemplateFormatVersion: 2010-09-09
Description: The template for creating EventBridge Schedule.
# -------------------------
# Metadata 
# -------------------------
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: Schedule Configuration
        Parameters:
          - EC2InstanceId
          - RDSInstanceId
          - ScheduleExpressionForStop
          - ScheduleExpressionForStart

# -------------------------
# <<< Parameters 
# -------------------------
Parameters:
  EC2InstanceId:
    Type: String

  RDSInstanceId:
    Type: String

  ScheduleExpressionForStop:
    Type: String
    Default: cron(0 13 * * ? *)  # UTC 0時 → JST 22時
    
  ScheduleExpressionForStart:
    Type: String
    Default: cron(0 23 * * ? *)  # UTC 23時 → JST 8時

Resources:
  #==========================
  # IAM Role for Lambda
  #==========================
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: LambdaSchedulerRole
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
        - arn:aws:iam::aws:policy/AmazonEC2FullAccess
        - arn:aws:iam::aws:policy/AmazonRDSFullAccess
      PermissionsBoundary: !Sub 'arn:aws:iam::${AWS::AccountId}:policy/DevelopUserBoundary'

  #==========================
  # Lambda Function
  #==========================
  SchedulerFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: EC2RDS-Scheduler
      Runtime: python3.9
      Handler: index.lambda_handler
      Role: !GetAtt LambdaExecutionRole.Arn
      Timeout: 90
      Code:
        ZipFile: |
          import boto3
          import os

          def lambda_handler(event, context):
              ec2_id = os.environ['EC2_ID']
              rds_id = os.environ['RDS_ID']
              action = event.get('action', 'start') # 初期値(EventBridgeで上書き)

              ec2 = boto3.client('ec2')
              rds = boto3.client('rds')

              if action == 'start':
                  ec2.start_instances(InstanceIds=[ec2_id])
                  rds.start_db_instance(DBInstanceIdentifier=rds_id)
              elif action == 'stop':
                  ec2.stop_instances(InstanceIds=[ec2_id])
                  rds.stop_db_instance(DBInstanceIdentifier=rds_id)

      Environment:
        Variables:
          EC2_ID: !Ref EC2InstanceId
          RDS_ID: !Ref RDSInstanceId

  #==========================
  # EventBridge
  #==========================
  # for Start
  StartSchedule:
    Type: AWS::Events::Rule
    Properties:
      Name: EC2RDSStartSchedule
      ScheduleExpression: !Ref ScheduleExpressionForStart
      State: ENABLED
      Targets:
        - Arn: !GetAtt SchedulerFunction.Arn
          Id: StartTarget
          Input: '{ "action": "start" }'

  # for Stop
  StopSchedule:
    Type: AWS::Events::Rule
    Properties:
      Name: EC2RDSStopSchedule
      ScheduleExpression: !Ref ScheduleExpressionForStop
      State: ENABLED
      Targets:
        - Arn: !GetAtt SchedulerFunction.Arn
          Id: StopTarget
          Input: '{ "action": "stop" }'

  #==========================
  # Lambda Permissions
  #==========================
  # for Start
  PermissionForEventsToInvokeLambda:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !Ref SchedulerFunction
      Action: lambda:InvokeFunction
      Principal: events.amazonaws.com
      SourceArn: !GetAtt StartSchedule.Arn

  # for Stop
  PermissionForEventsToInvokeLambdaStop:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !Ref SchedulerFunction
      Action: lambda:InvokeFunction
      Principal: events.amazonaws.com
      SourceArn: !GetAtt StopSchedule.Arn
```

人気の投稿