TECH PLAY

SCSKクラウドソリューション

SCSKクラウドソリューション の技術ブログ

1141

本記事は TechHarmony Advent Calendar 2025 12/25付の記事です 。 クリスマスマーケットでプレッツェルにハマりました 皆さんどうもこんにちは。いとさんです。 メリークリスマス!……と言いたいところですが、実は今日12月25日は、世界で初めて「Webサイト」が公開された記念すべき日でもあるそうです。  1990年の12月25日、イギリスの計算機科学者ティム・バーナーズ=リーが、 世界で初めてのWebブラウザとサーバ間の通信に成功 しました。 つまり、今こうして皆さんがブログを読めている環境の「誕生日」とも言える日なんです。ネットの歴史が動いたのがクリスマス当日だったというのは、なんだかロマンチックですよね。 A short history of the Web home.cern A Little History of the World Wide Web www.w3.org さて今回はタイトルにもありますように Amazon Bedrock AgentCore & Strands Agentsを使用したAWS構築支援エージェントの構築方法についてご紹介したいと思います!  AWS環境運用支援エージェント構築手順 🎯 エージェントの目標 AWS公式ドキュメントを使用した、開発・運用チーム向けのAWS運用支援エージェントを構築します。 チャットボットとの違いとして、自ら考え、道具を使い、経験を蓄積する「AIエージェント」としての機能を備えています。 チャットボットと「AIエージェント」の違いとは? 一般的なチャットボットは、あらかじめ学習した知識の範囲内でユーザーの問いに「反応」するだけですが、今回構築するAIエージェントには決定的な3つの違いがあります。 「知識」ではなく「道具」を使いこなす (Tools) 通常のチャットボットは古い知識で答えることがありますが、このエージェントは MCPClient というツールを使い、外部にある「最新のAWS公式ドキュメント」へ自らアクセスして情報を取得します。 「会話」ではなく「経験」を記憶する (Memory) ブラウザを閉じれば忘れてしまうチャットボットと違い、 AgentCore Memory を通じて「過去のトラブル対応事例」などを長期記憶(LTM)として蓄積します。これにより、使えば使うほど使用する環境に詳しい状態へと成長します。 「思考」の方向を制御できる安全性 (Steering) 自由奔放なAIとは異なり、 LLMSteeringHandler によって「破壊的な操作の提案を禁止する」といった運用のガードレールを思考プロセスそのものに組み込んでいます。 このように、最新の公式情報(MCP)と経験(LTM)を、安全なルール(ステアリング)の上で統合して提供できるのが「AWS運用支援エージェント」なのです。 構成図 ⚠️構築前提条件  AWSアカウントを所有していること。 GitHubアカウントを所有していること。 AWSリージョンは バージニア北部 ( us-east-1 ) を利用します。(StrandsAgent使用可能リージョンのため) Administrator Access相当、もしくは以下のポリシーを適用したIAMユーザーで作業すること。 { "Version": "2012-10-17", "Statement": [ { "Sid": "BedrockAccess", "Effect": "Allow", "Action": [ "bedrock:InvokeModel", "bedrock:ListFoundationModels", "bedrock:ListCustomModels" ], "Resource": "*" }, { "Sid": "AgentCoreFullAccess", "Effect": "Allow", "Action": "bedrock-agentcore:*", "Resource": "*" }, { "Sid": "S3AndECRForDeployment", "Effect": "Allow", "Action": [ "s3:CreateBucket", "s3:PutObject", "s3:GetObject", "s3:DeleteObject", "s3:ListBucket", "ecr:GetAuthorizationToken", "ecr:CreateRepository", "ecr:DeleteRepository", "ecr:BatchCheckLayerAvailability", "ecr:PutImage" ], "Resource": "*" }, { "Sid": "CodeBuildAndIAMManagement", "Effect": "Allow", "Action": [ "codebuild:*", "iam:CreateServiceLinkedRole", "iam:CreateRole", "iam:PutRolePolicy", "iam:DeleteRole", "iam:DeleteRolePolicy" ], "Resource": "*" }, { "Sid": "CloudWatchAndBoto3Access", "Effect": "Allow", "Action": [ "logs:*", "cloudwatch:*" ], "Resource": "*" } ] } ステップ 1: 環境準備(CodeSpaceの利用) まず、開発環境としてGitHub CodeSpacesをセットアップします。 GitHubリポジトリの作成 GitHubで新しいプライベートリポジトリを作成します(例: aws-ops-agent )。 CodeSpacesの起動 作成したリポジトリの画面左上「 <> Code 」ボタンから「 Codespaces 」タブを開き、「 Create codespace on main 」を選択して起動します。ターミナルが自動的に開きます。 AWS CLIのインストールと認証 ターミナルで以下のコマンドを実行し、AWS CLIをインストールします。 # ダウンロード curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" # 解凍 unzip awscliv2.zip # インストール sudo ./aws/install AWSアカウントへの認証を設定します(ブラウザでの検証コード入力が必要です) aws login --remote デフォルトリージョンが us-east-1 でいいか聞かれたら Enter を押します。 ステップ 2: AgentCoreメモリの作成(短期・エピソード記憶の準備) エージェントが会話履歴と社内ナレッジを記憶するためのAgentCore Memoryを作成します。 AgentCoreサービスへアクセス AWSマネジメントコンソールで「AgentCore」を検索してアクセスします。 左メニューから「 メモリー 」>「 メモリを作成 」をクリックします。 メモリ設定 すべてデフォルトのまま「 メモリを作成 」をクリックします。 エピソード記憶の有効化 (LTM) 作成したメモリの詳細画面を開き、「 編集 」をクリックします。 組み込み戦略の「 Episodes 」にチェックを入れ、「 変更を保存 」します。 重要 : 作成されたメモリの Memory ID と、エピソード記憶戦略の 戦略ID を控えておきます。(エージェント本体の作成の際に使用します) ステップ 3: エージェント本体の作成( backend.py ) エージェントの処理ロジックと、必要なツール、記憶、ステアリングを設定したAPIサーバーのコードを作成します。 ディレクトリとファイルの作成 以下のコードをコピーし、 memory_XXXXX-XXXXXXXXXX (Memory ID) と episodic_builtin_XXXXX-XXXXXXXXXX (戦略ID) のプレースホルダーを、ステップ2で控えた実際のIDに置き換えて貼り付けます。 mkdir agentcore cd agentcore touch backend.py backend.py にコードを記述 # 必要なライブラリをインポート from strands import Agent from strands.tools.mcp import MCPClient from strands.models import BedrockModel from strands.experimental.steering import LLMSteeringHandler # ステアリング用 from bedrock_agentcore.runtime import BedrockAgentCoreApp from mcp.client.streamable_http import streamablehttp_client from bedrock_agentcore.memory.integrations.strands.config import AgentCoreMemoryConfig, RetrievalConfig from bedrock_agentcore.memory.integrations.strands.session_manager import AgentCoreMemorySessionManager # 1. モデル設定 model = BedrockModel( model_id= "us.amazon.nova-2-lite-v1:0" , max_tokens= 4096 ) # 2. メモリー設定(STM/LTM) memory_config = AgentCoreMemoryConfig( memory_id= "memory_XXXXX-XXXXXXXXXX" , # ここをあなたのMemory IDに置き換える session_id= "aws_ops_handson" , actor_id= "ops_engineer" , retrieval_config={ # エピソード記憶(LTM)の検索設定 "/strategies/episodic_builtin_XXXXX-XXXXXXXXXX/actors/ops_engineer/sessions/aws_ops_handson" : RetrievalConfig() # ここをあなたの戦略IDに置き換える } ) session_manager = AgentCoreMemorySessionManager( agentcore_memory_config=memory_config ) # 3. ツール設定 (MCPClient) mcp_client = MCPClient( lambda : streamablehttp_client( "https://knowledge-mcp.global.api.aws" ) ) # 4. ステアリング設定(ポリシーの強制) # 例: 破壊的な操作の推奨を禁止し、公式ドキュメント参照を強制 handler = LLMSteeringHandler( system_prompt= "設定変更やリソース削除につながる操作は絶対に推奨しないでください。また、回答には必ず公式ドキュメントの参照URLを含めるようにしてください。" ) # AgentCoreランタイム用のAPIサーバーを作成 app = BedrockAgentCoreApp() # エージェント呼び出し関数を、APIサーバーのエントリーポイントに設定 @app.entrypoint async def invoke_agent ( payload, context ): # リクエストごとにエージェントを作成し、設定を適用 agent = Agent( model=model, tools=[mcp_client], # MCPClientをツールとして組み込む session_manager=session_manager, # 記憶(STM/LTM)を組み込む hooks=[handler] # ステアリング(ポリシー)を組み込む ) # エージェントをストリーミング呼び出し stream = agent.stream_async( payload.get( "prompt" ) ) # ストリーミングレスポンスをフロントに返却 async for event in stream: yield event # APIサーバーを起動 app.run() 依存関係のファイル作成 agentcore/requirements.txt を作成し、必要なパッケージを記述します。 touch requirements.txt requirements.txt に以下をコピー&ペーストします。 strands-agents strands-agents-tools strands-agents[otel] bedrock-agentcore bedrock-agentcore[strands-agents] 依存関係のファイル(requirements.txt)の目的 このファイルの最大の目的は、「環境の標準化」です。 1. 必要なライブラリの明示: そのプログラムを動かすために、どの外部ライブラリ(strands, boto3, requestsなど)が必要なのかをリストアップします。 2. バージョンの固定: 「どのバージョンの道具を使うか」を指定します(例:strands==0.1.0)。これにより、ライブラリが勝手にアップデートされてプログラムが壊れるのを防ぎます。 3. セットアップの自動化 : コマンド一つ(pip install -r requirements.txt)で、必要なものを一括インストールできるようにします。 ファイルを作成する具体的な理由 なぜわざわざファイルを作る必要があるのか、3つの重要な理由があります。 1. 開発環境と本番環境(AWS)の「ズレ」をなくすため 自分のPC(CodeSpaces)で動いても、AWS上のサーバーにデプロイした時に「ライブラリが入っていない」という理由でエラーになるのを防ぎます。 理由: デプロイ時にAWS側がこのファイルを読み込み、必要な環境を自動で構築するためです。 2. 多人数・多環境での共同開発をスムーズにするため 他の人がコードをGitHubからダウンロードした際、どのライブラリをインストールすればいいか迷わずに済みます。 理由: 「READMEに手書きでライブラリ名を並べる」といった手動作業を排除し、ミスを減らすためです。 3. デプロイツール(AgentCoreなど)の仕様 今回使用している agentcore launch などのツールは、内部でこのファイルを自動的に探しに行きます。  理由: クラウド上にエージェントを構築する際、プログラムを動かすための「コンテナ」の中に、自動でライブラリをインストールする仕組みになっているからです。 *家具の組み立てキットを例にしてみましょう 依存関係のファイルは、家具の「部品リスト(材料表)」に例えられます。 プログラム (backend.py): 家具の組み立て説明書。 依存関係ファイル (requirements.txt): 「ネジ(M4サイズ)×10個」「天板×1枚」といった材料リスト。 もし材料リストがなければ、説明書だけあっても「何を用意すればいいか」分からず、作業が進みませんよね。 この「材料リスト」があるからこそ、クラウドという遠く離れた場所でも正確にプログラムを動かせるのです。 ステップ 4: AgentCoreランタイムへのデプロイ 作成したエージェントコードをAWS上で動作するAPIサーバーとしてデプロイします。 AgentCoreスターターキットのインストール pip install bedrock-agentcore-starter-toolkit==0.2.2 Amazon Bedrock AgentCore スターターキットとは Amazon Bedrock AgentCore スターターキットは、AWS上で高性能なAIエージェントを「安全に」「速く」「大規模に」構築・運用するために必要なすべてが詰まった、開発者向けの公式ツールセット(CLIおよびライブラリ)です。 これを使用することで、インフラの知識が少なくても、数行のコードでプロ仕様のエージェントをクラウド上に公開できます。 スターターキットに含まれる主な内容 このキットは主に以下の3つの要素で構成されています。 要素 内容と役割 AgentCore CLI agentcore launch コマンドなどで、AWS上のサーバー(Runtime)やメモリ、セキュリティ設定を自動で構築・デプロイします。Strands Agents SDK エージェントの「脳」を動かすためのオープンソースSDK。Claude 3.5やNovaなどのLLMを使い、ツール呼び出しや推論を制御します。 サンプルテンプレート backend.py や requirements.txt の雛形。これを書き換えるだけで、自分の用途に合わせたエージェントがすぐに作れます。 通常と使用した場合での比較 「通常(すべて自前)の開発」と「AgentCoreスターターキット + Strands」を使用した場合の比較解説します。 一言でいうと、通常の開発は「材料集めとキッチン作りから始める料理」ですが、スターターキットは「最新設備の整った厨房で、レシピ通りに作る料理」のような違いがあります。 ① 開発スピードと手間の比較 通常の開発では、AIの「脳」を作る前に「箱(インフラ)」を作る作業が膨大です。 項目 通常の開発(自前) スターターキット使用 環境構築 Docker、サーバー、権限設定を個別に構築。 agentcore launch 一発で最適環境が完成。 ライブラリ管理 各ツールの互換性を自分で検証・修正。 公式SDKが最初から最適化されている。 デプロイ 数日~数週間(インフラ知識が必要)。 数分~数時間 (Pythonの知識だけでOK)。 ② 運用性能と安全性の比較 個人開発外で使う場合、この「運用面」の差がリスクの違いになります 項目 通常の開発(自前) スターターキット使用 実行時間制限 Lambda等だと 15 分 で強制終了。 最大 8 時間 の長時間処理が可能。 セッション分離 ユーザー間のデータ混入対策を自前実装。 セッションごとに 完全隔離 された安全な環境。 監視(デバッグ) ログを自前で集計・解析。 思考プロセスが自動で可視化される。 認証管理 APIキーの管理を暗号化して自作。 AgentCore Identity でセキュアに一元管理。 ③ 機能(賢さ)の拡張性の比較 エージェントに「新しい道具(ツール)」を持たせたい時の柔軟性が違います。 ・通常の開発: 新しいツールを増やすたびに、プロンプトを調整し、API接続コードを書き、例外処理を手動で追加します。 ・スターターキット: 世界標準の MCP (Model Context Protocol) に対応。Notion、Slack、GitHubなどの公式プラグインを、コードをほぼ書かずに「差し込むだけ」でエージェントが使いこなせます。 通常開発が向いている人: ・AWSを使わない、または完全に独自のサーバー構成にこだわりがある。 ・AIの推論ロジック自体を一から研究・開発したい。 スターターキットが向いている人: ・「動くもの」を最速で作って業務に導入したい。 ・セキュリティやスケーラビリティ(大人数での利用)を重視する。 ・最新のClaude 3.5やAmazon Novaなどの高性能モデルを、最高の環境で使いこなしたい。 設定ファイルの自動生成 以下のコマンドを実行し、設定プロセスを開始します。 agentcore configure 対話形式で質問されますが、 以下以外はすべて Enter で OK です。 Entrypoint : backend.py と入力。 Existing memory resources found :ステップ2で作成したメモリーの番号(例: [1] など)を入力。 ランタイムのデプロイ 以下のコマンドで、ECR、CodeBuild、AgentCoreランタイムなどのAWSリソースが自動で作成され、デプロイが開始されます。 agentcore launch デプロイ完了まで数分かかります。完了後、 Runtime ARN が出力されるので、これを控えておきます。 このとき認証エラーになる場合があります。原因として以下の3点が挙げられます。 ・認証の有効期限切れ : 手順1から手順4までに時間が空きすぎ、一時的なログインセッションが切れてしまった場合。 ・環境の初期化 : GitHub Codespacesを一度停止・再起動し、ログイン状態(キャッシュ)が消えてしまった場合。 ・ブラウザログインの失敗 : aws login --remote を実行した際、ブラウザ側での承認が正しく完了していなかった場合。           このような場合は aws login –remote こちらの手順を再度行いましょう。 aws configureでアクセスキー・シークレットアクセスキーを使用し紐づける事も可能ですが、セキュアな構成にしたい場合は推奨しません。    ステップ 5: 動作確認用フロントエンドの作成と実行 デプロイされたAPIサーバーをテストするための簡単なWebインターフェース(Streamlitを利用)を作成します。 元の階層に戻る cd ../ frontend.py の作成 frontend.py を作成し、以下のコードをコピー&ペーストします。 touch frontend.py frontend.py の内容: # 必要なライブラリをインポート import os, boto3, json import streamlit as st # サイドバーを描画 with st.sidebar: # デプロイ後に得られたAgentCoreランタイムのARNを入力 agent_runtime_arn = st.text_input( "AgentCoreランタイムのARN" ) # タイトルを描画 st.title( "AWS環境運用支援エージェント" ) st.write( "Strands AgentsがMCP(AWSドキュメント)とLTM(社内ナレッジ)を使って運用を支援します!" ) # チャットボックスを描画 if prompt := st.chat_input( "質問を入力してください(例:IAMポリシーの最小権限原則のベストプラクティスを教えて)" ): # ユーザーのプロンプトを表示 with st.chat_message( "user" ): st.markdown(prompt) # エージェントの回答を表示 with st.chat_message( "assistant" ): try : # AgentCoreランタイムを呼び出し agentcore = boto3.client( 'bedrock-agentcore' ) payload = json.dumps({ "prompt" : prompt}) response = agentcore.invoke_agent_runtime( agentRuntimeArn=agent_runtime_arn, payload=payload.encode() ) # ストリーミングレスポンスの処理 container = st.container() text_holder = container.empty() buffer = "" for line in response[ "response" ].iter_lines(): if line and line.decode( "utf-8" ).startswith( "data: " ): data = line.decode( "utf-8" )[ 6 :] # 文字列コンテンツの場合は無視 if data.startswith( '"' ) or data.startswith( "'" ): continue # 読み込んだ行をJSONに変換 event = json.loads(data) # ツール利用を検出 if "event" in event and "contentBlockStart" in event[ "event" ]: if "toolUse" in event[ "event" ][ "contentBlockStart" ].get( "start" , {}): # 現在のテキストを確定 if buffer: text_holder.markdown(buffer) buffer = "" # ツールステータスを表示 tool_name = event[ "event" ][ "contentBlockStart" ][ "start" ][ "toolUse" ].get( "name" , "unknown" ) container.info( f"🔍 {tool_name} ツールを利用しています" ) text_holder = container.empty() # テキストコンテンツを検出 if "data" in event and isinstance (event[ "data" ], str ): buffer += event[ "data" ] text_holder.markdown(buffer) elif "event" in event and "contentBlockDelta" in event[ "event" ]: buffer += event[ "event" ][ "contentBlockDelta" ][ "delta" ].get( "text" , "" ) text_holder.markdown(buffer) # 最後に残ったテキストを表示 text_holder.markdown(buffer) except Exception as e: st.error( f"エラーが発生しました: {e} " ) Streamlitの実行 StreamlitはPythonだけでデータ分析アプリやAIアプリのフロントエンド(画面)を爆速で構築できるオープンソースのフレームワークです。 今回はAIエージェントの仕様を簡単に確認・実行するために使用します。(本番実装向きではありません) pip install streamlit streamlit run frontend.py CodeSpacesのポップアップに従ってブラウザでアプリを開くか、ターミナルに表示されたURLにアクセスします。 動作確認 アプリのサイドバーに、ステップ4で控えた Runtime ARN を貼り付けます。 以下の質問をして、 MCPClientの利用 (AWSドキュメント検索)と ステアリング が効いているか確認します。 https://blog.usize-tech.com/contents/uploads/2025/12/a1f4b32fda82bf2c124175a5c026b99e.mp4 ちゃんと危険と記述してくれていますね。 ステップ 6: エピソード記憶(LTM)へのナレッジの投入 デプロイ後、LTMに社内固有のナレッジを「記憶」させることで、提案されたLTMの役割(過去の障害対応検索)を実現します。 LTMにナレッジを投入 Streamlitのチャットで、具体的な過去の事例をエージェントに教え込みます。 例: 「先月、NATゲートウェイの誤った設定でコストが急増した。解決策は、夜間はAWS Lambdaで停止する仕組みを導入したことだ。」 LTMの検索テスト ナレッジ投入後、LTMが検索される質問をします。 例: 「私が以前話したNATゲートウェイのコスト問題について、解決策はなんだったか?」 (LTMが有効になっていれば、過去のエピソードを踏まえた回答が得られるはずです。) エピソード記憶がちゃんと実装できている事も確認できましたね。 これで、AWSの公式ドキュメントとナレッジの両方を活用し、ポリシーで制御された「AWS環境運用支援エージェント」が完成します。   所感・まとめ 開発経験はまだ浅いですが、メモリー機能を備えた簡易的なエージェントを構築することができました。 難しい言語での作業が少なく約1時間と短い時間で構築でき、今後の開発速度効率化にとても期待できました。 今後は環境操作などの機能を追加して、完全自動化を実現する「ローカル版Kiro」のような仕組みを作ってみたり、 これまではPythonで実装してきましたが、アップデートによりTypeScriptでも実装可能になったため、複数言語での開発にも挑戦してみたいなーって思います。 年末に向けてPCもお部屋も大掃除しなくてはです。 それでは皆さん良いお年を〜
アバター
本記事は TechHarmony Advent Calendar 2025 12/25付の記事です 。 こんにちは、SCSK木澤です。 12/1から続けてきた今年のアドベントカレンダーも、ついに今日でラストですね。 本日発信される記事で、合計25日間で33記事が発信されたかと思います。 年末の忙しいさなか、お読み頂いた皆様、発信いただいた寄稿者の方々ありがとうございました。 さて今年のアドベントカレンダー、私は他のテーマの検証が完了しませんでしたので、今年はAmazon SESの小ネタを発信したい思います。 メール誤送信事故の防止 私は10年ほど前まで、色々なお客様のシステム開発や保守を担当していました。 その中で、メール誤送信の事故を見かけたことがありました(大量ではないですが) 結構ありがちなのが、開発中のシステムやリリース後においては開発/検証環境など、本番環境以外からの誤送信で、テスト実施の際に不必要な宛先にメールが送信されてしまった、というケースです。 とはいえ、本番環境以外においてもシステムの動作検証・テストとして全くメールを出さない訳にもいかないことがあります。 そうした場合、メール中継をするMTA(postfix等)において、不必要な宛先への送信をブロックする設定を行うことが事故防止のため望ましく、そのような実装をよく行っていました。   Amazon SESでの実装方法 AWSにおいてはAmazon SESを送信用のMTAとして用いることがベストプラクティスとなるかと思います。 Amazon SESにおいて送信の制限には、送信承認ポリシーによって行うことができます。 Amazon SESの送信承認ポリシーの作成 - Amazon Simple Email Service アイデンティティ所有者が Amazon SES の送信承認ポリシーを作成する方法について説明します。 docs.aws.amazon.com 設定手順 Amazon SESコンソール、設定内-IDをクリックし、検証済み(であることが前提ですが)IDの設定に入ります。 「承認」タブより承認ポリシーの作成に入ります。 今回はカスタムポリシーから作成しました。 ポリシードキュメントは以下のようにします(AWSアカウントはマスクしています) この設定では、 test@scsk.jp 宛のメールのみ送信を許可するように設定しています。 { "Version": "2012-10-17", "Statement": [ { "Sid": "stmt1766585448102", "Effect": "Deny", "Principal": "*", "Action": [ "ses:SendEmail", "ses:SendRawEmail" ], "Resource": "arn:aws:ses:ap-northeast-1:123456789012:identity/scsk.jp", "Condition": { "ForAnyValue:StringNotEquals": { "ses:Recipients": "test@scsk.jp" } } } ] } 本ポリシーを設定し、適用します。 テスト ID画面上の「テストEメールの送信」をクリックします。 許可されていない宛先を指定すると、下記のようにアクセス権がないというエラーが発生するはずです。   まとめ 今回はAmazon SESの小ネタをご紹介させていただきました。 開発/検証環境のメール環境においては、転ばぬ先の杖ということで必ず設定しておきましょう。 私は今年最後の投稿になるかもしれませんが、来年もTechHarmonyエンジニアブログ共、引き続きご愛顧の程よろしくお願いします。 皆様の2026年が良い年になりますように。今年もありがとうございました。
アバター
こんにちは。SCSKの末本です。 本記事では、AWSで構築しているシステムの保守運用をする中で発生した事象と、その解決策についてご紹介します。   発生した事象 今回のシステムは、Amazon Elastic Container Service(以下 ECS)を利用しており、1タスクで複数のコンテナを構成する環境です。 発生した事象は、 AWS_ECS_TASK_PATCHING_RETIREMENT によって ECS のタスクが生まれ変わる際、クライアントからのアクセスに対して一時的に HTTP 503 エラーが返されたというものです。 この事象は、アーキテクチャの本質的な理解と、ECS タスク定義内のコンテナ依存関係が鍵を握っていました。   AWS_ECS_TASK_PATCHING_RETIREMENT  とは AWS がメンテナンスやセキュリティアップデートを行うために、実行中のタスクを強制的に停止し、新しいタスクを起動するプロセス   なぜ 503エラー が発生したのか? 今回のシステム構成と、問題についてご説明します。 システム構成(1タスク内) tomcat コンテナ:  アプリケーションを実行するバックエンドとして動作するコンテナ web(Apache)コンテナ:  フロントエンドとして動作し、ロードバランサーからのリクエストを受け取り、tomcat コンテナへ転送するコンテナ log コンテナ:  ログ収集および転送を行う サイドカーコンテナ                                  サイドカーコンテナ とは メインのアプリケーションコンテナ(ここでは tomcat・web)の補助機能を提供するコンテナ   AWSによる ECSパッチ適用時の流れ AWS が ECSのパッチ適用をするため、ECSタスクの入替(新しいタスクを起動し、古いタスクを停止)が行われます。 この流れの中で、タスクがリクエストを受け付ける準備が整う前に、クライアントからアクセスされてしまうという問題が発生しました。 新しいタスクが起動を開始する。 web(Apache)コンテナ、log コンテナが比較的早く起動する。 (この時点では、バックエンドの tomcat はまだアプリケーションレベルでの準備ができていない。) ヘルスチェックを有効化したコンテナ(web・log)の状態をもって、タスク全体が早期に起動完了(RUNNING)と見なされる。   今回、tomcat コンテナにヘルスチェックが設定されていませんでした。 そのため tomcat のアプリケーション初期化時間にかかわらず、ヘルスチェックを有効化したコンテナ(web・Log)のヘルスステータスがすべて Healthy であることで、タスク全体が起動完了したと見なされました。                              ご参考: Amazon ECS タスクライフサイクル – Amazon Elastic Container Service タスクが ターゲットグループに登録 され、クライアントからアクセスが可能な状態になる。 クライアントからのリクエストが web(Apache)に到達するが、バックエンドの tomcat コンテナはまだ起動途中。 結果として Apache はバックエンドに接続できず、クライアントに HTTP 503 Service Unavailable を返す。   今回の問題 今回の問題は、ロードバランサーのヘルスチェック(Apacheのポートをチェック)がOKでも、タスク内の コンテナ間の依存関係 が考慮されていなかったため、 サービスが利用可能な状態 になる前にアクセスされてしまった ことです。   【回避策】ECSタスク定義の依存関係(dependsOn)の活用 この問題を解決するために、 ECSタスク定義内の dependsOn プロパティと コンテナヘルスチェック を組み合わせて設定 しました。 これにより、コンテナ間の起動順序と、次のコンテナが起動を開始するための 条件 を定義できます。 20190731_AmazonECS_DeepDive_AWSBlackBelt   dependsOn パラメータ の意味については以下の通りです。 設定値(条件) 意味 START 依存するコンテナの起動開始後、実行 COMPLETE 依存コンテナの実行が完了(終了)後、実行 SUCCESS 依存コンテナの実行が正常終了後、実行(exit code:0) HEALTHY 依存コンテナに定義した healthcheck に合格後、実行   修正後のコンテナ依存関係の設計 フロントエンド(web)が起動する前にバックエンド(tomcat)が完全に起動 することで、リクエスト処理可能な状態とする。 log コンテナがログファイルを正しく転送できるよう、 各コンテナ起動後に log コンテナを起動 させ、 転送対象のファイルが存在しないというエラーの発生を防ぐ。   コンテナ 依存設定 設定値(条件) 内容 tomcat (なし) – 依存関係なしのため、まず最初に起動する。 web(Apache) tomcat HEALTHY tomcat がアプリケーションレベルで完全に起動し、 サービス可能になるまで待機する。 log web(Apache) HEALTHY web コンテナのプロセス起動が確認されてから、 ログ転送を開始する。   設定内容 単に START(コンテナプロセスが起動)を待つだけでは、アプリケーションの初期化時間などを考慮できません。 この問題を解決するために、tomcat コンテナのタスク定義内に コンテナヘルスチェック を設定し、web(Apache)コンテナおよび log コンテナの dependsOn 設定で、HEALTHY 条件を指定しました。   // ECSタスク定義(コンテナ定義の抜粋イメージ) "containerDefinitions": [ { "name": "tomcat", // ... 他の設定 // Tomcatがサービス可能であることを確認するコンテナヘルスチェック "healthCheck": { "command": [ "CMD-SHELL", "curl -f http://localhost:8080/status || exit 1" ], "interval": 30, // 30秒ごとにチェック "retries": 3, // 3回失敗したらUNHEALTHY "startPeriod": 10, // 起動直後の10秒間はヘルスチェックの失敗を無視(猶予期間) "timeout": 6 // タイムアウトは6秒 } }, { "name": "web", // ... 他の設定 // webコンテナはtomcatがHEALTHY(サービス可能)になるまで起動を待機 "dependsOn": [ { "containerName": "tomcat", "condition": "HEALTHY" // ここが重要! } ] }, { "name": "log", // ... 他の設定 // logコンテナはwebがHEALTHY(サービス可能)になるまで起動を待機 "dependsOn": [ { "containerName": "web", "condition": "HEALTHY" // ここが重要! } ] } ] 上記の設定により、 今回の事象は解決し、ECSタスクのパッチ適用時に503エラーが出なくなりました。   今回の対応から学んだ3つの設計ポイント 1. ALBヘルスチェック ≠ サービス利用可能性 ロードバランサーのヘルスチェックは、 外部から特定のポートが応答しているか を確認するもので、タスクへのトラフィックを流すかどうかを判断します。 しかしマルチコンテナタスクでは、「ポートが開いている」ことと「アプリケーションがリクエストを処理する準備ができている」ことは同義ではありません。 ALBヘルスチェック : タスクへのトラフィック受付可否 を判断 コンテナヘルスチェック : タスク内のコンポーネントのサービス提供可否 を判断   2. マルチコンテナ設計における依存関係の明示 ECSタスクの設計において、 各コンテナの起動順序 を意識して設計しなければ、今回のようなコンポーネント間の疎通エラーを招きます。 以下のように、役割に応じて依存関係を定義することが、システムの信頼性を高めると学びました。 フロントエンドは、バックエンドの HEALTHY 状態を待つ。 サイドカー コンテナは、 メインコンテナ の START または HEALTHY 状態に依存する。   3. startPeriod(起動猶予期間)の活用 Tomcat などの Javaアプリケーションは、プロセス起動からリクエスト処理可能になるまでに数十秒かかることがあります。 dependsOn パラメータで HEALTHY を使う場合、tomcat コンテナのヘルスチェック定義に startPeriod(起動猶予期間)を設定することで、コンテナが起動直後の不安定な状態で即座に失敗と見なされるのを防ぐことができます。   【重要】今回の対応によるデメリット 今回の対応で可用性を高めることができましたが、デメリットとして タスク全体の起動時間の増加 があげられます。 本システムでは、開発環境で検証した上で、起動時間の増加を許容する方針にしました。   まとめ AWS ECSのタスク入れ替え時の503エラーは、一見するとシンプルなネットワークエラーに見えますが、その裏には「複数コンテナの非同期起動」という本質的な課題が隠れていました。 本記事でご紹介した設定内容は、あくまで 今回のシステムに おける最適な設計例 です。 コンテナの依存関係は、アプリケーションの構成によって大きく異なります。ご自身のシステムに適用される際は、 各コンテナの役割 と コンテナ間の通信タイミング を考慮し、最も適切なヘルスチェック、依存関係( START、HEALTHY など)およびパラメータを設定いただければと思います。 最後までお読みいただきありがとうございました!
アバター
LifeKeeperの『困った』を『できた!』に変える!サポート事例から学ぶトラブルシューティング&再発防止策 こんにちは、SCSKの前田です。 いつも TechHarmony をご覧いただきありがとうございます。 LifeKeeperを導入し、システムの高可用性を実現する上で、アプリケーションリソースの保護は非常に重要な要素です。しかし、アプリケーションARKは、その特性ゆえに、設定のわずかな見落とし、予期せぬ通信障害、そしてバージョンアップによる仕様変更など、多岐にわたる要因で『困った』事態に直面することがありますよね。 本連載企画「LifeKeeper の『困った』を『できた!』に変える!サポート事例から学ぶトラブルシューティング&再発防止策」では、まさにそんな「なぜかアプリケーションが切り替わらない」「エラーが出て起動できない」といった、LifeKeeper運用の現場で実際に発生した問い合わせ事例を基に、トラブルの原因、究明プロセス、そして何よりも『再発防止策』に焦点を当てて深掘りしていきます。今回の第三弾では、アプリケーションARK特有の「落とし穴」に焦点を当て、その解決と再発防止の鍵を探ります。 はじめに LifeKeeperの心臓部とも言えるアプリケーションリソースの保護は、システムの高可用性を実現する上で不可欠です。専用ARKから汎用ARKまで多岐にわたりますが、その複雑さゆえに設定ミスや連携アプリケーション側の要因で予期せぬトラブルが発生しがちです。 本記事では、 LB Health Check、MySQL、IIS、そしてGeneric ARKを用いたJP1/Baseのリソース構築・運用で実際に発生したサポート事例 を元に、アプリケーションARK特有の「落とし穴」を深掘りします。 通信障害、バージョン間の仕様変更、ホスト名の制約、スクリプトの依存性など、様々な角度から原因と対策を学ぶことで、アプリケーションの安定稼働と再発防止につなげるヒントを提供します。 その他の連載企画は以下のリンクからどうぞ! 【リソース起動・フェイルオーバー失敗の深層 #1】EC2リソースが起動しない!クラウド連携の盲点とデバッグ術 – TechHarmony 【リソース起動・フェイルオーバー失敗の深層 #2】ファイルシステムの思わぬ落とし穴:エラーコードから原因を読み解く – TechHarmony 今回の「困った!」事例 ケース1:ロードバランサーとの連携トラブル – ヘルスプローブの落とし穴 lbhcリソース作成中にエラー(140251)が発生する、LB Health Checkリソース作成時のエラーについて 事象の概要:  LifeKeeper for Windows環境でLB Health Checkリソース作成・起動時にエラーが発生し、リソース作成に失敗。 ロードバランサーからの正常性プローブがLifeKeeper側で受け取れない状況 に陥りました。 発生時の状況:  LBHCリソース作成後のリソース起動でロードバランサーとの通信がタイムアウト(エラーコード140251)しました。Azure内部ロードバランサーからの通信は許可済みと認識されていたにも関わらず、プローブが到達しませんでした。また、LifeKeeperのホスト名に小文字が混在している環境でした。 原因究明のプロセス:  初期には HC_TIMEOUT の調整やデバッグログ取得を試みましたが、デバッグログからも最終的にプローブを受け取れていない状況が判明。さらに、ホスト名に小文字が含まれることがLifeKeeper for Windowsの既知の不具合であり、リソース情報取得エラーの原因であることが明らかになりました。 判明した根本原因:  1. ロードバランサーからの正常性プローブがLifeKeeper側で受け取れていない通信経路上の問題、および 2. LifeKeeper for Windowsのホスト名が小文字混在であったことによるリソース情報取得エラーが複合的に発生していました。 ケース2:データベースARK特有の設定ミス – MySQLのパスワードとログパスの罠 MySQLリソース作成時のエラーについて 事象の概要:   MySQLリソース作成時 に「Invalid parameter value」エラーが発生し、さらにその後log-binのパスに関するエラーが発生。 リソース作成が成功しません でした。 発生時の状況:   my.cnf 内のMySQLユーザーパスワードに「$」が含まれており、ダブルクォーテーションで囲んでいましたがエラーが解消されませんでした。また、 log-bin パラメータがファイル名のみで指定されていました。既存システム(LifeKeeper v9.3.2)ではファイル名のみで動作していましたが、新システム(LifeKeeper v9.9.0)ではエラーとなりました。 原因究明のプロセス:  サポートとのやり取りにより、パスワードの特殊文字(「$」)を正しく扱うためにはシングルクォーテーションで括る必要があること、および log-bin のパスはLifeKeeper for Linux v9.6以降ではフルパス指定が必須になったことが判明しました。 判明した根本原因:  1. MySQLユーザーパスワードに特殊文字(「$」)が含まれる場合の記述ルール(シングルクォーテーションで括る)の不理解、および 2. LifeKeeper for Linuxのバージョンアップに伴うMySQL ARKの仕様変更( log-bin のフルパス指定必須化)への追従不足が原因でした。 ケース3:WebサーバーARKの特性理解不足 – IISの拡張前処理スクリプト IISリソース拡張前処理スクリプト実行時のエラーメッセージについて 事象の概要:  IISリソース作成時の拡張前処理スクリプト実行中にエラーメッセージが発生しましたが、 その後の拡張はエラーなく実行され、IISリソースの作成自体は完了 しました。 発生時の状況:  既にボリュームリソースが拡張済みであったにも関わらず、IISリソースの拡張前処理スクリプト内で再度ボリューム拡張を試みていました。 原因究明のプロセス:  サポートの確認により、このエラーは既にボリュームリソースが拡張されているため発生する、運用上問題のない情報メッセージであることが確認されました。 判明した根本原因:  拡張前処理スクリプトが、既に拡張済みのボリュームに対し再度拡張処理を行おうとしたため発生する、意図されたエラーメッセージであり、IISリソースの拡張自体には影響がありませんでした。 ケース4:Generic ARK利用時の注意点 – スクリプト依存とサポート範囲 Generic ARK リソース (JP1/Base)における quickCheck の仕組みについて 事象の概要:  Generic ARK(JP1/Base)における quickCheck の動作について問い合わせ。ネットワークメンテナンスに伴う通信断の影響で、 quickCheck が失敗しOSが再起動しました。 発生時の状況:   quickCheck スクリプト内で名前解決を使用しており、通信断により名前解決ができず quickCheck が失敗したと推測されました。 原因究明のプロセス:  問い合わせたGeneric ARKがサポート対象外であることが判明し、お客様が作成したスクリプトの内容に依存するため、LifeKeeper製品としての詳細な案内はできませんでした。 判明した根本原因:  サポート対象外のGeneric ARKを利用しており、スクリプトの内容(名前解決への依存)が起因する問題であったため、LifeKeeper製品としての根本原因は特定できず、スクリプト作成者による詳細確認が必要でした。 「再発させない!」ための対応策と学び 具体的な解決策: LB Health Checkリソース関連:  ネットワークセキュリティグループ(NSG)やファイアウォールで、ILBのIPアドレスからのプローブ用ポートへの通信を確実に許可する。 HC_TIMEOUT の設定値を環境に合わせて調整する。 LifeKeeper for Windowsを導入するサーバーの ホスト名は、すべて大文字で設定 する 。 MySQLリソース関連:  MySQLユーザーのパスワードに 特殊文字(「$」など) を使用する場合は、 必ず 「’」(シングルクォーテーション)で文字列全体を括って 設定する。 my.cnf 内の datadir 、 log-bin 、 log-tc パラメータは、LifeKeeper for Linux v9.6以降では共有ディスク上の 絶対パス(フルパス) で指定する。 IISリソース関連:  IISリソース作成時の拡張前処理スクリプト実行中に、既に拡張済みのボリュームに関するエラーメッセージが表示された場合、その後の IISリソース拡張が 成功 していれば、運用上問題ないメッセージとして認識 する。 Generic ARK関連:  利用するアプリケーションがLifeKeeperのサポート対象であることを事前に確認する。Generic ARKで利用するスクリプトは、 作成者が動作内容(特に外部依存性) を詳細に把握し、デバッグログ出力やエラーハンドリングを適切に実装する。 再発防止策(チェックリスト形式):   ARK のサポート範囲と互換性確認: 専用ARK利用時もGeneric ARK利用時も、対象アプリケーションとLifeKeeperのバージョンがサポートされているか、 サポートマトリクス で事前に確認する。   OS/LifeKeeper バージョンアップ時の仕様変更確認:  OSやLifeKeeper本体のバージョンアップを行う際は、リリースノートやドキュメントを詳細に確認し、 ARK固有の仕様変更(例: MySQL ARKの log-bin パス指定) がないか確認する。   ARK 固有の設定ファイル(例: my.cnf)の厳格な管理:  アプリケーションARKが参照する設定ファイルは、LifeKeeperの要件(例: パスワードの記述ルール、パスの絶対指定)に沿って適切に設定・管理する。   通信経路とセキュリティ設定の徹底確認:  ロードバランサーのヘルスプローブやアプリケーション間の通信など、LifeKeeperが監視・利用する通信経路について、 ファイアウォールやネットワークセキュリティグループの設定を構築前に徹底的に確認 し、必要なポートが解放されていることを保証する。   命名規則(ホスト名・ユーザー名など)の遵守:  LifeKeeperが動作する環境では、ホスト名やユーザー名にLifeKeeperの制約(例: Windows版でのホスト名の大文字制約 )がないか事前に確認し、 命名規則を遵守 する。   Generic ARK 利用時のスクリプト詳細把握:  Generic ARKを利用する場合は、スクリプトの作成者が動作内容(特に外部依存性、名前解決など)を詳細に把握し、デバッグログ出力やエラーハンドリングを適切に実装する。   LifeKeeper ログの日常的な監視とエラーコード理解:  LifeKeeperログに記録されるエラーメッセージやエラーコードの意味を正確に理解し、日常的に監視することで異常を早期に検知・対処できる体制を整える。 ベストプラクティス: 設計段階での詳細な要件定義:  アプリケーションリソースを保護する際は、LifeKeeperの要件、アプリケーションの要件、ネットワークの要件を詳細に定義し、設計書に落とし込む。特に通信要件や設定ファイルのパス、パスワードポリシーは入念に検討する。 公式ドキュメントの積極的活用:  各ARKの管理ガイド、処理概要、リリースノート、動作環境リストなど、SIOSが提供する最新の公式ドキュメントを常に参照し、推奨設定や既知の制約を把握する。 検証環境での徹底的なテスト:  OSアップデート、LifeKeeperバージョンアップ、アプリケーション設定変更など、システム構成に影響を与える変更は、必ず本番適用前に検証環境でLifeKeeperリソースを含むシステム全体の動作テストを実施する。 運用フローとチェックリストの確立:  リソース作成、変更、OSアップデートなどの主要な運用タスクについて、具体的な手順と確認項目を記した運用フローとチェックリストを確立し、ヒューマンエラーを防止する。 サポート活用と情報共有:  疑問点やエラー発生時には、積極的にSIOSサポートに問い合わせ、得られた知見はチーム内で共有しナレッジとして蓄積する。 まとめ 本記事では、LB Health Check、MySQL、IIS、Generic ARKといったアプリケーションリソースに関連する様々なトラブル事例を取り上げました。 これらの事例から、アプリケーションARKの安定稼働には、LifeKeeper本体やARKの仕様への深い理解に加え、連携するOSやアプリケーションの設定、そして基盤となるネットワーク通信環境の綿密な確認が不可欠であることが明らかになりました。 特に、OSやLifeKeeperのバージョンアップに伴う仕様変更への追従、設定ファイル記述ルールへの注意、そしてGeneric ARK利用時のスクリプト内容への詳細な把握が、トラブルを未然に防ぐ鍵となります。 日々の運用でこれらの点を意識し、公式ドキュメントの活用と検証を徹底することで、「困った!」を「できた!」に変え、より堅牢なクラスタ環境を構築・維持できるでしょう。 次回予告 次回の連載では、「クラスタの予期せぬ停止を防ぐ!ネットワーク構成のトラブルシューティング」と題し、LifeKeeper環境におけるネットワーク関連のトラブル事例とその解決策、安定稼働のためのベストプラクティスを深掘りします。どうぞご期待ください! 詳しい内容をお知りになりたいかたは、以下のバナーからSCSK LifeKeeper公式サイトまで
アバター
こんにちは。SCSKの井上です。 運用効率化を実現するためには、収集したデータを適切に可視化し、現状を一目で把握できる仕組みが重要です。New Relicでは、テンプレートを使って簡単にダッシュボードを構築できます。この記事で、New Relicで収集したデータの可視化方法を習得し、運用効率化につながる一助になれば幸いです。   はじめに ダッシュボード機能を活用し、CPU使用率やメモリ、レスポンスタイム、エラー率などの指標をグラフ化し、折れ線グラフで時系列の変化を表示すれば、リアルタイム監視に役立ちます。また、しきい値を設定し、異常値を色分けすることで、問題の早期発見が可能です。NRQL(New Relic Query Language)を用いることで、柔軟なカスタムチャートも作成できます。収集したデータを関連付けてオブザーバビリティを実現するためにも、ダッシュボードを使って可視化することが運用効率化の鍵になってきます。どんな作り方があるのか、どのように活用していけばよいかを解説してきます。   ダッシュボードを作る目的 目的が曖昧なまま作成されたダッシュボードは、利用されずに陳腐化してしまいます。そのため、 ダッシュボードを作成する際には、「誰が」「何を判断するためのものか」を明確にすること が不可欠です。たとえば、運用担当者であれば障害検知やリソース使用率の監視、マネージャー層であればコスト管理やSLA遵守、経営層であればビジネスインパクトの確認といったように、利用者ごとに必要な指標は異なります。 利用者 判断すること 指標例 運用担当者 サーバ・アプリが正常稼働しているか 障害や異常の有無 CPU・メモリ使用率 レスポンスタイム エラーレート アラート件数 マネージャー層 SLA遵守状況 コストが予算内か 稼働率 クラウド利用料 リソース消費量 経営層 技術的問題のビジネス影響 売上やUXへのインパクト トランザクション数 国別、曜日ごとのアクセス数 開発チーム 新機能リリース後のパフォーマンス ボトルネック特定 APIレスポンスタイム DBクエリ遅延 エラーログ   New Relic ダッシュボード カスタマイズやフィルタリング可能なNew Relicダッシュボードを使用して、スタック全体からデータをクエリし、ユースケースに応じた正確なインサイトを見つけられます。 newrelic.com   ダッシュボード(チャート)の種類 エリアチャートやラインチャートのような時系列可視化、バーやパイチャートによるカテゴリー比較、ビルボードやブレットによる重要KPIの強調表示など、New Relicのダッシュボードではデータの性質に応じて最適な視覚化手法を選ぶことができます。 チャートタイプ 用途 具体例 Area 単一属性の時系列推移を可視化 ・トラフィック量の増減 ・レスポンス量の変化 Bar カテゴリ間の合計値を比較 ・API別リクエスト数比較 ・エラー種別件数の比較 Billboard 単一の重要指標(KPI)を強調表示 ・エラー率のモニタリング ・レスポンスタイムの重要KPI表示 Bullet 実績値と目標値(Limit)の比較 ・SLA達成状況の表示 ・KPIが目標にどれほど近いか確認 Funnel 連続するプロセスの減少を表示 ・ユーザー遷移(訪問→購入) ・処理ステップの離脱分析 Heatmap 値の分布・密度を色で可視化 ・遅延の集中箇所の特定 ・ログ頻度やデータ密度の確認 Histogram データの分布(どの範囲が多いか)を把握 ・レスポンス時間の偏り分析 ・負荷データの分布確認 JSON クエリ結果を JSON のまま表示 ・開発者向けの詳細ビュー Line 複数系列の時系列推移の比較 ・CPU/メモリの変動確認 ・エラー件数の推移分析 Pie 全体に対する割合を表示 ・エラー種別割合 ・ユーザーOS/デバイス割合 Stacked Bar 合計値と内訳を同時に表示 ・サービス別トラフィック内訳 ・エラー構成比+総量 Table データを一覧形式で表示 ・FACET結果のランキング ・詳細データ比較、ログ確認   チャートタイプ | New Relic Documentation The chart types available when building queries in New Relic. docs.newrelic.com   ダッシュボードの作り方 ダッシュボードは主に次の3つの方法で作成できます。それぞれの方法について解説します。New Relicを使い始めた場合は、テンプレートから作成するか、既存のメトリクスデータを参考にNRQLの構成を理解した上で、カスタムダッシュボードを作成すると理解を深められます。 ダッシュボードを作り始める前に、ダッシュボードの編集や公開操作の権限の種類について確認します。以下、3つの種類が用意されています。編集は自分自身だけに限定したい、ダッシュボードが作成途中のため、完成してから公開したいなどの場合に、適切に選択することができます。 Permissions設定 説明 Edit – everyone in account アカウント内のすべてのユーザーがダッシュボードを編集できます。 Read-only – everyone in account アカウント内のすべてのユーザーがダッシュボードを閲覧のみできます。編集や削除は作成した自身のみに制限されます。 Private ダッシュボードは作成者のみが閲覧・編集可能です。完全に非公開の状態です。   New Relic実践入門 第2版 オブザーバビリティの基礎と実現 | 翔泳社 あらゆるデータを収集・分析・可視化して、システム/サービスの変化に能動的に対処せよITシステムやサービスが複雑化する現代において、オブザーバビリティ(Observability:可観測性)という考え方が極めて重要になっています。オブザーバビ... www.shoeisha.co.jp テンプレートから作成 既存テンプレート100種類以上から目的に合ったダッシュボードを簡単に作成できます。ダッシュボードを作成する際は、New Relicでデータ収集ができている状態から作成することを推奨します。ここでは、すでにInfrastructureエージェントが導入済の状態で手順を進めます。 1.左メニューより「Dashboards」をクリックします。 2.右上の「+ Create a dashboard」をクリックします。 3.「Browse pre-built dashboards」をクリックします。 4.テンプレートを選択します。 5.「Skip this step」をクリックします。次のステップも同様に「Skip this step」をクリックしてください。 6.ダッシュボードが作成されたメッセージを確認後、「View dashboard」をクリックします。 7.一から作成せずに高機能なダッシュボードが簡単に作成ができました。           推奨されるダッシュボード | New Relic Documentation 推奨されるダッシュボード docs.newrelic.com   カスタムダッシュボードから作成 既存テンプレートから作成したダッシュボードでは、不要なチャートが含まれたり、NRQLの修正箇所が分からずメンテナンスが難しい場合があります。一から作成すれば、必要な情報だけを表示でき、メンテナンス性も向上します。   1.左メニューより「Dashboards」をクリックします。 2.右上の「+ Create a dashboard」をクリックします。 3.「Create a new dashboard」をクリックします。 4.ダッシュボード名の入力と操作権限を選択し、「Create」をクリックします。 5.ダッシュボードの枠が作成されましたので、「Add a new chart」をクリックします。 6.「Add a chart」をクリックします。「Add text, images, or link」はダッシュボードに説明文やハイパーリンク、画像などを追加する際に使用します。 7.NRQLの編集画面にクエリを記載します。 8.「Run」を実行後、NRQLの実行結果が表示されます。chart typeで表示されているグラフの種類を変えることもできます。 9.鉛筆マークをクリックするとチャートの名前の入力やグラフの種類などを変更することができます。完了後、「Add to dashboard」をクリックします。 10.ダッシュボードに作成したNRQLが表示して完了になります。           表示されているチャートからダッシュボードを作成 既にホスト単位やサービス単位で表示されているチャートを個別に追加することで、必要なチャートだけを選択してダッシュボードに組み込むことができます。ダッシュボードを軽量に保ちながら段階的に構築でき、構成を確認しながら進められるため、完成イメージを把握しやすくなります。 1.ダッシュボードに追加したいチャートの「・・・」から、「Add to dashboard」をクリックします。   2.「Widget title」にチャートの名前を変更する場合は、変更します(日本語可)。追加したいダッシュボードを選択し、「Copy」をクリックします。ダッシュボートにタブを作成している場合は、ダッシュボート名/タブ名でリストが表示されています。 3.右下にダッシュボード完了のポップアップが表示されます。 4.ダッシュボード一覧からデータが追加されていることを確認します。   ダッシュボードの編集 ダッシュボードを作成した後、運用効率化のために構成を変更することがあります。ここでは、どのような編集方法があるのか、一例を解説します。ダッシュボードの一覧の横にある★をクリックするとリストのトップに表示されます。よく使うダッシュボードがある場合は、実施を推奨します。お気に入り機能はユーザー個人の設定のため、他のユーザには反映されません。   ダッシュボードの編集方法 ダッシュボードの編集は編集したいダッシュボード画面の右上のアイコンから実施します。鉛筆マーク中は編集モードとなり、表示するチャートの幅の変更や表示順の変更などができます。 ダッシュボードの編集開始は「鉛筆マーク」 ダッシュボードの編集完了は「Done editing」 タブの構成 タブを使ってチャートを分けることで、表示するデータ量を調整でき、読み込み速度とともに見やすさが向上します。また、「サービス別」「環境別」「機能別」など、目的に応じてタブを構成することで、必要な情報へ簡単にアクセスできるようになります。 1.編集したいダッシュボードの右上の「鉛筆マーク」をクリックします。 2.鉛筆マークをクリック後、「Add Page」をクリックします。 3.タブの名前を入力し、「Add page」をクリックします。 4.タブが追加されます。 5.タブの名前や複製、削除はタブをクリックして行います。 【補足】編集終了後は、「Done editing」をクリックします。   ダッシュボードの名前変更と編集権限 ダッシュボードの名前を変更したい場合や、完成してからダッシュボードをチーム内に公開したい、作成者以外ダッシュボードの編集をさせたくないなどの運用が発生した場合は、以下の手順にて変更ができます。 1.対象のダッシュボードを開き、右上「・・・」から「Settings」をクリックします。 2.名前の変更やダッシュボードの編集公開の変更ができます。   ダッシュボードの管理 | New Relic Documentation Manage your dashboard in New Relic: layout, export, night mode, create/edit/delete widgets. docs.newrelic.com   ダッシュボードのエクスポート・インポート ダッシュボードをエクスポートして保存し、後で復元したり、よく使うメトリクスやウィジェット構成をJSON化してテンプレートとして他のプロジェクトに展開できます。JSONの他に、運用レポートとしてダッシュボードをPDFで出力したり、テーブル形式であればCSVとしても出力できます。ここではJSONのエクスポートとインポートを例に解説します。 1.対象のダッシュボードから「・・・」より「Copy JSON to clipboard」をクリックします。 2.右下部に以下のポップアップが表示されます。この時点でメモ帳などにJSONを貼り付けできます。 3.ダッシュボード一覧画面にもどり「Import dashboard」をクリックします。 4.コピーしたJSONを貼り付けます。必要に応じて編集します。編集エラー個所はエディター内で確認できます。 5.ブラウザの画面更新ボタンをクリックし、ダッシュボード一覧に表示されていればインポート完了です。チャートが反映されているかを確認してください。       ダッシュボードとグラフのインポート、エクスポート、追加 | New Relic Documentation Import and export data from dashboards and charts. docs.newrelic.com   ダッシュボードのビジュアルを促進させるオプション New Relicではダッシュボードを視覚的にわかりやすく表示させるためのいくつかのオプション(Customize this visualization)が用意されています。これらのオプションを使って、運用効率化につながるダッシュボードをカスタマイズすることができます。Chart typeでグラフの種類も変更することができます。デフォルトで表示されたグラフが見づらい場合は、他のグラフの種類も表示することもできます。グラフの種類によって使えるオプションは異なります。 項目名 説明 実際の画面例・使用例 Y-axis (2) 異なる単位のデータ比較を同じチャートに表示 相関分析をする際に利用。負荷とパフォーマンス、エラーとトラフィックなど。 Other groups 表示しきれないグループをまとめる サーバー別にレスポンスタイムをグループ化し、色分け表示。 Legend 凡例の表示・非表示 チャート右下に「正常」「警告」「エラー」などの色ラベルが表示される。 Dashboard options 時間の固定 ダッシュボード上部にあるタイムピッカーで選択された時間範囲を無視し、チャートごとに固定の時間範囲を設定。 Colors チャートの色をカスタマイズ エラー率が高いと赤、正常なら緑など、しきい値に応じて色が変化。 Units 数値の単位を設定 レスポンスタイムを「ms」、データ転送量を「MB」で表示。 Thresholds しきい値を設定して色やアラートを変更 エラー率が5%を超えるとチャートが赤くなる設定等。 Markers 特定のイベントを示す縦線などを追加 デプロイ日時に縦線を追加し、パフォーマンス変化を視覚的に確認。 Null values nullデータの表示方法を設定 データがない時間帯をグレーで表示、またはゼロとして扱う設定。 Tooltip カーソルを合わせたときの詳細表示 「2025/12/01 14:00 – CPU使用率:75%」などのポップアップが表示される。 Initial sorting テーブルがどの列を基準に、どんな順番で並ぶか を指定する設定 テーブルを開いた瞬間に、確認したい順序で見たい場合。 Billboard settings 数値を大きく強調する KPI や重要なメトリクスに使う場合など。   Y-axis (2):異なるスケールのデータを同じチャートに表示 Y-axis(2)で単位が違うデータを一つのグラフでそれぞれ軸の単位を変更することでわかりやすく表示します。   Other groups:表示しきれないグループをまとめる Other groupsで表示しきれない下位グループをまとめて1つのグループとして表示します。   Legend:凡例の表示・非表示 Legendで凡例の表示非表示を設定することができます。   Dashboard options:時間の固定 Dashboard options(Ignore time picker)で NRQLで指定した期間 または ダッシュボードのデフォルト期間のみに固定します。TVモード(画面右上の鉛筆マークの横)で常時表示させる際に組み合わせて使用するケースを想定しています。   Colors:チャートの色をカスタマイズ Colorsで指定した色に変えることができます。Consistentは常に色は固定、Dynamicは値の変化(傾向)によって色が変わる設定になります。   Units:数値の単位を設定 Unitsで軸の単位を表示することができます。   Thresholds:しきい値を設定して色やアラートを変更 Thresholdsを用いることで、閾値設定したWarningやCriticalがどのラインに達した場合かを視覚的にわかるようになります。   Markers:特定のイベントを示す縦線などを追加 Markersでデプロイや変更箇所のイベントがあった時間帯を示すことができます。   Null values:nullデータの表示方法を設定 Null valuesでデータが欠損している場合のグラフの表示の仕方を調整することができます。   オプション 意味 使用シーン(活用例) Leave as null (default) データが存在しない部分は空白のままにする(初期設定) 一時的なデータ欠損を視覚的に確認したいとき。例:ネットワーク障害の影響を見たい場合。 Remove Null値のデータポイントを完全に除外する 欠損データが分析に不要な場合。例:平均値計算に影響を与えたくないとき。 Preserve the last value 最後の有効な値を保持し、Null部分に適用する データが途切れても継続的な傾向を見たいとき。例:CPU使用率が安定しているかを確認したい場合。 Transform into 0 Null値を「0」として扱う 欠損をゼロとして扱うことで、チャートの連続性を保ちたいとき。例:トラフィックが完全に停止したことを示したい場合。   Dashboard Customization Options Get more flexibility to customize the look and feel of your charts for more powerful data visualization. newrelic.com   Tooltip:カーソルを合わせたときの詳細表示 グラフ内のエンティティが多い際に、どのエンティティを指しているのかをカーソルを合わせることでわかるようになります。   Initial sorting:テーブル表示の順序設定 初めから並び順を固定したい場合は、このオプションを使います。テーブルのカラム名をクリックすることで都度順序の並び替えも可能です。   Billboard settings:数字の見せ方の設定 数字を強調させるために配置や大きさなどを設定することができます。URLを記載することで、チャートをクリック後に、該当のURLへアクセスすることも可能です。   項目 意味 Display mode 値やラベルの表示方式を選ぶ(Auto, Value only, Label only 等) Alignment テキストの配置 Value size 数値の文字サイズ Label size ラベルの文字サイズ Columns amount ビルボード表示の横幅(並べる列数の調整) Title リンクの表示名 Url リンク先 URL Open in a new tab 新しいタブで開くかどうか   Markdownを使った運用効率化 作成したダッシュボードの見方や問題が発生した際のエスカレーション手順リンクなどの情報をダッシュボード内に表示することができます。必要な判断材料や対応手順を一元的に確認でき、トラブル発生時の対応スピード向上に貢献できます。また、ダッシュボードに簡単な操作ガイドやFAQを表示することで、新しいメンバーでも迷わずダッシュボードを確認することができます。作成して形骸化させないためにも、本機能を使って運用効率化を促進していきたいですね。 1.対象のダッシュボードを開き、右上の「+ Add widget」をクリックします。 2.「Add text, images, or links」をクリックします。 3.文字やハイパーリンクなどを記載することができます。右側にプレビュー画面が表示されるため、実際の表示イメージを確認しながら作成できます。編集後、「Save」をクリックします。 4.右上の鉛筆マークをクリックして、配置の調整して完了になります。   ダッシュボードの管理 | New Relic Documentation Manage your dashboard in New Relic: layout, export, night mode, create/edit/delete widgets. docs.newrelic.com   ダッシュボードの設計ステップ ダッシュボードを作成する際の基本の考え方が整理されています。扱う指標を選定し目的に沿った情報配置を計画し、次に内容を一目で状況が理解できるようにレイアウトへ落とし込みます。そして、適切なチャート選択や文脈づけ(ラベル・単位・比較軸の明確化)を行い、情報の流れが変化 → 理由 → 行動として読み解けるように仕上げるプロセスが示されています。 Step 内容 目的 / 要点 1. 目的と質問の明確化 ダッシュボードで答えるべきビジネス質問を定義する 何を判断するための画面か?を明確にすることで、情報過多を防ぐ 2. KPIと必要データの選定 目的に直結する少数の指標を選ぶ データは収集→整形→モデリング→変換→可視化で準備する 3. ストーリーライン設計 現状 → 変化 → 要因 → アクションの流れを組む 何が起きたかを短いストーリーとして理解させる 4. 図表(チャート)選定 トレンド、比較、構成比など目的に合う可視化を選ぶ 折れ線=トレンド、棒=比較、円/ドーナツ=構成比など 5. レイアウト設計 視線の動きに合わせて情報を配置する 上:要点、中央:変化、下:詳細/原因。1画面で把握できる構成にする 6. ラベル・単位・文脈の明確化 タイトル・単位・比較軸を明確にする 誤解を防ぎ、意図を瞬時に伝えるために重要 7. ユーザーテストと改善 実際の利用者に見てもらい改善する(プロトタイピング) ユーザー理解と反復改善が成功の鍵。多くの失敗は会話不足が原因 8. 継続的メンテナンス KPI見直し、データ更新、自動化などの運用改善 ダッシュボードは作って終わりではなく継続的に最適化する   Effective Dashboard Design: Principles, Best Practices, and Examples Master dashboard design principles and best practices with this step-by-step guide. Learn to select metrics, choose the ... www.datacamp.com   ダッシュボードの活用例 ダッシュボードを作成し、チーム間で共通の指標を共有することで、意思決定のスピードが向上します。ダッシュボードを確認して、実際にどうしなければらないのか、行動につながる設計を行い、継続的に改善することで、運用効率に貢献することができます。たとえばダッシュボードを作成を作成することで以下のような活用ができます。 リアルタイム監視             : フロントエンド、バックエンドの状態をリアルタイムで確認 異常検知とアラート          : しきい値を設定し、異常が発生した際に通知や問題の早期発見とダウンタイムの防止 トレンド分析                   : 過去のデータを基にパフォーマンスの傾向、キャパシティの改善検討 チーム間の情報共有          : カスタムダッシュボードを作成し、開発・運用・ビジネスチームで共有 ビジネスインパクトの把握 : システムパフォーマンスが売上やユーザー体験にどう影響するかを可視化   様々な視点からダッシュボードを作成できますが、ここでは以下の視点に基づいて目的と指標を整理しました。 視点 目的 主な 指標 インフラ サーバ・クラウドリソースの監視 CPU使用率、メモリ使用率、ディスクI/O、ネットワーク帯域、ホスト稼働率 アプリ ユーザー体験可視化、ボトルネック特定 Apdexスコア、平均レスポンスタイム、エラー率、外部サービス呼び出し時間(API) コスト クラウド利用料やリソース消費の最適化 クラウドサービス別コスト、データ転送量、New Relic有償アカウント数 セキュリティ 不正アクセス検知や脆弱性管理 ログイン失敗回数、異常IP、セキュリティ関連アラート件数、CVE件数、 ビジネス 意思決定支援 トランザクション数、ユーザーセッション数、曜日ごとのページ訪問数   さいごに 2025年最後の記事は、New Relicに送信したデータをダッシュボードでどのように可視化し、運用に活かすか、設計の考え方も含めて紹介しました。ダッシュボードとNRQLを使いこなすことで、監視だけでなく、トレンド分析や異常検知、ビジネス指標の把握など、データ活用の幅が大きく広がります。この記事が、効率的な運用や意思決定のスピード向上に向けた第一歩となり、今後の改善や最適化に役立つ一助になれば幸いです。 SCSKはNew Relicのライセンス販売だけではなく、導入から導入後のサポートまで伴走的に導入支援を実施しています。くわしくは以下をご参照のほどよろしくお願いいたします。
アバター
前回の記事 では、取り組みの背景や概要をご紹介しました。今回は、ツールを開発するにあたり検討した 要件定義 についてお話しします。   業務要件(システム要件) 今回のツールは、AWS環境の設計・構築に関わるメンバーが、 構築フェーズ完了後にパラメータシートを効率的に作成する ことを目的としています。従来は、AWSコンソールを開き、設定値を目視で確認しながらExcelに転記するという作業が必要でしたが、この工程は非常に時間がかかり、ヒューマンエラーのリスクも高いものでした。 そこで、要件定義では「誰が」「どのような場面で」「どのような目的で」このツールを使うのかを明確化しました。 Who(だれが) 主な利用者は、当部に所属するインフラエンジニアやクラウド構築担当者です。特に、AWSの設計・構築を担当するメンバーが中心となりますが、専門的なスキルを持たないメンバーでも簡単に操作できることを重視しました。将来的には、運用担当者や品質管理チームなど、幅広い部門での利用も想定しています。 When(いつ) ツールの利用タイミングは、AWS環境の構築フェーズが完了した後です。構築手法は問いません。CloudFormationやCDKなどのIaCを使った場合でも、コンソールから手動で構築した場合でも、同じように利用できることを目指しました。これにより、プロジェクトの規模や構築方法に依存せず、標準化されたパラメータシートを作成できます。 Where(どこで) 基本的には社内ネットワークやローカルPCで利用します。セキュリティを考慮し、外部環境への依存を避ける設計としました。将来的には、社内ポータルやクラウド上での利用も検討しています。 What(なにを) ツールを使って、AWSリソースの詳細情報を収集し、Excel形式のパラメータシートを自動生成します。これにより、従来の手作業による転記やフォーマット調整を不要にし、成果物の標準化を実現します。 Why(なぜ) ドキュメント作成工程を省略化し、業務の生産性を向上させることが最大の目的です。さらに、ツールによって情報の正確性を担保し、ヒューマンエラーを防止することで品質向上にもつなげます。 How(どのように) 技術的なバックグラウンドを問わず、誰でも簡単に操作できるUIを提供します。AWS CLIの知識がなくても、GUIベースでリソースを選択し、Excel出力まで完結できる仕組みを目指しました。   機能要件 業務要件で明確化した利用目的をもとに、ツールに必要な機能を整理しました。ここでは、 どのような入力を受け取り、どのような出力を行うのか 、さらに 抽出する情報の方針 について検討した内容を詳しく説明します。 まず、どのような入力を受け取るか検討しました。 機能要件 — インプット(入力)比較表 案 方式 メリット デメリット   案① AWS CLI describe の結果JSON(構築後取得) 構築後に取得するため、CloudFormationテンプレートに含まれないパラメータも取得可能 構築方法に依存しない(手動構築やIaCどちらでも対応可能) CLI実行の事前作業が必要/権限・プロファイル設定が前提 〇採用 (正確性・汎用性重視) 案② CloudFormationテンプレート(構築時の宣言) 構築時点で利用しているため、情報の取得が容易、構築作業前にドキュメント作成可能 テンプレートに含まれないパラメータは取得できない 依存関係の解決が必要(参照IDなど) Cfn以外の構築方法では利用不可 ×不採用 (実環境との差異リスク)   次にどのような出力を行うのか検討しました。 機能要件 — アウトプット(出力)比較表 案 方式 メリット デメリット   案① Excel(.xlsx) 顧客納品に適合/レビュー性が高い 書式設計のルール設計が必要 〇採用(納品適合性) 案② CSV 軽量/他ツール連携しやすい 納品体裁への変換が必要(VBA等) ×不採用 案③ Markdown ドキュメント化容易/差分管理しやすい 顧客納品には不向き/表現力に制約 ×不採用   AWSリソースのパラメータをどの範囲で抽出するかについても検討しました。 抽出するデータ 案 方式 メリット デメリット   案① 必要な情報のみ抽出 AWS側でパラメータ追加があってもコード修正不要 Excel整形が容易 想定外のパラメータに気づけない リソースごとにコードが必要 ×不採用 案② すべてのパラメータを出力 顧客に正確な情報を提供可能 リソース追加に柔軟 Excel整形に工数がかかる 〇採用 (正確性・汎用性重視)   機能の全体像 最終的に、ツールは以下の機能を備えることを目指しました。 AWS CLIのdescribeコマンド結果を取り込み、JSONを解析 必要な情報を抽出し、Excel形式で整形して出力 複数リソースの選択・一括出力に対応 誰でも簡単に操作できるGUIを提供   まとめ 今回の取り組みを通じて、業務改善の重要性を改めて実感しました。パラメータシート作成の自動化は、単なる効率化にとどまらず、品質の一貫性やヒューマンエラー防止にも大きく貢献できることがわかりました。一方で、アプリケーション開発の知見不足から、設計や要件定義で試行錯誤を重ねる場面もありましたが、その経験自体がチームの成長につながったと感じています。 このツールにはまだ改善の余地がありますので、今後も継続的に改良を重ね、より使いやすく、業務に役立つものにしていきたいと思います。 というわけで、私の投稿はここまでです! 次回は齋藤さんにバトンタッチしますので、ぜひお楽しみに!
アバター
みなさん、こんにちは。SCSKの津田です。 LifeKeeper は、オンプレミスの物理サーバから仮想基盤、各種クラウドサービスまで、幅広い環境で導入・運用できる高可用性クラスタソフトウェアです。 SIOSによると、近年ではクラウド環境への導入が全体の約半数を占めるまでに拡大しており、当チームでも設計・構築案件の多くがクラウド基盤上で展開されています。 とはいえ、多くの企業システムでは今なおオンプレミス環境が主軸として稼働しており、物理サーバや仮想基盤で LifeKeeper を利用したいというニーズも依然として高い状況です。 そこで本記事では、仮想環境においてLifeKeeperを導入する上で押さえておきたいポイントをご紹介します。 仮想環境での冗長化をご検討中の方は、ぜひご確認ください! 仮想環境のHAクラスター構成パターン 仮想環境で構成できるHAクラスター構成の基本パターンは以下となります。 共有ストレージが使えない環境では、データレプリケーション構成にすることが可能です。 構成①:共有ストレージ構成 構成②:データレプリケーション構成 構成③:データレプリケーション構成 (WSFCとの組み合わせ)     ※HAクラスター構成の他にSSP(Single Server Protection)構成も可能。 仮想環境におけるLifeKeeper障害対応 LifeKeeperを導入することで、以下のような幅広い障害を検知し、自動復旧(フェールオーバー)によるサービス継続が可能となります。 ・アプリケーション障害 ・ゲストOS障害 ・仮想マシン障害 ・仮想化ソフトウェア(ハイパーバイザ)障害 ・物理ホスト障害 ・ネットワーク障害(物理ホスト間のすべての通信経路断絶時) ※ゲストOS障害~ネットワーク障害までの範囲については、コミュニケーションパスが全て断たれた場合にノード障害として検知します。 上記の通り、物理ホストの障害にはもちろん、仮想マシンやアプリケーション単位の障害にも柔軟に対応できるため、仮想環境ならではの冗長性を最大限に活かすことができます。 特にVMwareの「vSphere HA」と比較した場合、ESXiホスト障害時にはLifeKeeperの方が障害検知から復旧までの時間が短いというメリットがあります。(LifeKeeperでは、待機系ESXiホストがあらかじめ起動状態で待機しているため、再起動が必要となるvSphere HAよりも迅速なフェールオーバーが可能。) なお、リソースの監視や障害検知の方法については、仮想環境特有のものではなく、クラウド環境や物理環境と同様の仕組みを採用しています。 【OS別】サポート内容・留意事項 昨今Broadcom社によるVMwareの買収を受けて、VMware以外の仮想環境(ハイパーバイザ)を選択されるケースも増加傾向にあります。LifeKeeperでは、VMware以外の仮想環境にも対応していますので、お客様のニーズに合わせた仮想環境で高可用性構成を実現できる点も強みとなります。 本項ではLinux/Windows毎の最新サポート状況(Ver10)や留意事項をご紹介します。 LifeKeeper for Linux  サポート対象の 仮想環境 一覧(LifeKeeper for Linux version10.0) LifeKeeper for Linuxでサポートされる仮想環境(ハイパーバイザ)は下記の通りとなります。 仮想環境 バージョン VMware vSphere 7.0, 8.0, 8.0U1, 8.0U2, 8.0U3 VMware Cloud on AWS SDDC 1.19以降 KVM RHEL 8.10以降およびRHEL 9.0以降、ならびにOracle Linux(RHCK/UEK)8.10以降およびOracle Linux 9.0以降のバージョンのみをサポートし、その他のディストリビューションは対象外です。 Nutanix Acropolis Hypervisor (AOS) 6.10, 7.0, 7.3 Hyper-V Windows Server 2022 Red Hat OpenShift Virtualization 4.17以降 ※仮想マシン上で使用できるOSついては下記をご確認ください。 オペレーティングシステム – LifeKeeper for Linux LIVE – 10.0 留意事項 サポート対象の各仮想環境に依存した制限や詳細な留意事項については、下記リンクの 「使用環境に関する制限・留意事項」 セクションをご確認ください。 仮想化環境 – LifeKeeper for Linux LIVE – 10.0 また、仮想環境として採用されることの多い VMware vSphere や Hyper‑V については、サイオステクノロジー社より個別の構成ガイドが提供されています。各ハイパーバイザでの構成例や特有の注意点が詳細にまとめられていますので、設計時には必ず確認することを推奨します。 ▼ VMware vSphere LifeKeeper for Linux 仮想環境構成ガイド (VMware vSphere編) – SIOS LifeKeeper/DataKeeper User Portal [Linux][Windows]VMware vSphere環境でRDM使用時のLifeKeeperサポート構成について – SIOS LifeKeeper/DataKeeper User Portal ▼ Hyper‑V(Linux / Windows 共通) LifeKeeper 仮想環境構成ガイド (Hyper-V編) – SIOS LifeKeeper/DataKeeper User Portal 共有ストレージ利用時の留意事項 LifeKeeper for Linuxでクラスタの共有データ領域を利用する際の構成については、以下をご参照ください。 [Linux]クラスターの共有データ領域として利用できる構成 – SIOS LifeKeeper/DataKeeper User Portal なお、LifeKeeper for Linuxでは、共有ストレージの認定が行われています。複数ノードで同一データを参照する共有ストレージ(SCSI / FC / iSCSI / SASなど)は、SCSI-2/3 ReservationによるI/Oフェンシングを前提としており、認定されたストレージを使用する必要があります。認定ストレージの一覧は、以下のリンクにある表を展開してご確認ください。 共有ストレージ – LifeKeeper for Linux LIVE – 10.0 一方、以下の構成についてはストレージ認定が不要です。 ・NASストレージ(Recovery Kit for NASが必要) ・DataKeeperによるデータレプリケーションに利用する全てのディスク装置(内蔵/外付けを問いません) ・vSphere上でVMDK ARKにより保護される共有ストレージ上の仮想ディスク ・以下の条件をすべて満たす環境で利用するストレージ(Any Storage)    ① OS・ハードウェア・プラットフォームでサポートされているストレージであること    ② LifeKeeperのSCSI Reservation機能をオフにすること    ③ LifeKeeperのQuorum/Witnessによるフェンシング機能を利用すること Any Storageでは、I/OフェンシングにSCSI ReservationではなくQuorum/Witnessを使用する点が特徴です。 そのため、認定ストレージ一覧以外のストレージも利用可能です。 また、データ破壊の危険性を低減するため、STONITH機能との併用も推奨されています。             仮想環境でAny Storageを適用する場合、以下にご注意ください。 ・仮想環境(ハイパーバイザ)やゲストOSの要件は、製品の要件に準じます。 ・接続方式(FC、iSCSI、SASなど)は不問です。 ・シングルパス・マルチパスのいずれもサポートされます。    但しマルチパスを使う場合は、DMMP(Device Mapper Multipath ARK)のみがサポートされます。 ・Quorum/Witness機能を使用しない場合は製品のサポート対象外となります。    (LifeKeeperとQuorum/Witnessとの組み合わせに関する動作や仕様⇒サポート対象、    個々の共有ストレージに依存する事象⇒サポート対象外) ・ご利用のストレージメーカーへのお問い合わせ窓口を確保の上、お客様にて十分な動作確認の上で採用されることを    推奨します。 ・STONITH機能を使用する場合、HeartBeatの相互断絶が発生すると双方のノードで電源断が発生し、確実なサービスの継続    には繋がらない可能性がありますが、これはデータ破壊を回避するためのSTONITHの動作となりますのでご了承ください。 ——————————————————————————– ■参考URL Any Storage: [Linux]ストレージサポートポリシー(Any Storage)について – SIOS LifeKeeper/DataKeeper User Portal STONITH: STONITH – LifeKeeper for Linux LIVE – 10.0 リザベーションの無効化: リザベーションの無効化 – LifeKeeper for Linux LIVE – 10.0 Quorum/Witness: Quorum/Witness – LifeKeeper for Linux LIVE – 10.0 LifeKeeper for Windows サポート対象の 仮想環境 一覧(LifeKeeper for Windows version10.0) LifeKeeper for Windowsでサポートされる仮想環境(ハイパーバイザ)は下記の通りとなります。 仮想環境 バージョン VMware vSphere 7.0, 8.0, 8.0U1, 8.0U2, 8.0U3 Red Hat OpenShift Virtualization 4.17以降 KVM RHEL 8.10以降およびRHEL 9.0以降、ならびにOracle Linux(RHCK/UEK)8.10以降およびOracle Linux 9.0以降のバージョンのみをサポートし、その他のディストリビューションは対象外です。 Microsoft Hyper-V Server 2016, 2019, 2022 Nutanix Acropolis Hypervisor (AOS) 6.10,7.0,7.3 ※仮想マシン上で使用できるOSついては下記をご確認ください。 オペレーティングシステム – LifeKeeper for Windows LIVE – 10.0 留意事項 サポート対象の各仮想環境に依存した制限や詳細な留意事項については、下記リンクの 「使用環境に関する制限・留意事項」 セクションをご確認ください。 仮想化環境 – LifeKeeper for Windows LIVE – 10.0 また、仮想環境として採用されることの多い VMware vSphere や Hyper‑V については、サイオステクノロジー社より個別の構成ガイドが提供されています。各ハイパーバイザでの構成例や特有の注意点が詳細にまとめられていますので、設計時には必ず確認することを推奨します。 ▼ VMware vSphere LifeKeeper for Windows / DataKeeper Cluster Edition 仮想環境構成ガイド (VMware vSphere編) – SIOS LifeKeeper/DataKeeper User Portal [Linux][Windows]VMware vSphere環境でRDM使用時のLifeKeeperサポート構成について – SIOS LifeKeeper/DataKeeper User Portal ▼ Hyper‑V(Linux / Windows 共通) LifeKeeper 仮想環境構成ガイド (Hyper-V編) – SIOS LifeKeeper/DataKeeper User Portal 共有ストレージ利用時の留意事項 LifeKeeper for Windowsには、Linuxのようなサイオステクノロジー社による認定ストレージリストは公開されていませんが、標準的なSCSI、FC、iSCSI等の共有ディスクが利用可能です(参考:https://www.windowsservercatalog.com/hardware)。 詳細や制約については、事前にサポートへのお問い合わせを推奨いたします。 また、LifeKeeper for WindowsではAny Storageポリシーは提供されていませんが、Quorum/Witness機能を利用することでスプリットブレインの回避に役立ち、より堅牢な運用が可能となります。 【OS共通】その他設計・運用上のポイント 仮想環境専用ライセンスの使用ルール・制限事項 仮想環境では、以下のような仮想環境特有のライセンス利用ルールが設定されていますのでご注意ください。 ・一つのライセンスは、一つの占有された物理ホスト上でのみ使用可能。 ・異なる物理ホスト間でのみ、クラスター環境を構成可能。 ・一つのライセンスで異なるバージョンのLifeKeeperを使用することは不可。 ・一つのライセンスには一つのサポートレベルのみ適用可能。 ・最低販売数量は2つ(Core 4、2クラスター環境)からとする。 LifeKeeper 設定上の考慮点 LifeKeeperのインストールおよびクラスター設定は、物理環境と同様の手順で行うことができます。具体的な手順については、オンラインマニュアルをご参照ください。 ※IPリソースの監視処理について 仮想環境では、物理的なネットワークスイッチだけでなく、仮想的なネットワークスイッチも存在するため、これらを含めたネットワーク構成全体を十分に考慮する必要があります。 さいごに 今回は仮想環境においてLifeKeeperを導入する上で押さえておきたいポイントをご紹介いたしました。 多様な選択肢と注意点が存在しますが、その分多様な要件に適した HA 構成を実現できる柔軟性を備えています。 仮想環境でLifeKeeper導入をご検討中の方にとって、少しでも参考となりましたら幸いです。   詳しい内容をお知りになりたいかたは、以下のバナーからSCSK Lifekeeper公式サイトまで
アバター
本記事は TechHarmony Advent Calendar 2025 12/24付の記事です 。 こんにちは、SCSKでAWSの内製化支援『 テクニカルエスコートサービス 』を担当している貝塚です。 re:Invent2025の直前に、Network Firewall Proxyという機能のプレビューが開始されました。 リリース記事 AWS Network Firewall Proxy のプレビューのご紹介 - AWS AWS の新機能についてさらに詳しく知るには、 AWS Network Firewall Proxy のプレビューのご紹介 aws.amazon.com ブログ記事 Securing Egress Architectures with Network Firewall Proxy | Amazon Web Services Note: Dec 4, 2025 – expanded with additional section on application networking integrations. Customers who control acces... aws.amazon.com AWS Network Firewallで機能提供していた透過型プロキシではなく、クライアント側で明示的にプロキシサーバとして指定する必要のあるタイプのプロキシです。 私の担当するお客様でも金融業を中心に過去にプロキシサーバの導入を検討された結果EC2でプロキシを構築したり、Network FirewallでのTLS検査を検討されたりしていますので、それらのお客様への導入という視点からNetwork Firewall Proxyの機能を検討してみます。 アーキテクチャ 名前にNetwork Firewallとついていますが、既存のAWS Network Firewallの一機能ではなく、独立したリソースになっているようです。NAT Gatewayとセットで動作し、クライアントは専用のVPCエンドポイント(Proxyエンドポイント)経由でプロキシを使用することになります。 シンプル(単一VPC)構成 単一VPC構成例 Architecture overview より引用   上の図がもっともシンプルな構成ですが、実際に設定してみるとNetwork Firewall Proxyと同じサブネット(パブリックサブネット)に自動的にProxyエンドポイントが作成されることが分かります。同VPC内に既にエンドポイントがあるのに別サブネットにエンドポイントを作る必要性はイマイチ理解できませんが、構成上はどちらでも動作しました。 少し調べてみたところ、 こちら のblogではProxyと同じパブリックサブネットにエンドポイントが置かれていたので、そのあたりは好きに設計すればよさそうです。 中央集約構成 他のネットワークリソース(Internet GatewayやNetwork Firewallなど)と同様に、Network Firewall Proxyも、複数のVPCのProxy機能をひとつに集約した構成を取ることができます。 そしてここが素晴らしい点なのですが、Network Firewall Proxyの機能はVPCエンドポイントとして提供されているので、通信要件がHTTP/HTTPSのみであれば、Transit GatewayやVPC PeeringなどでVPC間を接続することなく、インターネットとの通信をセキュアに実現できてしまうのです。 中央集約構成(HTTP/HTTPSのみ) Securing Egress Architectures with Network Firewall Proxy より引用   HTTP/HTTPS以外にも通信要件がある場合は、従来同様Transit GatewayでVPC間を接続し、HTTP/HTTPS通信はProxyエンドポイント経由、HTTP/HTTPS通信以外はTransit Gateway経由という方式が紹介されています。 中央集約構成(HTTP/HTTPS以外の通信要件あり) Securing Egress Architectures with Network Firewall Proxy より引用 上図構成だと、HTTP/HTTPSの検査・制御はNetwork Firewall Proxyで行う、HTTP/HTTPS以外の検査・制御はNetwork Firewallで行うことになります。ログの出力先もログのフォーマットも別になり、運用管理上の負荷が増えそうですが、これは現状仕方ありません。 一方で、Transit Gatewayで中央集約VPCとつながっているのであれば、Proxy エンドポイントは各VPCに持つのではなく、下図の通り中央集約VPCにひとつだけ置くというのも選択肢としてありえそうですが……HTTP/HTTPSトラフィックがNetwork FirewallとNetwork Firewall Proxy両方通ることになると無駄に高額なトラフィック料金を払わされることになり現実的ではないのかもしれません。まだNetwork Firewall Proxyの料金が発表されていないので、この部分は料金の発表を待たないとこれ以上議論できなさそうです。 HTTP/HTTPS以外のトラフィックもHTTP/HTTPSトラフィックも、Inspection VPCのNetwork Firewallを通過する プロキシのルールについて プロキシのルール構造は下図のようになっています。 プロキシは1つのプロキシ設定を持ちます。 プロキシ設定は複数のルールグループを持つことができます。プロキシ設定内で、複数のルールグループに0~の優先度をつけることができ、値が小さいグループから順に評価されるようになっています。また、どのルール(後述)にも合致しなかった場合のデフォルトのアクション(許可/拒否)をプロキシ設定で指定します。 ルールグループは複数のルールを持つことができます。ルールグループの設定のところで各ルールを記述して行きます。ルールは検査した通信に対するアクション(許可/拒否)と条件を記したもので、0~の優先度をつけることができ、値が小さいルールから順に評価されるようになっています。 以上をまとめると、ルールはフェーズ(後述)ごとに、以下の順番で評価されていき、どのルールにも合致しなかった場合、デフォルトのアクションが実行されるということになります。 優先度0のルールグループ:優先度0のルール → 優先度0のルールグループ:優先度1のルール → 優先度0のルールグループ:優先度2のルール → … → 優先度1のルールグループ:優先度0のルール → 優先度1のルールグループ:優先度1のルール → … → 優先度2のルールグループ:優先度0のルール → … → デフォルトのアクション フェーズ プロキシのルールは、HTTP/HTTPSの通信の段階に応じて、PreDNS、PreREQUEST、PostRESPONSEの3つのフェーズに分けて適用されます。 クライアントがHTTP CONNECTを出し、ProxyがDNS名前解決を行う前にルールを適用するのがPreDNSです。 クライアントがHTTP REQUESTを出し、Proxyがあて先にHTTP REQUESTを行う前にルールを適用するのがPreRequestです。 あて先からProxyに返ってきたHTTP RESPONSEをクライアントに返す前にルールを適用するのがPostResponseです。 Securing Egress Architectures with Network Firewall Proxy より引用 アクション アクションは、許可(allow)、アラート(alert)、拒否(deny)の3つがあります。 許可(allow)、拒否(deny)はそのままの意味ですが、アラート(alert)はアラートログに出力した上で次以降のルールの評価を継続します。許可した場合でもログを出力することができますので、許可(allow)ログは証跡としての保存用、アラート(alert)ログはCloudWatch等で捕捉してSNS連携等のアクションにつなげるという使い方が想定されているのだと考えられます。 条件 アクションの発生条件を、リクエストやレスポンスに関わる各種値を使用して指定します。現在対応しているのは以下の通りです。 request:SourceAccount – リクエスト送信元のAWSアカウントID request:SourceVpc – リクエスト送信元のVPC ID request:SourceVpce – リクエスト送信元のVPCエンドポイントID request:Time – リクエストが発生した日時 request:SourceIp – 送信元のIPアドレス request:DestinationIp – 送信先のIPアドレス request:SourcePort – 送信元のポート番号 request:DestinationPort – 送信先のポート番号 request:Protocol – 通信プロトコル(TCPなど) request:DestinationDomain – 送信先のドメイン名 request:Http:Uri – HTTPリクエストのURI(パス) request:Http:Method – HTTPリクエストメソッド(GET, POSTなど) request:Http:UserAgent – HTTPリクエストのUser-Agentヘッダーの値 request:Http:ContentType – HTTPリクエストのContent-Typeヘッダーの値 request:Http:Header/CustomHeaderName – HTTPリクエスト内の指定したヘッダーの値(CustomHeaderNameを実際のヘッダー名に置き換えて使用) response:Http:StatusCode – HTTPレスポンスのステータスコード response:Http:ContentType – HTTPレスポンスのContent-Typeヘッダーの値 response:Http:Header/CustomHeaderName – HTTPレスポンス内の指定したヘッダーの値(CustomHeaderNameを実際のヘッダー名に置き換えて使用) 設定手順 プロキシの作成は以下の手順で実施します。 プロキシルールグループの作成 ルールの作成 プロキシ設定の作成 → ここで、プロキシルールグループを指定 (まだ作成していないなら) NATゲートウェイの作成 (TLS インターセプトモードを有効化するなら) プライベートCAの作成、Resource Access Manager共有設定 プロキシの作成 → ここで、プロキシ設定、NATゲートウェイ、プライベートCAを指定 Proxyエンドポイントの作成 本稿では、具体的な操作手順については説明を致しません。( 公式ドキュメント などをご参照ください)以下、注意すべき点のみを書いて行きます。 TLSインターセプトモードについて TLS通信の中身を検査するには、プライベート証明書を発行できるプライベートCAが必要になります。 公式ドキュメントの記述 が不親切なのですが、プライベートCAを作成し、RAM (Resource Access Manager) で共有して、「下位CAは作成できず従属CA証明書の発行のみ許可する権限」(AWSRAMSubordinateCACertificatePathLen0IssuanceCertificateAuthority)を与えてあげてください。プライベートCAのことをよく知っている人には当然のことなのかもしれませんが、私はこれが理解できておらずハマりました。 TLS検査の仕組みや、クライアントPCでプライベート証明書を信頼する手順は、以下の記事もご参照ください。 AWS Network FirewallでアウトバウンドトラフィックをTLSインスペクションする AWS Network Firewallで、アウトバウンド(egress)のTLSインスペクション機能を検証しました。アウトバウンドTLSインスペクションにより、クライアントPC(社内)から外部のウェブサーバへのHTTPS通信の内容を検査することができるようになります。 blog.usize-tech.com 2023.12.27 TLSインターセプトモードが有効になると、条件 request:Http:* や  response:Http:* を使用した検査が行えるようになります。 Proxyエンドポイントの作成 プロキシが作成されると、プロキシと同じサブネットにProxyエンドポイントが作成されます。Proxyエンドポイントは追加作成することができます。プロキシの詳細に「VPC エンドポイントサービス名」という項目が表示されるので、プロキシを使用したいVPCでVPCエンドポイントを作成し、タイプに「NLB と GWLB を使用するエンドポイントサービス」、サービス名に「VPC エンドポイントサービス名」の値を入れるようにしてください。なお、最初に作成されるProxyエンドポイントは不要であれば削除しても構いません。 クライアントでプロキシ設定して使用 プロキシの詳細に「プライベート DNS 名」が表示されるので、その値( xxxxxxxx.proxy.nfw.<リージョンID>.amazonaws.com )をクライアントのプロキシ設定箇所に設定して使用します。 さいごに 顧客企業への導入検討と銘打ちながら、検討らしきものはアーキテクチャ検討部分だけとなってしまいましたが、プレビューが進みGA段階になれば、プレビュー段階に存在する様々な制約も解消され、具体的に検討が進められるかなと考えています。 現段階では、インターネットアクセス要件がHTTP/HTTPSだけであればTransit GatewayやVPC Peeringを作ることなくVPCエンドポイントだけで接続できてしまう点がメリットとして大きいように感じます。 まずはプレビューで出来る範囲でいろいろ試してみたいと思います。
アバター
だいぶご無沙汰しております。村上です。 ラスベガスで開催された「 AWS re:Invent 2025 」に参加してきましたので、複数回にわたって参加レポートをお届けします。 では早速。今回は「Self-Paced Traning」と「AWS Builder Center」についてです。 ※ちなみにタイトルにもある通り、海外渡航は人生2回目の海外初心者です・・・ コミュニケーションや現地での過ごし方で苦戦したエピソードもどこかで紹介したいと思います。 (今回の記事の内容自体にはほとんど関係ありません) 「Self-pased Traning」に参加してみた Self-pased Traningとは? re:Inventの初日、気合を入れすぎて相当早く会場へ到着。 お目当てのセッションまで時間があったので、会場を歩き回っていたところ「Self-paced Traning」というエリアを発見しました。 これは、re:Inventの開催期間中、AWSサービスに関するのクイズやハンズオン、AWS認定試験の準備など、200以上の学習コンテンツが「無料で」受けられるというもの。 「 AWS Skill Builder 」にあるものと重複しているものもありそうでしたが、このようなイベントで初披露されるコンテンツもあるとのこと。空き時間でサクッと参加するにはちょうどよいアクティビティかなと。 ▼会場の雰囲気はこんな感じ。 PCとモニターが1台ずつ用意されていますので、自身のデバイスは不要です。 受付に一言を声かけて、好きな席に座るだけでOKです。 実際にやってみた 今回「AWS ESCAPE ROOM」というRPG風ゲーム形式の学習コンテンツに挑戦しました。 その中でも「Exam Prep for AWS Certified AI Practitioner」という、AI Practitioner認定向けコンテンツを選びました。 ▼スタート画面。 ネタバレになるので詳細は割愛しますが、 AI Practitionerで求められる知識を問うクイズと、「Amazon Bedrock」を使った生成AIアプリケーション構築のハンズオンが含まれていました。 クイズはAWS初学者向けで、英語ですが難しいものはありません。 途中BGMが流れたり、動画視聴なんかもあったりするので、有線イヤホンがあると便利です。 (持っていてよかったものについては「会場の歩き方編」なんかでまとめたいと思っています) ▼ハンズオンで利用したアーキテクチャ。 操作はガイド通りにポチポチやっていけば簡単に作成できます。初学者がイメージを掴むのにはよいかもしれません。 本当は「岩に乗ったペンギン」の画像を出力させるというお題でしたが、「ラーメンを食べる日本人女性」にしてみました。 ▼こんな感じの画像が出力されました。   このように、気軽に学習できるだけでなく、海外からの参加者と同じ空間でで手を動かすのもよい刺激になりました。 空き時間を有効活用できるアクティビティとしておすすめです。 「AWS Builder Center」を利用しよう 「Self-paced Traning」を利用するには、「Builder ID」が必要になります。 これは「 AWS Builder Center 」を利用するための個人に紐づくアカウント。Amazon Q DeveloperやAWS Skill Builder、AWS re:Postなど、学習コンテンツや学習ツールを利用できるようになります。 (ちなみに私もほとんど活用したことがなかったので、これから触ってみる予定です) 「AWS Builder Center」に関しては、AWSも非常に力を入れている印象でした。 メンバー向けのイベントや休憩可能な専用ブースもあり、会場スタッフも「是非寄ってみて!」と積極的に声をかけていました。 ▼立ち寄った専用ブース。 ▼SWAGもたくさん。   ということで、第一回はこのくらいで終わります。 re:Inventに参加した際は是非「Self-paced Traning」への参加を、 また、日々の学習の際は「AWS Builder Center」を、というお話でした、 また次回作も見てくれたらうれしいです。
アバター
本記事は TechHarmony Advent Calendar 2025 12/23付の記事です 。 どうも。四国の高知県に来ている寺内です。このブログを書くために、わざわざHHKBを出張に持ってきました。 さて。どこにいても、PCが変わっても、自分の慣れ親しんだ環境を使いたいものですよね。それが作業効率のみならず心地よさに大きく影響するからです。 VSCode周りやブラウザは長い時間を育ててきている設定ファイルを複数PC間で同期できるのでよいですが、OS周りの設定同期や共有は面倒なものがあります。ブラウザで環境が完結していたCloud 9は重宝する面が多々ありました。残念ながらサ終に向かっていることもあり、代替を検討するチームも多いでしょう。 当社のAWS Ambassadors 広野さんが2025年9月に投稿した以下のブログ記事では、Ubuntuが稼働するEC2のデスクトップコンソールをブラウザで操作するサーバを構築できます。 VSCode 導入済みで Web GUI アクセス可能な Amazon EC2 Ubuntu インスタンスを一発構築する [AWS CloudFormation] AWS Cloud9 の代わりとなるクラウド IDE の構築をいろいろ試しています。そのうちの1案です。 blog.usize-tech.com 2025.09.08 大変優れた記事ですが、こちらのCFnテンプレートでは、素のUbuntu稼働のEC2インスタンスを作成し、その後デスクトップ環境の構築を行います。これはEC2インスタンスを作成するタイミングの違いで、インストールされるツール・ライブラリのバージョンが異なることになります。チーム開発をしているケースで、ある程度の環境の統制を効かせたい場合、メンバー毎にバージョンの違いが生じるのは塩梅がよくありません。 そこで本記事では、このCFnテンプレートを個人利用スコープからチーム開発スコープに拡張します。広野さんのCloudFormationテンプレートを参考にしつつ、新たに開発サーバ構築ツール「vsimage」として再構成します。 vsimageツールのアーキテクチャの考え方はCloud 9 のアーキテクチャを踏襲します。つまり、チームとしてのAMIを一つ作っておき、メンバーはそのAMIからマイ環境のEC2インスタンスを起動するという使い方です。環境をビルドしAMIを作成するフェーズと、EC2インスタンス化するフェーズを分離することで、EC2作成時にデスクトップソフトウェアのインストール時間を待つ必要がなくなります。 登場人物の役割と利用方法概略 vsimageは、以下の二種類の役割の人間を想定しています。 AMI管理者 : Ubuntu OSおよび導入ツールの管理を行い、AMIをチームメンバーへ提供する責任を持つ役割です。 開発者 : AMI管理者によって提供されるAMIを用いて、自分専用のUbuntu EC2インスタンスを作成し、VSCodeを利用する役割です。 vsimageは、以下3つのCFnテンプレートからなります。 Image Builder構築テンプレート:  imagebuilder-pipeline.yaml AMI作成テンプレート:  ami-creation-execution.yaml EC2インスタンス構築テンプレート:  ec2-launch-from-ami.yaml 1と2のCFnテンプレートは、AMI管理者が使用します。3は開発者が使用します。 アーキテクチャ概要 Ubuntu ServerにGUI環境をインストールしUbuntu Desktopにします。その後、DCVやVSCodeなどの必要なツール群をインストールします。これらの一連の作業は、EC2 Image Builderを使用します。 Image Builder とは - EC2 イメージビルダー Image Builder は、安全なカスタム Amazon マシンイメージ (AMI) またはコンテナイメージを作成し、 AWS内の宛先のアカウントとリージョンで使用できるように配布するためのフルマネージドサービスです。 docs.aws.amazon.com AMI管理者は、Image Builderのコンポーネント定義とレシピ定義を行いUbuntuにインストールするソフトウェアを定義します。その設定をパイプラインとして定義します。 パイプラインを実行し、Image Builderで作成されたAMIをチームに公開します。 開発者はそのAMIを使用して、自らのVPC環境にEC2インスタンスを起動します。 ブラウザからスムーズにアクセスできるように、EC2起動と同時にRoute 53へFQDNと新規取得したElastic IPの組み合わせをAレコードで登録します。またSSL接続を行うためのオレオレサーバ証明書を内部で作り出します。 Ubuntuサーバは、安価なGravitonインスタンスタイプで動作します。そのため、AMI作成プロセスにおけるインスタンスタイプも同じくGravitonを指定しています。 AMI作成段階で作るインスタンスタイプは、t4g.large。EC2作成段階ではパラメータで指定可能ですが、デフォルトはt4g.largeです。 パスワード管理の仕組み vsimageでは、Ubuntuのrootパスワードは以下の二段階で設定します。 AMI作成段階(アーキテクチャ図でいうSTEP 2)で、  ami-creation-execution.yaml  にCloudFormationパラメータとして、AMI管理者が設定したパラメータストアキーを与えます。AMI作成中にパラメータストアからパスワード文字列を読み出し、Ubuntu ルートパスワードを設定します。生成された直後のAMIには、AMI管理者が定義した文字列がルートパスワードとなります。 EC2インスタンス作成段階(アーキテクチャ図でいうSTEP 3)では、開発者が実行する  ec2-launch-from-ami.yaml  にCloudFormationパラメータとして、開発者が設定したパラメータストアキーを与えます。EC2インスタンス作成中にパラメータストアからパスワード文字列を読み出し、Ubuntu ルートパスワードを設定します。もしパラメータストアキーが未設定であったり、パラメータストアの読み出しが失敗した場合は、AMI管理者の設定したルートパスワードのままとなります。 どちらの段階でのルートパスワード設定方法は、  /home/ubuntu/set-password-from-parameter.sh  というスクリプトがOS起動時にsystemctrl により実行されることで設定されます。 作成されるAMIの概略 作成されるAMIは以下の内容となります。 ベースとなるOSは、ubuntu-24-lts-arm64の最新版 EBSボリュームはルート領域の1つで20GBのサイズ ubuntu-desktopパッケージ一式とX windowサーバパッケージを導入 日本語パックパッケージとibus-mozcパッケージを導入 nginxパッケージを導入 certbotパッケージを導入 VSCodeパッケージを導入 Amazon管理コンポーネントのDCVサーバを導入 Amazon管理コンポーネントのCloudWatchエージェントを導入 Amazon管理コンポーネントのAWS CLIを導入 独自にAMI内部に作られるシェルスクリプトは以下3つがあります。いずれもubuntuユーザのホームディレクトリ  /home/ubuntu  に作られます。ルートパスワード設定とSSLサーバ証明症作成はsystemctlのサービスとして追加され、OS起動直後に一度だけ自動実行されます。 前述したルートパスワード設定ファイル:  set-password-from-parameter.sh SSLサーバ証明書作成スクリプト:  setup-ssl.sh SSLサーバ証明書更新スクリプト:  renew-cert.sh vsimageツール利用手順 以下では、CloudFormationテンプレートからCloudFormationスタックを作成する手順を示します。この手順に従い、パラメータを適切に設定すれば、Ubuntuサーバが完成します。 CFnテンプレートのダウンロード ダウンロードリンク vsimageは、以下3つのCFnテンプレートから成り、zip圧縮してあります。 Image Builder構築テンプレート:  imagebuilder-pipeline.yaml AMI作成テンプレート:  ami-creation-execution.yaml EC2インスタンス構築テンプレート:  ec2-launch-from-ami.yaml こちらのリンクからzipファイルをダウンロードしてください。 vsimage-cfn   前提条件 vsimageを使用する前提は以下です。 AMI管理者は、EC2インスタンスを起動後のUbuntu ルートパスワードをパラメータストアに保存しておく必要があります。このパスワードは、実質的には開発者のルートパスワードで上書きされますが、開発者によるパスワード定義がされていない場合にこのルートパスワードが有効になるように設計してあります。 開発者は、DNSルートから検索可能な正規のドメインを持ち、Route 53でホストゾーンを定義している必要があります。これは、最終的にブラウザからアクセスするためのURLとして使うことと、SSLサーバ証明書の署名にも利用します。 開発者は、UbuntuのEC2インスタンスを起動するためのVPCおよびパブリックサブネットを用意しておく必要があります。 開発者は、EC2インスタンスを起動後のUbuntu ルートパスワードをパラメータストアに保存しておく必要があります。 コードを使用する上での注意点 このサンプルコードではツール名称を「ytera-vsimage」と仮称します。ファイル名やパイプライン名などの随所で使用されているので、実際に使用されるときは  grep  などで検索して置き換えてください。 このツールが作成するリソースは、Costタグが付与するようにハードコーディングされています。  Key: Cost   Value: y.terauchi  の部分も適宜置き換えてください。 ImageBuilderの構築手順 まずImage Builder構築テンプレート  imagebuilder-pipeline.yaml  を用いて、Image Builderのパイプライン構築を行います。このスタック実行にはおおよそ5分ほどかかります。 パラメータ一覧 CloudFormationへ与えるパラメータは以下のとおりです。 PasswordParameterName AMI作成段階で指定するUbuntuルートパスワードを収納しているパラメータストアキー名を指定します。 LoggingBucket Image Builderの動作ログを保管するS3バケットを新規作成ときのバケット名を指定します。このパラメータが有効になるのは、 CreateNewBucket をtrueとしたときです。  CreateNewBucket 上記名前で新規作成するときに true を指定します。二回目以降のスタック実行の場合はS3バケットは存在しているので false を指定します。 ExistingBucketName S3バケットを新規作成しない場合に既存バケット名を指定します。新規作成する場合はパラメータ指定をしません。 コマンド例 AWS CLIで実行するときのコマンド例を以下に示します。 【一回目の実行であり、S3バケットを新規作成する場合】 aws cloudformation create-stack \ --stack-name ytera-vsimage-pipeline \ --template-body file://imagebuilder-pipeline.yaml \ --parameters \ ParameterKey=PasswordParameterName,ParameterValue=/ytera-vsimage/ubuntu-password \ ParameterKey=CreateNewBucket,ParameterValue= true \ ParameterKey=LoggingBucket,ParameterValue=ytera-vsimage-imagebuilder-logs-ap-northeast-1 \ --capabilities CAPABILITY_NAMED_IAM \ --region ap-northeast-1 【二回目以降の実行であり、既存のS3バケットを使用する場合】 aws cloudformation create-stack \ --stack-name ytera-vsimage-pipeline \ --template-body file://imagebuilder-pipeline.yaml \ --parameters \ ParameterKey=PasswordParameterName,ParameterValue=/ytera-vsimage/ubuntu-password \ ParameterKey=CreateNewBucket,ParameterValue= false \ ParameterKey=ExistingBucketName,ParameterValue=ytera-vsimage-imagebuilder-logs-ap-northeast-1 \ --capabilities CAPABILITY_NAMED_IAM \ --region ap-northeast-1 AMI作成手順 AMI作成テンプレート  ami-creation-execution.yaml  を実行し、AMI作成を行います。このスタック実行にはおおよそ40分ほどかかります。 パラメータ一覧 PipelineStackName 前工程でパイプラインを作成したスタック名を入力します。 ImageName 作成するAMIの名前を指定します。 EnableImageTests Image Builderは作成したAMIが正常に稼働するかをテストする機能があります。その自動テストを実施するかしないかを選択します。パイプラインではテスト定義をしていないため、falseを指定します。 コマンド例 aws cloudformation create-stack \ --stack-name ytera-vsimage-ami-creation \ --template-body file://ami-creation-execution.yaml \ --parameters \ ParameterKey=PipelineStackName,ParameterValue=ytera-vsimage-pipeline \ ParameterKey=ImageName,ParameterValue=ytera-vsimage-ami \ ParameterKey=EnableImageTests,ParameterValue= false \ --region ap-northeast-1 EC2インスタンスの作成手順 AMIが正常に作成できたら、EC2インスタンス構築テンプレート  ec2-launch-from-ami.yaml  を開発者として実行します。これにより個人の環境にEC2インスタンスを起動します。このスタック実行にはおおよそ10分ほどかかります。 パラメータ一覧 AmiCreationStackName 前工程でAMIを作成したスタック名を入力します。 InstanceType Ubuntuを稼働させるインスタンスタイプを指定します。Gravitonである必要があります。初期値はt4g.large。 VpcId Ubuntuを稼働させるVPC IDを指定します。 SubnetId Ubuntuを稼働させるサブネットIDを指定します。パブリックサブネットである必要あります。 AllowedSubnet Ubuntuへ接続可能なPCのCIDRを指定します。ここで指定したCIDRからUbuntuのTCP 8443ポート、443ポートが許可されます。 DomainName Ubuntuのホスト名を含むFQDNを指定します。これがブラウザからアクセスするときのURLとなります。 Route53HostZoneId FQDNで指定したドメインを定義しているRoute 53のゾーンIDを指定します。このゾーンIDに対してAレコードを追加します。 PasswordParameterName EC2インスタンスのUbuntuルートパスワードとして設定する文字列を収納しているパラメータストアキー名を指定します。 EMAIL SSLサーバ証明書に埋め込むメールアドレスを指定します。何でもかまいません。 コマンド例 aws cloudformation create-stack \ --stack-name ytera-vsimage-user1-instance \ --template-body file://ec2-launch-from-ami.yaml \ --parameters \ ParameterKey=AmiCreationStackName,ParameterValue=ytera-vsimage-ami-creation \ ParameterKey=InstanceType,ParameterValue=t4g.large \ ParameterKey=SubnetId,ParameterValue=subnet-0d29XXXXXXXXXXXXXXd \ ParameterKey=VpcId,ParameterValue=vpc-0e98dXXXXXXXXXXXXXX \ ParameterKey=AllowedSubnet,ParameterValue=2XX.2XX.XX.XX/32 \ ParameterKey=DomainName,ParameterValue=ytera-vsimage-user1-instance.example.com \ ParameterKey=Route53HostZoneId,ParameterValue=Z09XXXXXXXXXXXXXXXXXXXX \ ParameterKey=PasswordParameterName,ParameterValue=/ytera-vsimage/user1-password \ ParameterKey=EMAIL,ParameterValue=ytera@example.com \ --capabilities CAPABILITY_NAMED_IAM \ --region ap-northeast-1 Ubuntuへアクセス EC2インスタンス構築テンプレート  ec2-launch-from-ami.yaml  が正常終了すると、EC2へアクセスするURLが指定したFQDNを下に出力されます。スタックのOutputページを見ていただき、そのURLにDCVでアクセスしてください。 DCVの認証は、Ubuntuの一般ユーザ(ubuntu)とCFnテンプレートで指定したパラメータストアのパスワードでログイン可能です。その後、Ubuntuのログイン画面が出ますが、同じIDとパスワードでログインします。 本ツールのユースケースと今後の課題 本ツールでは、開発環境となるAMI作成と、実際のインスタンス化の工程を分離しているのが特徴です。常に開発環境のバージョンをセキュアに最新に保ち開発者に提供することが比較的簡単にできます。 毎晩AMI作成を自動で実行するようにスケジュールを組んでおき、開発者は毎朝EC2を作成する運用とすることで実現可能です。EC2作成のスタックでは、AMI作成スタックが出力するAMI IDを参照しているので、開発者はどのAMIが最新であるかを意識する必要がありません。 ただ開発者の個人設定などのホームディレクトリを、インスタンス外に自動退避し、EC2作成時に自動で戻す仕組みがまだできていませんが。 ライトなユースケースでは、Ubuntuの開発者のホームディレクトリをS3マウントしておくだけでもよいかもしれません。  Mountpoint for Amazon S3 はメチャ便利だよ Mountpoint for Amazon S3 はS3オブジェクトストレージを、ローカルディスクにマウントしブロックストレージのように扱うことのできる超便利な機能です。その使い方をAmazon Linux 2023 をベースに解説します。 blog.usize-tech.com 2025.08.24 最後に。本記事は、 広野さんの秀逸なCloudFormationがあったからこそ実現できました 。ありがとうございました。
アバター
本記事は TechHarmony Advent Calendar 2025 12/23付の記事です 。 こんにちは。SCSK渡辺(大)です。 肩こりが酷すぎたのでYouTubeで首回りのストレッチ動画を参考にやってみたらスッキリしました。 首剥がしとストレートネック治しの動画はお勧めです。 サンプルのナレッジ 以下のようなナレッジを作ることが出来ました。 背景 楽してナレッジを作りたかったのです。 AIの進化のおかげで重たい腰が上がった ※あくまで一個人の見解です。 恐らく1年前だったら1つのケースをナレッジ化するのに1分掛かるか、トークンが多すぎて1度の指示で全てのケースをナレッジ化することは出来なかったかと思います。 それが今では、 スクリプトの作成から始め、スクリプトの実行、ケースをカテゴリ別に仕分け、すべてのケースのナレッジ化までを丸っとAIにお任せすることが出来ます。 ※Kiroに実行許可をしていない場合には、スクリプトの実行など必要なタイミングでは人間の介在が必要です 最早、AIが「AWS Support のケースをナレッジ化するために進化してきました!」と言っているようなものです。 なので有難く使わせてもらいました。 思い立ったが吉日 ということで早速取り掛かってみようと、AWSマネジメントコンソールの AWS Support の画面を眺めていたところ、約2年前のケースまでしか残っていませんでした。 調べてみたところ、AWS Supportのケース履歴は、AWSマネジメントコンソール上では直近24か月間(2年間)までしか残っていません。[1] また、Boto3のリファレンス[2]では直近12か月(1年間)までとなっていますが、実際にはAWSマネジメントコンソールと同様に、直近24か月間(2年間)まで取得できます。(実際に試しました) つまり、 ナレッジ化したいと感じたらすぐに取り掛かったほうが良いということです。 理由は、直近24か月を超過したケースは見れなくなってしまうためです。 概要 AWS Support でクローズ済のケースをKiroにナレッジ化してもらいました。 大まかな流れ AWS Support ケース情報の取得(リクエスト) AWS Support ケース情報の取得(レスポンス) カテゴリ分類した後、カテゴリ単位でナレッジを作成 もう少し細かい流れ Kiroに実行許可をしていない場合には、スクリプトの実行など必要なタイミングでは人間の介在が必要ですが、殆どKiroにお任せできます。 ユーザーがKiroに指示文(後述)を伝える KiroがPython スクリプトを実行してケース情報を取得 Kiroが進捗管理表を確認 存在する → 続きから処理(5 へ) 存在しない → 新規作成 Kiroが未分類のケースを読み込み、進捗管理表に記録 Kiroがカテゴリ単位で ナレッジ を作成し、進捗管理表を更新 Kiroが未処理のケースがあるか確認 ある → 3 へ戻る ない → 完了 Kiroのセッションが中断した場合 → 新しいセッションで 2 へ戻る 必要なもの ローカル Kiro(他のエージェント型IDEでも良いと思いますが私は試してません) Pythonスクリプト(AWS Support ケース情報を取得する処理) boto3(Pythonスクリプトで使うため必要) Python 3.10 以上(boto3を使うために必要[3]) AWS 認証情報(boto3を使うために必要) AWS CLI 2.32以上(aws loginでAWS認証する場合には必要) AWS AWS Support プラン(Developer/Business/Enterprise) AWS Support ケース(解決済み) IAM権限(以下) { "Version": "2012-10-17", "Statement": [   {     "Effect": "Allow",     "Action": [       "sts:GetCallerIdentity",       "support:DescribeCases",       "support:DescribeCommunications"     ],     "Resource": "*"   } ] } Pythonスクリプト(AWS Support ケース情報を取得する処理) 畳んでいます。 Pythonスクリプト #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ AWS Support ケースダウンローダー サポートケースをダウンロードし、 各ケースをテキストファイルとして保存する。 """ import json import logging import os import sys from datetime import datetime from pathlib import Path import boto3 from botocore.exceptions import NoCredentialsError, ClientError, BotoCoreError OUTPUT_DIR = 'support_cases' EXCLUDED_KEYWORDS = [ "[除外したいケース名に含むキーワード1]", "[除外したいケース名に含むキーワード2]" ] def setup_logging() -> logging.Logger: """ロギング設定""" os.makedirs(OUTPUT_DIR, exist_ok=True) timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') log_file = f"{OUTPUT_DIR}/download_{timestamp}.log" logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler(log_file, encoding='utf-8'), logging.StreamHandler(sys.stdout) ] ) return logging.getLogger(__name__) def get_aws_credentials(): """認証情報を取得""" # ~/.aws/credentials があればboto3デフォルトに任せる creds_file = Path.home() / '.aws' / 'credentials' if creds_file.exists(): return 'default' # aws login キャッシュから取得 cache_dir = Path.home() / '.aws' / 'login' / 'cache' if not cache_dir.exists(): return None cache_files = list(cache_dir.glob('*.json')) if not cache_files: return None latest_file = max(cache_files, key=lambda f: f.stat().st_mtime) with open(latest_file, 'r', encoding='utf-8') as f: data = json.load(f) token = data.get('accessToken', {}) return { 'aws_access_key_id': token.get('accessKeyId'), 'aws_secret_access_key': token.get('secretAccessKey'), 'aws_session_token': token.get('sessionToken'), } def create_session(logger): """boto3 セッション作成""" creds = get_aws_credentials() if creds == 'default': logger.info("Using ~/.aws/credentials") return boto3.Session(region_name='us-east-1') if not creds or not creds.get('aws_access_key_id'): raise NoCredentialsError() logger.info("Using aws login cache") return boto3.Session( aws_access_key_id=creds['aws_access_key_id'], aws_secret_access_key=creds['aws_secret_access_key'], aws_session_token=creds['aws_session_token'], region_name='us-east-1' ) def validate_credentials(session, logger): """認証情報の有効性をテスト""" try: sts = session.client('sts') identity = sts.get_caller_identity() logger.info(f"認証成功: {identity.get('Arn', 'Unknown ARN')}") return True except ClientError as e: error_code = e.response['Error']['Code'] if error_code in ['InvalidUserID.NotFound', 'AccessDenied', 'TokenRefreshRequired', 'ExpiredToken', 'ExpiredTokenException']: logger.error("AWS認証情報が無効または期限切れです。認証情報を確認してください。") else: logger.error(f"AWS API エラー: {error_code} - {e.response['Error']['Message']}") return False except BotoCoreError as e: logger.error(f"AWS接続エラー: {e}") logger.error("ネットワーク接続またはAWS認証情報を確認してください。") return False except Exception as e: logger.error(f"認証テスト中の予期しないエラー: {e}") import traceback logger.error(traceback.format_exc()) return False def download_cases(session, logger): """全サポートケースをダウンロードして保存""" try: client = session.client('support', region_name='us-east-1') except Exception as e: logger.error(f"Supportクライアント作成エラー: {e}") raise logger.info("Fetching cases...") cases = [] next_token = None try: while True: params = {'maxResults': 100, 'includeResolvedCases': True} if next_token: params['nextToken'] = next_token response = client.describe_cases(**params) cases.extend(response.get('cases', [])) next_token = response.get('nextToken') if not next_token: break except ClientError as e: error_code = e.response['Error']['Code'] if error_code == 'SubscriptionRequiredException': logger.error("AWS Supportプランが必要です。Basic以上のサポートプランに加入してください。") return 0 else: logger.error(f"ケース取得エラー: {error_code} - {e.response['Error']['Message']}") return 0 except Exception as e: logger.error(f"ケース取得中の予期しないエラー: {e}") return 0 logger.info(f"Found {len(cases)} cases") saved_count = 0 for idx, case in enumerate(cases, 1): case_id = case['caseId'] subject = case.get('subject', '') logger.info(f"[{idx}/{len(cases)}] Processing: {case_id}") # 除外キーワードのチェック if any(kw in subject for kw in EXCLUDED_KEYWORDS): logger.info(f" -> Excluded (keyword): {subject[:50]}") continue # 進行中のケース(クローズしていないケース)を除外 status = case.get('status', '').lower() if status != 'resolved': logger.info(f" -> Excluded (not resolved): {subject[:50]} (status: {status})") continue try: comms = [] comm_token = None while True: params = {'caseId': case_id} if comm_token: params['nextToken'] = comm_token resp = client.describe_communications(**params) comms.extend(resp.get('communications', [])) comm_token = resp.get('nextToken') if not comm_token: break filename = f"{OUTPUT_DIR}/case_{case_id}.txt" with open(filename, 'w', encoding='utf-8') as f: f.write(f"ケースID: {case_id}\n") f.write(f"件名: {subject}\n") f.write(f"ステータス: {case.get('status', '')}\n") f.write(f"作成日時: {case.get('timeCreated', '')}\n") f.write(f"サービス: {case.get('serviceCode', '')}\n") f.write(f"カテゴリ: {case.get('categoryCode', '')}\n") f.write(f"重要度: {case.get('severityCode', '')}\n") f.write("=" * 60 + "\n\n") for i, comm in enumerate(comms, 1): f.write(f"--- メッセージ {i} ---\n") f.write(f"送信者: {comm.get('submittedBy', '')}\n") f.write(f"日時: {comm.get('timeCreated', '')}\n") f.write(f"内容:\n{comm.get('body', '')}\n\n") saved_count += 1 logger.info(f" -> Saved: {filename}") except Exception as e: logger.error(f" -> Error: {e}") logger.info(f"Completed: {saved_count} cases saved to {OUTPUT_DIR}/") return saved_count def main(): logger = setup_logging() logger.info("Starting download...") try: session = create_session(logger) # 認証情報の有効性をテスト if not validate_credentials(session, logger): return count = download_cases(session, logger) logger.info(f"Done: {count} cases saved to {OUTPUT_DIR}/") except NoCredentialsError: logger.error("AWS認証情報が見つかりません。認証情報を設定してください。") except Exception as e: logger.error(f"予期しないエラー: {e}") logger.error("詳細なエラー情報:") import traceback logger.error(traceback.format_exc()) if __name__ == "__main__": main() Kiroへの指示文 畳んでいます。 指示文 # AWS Support ケースダウンロード & ナレッジ 化 指示書 ## 重要な制約事項(必ず遵守) ### 禁止事項 - **追加のスクリプト(Python、シェルスクリプト等)を新規作成しないこと** - 既存のスクリプト `aws_support_knowledge_generator_cli.py` を勝手に修正しないこと - 指示書に記載されていない処理を勝手に追加しないこと - 出力ディレクトリ以外の場所にファイルを作成しないこと - **Kiro の SPEC 機能を使用しないこと**(この指示書に従って直接処理を行うこと) ### 許可される操作 - `aws_support_knowledge_generator_cli.py` の実行(ケースダウンロード) - `support_cases_knowledge/` ディレクトリへの ナレッジ Markdown ファイルの作成のみ - 既存ファイルの読み取り --- ## 1. ケースダウンロード(スクリプト実行) ### 実行コマンド ```bash python aws_support_knowledge_generator_cli.py ``` ### 動作内容 - 全サポートケースを `support_cases/` にテキストファイルとして保存 - ログは `support_cases/download_YYYYMMDD_HHMMSS.log` に出力 ### 出力形式 各ケースファイル (`case_{ID}.txt`) には以下を含む: - ケース ID、件名、ステータス、作成日時 - サービス、カテゴリ、重要度 - 全メッセージ履歴(送信者、日時、内容) --- ## 2. ナレッジ 化(Kiro による処理) ### 前提条件 - 事前に `python aws_support_knowledge_generator_cli.py` を実行してケースをダウンロード済みであること - `support_cases/` ディレクトリにケースファイルが存在すること ### 処理手順(重要:セッション中断に備えた段階的処理) **基本方針**: ファイル読み込み → 即座に進捗管理表に記載 → カテゴリ単位で ナレッジ 生成 → 次のファイル読み込み #### ステップ 1: 初期確認 1. `support_cases_knowledge/progress_management.md`(進捗管理表)が存在するか確認する 2. 存在する場合は進捗管理表を読み込み、「分類済み」列と「ナレッジ 生成済み」列を確認する #### ステップ 2: ファイル読み込みと即時分類(繰り返し) 1. `support_cases/` から**未分類のケースファイル**を可能な限り読み込む 2. **読み込んだら即座に**進捗管理表に追記する(「分類済み」に `✓`、「ナレッジ 生成済み」は空欄) 3. この時点でセッションが中断しても、次回は進捗管理表を見て続きから処理できる #### ステップ 3: カテゴリ単位での ナレッジ 生成(繰り返し) 1. 進捗管理表から「ナレッジ 生成済み」が空欄のケースを**カテゴリ単位で**抽出する 2. そのカテゴリの ナレッジ ファイルを生成(または追記)する 3. ナレッジ 生成完了後、該当ケースの「ナレッジ 生成済み」列に `✓` を付ける 4. **1 つのカテゴリの ナレッジ 生成が完了してから**、次のカテゴリに進む #### ステップ 4: 未読み込みファイルがあれば繰り返し - ステップ 2〜3 を、全ケースファイルの処理が完了するまで繰り返す ### 進捗管理表(progress_management.md) セッションをまたいでも処理状況を正確に把握できるよう、進捗管理表を管理する。 #### 進捗管理表の形式 ```markdown # 進捗管理表 最終更新: YYYY-MM-DD HH:MM:SS ## 処理状況サマリー - 総ケース数: XX 件 - 分類済み: XX 件 - ナレッジ 生成済み: XX 件 ## 分類済みケース一覧 | ケースファイル | カテゴリ | 件名 | 分類済み | ナレッジ 生成済み | | -------------- | ----------------- | ---------------- | -------- | ------------ | | case_xxx.txt | コスト・請求 | 請求に関する質問 | ✓ | ✓ | | case_yyy.txt | セキュリティ・IAM | IAM 権限の設定 | ✓ | | | case_zzz.txt | ネットワーク | VPC 設定について | ✓ | | ``` #### 進捗管理表の運用ルール(必須) 1. **即時記載の原則**: ケースファイルを読み込んだら、**その時点で即座に**進捗管理表に追記すること(全ファイル読み込み後ではない) 2. **2 段階チェック**: - 「分類済み」列: ファイルを読み込んでカテゴリを判定したら `✓` - 「ナレッジ 生成済み」列: そのケースを含む ナレッジ を生成したら `✓` 3. **カテゴリ単位処理**: 1 つのカテゴリの ナレッジ 生成を完了してから、次のカテゴリのファイル読み込みに進むこと 4. **セッション再開時**: まず進捗管理表を確認し、「分類済み」が空欄のケースのみ読み込み、「ナレッジ 生成済み」が空欄のカテゴリから処理を再開すること 5. **サマリー更新**: 進捗管理表を更新するたびに、処理状況サマリーも更新すること ### 応答言語 **Kiro からの応答は日本語で返すこと** --- ## 3. カテゴリ分類ルール 以下の 8 カテゴリに分類すること。複数カテゴリに該当する場合は、最も関連性の高い 1 つを選択する。 | カテゴリ名 | 対象サービス・キーワード | | --------------------------- | ----------------------------------------------------------------------------- | | 1. アカウント・サポート | アカウント設定、Organizations、サポートプラン、上限緩和申請、Service Quotas | | 2. セキュリティ・IAM | IAM、認証、暗号化、セキュリティグループ、WAF、KMS、Secrets Manager、GuardDuty | | 3. ネットワーク | VPC、Route 53、CloudFront、Direct Connect、ELB、ALB、NLB、Transit Gateway | | 4. コンピューティング | EC2、Lambda、ECS、EKS、Batch、Fargate、Auto Scaling | | 5. ストレージ・データベース | S3、EBS、RDS、DynamoDB、ElastiCache、Aurora、Redshift、EFS | | 6. 開発・CICD | CodePipeline、CodeBuild、CodeDeploy、CloudFormation、CDK、CodeCommit | | 7. 監視・運用 | CloudWatch、CloudTrail、Systems Manager、Config、EventBridge、X-Ray | | 8. コスト・請求 | 料金、請求、Cost Explorer、Savings Plans、Reserved Instance、Billing、Budget | --- ## 4. ナレッジ ファイル生成ルール ### 出力先 - `support_cases_knowledge/` ディレクトリに出力すること(ディレクトリが存在しない場合は作成する) - 他のディレクトリには出力しないこと ### ファイル命名規則 - `ナレッジ_カテゴリ名.md` 形式(例: `ナレッジ_コスト・請求.md`) ### 必須構成要素(すべて必須) > **⚠️ 重要: 目次は必ず作成すること。目次がない ナレッジ ファイルは不完全とみなす。** #### 4.1 目次(ファイル冒頭に必須) **すべての ナレッジ ファイルの冒頭には必ず目次を設けること。** 目次がないファイルは作成完了とみなさない。 ```markdown # ナレッジ: カテゴリ名 最終更新: YYYY-MM-DD ## 目次 - [Q1: 質問タイトル](#q1-質問タイトル) - [Q2: 質問タイトル](#q2-質問タイトル) ... --- (以下、各 ナレッジ の本文) ``` #### 4.2 各 ナレッジ の構成 ```markdown ## Q1: 質問タイトル ### 質問 (背景・状況を含めて、ユーザーからの質問内容を具体的に記載します。どのような状況で何を知りたいのか明確にします) ### 回答 (AWS サポートからの回答を詳細に記載します。手順がある場合はステップバイステップで記載します) ### 関連リンク - [AWS 公式ドキュメント](https://docs.aws.amazon.com/...) ### 元ケース - ファイル: `case_xxx.txt` ``` ### 記載ルール #### 文体 - **「です」「ます」調で統一**(質問、回答、説明文すべて) #### 自己完結性(最重要) - **ナレッジ 単体で問題と解決策が完全に理解できること** - 元ケースを参照しなくても実用的な情報として成立させる - 質問には背景・状況を含める(なぜその質問が発生したか) - 回答は要約ではなく、実際に役立つ詳細さで記載 - 手順がある場合は番号付きリストでステップバイステップで記載 - AWS CLI コマンド、設定値、パラメータは省略せず完全な形で記載 #### 汎用性(重要) - **特定環境に依存しない、誰でも使える ナレッジ にすること** - 以下の情報は汎用的な表現に置き換える: | 置換対象 | 置換後の表現 | | ---------------------- | --------------------------------- | | アカウント ID | `your-account-id` | | ARN | `arn:aws:service:::your-resource` | | バケット名・リソース名 | `your-bucket-name` 等 | | メールアドレス | `your-email@example.com` | | IP アドレス | `xxx.xxx.xxx.xxx` | | 組織 ID | `o-xxxxxxxxxx` | #### 禁止事項 - 「〜については元ケースを参照してください」という記載 - 具体的な値やコマンドを省略した曖昧な説明 - 元のケース内容に勝手な解釈を加えること --- ## 5. エラー対処 | エラー種別 | 対処方法 | | ---------- | ------------------------------------------------------------ | | 認証エラー | AWS 認証情報が不足しています。適切な認証設定を行ってください | | 権限エラー | Business/Enterprise Support プランが必要 | 学んだこと 今回の学びで大きかったことは、Kiroの利用においては 要約機能[4]が動くことを前提にした指示文にすべき だと感じました。 クレジット垂れ流し事件を起こさない方法 2025年12月12日にAWS IAM Identity CenterのユーザーでもClaude Opus 4.5が使えるようになった[5]ので、良い機会なのでClaude Opus 4.5のみ使用するように設定して指示文書を渡してみたのですが、なんとケース情報ファイルの読み込みだけでコンテキストを食い潰し、いざナレッジを作ろうとなった時にコンテキストの上限(80%)に達してしまいました。 それだけならまだ良かったのですが、要約機能が動いた後に再度ケース情報ファイルの読み込みが始まってしまい、またコンテキストの上限に達してしまい要約機能が動いて・・・という負のループに陥ってしまい、クレジットが垂れ流し状態になってしまいました。 上記の対応策として進捗管理表を作りました。 進捗管理表などを作成して随時更新するなどして要約機能が動いたとしても次のセッションで進捗が引き継がれるようにするべきであると、既に様々なところで言われていることですが今回とても痛感しました。 一方で、仕様書や設計書も作る必要があるような場合にはSpecs機能を使ってタスク管理しながら進めるほうが良いと思います。 Claude Opus 4.5 を利用した時のクレジット消費量が凄まじい 上記に関連してお伝えすると、Claude Opus 4.5 を利用した時のクレジット消費量が凄まじいです。 当記事に載せた指示文で実行した場合、完了するまでに約40クレジット消費しました。 約40ケースがナレッジ化の対象だったので、偶然かもしれませんが1クレジット/ケースでした。 Kiroを使ったことがある人は以下の画像を見ると震えるかもしれません。 ファイル名には「/」を含めないように指示するべき ファイル名に「/」を含めるように指示をしてしまうと、「/」より前がディレクトリで後ろがファイル名として判断されてしまいます。 対応策の具体例は、「開発・CI/CD.md」は避けて「開発・CICD.md」で指示すべきです。  そうしないと以下の画像のようになってしまいます。 まとめ 業務におけるナレッジ作成は大変なので、AWS Support のケースだけでも楽にナレッジ化できそうであることが分かって良かったです。 後続の運用を考えた時には最新化や棚卸も必要になると思いますが、再度 AWS Support に問い合わせするようなことはしなくても、MCPサーバーを使って最新の情報を確認できるようにしてあげれば、それらの作業もAIで楽に出来そうですね。 私が実際の業務で使うかどうかは別問題ですが、当記事がどなたかの役に立ちましたら幸いです。 Kiro に興味を持った方は、ぜひ  Kiro 公式サイト をチェックしてみてください。 参考情報 [1] AWS プレミアムサポートのよくある質問 –抜粋——————————————————- ケース履歴の保存期間はどれほどですか? ケース履歴情報は、作成後 24 か月間ご利用いただけます。 ————————————————————– [2] describe_cases – Boto3 1.42.9 documentation –抜粋(日本語訳)—————————————— ケースデータは作成後12か月間利用可能です。12か月以上前に作成されたケースの場合、リクエストがエラーを返す可能性があります。 ————————————————————– [3] Quickstart – Boto3 1.42.9 documentation –抜粋(日本語訳)—————————————— Pythonのインストールまたはアップデート Boto3をインストールする前に、Python 3.10以降を使っていることを確認してください。  ————————————————————– [4] Summarization – IDE – Docs – Kiro –抜粋(日本語訳)—————————————— 要約 すべての言語モデルには「コンテキストウィンドウ」があり、これはモデルが一度に処理できる最大テキスト量です。コンテキストウィンドウの長さはモデルによって異なります。 Kiroと会話すると、その会話の過去のすべてのメッセージをメモリーとしてモデルに送信し、モデルが最新の応答を生成する際にそれらを考慮できるようにします。会話が長くなると、モデルのコンテキストウィンドウの制限に近づき始めます。この時、Kiroは会話内のすべてのメッセージを自動的に要約し、コンテキストの長さを制限以下に戻します。 チャットパネルのコンテキスト使用メーターを使って、モデルのコンテキスト制限のどのくらいの割合が使われているかを把握できます。使用率がモデルの上限の80%に達すると、Kiroは自動的に会話をまとめます。 ————————————————————– [5] Claude Opus 4.5 support for AWS IAM Identity Center users – Kiro –抜粋(日本語訳)—————————————— AWS IAM Identity Centerユーザー向けのClaude Opus 4.5サポート us-east-1 および eu-central-1 リージョンの両方で、AWS IAM Identity Centerユーザー向けにClaude Opus 4.5のサポートを追加しました。Claude Opus 4.5は Kiro IDE と Kiro CLI の両方で利用可能です。 ————————————————————–
アバター
  本記事は TechHarmony Advent Calendar 2025 12/22付の記事です 。 こんにちは、稲葉です。 アドベントカレンダーの機会で、普段触っていないコンテナに触れてみようと思いました。 本記事ではコンテナでWordPressサイトを作成し、Amazon ECSにデプロイするところまで試してみようと思います。 構成 本記事で試す構成です。 検証用にローカルPCのDockerでWordPressサイトを構築します。 その後、本番用にECSでWordPressを公開します。 ローカルPCにWordPressサイトを構築する まずはdocker composeでWordPress環境を作成してみました。 下記のような構成で作成しました。 . ├── docker-compose.yml ├── .env ├── nginx │ ├── default.conf │ └── nginx.conf └── php-fpm ├── Dockerfile └── php.ini ファイル名 内容 ./docker-compose.yml 複数コンテナをまとめて管理するためのdocker compose用設定ファイル .env docker-compose.yml用の環境変数を記載するファイル (コード例は本記事の最後) ./nginx/default.conf nginxのサーバー設定用ファイル、php-fpm コンテナへ転送する設定などを記載 (コードは本記事の最後) ./nginx/nginx.conf nginxの基本設定ファイル(コードは本記事の最後) ./php-fpm/Dockerfile WordPressとphp-fpmの環境を作るためのDockerファイル ※nginx上でWordPressを公開する場合、WordPressはphp-fpmと同時に使用する必要がある (コードは本記事の最後) ./php-fpm/php.ini phpの設定ファイル(コードは本記事の最後) docker-compose.yml 下記設定docker-compose.ymlファイルで、ローカルPCのWordPressサイトを構築します。 services: nginx: image:nginx:alpine ports: - "8080:80" volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf - ./nginx/default.conf:/etc/nginx/conf.d/default.conf - wordpress_data:/var/www/html depends_on: - php-fpm networks: - wordpress-network php-fpm: build: context:./php-fpm dockerfile:Dockerfile volumes: - wordpress_data:/var/www/html environment: WORDPRESS_DB_HOST: ${WORDPRESS_DB_HOST} WORDPRESS_DB_USER: ${WORDPRESS_DB_USER} WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD} WORDPRESS_DB_NAME: ${WORDPRESS_DB_NAME} depends_on: - mysql networks: - wordpress-network mysql: image:mysql:8.0 environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE} MYSQL_USER: ${MYSQL_USER} MYSQL_PASSWORD: ${MYSQL_PASSWORD} volumes: - mysql_data:/var/lib/mysql networks: - wordpress-network volumes: wordpress_data: mysql_data: networks: wordpress-network: driver:bridge このdocker-compose.ymlでは3つのコンテナを立てる設定が記載されています。 nginx php-fpm mysql それぞれのコンテナの設定について簡単に記載します。 nginxコンテナ image:nginx:alpineで、nginxのコンテナはnginx:alpineというイメージを元にコンテナを作成する設定をしています。 ports: “8080:80″で、ローカルホストの8080番ポートにアクセスした際にコンテナの80番ポートに転送する設定をしています。 volumes: ./nginx/nginx.conf:/etc/nginx/nginx.confで、ローカルPCの./nginx/nginx.confとコンテナ環境の/etc/nginx/nginx.confを同期しています。 volumes: ./nginx/default.conf:/etc/nginx/conf.d/default.confでも同様です。 volumes: wordpress_data:/var/www/htmlでは、wordpress_data名前付きボリュームでコンテナ内の/var/www/html にマウントする設定をしています。 名前付きボリュームとは、ローカルPCのDockerで名前を付けて管理するボリュームになります。ローカルPC内の他のDockerコンテナからもマウントして使用可能です。 depends_on: php-fpmで、php-fpmのコンテナを作成した後にnginxコンテナを作成する設定をしています。 networks: wordpress-networkで、wordpress-networkというDockerネットワークにnginxコンテナを属させる設定を行っています。 Dockerネットワークに属すことで、属しているコンテナ間でサービス名を使って名前解決可能になります。 php-fpmコンテナ build: context:./php-fpmで、./php-fpmディレクトリをビルドコンテキストとして使用する設定をしています。 build: dockerfile:Dockerfileで、コンテナを立てるときに使用するDockerfileを指定しています。 volumesは、nginxと同様でコンテナ内の/var/www/html に名前付きボリュームのwordpress_dataをマウントしています。 この設定によって、php-fpmコンテナとnginxコンテナの/var/www/htmlは同期されます。 environment: WORDPRESS_DB_HOST:${WORDPRESS_DB_HOST}で、環境変数WORDPRESS_DB_HOSTの値に.envファイルのWORDPRESS_DB_HOSTで指定している値を使用する設定をしています。 他も同様になります。 mysqlコンテナ volumes: mysql_data:/var/lib/mysqlで、このデータベースのデータをmysql_dataという名前付きボリュームで管理することで永続化しています。 他の設定は、他のコンテナのところで説明しているため省略します。 ローカルPCのWordpressサイトに接続する コードができたら下記コマンドで、nginxとphp-fpm、mysqlの3つのコンテナを立てて、ローカルPCのWordPressサイトを構築できます。 docker compose up -d http://localhost:8080でローカルサーバーにアクセスすると、WordPressの初期設定画面が開きます。 まずは言語設定が聞かれるので、日本語を選択します。 次にデータベースの接続設定画面になりますが、こちらは.envに書いてある下記内容で入力します。 項目名 値 データベース名 wordpress ユーザー名 wordpress パスワード wordpress_password データベースホスト mysql テーブル接頭辞 wp_ そのまま初期設定とテスト記事を書くと、このように記事を表示できました。 これにてローカルPCのWordPress環境構築は完了です。 AWS環境にWordPressサイトを構築する それでは、AWS環境にWordPressサイトを構築していきます。 ECRリポジトリを作成する まずはECSで実行するためのコンテナイメージファイルを配置するためのECRリポジトリを作成します。 AWSの環境では、MySQLデータベースのところはRDSが担当するので、mysqlコンテナは立てません。 下記のシェルスクリプトを作成し、AWS CLIでECRリポジトリを作成しました。 ※下記シェルスクリプトを実行する前に、aws loginなどでAWSの認証を通してください。 . ├── docker-compose.yml ├── .env ├── nginx ├── php-fpm └── create-ecr.sh <- new #!/bin/bash # 設定 AWS_REGION="ap-northeast-1" PROJECT_NAME="wordpress" echo "=== ECRリポジトリを作成 ===" # Nginx用ECRリポジトリを作成 echo "Nginx用ECRリポジトリを作成中..." aws ecr create-repository \ --repository-name ${PROJECT_NAME}-nginx \ --region ${AWS_REGION} # PHP用ECRリポジトリを作成 echo "PHP用ECRリポジトリを作成中..." aws ecr create-repository \ --repository-name ${PROJECT_NAME}-php \ --region ${AWS_REGION} # アカウントIDを取得 ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) echo "=== ECRリポジトリ作成完了 ===" echo "Nginx ECR URL: ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${PROJECT_NAME}-nginx" echo "PHP ECR URL: ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${PROJECT_NAME}-php" echo "" echo "次に ./image-push.sh を実行してイメージをプッシュしてください" ECRにpushするイメージを作成する ECRにプッシュするために、nginx用とphp-fpm(とwordpress)用のイメージを作成します。 . ├── docker-compose.yml ├── .env ├── nginx ├── php-fpm ├── create-ecr.sh └── aws-ecs <- new ├── Dockerfile.nginx <- new └── Dockerfile.php <- new Dockerfile.nginx FROM nginx:alpine # 必要なパッケージをインストール(EFS用) RUN apk add --no-cache nfs-utils # Nginxの設定ファイルをコピー COPY nginx/nginx.conf /etc/nginx/nginx.conf COPY nginx/default.conf /etc/nginx/conf.d/default.conf # WordPressファイル用のディレクトリを作成 RUN mkdir -p /var/www/html # EFS用のマウントポイントを作成 VOLUME ["/var/www/html"] # ヘルスチェック用の設定を追加 RUN echo 'server {' > /etc/nginx/conf.d/health.conf && \ echo ' listen 80;' >> /etc/nginx/conf.d/health.conf && \ echo ' server_name _;' >> /etc/nginx/conf.d/health.conf && \ echo ' location /health {' >> /etc/nginx/conf.d/health.conf && \ echo ' access_log off;' >> /etc/nginx/conf.d/health.conf && \ echo ' return 200 "healthy\\n";' >> /etc/nginx/conf.d/health.conf && \ echo ' add_header Content-Type text/plain;' >> /etc/nginx/conf.d/health.conf && \ echo ' }' >> /etc/nginx/conf.d/health.conf && \ echo '}' >> /etc/nginx/conf.d/health.conf EXPOSE 80 # Nginxをフォアグラウンドで実行 CMD ["nginx", "-g", "daemon off;"] Dockerfile.php FROM php:8.2-fpm # 必要なパッケージをインストール RUN apt-get update && apt-get install -y \ libfreetype6-dev \ libjpeg62-turbo-dev \ libpng-dev \ libzip-dev \ unzip \ nfs-common \ gettext-base \ && docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install -j$(nproc) gd \ && docker-php-ext-install pdo_mysql \ && docker-php-ext-install mysqli \ && docker-php-ext-install zip \ && docker-php-ext-install opcache \ && rm -rf /var/lib/apt/lists/* # WordPressをダウンロードしてインストール RUN curl -O https://wordpress.org/latest.tar.gz \ && tar xzf latest.tar.gz \ && mkdir -p /var/www/html \ && mkdir -p /tmp/wordpress \ && cp -R wordpress/* /tmp/wordpress/ \ && cp -R wordpress/* /var/www/html/ \ && rm -rf wordpress latest.tar.gz \ && chown -R www-data:www-data /var/www/html # wp-config.phpのテンプレートは不要(起動時に作成) # PHP設定をコピー COPY php-fpm/php.ini /usr/local/etc/php/ # 起動スクリプトを作成 RUN echo '#!/bin/bash' > /start.sh && \ echo 'set -e' >> /start.sh && \ echo 'echo "Starting WordPress PHP-FPM container..."' >> /start.sh && \ echo 'echo "DB Host: $WORDPRESS_DB_HOST"' >> /start.sh && \ echo 'echo "DB Name: $WORDPRESS_DB_NAME"' >> /start.sh && \ echo 'echo "DB User: $WORDPRESS_DB_USER"' >> /start.sh && \ echo '' >> /start.sh && \ echo '# WordPressファイルがEFSにない場合はコピー' >> /start.sh && \ echo 'if [ ! -f /var/www/html/wp-config-sample.php ]; then' >> /start.sh && \ echo ' echo "Copying WordPress files to EFS..."' >> /start.sh && \ echo ' cp -R /tmp/wordpress/* /var/www/html/' >> /start.sh && \ echo 'fi' >> /start.sh && \ echo '' >> /start.sh && \ echo '# wp-config.phpを作成' >> /start.sh && \ echo 'cp /var/www/html/wp-config-sample.php /var/www/html/wp-config.php' >> /start.sh && \ echo 'sed -i "s/database_name_here/$WORDPRESS_DB_NAME/" /var/www/html/wp-config.php' >> /start.sh && \ echo 'sed -i "s/username_here/$WORDPRESS_DB_USER/" /var/www/html/wp-config.php' >> /start.sh && \ echo 'sed -i "s/password_here/$WORDPRESS_DB_PASSWORD/" /var/www/html/wp-config.php' >> /start.sh && \ echo 'sed -i "s/localhost/$WORDPRESS_DB_HOST/" /var/www/html/wp-config.php' >> /start.sh && \ echo '' >> /start.sh && \ echo '# ファイルの権限を設定' >> /start.sh && \ echo 'chown -R www-data:www-data /var/www/html' >> /start.sh && \ echo '' >> /start.sh && \ echo 'echo "Starting PHP-FPM..."' >> /start.sh && \ echo 'exec php-fpm' >> /start.sh && \ chmod +x /start.sh WORKDIR /var/www/html EXPOSE 9000 CMD ["/start.sh"] 作成したイメージをECRにpushする 次は、作成したDockerfileでイメージを作成し、ECRリポジトリにプッシュします。 下記のシェルスクリプトを作成し、AWS CLIでプッシュしました。 ※下記シェルスクリプトを実行する前に、aws loginなどでAWSの認証を通してください。 . ├── docker-compose.yml ├── .env ├── nginx ├── php-fpm ├── create-ecr.sh ├── image-push.sh <- new └── aws-ecs #!/bin/bash # 設定 AWS_REGION="ap-northeast-1" ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) ECR_REPO_BASE="${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com" NGINX_REPO="${ECR_REPO_BASE}/wordpress-nginx" PHP_REPO="${ECR_REPO_BASE}/wordpress-php" echo "=== DockerイメージをECRにプッシュ ===" # ECRにログイン echo "ECRにログイン中..." aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${ECR_REPO_BASE} # Nginxイメージをビルド・プッシュ echo "Nginxイメージをビルド中..." docker build -f aws-ecs/Dockerfile.nginx -t ${NGINX_REPO}:latest . docker push ${NGINX_REPO}:latest # PHPイメージをビルド・プッシュ echo "PHPイメージをビルド中..." docker build -f aws-ecs/Dockerfile.php -t ${PHP_REPO}:latest . docker push ${PHP_REPO}:latest echo "イメージプッシュ完了!" echo "次にTerraformでECS環境を構築してください" TerraformでAWSリソースを構築する ECSでWordpressサイトを公開するために必要なAWSリソースを構築します。 量が多いのでTerraformで構築します。 . ├── docker-compose.yml ├── .env ├── nginx ├── php-fpm ├── create-ecr.sh ├── image-push.sh ├── aws-ecs └── terraform <- new ├── main.tf <- new ├── output.tf <- new ├── variables.tf <- new └── terraform.tfvars <- new 各コードについては、本記事の最後に記載しています。 次のコマンドを叩くことでAWSリソースを構築します。 cd terraform terraform init terraform plan terraform apply AWS環境のWordPressサイトに接続する albのエンドポイントにアクセスするとWordPressの初期設定画面が開きます。 ローカルPCのWordPressサイトと同様に設定することで、WordPressサイトを公開できました。 終わりに Kiroと二人三脚で構築することができました! Dockerに触れた経験が少なかったので、WordPress環境を作ることで理解が深まったような気がします。 アドベントカレンダー当日の朝まで書いていました。。 コード ./.env # MySQL設定 MYSQL_ROOT_PASSWORD=root_password MYSQL_DATABASE=wordpress MYSQL_USER=wordpress MYSQL_PASSWORD=wordpress_password # WordPress設定 WORDPRESS_DB_HOST=mysql WORDPRESS_DB_USER=wordpress WORDPRESS_DB_PASSWORD=wordpress_password WORDPRESS_DB_NAME=wordpress ./nginx/default.conf server { listen 80; server_name localhost; root /var/www/html; index index.php index.html index.htm; client_max_body_size 100M; location / { try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { fastcgi_pass php-fpm:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } location ~ /\. { deny all; } location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 1y; add_header Cache-Control "public, immutable"; } } ./nginx/nginx.conf user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/conf.d/*.conf; } ./php-fpm/Dockerfile FROM php:8.2-fpm # 必要なパッケージをインストール RUN apt-get update && apt-get install -y \ libfreetype6-dev \ libjpeg62-turbo-dev \ libpng-dev \ libzip-dev \ unzip \ && docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install -j$(nproc) gd \ && docker-php-ext-install pdo_mysql \ && docker-php-ext-install mysqli \ && docker-php-ext-install zip \ && docker-php-ext-install opcache # WordPressをダウンロード RUN curl -O https://wordpress.org/latest.tar.gz \ && tar xzf latest.tar.gz \ && cp -R wordpress/* /var/www/html/ \ && rm -rf wordpress latest.tar.gz \ && chown -R www-data:www-data /var/www/html # PHP設定 COPY php.ini /usr/local/etc/php/ WORKDIR /var/www/html EXPOSE 9000 ./php-fpm/php.ini upload_max_filesize = 100M post_max_size = 100M memory_limit = 256M max_execution_time = 300 max_input_vars = 3000 ; OPcache設定 opcache.enable=1 opcache.memory_consumption=128 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=4000 opcache.revalidate_freq=2 opcache.fast_shutdown=1 ./terraform/output.tf output "alb_dns_name" { description ="DNS name of the load balancer" value =aws_lb.main.dns_name } output "aurora_cluster_endpoint" { description ="Aurora cluster endpoint" value =aws_rds_cluster.main.endpoint } output "aurora_reader_endpoint" { description ="Aurora reader endpoint" value =aws_rds_cluster.main.reader_endpoint } output "ecs_cluster_name" { description ="Name of the ECS cluster" value =aws_ecs_cluster.main.name } output "efs_file_system_id" { description ="EFS file system ID" value =aws_efs_file_system.wordpress.id } output "efs_dns_name" { description ="EFS DNS name" value =aws_efs_file_system.wordpress.dns_name } ./terraform/variables.tf variable "aws_region" { description ="AWS region" type =string default ="ap-northeast-1" } variable "project_name" { description ="Project name for resource naming" type =string default ="wordpress" } variable "db_username" { description ="Database username" type =string default ="wordpress" } variable "db_password" { description ="Database password" type =string sensitive =true } ./terraform/terraform.tfvars aws_region = "ap-northeast-1" project_name = "wordpress" db_username = "wordpress" db_password = "your-secure-password-here" ./terraform/main.tf terraform { required_providers { aws ={ source="hashicorp/aws" version="~> 5.57.0" } } } provider "aws" { region = var.aws_region profile ="inaba" } # Data sources data "aws_availability_zones" "available" { state ="available" } data "aws_caller_identity" "current" {} # VPC resource "aws_vpc" "main" { cidr_block ="10.0.0.0/16" enable_dns_hostnames =true enable_dns_support =true tags ={ Name="${var.project_name}-vpc" } } # Internet Gateway resource "aws_internet_gateway" "main" { vpc_id =aws_vpc.main.id tags ={ Name="${var.project_name}-igw" } } # Public Subnets resource "aws_subnet" "public" { count =2 vpc_id =aws_vpc.main.id cidr_block ="10.0.${count.index+1}.0/24" availability_zone = data.aws_availability_zones.available.names[count.index] map_public_ip_on_launch =true tags ={ Name="${var.project_name}-public-subnet-${count.index+1}" } } # Private Subnets resource "aws_subnet" "private" { count =2 vpc_id =aws_vpc.main.id cidr_block ="10.0.${count.index+10}.0/24" availability_zone = data.aws_availability_zones.available.names[count.index] tags ={ Name="${var.project_name}-private-subnet-${count.index+1}" } } # Route Table for Public Subnets resource "aws_route_table" "public" { vpc_id =aws_vpc.main.id route { cidr_block ="0.0.0.0/0" gateway_id =aws_internet_gateway.main.id } tags ={ Name="${var.project_name}-public-rt" } } # Route Table Associations for Public Subnets resource "aws_route_table_association" "public" { count =2 subnet_id =aws_subnet.public[count.index].id route_table_id =aws_route_table.public.id } # NAT Gateway for Private Subnets (1台のみ) resource "aws_eip" "nat" { domain ="vpc" depends_on =[aws_internet_gateway.main] tags ={ Name="${var.project_name}-nat-eip" } } resource "aws_nat_gateway" "main" { allocation_id =aws_eip.nat.id subnet_id =aws_subnet.public[0].id tags ={ Name="${var.project_name}-nat-gateway" } depends_on =[aws_internet_gateway.main] } # Route Table for Private Subnets (共通) resource "aws_route_table" "private" { vpc_id =aws_vpc.main.id route { cidr_block ="0.0.0.0/0" nat_gateway_id =aws_nat_gateway.main.id } tags ={ Name="${var.project_name}-private-rt" } } # Route Table Associations for Private Subnets resource "aws_route_table_association" "private" { count =2 subnet_id =aws_subnet.private[count.index].id route_table_id =aws_route_table.private.id } # Security Group for ALB resource "aws_security_group" "alb" { name_prefix ="${var.project_name}-alb-" vpc_id =aws_vpc.main.id ingress { description ="HTTP from allowed IP" from_port =80 to_port =80 protocol ="tcp" cidr_blocks =["x.x.x.x7/32"] } ingress { description ="HTTPS from allowed IP" from_port =443 to_port =443 protocol ="tcp" cidr_blocks =["x.x.x.x/32"] } egress { description ="All outbound traffic" from_port =0 to_port =0 protocol ="-1" cidr_blocks =["0.0.0.0/0"] } tags ={ Name="${var.project_name}-alb-sg" } lifecycle { create_before_destroy =true } } # Security Group for ECS resource "aws_security_group" "ecs" { name_prefix ="${var.project_name}-ecs-" vpc_id =aws_vpc.main.id ingress { description ="HTTP from ALB" from_port =80 to_port =80 protocol ="tcp" security_groups =[aws_security_group.alb.id] } egress { description ="All outbound traffic" from_port =0 to_port =0 protocol ="-1" cidr_blocks =["0.0.0.0/0"] } tags ={ Name="${var.project_name}-ecs-sg" } lifecycle { create_before_destroy =true } } # Security Group for EFS resource "aws_security_group" "efs" { name_prefix ="${var.project_name}-efs-" vpc_id =aws_vpc.main.id ingress { description ="NFS from ECS" from_port =2049 to_port =2049 protocol ="tcp" security_groups =[aws_security_group.ecs.id] } egress { description ="All outbound traffic" from_port =0 to_port =0 protocol ="-1" cidr_blocks =["0.0.0.0/0"] } tags ={ Name="${var.project_name}-efs-sg" } lifecycle { create_before_destroy =true } } # Security Group for RDS resource "aws_security_group" "rds" { name_prefix ="${var.project_name}-rds-" vpc_id =aws_vpc.main.id ingress { description ="MySQL from ECS" from_port =3306 to_port =3306 protocol ="tcp" security_groups =[aws_security_group.ecs.id] } egress { description ="All outbound traffic" from_port =0 to_port =0 protocol ="-1" cidr_blocks =["0.0.0.0/0"] } tags ={ Name="${var.project_name}-rds-sg" } lifecycle { create_before_destroy =true } } # EFS File System resource "aws_efs_file_system" "wordpress" { creation_token ="${var.project_name}-efs" performance_mode ="generalPurpose" throughput_mode ="provisioned" provisioned_throughput_in_mibps =10 encrypted =true tags ={ Name="${var.project_name}-efs" } } # EFS Mount Targets resource "aws_efs_mount_target" "wordpress" { count =2 file_system_id =aws_efs_file_system.wordpress.id subnet_id =aws_subnet.private[count.index].id security_groups =[aws_security_group.efs.id] } # Aurora Subnet Group resource "aws_db_subnet_group" "main" { name ="${var.project_name}-aurora-subnet-group" subnet_ids =aws_subnet.private[*].id tags ={ Name="${var.project_name}-aurora-subnet-group" } } # Aurora Cluster resource "aws_rds_cluster" "main" { cluster_identifier ="${var.project_name}-aurora-cluster" engine ="aurora-mysql" engine_version ="8.0.mysql_aurora.3.04.2" database_name ="wordpress" master_username = var.db_username master_password = var.db_password db_subnet_group_name =aws_db_subnet_group.main.name vpc_security_group_ids =[aws_security_group.rds.id] backup_retention_period =7 preferred_backup_window ="03:00-04:00" skip_final_snapshot =true deletion_protection =false tags ={ Name="${var.project_name}-aurora-cluster" } } # Aurora Instance (1台のみ) resource "aws_rds_cluster_instance" "main" { identifier ="${var.project_name}-aurora-instance" cluster_identifier =aws_rds_cluster.main.id instance_class ="db.r5.large" engine =aws_rds_cluster.main.engine engine_version =aws_rds_cluster.main.engine_version tags ={ Name="${var.project_name}-aurora-instance" } } # CloudWatch Log Group resource "aws_cloudwatch_log_group" "ecs" { name ="/ecs/${var.project_name}" retention_in_days =7 tags ={ Name="${var.project_name}-log-group" } } # ECS Cluster resource "aws_ecs_cluster" "main" { name ="${var.project_name}-cluster" tags ={ Name="${var.project_name}-cluster" } } # IAM Role for ECS Execution resource "aws_iam_role" "ecs_execution" { name ="${var.project_name}-ecs-execution-role" assume_role_policy =jsonencode({ Version="2012-10-17" Statement= [ { Action="sts:AssumeRole" Effect="Allow" Principal= { Service="ecs-tasks.amazonaws.com" } } ] }) tags ={ Name="${var.project_name}-ecs-execution-role" } } resource "aws_iam_role_policy_attachment" "ecs_execution" { role =aws_iam_role.ecs_execution.name policy_arn ="arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" } # CloudWatch Logs用のIAMポリシー resource "aws_iam_role_policy" "ecs_logs" { name ="${var.project_name}-ecs-logs-policy" role =aws_iam_role.ecs_execution.id policy =jsonencode({ Version="2012-10-17" Statement= [ { Effect="Allow" Action= [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ] Resource="arn:aws:logs:${var.aws_region}:${data.aws_caller_identity.current.account_id}:*" } ] }) } # ECS Task Definition resource "aws_ecs_task_definition" "main" { family = var.project_name network_mode ="awsvpc" requires_compatibilities =["FARGATE"] cpu ="512" memory ="1024" execution_role_arn =aws_iam_role.ecs_execution.arn volume { name ="wordpress-efs" efs_volume_configuration { file_system_id =aws_efs_file_system.wordpress.id root_directory ="/" } } container_definitions =jsonencode([ { name="nginx" image="${data.aws_caller_identity.current.account_id}.dkr.ecr.${var.aws_region}.amazonaws.com/${var.project_name}-nginx:latest" portMappings= [ { containerPort=80 protocol="tcp" } ] essential= true dependsOn= [ { containerName="php-fpm" condition="START" } ] mountPoints= [ { sourceVolume="wordpress-efs" containerPath="/var/www/html" readOnly= false } ] logConfiguration= { logDriver="awslogs" options= { "awslogs-group" = aws_cloudwatch_log_group.ecs.name "awslogs-region" = var.aws_region "awslogs-stream-prefix" = "nginx" } } }, { name="php-fpm" image="${data.aws_caller_identity.current.account_id}.dkr.ecr.${var.aws_region}.amazonaws.com/${var.project_name}-php:latest" essential= true mountPoints= [ { sourceVolume="wordpress-efs" containerPath="/var/www/html" readOnly= false } ] environment= [ { name="WORDPRESS_DB_HOST" value= aws_rds_cluster.main.endpoint }, { name="WORDPRESS_DB_NAME" value= aws_rds_cluster.main.database_name }, { name="WORDPRESS_DB_USER" value= aws_rds_cluster.main.master_username }, { name="WORDPRESS_DB_PASSWORD" value=var.db_password } ] logConfiguration= { logDriver="awslogs" options= { "awslogs-group" = aws_cloudwatch_log_group.ecs.name "awslogs-region" = var.aws_region "awslogs-stream-prefix" = "php-fpm" } } } ]) tags ={ Name="${var.project_name}-task" } } # Application Load Balancer resource "aws_lb" "main" { name ="${var.project_name}-alb" internal =false load_balancer_type ="application" security_groups =[aws_security_group.alb.id] subnets =aws_subnet.public[*].id enable_deletion_protection =false tags ={ Name="${var.project_name}-alb" } } # Target Group resource "aws_lb_target_group" "main" { name ="${var.project_name}-tg" port =80 protocol ="HTTP" vpc_id =aws_vpc.main.id target_type ="ip" health_check { enabled =true healthy_threshold =2 interval =30 matcher ="200,302" path ="/" port ="traffic-port" protocol ="HTTP" timeout =5 unhealthy_threshold =2 } tags ={ Name="${var.project_name}-tg" } } # ALB Listener resource "aws_lb_listener" "main" { load_balancer_arn =aws_lb.main.arn port ="80" protocol ="HTTP" default_action { type ="forward" target_group_arn =aws_lb_target_group.main.arn } } # ECS Service resource "aws_ecs_service" "main" { name ="${var.project_name}-service" cluster =aws_ecs_cluster.main.id task_definition =aws_ecs_task_definition.main.arn desired_count =1 launch_type ="FARGATE" network_configuration { subnets =aws_subnet.private[*].id security_groups =[aws_security_group.ecs.id] assign_public_ip =false } load_balancer { target_group_arn =aws_lb_target_group.main.arn container_name ="nginx" container_port =80 } depends_on =[ aws_lb_listener.main, aws_efs_mount_target.wordpress ] tags ={ Name="${var.project_name}-service" } }
