Yapodu Tech Blog

株式会社ヤポドゥの技術ブログです。

AWS Summit の感想・考察とおすすめしたいセッション動画

ご挨拶と記事概要

こんにちは株式会社ヤポドゥ技術部所属インフラエンジニアkojiroです。 本日は先日開催されたAWS Summit(2025/06/25・26)の感想考察と参加した14セッション中、印象にのこった!勉強になった!追加で調べたい!つまりおすすめをシェアしたい内容の記事になります。

目次

全体の印象ITトレンド

今年は何といってもAI Agentでした。ほぼ全てのセッションやトピックにAIが絡んできました。個人的にも直近でBedrockとRAGにふれていてよかったと振り返ります。ハルシネーションの改善、RAGの工夫、AIとの向き合い方、AIの取り入れ方に話題が集中していました。AI系のセッションでお勧めしたいのはやはりserver worksさんのセッションナンバーAP-36です。 AIとの向き合い方、AIのセキュリティ、AIの推進体制についてうまくまとめられており聞きごたえのある内容でした。

特に大事だと思ったキーワードで後から調べなおして理解を深める必要があるワードを列挙したいと思います。

  • AWS Audit MangerのAIベストプラクティス (AWS Generative AI Best Practices Framework v2)
  • OWASP Top10 LLM Applications
  • プロンプトインジェクション
  • AWSドキュメントセキュリティスコープ➀~⑤( 生成AIセキュリティスコーピングマトリックス )
  • 推論パラメータ Temperature
  • 階層的チャンキング
  • Advanced parsing
  • 情報と経験の両方が大事
  • 小さく早く始めてみる
  • 生成AI PoC 支援

もう一つAI Agent系のセッションでお勧めしたいのはセッションナンバーAWS-19です。こちらはAWSの公式セッションで生成AIアプリケーションの構築にあたり、気にするべきポイントや推奨するサービスを紹介してました。話題はやはりハルシネーションでAIの生成出力の精度をどのように改善したかでした。AWSが担当した様々な企業のケースを例にRAGのデータ設計の工夫をポイントに上げていました。 記事校正会社、薬剤会社、料理レシピ系のメディア会社の三つで共通していたのはRAGで取り込む文章を構造化、文章の分割をして分かり易くすることだという理解をしてます。つまりデータクレンジングに人の知恵や手間が加わる事でAI出力の精度に確実に影響がでるという内容でした。

こちらもキーワードを列挙したいと思います。

  • GenU
  • AWS Trainium2
  • AWS Inferentia 2
  • Guardrails 日本語対応
  • Amazon Q Business
  • Bedrock Advanced RAG
  • Amazon Bedrock

基調講演・SPセッション

両日オープニングセレモニーとしてメインステージで大規模なセッションがありました。AWSの白幡社長をはじめとして情報系の様々な大企業の社長・重要ポストの方のトークセッションが行われました。その中でも印象に残った方やポイント、大事だと思うキーワード等をシェアしていきたいと思います。

両日で一番印象に残ったのは株式会社ドワンゴ 代表取締役社長 夏野 剛氏です。この後、荒れそうな株主総会があるということでスケージュールの合間を縫って登壇されていました。ドワンゴニコニコ動画を運営する会社で最近では KADOKAWAを傘下に加えたコンテンツメディア会社です。今年の3月にAWSと連携して長期プロジェクトをすすめ、クラウド化が完了した経緯があり、今回のセッションが決まったようでした。会員数1億人を抱えているニコニコのコンテンツは100%オンプレミスで稼働していたようで夏野社長はセキュリティやコスト面を考えてクラウド化が課題だったとおっしゃってました。堅牢性、柔軟性、献身性、多様性を考慮し他社と徹底的に比較分析をした時にAWSが選択肢に上がったという内容でした。それを聞いて改めて勉強している内容の優位性や意義を感じ、安心感と危機感が入り混じりました。クラウド化プロジェクトは3年前からはじまり、構想段階をふくめとプラス1年という大規模な長期プロジェクトだったと振り返ってます。それでも2024年6月に大規模なサイバー攻撃を受けて、大変な目にあった事を" 経験者は語る "といった面持ちでお話し頂き、AWSに移行途中だったこともあり、後一年早ければと後悔を語っていました。その経緯もありプロジェクトの進行を早めた背景があったことも打ち明けています。今後はKADOKAWAつまり書籍コンテンツをフルクラウド化していくというプロジェクトが現在進行中の様です。個人的にアニメが好きなので人気小説家の文庫や教育書籍なども含めて書籍コンテンツのフルクラウド化がどのようなビジョン、ビジュアルやストーリーでアップデート・リリースされていくのかとても期待感を持ちました。

長くなりましたが二日間のメインセッションで大事だと思ったキーワードを列挙していきたいと思います。

運用・インフラ設計の課題領域セッション

次に紹介したいセッションはセッションナンバーAWS-50のAWSにおけるグレー障害の検出と対策になります。インフラ設計における障害対応のど真ん中の内容だと思いました。グレー障害をいかに検出・対応するかを概要から該当ケース・解決策まで聞きごたえのある内容でセッションしてくれました。こちらは僕が内容をお伝えするよりAWS Summitのwebページで上がっている動画を見ていただく事を強くお勧めします。

こちらもキーワードを列挙していきます。

  • contributor Insigte
  • 複合アラーム
  • グレイスフルグラデーション
  • AZI( Availability Zone Independent )
  • シャロー or ディープ
  • メトリクスディメンション
  • ゾーンシフト
  • AWS ARC( AWS Application Resilience Capability )
  • AWS FIS( AWS Fault Injection Simulator )
  • ジッター

興味・関心のあるセッション

こちらは個人的に興味・関心のあるセッションだった為、受講したセッションのうち、おすすめしたい内容だったものをシェアしたいと思います。 現在、第四次アニメブーム( 勝手に言ってます )的な波に飲み込まれている実感のある私ですが、アニメの制作現場にまつわる内容のセッションがありました。セッションナンバーはAWS-64になります。アニメやCG/VFXの制作現場で取り入れるべきクラウドコンテンツ入門といった内容でした。アニメ市場は現在3000億円市場とされており、そこで働く制作人のほとんどがフリーランスのクリエイターで全体の8割を占めているそうです。個人的には近年で一番分かり易く成長している、世界とすぐ繋がることが出来る、日本が世界に誇る!激強コンテンツという印象です。ポテンシャルは3000億どころではない実力を秘めた市場ではないかとたたえます。ただそんな表側の印象とは裏腹にテレビやネットで放送されている現行のアニメもその都度、反響営業で制作委員会が立ち上げられ、鮮度を過ぎた中だるみのタイミングで打ち切られる印象も強いです。そんな事情も含んでいる制作現場の課題として人材不足やリソース不足、オフィスとリモート、コストの最適化の問題を解決してきたのがAWSだったようです。アニメーターの仕事に対してリスペクトしかわかない程、重労働な印象が強いのですがやっと時代が追い付いてきて、アニメの質とスピードの両立が実現しようとしていると思います。脱線しましたがセッションの内容はAWS初学者にも優しい内容かつこの分野でしか出てこないようなサービスも紹介されていました。

ここでもキーワードのみ列挙していこうと思います。

  • AWS Deadline Cloud( レンダリングファーム )
  • AWS DCV + EC2( ハンズオンありリモートで高性能マシンを使える技術 )
  • App Stream 2.0
  • モニターとサブミッターのインストール
  • AWS Deadline Cloudはスポットインスタンスで実装されている相性が良い。

最後に紹介したいセッションはセッションナンバーCUS-24のGMO決済システムで内製開発の9年間の歩みを紹介したセッションです。こちらもオンプレミスからクラウドへの段階移行のストーリーですが社内エンジニアの声から動き出したプロジェクトとしてとても聞きごたえがあり、現状とてもうまくいっているケースとして紹介されています。 ルールを決めてクラウドの恩恵を最大限、活かせる移行にするため、EC2の使用を禁止し、オンプレのアプリケーションをそのまま持ってこないようにしたというエピソードはとても本質をついていると思いました。 タイムアウトを待ってエラーを返すより即時にエラーを返した方がユーザー体験がいいという言葉は名言だと思います。