アバター
本記事は TechHarmony Advent Calendar 2025 12/21付の記事です 。 皆さんこんにちは。UGです。 クリスマスが今年もやってくるということで、サンタクロースはなぜ 赤い服 を着ているのでしょうか? と今ではサンタクロースよりもカーネル・サンダースという白髭を好む私はふと疑問に思いました。 カーネルサンダースも思えば白と赤だなぁ?というのはおいておいて、サンタクロースの服が赤というのは、サンタクロースのモデルとされるセント・ニコラスが生前、教会の儀式の際に着ていた服の色がもとになったと言われているみたいです。 あとはコカ・コーラの宣伝によるものらしいです。 サンタはどうして「赤い衣装」を着ているの? あなたの朝がいつもイイ朝でありますように—ニッポン放送『羽田美智子のいってらっしゃい』。12月21日放送分のテーマは「サンタクロースの疑問」です。 「サンタクロースの服=赤」というイメージがあります。なぜ赤な... news.1242.com ちなみに私のチャッピー君は「20世紀初頭の印刷技術で赤が最も再現しやすかったから」と教えてくれましたが、調べても出てこなかったので問い詰めたところ嘘と白状しました。。。 皆さんもハルシネーションには気を付けましょう。 さて本題ですが、今回は新規作成したIAMユーザのMFA設定を自動でチェックし、設定されていなければ自動で無効化する仕組みを実装してみたのでご紹介出来たらなと思います! 結論 まず先に構成やコードを載せておきますので、説明よりも早く実装したいという方は参考にしていただければと思います。 前提:CloudTrailが有効化されていること 構成:EventBrige + Step Functions 注意点:バージニア北部(us-east-1)で構築すること EventBridgeルール: { "source": ["aws.iam"], "detail-type": ["AWS API Call via CloudTrail"], "detail": { "eventName": ["CreateUser"] } } Step Functions ASL: { "Comment": "A description of my state machine", "StartAt": "Wait", "States": { "Wait": { "Type": "Wait", "Seconds": 86400, "Next": "ListMFADevices", "Assign": { "UserName.$": "$.detail.requestParameters.userName" } }, "ListMFADevices": { "Type": "Task", "Parameters": { "UserName.$": "$UserName" }, "Resource": "arn:aws:states:::aws-sdk:iam:listMFADevices", "Next": "GetMfaDeviceCount" }, "GetMfaDeviceCount": { "Type": "Pass", "Next": "CheckMFA", "Parameters": { "MfaDeviceCount.$": "States.ArrayLength($.MfaDevices)" } }, "CheckMFA": { "Type": "Choice", "Choices": [ { "Next": "成功", "Variable": "$.MfaDeviceCount", "NumericGreaterThan": 0 } ], "Default": "DeleteLoginProfile" }, "DeleteLoginProfile": { "Type": "Task", "Parameters": { "UserName.$": "$UserName" }, "Resource": "arn:aws:states:::aws-sdk:iam:deleteLoginProfile", "Next": "Disabled Notification" }, "Disabled Notification": { "Type": "Task", "Resource": "arn:aws:states:::sns:publish", "Parameters": { "TopicArn": "<トピックARN>", "Message.$": "States.Format('User {} did not set MFA and was disabled.', $UserName)", "Subject": "IAM User MFA Not Set" }, "End": true }, "成功": { "Type": "Succeed" } }, "QueryLanguage": "JSONPath" }こ ※SNSはおまけなので、削除するか通知させたければ”TopicArn”の部分をご自身で作成したものに変更してください。   背景 どこの環境でもMFAを設定することはセキュリティを担保するために必須なものとなっているかと思います。 とは言えMFAを設定するのはめんどくさいですし、純粋に設定し忘れていたという問題もあります。 (狙ったわけではないですが、思えば前回MFAめんどくさいでProtonのブログ書いてました笑) Proton Authenticator を使ってみる AWSやクラウド作業でのMFAが面倒な方必見。PCでもスマホでも使える「Proton Authenticator」の導入方法を解説します。デバイス間同期、コードコピー、他アプリからのインポート、バックアップ設定まで、実務でMFAを効率的に使うためのポイントをまとめました。 blog.usize-tech.com 2025.08.19 そのための対策として、MFAを設定しないとリソースを操作することができないIAMポリシーを設定しているところも多いのではないでしょうか? しかし、IAMポリシー対策はリソース操作はできないものの、マネージメントコンソールにアクセスすることは可能です。 そういったリスクも回避したいといった場合に、MFAを設定していないIAMユーザーを無効化してしまうというのも1つの対策となります。 ただMFAが設定されているのかを確認して設定されていなければ無効化、なんてことを手動でやっていたら大変です。。。 なので手動が大変なら自動化してしまえ!ということで自動化させてみました。   前提 前提事項として、CloudTrailが有効化されている必要があります。 理由としては、CloudTrailで記録される「CreateUser」というIAMユーザーが作成された時のイベントをトリガーに今回の自動化フローは動くためです。 みなさん問題はないかと思いますが、CloudTrailは有効化必須のサービスなので、もし有効化されていないので、本ブログ内容関係なくすぐ有効化しましょう!   構成説明 今回の自動化のざっくり流れは 新規IAMユーザーを作成 ※こちらは手動 EventBrigeでIAMユーザの作成イベントを検出してStep Functionsを起動 ←ここから自動 Step Functionsのフロー内で、一定時間待ったのちMFAの設定有無を確認、設定されていなければ無効化 となっており、EventBrigeとStep Functionsのみで実現することができます。 では詳しくご紹介していきます。 IAMユーザ作成をトリガーとして Step Functions を起動 前提の節でも触れましたが、IAMユーザーが作成されると「CreateUser」イベントが記録されます。 このイベントをEventBridgeルールで検出し、Step Functionsを開始します。 EventBridgeルール: { "source": ["aws.iam"], "detail-type": ["AWS API Call via CloudTrail"], "detail": { "eventName": ["CreateUser"] } } Step Functions のステートマシン構成 Step Functionsのステートマシンの構成は以下のようになっています。 細かい設定の説明は後回しにして、先に役割単位でまとめて説明していきます。 まず、「Wait」でMFA登録有無の確認までの時間を設定しています。 例えば、IAMユーザー作成が24時間以内にMFAを設定することといったルールの場合は、Waitに86400秒を設定します。 次に、「IAM: ListMFADevices」「Pass state」「Choice state」の部分で、IAMユーザーのMFAの設定有無の確認を行っています。 設定されているのであれば、「Succeed state」に遷移し、特に何も行いません。 設定されていなければ、「DeleteLoginProfile」でIAMユーザーの無効化をします。 「SNS: Publish」はおまけですが、「無効化しましたよ」の通知用となります。 ざっくりだと以上のようになっていて、各ステートごとの細かい設定についても説明します。 まず、「Wait」では待機時間の秒数とともに、EventBrigeからの入力値である”detail.requestParameters.userName”を変数へ格納しています。 “detail.requestParameters.userName”は作成されたIAMユーザーの名前となっており、他のステートで利用するため最初に変数へ格納しています。 次に、「IAM: ListMFADevices」でIAMユーザーのMFAデバイスリストを取得してきています。 ListMFADevices - AWS Identity and Access Management Lists the MFA devices for an IAM user. If the request includes a IAM user name, then this operation lists all the MFA de... docs.aws.amazon.com MFA設定がされていない場合の出力結果: { "IsTruncated": false, "MfaDevices": [] } しかし、「IAM: ListMFADevices」の出力結果からでは、「Choice state」で分岐をさせることができません。 そのため、「Pass state」の中で”States.ArrayLength($.MfaDevices)”によってパラメーターの変換を行っています。 パラメータ変換後: { "MfaDeviceCount": 0 } これにより、MFAの登録デバイスを数値で表せるようにして、「Choice state」にて”$.MfaDeviceCount > 0″の条件でMFAの登録有無の分岐を実現しています。 そして、MFA登録がされていなければ、「DeleteLoginProfile」でIAMユーザーを無効化しています。 DeleteLoginProfile - AWS Identity and Access Management Deletes the password for the specified IAM user or root user, For more information, see Managing passwords for IAM users... docs.aws.amazon.com   注意点 最後に注意点ですが、今回ご紹介した構成は 『 バージニア北部(us-east-1) 』 で構築する必要がございます。 と言いますのも、「CreateUser」イベントはバージニア北部リージョンに記録されるためです。 そのため、そのほかのリージョンのEventBrigeで検出しようとしても、検出されず、となってしまいます。 CloudTrail concepts - AWS CloudTrail This page summarizes basic concepts related to CloudTrail such as describing the types of CloudTrail events. docs.aws.amazon.com 公式ドキュメントにも⚠重要と明記されていましたが、自分もこの仕様を知らず、最初に東京リージョンに作成して、なんで動かないんだ?とつまづきました笑 今回のメインサービスであるIAMがグローバルサービスなので、バージニア北部リージョンで実装することに大きな問題はないかと思いますが、ご注意いただければと思います。   まとめ ということでMFA設定をしていなければ自動で無効化をご紹介させていただきました。 MFAが本当に役に立っているのか?みたいな話もありますが、昨今大きなセキュリティ問題も発生しており、セキュリティの意識や要望は強くなってくると思われます。 そんな中でこんなのもあるんだな~と本ブログが一助になればよいかな~と。 最後までお読みいただきありがとうございました!!
アバター
本記事は TechHarmony Advent Calendar 2025 12/20付の記事です 。 高知の喫茶店からこんにちは。出張中のMasedatiです。 高知には独自のモーニング文化があるようで、今日はおにぎりと味噌汁、オムレツとゆで卵、バターたっぷりの食パンとサラダをモリモリ食べながらこの記事を執筆しています。 さて、今回の内容は以下のAWSアップデートについてです。 Amazon Quick Suite browser extension now supports Quick Flows - AWS Discover more about what's new at AWS with Amazon Quick Suite browser extension now supports Quick Flows aws.amazon.com ざっくり言うと「 ブラウザの中で、そのままAIアシスト(要約・Q&A・社内ナレッジ参照・アクション実行・ファイル分析)ができ、その拡張機能が Quick Flows でもサポート可能になった 」とのこと。 Quick Suiteブラウザ拡張機能とは ChromeやFirefoxのブラウザ内でQuick Suiteと対話することができます。 ブラウザ拡張機能を インストール して、Quick Suiteのアカウント名とユーザ名でサインインしてみましょう。 無事サインインが完了すると、現在開いているWebページが表示されます。 +ボタン を押すことで、現在開いているブラウザのタブをチャットの会話コンテキストに追加できます。 追加後は、そのウェブページの内容について質問したり、分析したりできるようになります。 例えば、Techブログを書くとき参考にしたAWSドキュメント等を+ボタンでQuick Suiteに登録しておけば、ブログ執筆途中の画面で記載内容の添削やレビューを行うことが可能となります。(今この記事を執筆に使ってみましたが、とても便利です) Quick Flowsのサポートが追加されました さて、本題ですが、このブラウザ拡張機能からQuick Flowsを実施することができるようになりました。 Amazon Quick Flowsは、Amazon Quick Suiteの機能の1つで、自然言語で命令するだけで、複数のステップのワークフローを作成することができるものです。 今回Quick Flowsをサポートすることになり、ブラウザを離れることなくQuick Flowsを直接実行できます。 やってみた デモとして、ブログ記事がガイドラインに違反していないかどうかチェックするワークフローを作成してみます。 まず、Quick Suiteのスペースに「ブログ執筆ガイドライン」を格納します。 # ブログ執筆ガイドライン ## 文体・トーン * 文体: です・ます調で統一 * トーン: 親しみやすく、かつ専門的 * 一人称: 「私」または「筆者」 ## 表記ルール * 製品名・サービス名は正確であること * 半角数字を使用すること: 「3つ」「20個」 * 単位は全角: 「10MB」「30日間」 * 括弧: 全角()を使用 * 引用符: 「」を使用(""は避ける) * 中黒: ・を使用 ## 禁止用語・推奨表現 * 過度にカジュアルな表現は用いない(「めっちゃ」「ヤバい」など) * 曖昧な表現は用いない(「たぶん」「かもしれない」など) * 禁止用語 - 「簡単」→ 「シンプル」「わかりやすい」を使用 - 「誰でも」→ 「技術的な知識がなくても」など具体的に - 「すごい」→ 「強力な」「効果的な」など具体的に - 「便利」→ 具体的なメリットを記述   次にFlowを作成します。 上記のとおりフローの作成は自然言語で行います。 ブログ記事を、スペースに格納した執筆ガイドラインに基づいてレビューを行ってもらいます。 「生成」ボタンを押すと以下のようなワークフローが完成しました。 拡張機能の「F」ボタンから上記ワークフローを実施することができます。 さっそくワークフローを実行して、過去の私の記事をレビューしてもらいました。 Hey Kiro, Spotifyのプレイリストで打線組んで。 AWSが発表した次世代エージェント型IDE「Kiro」を実際に触ってみて、Webアプリケーションを構築してみた体験記となります。 blog.usize-tech.com 2025.08.14 結果 では、緊急対応の修正をしていきます。
アバター
本記事は TechHarmony Advent Calendar 2025 12/19付の記事です 。 こんにちは。社会人歴1年目、AWS歴も1年目の新人tknこと髙野です。 今年初めて紅茶のアドベントカレンダーを朝食のお供に買ったのですが、先日何の偶然かお味噌汁とハーブティーという組合せが誕生しました。食の常識を覆す出来事に、朝からとてもよく目が覚めました。アドベントカレンダーは偉大です。。 さて先日、私がとある指令を受けたことからこのブログは始まります。 指令内容 名前が異なっているが、役割が同じAmazon EventBridgeのルールが2つ作成されている(EventRule-a, EventRule-b)。なぜ作成されたのか、どちらが現在使用されているものなのか調査してほしい。 もちろん実際はとても詳細にご説明いただきましたが、、ざっくりお伝えするとこのような指令を受けました。 以下のアーキテクチャ図は私が今回調査した環境を抜粋して表現したものであり、水色の丸で囲まれたEventRuleが今回の調査対象です。 また、調査対象のリソースの特徴・設定は以下の通りです。 EventRule-a / EventRule-b AWS Lambdaの関数のプログラムにより動的に作成 されたEventRule イベントパターン:AWS CodeCommitのあるブランチへのマージ ターゲット:Lambda 2つのLambda どちらも関数内で Amazon CloudWatch Logsへのログの出力処理 あり この環境を見たとき私は「AWS CloudTrailを見ればとりあえず何か分かるかな?」と単純に考えて調査を進め、行き詰まることになりました…。 そこで今回のブログでは、 AWS初心者が上記環境の リソースの作成履歴を調べた際に役立ったログ や、 ログに含めるべきだと思った情報 についてお伝えしたいと思います。 調査で最終的に分かったこと 私の調査方法をご説明する前に、今回の調査で最終的に分かったことをお伝えします。 調査対象のEventRule-a/bが作成された日時 が分かった(EventRule-aが先、EventRule-bが後) EventRule-aと同じ命名規則で作成された 他の役割のEventRuleは既に削除されている ことが分かった EventRule-bの作成日以降に、ルール作成を担うLambda関数のコードを記録するCodeCommitに該当ファイルのマージが見られた 以上の結果より、私は 「ルールの作成を担うLambda関数において、命名規則のコードが変更されたことで別名で同じ役割のEventRuleが作成された」 という仮説を最有力のEventRule誕生理由としてこの調査を終えることになりました。 最終的に、謎の大解明まで持っていくことができなかったのが悔しいところです。。   著者が躓いた調査環境の特徴 さて、私が躓いたポイントについてお話するにあたり、調査環境の特徴について追加で以下に示します。 対象環境の作成は半年以上前に行われており、活発に稼働していた期間も同時期であったことから、デフォルトで保存期間が90日の CloudTrailには情報が残っていなかった 対象のEventRuleが監視していたブランチにはマージが行われておらず、 EventRule呼び出しのログ自体が残っていなかった ここですね!このポイントに気づくのに私は多くの時間を使いました。。 AWS初心者ひいてはログ調査初心者でもある私は、 最初に環境の作成時期や稼働時期を調べることをせずに 、とりあえず色々なログを見る!という行動に突っ走っておりました。その結果、ルールの稼働記録を見るための操作・呼び出しログばかりを探しては見つからずに困惑することになりました。 もし頻繁に稼働しているリソースを調査する場合は、CloudTrailで以下のようなログを中心に調査を進めることができるでしょう。 CodeCommitの挙動に基づくログ ・GitPush:コミットのプッシュ ・CreatePullRequest:プルリクエストの作成 ・MergePullRequestByFastForward/MergePullRequestBySquash:プルリクエストのマージ ・UpdatePullRequestStatus:プルリクエストのクローズ(マージまたは却下) EventRuleの挙動に基づくログ ・PutRule:EventRuleの作成・更新 ・DeleteRule:EventRuleの削除 ・EnableRule/DisableRule:EventRuleの有効化/無効化 ・PutTargets:EventRuleのターゲットの追加・更新 ・PutEvents:イベントバスへのカスタムイベントの発行 なお、 EventRuleのターゲットとして呼び出されるLambda関数のAPIコールは「データイベント」に分類される ため、デフォルトで管理イベントのみを記録するCloudTrailではログが残らないため注意しましょう。代わりにCloudWatchでログを確認することができます。(参照: Lambda 関数ログの操作 – AWS Lambda ) ここで、対象のEventRuleはどちらも同じイベントパターンであるため、今から動作検証しても両方とも検知・作動してしまいます。そこで私は、EventRuleやLambdaの動作状況に関する調査から、誕生の歴史に関する調査に移ることにしました。   リソース作成履歴の調査に活躍したログ 以下では、リソースの作成履歴を調査する中で役立ったログについてご紹介します。 Amazon CloudWatchのロググループ ログストリームとは、CloudWatch Logsが取集したログの中で同一のソースをもつログイベントのことであり、ロググループとは「 保持、モニタリング、アクセス制御について同じ設定を共有するログストリームのグループ 」のことです。(参照: ロググループとログストリームの操作 – Amazon CloudWatch Logs ) 今回の調査環境では、EventRuleの作成用とターゲット用のLambdaそれぞれに、 CloudWatch Logsへのログの書き込み権限を付与 していました。CloudWatch Logsへのログの書き込みに必要な権限は、 logs:CreateLogGroup , logs:CreateLogStream , logs:PutLogEvents の3つであり、これらはAWSLambdaBasicExecutionRoleというAWSマネージドポリシーをLambdaに付与することで簡単に実現できます。(参照: AWSLambdaBasicExecutionRole – AWS 管理ポリシー ) 上記の権限を付与することで、以下のようにLambda関数がいつ実行されたのかが自動で記録され、 EventRuleの作成日時 を知ることができました。 また、Lambda関数ではPythonの標準ライブラリであるloggingモジュールを使用して、 logger.info(f"event: {json.dumps(event)}") のようにイベント内容を出力することで、以下のような イベントの詳細な処理内容を確認 することができました。 {   "originalEvent": {       "version": "0",       "id": "XXXXXXXX",       "detail-type": "API Call",       "source": "XXXXXXXX",       "account": "123456789012",       "time": "2025-12-15T06:57:58Z",       "region": "ap-northeast-1",       "resources": [],       "detail": {           "eventVersion": "1.0",           "userIdentity": {},           "eventTime": "2025-12-15T06:57:58Z",           "eventSource": "XXXXXXXX",           "eventName": "CreateEventRule",           "awsRegion": "ap-northeast-1",           "sourceIPAddress": "XXXXXXXX",           "userAgent": "XXXXXXXX",           "requestParameters": {/* イベントの処理内容 */},           "requestID": "XXXXXXXX",           "eventID": "XXXXXXXX", "readOnly": false,           "eventType": "AwsApiCall",           "managementEvent": true,           "recipientAccountId": "123456789012",           "eventCategory": "Management",           "sessionCredentialFromConsole": "true"       }   },   "createRuleName": "EventRuleFunction" } しかし、上記のようなルールログはEventRuleのプロパティなどをもとに出力するものであり、ルール名の情報は反映されません。そこで調査環境では、Lambda関数内に logger.info(f"EventRule created. : {rule_name}") を追加することで、作成したルール名を含むログを出力していました。 このコードが無ければEventRule-aとbどちらの作成日時か正確に判別できなかった ため、ログ設計の重要性を感じました。 また、この ログを EventRule created という キーワードでフィルターすることで、各EventRuleの作成日時を時系列順で取得 することができ、命名規則が途中からEventRule-a→EventRule-bのように変化していることに気づくことができました。Lambda関数の作者の方に感謝しかありません。。 CloudWatchのログツールにはCloudWatch Logsだけでなく、メトリクスが存在します。 しかし、EventBridgeやLambdaに関してCloudWatchの標準メトリクスが集められるのは、以下のような リソースの呼び出しイベント であり、調査環境のケースには適しませんでした。      EventBridge関連のメトリクス ・Invocations:EventRuleがターゲット(Lamba関数)の呼び出しに成功した関数 ・TriggeredRules:EventRuleがトリガーされた回数 ・MatchedEvents:イベントがEventRuleのイベントパターンと一致した回数 ・InvocationsLatency:イベントを検知してからターゲットを呼び出すまでの時間 Lambda関連のメトリクス ・Invocations:Lambda関数が呼び出された回数 ・Errors:Lambda関数の実行がエラーで終了した回数 ・Duration:Lambda関数が実行開始から終了までにかかった時間 AWS Config AWS ConfigとはAWSアカウント内のリソースの設定変更を監視し、記録するサービスです。ConfigはAWSアカウント発行後に一度有効化し、記録する対象リソースを指定することで情報の記録が始まります。 ここでは、リソースタイムラインを確認することで、あるリソースの作成時の構成から現在の構成までの変更履歴を見ることができます。 しかし、ここで注意すべきは 必ずしもリソース情報が最も古い地点=リソースの作成日時とは限らない ことです。 リソースタイムラインで確認できるリソースの設定情報の中に、 "configurationItemStatus": "ResourceDiscovered" がある場合、それは Configが対象リソースを初めて検出したこと を示します。そのため、Configが有効化される前に作成されたリソースなどは、Configを有効化してリソースが発見された時点で追跡が開始されるため、Configのログをリソース作成日時の根拠とすることは望ましくありません。 一方で、Configの便利な点として 削除したリソースの構成履歴も確認できる 点が挙げられます。 以下のように削除したリソースも含めて検索できるうえ、存在した期間、変更履歴、削除日などを確認することが可能です。 今回の調査環境では、このリソース履歴において EventRule-aと 同一の命名規則で他の役割をもつEventRuleが全て削除済 であることが確認 できました。一方で、EventRule-bと同一の命名規則のEventRuleは現役であったことから、 EventRule-aが不要な関数である可能性が高い と判断することができました。   調査結果のまとめ これまでの調査結果より、「EventRule-aはEventRule-bより先に作成された」、「EventRule-aと同様の命名規則のEventRuleは既に全て削除されている」という点から、EventRule-aが不要なEventRuleである可能性が高まりました。 そこで仮説をより強固にするべく、EventRuleを作成するLambda関数の命名規則コードの変遷を追跡しようと、 Lambda関数のバージョン や CodeCommitのコミット履歴 の確認を試みました。が、、 Lambda:バージョン履歴なし CodeCommit:ある日あるコミットでLambda関数のコード関連ファイルが全て誕生 ただし、EventRule-b作成日以降に該当ファイルのマージを確認 上記の結果より、「EventRule-aが作成された後に、Lambda関数においてEventRuleの命名規則の変更があり、EventRule-bが作成されてその後使用されている… のではないか? 」という結論に終わりました。。 ログに含めるべきだと思った情報 以上の結果より、各リソースにおいてログに含めてあると調査がしやすいのではないかと感じた情報をまとめます。 EventBridge/Lambda: 呼び出し元のリソース名 方法1:EventRuleのイベントパターンにおいて、detail-typeにEventRule名を含めた文字列を設定 方法2:EventRuleの 入力トランスフォーマー で、Lambdaに渡す情報にリソース名を含めるように設定 CodeCommit: こまめな コミット履歴 EventBridge/Lambdaについては、どちらの手法も動的にEventRuleを作成する調査対象のような環境では適用しやすいうえ、これによりLambdaのCloudWatchロググループにおいて、 Lambdaを呼び出したEventRule名を 無期限 の間確認可能になる ことが期待できます。 CodeCommitについては、developやmasterなど複数人で共有するブランチでは完成版のコミットを意識する必要があるものの、 featureなど一時的/個人的なブランチではこまめにコミット して履歴を残すことで、 将来の自身・チームメンバーがコード設計の意図を辿りやすくなる ことが考えられます。   おわりに 今回、調査を通してログが環境理解にどのように役立つかを身をもって学ぶことができました。今回学んだ”将来環境を引き継ぐ人に向けた開発”の視点を、今後の開発業務に活かしていきたいと思います。 初めてのブログで拙いところも多々あったかと思いますが、いかがでしたでしょうか。 今後、様々なAWSリソースについて学びを深めるとともに、このようなアウトプットのスキルも向上させていきたいと願うばかりです。 最後までお付き合いいただき、誠にありがとうございました。 クリスマス・イブまであと6日、皆さま体調に気を付けてお過ごしください!
アバター
本記事は TechHarmony Advent Calendar 2025 12/19付の記事です 。 こんにちは、ひるたんぬです。 最近は急速に気温が下がってきましたね… 私は寒いときにブルッと鳥肌が立つのですが、なぜ感動したときや恐怖を感じたときも同じような反応をするのでしょうか? さて、そのような探索を進めるためには、鳥肌が生じているときの脳の活動の様子を調べることが有効です。ところが、これがなかなか簡単ではありません。…(中略)…脳活動を測定するというさらに慣れない環境だと、鳥肌はもっと立ちにくくなることを覚悟しなければならないでしょう。これでは実験データを集めるだけでも気の遠くなる仕事になってしまいます。こうした事情から、鳥肌を測定して脳の活動と関連づけるという研究はこれまでのところ行われてきていないのです。 引用:academist「 恐怖、感動、驚き——さまざまな感情体験で鳥肌が生じるのはなぜ? 」 調査をする中で、傾向論のようなものはありましたが、具体的に鳥肌が立つメカニズムまで解明された研究は見当たりませんでした。 人間の身体の不思議の一つですね。 さて、今回は技術的な話とは少し離れますが、AWSのリージョンについて少し紐解いていきたいと思います。 AWSのリージョン AWSでは、記事執筆時点(2025年12月)で37個のリージョンが存在しています。 日本国内でも「東京リージョン」や「大阪リージョン」が存在し、AWSに触れたことがある方なら一度は聞いたことがあるのではないかと思います。 グローバルインフラストラクチャ aws.amazon.com そんなAWSのリージョンの中で「バージニア北部リージョン」は他のリージョンとは少々事情が異なります。 というのも、バージニア北部リージョンでないといけない場合(例:CloudFrontに紐づけるACMの証明書)や多くの新サービスの提供がバージニア北部リージョンから始まるなど…AWSに必須なリージョンと言っても過言ではありません。 Global services - AWS Fault Isolation Boundaries In addition to Regional and zonal AWS services, there is a small set of AWS services whose control planes and data plane... docs.aws.amazon.com そんな「バージニア北部リージョン」ですが、そもそもなぜ「バージニア北部」にリージョンが設立されたのでしょうか? そもそも私は州名すら聞いたことがなかったので、その理由を調べてみました。 バージニア北部リージョン バージニアってどこ? まずは、バージニア州について少し調べてみます。 バージニア州はアメリカ本土の東部に位置する州です。 2020年現在の人口は8,654,542人で、12番目に人口が多い州です。 2020 Census Apportionment Results Congressional seats were apportioned among the 50 states based on the 2020 Census population counts. Apportionment resul... www.census.gov なぜバージニア北部に? では、肝心な理由について考察していきます。 AWSによる公式のドキュメント・リリースは存在しなかったため、あくまでも調査による推測の域は出ません。 バージニア州北部には、通称「データセンター・アレイ」と呼ばれる世界最大のデータセンター集積地があります。 ここにデータセンターが集まってきた理由として、以下が挙げられます。 米国東海岸におけるインターネットの心臓部 1960~70年代に米国防総省ARPAが始めたARPANETの一大拠点がバージニア州アーリントンに置かれ、1980年代には東海岸初期のインターネットエクスチェンジMAE-Eastがタイソンコーナー(バージニア州)に開設されるなど、 この地域は早くから通信インフラの要衝 となっていました。 今日では、世界中のインターネットトラフィックの70%がこの「データセンター・アレイ」を通るまでになったとも言われています。 ReH0803-ch4-2 www.airc.aist.go.jp 再生水プロジェクトで世界有数のデータセンター集積地に―バージニア州ラウドン郡の実践 | IT Leaders 米バージニア州北部、ワシントンDC郊外に位置するラウドン郡(Loudoun County)。自然豊かなこの地帯に、驚くほどの数のデータセンターが集積している。要因は3つ。1つは高速なネットワーク接続環境、もう1つは安価な電力、そして3つ目に... it.impress.co.jp 安価な電力供給 データセンターの稼働に欠かせない要因の一つとして、安定した電力供給が挙げられます。バージニアの地域には石炭ベルト地帯にある電力会社が、火力発電をメインに電力供給をしています。このこともあり、この地域の電気料金は、アメリカの平均より34%も安価だということです。 今後は石炭利用だけでなく、シェールガスや天然ガスでの発電などが進められるようです。 なお、AWSではデータセンターの電力を補うために風力・太陽光の発電設備を稼働、また再生可能エネルギーの利用に力を入れているようです。 https://aws.amazon.com/jp/blogs/news/more-amazon-wind-and-solar-farms-are-live/ https://www.aboutamazon.jp/news/sustainability/amazon-is-the-worlds-largest-corporate-purchaser-of-renewable-energy-for-the-fourth-year-in-a-row 豊富な水資源 データセンターの冷却には欠かせない大量の水ですが、バージニア州には2008年に水処理施設が完成しました。 この処理施設の再生水を冷却に再利用することにより、データーセンター事業者は安価に大量の水を使用することができ、水道事業者は従来捨てていた水に、大きな処理コストをかけることなく値段をつけて販売できるようになりました。 再生水プロジェクトで世界有数のデータセンター集積地に―バージニア州ラウドン郡の実践 | IT Leaders 米バージニア州北部、ワシントンDC郊外に位置するラウドン郡(Loudoun County)。自然豊かなこの地帯に、驚くほどの数のデータセンターが集積している。要因は3つ。1つは高速なネットワーク接続環境、もう1つは安価な電力、そして3つ目に... it.impress.co.jp 税制面での優遇 バージニア州では、新規資本投資が1億5000万ドル以上、50人以上の新規雇用を生み出すプロジェクトでは、導入されるサーバーなどの危機に対して、各種税金が免除されるという制度もあります。 Data Center Retail Sales & Use Tax Exemption | Virginia Economic Development Partnership Virginia offers a data center retail sales and use tax exemption (DCRSUT Exemption) on qualifying computer equipment or ... www.vedp.org 他のリージョンは? 上述した通り、「バージニア北部リージョン」が設立された理由としては 「通信・電力・水」といったインフラに加え、「税制」面でのメリットが大きかった ため、と考えられます。 では、他のリージョンが設立された理由は何なのでしょうか? 例えば、東京リージョンの例を見てみます。 東京リージョンは2011年3月に提供が開始されました。その時のインタビュー記事を見てみると、 顧客の多くは米国(東部および西部)やシンガポールのデータセンターを利用している。この物理的な距離によって「遅延(レイテンシ)」と「国外へのデータ配備」という問題が発生していたが、その解消が国内ユーザーの大きな要望だった 引用:ZDNET「 AWS幹部に国内データセンター設立の背景を聞く–普及には「楽観的」 」 AWSを使いたいがデータは日本に置かなければならない、だからデータが日本にあることを確認したいというニーズがあった。 引用:ZDNET「 AWS幹部に国内データセンター設立の背景を聞く–普及には「楽観的」 」 と、顧客ニーズがきっかけになっていることが伺えます。 終わりに 今回は、普段何気なく使っているAWSリージョンの設立背景について、自分なりに調査してみました。 バージニア北部リージョンはインフラ・税制上のメリットから、それ以外のリージョンは顧客ニーズからという結論に至り、バージニア北部リージョンでのリソース使用料金が、他のリージョンよりも比較的安価な理由も頷ける結果となりました。
アバター
こんにちは。 先日私の所属している部でもGoogleのNotebookLM Enterpriseライセンスを購入しまして、進化したNotebookLMが使えるようになりました。 ということで、今回は、そんなNotebookLMとはどんなサービスなのか、特徴やメリットは?使い方は?、を中心にご紹介していきたいと思います。NotebookLMが気になっている方や導入を検討している方の参考になれば幸いです。 NotebookLMは、Googleが提供する最新のAIノート管理サービスです。AI技術を活用することで、大量の情報やメモを効率的に整理したり、必要な情報を素早く検索したりすることが可能になっています。次世代型の知的生産ツールとして注目を集めており、企業や教育現場など様々なシーンで導入が進んでいるサービスです。   はじめに 近年、AI技術の進歩は目覚ましく、私たちの働き方や生活を大きく変えつつあります。とくに自然言語処理の分野では、ChatGPTやGemini、Microsoft Copilotといった生成AIが注目を集め、それぞれがドキュメント作成やアイデア出し、業務自動化など、さまざまなシーンで活用されるようになりました。 私もプライベートではChatGPT Plusを利用しており、自分好みの応答を返してくれるように学習させていたり、勉強する際には音声会話を利用していたりするほど、もはやAIは自然に生活に溶け込んでいると言えますね。   NotebookLMとは NotebookLMは、AIを活用したノート管理・情報整理のためのサービスであり、膨大なメモやドキュメントの中から必要な情報を効率よく見つけ出したり、複数の資料を横断的にまとめたりできるのが特徴です。 本記事では、このNotebookLMの概要や特徴について詳しくご紹介していきます。 文書アップロード NotebookLMでは以下のファイルや情報源をソースとして指定できます。 テキストファイル(.txt) PDFファイル(.pdf) Google ドキュメント(Google Docs) Google スライド(Google Slides) Google ドライブ上のサポートされているファイル ウェブページ(URLを指定してインポート) その他のサポート内のファイル(.mp3、.png、.jpeg、.jpg etc.) Microsoft Word, Powerpoint, Excel(enterprise版のみ) 読み込ませるソースが決まっていないときは、右上の「Discover sources」から、調査したいことについて検索をかけると合致するソースを見つけて提示してくれます。 Q&A 指定したさまざまなソースから、AIが自動的に情報を参照し、質問に対する適切な回答を返してくれます。 たとえば、複数の資料や膨大な情報が手元にある場合でも、「この会議の要点は?」「この資料全体のまとめを知りたい」といった形で質問を投げるだけで、NotebookLMが関連箇所を抽出し、わかりやすく整理して回答してくれます。 従来は、膨大な資料の中から自分で必要な情報を探し、要点をまとめあげるのに多くの時間と手間がかかっていました。しかしNotebookLMを使えば、AIが自動で情報を横断・整理し、重要なポイントや概要をすぐに把握することが可能になります。結果として、調査や情報整理にかかる時間が大幅に短縮され、効率的な情報活用が実現できます。 右上の「ノートブックを設定」から会話のスタイルをカスタマイズできます。デフォルトの会話スタイルから、より具体的なニーズに応じた設定への変更が可能です。 マインドマップ NotebookLMには、AIが自動でマインドマップを作成してくれる機能も搭載されています。マインドマップとは、中心となるテーマから関連する情報やキーワードを放射状に広げて視覚化することで、情報の構造や繋がりを直感的に把握できる思考整理ツールとして知られています。 膨大な資料やメモをそのまま読み進めていくと、なかなか全体像や関係性が見えにくいことがありますが、マインドマップを活用することで、主要なトピックやその下位項目、関連性が一目で分かるようになります。NotebookLMの場合も、指定したソースからAIが重要なポイントやトピックを抽出し、自動でマインドマップとして可視化してくれるため、初見の資料でも全体の流れやポイントをすばやく整理できます。 音声生成/動画生成機能 NotebookLMには、「audio overview(オーディオ概要)」や「video overview(ビデオ概要)」という機能も用意されています。これは、指定した資料やノートの内容をAIが自動で要約し、その要点を音声や動画の形式で分かりやすく伝えてくれる機能です。 audio overviewは、資料の重要ポイントや全体の概要をAIがナレーション音声として読み上げてくれるものです。移動中やちょっとした隙間時間にも耳から情報をインプットできるため、効率的に内容を把握したい方に最適です。 また、video overviewは、AIが自動で要点をまとめ、図表や文字情報とともに動画として解説してくれます。視覚的に情報を整理しながら要約を確認できるため、全体像を短時間でつかみたいときに非常に便利です。 これらの機能によって、notebookLMは「読む」「見る」「聴く」などさまざまな方法で情報を理解できるサービスへと進化しています。忙しいビジネスパーソンや効率よく学びたい方には特におすすめの機能です。   レポート機能 NotebookLMには、「reports(レポート)」機能という機能が搭載されています。これは、AIが指定したノートや資料をもとに、さまざまな形式のレポートを自動で生成してくれる機能です。 たとえば、複数の資料や会議メモをまとめて「サマリーレポート」や「比較レポート」、「FAQ形式」など、用途に合わせたテンプレートでレポート化することが可能です。内容を自分で一からまとめなおす手間が大幅に省けるうえ、AIがポイントを抜き出して分かりやすく構成してくれるため、後で見返したり、チーム内で共有したりするときにも非常に役立ちます。     無料版/有料版   NotebookLM(無料版) NotebookLM for Enterprise 機能 ノートブックやメモの作成、ソースの追加や削除、AIとのチャットによるコンテンツ質問、音声生成、インタラクティブモード、ガイドブック機能、そしてアナリティクス(分析機能)など。 情報の整理や共有、分析までを一元的に効率よく行うことが可能。 ノートブックやメモの作成、ソースの追加や削除、AIとのチャットによるコンテンツ質問、音声生成、インタラクティブモード、ガイドブック機能、そしてアナリティクス(分析機能)など。 情報の整理や共有、分析までを一元的に効率よく行うことが可能。(同様) ソース Google ドキュメントとスライド、コピーしたテキスト、 公開 URL、 YouTube 動画、 PDF、 マークダウン、 音声ファイル Google ドキュメントとスライド、コピーしたテキスト、 公開 URL、 YouTube 動画、 PDF、 マークダウン、 音声ファイル、 DOCX、 PPTX、 XLSX 共有 共有リンクを作成 アクセス権限を設定し、組織内の特定のユーザーへ共有が可能 最大ノートブック数 100 500 ノートブック当たりソース数 50 300  処理回数 チャットクエリ:50 音声概要生成:3 チャットクエリ:500 音声概要生成:20   最後に 最後までお読みいただき、ありがとうございました。 AI技術は今となっては日常生活にも仕事をする上でも欠かせないものになりつつあると思います。新たなAI技術はどう活用していくかが大切になりますが、今回のNotebookLMは多量の情報の整理や資料検索機能に長けていると感じました。マインドマップや音声・動画による要約は現時点では私はあまり利用していませんが、大量データを読み込む必要がある、でも時間がない、といった人には移動中や通退勤中の”ながら作業”を可能にするので、便利なツールになりえるかもしれません。 操作が直感的で、初めてでも迷うことなく使い始められる点も良かったと感じました。 これから導入を検討している方や、効率化を目指したい方の参考になれば幸いです。
アバター
前回記事からの続きです。 IoTに高可用性はなぜ必要?信頼性を確保するための第一歩 – TechHarmony   アーキテクチャ概要 まず、クラスタ構成については、以下の通りです。 Pacemaker :リソース管理(仮想IPやサービスの制御) Corosync :クラスタ通信(ノード間の状態同期) Raspberry Pi 5[2台] :クラスタノード 仮想IP(VIP) :サービス提供用IP クラスタ全体構成の構成図   今回は、HUBを用いて、1号機と2号機を接続し、同じネットワークアドレスの設定をしていきます。 仮想IPリソースを作成し、1号機と2号機にインストールしたPacemakerでリソース監視を行い、 Corosyncでノード間の状態を同期し、クラスタ通信を行います。   実際の画像です(赤枠で囲っているものがケースで覆われていますが、Raspberry Piです)   実装手順 1. 環境準備 Raspberry Pi OS ネットワーク設定(今回は固定IPにて設定) Pacemaker、Corosync、pcsインストール Raspberry Piのセットアップを2台ともに設定を入れていきます。 環境の用意ができましたら、まずは、Raspberry Pi にPacemakerとCorosyncをインストールしていきます。 1. OSアップデート  :まずRaspberry Pi のターミナルを開き、最新パッケージに更新します。 #sudo apt update #sudo apt upgrade -y  2. 必要パッケージのインストール  :PacemakerとCorosyncをインストールします。 #sudo apt install pacemaker corosync pcs -y 3. pcsdサービスの起動・自動起動設定 #sudo systemctl enable pcsd #sudo systemctl start pcsd 4. 設定完了確認 #pcs –version #pacemakerd –version #corosync -v 対象のバージョンが表示されるとOKとなります。 続いてクラスタ設定をしていきます。   2. Corosync設定 Corosyncの設定は、 /etc/corosync/corosync.conf  にて行っていきます。 以下、今回設定した内容となります。 totem {     version: 2     cluster_name: クラスタ名     transport: knet     crypto_cipher: aes256     crypto_hash: sha256     cluster_uuid:00000000-0000-0000-0000-000000000000 (※実際にはユニークなUUIDが表示されます) } nodelist {     node {         ring0_addr: 192.168.179.1         name: ラズパイ1号機         nodeid: 1     }     node {         ring0_addr: 192.168.179.2         name: ラズパイ2号機         nodeid: 2     } } quorum {     provider: corosync_votequorum     two_node: 1 } logging {     to_logfile: yes     logfile: /var/log/corosync/corosync.log     to_syslog: yes     timestamp: on } quorumセクションはクラスタノードのどちらをアクティブとするかを判定する設定がされています。 今回は2ノードのみのため、2ノードで動作できる設定を入れております。 loggingセクションは、Corosync動作時のエラーログやイベント履歴を、指定したファイルとシステムログ双方に、日時付きで詳細に残す設定が入っております。   3. クラスタ認証設定 クラスタを起動していきます。 #sudo systemctl start corosync #sudo systemctl start pacemaker 1号機と2号機のノード認証を行い、クラスタ構成を作成します。 #pcs cluster auth ラズパイ1号機 ラズパイ2号機 #pcs cluster setup –name iot-cluster ラズパイ1号機 ラズパイ2号機 #pcs cluster start –all   4. リソース設定(仮想IPリソース) 続いて、仮想IPリソースの作成をしていきます。 ここで注意点があるのですが、仮想IPリソースを作成するのは1号機のみで実施します。 実は、1号機2号機ともに作成を最初しており、上手く動作しないなーということに陥っておりましたので、 皆様はお気を付けください。 ■設定値 – 仮想IPにしたいIPアドレス :  192.168.179.100 – サブネット(netmask) : /24(255.255.255.0の場合) – リソース名 :  my-vip ■実行コマンド #pcs resource create my-vip  ocf:heartbeat:IPaddr2 ip= 192.168.179.100 cidr_netmask=24 op monitor interval=30s   ■作成後の状態確認 #pcs status 仮想IP( my-vip )が「Started on <ノード名>」のように表示されていれば成功です。 これで、ノード障害が発生したとしても、仮想IPが自動で生きているノードに引き継がれます。   これにてクラスタ設定は完了となります。   動作確認 1. スイッチオーバー(手動) クラスタの動作確認をしていきたいと思います。 まずはスイッチオーバーと呼ばれる手動にて行うリソース移動を確認していきます。 コマンドを実行して、1号機⇒2号機へ仮想IPリソースが移動するか見ていきましょう。 事前確認でリソースがどちらのノードにあるか確認します。 ■事前確認 #pcs status Cluster name: クラスタ名 Status of pacemakerd: ‘Pacemaker is running’ (last updated 2025-10-29 16:53:16 +09:00) Cluster Summary: * Stack: corosync * Last updated: Wed Oct 29 16:53:17 2025 * 2 nodes configured * 1 resource instance configured Node List: * Online: [ ラズパイ1号機  ラズパイ2号機 ] Full List of Resources: * my-vip (ocf:heartbeat:IPaddr2): Started ラズパイ1号機 Daemon Status: corosync: active/enabled pacemaker: active/enabled pcsd: active/enabled 仮想IPリソース(my-vip) の箇所に記載のあるノードが、現在、仮想IPリソースを所持しているノードになります。 そのため、現時点では ラズパイ1号機 に仮想IPリソースがあること確認できました。 それでは、1号機から2号機へリソースを移動させたいと思います。 実施方法としては、以下コマンドを実行します。 ■リソース移動コマンド実行 #pcs resource move  my-vip  ラズパイ2号機   ■スイッチオーバー後の確認 #sudo pcs status Cluster name: クラスタ名 Status of pacemakerd: ‘Pacemaker is running’ (last updated 2025-10-29 16:55:19 +09:00) Cluster Summary: * Stack: corosync * Last updated: Wed Oct 29 16:55:20 2025 * 2 nodes configured * 1 resource instance configured Node List: * Online: [ ラズパイ2号機    ラズパイ1号機 ] Full List of Resources: * my-vip (ocf:heartbeat:IPaddr2): Started ラズパイ2号機 Daemon Status: corosync: active/enabled pacemaker: active/enabled pcsd: active/enabled 仮想IPリソース(my-vip) の箇所を確認すると、 ラズパイ2号機 の表記があり、1号機から2号機へ変更されていましたので、無事スイッチオーバーが出来たことを確認しました。   2. スイッチバック(手動) 続いて、2号機⇒1号機へコマンドを実行して、仮想IPリソースを戻せるか確認します。 ■事前確認 # pcs status Cluster name: クラスタ名 Status of pacemakerd: ‘Pacemaker is running’ (last updated 2025-10-29 17:07:59 +09:00) Cluster Summary:   * Stack: corosync   * Last updated: Wed Oct 29 17:08:00 2025   * Last change:  Wed Oct 29 17:07:28 2025 by root via cibadmin on ラズパイ2号機   * 2 nodes configured   * 1 resource instance configured Node List:   * Online: [ ラズパイ2号機 ラズパイ1号機  ] Full List of Resources:   * my-vip    (ocf:heartbeat:IPaddr2):    Started  ラズパイ2号機 Daemon Status:   corosync: active/enabled   pacemaker: active/enabled   pcsd: active/enabled ■リソース移動コマンド実行 #pcs resource move my-vip ラズパイ1号機   ■スイッチバック後の確認 sudo pcs status Cluster name: クラスタ名 Status of pacemakerd: ‘Pacemaker is running’ (last updated 2025-10-29 17:13:58 +09:00) Cluster Summary:   * Stack: corosync   * Last updated: Wed Oct 29 17:13:59 2025   * Last change:  Wed Oct 29 17:13:44 2025 by root via cibadmin on  ラズパイ1号機   * 2 nodes configured   * 1 resource instance configured Node List:   * Online: [ ラズパイ1号機 ラズパイ2号機  ] Full List of Resources:   * my-vip    (ocf:heartbeat:IPaddr2):     Started ラズパイ1号機 Daemon Status:   corosync: active/enabled   pacemaker: active/enabled   pcsd: active/enabled   3. フェイルオーバー(自動) 最後の動作確認として、フェイルオーバーと呼ばれる、リソースが自動で移動されるかを確認します。 1号機で疑似障害を起こし、2号機へ仮想IPリソースが自動で移動するか確認します。 疑似障害としては、1号機-HUB間のLANケーブルを抜線し、疎通ができない状態にします。 抜線後、2号機にて確認コマンドを実行し、仮想IPリソースが移動していましたら、フェイルオーバーされていると判断します。 ■フェイルオーバー動作イメージ ■事前確認 #pcs status Cluster name: クラスタ名 Status of pacemakerd: ‘Pacemaker is running’ (last updated 2025-10-29 17:23:32 +09:00) Cluster Summary:   * Stack: corosync   * Last updated: Wed Oct 29 17:23:33 2025   * Last change:  Wed Oct 29 17:13:44 2025 by root via cibadmin on  ラズパイ1号機   * 2 nodes configured   * 1 resource instance configured Node List:   * Online: [ ラズパイ2号機  ラズパイ1号機  ] Full List of Resources:   * my-vip    (ocf:heartbeat:IPaddr2):     Started  ラズパイ2号機 Daemon Status:   corosync: active/enabled   pacemaker: active/enabled   pcsd: active/enabled ■1号機-HUB間のLANケーブルを抜線   ■フェイルオーバーされたか、仮想IPリソースの確認 # pcs status Cluster name: クラスタ名 Status of pacemakerd: ‘Pacemaker is running’ (last updated 2025-10-29 17:37:32 +09:00) Cluster Summary:   * Stack: corosync   * Last updated: Wed Oct 29 17:37:33 2025   * Last change:  Wed Oct 29 17:23:33 2025 by root via cibadmin on ラズパイ1号機   * 2 nodes configured   * 1 resource instance configured Node List:   * Online: [ ラズパイ2号機 ]   * Offline: [ ラズパイ1号機 ] Full List of Resources:   * my-vip    (ocf:heartbeat:IPaddr2):     Started  ラズパイ2号機 Daemon Status:   corosync: active/enabled   pacemaker: active/enabled   pcsd: active/enabled my-vip の箇所に無事2号機のノード名があり、フェイルオーバーの確認ができました。 また、Node Listの1号機の表示がOflineとなっており、2号機のみOnline(稼働の確認が取れている状態)となりました。   最後に Pacemaker + Corosyncを使えば、IoT環境でも高可用性を実現できることが確認できました。 LifeKeeper製品を取り扱う、LifeKeeperチームとして、今回IoT環境での冗長化や障害対応の仕組みを実際に検証していき、普段とは違う試みが出来たと感じました。 今後も色んな活用方法を実践していきたいと思います。
アバター
こんにちは。SCSKの井上です。 WEBサイトに訪れたユーザーが不満を感じる前に、問題を検出する方法はないでしょうか?せっかく訪れたユーザーが、サイトが使えない・遅いといった理由で離れてしまうと、企業のブランド価値低下や機会損失につながります。そこで、New RelicのSynthetic Monitoring(外形監視)を使って、影響が拡大する前に継続的に監視し、問題を早期に発見する一助になれば幸いです。   はじめに 外形監視を導入することで、稼働率や応答速度をはじめとするデータを可視化することができます。リンク切れやページ表示の遅延で気づいていたらユーザー離れが起きていた事態を防ぐためにも、チェックを自動化して障害や問題を早期に発見することが大切になってきます。New Relicは日本だけではなく世界の拠点から外形監視を実行できるため、グローバルにアクセスされるサイトの品質管理にも対応できます。この記事では7種類の外形監視の使い方について解説していきます。   外形監視でできること 外形監視は、ユーザー視点でWebサイトやAPIの可用性やパフォーマンスを外部からチェックする仕組みです。実際のユーザーアクセスと同じ状況を再現することで、問題を早期に発見することができます。New Relicの外形監視では以下のような機能が実現できます。 機能 説明 可用性チェック WebサイトやAPIの稼働状況をPingやHTTPリクエストで確認 APIテスト REST APIやGraphQLのレスポンスコード・内容を検証 ブラウザ操作の再現 スクリプト化されたブラウザモニターでログインやフォーム入力を再現 パフォーマンス測定 ページロード時間やAPIレスポンス時間を計測 グローバル監視 世界中の複数ロケーションからテストを実行し、地域別の応答速度を確認 エラー検知と通知 HTTPステータスやレスポンス異常を検知し、アラートを発報   New Relic実践入門 第2版 オブザーバビリティの基礎と実現 | 翔泳社 あらゆるデータを収集・分析・可視化して、システム/サービスの変化に能動的に対処せよITシステムやサービスが複雑化する現代において、オブザーバビリティ(Observability:可観測性)という考え方が極めて重要になっています。オブザーバビ... www.shoeisha.co.jp 外形監視 | コードをテストして改善する Synthetics テストを作成してグローバルトラフィックのシミュレーション、エンドポイントの稼働時間を測定して、可用性の問題を解決します。お客様に影響を与える前にすべて本番前環境で実行します。 newrelic.com   外形監視を始める前に 外形監視を設定する際に、無料で利用できる範囲や、注意すべきポイント、さらに設定時によく使われる用語について解説します。 外形監視の実行可能回数 無料枠では、外形監視の実行可能回数は月500回までです。なお、契約プランによって外形監視の実行可能枠は異なります。 ただし、Ping監視については実行回数のカウント対象外です。外形監視は複数ロケーションから実行でき、 1ロケーションにつき1回としてカウント されます。例えば東京とロンドンで1分間隔で監視すると、1分で2回、1時間で120回となり、ロケーションが増えるほど実行回数も増えます。そのため、優先地域に絞ってロケーションを選定することが重要です。また、外形監視の ブ ラウザ実行環境(Browser)でChromeとFirefoxを選択、デバイステスト(Device Emulation)でモバイルとデスクトップなど複数選択した場合も、それぞれに実行回数がカウント されます。実行上限を超える場合、設定時に以下の画面が表示されます。   外形監視の設定を保存する前に、意図した通りに外形監視が動作するかを検証する「Validate」というボタンがあります。これについては、チェックを行う前の動作確認の建付けとなっているため、実行回数のカウント対象外です。   外形監視の使用制限と使用状況の追跡 | New Relic Documentation The number of New Relic synthetic monitor checks that are included per month with each pricing edition. docs.newrelic.com   Device Emulation(ブラウザベースのデバイステスト) この後に説明するSimple BrowserやScripted Browserで利用できるオプション設定で、ChromeやFirefoxのエミュレーション機能を使って、モバイルやタブレットでの異なるデバイスで画面表示をテストできます。ただし、各デバイスとのネットワーク速度やOSは再現できないため、同じサイトでも表示速度やJavaScriptの実行処理の差がでます。画像やテキストが正しく読みこまれているか、ボタンは押せる位置にあるかなどは確認できます。より詳細にテストしたい場合は、実機を用いて打鍵も考慮する必要があります。   デバイス エミュレーション | New Relic Documentation Emulating mobile or tablet devices in browser based synthetic monitors docs.newrelic.com   ユーザ体験の可視化指標:Apdex アプリケーションのパフォーマンスに対するユーザー体験を数値化する指標としてApdexがあります。1.0に近いほど、ユーザー体験は問題ないとされています。以下についてはベンダーごとに評価基準は異なります。 Apdex 値の範囲 評価( Rating) 0.94 ~ 1.00 Excellent(非常に良い) 0.85 ~ 0.93 Good(良い) 0.70 ~ 0.84 Fair(普通) 0.50 ~ 0.69 Poor(悪い) 0.00 ~ 0.49 Unacceptable(許容外)   Application Performance Index – ApdexTechnical Specificationの資料によると、計算式については以下と定義されています。 Apdex(T) = (Satisfied count + (Tolerating count ÷ 2)) ÷ Total samples 不満と感じるのは満足の閾値から4倍の値と上記資料で報告されています。計算する際は満足・許容・不満の3つのカテゴリに分けられています。 満足(Satisfied)      :レスポンスタイム ≤ T 許容(Tolerating)    :T < レスポンスタイム ≤ 4T 不満足(Frustrated):レスポンスタイム > 4T 実際の計算式についてNew Relicの公式サイトを参考に算出します。今回、外形監視を例に、ログインからログイン完了後のページを表示する際に満足できるレスポンスタイムを3秒(=T)とします。 満足(Satisfied)      : レスポンスタイム ≤  3秒 許容(Tolerating)    :3秒 < レスポンスタイム ≤ 12秒 不満足(Frustrated):レスポンスタイム > 12秒   100回測定した結果が以下となったとします。 満足数:60回 許容数:30回 不満足 :10回 これらを先ほどの式に当てはめてみると、Apdex(T3)=(60+(30÷2))÷100 =0.75となりました。0.75はApdexの範囲で示すと”普通”に該当します。ただし、この基準はあくまで目安です。ユーザー体験はレスポンスタイム以外にもユーザーインタフェースのわかりやすさや、機能の充実度などにも影響します。普段とは大きくApdexスコアが下がっているなど、傾向と合わせて確認することで効率的に活用できます。   参考: https://www.apdex.org/index.php/documents/   Apdex:ユーザー満足度の測定 | New Relic Documentation New Relic uses Apdex to measure whether users are satisfied, tolerating, or dissatisfied with your app's response time. docs.newrelic.com   外形監視の導入と設定 New Relicでは、Webサイトのパフォーマンスを多角的に検証できる 7種類のSynthetic Monitoring(外形監視) が用意されています。これらのモニターは、単純な死活確認から複雑なユーザー操作のシナリオ再現まで対応しています。ここでは、各モニターの設定方法や活用シーンを解説していきます。 種類 機能概要 主な用途 Ping(死活監視) URLにリクエストを送り、応答を確認(軽量) サイトの死活監視、基本的な可用性チェック Simple browser(ページ表示速度監視) ページをブラウザで開き、レンダリング確認 ページ表示確認、JavaScript実行確認 Step Monitor(ノーコード監視) コード不要で複数操作を設定可能 ログインやフォーム入力など簡単なユーザーフロー確認 Scripted browser(ユーザ操作監視) JavaScriptで高度な操作をカスタマイズ ログイン確認、E2Eテスト Scripted API(API監視) APIエンドポイントにリクエストを送りレスポンス検証 APIの正常性監視、エンドポイント監視 Certificate Check(SSL証明書監視) SSL証明書の有効期限を監視 セキュリティ維持、証明書期限切れ防止 Broken Links Monitor(リンク切れ監視) ページ内リンクの正常性を確認 UX品質維持   Syntheticモニターの概要 | New Relic Documentation New Relic synthetic monitoring capabilities give you automated, scriptable tools to monitor your websites, critical busi... docs.newrelic.com   Availability – Ping(死活監視) URLの死活監視など、もっとも単純な監視方法です。月内の実行可能回数枠については対象外となっています。 1.左ペインより「Synthetic Monitoring」>「Monitors」より「Create monitor」をクリックします。 2.監視種類Availability – Pingを選択します。 3.以下の設定内容※を参照の上、「Select locations」をクリックします。 4.New Relic の外形監視(Synthetic Monitoring)で監視拠点を選びます。設定後、「Save monitor」をクリックします。 5.設定した監視間隔で外形監視が実行されます。       ※設定内容 項目名 意味・用途 Name (required) 外形監視の名前。 URL (required) 監視対象のURL。 Period 監視の実行間隔。例:1分、5分、15分など。 Text validation (optional) レスポンスに含まれるべき文字列を指定。指定文字列が含まれないと失敗と判定。 ApdexTarget (optional) パフォーマンス評価指標(Apdex)の目標値。 Verify SSL SSL証明書の検証を有効にするかどうか。チェックすると証明書の有効性も確認。 Bypass HEAD request HEADに対応していないシステムに対してHEAD+Bodyを確認する。 軽量な死活監視、サーバー負荷を避けたい場合:チェックなし 特定の文字列が表示されているか検証したい場合:チェックあり Redirect is failure リダイレクトが発生した場合に失敗とみなすかどうか。 URLがそのまま使える状態であることを確認とする場合:チェックあり リダイレクトが仕様として許容されている(例:HTTP→HTTPS)場合:チェックなし Custom headers リクエストに追加するカスタムHTTPヘッダー。キャッシュを無効化、APIキーなどを含める場合に使用。 Tags モニターにタグを付けて分類・検索しやすくする。形式は key:value。   Page load performance – Simple browser(ページ表示速度監視) 指定したURLを実際のブラウザで開き、ページの読み込みや基本的な表示を確認する外形監視です。Webページがブラウザで正常に表示されるかどうかを確認するなどに使われます。 1.左ペインより「Synthetic Monitoring」>「Monitors」より「Create monitor」をクリックします。 2.監視種類Page load performance – Simple browserを選択します。 3.以下の設定内容※を参照の上、「Select locations」をクリックします。 4.New Relic の外形監視(Synthetic Monitoring)で監視拠点を選びます。設定後、「Validate」をクリックします。 5.ページの読み込み時間がタイムラインで表示されます。外形監視を保存する場合は、「Save monitor」をクリックして完了です。       ※設定内容 項目名 説明 Name (required) 外形監視の名前。 URL (required) 監視対象のWebページのURL。 Period 外形監視の実行間隔。例:「15 mins」は15分ごとに監視を実行します。 Tags 外形監視にタグを付与して分類や検索をしやすくします。形式は key:value。 Text validation (optional) ページ内に特定の文字列が含まれているかを確認するための文字列を入力。HTTPステータスコードだけではなく、特定の文字も表示されていることをもって成功としたい場合に使用。 ApdexTarget (optional) パフォーマンス評価指標(Apdexスコア)の目標値。 Verify SSL SSL証明書の有効性を確認するオプション。チェックを入れるとHTTPS証明書の検証を行います。 Enable screenshot on failure and in script 外形監視失敗時にスクリーンショットを取得するオプション。どこで失敗したのかを確認することができる。デフォルトで有効となっています。 Custom headers HTTPリクエストに追加するカスタムヘッダー。認証や特定のAPI利用時に必要。Nameにヘッダー名、Valueに値を入力。   User step execution – Step Monitor(ノーコード監視) ユーザーがサイトで行う一連の操作を、順番に自動で試して問題がないか確認する外形監視です。ログインIDとパスワードを入力して、ログインが問題なくできるかを確認などに使われます。 1.左ペインより「Synthetic Monitoring」>「Monitors」より「Create monitor」をクリックします。 2.監視種類User step execution – Step Monitorを選択します。 3.以下の設定内容※を参照の上、「Select locations」をクリックします。 4.New Relic の外形監視で監視拠点を選びます。設定後、「Define steps」をクリックします。 5.ノーコードでWebアプリのユーザー操作をGUI上からステップ形式で設定します。 6.保存前にスクリプトに問題がないか動作確認するため、「Validate」をクリックします。 7.Successが表示されていれば、スクリプトに問題なく実行できる状態です。「Save monitor」をクリックして完了です。 【補足】スクリプトに問題がある場合は、問題個所とともにエラーキャプチャが表示されます。   ※設定内容 項目名 説明 Name (required) 外形監視の名前。 URL (required) 監視対象のWebページのURL。 Period 外形監視の実行間隔。例:「15 mins」は15分ごとに監視を実行します。 Tags 外形監視にタグを付与して分類や検索をしやすくします。形式は key:value。 ApdexTarget (optional) パフォーマンス評価指標(Apdexスコア)の目標値。 Enable screenshot on failure and in script 外形監視失敗時にスクリーンショットを取得するオプション。どこで失敗したのかを確認することができます。デフォルトで有効となっています。   User flow / functionality – Scripted browser(ユーザ操作監視) ユーザ操作をスクリプトを使ってサイトの動作を監視する外形監視です。ECサイトの購入フロー(商品検索→カートに入れる→ログイン→購入等)が問題なく遷移できるか、一連のシナリオテストを確認するなどに使われます。 1.左ペインより「Synthetic Monitoring」>「Monitors」より「Create monitor」をクリックします。 2.監視種類User flow / functionality – Scripted browserを選択します。 3.以下の設定内容※を参照の上、「Select locations」をクリックします。 4.スクリプトを記載後、動作確認をするために「Validate」をクリックします。 5.Successと表示されていれば、スクリプトは正常に動作しています。「Save monitor」をクリックして完了になります。 【補足】スクリプトに問題がある場合は、Script Logから該当の行付近を確認し、修正を行います。   ※設定内容 項目名 説明 Name (required) 外形監視の名前。 Period 外形監視の実行間隔。例:「15 mins」は15分ごとに監視を実行します。 Tags 外形監視にタグを付与して分類や検索をしやすくします。形式は key:value。 ApdexTarget (optional) パフォーマンス評価指標(Apdexスコア)の目標値。 Enable screenshot on failure and in script 外形監視失敗時にスクリーンショットを取得するオプション。どこで失敗したのかを確認することができる。デフォルトで有効となっています。   スクリプト化ブラウザモニターの概要 | New Relic Documentation How to create scripted browsers, which send Selenium browsers to your website to test key workflows such as login or sea... docs.newrelic.com   Endpoint availability – Scripted API(API監視) 外部APIの応答時間・可用性を定期的にチェックし、遅延や障害の発生有無を確認する外形監視です。Synthetics REST APIは 1秒あたり3リクエストまでの制限となっています。制限を超えた場合、429レスポンスコードを返します。 1.左ペインより「Synthetic Monitoring」>「Monitors」より「Create monitor」をクリックします。 2.監視種類Endpoint availability – Scripted APIを選択します。 3.以下の設定内容※を参照の上、「Select locations」をクリックします。 4.スクリプトを記載後、動作確認をするために「Validate」をクリックします。 5.Successと表示されていれば、スクリプトは正常に動作しています。「Save monitor」をクリックして完了になります。       ※設定内容 項目名 説明 Name (required) 外形監視の名前。 Period 監視の実行間隔。例:「15 mins」は15分ごとに監視を実行します。 ApdexTarget (optional) パフォーマンス評価指標(Apdexスコア)の目標値。 Runtime スクリプト実行環境をプルダウンメニューから選択。古いスクリプトの場合、最新Nodeで動かない場合があるので、動作確認のValidateを実行して確認。 Tags 外形監視にタグを付与して分類や検索をしやすくします。形式は key:value。   Synthetics REST API | New Relic Documentation Use the New Relic synthetics REST API to create, delete, and manage synthetic monitors. docs.newrelic.com   合成APIテストを記述する | New Relic Documentation Use API test scripts to ensure your API endpoint is functioning correctly. docs.newrelic.com   SSL certificate expiration – Certificate Check(SSL証明書監視) SSL証明書の有効期限や有効性を監視する外形監視です。証明書が切れるとブラウザに警告が表示され、ユーザー離脱や企業の信頼低下につながるため、事前に検知して防ぎます。 1.左ペインより「Synthetic Monitoring」>「Monitors」より「Create monitor」をクリックします。 2.監視種類SSL certificate expiration – Certificate Checkを選択します。 3.以下の設定内容※を参照の上、「Select locations」をクリックします。 4.ロケーションを選択後、動作確認をするために「Validate」をクリックします。 5.Successと表示されていることを「Save monitor」をクリックして完了になります。 【補足】設定した有効期限を下回っている場合は、以下の画面が表示されます。   ※設定内容 項目 意味 Name (required) 外形監視の名前。 Domain (required) チェック対象のドメイン名。SSL証明書の有効期限を確認したいURLを指定します。 Days remaining until expiration (required) アラートを出すまでの残り日数のしきい値。 例:30 → 証明書の有効期限が30日未満になったら通知 Period 外形監視の実行頻度。どれくらいの間隔でチェックするかを設定します。   Page link crawler – Broken Links Monitor(リンク切れ監視) 商品ページや決済ページへのリンク、掲載サイトから外部サイトへのリンクが正しく動作しているかどうかを定期的に確認する外形監視です。リンク切れによるユーザー離れやメンテナンスへの信用低下を防ぎ、ユーザー体験を損なわないようにします。 1.左ペインより「Synthetic Monitoring」>「Monitors」より「Create monitor」をクリックします。 2.監視種類Page link crawler – Broken Links Monitorを選択します。 3.外形監視の名前、対象のURL、実施間隔を入力後、「Select locations」をクリックします。ApdexとTagsは任意項目になります。 4.どのロケーションから外形監視をするかを設定し、「Validate」をクリックします。 5.リンク切れがない場合はSuccessと表示されます。 外形監視を実施する場合は、「Save monitor」をクリックします。 【補足】リンク切れがある場合は、Failedと表示され、Script Logに該当のURLが記載されています。このまま外形監視を実施する場合は、「Save monitor」をクリックします。   モニターの追加と編集 | New Relic Documentation Synthetic monitoring: how to add or edit ping monitors, simple browser monitors, scripted browser monitors, and API test... docs.newrelic.com   Secure credentials Secure credentialsは、 パスワードなどのセキュアな情報を管理し、外形監視のスクリプト内で参照できる仕組み です。セキュアな情報をスクリプト内に直接記載しないことで、漏えいリスクを低減することができます。また、複数のスクリプトを管理する場合は、変数で記述することで認証情報を一元管理ができます。 一度作成したkey名は固定で、後から編集できるのは値(value)と説明(description)のみになりますので、key名を変更したい場合は、作り直す必要 があります。値の変更後、個々のスクリプトで使用しているKeyの修正は不要で反映されます。この機能は、Scripted browser、Scripted API、およびStep Monitorで使用できます。 作成方法 1.Synthetic MonitoringよりSecure credentialsを選択後、Create secure credentialをクリックします。 2.変数名(Key)及び、値(Value)を入力します。必要に応じて説明を入力後、「Save」をクリックします。 3.ブラウザの更新を実施することで、作成されたSecure credentialsが一覧に表示されます。       利用方法 1.対象の外形監視を開き、「Insert secure credential」をクリックします。 2.作成されているsecure credentialの一覧が表示されますので、使用したいkeyをクリックします。 3.スクリプト内に対象のKeyが$secure.KEY_NAMEの形式で表示されます。       スクリプト化されたブラウザやAPIテストのための安全な認証情報の保存 | New Relic Documentation Use secure credentials with synthetic monitoring to store critical information, such as passwords, API keys, usernames, ... docs.newrelic.com   外形監視の見方 ここまでで、7種類の外形監視について、それぞれの利用用途と設定方法を解説してきました。次は、実際に設定した外形監視の結果をどのように確認すべきかを見ていきます。 Monitors画面 複数の外形監視を運用している場合、過去24時間の成功率や失敗したロケーションを一覧で確認できます。どのモニターで問題が発生しているかを素早く把握することができます。また、Alert statusの色分け(赤・緑・グレー)によって、障害有無を即座にわかります。この画面では以下のことが確認できます。 Alert status (Name欄の六角形) 緑:未解決のインシデントなし 赤:インシデント進行中 グレー:アラート条件なし Monitor status :監視がEnabled(有効)、Disabled(無効)の状態確認 Success rate (24 hours) :24時間以内のモニターチェック成功の割合 Locations failing :監視失敗したロケーション数 Period :監視の実行頻度 Monitor type :監視の種類   シンセティック・モニター・インデックス | New Relic Documentation You can view a summary of your monitors' uptime and average performance and to access monitor details in New Relic's syn... docs.newrelic.com   Summary画面 サマリー画面では、外形監視の実行単位で障害の特定や改善策の検討を確認する画面です。一覧画面では全体の外形監視の実行状態を確認することに対して、サマリー画面では、外形監視単位で詳細に確認する位置づけです。 この画面では、外形監視の再実行を実施することができます。ネットワークや外部サービスの一時的な不具合で外形監視が失敗しているのか、サーバの設定変更などで構成変更後、外形監視が正しく実行できているかなど、今すぐ確認したい場合は「Run check」をクリックして確認できます。 外形監視の種類によって表示されるグラフは異なりますが、主な確認できる項目は以下の通りです。 グラフ項目 意味 利用シーン Error response codes HTTPステータスコード(200以外)を表示 エラー発生箇所を確認し、原因を特定 Average size by resource type HTML、CSS、JavaScript、画像などの平均サイズを表示 ページの重さや最適化の必要性を把握 Duration by domain 各ドメインごとの処理時間を表示 遅延の原因となるドメインを分析 Total requests by domain ドメインごとのリクエスト数を集計 過剰なリクエストなどを確認 Performance timings DNS、SSL、接続、送信、待機、受信のページ読み込みに関わる全体の流れの時間を表示 ボトルネックを特定 Request & response time リクエスト送信からレスポンス受信までの時間 ネットワーク応答速度を評価 Connection times DNS、SSL接続などの時間 接続関連の遅延要因を分析     シンセティック・モニタリング概要ページ | New Relic Documentation Use the Overview page to understand your monitor's overall performance, and to quickly access interesting monitor result... docs.newrelic.com   Results画面 サマリー画面で全体の傾向を把握後、主に実行結果を詳細を深堀していく際に使用する画面です。どのタイミングで失敗しているのか、特定のロケーションで遅延しているのか、継続的に外形監視が失敗しているのかを確認できます。検索ボックス横のLocationより特定の場所の結果だけを表示/非表示することができます。外形監視の成功や失敗の一覧画面が表示されています。赤枠の一覧内の該当のタイムスタンプをクリックすることで、以下のことが確認できます。 ページ全体のパフォーマンス状況                                           (Bytes Transferred:ページサイズ、Requests:発生したHTTPリクエストの総数、Total time:読み込み完了時間) 画像やJavaScriptのどのリソースが遅いか エラーが発生したリソースの特定 ウォーターフォール形式での読み込み順序と並列性の確認   シンセティック・モニタリング。個々のモニターランにアクセス | New Relic Documentation Use the synthetics results page to quickly access interesting monitor results, and to sort your results by location and ... docs.newrelic.com   Resources画面 主にこの画面はページの読み込み速度が遅いときに詳細な深堀をするために使用します。ページ読み込みのボトルネックをHTML、CSS、JavaScript、画像などのリソース単位で確認することができます。Resource画面を開くと左側のリストに平均ダウンロード時間が遅い順にソートされています。右側では時系列でパフォーマンスの変化が表示されています。どのリソースタイプが時間がかかっているのかを確認することができます。左側のリストをクリックすると、該当のリソースのダウンロード時間に関する情報が確認できます。ロケーションの問題か、特定の時間帯に遅延が見られるのかなどを確認できます。さらにクリックすると該当のリソースのHTTPリクエストの詳細とレスポンスタイムの内訳を確認することができます。DNSやSSLの接続に問題があるのか、サーバの処理速度に問題か、ネットワーク帯域が狭い、距離が遠いなどの問題を詳細にドリルダウン形式で分析することができます。   シンセティックモニタリング。ロードタイムの把握 | New Relic Documentation Use the Resources page to understand how your website's resources perform. Compare usage across resources, or view indiv... docs.newrelic.com   編集画面 外形監視の編集画面では、監視対象のURLの変更、スクリプトの修正、監視実行の有効無効化、頻度、ロケーションの変更などが実施できます。 該当の外形監視を開き、「General」を開きます。編集はこの画面で行います。監視実行を無効化する場合は「Monitor enabled」のチェックを外します。編集完了後は、「Validate」を実行して、問題がいないことを確認してから、「Save monitor」をクリックします。 【補足】外形監視を複数修正した場合は、上部の外形監視名のプルダウンメニューから対象の監視名を選択することで該当の編集ページに遷移します。これにより、外形監視の一覧画面に戻らずに該当の外形監視の詳細ページを確認することができます。   Location status画面(各地域の障害ステータス) 該当のロケーションでネットワークの問題や障害が起きているのかを確認することができます。この画面で特定の地域のみ発生しているのか、全地域に発生しているのかを切り分けることができます。サービスは正常に起動しているが、外形監視の失敗が突然連続している場合は、下記のステータスを確認します。   New Relic プラットフォームに関する障害ステータス情報は以下で確認できます。 New Relic Status Welcome to New Relic's home for real-time and historical data on system performance. status.newrelic.com   参考:プライベートロケーション 通常はインターネット上の公開サーバーを監視しますが、社内ネットワークやファイアウォールの内側にあるシステムは外部からアクセスできません。自分の会社のネットワーク内から監視する場合は、プライベートロケーション機能を使うことで実現できます。この機能を使うには、コンテナを使う必要があります。この記事では、概要のみの説明とし、詳細は別の記事で解説します。 プライベートロケーションの監視 | New Relic Documentation Use New Relic's synthetic private locations with New Relic's alerts to be notified if a location is under-provisioned, m... docs.newrelic.com   さいごに この記事では、Synthetic Monitoring(外形監視)について、利用できる監視方法や設定手順、結果の見方までを解説しました。New Relicには多彩な外形監視機能があります。本記事を参考に、外形監視を気軽に始めていただき、今後のUX改善やパフォーマンス最適化に役立てていただければ幸いです。 SCSKはNew Relicのライセンス販売だけではなく、導入から導入後のサポートまで伴走的に導入支援を実施しています。くわしくは以下をご参照のほどよろしくお願いいたします。
アバター
全くの未経験者がアプリケーション開発手法を習得するまでに、どのくらい時間がかかるでしょうか? まずプログラミング言語、動作のロジックを学び・・・最低でも2~3年の修業期間が必要そうですよね。 未経験者である自分は時間も根気も足らず長年手を出せずにいましたが、「AIに全部やってもらったら出来るのでは?」ということでGeminiとGoogle Cloudを使ってみたところ、なんと 数時間 で出来てしまいました。 この記事では、未経験者の自分がアプリ開発するために使った手法と、Google Cloudのサービスをご紹介します。 知識経験ゼロだけどやってみたい!という方の参考になれば幸いです。 ※最新情報については公式ドキュメントをご参照ください。 AIアプリケーション開発の道のり 前提として、自分は アプリ開発の経験なし、コーディング経験もほぼなし のインフラエンジニアです。 こんな状態でのスタートでしたが、Geminiに丸投げしてみたところ開発の順序と具体的な方法を提示してくれたので、実際その通りに進めることでアプリ開発ができました。 以下が今回試してみた流れです。 1.作成したいアプリを考える 2.Vertex AI(Gemini)でコード生成する 3.Cloud Shellでファイル作成し、コードを転記する 4.Cloud Runへデプロイする →アプリケーション公開完了!   実際に作ってみる 作成したいアプリを考える まずは「どんなアプリケーションを作るか」です。日常の困りごとから考えてみました。 我が家は1週間分の食材をまとめ買いしているのですが、週の後半になるにつれて食材の種類が減っていくので献立を考える難易度が上がっていきます。 この困りごとを解消するアイディアをGeminiに壁打ちし、 「食材とジャンル(和洋中)を入力すると、Geminiが即座にレシピを提案する Web アプリ」 に決定しました!   Vertex AI(Gemini)でコード生成する コードは Vertex AI Studioのチャット機能 で一から作成することが可能です。 Vertex AIとは、Google Cloudが提供する 機械学習(ML)のための統合プラットフォーム です。 開発者が高性能なAIモデル(Geminiなど)を利用し、アプリケーションに組み込むことができます。 今回のアプリ作成においては「レシピ考案する」というアプリの頭脳となる部分を担うのと同時に、「コードの生成」もしてもらいます。 まず、Vertex AI Studioの[チャット]から、必要なコードを作成してもらうための依頼をします。 コード作成を頼すると、ファイル構成やファイルの中身のコードを回答してくれます。 ただ、こちらをそのままアプリのコードとして利用したところ、こちらが伝えたい内容が上手くVertex AIに伝わらなかったようで、 思った通りにアプリを動かすのにかなり時間がかかりました。 精度を高めるためには、 あらかじめ別のGeminiに作りたいアプリと仕様について伝えた上で「Vertex AIでコード生成するための依頼文」を作成してもらい、 それをVertex AIへの依頼文として採用する 形が手っ取り早くおススメです。 Geminiに事前にやりたいことを相談した上でVertex AIに依頼したのが以下の画面です。具体的に指示を出すことで、コード生成の精度が上がりました。 Vertex AIからの回答で、アプリケーションの土台となる PythonとHTMLのコードを一式生成出来ました。   Cloud Shellでファイル作成し、コードを転記する コードが出来たので、アプリにデプロイするための環境を準備します。これには Cloud Shell を使います。 Cloud Shellは、 Webブラウザ上で動作する統合開発環境 です。 特別な環境を用意しなくとも、すぐにターミナル・エディタが利用できます。 Google Cloud コンソールのツールバーにあるエディタボタンにカーソルを当てると「Cloud Shellをアクティブにする」という文字とともに承認確認画面が表示され、承認することでCloud Shellが起動します。 エディタ画面でフォルダを新規作成し、新規ファイルにVertex AIが生成したコードをコピー&ペーストします。 必要に応じてプロジェクト IDやリージョンなどの設定を修正し保存します。 (Vertex AIのコードには、コメントアウトで「環境に合わせてプロジェクトIDとリージョンを設定してください」とメモが残されていました。わかりやすい!)   Cloud Runへデプロイ ファイルの準備が整ったのでいよいよデプロイです。 インフラエンジニアには馴染のないデプロイですが、こんなに簡単にアプリケーション作成して公開できるものなの?という疑念は残ります。 ここで実施するのは、 Cloud Shell上でデプロイコマンドを実行すること のみです。 こんな簡単にできるのか・・・!?これを実現するのが Cloud Run というフルマネージドのサーバーレスプラットフォームです。 Cloud Runは、 Webアプリケーションをコンテナとして実行するためのフルマネージド環境を一括で提供 します。 作ったアプリをイメージ化してそのままCloud Runに載せるだけで公開できます。 本来、Cloud Runでアプリケーションを動かすには、コードを コンテナイメージ に変換し、レジストリサービスにファイルを登録する作業が必要です。 ですが、このデプロイコマンドに–sourceなどのオプションのコマンドを組み込むことによって、デプロイに必要な関連するリソース作成・設定などをデプロイと同時に自動でおこなってくれるのです。 なんという便利さ・・・! Cloud Shellのターミナルから「gcloud run deploy」のコマンドを実行し、Cloud Runに対して「このフォルダ(–source .)にあるコードを使って recipe-app-blogという名前のサービスとして公開してほしい」と命令します。 デプロイが成功し、サービスURLが発行されました。 デプロイ完了後、Cloud Runのサービス画面に遷移すると、先ほどデプロイコマンドで指示した通り「recipe-app-blog」というリソースができています。 URLが生成されるので、このURLを開くとアプリケーションが見れるはず・・・! URLを開くと、アプリケーションが表示されました! 早速、冷蔵庫に余っている食材と食べたいジャンルを入力すると・・・ レシピを提案してくれました。アプリケーション作成成功です! Webアプリの中身を修正したい場合は、Cloud Shellのターミナル画面で geminiコマンドを実行 することで 直接Geminiを呼び出し 対話形式でコードを修正することも可能 です。   トラブルシューティング奮闘編 上記の流れで簡単にアプリ公開ができたように見えますが(実際簡単ではありましたが)、いくつか引っかかったポイントがあったのでトラブルシューティングに使えるサービスもご紹介します。   デプロイの中のビルドが失敗 Cloud Shellでのデプロイ実行時に、ビルドが失敗した旨のエラーが発生しました。 デプロイの処理の中に含まれているビルドの段階で失敗した場合は、ビルドに使用されるサービスである Cloud Build の履歴からエラー内容を見ることができます。 ステータスが失敗になっているビルドのログを見ると、 ビルドの中のどのステップで何が原因で失敗したのか を見ることができます。 自分の場合は、作成した一部のファイルの中身に余計な文字列が入ってしまいビルドが失敗していたようでした。   デプロイ成功したのに、URLが開けない 続いて、デプロイは成功したのに、URLを開いてみるとアプリケーションが表示されない、という事象です。 このような場合は Cloud Runのエラーログ 確認が有効です。 Cloud Runの[オブザーバビリティ]>[ログ]で重大度を「エラー」に絞り、ログを見てみます。 ぱっと見で中身が分からなかったのでGeminiに聞いてみたところ、Pythonの構文エラーということが判明し、場所を特定後修正すると解消されました。   URLは開けたが、アプリケーション動作が失敗する 最後は、アプリで回答を得ようとすると肝心の回答が返ってこずにエラーとなるパターンです。 これはぱっと見で権限エラーっぽいことがわかりました。 詳細をGeminiで確認したところ、 アプリがVertex AI にアクセスするための許可が不足している 様子です。 必要な権限を確認し、アプリを動かすサービスアカウントにVertex AIで必要な権限を追加します。 権限不足はあらゆる場所で発生しかなり引っかかったポイントなので、エラーが発生した場合は真っ先に疑うと良いと思います。   おわりに 今回初めてアプリ開発をしてみて、AIへの指示(プロンプト)をいかに的確におこなえるかが、作業を効率化・品質を高める鍵となることがよくわかりました。 そして何より、全くの未経験でもアプリ開発ができるすごさ!!わからないところはGeminiに教えてもらい自分の知識も深めながら、トライ&エラーで手軽にアプリ開発ができました。 さらに今回は、Google Cloudの無料トライアル(90日、クレジット300ドル) の範囲でまかなうことができ、コスト面でも安心して挑戦できました。 「作りたいものはあるけど実現する技術がない・・・」と諦めていた方は、ぜひVertex AI と Cloud Run を使ってアイディアを形にしてみてください! 最後までお読みいただきありがとうございました。
アバター