こちらもキーワードを列挙していこうと思います。

  • クラウド警察
  • SageMaker
  • Workspaces
  • マルチQR決済GW
  • PrivateLink
  • クラウドの良さを取り入れないと意味がない
  • エンジニアのモチベーションファースト( 触ってみたいを採用した )
  • マネージドをつかう
  • エンタープライズサポートに切り替える時期

まとめと案内

今回は特に印象に残ったセッションを紹介しましたが興味深かったもの、勉強になったセッションはほかにもたくさんありました。あくまでも僕が受講したセッションの中で独断と偏見でセレクトしています。

そして全てではないようなのですが期間限定でAWS Summitのセッションを見返せるページが開設されていましたので紹介しておきます。 https://summitjapan.awslivestream.com/ ※アカウント登録をしていないと見れません。

記事で紹介したセッションナンバーは以下になります。

AP-36 AWS-19 SP-01 KEY-01 AWS-50 AWS-64 CUS-24

年々規模を増して広がりを見せるAWSですが来年もぜひ参加し、トレンド同行と勉強の継続をしていきたいです。 これで" AWS Summit の感想考察とおすすめしたいセッション動画 "を終わります。

あなたの正義はどっち?命名規則とシークレット名

ご挨拶と記事概要

こんにちは株式会社ヤポドゥ・技術部所属、インフラエンジニア見習いのkojiroです。 今回はAWS Secrets Managerを使用する際に自動で生成されるシークレット名をカスタム可能かについて投稿します。 尚、こちらの投稿はAWS RDS系DBの環境変数をSecrets Manager管理にする場合にフォーカスしています。 DBを使わないケースのプロジェクトは昨今、稀ではありますがそれ以外のケースを割愛しておりますことをお断りしておきます。

目次

TerraformでSecrets Managerを使ってみた

TerrafromでSecret Managerを有効にするコマンドは以下の様に構成します。

resource "aws_rds_cluster" "main" {
  cluster_identifier           = "myapp-db"
  engine                       = "aurora-postgresql"
  manage_master_user_password = true
}

上記コマンドで大事な箇所はmanage_master_user_password = trueであり このコマンドがあることでSecrets Managerが起動し、DBの環境変数を自動生成、自動管理、自動連携してくれます。

Secrets Managerがシークレット名( 環境変数データの識別子 )を生成します。

rds!cluster-myapp-db-a1b2c3d4e5.....

このシークレット名を使ってTerraformに環境変数が渡されます。この時Terraformがシークレット名を管理していない事も重要なポイントです。 シークレット名の確認コマンドは以下になります。

aws secretsmanager list-secrets \
  --query "SecretList[?starts_with(Name, 'rds!cluster-')].Name" \
  --output text

シークレット名を使いたくない理由

このセクションではSecrets Managerで生成されたシークレット名を使いたくない理由を列挙していこうと思います。まるで恨み節のように。

➀シークレット名は長くてかっこ悪い使いづらい。

➁Terraformでせっかく決めた命名規則と足並みがそろわない。

➂シークレット名だけ他の変数名と比べて浮いてしまう。セキュアなはずなのに目立つからなんだか不安。

④とにかく使いたくない。コントロールしたい。

技術的な側面はそっちのけで感情論をぶつけて、無理やり広げてみました。

たったの4つでした。でも共感してほしい。

シークレット名を分解してみた

Secret Managerで生成されたシークレット名を分解し、それがどのような内容なのか調べてみるとなんとなく見えてくる大事なポイントがあります。

シークレット名( 見本 )

rds!cluster-myapp-db-a1b2c3d4e5.....

構成分解

rds!cluster : AWSが予約している接頭辞( プレフィックス )

myapp : インフラコードcluster_identifierの箇所で指定した名前が使われる。唯一任意に決められる命名箇所。

a1b2c3d4e5.... : AWSが自動生成したランダムID識別子 そしてこのシークレット名に紐づけられて呼び出される中身が以下のようなjson形式の内容になります。これがシークレット名の実体であり、環境変数として渡されます。

{
  "engine": "aurora-postgresql",
  "host": "example.cluster-abcdefghij.us-west-2.rds.amazonaws.com",
  "username": "master",
  "password": "5L8*kswJdK!zqT2h",
  "dbname": "postgres",
  "port": 5432
}

こちらの内容もAWS側で自動生成され、RDSとSecrets Managerが話し合って決定します。 内容をカスタムすることは当然できません。 シークレット名に紐づいて呼び出す内容(json)を使って、それぞれの項目に合わせて名前と値で呼び出す、キーとバリューの関係でマッピングしていくRDSとSecrets Managerの連携システムです。

それを踏まえて見えてきそうなこと、

  • シークレット名って大事そう。
  • 予約しているプレフィックスと長いランダムIDで出来てるんだ!
  • シークレット名の中身ってjsonなんだ。
  • それってRDSとSecrets Managerが話し合って決めているんだ!

結論

  • シークレット名はカスタム不可能な大事な識別子です。
  • Terraformの命名規則にあわせてresource構文を使い、変数名を再定義( rds!cluster-myapp-db-a1b2c3d4e5..... = secrets_myapp_db )しようものなら即座にRDSとの連携が壊れます。AWS側で認識されなくなります。( Terraformが管理していない理由 )

自己管理 VS AWS管理

結論を踏まえてそれでも自分で決めた命名規則環境変数を運用したい場合 manage_master_user_password = trueをTerraformで指定せず、自前で

resource "aws_secretsmanager_secret" "myapp_db" {
  name = "secrets_myapp_db"
}

resource "aws_secretsmanager_secret_version" "myapp_db_version" {
  secret_id     = aws_secretsmanager_secret.myapp_db.id
  secret_string = jsonencode({
    username = "admin"
    password = "your-secure-password"
    engine   = "aurora-postgresql"
    host     = "myapp-db.cluster-xxxxxx.ap-northeast-1.rds.amazonaws.com"
    port     = 5432
  })
}

などとして定義してしまいましょう。

そうすればTerraform管理で他のリソースとの命名に足並みをそろえた実装を可能にします。

Terraformの命名規則を使い慣れている人ならその管理コストはSecrets Managerを使うよりコスパがいいと判断する見方もあるかもしれません。

セキュリティーの強度に少しの優劣があるものの、やっている事の本質に大きな違いはありません。 ただ重要なのはこの後です。

AWS環境変数の運用にあたってSecrets Managerを使う事を推奨している点に有無を言わさぬ、正義があります。

推奨理由として以下があげられるでしょう。

  • AWS環境変数をすべて自動で管理してくれる
  • AWSが強力なランダムパスワードを自動生成してくる
  • パスワードを自動でローテーションをしてくれる
  • 設定ミスのリスクがほとんどない
  • AWSベストプラクティスに準拠出来る
  • AWS他サービスとネイティブに連動する

以上の理由から自己管理で使いやすい名前を取るか、AWS管理でコントロールできない長い名前を使うか、天秤にかけ決断してください。

以上で" あなたの正義はどっち?命名規則とシークレット名 "を終わります。

参考資料 : AWS公式ページURL https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-secrets-manager.html?utm_source=chatgpt.com

RDSとsecrets managerが密に連携してパスワードが生成されているようでそこにterraformの変数名の定義が入り込む余地はない解釈です。

仮に動作してもAWSは推奨していない為、誤動作があっても責任を取らないというスタンスだと思います。

AI Agent, MCP, Bedrock Knowledge Baseで作るAIハンズオン (Part 2 - 実践編・AIエージェントを動かす)

はじめに

前回の Part 1 では、Terraform を使用して AWS 環境(Aurora PostgreSQL、S3、Amazon Bedrock Knowledge Base)を構築しました。

今回の Part 2 では、構築した環境を活用して、LangChain ベースの AI エージェントアプリケーションをローカル環境で起動し、以下の連携動作を確認します

  • Amazon Bedrock Knowledge Base を使用した RAG による情報検索
  • Asana MCP Server を通じたタスク管理システムとの連携
  • LangChain による両システムの統合

AI エージェントのローカル起動

Asana MCP Server と作成済みの Knowledge Base を使用し、LangChain ベースの AI エージェントアプリをローカル環境で起動・動作確認します。

Asana MCP Server について

本記事では、Asana との連携に サードパーティー製の MCP Server を使用しています。
Asana 公式の MCP Server も存在しますが、こちらは OAuth 認証が必要となっています。今回の検証環境では、よりシンプルに動作確認を行うため、Personal Access Token(個人アクセストークン)で認証可能なサードパーティー製を採用しました。

github.com

注意事項

サードパーティー製ツールを使用する際は、以下の点にご注意ください

  • Slack のように、ある日突然 API の利用制限が厳しくなる可能性があります
  • 本番環境での利用時は、公式の OAuth 認証方式の採用も検討してください
  • API の利用状況を定期的に監視し、制限に達しないよう注意が必要です

.env 作成

アプリで使用する2つの情報を .env に指定します。

  • Knowledge base 作成時に控えた Knowledge Base ID
  • Asana Personal Access Token (個人アクセストークン)

ypd-langchain ディレクトリに移動

$ cd ypd-langchain

.env.example を元に起動用 .env をコピー作成

$ cp -p .env.example .env 

各自取得した値で .env を修正してください。

ASANA_ACCESS_TOKEN="2/1206666666666666/1210555555555555:ffff3333ddd444444fffff222eeeeeee"
BEDROCK_KNOWLEDGE_BASE_ID="NNIDIDIDID"

LangChain アプリコンテナ Build

ypd-langchain/docker ディレクトリに移動し Docker 関連のファイルが存在することを確認してください。

$ cd docker
$ ls
Dockerfile  docker-compose.yml

docker compose build でイメージをビルド

$ docker compose build

成功時の出力例

 => [app] resolving provenance for metadata file                                                                                                                 0.0s
[+] Building 1/1
 ✔ app  Built                              

コンテナイメージの確認

$ docker images | grep ypd-langchain-app
ypd-langchain-app                                                                      latest         f4d307d9778d   4 hours ago    559MB

LangChain アプリコンテナ 起動

docker compose up でコンテナを起動

$ docker compose up

上記コマンドを実行すると、localhost:8000API が利用可能になります。
成功時の出力例

app-1  | INFO:main:Asana MCP client initialized successfully
app-1  | INFO:botocore.credentials:Found credentials in environment variables.
app-1  | INFO:knowledge_base:Knowledge Base retriever initialized for ID: NNIDIDIDID
app-1  | INFO:main:Knowledge Base client initialized successfully
app-1  | INFO:     Application startup complete.
app-1  | INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)

Local 環境での AI Agent 動作確認

localhost への curl でアプリの動作確認を実施します。

一般的な質問の例

curl -X POST http://localhost:8000/generate \
     -H "Content-Type: application/json" \
     -d '{"prompt": "こんにちは"}'

成功時の出力例

{"response":"こんにちは!今日はどんなことをお手伝いできますか?質問があれば、遠慮なく聞いてくださいね。元気に過ごせていますか?"}

Asana 関連の質問例

Asana プロジェクトの一覧確認

# プロジェクトの確認
curl -X POST http://localhost:8000/generate \
     -H "Content-Type: application/json" \
     -d '{"prompt": "現在のプロジェクト一覧を見せて"}'

成功時の出力例

{"response":"現在利用可能なプロジェクトは以下の通りです:\n\n1. Yapodu OpenAI & SD\n2. 技術ブログ\n\nこれらのプロジェクトは、ワークスペース「yapodu.co.jp」内に存在しています。"}

Knowledge Base 関連の質問例

レコードリストの確認

curl -X POST http://localhost:8000/generate \
     -H "Content-Type: application/json" \
     -d '{"prompt": "レコードのリストはありますか?"}'

成功時の出力例

{"response":"以下に、関連する文書からレコードのリストを抜粋しました。\n\n### Jazz レコードのリスト\n1. **Great Jazz Trio** - At Village Vanguard\n2. **Tina Brooks** - True Blue\n3. **Miles Davis** - Kind Of Blue\n4. **Miles Davis Quintet** - Cookin'\n5. **Miles Davis** - My Funny Valentine\n6. **Miles Davis** - Birth of the Cool\n7. **John Coltrane** - Ballads\n8. **John Coltrane** - Blue Train\n9. **John Coltrane** - A Love Supreme\n10. **Lee Morgan** - The Sidewinder\n11. **The Jazz Messengers** - At the Cafe Bohemia\n12. **Art Blakey & The Jazz Messengers** - Moanin'\n13. **Freddie Hubbard** - Hub-Tones\n14. **Dexter Gordon** - Our Man in Paris\n15. **Dexter Gordon** - Go\n16. **Sonny Clark** - Cool Struttin'\n17. **Sonny Rollins** - Saxophone Colossus\n18. **Cannonball Adderley** - Somethin' Else\n19. **Bill Evans Trio** - Portrait in Jazz\n20. **Bill Evans Trio** - Sunday at the Village Vanguard\n21. **The Oscar Peterson Trio** - We Get Requests\n22. **Herbie** - [不明]\n\n### 関連文書\n- **vinyl_record.xlsx** からの抜粋\n- **bass.csv** からの抜粋\n\nこれらのリストはJazzレコードに限定されています。他のジャンルのレコードについては、さらなる検索が必要です。"}

動作確認不可時の確認箇所

  • .env に正しい値を指定して build しているか?
  • .env 修正前に build していないか?
  • build & up 実行時に AWS 環境変数は全て設定されているか?

Part 2 まとめ

本記事では、AI エージェントアプリケーションのローカル環境での起動と動作確認を行いました。

確認できた内容

  • Docker を使用した開発環境の構築
  • Knowledge Base からの情報検索(RAG)
  • Asana MCP Server を通じたプロジェクト情報の取得
  • LangChain による両システムの統合動作

さらに試してみよう

構築した環境では、以下のような発展的な操作も可能です

1. RAG のデータソースを拡充

Knowledge Base の S3 バケットに追加のドキュメントをアップロードし、同期を実行することで、AI エージェントの知識を拡張できます

  • 社内ドキュメント(PDF、Word、Excel
  • 技術仕様書やマニュアル
  • FAQ やナレッジベース記事

追加後は様々な質問を試してみましょう:

# 例:追加したドキュメントに関する質問
curl -X POST http://localhost:8000/generate \
     -H "Content-Type: application/json" \
     -d '{"prompt": "社内の開発ガイドラインについて教えて"}'

2. Asana MCP を使ったタスク操作

現在の実装では情報取得が中心ですが、Asana MCP Server はタスクの作成や更新も可能です

# 例:新しいタスクの作成依頼
curl -X POST http://localhost:8000/generate \
     -H "Content-Type: application/json" \
     -d '{"prompt": "技術ブログプロジェクトに「Part 3 執筆」というタスクを追加して"}'

これらの機能を活用することで、単なる情報検索を超えた、実用的な AI アシスタントとして活用できます。

動作確認完了後の destroy 実行

terraform apply で作成したすべてのリソースを、terraform destroy コマンドで一括削除します。 terraform/environment/dev-ypd/default ディレクトリに移動し、以下のコマンドを実行してください。

$ cd terraform/environment/dev-ypd/default
$ terraform destroy

apply の時と同様に、削除対象のリソース一覧が表示され、実行の確認を求められます。
内容を確認し、問題がなければ yes と入力してください。
数十のリソースが順次削除されていきます。Aurora クラスターの削除には10分以上かかる場合があります。

次回の Part 3(解説編)では、このシステムの内部構造や技術的な仕組みについて解説します。

AI Agent, MCP, Bedrock Knowledge Baseで作るAIハンズオン (Part 1 - AWS 環境構築編)

はじめに

2025年は AI Agent や MCP (Model Context Protocol) といった技術が注目を集めています。これらは、複数の外部システムと連携しながら、対話的にタスクを実行する“拡張可能なAI”を実現するための重要な要素です。

今回から、AI Agent を使って Knowledge Base と Asana MCP Server を連携させることで、AI がどのように情報を取得・処理・応答するのかを段階的に確認していきます。 今回は ローカル環境での動作確認を前提として、Terraform による AWS リソースの構築から始め、最終的に AI Agent の仕組みを理解することを目指します。

本シリーズの構成 このブログは全3回構成でお届けします。

  • AWS 環境構築編 - Part 1

    • Terraform を用いた AWS 環境の構築を行い、ベクターDB(Aurora PostgreSQL)と Knowledge Base の初期設定・動作確認を行います。
  • 実践編 - Part 2

    • 構築済みの環境を使って、ローカルでコンテナを起動し、AI Agent が Asana MCP Server や Knowledge Base と連携して動作する様子を実際に確認します。
  • 解説編 - Part 3

    • AI Agent の内部構造や、MCP Server を通じた外部API連携、ベクター検索による回答生成の流れを技術的に解説します。

ハンズオンで構築するアプリケーションの全体像

このシリーズを通して、以下の機能を統合したAIエージェントアプリケーションを構築し、ローカル環境で動作させます。

AWS上のKnowledge Base(RAG)からの情報参照や、Asana MCPサーバーを通じてAsanaのタスクが操作を行えます。

なお、本ハンズオンではフロントエンドUIは構築しません。動作確認は、curlコマンド等でバックエンドに直接APIリクエストを送信して行いますので、あらかじめご了承ください。

前提

ハンズオン動作環境

このハンズオンは以下の環境で動作確認をしています

ハンズオン用 GitHub レポジトリ

GitHub - yapodu-inc/ypd-langchain-agent-hands-on: 株式会社ヤポドゥAIエージェント開発の基礎ハンズオン用レポジトリ

推奨環境(Windows

macOS での実施について

本ハンズオンは Linux 環境を前提に作成されていますが、Docker Desktopがインストールされた macOS でも実施可能です。ただし、一部のコマンドやパスの指定方法が異なる場合があります。

必要なツール

  • Docker および Docker Compose v2.x
    • Compose は公式手順であればオプションとしてインストールされています。
  • Git
  • VS Code
  • Terraform

AWS アカウント

以下のいずれも AdministratorAccess 相当の権限を持つ必要があります。

  • マネジメントコンソールへのアクセス権(UI操作用)
  • Terraform ・ AWS CLI を使用するための API 認証情報(アクセスキー・シークレットキーなど)

Asana アカウント

参加者の前提スキル

  • AWS CLI 用の環境変数を設定できる
  • Docker の基本操作を理解している
    • 例: docker build, docker run, docker compose up
  • Terraform の基本的なコマンドを理解している
    • terraform init, plan, apply の一連の流れを説明できる、または実行した経験がある

Part 1: 環境構築の実践

tfstate 用 S3 バケット作成

Terraform の tfstate(状態ファイル)を管理するための S3 バケットを作成します。
tfstate は、Terraform がインフラの現在の構成を追跡するために使用する重要な情報です。

Region 指定

マネージメントコンソールの AWS region を us-west-2 (オレゴン) に指定

CloudShell を起動する

環境変数オレゴンが設定されていることを確認

~ $ echo $AWS_REGION
us-west-2

tfstate 用 S3 バケット手動作成

CloudShell で tfstate 用 S3 バケットを作成します。

CloudShell 上で以下のコマンドを実行して、任意の名前(例として AWS アカウント ID を含めたもの)で S3 バケットを作成します。

~$ aws s3 mb s3://yapodu-hands-on-$(aws sts get-caller-identity --query Account --output text) --region us-west-2

バケット名は Terraform のコードに記載するため、テキスト等に控えてくおいて下さい。

作成後にマネージメントコンソールの
[ S3 ] -> [ 汎用バケット ]
に作成したバケット名が表示されていることを確認して下さい。

terraform apply 前確認

terraform apply を実行する前に、準備と確認を行います。

git clone と VS Code 起動

ハンズオン用のリポジトリをローカル環境にクローンします。

$ git clone https://github.com/yapodu-inc/ypd-langchain-agent-hands-on.git

クローン完了後、VS Code でプロジェクトを開きます

$ cd ypd-langchain-agent-hands-on
$ code .

VS Code が起動したら、以下の構成を確認してください
terraform/ - AWS リソース定義(Part 1 で使用)
ypd-langchain/ - AI エージェントアプリケーション(Part 2 で使用)
doc/ - ドキュメントとサンプルデータ

Terraformの version 確認

今回のハンズオンでは Terraform 1.12.1 を使用します。 WSL2 上で Terraform のバージョンが一致しているか確認し、未インストールまたは異なるバージョンの際はインストールして下さい。

WSL2での確認例

$ terraform version 
Terraform v1.12.1
on linux_amd64

tfenv で version 指定する例

以下は tfenv を使用したバージョン指定の Terraform インストール方法です。

tfenv インストール

$ git clone https://github.com/tfutils/tfenv.git ~/.tfenv

tfenv パス指定

$ echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bashrc
$ source ~/.bashrc

Terraform 1.12.1のインストールと確認

$ tfenv install 1.12.1
$ tfenv use 1.12.1
$ terraform --version

terraform backend の修正

terraform/environment/dev-ypd/default/backend_dev-ypd.tfbucket を CloudShell で作成したバケット名に修正して下さい。

# bucket= 作成したS3バケットの名前を指定して下さい。
terraform {
  backend "s3" {
    bucket = "terraform-backend-yapodu-ai-bot-123456789012"
    key    = "terraform/state/yapodu-ai-bot/ypd-dev/default/terraform.tfstate"
    region = "us-west-2"
  }
}

AWS環境変数の設定

ローカル環境にAWS用の環境変数を設定して下さい。

本来、Terraform を実行する際に環境変数による認証情報の指定は非推奨ですが、本ハンズオンではセットアップを簡易にするため、この手順を採用します。

AWS 関連環境変数

AWS CLI 確認

Terraform 実行前に AWS CLI を実行し AWS 認証情報が設定されていること、 S3 バケット名が表示されることを確認して下さい。

AWS 認証情報

$ aws sts get-caller-identity

成功時の出力例

{
    "UserId": "AROACCCCCCCCCCCCCCCCC:example.example-ac@yapodu.co.jp",
    "Account": "123456789012",
    "arn:aws:iam::123456789012:user/example-ac"
}

S3 一覧

$ aws s3 ls

成功時の出力例
作成した S3 バケット名が出力されていることを確認して下さい。

2025-06-07 11:49:47 yapodu-hands-on-123456789012

terraform init 実行

Terraform のプロバイダーやバックエンドを初期化し、必要なプラグイン / モジュールをダウンロードするために init を実行します。

$ cd terraform/environment/dev-ypd/default
$ terraform init 

成功時の出力例

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

init 実行後の validate & plan 確認

terraform validate で構文エラーがないかを確認し、terraform plan でこれから適用されるリソースの内容を事前確認します。


validate 実行

$ terraform validate 

成功時の出力例

Success! The configuration is valid.



plan 実行

$ terraform plan

成功時の出力例

Plan: 39 to add, 0 to change, 0 to destroy.

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

plan を確認することで、意図しないリソース作成・削除を未然に防ぐことができます。必要に応じて追記も可能です。

apply 実行

準備が完了したので、terraform apply を実行してインフラを構築します。

terraform apply

実行内容が表示されたあと、以下のようなプロンプトが表示されます。
プロンプトで表示される内容を確認し、yes と入力することでリソースの作成が開始されます

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

成功時の出力例

aws_rds_cluster_instance.main_db_01: Still creating... [09m00s elapsed]
aws_rds_cluster_instance.main_db_01: Creation complete after 9m3s [id=ypd-dev-aurora-main]

Apply complete! Resources: 39 added, 0 changed, 0 destroyed.

terraform apply によって AWS リソースの第1段が作成されました。続いて PostgreSQL の設定を行います

Knowledge Base 用のベクターデータベース設定(Aurora PostgreSQL

terraform apply が完了すると、AWS コンソールの
[ RDS ] -> [データベース ]
に Aurora クラスタypd-dev-aurora-main-cluster が作成されています。 この Aurora PostgreSQL を、Amazon Bedrock Knowledge Base のベクターデータベースとして使用するための設定を行います。

Data API 経由で必要な PostgreSQL 拡張機能(pgvector)と、埋め込みベクトル保存用のテーブルを作成します。
以下の手順のリソース名を作成されたリソース名へ置き換えて実行してください。

1. 必要情報取得

1.1. Aurora クラスター情報の確認

aws rds describe-db-clusters \
  --db-cluster-identifier "ypd-dev-aurora-main-cluster" \
  --region us-west-2 \
  --query 'DBClusters[0].{ClusterArn:DBClusterArn,DatabaseName:DatabaseName,MasterUsername:MasterUsername,HttpEndpointEnabled:HttpEndpointEnabled}'

出力例:

{
    "ClusterArn": "arn:aws:rds:us-west-2:123456789012:cluster:ypd-dev-aurora-main-cluster",
    "DatabaseName": "main_db",
    "MasterUsername": "ypodu_pdadmin",
    "HttpEndpointEnabled": true
}

1.2. Secrets Manager の認証情報ARN取得

aws secretsmanager list-secrets \
  --region us-west-2 \
  --query 'SecretList[?contains(Name, `rds`)].{Name:Name,ARN:ARN}'

出力例:

[
    {
        "Name": "rds!cluster-c8888888-d222-1c11-999c-445cc44444444",
        "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:rds!cluster-c8888888-d222-1c11-999c-445cc44444444-CMHOsq"
    }
]

2. Aurora PostgreSQL の初期設定(Data API

DATA API(SQL を直接 HTTP 経由で実行できる API) を使用して Aurora PostgreSQL に必要な拡張機能とテーブルを作成します。
取得した ClusterArn と Secret ARN を使って、以下のリソースを作成します。 以下のコマンドの
--resource-arn,
--secret-arn
は適宜置き換えてください。

2.1. pgvector 拡張の有効化

aws rds-data execute-statement \
  --resource-arn 'arn:aws:rds:us-west-2:123456789012:cluster:ypd-dev-aurora-main-cluster' \
  --secret-arn   'arn:aws:secretsmanager:us-west-2:123456789012:secret:rds!cluster-c8888888-d222-1c11-999c-445cc44444444-CMHOsq' \
  --database     'main_db' \
  --sql          'CREATE EXTENSION IF NOT EXISTS vector;' \
  --region       us-west-2

2.2. Bedrock Knowledge Base 用テーブルの作成

Titan V2 に対応するため、vector(1024) 型を使用します。

aws rds-data execute-statement \
  --resource-arn 'arn:aws:rds:us-west-2:123456789012:cluster:ypd-dev-aurora-main-cluster' \
  --secret-arn   'arn:aws:secretsmanager:us-west-2:123456789012:secret:rds!cluster-c8888888-d222-1c11-999c-445cc44444444-CMHOsq' \
  --database     "main_db" \
  --sql          "CREATE TABLE IF NOT EXISTS bedrock_knowledge_base (
                    id        UUID PRIMARY KEY DEFAULT gen_random_uuid(),
                    embedding vector(1024),
                    chunks    TEXT NOT NULL,
                    metadata  JSONB
                 );" \
  --region       us-west-2

2.3. テキスト検索用 GIN インデックスの作成

aws rds-data execute-statement \
  --resource-arn 'arn:aws:rds:us-west-2:123456789012:cluster:ypd-dev-aurora-main-cluster' \
  --secret-arn   'arn:aws:secretsmanager:us-west-2:123456789012:secret:rds!cluster-c8888888-d222-1c11-999c-445cc44444444-CMHOsq' \
  --database     'main_db' \
  --sql          'CREATE INDEX IF NOT EXISTS bedrock_knowledge_base_chunks_idx 
                    ON bedrock_knowledge_base USING gin 
                    (to_tsvector('\''simple'\'', chunks));' \
  --region       us-west-2

2.4. ベクター検索用 HNSW インデックスの作成

aws rds-data execute-statement \
  --resource-arn 'arn:aws:rds:us-west-2:123456789012:cluster:ypd-dev-aurora-main-cluster' \
  --secret-arn   'arn:aws:secretsmanager:us-west-2:123456789012:secret:rds!cluster-c8888888-d222-1c11-999c-445cc44444444-CMHOsq' \
  --database     'main_db' \
  --sql          'CREATE INDEX IF NOT EXISTS bedrock_knowledge_base_embedding_idx 
                    ON bedrock_knowledge_base USING hnsw 
                    (embedding vector_cosine_ops);' \
  --region       us-west-2

3. 作成内容の確認

3.1 テーブルの存在確認

aws rds-data execute-statement \
  --resource-arn 'arn:aws:rds:us-west-2:123456789012:cluster:ypd-dev-aurora-main-cluster' \
  --secret-arn 'arn:aws:secretsmanager:us-west-2:123456789012:secret:rds!cluster-c8888888-d222-1c11-999c-445cc44444444-CMHOsq' \
  --database 'main_db' \
  --sql 'SELECT table_name FROM information_schema.tables WHERE table_name = '\''bedrock_knowledge_base'\'';' \
  --region us-west-2

出力例

{
    "records": [
        [
            {
                "stringValue": "bedrock_knowledge_base"
            }
        ]
    ],
    "numberOfRecordsUpdated": 0
}

3.2 インデックスの確認

aws rds-data execute-statement \
  --resource-arn 'arn:aws:rds:us-west-2:123456789012:cluster:ypd-dev-aurora-main-cluster' \
  --secret-arn 'arn:aws:secretsmanager:us-west-2:123456789012:secret:rds!cluster-c8888888-d222-1c11-999c-445cc44444444-CMHOsq' \
  --database 'main_db' \
  --sql 'SELECT indexname, indexdef FROM pg_indexes WHERE tablename = '\''bedrock_knowledge_base'\'';' \
  --region us-west-2

出力例

{
    "records": [
        [
            {
                "stringValue": "bedrock_knowledge_base_pkey"
            },
            {
                "stringValue": "CREATE UNIQUE INDEX bedrock_knowledge_base_pkey ON public.bedrock_knowledge_base USING btree (id)"
            }
        ],
        [
            {
                "stringValue": "bedrock_knowledge_base_chunks_idx"
            },
            {
                "stringValue": "CREATE INDEX bedrock_knowledge_base_chunks_idx ON public.bedrock_knowledge_base USING gin (to_tsvector('simple'::regconfig, chunks))"
            }
        ],
        [
            {
                "stringValue": "bedrock_knowledge_base_embedding_idx"
            },
            {
                "stringValue": "CREATE INDEX bedrock_knowledge_base_embedding_idx ON public.bedrock_knowledge_base USING hnsw (embedding vector_cosine_ops)"
            }
        ]
    ]
}

Knowledge Base 用のベクターデータベース設定が完了したので、続いて Knowledge Base の設定を行います。

Model 有効化

Amazon Bedrock では、各種基盤モデル(Anthropic Claude、Amazon Titan、Amazon Nova など)を使用する前に、明示的にアクセス許可を有効化する必要があります。

本ハンズオンでは以下のモデルを使用します

  • Amazon Nova Pro: Knowledge Base のテスト用
  • Amazon Titan Text Embeddings V2: ベクトル埋め込み生成用(Knowledge Base で自動的に使用)

これらのモデルを利用可能にするため、Amazon プロバイダーのモデルアクセスを一括で有効化します

[ Amazon Bedrock ] -> [ モデルアクセス ]

※左メニューの下部にあるため、注意
[ 特定のモデルを有効にする ] or [ モデルアクセスを変更 ]をクリックする
AWS アカウントに対して初めてモデルアクセスを有効にする際は [ 特定のモデルを有効にする ]が表示される

[ Amazon ] を選択 [ 次へ ] をクリック [ 送信 ] をクリック [ モデルアクセス ] ページで、Amazon 配下のモデルにアクセスが付与されていることを確認
※有効になっていない場合は、10分ほど待つ

Knowledge Base の作成

Amazon 系の基盤モデルへのアクセスが有効化されたので、続いて Terraform で Bedrock Knowledge Base を apply します。

plan 確認

terraform/environment/dev-ypd/default ディレクトリに移動

cd terraform/environment/dev-ypd/default

03_bedrock_knowledgebase.tf.bk03_bedrock_knowledgebase.tf にリネーム

$ mv 03_bedrock_knowledgebase.tf.bk 03_bedrock_knowledgebase.tf
$ ls 03_bedrock_knowledgebase.tf
03_bedrock_knowledgebase.tf

terrafom plan で Bedrock Knowledge Base が add されることを確認

terraform plan

成功時の出力例

Plan: 2 to add, 0 to change, 0 to destroy.

apply 実行

terraform apply を実行して Bedrock Knowledge Base を作成

terraform apply

成功時の出力例

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Outputs:

bedrock_knowledge_base_arn = "arn:aws:bedrock:us-west-2:123456789012:knowledge-base/NNIDIDIDID"
bedrock_knowledge_base_id = "NNIDIDIDID"
bedrock_knowledge_base_name = "ypd-dev-knowledge-base"

ベクターDBが正常に稼働していれば apply は成功します。

Knowledge Base ID の取得

apply 完了時に出力される
bedrock_knowledge_base_id の値(例: "NNIDIDIDID"
は、後続の作業で使用するため控えておいて下さい。

Knowledge Base 動作確認

Knowledge Base 用 S3バケットへデータアップロード

[ Amazon S3 ] -> [ バケット ] -> [ ypd-dev-knowledgebase-bucket-aaa999bb ]
[ ↑ アップロード ] をクリック doc/knowledge-base-data-source 配下の vinyl_record.xlsx をアップロードします。
アップロードされたことを確認

Knowledge Base データソースに同期実行します。

[ Amazon Bedrock ] -> [ ナレッジベース ] -> [ ypd-dev-knowledge-base ] をクリック

[ データソース ] -> [ ypd-dev-kb-src-s3 ] を選択し
[ ↻ 同期 ] をクリック

[ ナレッジベースをテスト ]をクリックし、Knowledge Base の RAG 検索の動作確認します。 [ モデルを選択 ] で Amazon Nova Pro を選択し [ 適用 ]をクリック [ 質問を入力 ] に質問を入力
質問例: 「レコードのリストはありますか?」など 応答が返ってくることを確認

Part 1 まとめ

ここまでで、Terraform を使用した AWS 環境の構築と、Amazon Bedrock Knowledge Base の初期設定が完了しました。

次回の Part 2 では、構築した環境を使用して、ローカルでコンテナを起動し、AI Agent が Asana MCP Server や Knowledge Base と実際に連携する様子を確認していきます。

OpenAI API自動課金の停止方法 - 予期しない請求を避ける

概要

未使用の Open AI API クレジットの自動更新を無効にする

OpenAI のAPI クレジット 課金仕様

API クレジットは一年の有効期限が設定されている 未使用であっても返金不可

All sales of Services, including sales of prepaid Services, are final. Service Credits are not refundable and expire one year after the date of purchase or issuance if not used, unless otherwise specified at the time of purchase.

openai.com

自動課金発生時の通知

OpenAI から API の自動入金を行ったメールが送付される 件名: Your OpenAI API account has been funded

自動課金の無効化手順

使用してない際は無駄な課金となるため、自動課金を無効化する

  1. platform.openai.com へログイン
  2. Billing へ移動
  3. [ Auto recharge is on ] となっていることを確認し [ Modify ] をクリック
  4. Auto recharge settings の [Yes, automatically recharge my card when my credit balance falls below a threshold] のチェックボックスを OFFにして [ Save setting ] をクリック
  5. 画面更新を行い [ Auto recharge is off ]となっていることを確認する

IPA非機能要求グレードで整理する非機能要件定義の進め方

いわゆるインフラ構築の業務を行う際に、まずは非機能要件定義から開始することが多くあります。 今回は非機能要件定義と使用される IPA の資料 非機能要求グレード について書いていきます。

非機能要件定義とは

そもそも、非機能要件定義とは何でしょうか?

Non-functional Requirements

非機能要件定義とは 非機能要件(Non-functional Requirements)、または品質属性(Quality Attributes)と定義されておりシステムが提供する具体的な機能以外に、持つべき重要な特性のことを指します。 例えば、性能、セキュリティ、ユーザビリティ、互換性といった属性がこれにあたり、これらはシステムの「機能」そのものではなく、求められる「特性」です。特定のコード行を記述して実装するものではなく、ソリューション全体から現れる特性と言えます。 顧客が要求するこのような属性は仕様書に記述される必要があり、プロジェクトに適用される要件の種類を決定し、適切なものを含める必要がある。

上記は要約となりますが、システムの具体的な機能やコードと異なる特性を仕様書としてまとめることと言えます。

非機能要求

非機能要求とは、クライアントがソフトウェアを通じて実現したい目的を具体化したもの、主にシステム基盤において実現される要求です。

IPA 非機能要求グレードとは

IPA 非機能要求グレード2018

www.ipa.go.jp

「非機能要求グレード」は、「非機能要求」についてのユーザと開発者との認識の行き違いや、互いの意図とは異なる理解を防止することを目的とし、非機能要求項目を網羅的にリストアップして分類するとともに、それぞれの要求レベルを段階的に示したものです。重要な項目から順に要求レベルを設定しながら、両者で非機能要求の確認を行うことができるツール群です。

非機能要件定義を進める際に、フレームワークのようにある程度のひな形や定義を使用し進めることができるようになります。

段階的な手順

IPAの非機能要求グレード内の利用ガイドには以下の手順が紹介されています。

  1. モデルシステムの選定
    • 規模やシステム内容に合うモデルを選択。
  2. 重要項目のレベル設定
    • 重要度の高いメトリクス(指標)に絞り込んだ上で、モデルとなるシステムを想定したレベル値の選択。
    • 各メトリクスの選択レベルを調整することで、目的のシステムへの要求に近づけていきます。
  3. 重要項目以外のレベル設定
    • 非機能要求の全項目について要求レベルを決定。

どのように進めるか?

ヤポドゥでは利用ガイドをベースにおおよそ以下の手順で進めます。

  • モデルシステムの選定と項目の絞り込みについて打ち合わせ等で認識合わせを行い、その後システムに沿った項目表(ヒアリングシート)を埋めていく流れとなります。
  • プロジェクトによって異なりますが、決定事項を Markdown や Word などで文章として記載し、非機能要件定義書として納品を行います。

非機能要求グレードに含まれていないもの

非機能要求グレードは2018年に更新されていますが、クラウドに関してはクラウド事業者のSLA(サービス品質保証)の確認やSaaS利用の導入事例が一部記載されているのみであり、実務的には補足的な内容にとどまっています。
そのため、具体的なクラウドサービス選定や実際の運用設計にあたっては、自身でより詳細かつ最新の情報を補完する必要があります。
AI(人工知能)やCI/CD(継続的インテグレーション/継続的デリバリー)といった比較的新しい技術領域や概念に関する記述は、現行のグレードには盛り込まれていません。
それらのグレードに含まれていない、あるいは記述が不十分な技術領域に関する非機能要件については、プロジェクトの具体的な内容や技術的特性を十分に考慮した上で、既存の評価項目に追記する形で整理するのか、あるいは独立した新たな評価項目として設定・管理するのかを、個別に検討し判断する必要があります。

非機能要求グレードに含まれていない項目記載の具体例

クラウドのサービス利用

クラウドネイティブなシステム設計では、使用するサービスに踏み込んだ検討が必要です。
非機能要求グレードで挙げられている可用性やセキュリティといった重要項目をクラウド環境に当てはめ、より具体的な非機能要件として定義していきます。 例えば、以下のような項目が考えられます。

重要項目

  • 可用性・SLA管理
    • 利用する各クラウドサービスの SLAを把握し、システム全体の目標SLA(例:99.99%)を達成するための設計になっているか。本番環境とその他での SLA を分ける必要がある際は使用すべきサービスのオプションを確認する。
    • 例: Aurora Cluster の有無
  • 性能・拡張性
    • オートスケーリング戦略、サーバーレス環境の複数インスタンス稼働
    • 例: ECSのAuto Scaling、初期起動タスク設定方針
  • セキュリティ
    • 最小権限の原則に基づいたロール・権限設計、定期的な棚卸し
    • 例: IAMポリシーの設計、複数環境時の IAM Identity Center の活用
  • 運用・保守性
    • クラウドプロバイダー提供の監視サービスの活用、アラート設計、通知体制
    • 例: Datadog, CloudWatchの活用、アラート設計、IaC - GitOpsの活用

AI(人工知能)活用

AIをシステムに組み込む場合、従来のシステムとは異なる品質特性が求められます。

  • 信頼性・精度
    • モデルの精度と再現性: AIモデルの予測精度(例:正解率、適合率、再現率)、再現性を担保するための仕組み。
    • 誤判定時の影響と対策: 誤った予測をした場合の影響範囲を特定し、そのリスクを低減・回避する策。
  • データの品質: 学習データの品質(正確性、網羅性、バイアスの有無)がモデルの性能に大きく影響するため、データ収集・管理プロセスも重要。
    • RAG (Retrieval Augmented Generation) のデータ元となるデータソースの選定、データの前処理、クリーニング、取り込み運用の設計。
  • セキュリティ・倫理:
    • 学習データの保護: 個人情報や機密情報を含む場合の適切なマスキング、匿名化。

CI/CD(継続的インテグレーション/継続的デリバリー)

プロジェクトによって記載は変わりますが、開発の迅速性と品質を両立するため、CI/CDパイプライン自体の非機能要件も定義するケースが増えています。 ただし、あくまでも非機能要件の一部であり、機能に紐づく品質などは別途定義する必要があります。

  • 効率性・速度
    • デプロイ頻度: どの程度の頻度でリリースを行えるようにするか。
  • 信頼性・品質
    • 自動テスト: CI/CD時の自動テスト方針
    • デプロイ戦略: Blue/Greenデプロイ、カナリアリリースなど、安全なデプロイ戦略の採用とロールバック手順の確立。
  • IaC のテスト
    • インフラ構成コードのテストと検証。
  • セキュリティ
    • パイプラインの保護: CI/CDツールやリポジトリへのアクセス制御、シークレット管理(例: GitHub Actionsのシークレット、Workload Identity連携)。
    • 脆弱性スキャン: コードやコンテナイメージに対する静的/動的解析、脆弱性スキャンをパイプラインに組み込む (例: Amazon Inspector)。
  • 運用・保守性
    • パイプラインの監視: パイプラインの実行状況、成功/失敗の監視と通知。

これらの項目はあくまで一例であり、AIや自動テストなどは機能要件にそのまま記載するほうがよいケースが多いです。
プロジェクトの目的、規模、技術スタック、規制要件などに応じて、必要な項目を取捨選択し、具体的な目標値を設定していくことが重要です。

非機能要件定義を非機能要求グレードに沿って進める利点

非機能要件定義を非機能要求グレードに沿って進めることには大きな利点があります。最新技術に関する項目が含まれていない場合もありますが、基本的な考え方や品質基準が体系的かつ網羅的に整理されており、実務において非常に有効な指針となります。また、情報技術に対して抵抗感や苦手意識を持つ関係者に対しては、「経済産業省が推奨する基準である」という公式な根拠を示すことで、客観的かつ説得力のある基準として利用でき、プロジェクト内での合意形成や品質保証において大きな効果を発揮します。

【テスト, 監視シナリオ編】Playwright MCP を WSL2 経由で実行する

前回の続きです。
Playwright MCP で WSL2 Docker の Playwright が起動できることを確認したので、以下を評価、作成していきます。

  • Web サイトのテストケース
  • 監視用のログイン - ログアウトのシナリオ

Playwright MCP でのテストケース

前提

  • テストサイトはEC サイトのデモ用として使用可能な www.saucedemo.com で実行する
  • Markdown での簡易的なテストケースが存在している。
  • 指示は 前回動作確認をした Docker 環境 で行う。

www.saucedemo.com

www.saucedemo.com

Cline への指示

既存のテストケースを Playwright で実行可能なコードとして出力し、その後ブラウザ操作を行い、テストケースの追加を行うよう指示をします。

- 日本語で回答してください。
- Playwright MCP を使用してください。
    - Playwright MCP は http://localhost:9876/sse で起動済みです。
- 以下のサイトのテストケースを作成しました。
    - テストを行う URL: https://www.saucedemo.com/
    - 前提: システムの構築が完了したので、テストを実行する準備が整いました。
    - テストケース    

TC‐ID | タイトル | 目的/カバー範囲 | 前提条件 | 手順 | 期待結果
TC‑01 | 標準ユーザーで正常ログイン | 認証処理とダッシュボード表示を確認 | standard_user / secret_sauce の資格情報が有効<200b>saucedemo.com | 1. https://www.saucedemo.com/ にアクセス2. ユーザー名欄に standard_user を入力3. パスワード欄に secret_sauce を入力4. LOGIN ボタンをクリック | ① /inventory.html に遷移する② ページタイトル「Products」が表示される
TC‑02 | ログイン失敗(ロックアウトユーザー) | エラーメッセージ表示を確認 | なし | 1‑4. TC‑01 と同様だがユーザー名は locked_out_user | フォーム下に赤字のエラーバナー「Sorry, this user has been locked out.」が表示される
TC‑03 | 商品を 1 点カートに追加 | 追加ボタン動作とカートバッジ更新 | ログイン済み(TC‑01 成功後) | 1. 最初のアイテム Add to cart をクリック2. 右上カートアイコンを確認 | ① ボタンが Remove に変わる② カートバッジの数が「1」になる
TC‑04 | カートから商品を削除 | Remove ボタンとバッジ更新を確認 | TC‑03 の続き | 1. カートアイコンをクリック→/cart.html2. Remove をクリック | ① 商品行が一覧から消える② カートバッジが消える/「0」になる
TC‑05 | 並べ替え機能(価格:低→高) | ドロップダウンソートが正しく機能するか | ログイン済み | 1. /inventory.html で右上 Sort ドロップダウンを Price (low to high) に変更 | 商品カードが「$7.99 → … → $49.99」の昇順で並ぶ
TC‑06 | 購入フロー完走 | Checkout 手順と合計計算 | カートに 2 品追加済み | 1. /cart.html → Checkout2. フォームに First/Last/Zip を入力3. Continue → 確認画面で内容確認4. Finish | ① /checkout-complete.html へ遷移② “THANK YOU FOR YOUR ORDER” が表示される  

- このテストケースに不足があれば、追加してください。
- テストケースの内容を Playwright で実行できるように、コードを作成してください。

実行

テキストベースのケースに沿ってテストケースコードが作成されます、 対応するケース No も記載されていることが確認できます。

※コード作成時に追加の Playwright MCPのツールの導入を求められるので、すべて許可を与えてます。

// @ts-check
const { test, expect } = require('@playwright/test');

/**
 * SauceDemo Webサイトのテストスイート
 * テストケースID: TC-01~TC-06
 */

test.describe('SauceDemo テストスイート', () => {
  // 各テスト前に実行
  test.beforeEach(async ({ page }) => {
    // ベースURLに移動
    await page.goto('https://www.saucedemo.com/');
  });

  /**
   * TC-01: 標準ユーザーで正常ログイン
   * 目的: 認証処理とダッシュボード表示を確認
   */
  test('TC-01: 標準ユーザーで正常ログイン', async ({ page }) => {
    // 1. ユーザー名欄に standard_user を入力
    await page.fill('[data-test="username"]', 'standard_user');
    
    // 2. パスワード欄に secret_sauce を入力
    await page.fill('[data-test="password"]', 'secret_sauce');
    
    // 3. LOGIN ボタンをクリック
    await page.click('[data-test="login-button"]');
    
    // 期待結果①: /inventory.html に遷移する
    await expect(page).toHaveURL(/.*\/inventory.html/);
    
    // 期待結果②: ページタイトル「Products」が表示される
    await expect(page.locator('.title')).toHaveText('Products');
  });

コードの作成が完了すると WSL2 上でブラウザが実行されサイトの確認を行い追加のテストケース作成を行います。

最後に以下の項目が含まれている README.md がテストコード配置ディレクトリに追加されました。

  • 概要
  • テストケース一覧
  • テストの実行方法
  • ファイル構成

実行結果

  • 既存のテキストテストケースにに対応するテストコードがリポジトリディレクトリに沿って配置される
  • テストケースが4つ追加
  • README.md がテストディレクトリに新規作成される
  • API 費用: 約 $0.73

指示として、もっと具体的に実行したいケースや、技術を提示すれば、ケースはさらに増えていきますので是非お試しください。

Playwright MCP での監視用シナリオ

続いては、監視シナリオを作成します。

前提

  • テストケースの作業情報とファイルは一旦消去して実施
  • 言語として Python 3.12 を指定
  • 想定実行環境は Docker コンテナでの実行

Cline への指示

情報としてECサイトのログイン - ログアウトの監視用シナリオを python で作成したいことを伝えます。
当初はもう少しシンプルな指示で作成を試みてましたが、どうも Sonnet さんが、作業リポジトリの Docker 周辺をどうしても操作したがるので、若干長めになりました。

- 日本語で回答してください。
- Playwright MCP を使用して [調査] ください。
    - Playwright MCP は http://localhost:9876/sse で起動済みです。
    - 必要であれば、ブラウザを起動しサイトを操作して調査してください。
- Playwright ログイン - ログアウト用監視シナリオを作成してください。
    - テストを行う URL: https://www.saucedemo.com/
    - 前提: システムの構築が完了したので、テストを実行する準備が整いました。
    - 言語は Playwright for Python の 3.12 で作成してください。
    - Python のシナリオを実行する際は Playwright MCP は使用しない前提で作成してください。
    - 動作環境はこのリポジトリではなく Docker 上で汎用的に動作するように作成してください。
    - 動作可能な手順を新規の README.md に記載してください。

実行

指示通りにブラウザが起動され、ログイン - ログアウトの動作を確認がされました。 その後に新規にテストコード実行用ディレクトリが作成され、Dockerfiledocker-compose.yml が作成され、 シナリオ用 py ファイルも作成されてます。 README.md は新規作成ではなく既存への追記となってますが、こちらも指示次第で修正は可能です。

$ tree .
.
├── Dockerfile
├── README.md
├── cline_mcp_settings.json.example
├── docker-compose.yml
├── login_logout_test.py
├── scenario
│   └── entrypoint.sh
└── test
    ├── Dockerfile
    └── docker-compose.yml

テストコードも headless で記載されています。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Sauce Demo サイトのログイン・ログアウトテストシナリオ
"""

import asyncio
from playwright.async_api import async_playwright


async def run_login_logout_test():
    """
    Sauce Demo サイトのログイン・ログアウトテストを実行する
    """
    async with async_playwright() as playwright:
        # 環境変数からヘッドレスモードの設定を取得(デフォルトはTrue)
        import os
        headless = os.environ.get('HEADLESS', 'True').lower() in ('true', '1', 't')
        print(f"ヘッドレスモード: {headless}")
        
        # ブラウザを起動
        browser = await playwright.chromium.launch(headless=headless)
        context = await browser.new_context()
        page = await context.new_page()

        # テスト開始のログを出力
        print("テスト開始: Sauce Demo ログイン・ログアウトテスト")

        try:
            # ログインページにアクセス
            await page.goto("https://www.saucedemo.com/")
            print("ページにアクセスしました: https://www.saucedemo.com/")

            # ページタイトルを確認
            title = await page.title()
            assert title == "Swag Labs", f"ページタイトルが一致しません。期待値: 'Swag Labs', 実際: '{title}'"
            print(f"ページタイトル確認: {title}")

            # ユーザー名とパスワードを入力
            await page.fill('input[data-test="username"]', "standard_user")
            await page.fill('input[data-test="password"]', "secret_sauce")
            print("ユーザー名とパスワードを入力しました")

            # ログインボタンをクリック
            await page.click('input[data-test="login-button"]')
            print("ログインボタンをクリックしました")

            # 商品ページに遷移したことを確認
            await page.wait_for_url("https://www.saucedemo.com/inventory.html")
            inventory_title = await page.title()
            assert inventory_title == "Swag Labs", "ログイン後のページタイトルが一致しません"
            
            # 商品ページのヘッダーテキストを確認
            products_header = await page.text_content(".title")
            assert products_header == "Products", f"商品ページのヘッダーが一致しません。期待値: 'Products', 実際: '{products_header}'"
            print("ログインに成功し、商品ページに遷移しました")

            # メニューボタンをクリック
            await page.click('#react-burger-menu-btn')
            print("メニューボタンをクリックしました")

            # ログアウトリンクが表示されるまで待機
            await page.wait_for_selector('#logout_sidebar_link', state="visible")
            
            # ログアウトリンクをクリック
            await page.click('#logout_sidebar_link')
            print("ログアウトリンクをクリックしました")

            # ログインページに戻ったことを確認
            await page.wait_for_url("https://www.saucedemo.com/")
            login_title = await page.title()
            assert login_title == "Swag Labs", "ログアウト後のページタイトルが一致しません"
            
            # ログインボタンが表示されていることを確認
            login_button = await page.is_visible('input[data-test="login-button"]')
            assert login_button, "ログインボタンが表示されていません"
            print("ログアウトに成功し、ログインページに戻りました")

            print("テスト成功: ログイン・ログアウトのフローが正常に完了しました")
            
        except Exception as e:
            print(f"テスト失敗: {str(e)}")
            raise
        finally:
            # ブラウザを閉じる
            await browser.close()
            print("テスト終了: ブラウザを閉じました")


if __name__ == "__main__":
    asyncio.run(run_login_logout_test())

実行結果

  • テスト用 Docker 環境作成
  • Python のテストコードが作成
  • 既存の README.md へ追記される
  • API 費用: 約 $0.27

最後に

2 回にわたって Playwright MCP を操作し、テストケース生成と監視シナリオ構築の両方を確認できました。
テストケース × 監視シナリオ を組み合わせれば、これまで手動で行っていた運用テストもコード化して自動化できます。
CI/CD への組み込みや継続的監視に応用し、開発スピードと品質向上にぜひ役立ててみてください。

参考