電通総研のブログ - TECH PLAY

TECH PLAY

電通総研

電通総研 の技術ブログ

全867件

こんにちは!金融ソリューション事業部の孫です。 現在、我々はChatGPT全般の活用を積極的に検討しており、その多様な可能性の中には メタバース におけるChatGPTの利用も含まれています。 この観点から、 AWS 上にサーバーレス アーキテクチャ を採用したChatGPT活用アプリケーションの設計と構築を実施いたしました。 はじめに インフラストラクチャの全体像 実装手順 構築手順 事前準備 手順1. Lambda関数の作成 手順2. DynamoDBの作成 手順3. WebSocket API Gatewayの作成 手順4. SNSトピックの作成 機能検証 セッションテスト 複数のクライアントが同時にセッションを持つテスト 終わりに はじめに ChatGPTベースのアプリケーションを構築する際には、2つの一般的な選択肢があります。 一つは既存のアプリケーションにOpenAI API を直接統合すること、もう一つはOpenAI API をラップしてインフラサービス化にすることです。 今回は、以下の点を考慮して、後者の選択をしました: セキュリティリスク:アプリケーション側でOpenAI API Keyを管理する必要があること コスト管理:OpenAIとのやり取りは有料で、ユーザーの質問の頻度と単語数を制御する必要があること 再利用可能性:開発したソリューションは他のプロジェクトに適用可能で、コストを節約できること 今回は、インフラスト ラク チャを設計する前に、以下の要件を明確にしました: 複数のユーザーが同時に一つのOpenAIアカウントを使用できること 従量課金制を実装し、コストを削減すること サーバーの維持コストを削減すること API トラフィック 制御を実装すること OpenAIへのリク エス トの同時実行数を制限すること これらの要件に基づいて、今回は以下のインフラスト ラク チャ設計を完成させました。 インフラスト ラク チャの全体像 本記事では、下記の構成図に基づき、構築作業を進めていきます。 WebSocket API Gateway :クライアントのリク エス トをバックエンドサービスにルーティングするために使用します。 API リク エス トの トラフィック 制御ができます HTTPの30秒の タイムアウト 制限を解決し、503エラーを減らすために、WebSocket接続方式を選択しました meta_connect_handler :ユーザーの認証機能を提供します。 本記事では、インフラ構築に焦点を当てるため、認証に関する実装は対象外としております meta_handler_chat :ユーザーのリク エス トを Amazon SNS サービスに転送する機能を提供します。 ユーザーのリク エス トは SNS を介して処理されるため、OpenAIサーバーへの即時リク エス トが不要となり、非同期処理になります meta_chat :ユーザーからのリク エス トをOpenAIサーバーに送信し、その結果を受け取る機能を提供します。 本記事においては、 LangChain (version: 0.0.317) フレームワーク を活用して、OpenAI API を介してOpenAIとのやり取りを行います LangChain フレームワーク を使用することで、OpenAI API を直接利用することなく、LLM(Large Language Models)アプリケーションの開発を高速化できます ただし、LangChainのバージョン更新は頻繁に行われるため、本記事で使用している API が将来的に非推奨(deprecated)になる可能性にご注意ください。そのため、特定のバージョンを固定することをお勧めします。 meta_disconnect_handler :ユーザーがログアウトした後、その会話履歴を削除する機能を提供します。 Dynamodb :ユーザーの会話履歴を保存するテーブルを作成します。 SNS :ユーザーのリク エス トを非同期に処理するために使用します。 上記の AWS アーキテクチャ 図に記載した番号①〜⑨に沿って、処理の流れを説明します。 ①: ユーザーはWebSocket URL接続を介してChatGPTサービスの利用を開始する ②: 接続は最初にWebSocketのデフォルトの /$Connect ルートにルーティングされ、 meta_connect_handler で接続の認証を実施する ③: ユーザーは /sendprompt ルートを通じてチャット内容を meta_handler_chat に送信する ④: meta_handler_chat が処理した後、ユーザーリク エス トは SNS サービスのトピックに送信する ⑤: SNS はユーザーリク エス トを サブスクリプション meta_chat Functionに送信する ⑥: meta_chat は Langchain を利用し、OpenAIとの対話機能をそろえ、会話の文脈はDynamoDBに保存される ⑦: OpenAIサーバーは質問回答を返し、WebSocket接続を介してユーザーに返却する ⑧: ユーザーがLogoutしたら、 /$disconnect ルートがトリガーされる ⑨: meta_disconnect_handler はDynamoDBのユーザー会話の文脈を削除し、プロセスが終了する 実装手順 構築手順 以下の手順で構築を行います。 Lambda関数の作成 DynamoDBの作成 WebSocket API Gateway の作成 SNS トピックの作成 事前準備 NodeJS開発環境のセットアップ ローカルに Node.js をダウンロードしてインストールします(18.xバージョンを推奨) 本記事で提供されたコードは、Lambdaにコピーすることでそのまま クラウド 環境でビルド・運用が可能です ただし、後述するLangChainレイヤーの作成プロセスにおいてローカル環境でLangChainパッケージをダウンロードする必要があり、その際にはNodeJS環境が使用されることにご注意ください AWS アカウントの作成 AWS アカウントを持っている場合は、対応不要です AWS アカウントをお持ちでない場合は、 カウント作成の流れ を参考に、アカウントを作成してください ※本検証を行う場合、使用する AWS リソースの利用料金が発生する点にご注意ください OpenAIアカウントの作成 OpenAI API のアカウントを作成し API KEYを入手します API KEYの発行手順は こちら を参照してください 手順1. Lambda関数の作成 meta_connect_handler AWS Lambdaコンソールで meta_connect_handler という名前のLambda関数を作成し、ランタイムとしてNode.js 18.xを選択します。 ※上述した通り、本記事ではインフラ構築に焦点を当てるため、認証に関する実装は対象外です。デフォルトで生成されたコードをそのまま使用してください。 meta_handler_chat 上記と同様に AWS Lambdaコンソールで meta_handler_chat という名前のLambda関数を作成します。 この関数はユーザーリク エス トを受け取り、 SNS サービスのトピックに送信する役割を果たします。 この関数に SNS のPublic権限を追加し、 環境変数 で SNS のARN値( SNS_TOPIC_ARN )を設定してください。 具体的な実装コードは以下のとおりで、ユーザーのメッセージ( event.body.user_msg )を取得し、ユーザー接続情報とメッセージ内容を含む SNS のトピックを発行します。 // aws-sdkパッケージをインポートします import { SNSClient, PublishCommand } from "@aws-sdk/client-sns"; const client = new SNSClient(); const topicArn = process.env.SNS_TOPIC_ARN; export const handler = async(event) => { let body; if (typeof event.body === 'string') { body = JSON.parse(event.body); } else { body = event.body; } // ユーザー接続情報とメッセージ内容を含むSNSのトピックを発行します const command = new PublishCommand({ TopicArn:topicArn, Message:JSON.stringify({ requestContext:event.requestContext, payload: body.user_msg, }) }); let response; try{ await client.send(command); }catch (error) { console.log("Error:", JSON.stringify(error)); } }; meta_chat 同様な手順で AWS Lambdaコンソールで meta_chat という名前のLambda関数を作成します。 この関数はLangchainを使用してOpenAIサーバーとのインタ ラク ションする役割を果たします。 DynamoDBおよびAPIGatewayへのアクセス権限を追加し、OpenAI API KEYを 環境変数 として設定してください。 また、Lambdaではlangchainパッケージがないため、ローカルでダウンロードし、Layerとして関数にアップロードする必要があります。 具体的な手順は以下のとおりです: ローカルで npm install langchain を実行し、langchainをインストールします。 生成された node_module フォルダをZIPのパッケージ化します。 ZIPファイルをLayerにアップロードし、関数でlayer依存関係を設定します。 注意:OpenAIサービスの実行時間は3秒を超える可能性があるため、関数の実行時間設定を調整し(3秒 → 1分 )、 タイムアウト の問題を回避してください。 「コード」タブにて、下記のコードをコピーしてください。 // Langchainとaws-sdkパッケージをインポートします import { ChatOpenAI } from "langchain/chat_models/openai"; import { ConversationChain } from "langchain/chains"; import { BufferMemory } from "langchain/memory"; import { DynamoDBChatMessageHistory } from "langchain/stores/message/dynamodb"; import { ApiGatewayManagementApiClient, PostToConnectionCommand } from "@aws-sdk/client-apigatewaymanagementapi"; export const handler = async (event) => { console.log(JSON.stringify(event)); const body = JSON.parse(event.Records[0].Sns.Message); //SNSのトピックから必要な情報(クライアントの接続情報、ユーザーの質問内容のpayload)を読み取ります const requestContext = body.requestContext; const connectionId = requestContext.connectionId; const user_request = body.payload; // apigateway クライアントの初期化 const apigateway_client = new ApiGatewayManagementApiClient({ endpoint: 'https://'+requestContext.domainName + '/' + requestContext.stage, });  // 文脈保存先としてのDynamoDBを設定し、DynamoDBChatMessageHistoryを初期化します const chatHistory = new DynamoDBChatMessageHistory({ tableName: "Conversations", partitionKey: "ConnectionId", sessionId: connectionId, config: { region: "ap-northeast-1", }, }); // const memory = new BufferMemory({ chatHistory: chatHistory, }); // OpenAI model の初期化 const model = new ChatOpenAI({ modelName: "gpt-3.5-turbo", temperature: 0.5 }); // 初期化されたメモリおよびモデルを利用して、ConversationChainを初期化します。 const chain = new ConversationChain({ memory: memory, llm: model, verbose: true }); try { // OpenAIサーバーにリクエストを送信します const response = await chain.call({ input: user_request, }); // OpenAIからの回答を受け取り、それをクライアントに返却します const api_gateway_input = { ConnectionId: connectionId, Data: JSON.stringify(response) };    const command = new PostToConnectionCommand(api_gateway_input); await apigateway_client.send(command); } catch (error) { console.log("Error:", JSON.stringify(error)); } }; meta_disconnect_handler meta_disconnect_handler という名前のLambda関数を作成し、主にユーザーの会話履歴をクリアするために使用されます。 meta_chat と同様に、DynamoDBへのアクセス権限を追加してください。 具体的なコードは以下のとおりです。 // Langchainパッケージをインポートします import { BufferMemory } from "langchain/memory"; import { DynamoDBChatMessageHistory } from "langchain/stores/message/dynamodb"; export const handler = async (event) => { console.log(JSON.stringify(event)); const requestContext = event.requestContext; const connectionId = requestContext.connectionId; const chatHistory = new DynamoDBChatMessageHistory({ tableName: "Conversations", partitionKey: "ConnectionId", sessionId: connectionId, config: { region: "ap-northeast-1", }, }); const memory = new BufferMemory({ chatHistory: chatHistory, }); //DynamoDBから該当するユーザーの会話文脈を削除します await memory.chatHistory.clear(); }; 手順2. DynamoDBの作成 AWS 管理コンソール上で Amazon DynamoDB コンソールを開き、 Conversations という名前のテーブルと パーティション キーを ConnectionId に設定します。 通常、 パーティション キーはユーザーIDにすべきですが、今回ではログイン機能がないため、クライアント接続IDを パーティション キーとして使用します。 手順3. WebSocket API Gateway の作成 コンソールからWebSocket API Gateway を作成します。 ルーティングキー $connect 、 $disconnect 、および sendprompt を追加します。 Lambda関数の統合をそれぞれ設定します。 WebSocket URL( wss ://)を記録します。 手順4. SNS トピックの作成 標準の SNS トピックを作成します。 サブスクリプション を作成し、ポリシーのフィールドでlambdaを選択し、 meta_chat のARNリンクをエンドポイントのフィールドに貼り付けます。 SNS トピックARNをコピーし、 lambda_handle_chat の 環境変数 SNS_TOPIC_ARN の値に貼り付けます。 機能検証 セッションテスト wscatツールのインストール npm install -g wscat を実行し、wscatツールをインストールします。これは AWS が提供するWebSocket API をテストするツールです。 参考資料 。 WebSocket URLへの接続 以下のコマンドを使用して API Gateway に接続します: wscat -c 「WebSocket URL(wss://)」 セッションの開始 質問1「what is your name?」および質問2「What did I ask you just now?」に対する回答の関連性を確認します(文脈確認)。 DynamoDBのデータを確認 DynamoDBで会話履歴を確認します。 セッションの終了 [ctrl + c]を押してセッションを終了し、再度DynamoDBを確認して、以前のセッション記録が削除されたことを確認します。 複数のクライアントが同時にセッションを持つテスト 2つのクライアントで実施している会話がそれぞれ独立して行われることを確認するためのシミュレーションを行います。 終わりに この記事では、 AWS 上でChatGPTベースのインフラスト ラク チャの設計および構築について取り上げました。 今後、本インフラ構成において以下の点についてさらなる改善を行う予定です。 OpenAIのアクセスキーを保護するために AWS Secret Serviceを使用します ユーザー数が増えるにつれて、OpenAIの使用制限に達した場合に備えて、シームレスなアカウント切り替えを実装します より正確な回答を提供するためにVectorDBを統合することを検討しています より対話型のユーザーエクス ペリエ ンスを提供するために、ストリーミング応答モデルに移行します これからもChatGPTの応用シナリオについてさらに探求し、その結果をAIに興味を持つ読者と継続的に共有し続ける予定です。 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! ISID採用ページ(Web3/メタバース/AI) 執筆: @chen.sun 、レビュー: @wakamoto.ryosuke ( Shodo で執筆されました )
皆さんこんにちは。グループ経営ソリューション事業部グループ経営 コンサルティング 第2ユニット一般会計 コンサルティング 部第2グループ(FAC2部)に所属している小林です。 FAC2部では自社製品である「Ci X (サイクロス)」という会計システムパッケージの新規開発・導入・保守を行っており、私は主にその保守業務を担当しています。 この記事ではISIDに興味をお持ちの就活生の方々向けに私がISIDに入社して初めて担当した業務から学んだことについて、自身の振り返りの意味も込めてご紹介したいと思います。 あと、Ci Xに関しては こちら も参考にしてみてください! 自己紹介 まずは自己紹介いたします。 私は2022年に新卒入社し、半年の研修を経て、現在は2年目の勤務になります。 大学では院まで進学し、 放射線 系の研究をしていました。 そのままの進路でいくのならば、メーカー勤務や 原子力 関係の企業に就職するのが王道でした。 物理という学問は好きでしたし、研究室も自分で望んで所属しましたが、大学4年間で勉強した物理の理論を、研究室で応用することは少なく、愚直に地味な実験を繰り返す成果の見えない生活が率直に自分には合っていませんでした。そんな時にHP係を担当しまして、学べば学ぶほど、スキルが身に付くのを感じ、研究室のHPを管理したり、学会のHPを作成することが楽しかったのを覚えています。 ささいな理由ではありましたが、本当に自分のやりたいことって何だろうと考えた時に気づいたらIT業界を志すようになっていました。就活では上手くいかないことだらけでしたが、自分の率直な思いを面白いと聞いてくれたのがISIDで、IT経験が特にない私でも希望していた開発の部署に配属させてくれました。 そして現在、私は自社製品の保守業務からスタートしています。 配属されてから一年も経過はしていませんが、業務はかなり幅広いです。 今回はそれについて広く浅く紹介いたします。 保守の仕事内容について 保守業務のおおまかな流れは製品のリリース後、まず、お客様が製品を使用していて何かしらお問い合わせが生じた際にその旨を保守窓口が受け取り、保守チームに対応を要求します。そしてその後、保守チームは再現調査や原因究明を行って不具合かどうかを判断し、必要があれば設計を変更したり、中身の実装を修正したりして仕様変更対応を行い、テストをします。 以下では私が携わった範囲で担当した業務プロセスを私自身の所感も含めて説明します。 1.原因調査 トラブルシューティング の入り口になるプロセスです。起こってしまったトラブルに対して何が原因だったのか監査ログやシステムログなどを通して原因を探ります。 このプロセスはいざやってみるとどの工程の中でも直感とスキル、判断力が必要で、これを即座にできる人は保守としての力が特に強い人なのだと個人的に思っています。 2.設計 もし、仕様変更が必要な場合、設計を修正することがあります。欠陥修正に該当する設計書の内容を読み込んで画面定義やロジックなどどこを修正すべきなのか判断し、修正します。特にロジックが難しく、簿記の知識も絡む箇所もあるので、何度見返しても不明な部分に関しては先輩社員に聞きながら進めていました。 3.実装 上記の設計修正が完了したあと、その設計に基づいて実際に内部の実装も変更します。 実装で用いる技術要素は以下です。 バックエンド技術( Java , Spring Boot, Thymeleaf, PostgreSQL 等) フロントエンド技術( HTML5 、TypeScript、Vue.js 等) 業務は新卒の研修で学んだことが直接生きており、改めて研修の大切さを実感しました。 4.テスト 実装が完了した後はテストを行い、機能に問題がないか不具合チェックをします。直接変更してはいなくともその変更の影響を受けたところに対してバグが出てしまうこともあるため、機能のテストだけでなく、その周辺に関してもテストをします。配属直後はこのプロセスから携わり、Ci*Xがどういう機能を有しているのか学びながらこれらのテストを行っていました。 5.その他 上記以外にも SQL を更新したり、サーバーの管理者としての業務もあります。 SQL にはデータを定義する DDL やデータを操作する DML など種類がありますが、フォルダごとに配置され、一括して リポジトリ にまとめられています。 私はGitを使用してチームメンバーが編集や新規作成した SQL を更新しています。Gitの勉強にもなりますし、 SQL を取り込む際にエラーになることは多々あるので、 SQL の内容について考える機会も多いです。 また、Ci*Xのテスト環境は AWS で運用しており、アプリケーションが動作している環境は Amazon EC2 を使っています。チーム内から依頼されたサーバーの容量拡張や棚卸、新規作成、複製などの業務を担当しています。また、手動で行っていたこれらの業務も今は AWS CDK と GitHub Actionsを用いて ソースコード から自動で行えるように取り組んでいます。 AWS は未経験でしたが、触ってみると楽しいことも多く、 AWS Certified Cloud Practitioner という初級の資格を取りつつ、もっと知識を深めて業務に応用できたらいいなと思っています。 一日の流れ 毎朝、 Jira のチケットの進捗状況を確認します。 朝会終了後はチケットの作業に取り組むことが多いです。 隔週で勉強会があったり、毎週、一般会計 コンサルティング 部の方たちと雑談するような時間もあります。 配属当初は不明点を上司に相談できるような夕会の時間も設けてもらっていました。 FAC2部(保守業務)での働き方の特徴 配属前、開発は設計や実装などある程度の期間を設定し、段階を踏みながら業務を進めていくイメージを持っていましたが、保守業務の特徴は多種多様な角度から不具合の対処やテストを求められることが多く、内容の異なるチケットを抱えていることはよくあることなので、その点において配属直後から幅広い業務に携われていると感じています。 チケットも自分で選択しながら進められますし、先輩社員との1on1で業務やそれ以外に困っていることなどを適宜聞いてくれる場もありますので裁量を持って仕事させてもらえる環境だなと日々感じています。 また、基本的にテレワークがメインになります。出社する必要がないので、そういう点で気楽さを感じています。ただ、テレワークにおけるコミュニケーションはテキストやメールが主となるため、個人の文章力や読解力の差で情報伝達内容の認識に差異や時差が生じてしまったり、情報収集が必要最低限になることが多いなど、難しさも感じています。会議を設定して、あらかじめ質問をまとめ、限られた時間で情報収集する力が求められるなと日々感じています。 最後に 今回は、Ci*Xシリーズの保守業務の内容とその仕事や働き方の特徴についてお伝えしました。 テクニカルな話題が多い中で、少し異色なブログではありましたが、いかがでしたか? 保守業務は様々な角度から問題点が切り込まれるので大変な思いをすることもたくさんありますが、その分、身につくスキルは多いと思います。 これを見てくださっている就活生のみなさんとも共に仕事ができたらなと思います! ありがとうございました! www.isid.co.jp 執筆: @kobayashi.shun 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
皆さんこんにちは。グループ経営ソリューション事業部グループ経営 コンサルティング 第2ユニット一般会計 コンサルティング 部第2グループ(FAC2部)に所属している小林です。 FAC2部では自社製品である「Ci X (サイクロス)」という会計システムパッケージの新規開発・導入・保守を行っており、私は主にその保守業務を担当しています。 この記事ではISIDに興味をお持ちの就活生の方々向けに私がISIDに入社して初めて担当した業務から学んだことについて、自身の振り返りの意味も込めてご紹介したいと思います。 あと、Ci Xに関しては こちら も参考にしてみてください! 自己紹介 まずは自己紹介いたします。 私は2022年に新卒入社し、半年の研修を経て、現在は2年目の勤務になります。 大学では院まで進学し、 放射線 系の研究をしていました。 そのままの進路でいくのならば、メーカー勤務や 原子力 関係の企業に就職するのが王道でした。 物理という学問は好きでしたし、研究室も自分で望んで所属しましたが、大学4年間で勉強した物理の理論を、研究室で応用することは少なく、愚直に地味な実験を繰り返す成果の見えない生活が率直に自分には合っていませんでした。そんな時にHP係を担当しまして、学べば学ぶほど、スキルが身に付くのを感じ、研究室のHPを管理したり、学会のHPを作成することが楽しかったのを覚えています。 ささいな理由ではありましたが、本当に自分のやりたいことって何だろうと考えた時に気づいたらIT業界を志すようになっていました。就活では上手くいかないことだらけでしたが、自分の率直な思いを面白いと聞いてくれたのがISIDで、IT経験が特にない私でも希望していた開発の部署に配属させてくれました。 そして現在、私は自社製品の保守業務からスタートしています。 配属されてから一年も経過はしていませんが、業務はかなり幅広いです。 今回はそれについて広く浅く紹介いたします。 保守の仕事内容について 保守業務のおおまかな流れは製品のリリース後、まず、お客様が製品を使用していて何かしらお問い合わせが生じた際にその旨を保守窓口が受け取り、保守チームに対応を要求します。そしてその後、保守チームは再現調査や原因究明を行って不具合かどうかを判断し、必要があれば設計を変更したり、中身の実装を修正したりして仕様変更対応を行い、テストをします。 以下では私が携わった範囲で担当した業務プロセスを私自身の所感も含めて説明します。 1.原因調査 トラブルシューティング の入り口になるプロセスです。起こってしまったトラブルに対して何が原因だったのか監査ログやシステムログなどを通して原因を探ります。 このプロセスはいざやってみるとどの工程の中でも直感とスキル、判断力が必要で、これを即座にできる人は保守としての力が特に強い人なのだと個人的に思っています。 2.設計 もし、仕様変更が必要な場合、設計を修正することがあります。欠陥修正に該当する設計書の内容を読み込んで画面定義やロジックなどどこを修正すべきなのか判断し、修正します。特にロジックが難しく、簿記の知識も絡む箇所もあるので、何度見返しても不明な部分に関しては先輩社員に聞きながら進めていました。 3.実装 上記の設計修正が完了したあと、その設計に基づいて実際に内部の実装も変更します。 実装で用いる技術要素は以下です。 バックエンド技術( Java , Spring Boot, Thymeleaf, PostgreSQL 等) フロントエンド技術( HTML5 、TypeScript、Vue.js 等) 業務は新卒の研修で学んだことが直接生きており、改めて研修の大切さを実感しました。 4.テスト 実装が完了した後はテストを行い、機能に問題がないか不具合チェックをします。直接変更してはいなくともその変更の影響を受けたところに対してバグが出てしまうこともあるため、機能のテストだけでなく、その周辺に関してもテストをします。配属直後はこのプロセスから携わり、Ci*Xがどういう機能を有しているのか学びながらこれらのテストを行っていました。 5.その他 上記以外にも SQL を更新したり、サーバーの管理者としての業務もあります。 SQL にはデータを定義する DDL やデータを操作する DML など種類がありますが、フォルダごとに配置され、一括して リポジトリ にまとめられています。 私はGitを使用してチームメンバーが編集や新規作成した SQL を更新しています。Gitの勉強にもなりますし、 SQL を取り込む際にエラーになることは多々あるので、 SQL の内容について考える機会も多いです。 また、Ci*Xのテスト環境は AWS で運用しており、アプリケーションが動作している環境は Amazon EC2 を使っています。チーム内から依頼されたサーバーの容量拡張や棚卸、新規作成、複製などの業務を担当しています。また、手動で行っていたこれらの業務も今は AWS CDK と GitHub Actionsを用いて ソースコード から自動で行えるように取り組んでいます。 AWS は未経験でしたが、触ってみると楽しいことも多く、 AWS Certified Cloud Practitioner という初級の資格を取りつつ、もっと知識を深めて業務に応用できたらいいなと思っています。 一日の流れ 毎朝、 Jira のチケットの進捗状況を確認します。 朝会終了後はチケットの作業に取り組むことが多いです。 隔週で勉強会があったり、毎週、一般会計 コンサルティング 部の方たちと雑談するような時間もあります。 配属当初は不明点を上司に相談できるような夕会の時間も設けてもらっていました。 FAC2部(保守業務)での働き方の特徴 配属前、開発は設計や実装などある程度の期間を設定し、段階を踏みながら業務を進めていくイメージを持っていましたが、保守業務の特徴は多種多様な角度から不具合の対処やテストを求められることが多く、内容の異なるチケットを抱えていることはよくあることなので、その点において配属直後から幅広い業務に携われていると感じています。 チケットも自分で選択しながら進められますし、先輩社員との1on1で業務やそれ以外に困っていることなどを適宜聞いてくれる場もありますので裁量を持って仕事させてもらえる環境だなと日々感じています。 また、基本的にテレワークがメインになります。出社する必要がないので、そういう点で気楽さを感じています。ただ、テレワークにおけるコミュニケーションはテキストやメールが主となるため、個人の文章力や読解力の差で情報伝達内容の認識に差異や時差が生じてしまったり、情報収集が必要最低限になることが多いなど、難しさも感じています。会議を設定して、あらかじめ質問をまとめ、限られた時間で情報収集する力が求められるなと日々感じています。 最後に 今回は、Ci*Xシリーズの保守業務の内容とその仕事や働き方の特徴についてお伝えしました。 テクニカルな話題が多い中で、少し異色なブログではありましたが、いかがでしたか? 保守業務は様々な角度から問題点が切り込まれるので大変な思いをすることもたくさんありますが、その分、身につくスキルは多いと思います。 これを見てくださっている就活生のみなさんとも共に仕事ができたらなと思います! ありがとうございました! www.isid.co.jp 執筆: @kobayashi.shun 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
こんにちは。X(クロス) イノベーション 本部 ソフトウェアデザインセンター セキュリティグループの耿です。 AWS WAF は簡単に Web アプリに WAF を追加でき、かつ値段も他の WAF 製品より安いため、好きな AWS サービスの一つです。そんな AWS WAF ですがしばらく構築・運用し、これを最初から知っておけば・・・と思ったことがあるので 8つご紹介します。 AWS WAF の基本については分かっている前提で、特に説明はいたしません。また2023年10月現在の最新バージョンである、いわゆる「 AWS WAF v2」を対象としています。 その1: AWS マネージドルールのボディサイズ制限が厳しい その2: ファイルアップロードが AWS マネージドルールの XSS に引っかかることがある その3: マネージドルールにはバージョンがある その4: CloudWatch Logs のロググループ名に決まりがある その5: 35個のログストリームに分割される その6: ログに Cookie ヘッダーが記録されてしまう その7: ログ出力条件の EXCLUDED_AS_COUNT とは何か その8: コンソールで作成したルールを JSON 出力すると IaC での書き方がわかる さいごに その1: AWS マネージドルールのボディサイズ制限が厳しい AWS WAF を利用する際に AWS マネージドルール はとても便利です。その中の コアルールセット (CRS) マネージドルールグループ には SizeRestrictions_BODY というリクエストボディのサイズを検査するルールがあり、 8 KB を超えるボディを持つリクエストをブロック します。 ボディサイズが大きいリクエストや、ファイルアップロードにおいては 8 KB を簡単に超えてしまう ことがあるので、本番環境に導入する前に想定するサイズのリクエストがブロックされないかしっかりテストが必要です。 ※このようなルールが設定されている理由は、 AWS WAF は リクエストボディの最初の 8 KB しか検査できない という制約があるためです。リクエストボディの 8 KB 以降の位置に攻撃文字列が含まれていても検査できないため、コアルールセットでは 8 KB を超えるリクエストを一律でブロックすることで対応しています。 ※(2024/3/11追記)ALB以外に関連付けるWAF Web ACL のリクエストボディの検査サイズ制限が 16 KB(64 KBに引き上げ可能)に増えました。 https://aws.amazon.com/about-aws/whats-new/2024/03/aws-waf-larger-body-inspections-regional-resources/ 想定する正当なリクエストが 8 KB を超えてしまう場合、ルールグループ内の SizeRestrictions_BODY ルールのアクションを「Count」にオーバーライドすることで、実質的に除外することができます。ただしボディサイズ制限が全くないのは心許ないので、次のように WAF Web ACL を作ることが考えられます。 コアルールセットマネージドルールグループでは SizeRestrictions_BODY を「Count」にオーバーライドする 適切な値でボディサイズ制限を行う独自ルールを作成する このようなルールを複数作り、リクエストパスに応じて異なるボディサイズの 閾値 を設定することも可能です(例えばファイルアップロードを受け付ける URI パスに対しては 100 KB に制限し、それ以外の URI パスに対しては 8 KB に制限するなど) ボディサイズ制限の 閾値 を 8 KB より大きくする場合、前述の通り、それを超える部分のリクエストボディの中身は他のルールでも検査されないことに留意してください なお、re:Post の次の投稿でも SizeRestrictions_BODY でブロックされた場合の対応方法が記載されています。マネージドルールに一致した際に追加されるラベルと独自ルールを組み合わせて、特定の URI パス(=ファイルアップロードを行う URI パス)ではない場合のみブロックを発動させる方法です。 AWS WAF によってブロックされているファイルをアップロードするにはどうすればよいですか? https://repost.aws/ja/knowledge-center/waf-upload-blocked-files その2: ファイルアップロードが AWS マネージドルールの XSS に引っかかることがある Web アプリに対してバイナリファイルのアップロードをした時に、運悪く コアルールセット (CRS) マネージドルールグループ の CrossSiteScripting_BODY ルールに引っかかってしまったことがありました。そのときのログの一部は次の通りです。バイナリデータが XSS の シグネチャ に一致してしまったようです。 " terminatingRuleMatchDetails ": [ { " conditionType ": " XSS ", " location ": " BODY ", " matchedData ": [ " < ", " \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 " ] } ] , re:Post の次の投稿によると、 ファイルアップロードでは CrossSiteScripting_BODY 以外にも SQLi_BODY 、 WindowsShellCommands_BODY 、 GenericLFI_BODY 、 SizeRestrictions_BODY ルールによってブロックされる可能性がある ようです。 AWS WAF によってブロックされているファイルをアップロードするにはどうすればよいですか? https://repost.aws/ja/knowledge-center/waf-upload-blocked-files 投稿では対応方法として「文字列または 正規表現 ( regex ) 一致条件が設定されたセーフリストを使用して、リクエストを許可します。」が紹介されています。マネージドルールに一致した際に追加されるラベルと独自ルールを組み合わせて、リクエストボディに特定の文字列(ファイル拡張子などを想定していると解釈しました)が含まれていない場合のみブロックを発動する方法です。(注:日本語の投稿ではなぜかリクエストヘッダーから特定の文字列を探すとありますが、 英語の投稿 ではリクエストボディから探すと書いてあります。リクエストボディの方がしっくりきています。) あるいは「その1」の SizeRestrictions_BODY の場合と同じように、特定の URI パス(=ファイルアップロードを行う URI パス)ではない場合のみブロックを発動させる方法を取っても良さそうです。 その3: マネージドルールにはバージョンがある マネジメントコンソールでマネージドルールを使っていたらすぐに気が付いたと思うのですが、筆者は CDK で Web ACL を作っていたのでずっと知りませんでした。 マネージドルールにはバージョンが存在します 。 ( AWS マネージドルールのうち「IP レピュテーション、 Bot Control、アカウント乗っ取り防止のルールグループ」にはバージョンが存在しません。バージョンに関わらず、日ごろから頻繁にルールが更新されるためでしょう。) バージョンを特に指定しない場合、そのマネージドルールがデフォルトと設定したバージョンが利用され、ルールプロバイダーがデフォルトバージョンを変更すると構築した Web ACL でも自動的に新しいバージョンに更新されます。自動的に更新されることを避けたい場合は、「静的バージョン」を明示的に指定します。ただしこの場合も、「緊急時の必須の更新」がされる可能性があるそうです。またバージョンの有効期限が切れると、次のような扱いになるようです。 AWS マネージドルールルールグループの場合、 AWS WAF は、有効期限切れのバージョンを使用しているウェブ ACL を、ルールグループのデフォルトバージョンに移動します。 AWS Marketplace ルールグループの場合、プロバイダーは有効期限の処理方法を決定します。詳細については、マネージドルールグループプロバイダーに問い合わせてください。 マネージドルールには SNS トピックが用意されている場合があり、サブスクライブすることでバージョンを含めたルールの更新情報を受け取ることができます。特に静的バージョンを使用する場合はルールバージョンを手動更新することになるので、 SNS トピックをサブスクライブしておくと良いでしょう。 その4: CloudWatch Logs のロググループ名に決まりがある AWS WAF を利用する場合はログをぜひ取っておきたいところですが、CloudWatch Logs に出力する場合、 ロググループ名は aws-waf-logs- で始まる必要があります 。 https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/logging-cw-logs.html#logging-cw-logs-naming マネジメントコンソールでロググループを指定する場合は画面にこの条件が書いてありますし、 aws-waf-logs- で始まるロググループ以外は選択肢に表示されないのでまだ分かりやすいです。 しかし CloudFormation (もちろん CDK も)を利用する場合、 aws-waf-logs- で始まるロググループ以外を Web ACL に関連付けしようとすると、デプロイ時に次のようなエラーになります。「ARN が有効でない」というエラーメッセージでは何がいけないのか全く分からず、どハマりしたことがあるのは自分だけではないはずです。 Resource handler returned message: "Error reason: The ARN isn't valid. A valid ARN begins with arn: and includes other information separated by colons or slashes., field: LOG_ DESTINATION , parameter: arn: aws :logs:ap-northeast-1:111122223333:log-group:waf-logs-xxxxx ちなみにログの出力先が S3 バケット の場合も、 バケット 名は aws-waf-logs- で始まる必要があります。 https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/logging-s3.html#logging-s3-naming その5: 35個のログストリームに分割される (2025/9/5更新)いつ変わったのか分かりませんが、今はWAFのログストリームが分割されなくなっているようです。なお、それでもログの検索はCloudWatch Logs Insightsを利用するのが便利であることには変わりません。 CloudWatch Logs にログを出力すると、 35個のログストリームに分割 され、この数を減らすことはできません 。出力の スループット を高めるためのようです。 近い時刻で発生したログメッセージでも、複数のログストリームに分散して出力されるため、ロググループから特定のログを探すのは難しいです。ログストリームを横断して時系列にログを見たり、特定のログを探したい場合は CloudWatch Logs Insights を利用するのが便利です。以下の公式ブログや re:Post 投稿が参考になります。 Amazon CloudWatch Logs による AWS WAF ログの分析 https://aws.amazon.com/jp/blogs/news/analyzing-aws-waf-logs-in-amazon-cloudwatch-logs/ CloudWatch または Amazon S3 に保存されている AWS WAF ログを分析するオプションは何ですか? https://repost.aws/ja/knowledge-center/waf-analyze-logs-stored-cloudwatch-s3 その6: ログに Cookie ヘッダーが記録されてしまう WAF Web ACL のログを出力すると、 httpRequest.headers フィールドにリクエストヘッダーが記録されます。つまり、 クライアントが送信した Cookie も記録されてしまいます 。 (スクリーンキャプチャの値はダミーです) 例えば分析のためにログを出力したり、共有したりすると有効なセッション ID などセンシティブな情報が漏えいするリスクがあります。 この問題への対応として、ログ出力時に 特定フィールドをマスキング することが可能です。例えば cookie ヘッダーをマスキングするには次のように設定します。 このように設定すると、出力されるログの cookie ヘッダーは REDACTED という文字列に置き換えられます。 ※(追記) Cookie ヘッダーをマスキングするデータ保護機能が増強されました。セッションIDなど特定の Cookie のみを対象としたり、マスキングの代わりにハッシュ化を行うこともできるようになっています。 https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/data-protection-masking.html その7: ログ出力条件の EXCLUDED_AS_COUNT とは何か ログを出力する場合、アクションが特定の条件に該当する場合のみ出力するように設定できます。リクエストが許可された場合のログも全て記録すると量が多くなってしまうので、「ブロック」時と「カウント」時のみ出力したいことがあります。 カウント時の条件は、実は COUNT と EXCLUDED_AS_COUNT の2種類があります 。基本的には COUNT 扱いと考えて良いですが、 EXCLUDED_AS_COUNT として扱われるケースが2つ、以下のブログで説明されています。 AWS WAF のログ分析に関する考慮事項 https://aws.amazon.com/jp/blogs/news/aws-waf-log-analysis-considerations/ マネージドルールグループで ”Set all rule actions to count” で Count に設定した場合 マネージドルールグループで個別のルールを Count に設定した場合 ただし上の AWS のブログは情報が古く、現在個別のルールを Count に設定した場合の動きは少々異なるようです( 参照 )。簡単にまとめると、以下のようになると理解しています: 2022 年 10 月 27 日より前に、 WAF ルールの JSON では ExcludedRules が利用でき、これに含めた個別ルールは EXCLUDED_AS_COUNT 扱いになる マネジメントコンソールで個別ルールを Count に設定すると、 EXCLUDED_AS_COUNT 扱いになる 2022 年 10 月 27 日以降は、 WAF ルールの JSON で ExcludedRules に含めた個別ルールは変わらず EXCLUDED_AS_COUNT 扱いになる WAF ルールの JSON で RuleActionOverrides が新しく利用でき、オーバーライド先をカウントにした場合は COUNT 扱いになる マネジメントコンソールで個別ルールを Count に設定(過去に作成したルールの編集も含めて)すると、 COUNT 扱いに変わる この動きを意識してログ出力条件を作成すると良いと思います。 その8: コンソールで作成したルールを JSON 出力すると IaC での書き方がわかる CloudFormation もしくは CDK で複雑な条件の Web ACL を作成する場合、書き方が分からずに困ることがあります。 例えば「 URI パスが /file/upload 以外へのリクエストでボディサイズが 100 KB 以上の場合にブロックする」ルールは、CDK だとこんな感じで書くことになります。(ルール部分のみ) { name : "SizeConstraint" , priority: 10 , statement: { andStatement: { statements: [ { notStatement : { statement : { byteMatchStatement : { searchString : "/file/upload" , fieldToMatch : { uriPath : {} , } , textTransformations : [ { priority : 0 , type : "NONE" , } , ] , positionalConstraint : "EXACTLY" , } , } , } , } , { sizeConstraintStatement : { fieldToMatch : { body : { oversizeHandling : "CONTINUE" , } , } , comparisonOperator : "GE" , size : 100 * 1000 , textTransformations : [ { priority : 0 , type : "NONE" , } , ] , } , } , ] , } , } , action: { block: {} } , visibilityConfig: { sampledRequestsEnabled: true , cloudWatchMetricsEnabled: true , metricName: "SizeConstraint" , } , } , これをヒントなしで正しく書ける気がしません。一方でマネジメントコンソールでルールを作成すれば、画面の説明に従って割と分かりやすく作成できます。 そこで IaC で WAF のルールを作る場合も、まずはマネジメントコンソールで試しに作成してみて、画面で「ルール JSON エディタ」に切り替えましょう 。 JSON でのルールの書き方を表示してくれます。これをコピーして IaC で利用すると良いでしょう。(CDK に使う場合はプロパティ名の頭文字を大文字から小文字に変換する必要がありますが、自前で書くよりはずっと楽です。) ちなみにルール JSON エディタ画面の説明にもある通り、 JSON を使えばビジュアルエディタではサポートされていないような、深い階層の条件を持つルールを作ることもできます。以下の re:Post 投稿も参考になります。 複雑なカスタム AWS WAF JSON ルールを作成する方法を教えてください。 https://repost.aws/ja/knowledge-center/waf-create-complex-custom-rules さいごに ご紹介した内容はいずれも公式ドキュメントやブログに書いてあることなのですが、WAF を使い始める時は早く構成したい気持ちが先走ってなかなか網羅的にチェックはできませんね。今振り返ると最初に知っておきたかったと感じたことをまとめてみました。誰かの参考になれば嬉しいです。 記事の中に掲載したリンクで特におすすめのものを再掲しておきます。 コアルールセット (CRS) マネージドルールグループ https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/aws-managed-rule-groups-baseline.html#aws-managed-rule-groups-baseline-crs (どのようなルールで検査を行うのか、利用前に一通り把握しておきましょう) AWS WAF によってブロックされているファイルをアップロードするにはどうすればよいですか? https://repost.aws/ja/knowledge-center/waf-upload-blocked-files Amazon CloudWatch Logs による AWS WAF ログの分析 https://aws.amazon.com/jp/blogs/news/analyzing-aws-waf-logs-in-amazon-cloudwatch-logs/ CloudWatch または Amazon S3 に保存されている AWS WAF ログを分析するオプションは何ですか? https://repost.aws/ja/knowledge-center/waf-analyze-logs-stored-cloudwatch-s3 ルールグループ内のアクションオーバーライド https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/web-acl-rule-group-override-options.html 複雑なカスタム AWS WAF JSON ルールを作成する方法を教えてください。 https://repost.aws/ja/knowledge-center/waf-create-complex-custom-rules 以下は、この記事では触れませんでしたが参考となる re:Post の投稿です。 AWS WAF ルールでブロックされているファイルのアップロードを、ルールを除外せずに明示的に許可するには、どうすればよいですか? https://repost.aws/ja/knowledge-center/waf-explicit-allow-file-uploads AWS WAF の HTTP リクエストの XSS または SQLi 検査から特定の URI を除外する方法を教えてください。 https://repost.aws/ja/knowledge-center/waf-exclude-specific-requests-inspection AWS WAF を利用して DDoS 攻撃を緩和するにはどうすればいいですか? https://repost.aws/ja/knowledge-center/waf-mitigate-ddos-attacks 私たちは一緒に働いてくれる仲間を募集しています! 電通総研中途採用ページ 電通総研新卒採用ページ 執筆: @kou.kinyo 、レビュー: 寺山 輝 (@terayama.akira) ( Shodo で執筆されました )
こんにちは。X(クロス) イノベーション 本部 ソフトウェアデザインセンター セキュリティグループの耿です。 AWS WAF は簡単に Web アプリに WAF を追加でき、かつ値段も他の WAF 製品より安いため、好きな AWS サービスの一つです。そんな AWS WAF ですがしばらく構築・運用し、これを最初から知っておけば・・・と思ったことがあるので 8つご紹介します。 AWS WAF の基本については分かっている前提で、特に説明はいたしません。また2023年10月現在の最新バージョンである、いわゆる「 AWS WAF v2」を対象としています。 その1: AWS マネージドルールのボディサイズ制限が厳しい その2: ファイルアップロードが AWS マネージドルールの XSS に引っかかることがある その3: マネージドルールにはバージョンがある その4: CloudWatch Logs のロググループ名に決まりがある その5: 35個のログストリームに分割される その6: ログに Cookie ヘッダーが記録されてしまう その7: ログ出力条件の EXCLUDED_AS_COUNT とは何か その8: コンソールで作成したルールを JSON 出力すると IaC での書き方がわかる さいごに その1: AWS マネージドルールのボディサイズ制限が厳しい AWS WAF を利用する際に AWS マネージドルール はとても便利です。その中の コアルールセット (CRS) マネージドルールグループ には SizeRestrictions_BODY というリク エス トボディのサイズを検査するルールがあり、 8 KB を超えるボディを持つリク エス トをブロック します。 ボディサイズが大きいリク エス トや、ファイルアップロードにおいては 8 KB を簡単に超えてしまう ことがあるので、本番環境に導入する前に想定するサイズのリク エス トがブロックされないかしっかりテストが必要です。 ※このようなルールが設定されている理由は、 AWS WAF は リクエストボディの最初の 8 KB しか検査できない という制約があるためです。リク エス トボディの 8 KB 以降の位置に攻撃文字列が含まれていても検査できないため、コアルールセットでは 8 KB を超えるリク エス トを一律でブロックすることで対応しています。 想定する正当なリク エス トが 8 KB を超えてしまう場合、ルールグループ内の SizeRestrictions_BODY ルールのアクションを「Count」にオーバーライドすることで、実質的に除外することができます。ただしボディサイズ制限が全くないのは心許ないので、次のように WAF Web ACL を作ることが考えられます。 コアルールセットマネージドルールグループでは SizeRestrictions_BODY を「Count」にオーバーライドする 適切な値でボディサイズ制限を行う独自ルールを作成する このようなルールを複数作り、リク エス トパスに応じて異なるボディサイズの 閾値 を設定することも可能です(例えばファイルアップロードを受け付ける URI パスに対しては 100 KB に制限し、それ以外の URI パスに対しては 8 KB に制限するなど) ボディサイズ制限の 閾値 を 8 KB より大きくする場合、前述の通り、それを超える部分のリク エス トボディの中身は他のルールでも検査されないことに留意してください なお、re:Post の次の投稿でも SizeRestrictions_BODY でブロックされた場合の対応方法が記載されています。マネージドルールに一致した際に追加されるラベルと独自ルールを組み合わせて、特定の URI パス(=ファイルアップロードを行う URI パス)ではない場合のみブロックを発動させる方法です。 AWS WAF によってブロックされているファイルをアップロードするにはどうすればよいですか? https://repost.aws/ja/knowledge-center/waf-upload-blocked-files その2: ファイルアップロードが AWS マネージドルールの XSS に引っかかることがある Web アプリに対してバイナリファイルのアップロードをした時に、運悪く コアルールセット (CRS) マネージドルールグループ の CrossSiteScripting_BODY ルールに引っかかってしまったことがありました。そのときのログの一部は次の通りです。バイナリデータが XSS の シグネチャ に一致してしまったようです。 " terminatingRuleMatchDetails ": [ { " conditionType ": " XSS ", " location ": " BODY ", " matchedData ": [ " < ", " \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 " ] } ] , re:Post の次の投稿によると、 ファイルアップロードでは CrossSiteScripting_BODY 以外にも SQLi_BODY 、 WindowsShellCommands_BODY 、 GenericLFI_BODY 、 SizeRestrictions_BODY ルールによってブロックされる可能性がある ようです。 AWS WAF によってブロックされているファイルをアップロードするにはどうすればよいですか? https://repost.aws/ja/knowledge-center/waf-upload-blocked-files 投稿では対応方法として「文字列または 正規表現 ( regex ) 一致条件が設定されたセーフリストを使用して、リク エス トを許可します。」が紹介されています。マネージドルールに一致した際に追加されるラベルと独自ルールを組み合わせて、リク エス トボディに特定の文字列(ファイル拡張子などを想定していると解釈しました)が含まれていない場合のみブロックを発動する方法です。(注:日本語の投稿ではなぜかリク エス トヘッダーから特定の文字列を探すとありますが、 英語の投稿 ではリク エス トボディから探すと書いてあります。リク エス トボディの方がしっくりきています。) あるいは「その1」の SizeRestrictions_BODY の場合と同じように、特定の URI パス(=ファイルアップロードを行う URI パス)ではない場合のみブロックを発動させる方法を取っても良さそうです。 その3: マネージドルールにはバージョンがある マネジメントコンソールでマネージドルールを使っていたらすぐに気が付いたと思うのですが、筆者は CDK で Web ACL を作っていたのでずっと知りませんでした。 マネージドルールにはバージョンが存在します 。 ( AWS マネージドルールのうち「IP レピュテーション、 Bot Control、アカウント乗っ取り防止のルールグループ」にはバージョンが存在しません。バージョンに関わらず、日ごろから頻繁にルールが更新されるためでしょう。) バージョンを特に指定しない場合、そのマネージドルールがデフォルトと設定したバージョンが利用され、ルールプロバイダーがデフォルトバージョンを変更すると構築した Web ACL でも自動的に新しいバージョンに更新されます。自動的に更新されることを避けたい場合は、「静的バージョン」を明示的に指定します。ただしこの場合も、「緊急時の必須の更新」がされる可能性があるそうです。またバージョンの有効期限が切れると、次のような扱いになるようです。 AWS マネージドルールルールグループの場合、 AWS WAF は、有効期限切れのバージョンを使用しているウェブ ACL を、ルールグループのデフォルトバージョンに移動します。 AWS Marketplace ルールグループの場合、プロバイダーは有効期限の処理方法を決定します。詳細については、マネージドルールグループプロバイダーに問い合わせてください。 マネージドルールには SNS トピックが用意されている場合があり、サブスクライブすることでバージョンを含めたルールの更新情報を受け取ることができます。特に静的バージョンを使用する場合はルールバージョンを手動更新することになるので、 SNS トピックをサブスクライブしておくと良いでしょう。 その4: CloudWatch Logs のロググループ名に決まりがある AWS WAF を利用する場合はログをぜひ取っておきたいところですが、CloudWatch Logs に出力する場合、 ロググループ名は aws-waf-logs- で始まる必要があります 。 https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/logging-cw-logs.html#logging-cw-logs-naming マネジメントコンソールでロググループを指定する場合は画面にこの条件が書いてありますし、 aws-waf-logs- で始まるロググループ以外は選択肢に表示されないのでまだ分かりやすいです。 しかし CloudFormation (もちろん CDK も)を利用する場合、 aws-waf-logs- で始まるロググループ以外を Web ACL に関連付けしようとすると、デプロイ時に次のようなエラーになります。「ARN が有効でない」というエラーメッセージでは何がいけないのか全く分からず、どハマりしたことがあるのは自分だけではないはずです。 Resource handler returned message: "Error reason: The ARN isn't valid. A valid ARN begins with arn: and includes other information separated by colons or slashes., field: LOG_ DESTINATION , parameter: arn: aws :logs:ap-northeast-1:111122223333:log-group:waf-logs-xxxxx ちなみにログの出力先が S3 バケット の場合も、 バケット 名は aws-waf-logs- で始まる必要があります。 https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/logging-s3.html#logging-s3-naming その5: 35個のログストリームに分割される CloudWatch Logs にログを出力すると、 35個のログストリームに分割 され、この数を減らすことはできません 。出力の スループット を高めるためのようです。 近い時刻で発生したログメッセージでも、複数のログストリームに分散して出力されるため、ロググループから特定のログを探すのは難しいです。ログストリームを横断して時系列にログを見たり、特定のログを探したい場合は CloudWatch Logs Insights を利用するのが便利です。以下の公式ブログや re:Post 投稿が参考になります。 Amazon CloudWatch Logs による AWS WAF ログの分析 https://aws.amazon.com/jp/blogs/news/analyzing-aws-waf-logs-in-amazon-cloudwatch-logs/ CloudWatch または Amazon S3 に保存されている AWS WAF ログを分析するオプションは何ですか? https://repost.aws/ja/knowledge-center/waf-analyze-logs-stored-cloudwatch-s3 その6: ログに Cookie ヘッダーが記録されてしまう WAF Web ACL のログを出力すると、 httpRequest.headers フィールドにリク エス トヘッダーが記録されます。つまり、 クライアントが送信した Cookie も記録されてしまいます 。 (スクリーンキャプチャの値はダミーです) 例えば分析のためにログを出力したり、共有したりすると有効なセッション ID などセンシティブな情報が漏えいするリスクがあります。 この問題への対応として、ログ出力時に 特定フィールドをマスキング することが可能です。例えば cookie ヘッダーをマスキングするには次のように設定します。 このように設定すると、出力されるログの cookie ヘッダーは REDACTED という文字列に置き換えられます。 その7: ログ出力条件の EXCLUDED_AS_COUNT とは何か ログを出力する場合、アクションが特定の条件に該当する場合のみ出力するように設定できます。リク エス トが許可された場合のログも全て記録すると量が多くなってしまうので、「ブロック」時と「カウント」時のみ出力したいことがあります。 カウント時の条件は、実は COUNT と EXCLUDED_AS_COUNT の2種類があります 。基本的には COUNT 扱いと考えて良いですが、 EXCLUDED_AS_COUNT として扱われるケースが2つ、以下のブログで説明されています。 AWS WAF のログ分析に関する考慮事項 https://aws.amazon.com/jp/blogs/news/aws-waf-log-analysis-considerations/ マネージドルールグループで ”Set all rule actions to count” で Count に設定した場合 マネージドルールグループで個別のルールを Count に設定した場合 ただし上の AWS のブログは情報が古く、現在個別のルールを Count に設定した場合の動きは少々異なるようです( 参照 )。簡単にまとめると、以下のようになると理解しています: 2022 年 10 月 27 日より前に、 WAF ルールの JSON では ExcludedRules が利用でき、これに含めた個別ルールは EXCLUDED_AS_COUNT 扱いになる マネジメントコンソールで個別ルールを Count に設定すると、 EXCLUDED_AS_COUNT 扱いになる 2022 年 10 月 27 日以降は、 WAF ルールの JSON で ExcludedRules に含めた個別ルールは変わらず EXCLUDED_AS_COUNT 扱いになる WAF ルールの JSON で RuleActionOverrides が新しく利用でき、オーバーライド先をカウントにした場合は COUNT 扱いになる マネジメントコンソールで個別ルールを Count に設定(過去に作成したルールの編集も含めて)すると、 COUNT 扱いに変わる この動きを意識してログ出力条件を作成すると良いと思います。 その8: コンソールで作成したルールを JSON 出力すると IaC での書き方がわかる CloudFormation もしくは CDK で複雑な条件の Web ACL を作成する場合、書き方が分からずに困ることがあります。 例えば「 URI パスが /file/upload 以外へのリク エス トでボディサイズが 100 KB 以上の場合にブロックする」ルールは、CDK だとこんな感じで書くことになります。(ルール部分のみ) { name: "SizeConstraint" , priority: 10 , statement: { andStatement: { statements: [ { notStatement: { statement: { byteMatchStatement: { searchString: "/file/upload" , fieldToMatch: { uriPath: {} , } , textTransformations: [ { priority: 0 , type : "NONE" , } , ] , positionalConstraint: "EXACTLY" , } , } , } , } , { sizeConstraintStatement: { fieldToMatch: { body: { oversizeHandling: "CONTINUE" , } , } , comparisonOperator: "GE" , size: 100 * 1000 , textTransformations: [ { priority: 0 , type : "NONE" , } , ] , } , } , ] , } , } , action: { block: {} } , visibilityConfig: { sampledRequestsEnabled: true , cloudWatchMetricsEnabled: true , metricName: "SizeConstraint" , } , } , これをヒントなしで正しく書ける気がしません。一方でマネジメントコンソールでルールを作成すれば、画面の説明に従って割と分かりやすく作成できます。 そこで IaC で WAF のルールを作る場合も、まずはマネジメントコンソールで試しに作成してみて、画面で「ルール JSON エディタ」に切り替えましょう 。 JSON でのルールの書き方を表示してくれます。これをコピーして IaC で利用すると良いでしょう。(CDK に使う場合はプロパティ名の頭文字を大文字から小文字に変換する必要がありますが、自前で書くよりはずっと楽です。) ちなみにルール JSON エディタ画面の説明にもある通り、 JSON を使えばビジュアルエディタではサポートされていないような、深い階層の条件を持つルールを作ることもできます。以下の re:Post 投稿も参考になります。 複雑なカスタム AWS WAF JSON ルールを作成する方法を教えてください。 https://repost.aws/ja/knowledge-center/waf-create-complex-custom-rules さいごに ご紹介した内容はいずれも公式ドキュメントやブログに書いてあることなのですが、WAF を使い始める時は早く構成したい気持ちが先走ってなかなか網羅的にチェックはできませんね。今振り返ると最初に知っておきたかったと感じたことをまとめてみました。誰かの参考になれば嬉しいです。 記事の中に掲載したリンクで特におすすめのものを再掲しておきます。 コアルールセット (CRS) マネージドルールグループ https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/aws-managed-rule-groups-baseline.html#aws-managed-rule-groups-baseline-crs (どのようなルールで検査を行うのか、利用前に一通り把握しておきましょう) AWS WAF によってブロックされているファイルをアップロードするにはどうすればよいですか? https://repost.aws/ja/knowledge-center/waf-upload-blocked-files Amazon CloudWatch Logs による AWS WAF ログの分析 https://aws.amazon.com/jp/blogs/news/analyzing-aws-waf-logs-in-amazon-cloudwatch-logs/ CloudWatch または Amazon S3 に保存されている AWS WAF ログを分析するオプションは何ですか? https://repost.aws/ja/knowledge-center/waf-analyze-logs-stored-cloudwatch-s3 ルールグループ内のアクションオーバーライド https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/web-acl-rule-group-override-options.html 複雑なカスタム AWS WAF JSON ルールを作成する方法を教えてください。 https://repost.aws/ja/knowledge-center/waf-create-complex-custom-rules 以下は、この記事では触れませんでしたが参考となる re:Post の投稿です。 AWS WAF ルールでブロックされているファイルのアップロードを、ルールを除外せずに明示的に許可するには、どうすればよいですか? https://repost.aws/ja/knowledge-center/waf-explicit-allow-file-uploads AWS WAF の HTTP リク エス トの XSS または SQLi 検査から特定の URI を除外する方法を教えてください。 https://repost.aws/ja/knowledge-center/waf-exclude-specific-requests-inspection AWS WAF を利用して DDoS 攻撃を緩和するにはどうすればいいですか? https://repost.aws/ja/knowledge-center/waf-mitigate-ddos-attacks 私たちは同じチームで働いてくれる仲間を大募集しています!たくさんのご応募をお待ちしています。 セキュリティエンジニア 執筆: @kou.kinyo 、レビュー: 寺山 輝 (@terayama.akira) ( Shodo で執筆されました )
こんにちは、ISID 金融ソリューション事業部の岡崎です。 今回はUE5.2の新機能であるプロシージャルコンテンツ生成 フレームワーク (PCG:Procedural Content Generation Framework)の紹介を行います。 はじめに PCGとはコンテンツ生成に関するルールを作成し、そのルールに沿って植物や岩などのアセットを大量に配置できる機能です。 アセットの種類や位置、大きさなどを指示するルールを作成することで制作時間を大幅に削減でき、 ルールを流用することで大規模なワールド作成なども行えます。 また、変更に対して柔軟に対応しやすいという点もメリットになります。 今回は Gaea という3D地形生成ツールを使用して ランドスケープ を作成しながら、PCGを使用してフォトリアルな森の作り方を説明します。 検証環境/ツール OS: Windows 11 pro GPU : NVIDIA GeForce RTX 4070 Ti Game Engine: Unreal Engine 5.2.0 実装手順 Gaea上で ランドスケープ を作成 ハイトマップをUE5プロジェクトにインポート PCGを使用して森を生成 1. Gaea上で ランドスケープ を作成 まずはUE上でPCGを使用する前に、木々を生やすための土地( ランドスケープ )を作成します。 UEにも ランドスケープ を造形するツールは搭載しているのですが、今回は Gaea という3D地形生成を使用して ランドスケープ を生成します。 こちらの記事 でUEの ランドスケープ 機能を紹介しているので、ぜひこちらもご覧ください。 まずは Gaea をインストールします。 解像度が1024x1024までは無料で使うことができるので、今回は無料版を使用します。 Gaeaを開くと下記のような画面になります。 左のタブの「Geo Primitives」から使用したい地形のモデルを ドラッグ&ドロップ します。 また、いくつかの地形モデルを組み合わせることもできます。 下の図では「Range(山岳)」と「Rocky(岩肌)」のノードを「Combine」を使用して組み合わせてみました。 「Range(山岳)」 「Rocky(岩肌)」 組み合わせた地形 今回の ランドスケープ では、もう少し平地の部分も欲しかったので、 「Range」と「Worselands」の地形ノードを組み合わせて使用しました。 また組み合わせた地形に「FractalTerraces(地層)」のノードや「Erosion(浸食)」のノードを組み合わせ、 よりイメージに近い地形を作成しました。 詳しい地形ノードや効果のノードに関しては こちらの公式リファレンス を参照しました。 次にこれまで作成した地形をUEで使用するためにエクスポート作業を行います。 最終的に作成した「Erosion(浸食)」のノードを右クリックし、Renameを行います。 今回私は「MyWorld」という名前に変更しました。 続いて「MyWorld」を再度右クリックし、Mark for Exportを押下します。 右側のタブにエクスポートの詳細が表示されるので、出力形式を「. png 」に変更します。 また、 UEで推奨しているランドスケープの解像度の値 は1009なので、「Resolution」を「1009」に変更します。 GaeaからUEにデータを移行する際、縦横の比率の変更をする必要があります。 右側の詳細画面のタブを「MyWorld Properties」に切り替え、地形の縦横・高低比率を調査するための「Lv」のボタンを押下します。 すると下記画面のように作成した地形の縦横比率が変わった状態のサンプルが表示されます。 デフォルトのままエクスポートをすると、この状態の地形がUEに入ってしまうので設定を変えていきます。 「Lv」の下にある「Clmp」ボタンを押下し、「Clmp Max」の値を「25%」に変更します。 (この値は作成した ランドスケープ を見ながら適宜調整します) これで元のモデルと同じ縦横比率になるので、このままBuildタブに戻り、「Start Build」を行いファイルを出力します。 続いて出力したファイルをUEにインポートします。 2. ハイトマップをUE5プロジェクトにインポート UEを開き選択モードから ランドスケープ モードに変更します。 新しい ランドスケープ のタブから、「ファイルからインポート」を選択します。 先ほどGaeaでエクスポートした「. png 」ファイルを選択します。 インポート設定画面で、解像度をGaeaで設定した「1009x1009」に変更してインポートします。 インポート後、 ランドスケープ が出現していないように見えますが、「ExponentalHeight」が画面にモヤをかけてしまっており、遠くの ランドスケープ が見えなくなっているだけなので、 選択モードに変更後、上下の位置を変えることで ランドスケープ が見えるようになります。 これでGaeaで作成した ランドスケープ をUE上で使うことができます。 続いて作成した ランドスケープ にPCGで森を作成します。 3. PCGを使用して森を生成 まずPCGで森を作成する前に、作成された ランドスケープ のマテリアルがデフォルトのままで味気ないので、マテリアルを割り当てます。 今回は簡易的に行うため、 アウトライナー で ランドスケープ を選択し、 ランドスケープ マテリアルに任意のマテリアルを選択しました。 次にPCGを使用するために プラグイン の設定をする必要があります。 プラグイン 設定画面から「Procedural Content Generation Framework」をオンにします。UEを再起動させて設定を反映させます。 次に今回フォトリアルな森を作成するために使用するアセットのダウンロードを行います。 Unreal マーケットプレイス から「Megascans Trees(早期アクセス)」を開きダウンロードします。 今回はヨーロッパ風の木を使用しましたが、他に何種類かあったので自分の作りたいイメージに合ったものをダウンロードします。 ダウンロードが完了するとプロジェクトのコンテンツブラウザからダウンロードした木々のアセットを表示できます。 このアセットは後で使うので一旦このまま置いておきます。 UEの編集画面より、PCGで森を生成するための範囲を決めるために「PCGVolume」というアセットを生成します。 画面上部よりアセット追加ボタンを押し、検索して生成してください。 生成した範囲をワールド上に設置し、森を作成したい大きさに任意で設定します。 次に、この範囲とPCGで作成するルールを記載するアセットを紐づけます。 まずルールを記載するためにコンテンツブラウザ内に「PCGグラフ」を作成します。今回は「MyWorldPCG」と 命名 しました。 次に編集画面で アウトライナー より先ほど範囲を決めるために作成した「PCGVolume」を選択し、子要素の「PCGComponent」を選択します。 選択すると、 インスタンス 直下にGraphを選択する欄があるので、先ほど作成した「MyWorldPCG」を選択し、ルールと範囲を紐づけます。 続いて「MyWorldPCG」を編集してルールを作成します。 「MyWorldPCG」を開くとブループリントの編集画面のようなものがでてきます。 まずは「 Surface Sampler」というノードを作成し、「Input」の「Landscape」ピンと繋ぎます。 このノードは Surface (面)に対してルールを適応させていくことができます。 「 Surface Sampler」を選択し、右側の設定画面から「Points Per Squared Meter 」の値を変更します。 この値は、 平方メートルあたりのポイント数を設定できます。今回は一旦「0.01」としました。 次に「Transform Point」ノードを作成し、右につなげます。 ここではアセットの大きさや向きを設定できます。 「Rotation Max」のZ値を360に設定します。これにより生成されたアセットの向きがランダムになります。 また「Scale Min」を0.7に設定します。これにより生成されたアセットの大きさが70~100%の間でランダムになります。 この「Transform Point」を選択した状態で、キーボードの「D」を押下します。 するとノードの右上に水色のマークがついていることを確認できます。これは デバッグ 状態で表示できるモードであるという印です。 UE編集画面に戻ると、「Transform Point」で生成したアセット生成ポイントが デバッグ 状態で見ることができます。(黒や白でブロックが置かれている部分に指定したアセットが表示される予定) 今作成した生成ポイントには大きな木を配置する予定なので、 続けて、小さな木を配置する用のポイントも追加します。 「 Surface Sampler」と「Transform Point」をコピーします。 「 Surface Sampler」の「Points Per Squared Meter 」の値を「0.1」にします。これにより先ほど作成した大きな木用のポイントの10倍の数のアセットが生成できます。 さらに「Point Extents」でブロックの大きさを変更します。デフォルトが「100」だったので半分の「50」に設定します。 この段階でUE編集画面に戻ると下記画像のように変更されます。 同様にさらに小さな草を生やすためのノードもコピーしました。 次に作成したポイントに実際のアセットを割り当てていきます。 「Static Mesh Spawner」ノードを作成します。 右側の設定画面で「Mesh Entries」の右側のプラスボタンを押し、配列を3つ作成します。 追加した配列の内部に入っていき「Description > Static Mesh」の順に開き、先ほど マーケットプレイス から追加した木のアセットを選択します。 木のアセットは「Contents > BlackAlder > Geometry > PivotPainter」の中にあります。 選択して割り当てたら、配列の残った2つにも同様に木のアセットを選択します。 この時、この3つの木のアセットがランダムで生成されるので、使いたい3種類の木のアセットを選択してください。 UE編集画面に戻ると下記画像のように大きな木がランダムで生成されているのを確認できます。 同様に、後2つの「Static Mesh Spawner」ノードを作成します。ここでは小さい木やさらに小さい草木のアセットをそれぞれ配置します。 配置が完了すると以下のようなフォトリアルな森が完成します。 上記の方法で、 数に関しては「Points Per Squared Meter 」の値を変更し 種類に関しては「Description > Static Mesh」のメッシュを変更することで、さまざまな種類の森を簡単に作ることができます。 おわりに UE5.2の新機能であるプロシージャルコンテンツ生成 フレームワーク (PCG:Procedural Content Generation Framework)の紹介を行いました。 画像でお見せしたようなフォトリアルなワールドがとても手軽に作成できるとても便利な機能だと感じました。 ルールベースでコンテンツを生成するので編集や複製なども容易にでき、今後の開発でも色々使用していきたいです。 ルールを作成することで、森の中に道を作成したり、その道にそって草を配置することなどもできるので、 次回はもう少し深掘りしたPCGの使用方法をご紹介します。 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! ISID採用ページ 執筆: @okazaki.wataru 、レビュー: @wakamoto.ryosuke ( Shodo で執筆されました )
こんにちは、ISID 金融ソリューション事業部の岡崎です。 今回はUE5.2の新機能であるプロシージャルコンテンツ生成 フレームワーク (PCG:Procedural Content Generation Framework)の紹介を行います。 はじめに PCGとはコンテンツ生成に関するルールを作成し、そのルールに沿って植物や岩などのアセットを大量に配置できる機能です。 アセットの種類や位置、大きさなどを指示するルールを作成することで制作時間を大幅に削減でき、 ルールを流用することで大規模なワールド作成なども行えます。 また、変更に対して柔軟に対応しやすいという点もメリットになります。 今回は Gaea という3D地形生成ツールを使用して ランドスケープ を作成しながら、PCGを使用してフォトリアルな森の作り方を説明します。 検証環境/ツール OS: Windows 11 pro GPU : NVIDIA GeForce RTX 4070 Ti Game Engine: Unreal Engine 5.2.0 実装手順 Gaea上で ランドスケープ を作成 ハイトマップをUE5プロジェクトにインポート PCGを使用して森を生成 1. Gaea上で ランドスケープ を作成 まずはUE上でPCGを使用する前に、木々を生やすための土地( ランドスケープ )を作成します。 UEにも ランドスケープ を造形するツールは搭載しているのですが、今回は Gaea という3D地形生成を使用して ランドスケープ を生成します。 こちらの記事 でUEの ランドスケープ 機能を紹介しているので、ぜひこちらもご覧ください。 まずは Gaea をインストールします。 解像度が1024x1024までは無料で使うことができるので、今回は無料版を使用します。 Gaeaを開くと下記のような画面になります。 左のタブの「Geo Primitives」から使用したい地形のモデルを ドラッグ&ドロップ します。 また、いくつかの地形モデルを組み合わせることもできます。 下の図では「Range(山岳)」と「Rocky(岩肌)」のノードを「Combine」を使用して組み合わせてみました。 「Range(山岳)」 「Rocky(岩肌)」 組み合わせた地形 今回の ランドスケープ では、もう少し平地の部分も欲しかったので、 「Range」と「Worselands」の地形ノードを組み合わせて使用しました。 また組み合わせた地形に「FractalTerraces(地層)」のノードや「Erosion(浸食)」のノードを組み合わせ、 よりイメージに近い地形を作成しました。 詳しい地形ノードや効果のノードに関しては こちらの公式リファレンス を参照しました。 次にこれまで作成した地形をUEで使用するためにエクスポート作業を行います。 最終的に作成した「Erosion(浸食)」のノードを右クリックし、Renameを行います。 今回私は「MyWorld」という名前に変更しました。 続いて「MyWorld」を再度右クリックし、Mark for Exportを押下します。 右側のタブにエクスポートの詳細が表示されるので、出力形式を「. png 」に変更します。 また、 UEで推奨しているランドスケープの解像度の値 は1009なので、「Resolution」を「1009」に変更します。 GaeaからUEにデータを移行する際、縦横の比率の変更をする必要があります。 右側の詳細画面のタブを「MyWorld Properties」に切り替え、地形の縦横・高低比率を調査するための「Lv」のボタンを押下します。 すると下記画面のように作成した地形の縦横比率が変わった状態のサンプルが表示されます。 デフォルトのままエクスポートをすると、この状態の地形がUEに入ってしまうので設定を変えていきます。 「Lv」の下にある「Clmp」ボタンを押下し、「Clmp Max」の値を「25%」に変更します。 (この値は作成した ランドスケープ を見ながら適宜調整します) これで元のモデルと同じ縦横比率になるので、このままBuildタブに戻り、「Start Build」を行いファイルを出力します。 続いて出力したファイルをUEにインポートします。 2. ハイトマップをUE5プロジェクトにインポート UEを開き選択モードから ランドスケープ モードに変更します。 新しい ランドスケープ のタブから、「ファイルからインポート」を選択します。 先ほどGaeaでエクスポートした「. png 」ファイルを選択します。 インポート設定画面で、解像度をGaeaで設定した「1009x1009」に変更してインポートします。 インポート後、 ランドスケープ が出現していないように見えますが、「ExponentalHeight」が画面にモヤをかけてしまっており、遠くの ランドスケープ が見えなくなっているだけなので、 選択モードに変更後、上下の位置を変えることで ランドスケープ が見えるようになります。 これでGaeaで作成した ランドスケープ をUE上で使うことができます。 続いて作成した ランドスケープ にPCGで森を作成します。 3. PCGを使用して森を生成 まずPCGで森を作成する前に、作成された ランドスケープ のマテリアルがデフォルトのままで味気ないので、マテリアルを割り当てます。 今回は簡易的に行うため、 アウトライナー で ランドスケープ を選択し、 ランドスケープ マテリアルに任意のマテリアルを選択しました。 次にPCGを使用するために プラグイン の設定をする必要があります。 プラグイン 設定画面から「Procedural Content Generation Framework」をオンにします。UEを再起動させて設定を反映させます。 次に今回フォトリアルな森を作成するために使用するアセットのダウンロードを行います。 Unreal マーケットプレイス から「Megascans Trees(早期アクセス)」を開きダウンロードします。 今回はヨーロッパ風の木を使用しましたが、他に何種類かあったので自分の作りたいイメージに合ったものをダウンロードします。 ダウンロードが完了するとプロジェクトのコンテンツブラウザからダウンロードした木々のアセットを表示できます。 このアセットは後で使うので一旦このまま置いておきます。 UEの編集画面より、PCGで森を生成するための範囲を決めるために「PCGVolume」というアセットを生成します。 画面上部よりアセット追加ボタンを押し、検索して生成してください。 生成した範囲をワールド上に設置し、森を作成したい大きさに任意で設定します。 次に、この範囲とPCGで作成するルールを記載するアセットを紐づけます。 まずルールを記載するためにコンテンツブラウザ内に「PCGグラフ」を作成します。今回は「MyWorldPCG」と 命名 しました。 次に編集画面で アウトライナー より先ほど範囲を決めるために作成した「PCGVolume」を選択し、子要素の「PCGComponent」を選択します。 選択すると、 インスタンス 直下にGraphを選択する欄があるので、先ほど作成した「MyWorldPCG」を選択し、ルールと範囲を紐づけます。 続いて「MyWorldPCG」を編集してルールを作成します。 「MyWorldPCG」を開くとブループリントの編集画面のようなものがでてきます。 まずは「 Surface Sampler」というノードを作成し、「Input」の「Landscape」ピンと繋ぎます。 このノードは Surface (面)に対してルールを適応させていくことができます。 「 Surface Sampler」を選択し、右側の設定画面から「Points Per Squared Meter 」の値を変更します。 この値は、 平方メートルあたりのポイント数を設定できます。今回は一旦「0.01」としました。 次に「Transform Point」ノードを作成し、右につなげます。 ここではアセットの大きさや向きを設定できます。 「Rotation Max」のZ値を360に設定します。これにより生成されたアセットの向きがランダムになります。 また「Scale Min」を0.7に設定します。これにより生成されたアセットの大きさが70~100%の間でランダムになります。 この「Transform Point」を選択した状態で、キーボードの「D」を押下します。 するとノードの右上に水色のマークがついていることを確認できます。これは デバッグ 状態で表示できるモードであるという印です。 UE編集画面に戻ると、「Transform Point」で生成したアセット生成ポイントが デバッグ 状態で見ることができます。(黒や白でブロックが置かれている部分に指定したアセットが表示される予定) 今作成した生成ポイントには大きな木を配置する予定なので、 続けて、小さな木を配置する用のポイントも追加します。 「 Surface Sampler」と「Transform Point」をコピーします。 「 Surface Sampler」の「Points Per Squared Meter 」の値を「0.1」にします。これにより先ほど作成した大きな木用のポイントの10倍の数のアセットが生成できます。 さらに「Point Extents」でブロックの大きさを変更します。デフォルトが「100」だったので半分の「50」に設定します。 この段階でUE編集画面に戻ると下記画像のように変更されます。 同様にさらに小さな草を生やすためのノードもコピーしました。 次に作成したポイントに実際のアセットを割り当てていきます。 「Static Mesh Spawner」ノードを作成します。 右側の設定画面で「Mesh Entries」の右側のプラスボタンを押し、配列を3つ作成します。 追加した配列の内部に入っていき「Description > Static Mesh」の順に開き、先ほど マーケットプレイス から追加した木のアセットを選択します。 木のアセットは「Contents > BlackAlder > Geometry > PivotPainter」の中にあります。 選択して割り当てたら、配列の残った2つにも同様に木のアセットを選択します。 この時、この3つの木のアセットがランダムで生成されるので、使いたい3種類の木のアセットを選択してください。 UE編集画面に戻ると下記画像のように大きな木がランダムで生成されているのを確認できます。 同様に、後2つの「Static Mesh Spawner」ノードを作成します。ここでは小さい木やさらに小さい草木のアセットをそれぞれ配置します。 配置が完了すると以下のようなフォトリアルな森が完成します。 上記の方法で、 数に関しては「Points Per Squared Meter 」の値を変更し 種類に関しては「Description > Static Mesh」のメッシュを変更することで、さまざまな種類の森を簡単に作ることができます。 おわりに UE5.2の新機能であるプロシージャルコンテンツ生成 フレームワーク (PCG:Procedural Content Generation Framework)の紹介を行いました。 画像でお見せしたようなフォトリアルなワールドがとても手軽に作成できるとても便利な機能だと感じました。 ルールベースでコンテンツを生成するので編集や複製なども容易にでき、今後の開発でも色々使用していきたいです。 ルールを作成することで、森の中に道を作成したり、その道にそって草を配置することなどもできるので、 次回はもう少し深掘りしたPCGの使用方法をご紹介します。 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! ISID採用ページ 執筆: @okazaki.wataru 、レビュー: @wakamoto.ryosuke ( Shodo で執筆されました )
こんにちは、グループ経営ソリューション( GMS )事業部 グループ経営 コンサルティング 第2ユニット 一般会計 コンサルティング 部 第2グループ、3年目の塚本です。 普段は会計ソリューションである Ci*Xシリーズ の新規開発を担当しています。 ※ Ci*Xシリーズの導入に関して気になる方は川島さんの以下の記事を参考にしてください。 SIerで自社製品導入をする新卒5年目(※IT経験なし)の働き方と今感じること~ちょこっと就活の話も添えて~ 本記事では、業務内容や 1 週間の過ごし方など、私の主な働き方についてざっくりとご紹介します。 IT 企業への就職を検討されている学生の方や、ISID にご興味をお持ちの方の参考になれば幸いです。 目次 目次 自己紹介 仕事内容 新規開発の作業工程 要件定義 設計 実装・単体テスト 結合テスト 製品化 配属後からこれまでの流れ 2年間働いてみて 最後に 自己紹介 私は工学部電気電子系学科出身で、4年間物理学を学んでいました。私の学部では通常であればそのまま院に進学し、メーカーや電気関係の企業に就職することがほとんどです。しかし、院には進学せず学部卒で2021 年に新卒入社しました。入社後に半年間の研修を経て、グループ経営ソリューション事業部に配属されました。 私が院に進学せず、IT企業を目指すことになったきっかけは2つあります。 1つ目は私が所属していた学部では毎年95%以上が院に進学しているという理由から、院に進学するのは当たり前という流れがあり、"〇〇の研究がしたい"というモチベーションの人がほとんどいなかったことです。モチベーション高く仕事をしている企業に就職した方が自己成長に繋がるのではないかと考えました。 2つ目はアルバイト先の塾で、生徒の点数ランキング作成の仕事を手書きという原始的な方法からエクセルの関数などを使って自動化したことにやりがいを感じたことです。 また、大学進学時に経済学部や 経営学 部に進学するか迷っていたこともありもともと会計には興味があったので、グループ経営ソリューション事業部に希望して希望通り配属されています。 自己紹介はこれくらいにして、これから私が所属する第2グループの業務のうち 新規開発 を中心にお話しします。 仕事内容 私が所属する一般会計 コンサルティング 部では自社パッケージの会計システムである Ci*Xシリーズ の 導入・新規開発・保守 を行っています。 その中でも第2グループでは新規開発・運用・保守を行っていて、私は主に 新規開発 に携わりました。 新規開発の作業工程 私のプロジェクトでは、新規開発の作業工程をざっくり分けると以下の8工程です。 このプロジェクトではそれぞれの工程(赤い箱:私が経験した工程)でどのようなことを行ったかを配属から2年の範囲内で説明します。 ※私が経験した内容のみに絞って説明しているので各工程で他に必要なことがあることに注意してください。 要件定義 要件定義では、ユーザーの要求をシステムで実現することを目的に、どのような機能を開発すれば要求を満たすことができるのかを考えるフェーズです。そして、洗い出された要件を要件定義書に文書化します。 メッセージ入力機能を例に挙げると、入力したメッセージをコピー、削除、送信取消、転送できる必要があるかなどを考えます。また、その領域に関して書籍やインターネットで調査し、それでもわからない論点などはその領域に詳しい方に質問をしました。 設計 設計は、要件定義書に記載された要件を満たすように機能を細かく考えるフェーズです。 具体的には、システムを動かす際に矛盾が生じないように、ユーザーがどのように機能を使うか( ユースケース 定義)、画面構成はどうするか、計算ロジックはどうするかなどを考えて以下の資料に記載します。 ユースケース 定義書(ユーザー目線でできることをまとめた資料) ドメイン モデル図(概念クラスの関係性の図をまとめた資料) 概念クラス(概念とその属性をまとめた資料) 画面定義書(画面のイメージや制御についてまとめた資料) ロジック定義書(複雑な処理の仕組みについてまとめた資料) 結合テスト 仕様書( 結合テスト に使用するテストケースをまとめた資料) 実装・ 単体テスト 実装・ 単体テスト は、設計書の設計内容を満たすように実際にコーディングし、設計書通りに動作するか確認するフェーズです。 実装で用いる技術要素は以下です。 バックエンド技術( Java , Spring Boot, Thymeleaf, PostgreSQL 等) フロントエンド技術( HTML5 、TypeScript、Vue.js 等) 結合テスト 結合テスト は、設計で作成した 結合テスト 仕様書に記載されたテストケースに従ってシステムが正しく動作しているかを検証するフェーズです。正しく動いていない場合や、設計書・ 結合テスト 仕様書が間違っている場合は欠陥として報告します。 製品化 製品化ではユーザーがシステムの操作で分からないときに閲覧できるマニュアルを作成します。 マニュアル作成 配属後からこれまでの流れ 配属後半年は簡単なタスクで製品のキャッチアップや技術のレベルアップを進め、 結合テスト を経験しました。その後、1年くらいで要件定義から実装・ 単体テスト までを経験することが出来ました。 業務の種類にもよりますが、まだマネジメント業務がないため MTG は比較的少なく作業がメインです。また、品質の高い実装力をつけるため、隔週で勉強会に参加して自己研鑽しています。 2年間働いてみて 配属から約1年半はテレワークメインでした。メンバーと直接的なコミュニケーションを取る機会がかなり少なかったため、質問しづらい関係性で業務に詰まったときは少し辛い環境でした。しかし、半年くらい前から出社日を合わせてプロジェクトメンバーと直接コミュニケーションを取ったことでリモートワークでも以前より質問がしやすい環境になり、今はかなりいい環境で働けていると思います。 業務ではシステムの新規開発で要件定義から 結合テスト までの工程を経験できたので、同年代の開発者の中では システム開発 に関して凄く幅広い経験をでき、力がかなりつきました。その経験は多くの知識(会計知識から開発の技術知識など)が必要なため、学習などで補ったりすることが大変ではありました。しかし、たくさん知識が付いたことで配属当初では考えられないほどの自信が付き、自己成長によるやりがいも感じています。また、 システム開発 では定番かもしれませんが、自分で設計した機能が実装されて実際に動くところを見ることでもやりがいを感じました。 先輩社員から、「この業界は3年間がインプット期間、4年目以降はアウトプットで結果を出す」と言われています。そのおかげて1つ1つのタスクで色々調べたりメモを残したりしてたくさんインプットできています。4年目からのプレッシャーが少しはありますが、それ以上にこの3年間の成長を実感しました。 自分がやりたいことをできる部署に配属してもらい、配属先でもやりたい業務をたくさん任せてもらいました。自分がやりたい・楽しいと思える仕事にたくさん関わることができ、最高のモチベーションで仕事をすることができています。これからもより楽しく仕事をやっていきたいと思っています。 最後に 就活生のみなさんには、やりたいことを明確にしてほしいと思っています。この記事を見て、第2グループでやっていることと自分のやりたいことが一致するかをぜひ考えてみてください。ISIDではやりたいことを発信していると、やらせてもらえることが多い環境だと思うので少しでもやりたいことができそうだと思った方は、ぜひご応募いただければなと思います。 www.isid.co.jp 執筆: @tsukamoto.sou 、レビュー: @sato.taichi ( Shodo で執筆されました )
こんにちは、グループ経営ソリューション( GMS )事業部 グループ経営 コンサルティング 第2ユニット 一般会計 コンサルティング 部 第2グループ、3年目の塚本です。 普段は会計ソリューションである Ci*Xシリーズ の新規開発を担当しています。 ※ Ci*Xシリーズの導入に関して気になる方は川島さんの以下の記事を参考にしてください。 SIerで自社製品導入をする新卒5年目(※IT経験なし)の働き方と今感じること~ちょこっと就活の話も添えて~ 本記事では、業務内容や 1 週間の過ごし方など、私の主な働き方についてざっくりとご紹介します。 IT 企業への就職を検討されている学生の方や、ISID にご興味をお持ちの方の参考になれば幸いです。 目次 目次 自己紹介 仕事内容 新規開発の作業工程 要件定義 設計 実装・単体テスト 結合テスト 製品化 配属後からこれまでの流れ 2年間働いてみて 最後に 自己紹介 私は工学部電気電子系学科出身で、4年間物理学を学んでいました。私の学部では通常であればそのまま院に進学し、メーカーや電気関係の企業に就職することがほとんどです。しかし、院には進学せず学部卒で2021 年に新卒入社しました。入社後に半年間の研修を経て、グループ経営ソリューション事業部に配属されました。 私が院に進学せず、IT企業を目指すことになったきっかけは2つあります。 1つ目は私が所属していた学部では毎年95%以上が院に進学しているという理由から、院に進学するのは当たり前という流れがあり、"〇〇の研究がしたい"というモチベーションの人がほとんどいなかったことです。モチベーション高く仕事をしている企業に就職した方が自己成長に繋がるのではないかと考えました。 2つ目はアルバイト先の塾で、生徒の点数ランキング作成の仕事を手書きという原始的な方法からエクセルの関数などを使って自動化したことにやりがいを感じたことです。 また、大学進学時に経済学部や 経営学 部に進学するか迷っていたこともありもともと会計には興味があったので、グループ経営ソリューション事業部に希望して希望通り配属されています。 自己紹介はこれくらいにして、これから私が所属する第2グループの業務のうち 新規開発 を中心にお話しします。 仕事内容 私が所属する一般会計 コンサルティング 部では自社パッケージの会計システムである Ci*Xシリーズ の 導入・新規開発・保守 を行っています。 その中でも第2グループでは新規開発・運用・保守を行っていて、私は主に 新規開発 に携わりました。 新規開発の作業工程 私のプロジェクトでは、新規開発の作業工程をざっくり分けると以下の8工程です。 このプロジェクトではそれぞれの工程(赤い箱:私が経験した工程)でどのようなことを行ったかを配属から2年の範囲内で説明します。 ※私が経験した内容のみに絞って説明しているので各工程で他に必要なことがあることに注意してください。 要件定義 要件定義では、ユーザーの要求をシステムで実現することを目的に、どのような機能を開発すれば要求を満たすことができるのかを考えるフェーズです。そして、洗い出された要件を要件定義書に文書化します。 メッセージ入力機能を例に挙げると、入力したメッセージをコピー、削除、送信取消、転送できる必要があるかなどを考えます。また、その領域に関して書籍やインターネットで調査し、それでもわからない論点などはその領域に詳しい方に質問をしました。 設計 設計は、要件定義書に記載された要件を満たすように機能を細かく考えるフェーズです。 具体的には、システムを動かす際に矛盾が生じないように、ユーザーがどのように機能を使うか( ユースケース 定義)、画面構成はどうするか、計算ロジックはどうするかなどを考えて以下の資料に記載します。 ユースケース 定義書(ユーザー目線でできることをまとめた資料) ドメイン モデル図(概念クラスの関係性の図をまとめた資料) 概念クラス(概念とその属性をまとめた資料) 画面定義書(画面のイメージや制御についてまとめた資料) ロジック定義書(複雑な処理の仕組みについてまとめた資料) 結合テスト 仕様書( 結合テスト に使用するテストケースをまとめた資料) 実装・ 単体テスト 実装・ 単体テスト は、設計書の設計内容を満たすように実際にコーディングし、設計書通りに動作するか確認するフェーズです。 実装で用いる技術要素は以下です。 バックエンド技術( Java , Spring Boot, Thymeleaf, PostgreSQL 等) フロントエンド技術( HTML5 、TypeScript、Vue.js 等) 結合テスト 結合テスト は、設計で作成した 結合テスト 仕様書に記載されたテストケースに従ってシステムが正しく動作しているかを検証するフェーズです。正しく動いていない場合や、設計書・ 結合テスト 仕様書が間違っている場合は欠陥として報告します。 製品化 製品化ではユーザーがシステムの操作で分からないときに閲覧できるマニュアルを作成します。 マニュアル作成 配属後からこれまでの流れ 配属後半年は簡単なタスクで製品のキャッチアップや技術のレベルアップを進め、 結合テスト を経験しました。その後、1年くらいで要件定義から実装・ 単体テスト までを経験することが出来ました。 業務の種類にもよりますが、まだマネジメント業務がないため MTG は比較的少なく作業がメインです。また、品質の高い実装力をつけるため、隔週で勉強会に参加して自己研鑽しています。 2年間働いてみて 配属から約1年半はテレワークメインでした。メンバーと直接的なコミュニケーションを取る機会がかなり少なかったため、質問しづらい関係性で業務に詰まったときは少し辛い環境でした。しかし、半年くらい前から出社日を合わせてプロジェクトメンバーと直接コミュニケーションを取ったことでリモートワークでも以前より質問がしやすい環境になり、今はかなりいい環境で働けていると思います。 業務ではシステムの新規開発で要件定義から 結合テスト までの工程を経験できたので、同年代の開発者の中では システム開発 に関して凄く幅広い経験をでき、力がかなりつきました。その経験は多くの知識(会計知識から開発の技術知識など)が必要なため、学習などで補ったりすることが大変ではありました。しかし、たくさん知識が付いたことで配属当初では考えられないほどの自信が付き、自己成長によるやりがいも感じています。また、 システム開発 では定番かもしれませんが、自分で設計した機能が実装されて実際に動くところを見ることでもやりがいを感じました。 先輩社員から、「この業界は3年間がインプット期間、4年目以降はアウトプットで結果を出す」と言われています。そのおかげて1つ1つのタスクで色々調べたりメモを残したりしてたくさんインプットできています。4年目からのプレッシャーが少しはありますが、それ以上にこの3年間の成長を実感しました。 自分がやりたいことをできる部署に配属してもらい、配属先でもやりたい業務をたくさん任せてもらいました。自分がやりたい・楽しいと思える仕事にたくさん関わることができ、最高のモチベーションで仕事をすることができています。これからもより楽しく仕事をやっていきたいと思っています。 最後に 就活生のみなさんには、やりたいことを明確にしてほしいと思っています。この記事を見て、第2グループでやっていることと自分のやりたいことが一致するかをぜひ考えてみてください。ISIDではやりたいことを発信していると、やらせてもらえることが多い環境だと思うので少しでもやりたいことができそうだと思った方は、ぜひご応募いただければなと思います。 www.isid.co.jp 執筆: @tsukamoto.sou 、レビュー: @sato.taichi ( Shodo で執筆されました )
こんにちは。ISID 金融ソリューション事業部の若本です。 先日、GPT-4から発展し、 画像も扱うことができるGPT-4 with vision(GPT-4V)が発表 されました。GPT-4Vは大規模マルチモーダルモデル(LMMs: Large multimodal models)と呼ばれるAIモデルの一種であり、GPT-4の入力として「画像」を拡張したものになります。 今日は Microsoft Researchの論文[1]を中心に、Open AIの発表したSystem Card[2]も踏まえ、GPT-4Vでできることや苦手とすること、そして実用上の制限について解説します。 GPT-4Vの特徴 ① 画像とテキストを入力にできる GPT-4Vでは、GPT-4のテキスト入力に加えて画像も入力することが可能になりました。 画像は複数枚入力することが可能であり、かつ、画像とテキストを任意に交互に組み合わせて入力できます。 ② 画像に関する常識を理解している 画像の中の情報を判別するだけでなく、視覚的な常識に基づいて推論を行うことができます。 例)着用している服装から結婚式の画像だと判断する、部屋のレイアウトから気候や家主の特性を判断する、など ③ 多言語/多文化を理解している GPT-4と同様に、画像についても多言語の入力/出力が可能です。例では、手書き文字に近い崩れたフォントについても正しく理解し、多言語で出力されています。 また、特定の文化圏に関する画像についても理解し説明できることが論文中で示されています。 ④ 感情を理解している 画像中の人間の表情から感情を識別できます。他にも、入力した画像コンテンツがどのような印象を相手に与えるのかといった視覚的な感情も解釈することができます。 また、ネット ミーム の説明などユーモアを理解する能力を持っていることも報告されています。 GPT-4Vができるタスク ① 画像/ビデオの説明 撮影条件に大きく左右されず、画像について説明することができます。画像全体のマクロな説明から、画像内の特定のオブジェクトについてのミクロな説明も可能です。 また、フレームごとに画像を与えることで、ビデオも入力し説明できます。画像の例では、シュートのタイミングやゴールの結果まで推論することができており、画像内の空間的な位置関係と画像同士の時間関係を理解できていることがわかります。 ② 物体の位置特定 画像中の物体の位置や、その物体が何か特定できます。画像の例では、画像内に映る複数人の人物の位置を特定し、それぞれ位置座標と説明を出力しています。 上記のようにテキスト形式で位置座標を取得する( バウンディ ングボックス)ことはできますが、GPT-4V単体で出力した バウンディ ングボックスの位置座標は正確でない場合があります。ただし、これはpromptによって改善可能です。 ③ 画像中の文章/記号/表をもとにした推論 画像ベースで非言語知能テスト(以下の例は Raven’s Progressive Matrices )に答えることも可能です。画像内の文章や記号を理解し、解答することが可能です。 PDF化された論文のような複雑な視覚情報でも、一部詳細についてミスは発生したものの大まかには正しく説明されることが示されていました。これらの理解能力を応用することで、Web ブラウジング のようなエージェント操作も実行できる可能性があることが示されています。 ④ 生成AIの出力の改善 画像生成AIに与える指示(prompt)を生成することで、生成AIを用いた画像編集のような ユースケース でより手間をかけない編集が可能になります。画像の例では、暗いトーンでより表紙らしい画像にするための指示をGPT-4Vを用いて生成しています。 ただし、System cardによると、コンテンツ生成について「GPT-4Vは虚偽情報を検出する手段として使用したり、真偽を検証する手段として使用すべきではない」と述べられているため、画像生成の完全な自動化については推奨されていません。 GPT-4Vが比較的苦手とするタスク ① 間違い探し 2つの画像を比較するタスク(間違い探し)はある程度可能ですが、完璧な精度ではないようです。 ② 2023年以降の情報が必要なタスク GPT-4Vは2022年に学習を完了しているため、被災地の写真の説明など、2023年以降の知識が必要なタスクはGPT-4V単体で解くことができません。論文中では、Bing Image Search プラグイン を用いて関連画像を検索した後、GPT-4Vに説明させています。 ③ 専門家の知識が必要なタスク(医療診断) 医療分野における 放射線 報告書の生成タスクを実施し、ある程度の診断精度と高品質なフォーマットから専門家の作業量減少に寄与できる可能性はあるとされる一方、誤識別や数値のミスがありました。 System Cardにおいても、専門家の検証の結果、「医療領域において完璧なパフォーマンスではなく、現在のバージョンのGPT-4Vは医療を遂行するための専門的な医療アド バイス 、診断、治療、判断を代替するには適していない」と結論付けています。 ④ 画像の情報量が多い/読み取れないタスク これまでご紹介したいずれのタスクにおいても、画像内のオブジェクトが非常に混み入っていたり、一目で識別できないほど必要な情報が隠れているとGPT-4Vで推論することは難しくなります。特に、物体のカウントや前述の物体位置検出などでは情報量の多い画像において精度が悪化していました。 制限 Open AIにより、下記のようなクエリには応答しないようチューニングが施されているようです[2]。 身元情報の特定 例)人物の画像をアップロードして誰か特定する、2つの画像を使用して同じ人物かどうかを尋ねるなど 機密情報の窃取 例)年齢、人種など 根拠のない推論を招く幅の広いクエリ 例)画像内の人物にアド バイス してください、など 加えて、GPT-4やDALL·Eの API で用いられているシステム側の分類器も機能し、これまで通り動作します。 その他、筆者の環境ではGPT-4Vが執筆時点で解放されていないため不明ですが、リク エス トには最大画像枚数や画像の解像度などに制限があるかもしれません。 おわりに 今回は、論文をベースにGPT-4Vのできることやその特徴についてご紹介しました。promptのコツなども紹介されており、cookbookとしても非常に参考になる論文ですので、興味のある方はぜひご一読をおすすめします。 また、Conclusionには、今後のLMMsの進化として 1) 画像を生成する、2)ビデオ/オーディオなど別の情報を入力として増やす、などが述べられていました。今後、より進化したLMMsの登場により、さらに広範囲に我々の生活にAIが浸透していくことが期待されます。 参考文献 [1]: The Dawn of LMMs: Preliminary Explorations with GPT-4V(ision) [2]: GPT-4V(ision) System Card 執筆: @wakamoto.ryosuke 、レビュー: @yamada.y ( Shodo で執筆されました )
こんにちは。ISID 金融ソリューション事業部の若本です。 先日、GPT-4から発展し、 画像も扱うことができるGPT-4 with vision(GPT-4V)が発表 されました。GPT-4Vは大規模マルチモーダルモデル(LMMs: Large multimodal models)と呼ばれるAIモデルの一種であり、GPT-4の入力として「画像」を拡張したものになります。 今日は Microsoft Researchの論文[1]を中心に、Open AIの発表したSystem Card[2]も踏まえ、GPT-4Vでできることや苦手とすること、そして実用上の制限について解説します。 GPT-4Vの特徴 ① 画像とテキストを入力にできる GPT-4Vでは、GPT-4のテキスト入力に加えて画像も入力することが可能になりました。 画像は複数枚入力することが可能であり、かつ、画像とテキストを任意に交互に組み合わせて入力できます。 ② 画像に関する常識を理解している 画像の中の情報を判別するだけでなく、視覚的な常識に基づいて推論を行うことができます。 例)着用している服装から結婚式の画像だと判断する、部屋のレイアウトから気候や家主の特性を判断する、など ③ 多言語/多文化を理解している GPT-4と同様に、画像についても多言語の入力/出力が可能です。例では、手書き文字に近い崩れたフォントについても正しく理解し、多言語で出力されています。 また、特定の文化圏に関する画像についても理解し説明できることが論文中で示されています。 ④ 感情を理解している 画像中の人間の表情から感情を識別できます。他にも、入力した画像コンテンツがどのような印象を相手に与えるのかといった視覚的な感情も解釈することができます。 また、ネット ミーム の説明などユーモアを理解する能力を持っていることも報告されています。 GPT-4Vができるタスク ① 画像/ビデオの説明 撮影条件に大きく左右されず、画像について説明することができます。画像全体のマクロな説明から、画像内の特定のオブジェクトについてのミクロな説明も可能です。 また、フレームごとに画像を与えることで、ビデオも入力し説明できます。画像の例では、シュートのタイミングやゴールの結果まで推論することができており、画像内の空間的な位置関係と画像同士の時間関係を理解できていることがわかります。 ② 物体の位置特定 画像中の物体の位置や、その物体が何か特定できます。画像の例では、画像内に映る複数人の人物の位置を特定し、それぞれ位置座標と説明を出力しています。 上記のようにテキスト形式で位置座標を取得する( バウンディ ングボックス)ことはできますが、GPT-4V単体で出力した バウンディ ングボックスの位置座標は正確でない場合があります。ただし、これはpromptによって改善可能です。 ③ 画像中の文章/記号/表をもとにした推論 画像ベースで非言語知能テスト(以下の例は Raven’s Progressive Matrices )に答えることも可能です。画像内の文章や記号を理解し、解答することが可能です。 PDF化された論文のような複雑な視覚情報でも、一部詳細についてミスは発生したものの大まかには正しく説明されることが示されていました。これらの理解能力を応用することで、Web ブラウジング のようなエージェント操作も実行できる可能性があることが示されています。 ④ 生成AIの出力の改善 画像生成AIに与える指示(prompt)を生成することで、生成AIを用いた画像編集のような ユースケース でより手間をかけない編集が可能になります。画像の例では、暗いトーンでより表紙らしい画像にするための指示をGPT-4Vを用いて生成しています。 ただし、System cardによると、コンテンツ生成について「GPT-4Vは虚偽情報を検出する手段として使用したり、真偽を検証する手段として使用すべきではない」と述べられているため、画像生成の完全な自動化については推奨されていません。 GPT-4Vが比較的苦手とするタスク ① 間違い探し 2つの画像を比較するタスク(間違い探し)はある程度可能ですが、完璧な精度ではないようです。 ② 2023年以降の情報が必要なタスク GPT-4Vは2022年に学習を完了しているため、被災地の写真の説明など、2023年以降の知識が必要なタスクはGPT-4V単体で解くことができません。論文中では、Bing Image Search プラグイン を用いて関連画像を検索した後、GPT-4Vに説明させています。 ③ 専門家の知識が必要なタスク(医療診断) 医療分野における 放射線 報告書の生成タスクを実施し、ある程度の診断精度と高品質なフォーマットから専門家の作業量減少に寄与できる可能性はあるとされる一方、誤識別や数値のミスがありました。 System Cardにおいても、専門家の検証の結果、「医療領域において完璧なパフォーマンスではなく、現在のバージョンのGPT-4Vは医療を遂行するための専門的な医療アド バイス 、診断、治療、判断を代替するには適していない」と結論付けています。 ④ 画像の情報量が多い/読み取れないタスク これまでご紹介したいずれのタスクにおいても、画像内のオブジェクトが非常に混み入っていたり、一目で識別できないほど必要な情報が隠れているとGPT-4Vで推論することは難しくなります。特に、物体のカウントや前述の物体位置検出などでは情報量の多い画像において精度が悪化していました。 制限 Open AIにより、下記のようなクエリには応答しないようチューニングが施されているようです[2]。 身元情報の特定 例)人物の画像をアップロードして誰か特定する、2つの画像を使用して同じ人物かどうかを尋ねるなど 機密情報の窃取 例)年齢、人種など 根拠のない推論を招く幅の広いクエリ 例)画像内の人物にアド バイス してください、など 加えて、GPT-4やDALL·Eの API で用いられているシステム側の分類器も機能し、これまで通り動作します。 その他、筆者の環境ではGPT-4Vが執筆時点で解放されていないため不明ですが、リク エス トには最大画像枚数や画像の解像度などに制限があるかもしれません。 おわりに 今回は、論文をベースにGPT-4Vのできることやその特徴についてご紹介しました。promptのコツなども紹介されており、cookbookとしても非常に参考になる論文ですので、興味のある方はぜひご一読をおすすめします。 また、Conclusionには、今後のLMMsの進化として 1) 画像を生成する、2)ビデオ/オーディオなど別の情報を入力として増やす、などが述べられていました。今後、より進化したLMMsの登場により、さらに広範囲に我々の生活にAIが浸透していくことが期待されます。 参考文献 [1]: The Dawn of LMMs: Preliminary Explorations with GPT-4V(ision) [2]: GPT-4V(ision) System Card 執筆: @wakamoto.ryosuke 、レビュー: @yamada.y ( Shodo で執筆されました )
こんにちは、X イノベーション 本部 ソフトウェアデザインセンター セキュリティグループの福山です。 今回は、弊社CSIRTチームの一機能として活動している「 脆弱性 管理チーム」の活動に関する内容となります。 昨今では、Log4shellやSpring4shellなど、影響範囲の広い 脆弱性 が後を絶ちません。 これらの緊急度の高い 脆弱性 情報が公開された場合を想定した、情報収集〜現場対応までのCSIRT目線での模擬訓練を、FutureVulsを含めて実施してみましたので紹介したいと思います。 FutureVulsとは FutureVulsを導入した経緯 事前準備 模擬訓練 情報収集 トリアージ 全社周知 個別周知 対応状況の確認 対応結果 見つかった課題 最後に FutureVulsとは フューチャー株式会社が開発する OSS の 脆弱性 スキャナVulsがベースになっており、組織単位で継続的に 脆弱性 管理するための 脆弱性 管理サービスです。 参考: https://vuls.biz/ FutureVulsの主な特徴についてピックアップします。 スキャンについて 検知精度、検知スピードに優れており、サーバへの負荷が軽い。 スキャナを導入せずに手動でソフトウェア情報を登録し、管理することも可能。 検出された情報について ソフトウェア情報の一括管理や、複数グループを束ねたグループセットでの横断検索が可能。 参考: グループセット 検出された 脆弱性 情報を一覧で一括管理が可能。 自動 トリアージ について 脆弱性 の危険度合いをスコアで示すCVSSによる従来の評価手法では、以下の点が考慮されていません。 脆弱性 の悪用の容易さ 実際の資産が攻撃を受ける環境にあるか 資産価値 攻撃を受けた際の業務影響度合い また、現場でどのように対応すべきかの判断がもう一段階必要となってきます。 そこで2019年12月、これらを解決する新しい評価手法「SSVC(Stakeholder-Specific Vulnerability Categorization)」が米 カーネギーメロン大学 ソフトウェア工学 研究所によって提案されました。 SSVCでは意思決定ツリーを用いて「immediate」「out_of_cycle」「scheduled」「defer」の4段階で対応優先度を導出します。 FutureVulsにはSSVCの機能が早くも導入されており、各 脆弱性 に対して4段階評価で対応優先度が自動で付与されることで、現場の負担を減らすことができます。 参考: SSVC(Stakeholder-Specific Vulnerability Categorization)を活用した脆弱性管理 FutureVulsを導入した経緯 FutureVulsを活用した 脆弱性 管理チームの緊急時運用フローを確認したい 弊社ではNIST NVD、 JVN iPediaから収集した情報と、シートに入力された各プロジェクトのソフトウェア情報を突き合わせ、該当する 脆弱性 情報の個別周知運用を行っていました。 ただし以下の課題があり、その要件を満たすべく2023年7月よりFutureVulsに本番移行することが決まりました。 <FutureVuls導入前の課題> より正確かつ最新のソフトウェア情報を管理したい 該当する 脆弱性 情報をよりタ イムリ ーに周知したい 各プロジェクトに個別に対応判断を委ねず、判断基準を設けたい 対応状況をより正確に把握したい 事前準備 訓練に使用する 脆弱性 はSpring4Shell(CVE-2022-22965)を採用 Spring4Shellの採用に至った条件は以下 仮想の 脆弱性 ではなく、既存の 脆弱性 を利用した方がやりやすい 社内で利用されているソフトウェア 擬似サーバへの CPE 登録が想定されるもの 参考: 擬似サーバとは リモートコード実行が可能な 脆弱性 で、PoCが公開されているもの 公表された時点でCVE未採番で、セキュリティパッチが公開されていないもの 事前にプロジェクトに協力を募り、3プロジェクトからの協力を取り付ける FutureVulsの擬似サーバを利用し、 CPE 形式でソフトウェア情報を登録 プロジェクトA Spring Framework 5.3.17 OracleJDK 9 Apache HTTP Server 2.4.53 Apache Tomcat 9.0.60 プロジェクトB Spring Boot 2.5.0 OpenJDK 9 nginx 1.6.0 Apache Tomcat 9.0.59 プロジェクトC Spring Framework 5.2.0 OracleJDK 8 Apache HTTP Server 2.4.52 Apache Tomcat 9.0.59 模擬訓練 模擬訓練の流れは以下となります。 情報収集 -> トリアージ -> 全社周知 -> 個別周知 -> 対応状況の確認 なお、全社周知と個別周知の役割の違いは以下です。 全社周知 個別周知 ・ゼロデイ 脆弱性 等、CVEが採番される前の段階でも情報をいち早く整理し伝える ・該当プロジェクトに直接周知することで、対応が必要であることを認識していただく ・影響を受ける条件や、PoCの再現結果を掲載する ・該当プロジェクトの対応状況を可視化する ・FutureVulsを利用しない社員向けにも周知する 以上を踏まえて、実際の訓練の内容に移ります。 情報収集 社内で利用されているソフトウェアにおいて、ゼロデイ 脆弱性 や影響範囲の広い 脆弱性 情報が公開されていないか、複数のWebサイトでチェックしています。 よく参考にしている情報発信元を紹介します。 CyberSecurityHelp:独自の 脆弱性 DBを公開しており、リスク評価、パッチの提供有無、Atack Vector 、Public exploit(実際の悪用有無)、Exploit availability(PoC、攻撃コードの有無)、回避策などの情報をタ イムリ ーに提供するサイトで、公開されるタイミングはCVE採番後。 URL: https://www.cybersecurity-help.cz/ Lunasec:米セキュリティ企業。2021年に公開されたLog4Shellの際にもブログをいち早く公開しており、影響を受ける条件、PoC、回避策などをわかりやすくブログにまとめている URL: https://www.lunasec.io/docs/blog/spring-rce-vulnerabilities/ Bleeping Computer: 脆弱性 情報を含む最新のセキュリティニュースをいち早く提供する海外サイト URL: https://www.bleepingcomputer.com/tag/vulnerability/ Security Next: 脆弱性 情報を含む最新のセキュリティニュースを日本語でいち早く提供するサイト URL: https://www.security-next.com/135304 piyolog: 脆弱性 情報を含む最新のセキュリティニュースがわかりやすく日本語で解説されたブログ URL: https://piyolog.hatenadiary.jp/entry/2022/04/01/065946 GitHub Advisory Database: GitHub Security Advisoriesで公開された 脆弱性 や、依存関係を追跡して得られた依存先ソフトウェアの 脆弱性 を一覧表示する URL: https://github.com/advisories ただし、これらはあくまで参考情報ですので、最終的に一次情報源の確認は必須です。 公的機関( JPCERT/CC 、 JVN 、 IPA 、NIST NVD) 開発元(今回はSpring) URL: https://spring.io/security/ トリアージ これまでの情報を整理した上で、全社周知要否( トリアージ )を2つの観点で実施します。 影響範囲の確認 各プロジェクトにおける利用状況を確認するため、FutureVulsのグループセットからソフトウェア名で検索します。 参考: グループセット内のソフトウェア名検索 緊急度合いの確認 脆弱性 管理チームで利用している緊急度 判断表 をもとに、緊急度を確認します。 No RCE PoC 開発元の評価 緊急度 1 可能 有 高以上 緊急 2 可能 無 高以上 高 3 不可 有 高以上 高 4 不可 無 高以上 中 5 可能 有 中以下 高 6 可能 無 中以下 中 7 不可 有 中以下 中 8 不可 無 中以下 中 9 可能 有 未評価 緊急 10 可能 無 未評価 高 11 不可 有 未評価 高 12 不可 無 未評価 中 公表時点では、No.9の「緊急」に該当しました。 トリアージ の結果、全社周知が必要と判断したため次のステップに進みます。 全社周知 全社周知の準備を進めつつ、MITRE社によるCVE採番状況のチェックもしながら状況変化をキャッチアップします。 URL: https://cve.mitre.org/cve/search_cve_list.html PoC、回避策の検証 まずはPoCを探すところからですが、例として以下の リポジトリ では、 GitHub で公開されているPoCを自動収集しています。 URL: https://github.com/nomi-sec/PoC-in-GitHub/tree/master 当時、実際に対応した際は以下のPoCが出回っており、こちらを実施しました。 LunaSec社も改善に加わっているようです。(※中には悪意のあるPoCを公開している リポジトリ もあるため、コードの中身をよく読んで、社内と隔離されたネットワーク上で実行するようにする) URL: https://github.com/reznok/Spring4Shell-POC dockerを利用するため容易に実施できるものになっています。(環境構築に時間が掛かる場合があります) また、Lunasecによると、脆弱パターンの ブラックリスト を記載したInitBinderを挿入することが緩和策になると謳っています。 全社周知(社内 ポータルサイト へのニュース掲載) 内容としては以下の項目をまとめています。 脆弱性 の概要(RCEの可否、PoCの有無も含む) 影響を受けるソフトウェアバージョンおよび条件 根本対策(パッチ公開情報) 回避策(PoCの実施結果) 攻撃の兆候がないかログの確認を依頼(SOCがあれば活用) 参考情報 CVE採番後の対応 MITER社から公開されるCVE採番情報を確認したら、以下のチェックおよび対応します。 公的機関、開発元から情報が公開・更新されているか 情報収集の際にチェックした各発信元の情報が更新されているか パッチのリリース状況 社内 ポータルサイト に投稿した記事に追記 個別周知 次に、 脆弱性 バージョンを利用している該当プロジェクトに対して個別周知、対応期限を設定します。 オーガニゼーショントピック(CVE別にトピックを立てて情報共有できる機能)の投稿 参考: トピックによる情報共有・注意喚起 送信すると、該当するグループの全メンバへメールが発報されます。 また、SlackやTeamsへの連携も可能です。 Slack連携: https://help.vuls.biz/manual/notification/slack_app/ Teams連携: https://help.vuls.biz/manual/notification/teams/ スペシャ ル警戒タグの設定 こちらの機能を簡単にご紹介します。 脆弱性 単位で独自のタグを付けられる 例えば、「全社周知対象(トピック掲載あり)」や「緊急対応必須」として、ユーザへの情報認識を早めたり、CSIRT側で後から状況を見返す時に便利になると思います。 タグは1つのCVE-IDに対して複数設定できます。 対応期限を設定でき、該当タスクの対応期限を一括で上書き更新できる CVE検知済みのグループに対して設定された旨の通知ができる(通知の際、コメントは不可) 参考: スペシャル警戒タグ機能 今回の対応期限は判断日の5営業日後としました。 各プロジェクトの 脆弱性 情報のサマリに警戒タグが入りました。 対応状況の確認 最後に各プロジェクトの対応状況を後追いします。 FutureVulsではタスクステータスを用いて、対応状況を管理できます。 タスク対応の流れは以下です。 引用: ステータス 次のアクションとして、 スペシャ ル警戒タグで設定した対応期限を超過したタスクに対してリマインドします。 対応期限の翌営業日になったら、グループセットのタスクタブから、フィルターでCVE-2022-22965のタスクステータスが「NEW(新規)」と「INVESTIGATING(調査中)」を抽出します。 タスクに一括チェックした上で、タスクを編集からコメントを送信することで、該当グループの所属メンバ全員にメールを送信できます。 その後はタスクのコメント上でのやり取りも可能です。 対応結果 模擬訓練に参加したプロジェクトの対応結果は以下のようになりました。 プロジェクト 結果 ソフトウェア別の対応 プロジェクトA CPE スキャン(*)にて検出され、対応完了 Spring Framework 5.3.17が検出対象となったため、最新バージョンに CPE を更新し、クローズ プロジェクトB CPE スキャンでは検出できず、個別連絡にて対応依頼の上、完了 Spring Boot 2.5.0は Spring Framework に依存しているが、 CPE スキャンでは検出されず。原因と対応策は下記課題3を参照。Spring Bootの最新バージョンに CPE を更新。 プロジェクトC CPE スキャンにて検出され、対応完了 JDK 8は影響を受けないが検出対象となった。原因と対応策は下記課題4を参照。タスクのステータスを「NOT_AFFECTED(影響なし)」に変更し、クローズ。 * CPE スキャン:擬似サーバ上にソフトウェア名、バージョン情報を手動登録し、日次でスキャンさせる機能。 参考: CPEスキャン 見つかった課題 模擬訓練を通して発見した課題についてまとめます。 No 課題 対応策 補足 1 CVE未採番の状態でもユーザへ第一報を通知したい グループセットのソフトウェアタブで「Spring」と検索し、該当するプロジェクトメンバに連絡する FutureVulsのオーガニゼーショントピックや スペシャ ル警戒タグはCVE採番済みの 脆弱性 に対してしか利用できない。現状はチャットなど別の手段で連絡するしかない。 2 対応済みのプロジェクトにもオーガニゼーショントピックが通知されてしまう オーガニゼーショントピックをなるべく早めに発報することで、対応済み案件へ通知される確率を下げる。またトピック内に注意書きを入れる。 オーガニゼーショントピックは 脆弱性 単位で通知する機能となっており、各タスクのステータスまでチェックしないため、既に対応がクローズしている案件にも通知されるため、注意が必要。 3 Spring Bootの脆弱バージョンを CPE スキャンしても、CVE-2022-22965が検出されない 依存ライブラリスキャンを利用する CPE スキャンは登録したライブラリや フレームワーク の依存ライブラリの 脆弱性 までは検知できない。依存ライブラリスキャンの手法の1つとして GitHub Security Alerts連携 がある。PoCで利用したSpring Bootのpom. xml をスキャン対象の GitHub リポジトリ に手動であげるとFutureVuls側で検出されることを確認。 4 JDK 8であれば影響を受けないはずだが検出されてしまう トピック内に影響を受ける条件を記載し、プロジェクト側にステータスを「NOT_AFFECTED(影響なし)」に変更してもらうようにする FutureVulsには外部条件を考慮した検知の仕組みは現状ないため、ステータスを変更してもらう必要がある 最後に 今回、 脆弱性 対応模擬訓練を行うことで、FutureVulsを活用した緊急時の一連のフローを確認することができました。 また、課題はいくつか見つかりましたが、運用でカバーできそうであることもわかりました。 FutureVulsはリリース頻度が高いため、このあたりの課題が機能アップデートによって解消されることに期待したいと思います! 私たちは同じチームで働いてくれる仲間を大募集しています!たくさんのご応募をお待ちしています。 セキュリティエンジニア 執筆: @fukuyama.kenta ( Shodo で執筆されました )
こんにちは、X イノベーション 本部 ソフトウェアデザインセンター セキュリティグループの福山です。 今回は、弊社CSIRTチームの一機能として活動している「 脆弱性 管理チーム」の活動に関する内容となります。 昨今では、Log4shellやSpring4shellなど、影響範囲の広い 脆弱性 が後を絶ちません。 これらの緊急度の高い 脆弱性 情報が公開された場合を想定した、情報収集〜現場対応までのCSIRT目線での模擬訓練を、FutureVulsを含めて実施してみましたので紹介したいと思います。 FutureVulsとは FutureVulsを導入した経緯 事前準備 模擬訓練 情報収集 トリアージ 全社周知 個別周知 対応状況の確認 対応結果 見つかった課題 最後に FutureVulsとは フューチャー株式会社が開発する OSS の 脆弱性 スキャナVulsがベースになっており、組織単位で継続的に 脆弱性 管理するための 脆弱性 管理サービスです。 参考: https://vuls.biz/ FutureVulsの主な特徴についてピックアップします。 スキャンについて 検知精度、検知スピードに優れており、サーバへの負荷が軽い。 スキャナを導入せずに手動でソフトウェア情報を登録し、管理することも可能。 検出された情報について ソフトウェア情報の一括管理や、複数グループを束ねたグループセットでの横断検索が可能。 参考: グループセット 検出された 脆弱性 情報を一覧で一括管理が可能。 自動 トリアージ について 脆弱性 の危険度合いをスコアで示すCVSSによる従来の評価手法では、以下の点が考慮されていません。 脆弱性 の悪用の容易さ 実際の資産が攻撃を受ける環境にあるか 資産価値 攻撃を受けた際の業務影響度合い また、現場でどのように対応すべきかの判断がもう一段階必要となってきます。 そこで2019年12月、これらを解決する新しい評価手法「SSVC(Stakeholder-Specific Vulnerability Categorization)」が米 カーネギーメロン大学 ソフトウェア工学 研究所によって提案されました。 SSVCでは意思決定ツリーを用いて「immediate」「out_of_cycle」「scheduled」「defer」の4段階で対応優先度を導出します。 FutureVulsにはSSVCの機能が早くも導入されており、各 脆弱性 に対して4段階評価で対応優先度が自動で付与されることで、現場の負担を減らすことができます。 参考: SSVC(Stakeholder-Specific Vulnerability Categorization)を活用した脆弱性管理 FutureVulsを導入した経緯 FutureVulsを活用した 脆弱性 管理チームの緊急時運用フローを確認したい 弊社ではNIST NVD、 JVN iPediaから収集した情報と、シートに入力された各プロジェクトのソフトウェア情報を突き合わせ、該当する 脆弱性 情報の個別周知運用を行っていました。 ただし以下の課題があり、その要件を満たすべく2023年7月よりFutureVulsに本番移行することが決まりました。 <FutureVuls導入前の課題> より正確かつ最新のソフトウェア情報を管理したい 該当する 脆弱性 情報をよりタ イムリ ーに周知したい 各プロジェクトに個別に対応判断を委ねず、判断基準を設けたい 対応状況をより正確に把握したい 事前準備 訓練に使用する 脆弱性 はSpring4Shell(CVE-2022-22965)を採用 Spring4Shellの採用に至った条件は以下 仮想の 脆弱性 ではなく、既存の 脆弱性 を利用した方がやりやすい 社内で利用されているソフトウェア 擬似サーバへの CPE 登録が想定されるもの 参考: 擬似サーバとは リモートコード実行が可能な 脆弱性 で、PoCが公開されているもの 公表された時点でCVE未採番で、セキュリティパッチが公開されていないもの 事前にプロジェクトに協力を募り、3プロジェクトからの協力を取り付ける FutureVulsの擬似サーバを利用し、 CPE 形式でソフトウェア情報を登録 プロジェクトA Spring Framework 5.3.17 OracleJDK 9 Apache HTTP Server 2.4.53 Apache Tomcat 9.0.60 プロジェクトB Spring Boot 2.5.0 OpenJDK 9 nginx 1.6.0 Apache Tomcat 9.0.59 プロジェクトC Spring Framework 5.2.0 OracleJDK 8 Apache HTTP Server 2.4.52 Apache Tomcat 9.0.59 模擬訓練 模擬訓練の流れは以下となります。 情報収集 -> トリアージ -> 全社周知 -> 個別周知 -> 対応状況の確認 なお、全社周知と個別周知の役割の違いは以下です。 全社周知 個別周知 ・ゼロデイ 脆弱性 等、CVEが採番される前の段階でも情報をいち早く整理し伝える ・該当プロジェクトに直接周知することで、対応が必要であることを認識していただく ・影響を受ける条件や、PoCの再現結果を掲載する ・該当プロジェクトの対応状況を可視化する ・FutureVulsを利用しない社員向けにも周知する 以上を踏まえて、実際の訓練の内容に移ります。 情報収集 社内で利用されているソフトウェアにおいて、ゼロデイ 脆弱性 や影響範囲の広い 脆弱性 情報が公開されていないか、複数のWebサイトでチェックしています。 よく参考にしている情報発信元を紹介します。 CyberSecurityHelp:独自の 脆弱性 DBを公開しており、リスク評価、パッチの提供有無、Atack Vector 、Public exploit(実際の悪用有無)、Exploit availability(PoC、攻撃コードの有無)、回避策などの情報をタ イムリ ーに提供するサイトで、公開されるタイミングはCVE採番後。 URL: https://www.cybersecurity-help.cz/ Lunasec:米セキュリティ企業。2021年に公開されたLog4Shellの際にもブログをいち早く公開しており、影響を受ける条件、PoC、回避策などをわかりやすくブログにまとめている URL: https://www.lunasec.io/docs/blog/spring-rce-vulnerabilities/ Bleeping Computer: 脆弱性 情報を含む最新のセキュリティニュースをいち早く提供する海外サイト URL: https://www.bleepingcomputer.com/tag/vulnerability/ Security Next: 脆弱性 情報を含む最新のセキュリティニュースを日本語でいち早く提供するサイト URL: https://www.security-next.com/135304 piyolog: 脆弱性 情報を含む最新のセキュリティニュースがわかりやすく日本語で解説されたブログ URL: https://piyolog.hatenadiary.jp/entry/2022/04/01/065946 GitHub Advisory Database: GitHub Security Advisoriesで公開された 脆弱性 や、依存関係を追跡して得られた依存先ソフトウェアの 脆弱性 を一覧表示する URL: https://github.com/advisories ただし、これらはあくまで参考情報ですので、最終的に一次情報源の確認は必須です。 公的機関( JPCERT/CC 、 JVN 、 IPA 、NIST NVD) 開発元(今回はSpring) URL: https://spring.io/security/ トリアージ これまでの情報を整理した上で、全社周知要否( トリアージ )を2つの観点で実施します。 影響範囲の確認 各プロジェクトにおける利用状況を確認するため、FutureVulsのグループセットからソフトウェア名で検索します。 参考: グループセット内のソフトウェア名検索 緊急度合いの確認 脆弱性 管理チームで利用している緊急度 判断表 をもとに、緊急度を確認します。 No RCE PoC 開発元の評価 緊急度 1 可能 有 高以上 緊急 2 可能 無 高以上 高 3 不可 有 高以上 高 4 不可 無 高以上 中 5 可能 有 中以下 高 6 可能 無 中以下 中 7 不可 有 中以下 中 8 不可 無 中以下 中 9 可能 有 未評価 緊急 10 可能 無 未評価 高 11 不可 有 未評価 高 12 不可 無 未評価 中 公表時点では、No.9の「緊急」に該当しました。 トリアージ の結果、全社周知が必要と判断したため次のステップに進みます。 全社周知 全社周知の準備を進めつつ、MITRE社によるCVE採番状況のチェックもしながら状況変化をキャッチアップします。 URL: https://cve.mitre.org/cve/search_cve_list.html PoC、回避策の検証 まずはPoCを探すところからですが、例として以下の リポジトリ では、 GitHub で公開されているPoCを自動収集しています。 URL: https://github.com/nomi-sec/PoC-in-GitHub/tree/master 当時、実際に対応した際は以下のPoCが出回っており、こちらを実施しました。 LunaSec社も改善に加わっているようです。(※中には悪意のあるPoCを公開している リポジトリ もあるため、コードの中身をよく読んで、社内と隔離されたネットワーク上で実行するようにする) URL: https://github.com/reznok/Spring4Shell-POC dockerを利用するため容易に実施できるものになっています。(環境構築に時間が掛かる場合があります) また、Lunasecによると、脆弱パターンの ブラックリスト を記載したInitBinderを挿入することが緩和策になると謳っています。 全社周知(社内 ポータルサイト へのニュース掲載) 内容としては以下の項目をまとめています。 脆弱性 の概要(RCEの可否、PoCの有無も含む) 影響を受けるソフトウェアバージョンおよび条件 根本対策(パッチ公開情報) 回避策(PoCの実施結果) 攻撃の兆候がないかログの確認を依頼(SOCがあれば活用) 参考情報 CVE採番後の対応 MITER社から公開されるCVE採番情報を確認したら、以下のチェックおよび対応します。 公的機関、開発元から情報が公開・更新されているか 情報収集の際にチェックした各発信元の情報が更新されているか パッチのリリース状況 社内 ポータルサイト に投稿した記事に追記 個別周知 次に、 脆弱性 バージョンを利用している該当プロジェクトに対して個別周知、対応期限を設定します。 オーガニゼーショントピック(CVE別にトピックを立てて情報共有できる機能)の投稿 参考: トピックによる情報共有・注意喚起 送信すると、該当するグループの全メンバへメールが発報されます。 また、SlackやTeamsへの連携も可能です。 Slack連携: https://help.vuls.biz/manual/notification/slack_app/ Teams連携: https://help.vuls.biz/manual/notification/teams/ スペシャ ル警戒タグの設定 こちらの機能を簡単にご紹介します。 脆弱性 単位で独自のタグを付けられる 例えば、「全社周知対象(トピック掲載あり)」や「緊急対応必須」として、ユーザへの情報認識を早めたり、CSIRT側で後から状況を見返す時に便利になると思います。 タグは1つのCVE-IDに対して複数設定できます。 対応期限を設定でき、該当タスクの対応期限を一括で上書き更新できる CVE検知済みのグループに対して設定された旨の通知ができる(通知の際、コメントは不可) 参考: スペシャル警戒タグ機能 今回の対応期限は判断日の5営業日後としました。 各プロジェクトの 脆弱性 情報のサマリに警戒タグが入りました。 対応状況の確認 最後に各プロジェクトの対応状況を後追いします。 FutureVulsではタスクステータスを用いて、対応状況を管理できます。 タスク対応の流れは以下です。 引用: ステータス 次のアクションとして、 スペシャ ル警戒タグで設定した対応期限を超過したタスクに対してリマインドします。 対応期限の翌営業日になったら、グループセットのタスクタブから、フィルターでCVE-2022-22965のタスクステータスが「NEW(新規)」と「INVESTIGATING(調査中)」を抽出します。 タスクに一括チェックした上で、タスクを編集からコメントを送信することで、該当グループの所属メンバ全員にメールを送信できます。 その後はタスクのコメント上でのやり取りも可能です。 対応結果 模擬訓練に参加したプロジェクトの対応結果は以下のようになりました。 プロジェクト 結果 ソフトウェア別の対応 プロジェクトA CPE スキャン(*)にて検出され、対応完了 Spring Framework 5.3.17が検出対象となったため、最新バージョンに CPE を更新し、クローズ プロジェクトB CPE スキャンでは検出できず、個別連絡にて対応依頼の上、完了 Spring Boot 2.5.0は Spring Framework に依存しているが、 CPE スキャンでは検出されず。原因と対応策は下記課題3を参照。Spring Bootの最新バージョンに CPE を更新。 プロジェクトC CPE スキャンにて検出され、対応完了 JDK 8は影響を受けないが検出対象となった。原因と対応策は下記課題4を参照。タスクのステータスを「NOT_AFFECTED(影響なし)」に変更し、クローズ。 * CPE スキャン:擬似サーバ上にソフトウェア名、バージョン情報を手動登録し、日次でスキャンさせる機能。 参考: CPEスキャン 見つかった課題 模擬訓練を通して発見した課題についてまとめます。 No 課題 対応策 補足 1 CVE未採番の状態でもユーザへ第一報を通知したい グループセットのソフトウェアタブで「Spring」と検索し、該当するプロジェクトメンバに連絡する FutureVulsのオーガニゼーショントピックや スペシャ ル警戒タグはCVE採番済みの 脆弱性 に対してしか利用できない。現状はチャットなど別の手段で連絡するしかない。 2 対応済みのプロジェクトにもオーガニゼーショントピックが通知されてしまう オーガニゼーショントピックをなるべく早めに発報することで、対応済み案件へ通知される確率を下げる。またトピック内に注意書きを入れる。 オーガニゼーショントピックは 脆弱性 単位で通知する機能となっており、各タスクのステータスまでチェックしないため、既に対応がクローズしている案件にも通知されるため、注意が必要。 3 Spring Bootの脆弱バージョンを CPE スキャンしても、CVE-2022-22965が検出されない 依存ライブラリスキャンを利用する CPE スキャンは登録したライブラリや フレームワーク の依存ライブラリの 脆弱性 までは検知できない。依存ライブラリスキャンの手法の1つとして GitHub Security Alerts連携 がある。PoCで利用したSpring Bootのpom. xml をスキャン対象の GitHub リポジトリ に手動であげるとFutureVuls側で検出されることを確認。 4 JDK 8であれば影響を受けないはずだが検出されてしまう トピック内に影響を受ける条件を記載し、プロジェクト側にステータスを「NOT_AFFECTED(影響なし)」に変更してもらうようにする FutureVulsには外部条件を考慮した検知の仕組みは現状ないため、ステータスを変更してもらう必要がある 最後に 今回、 脆弱性 対応模擬訓練を行うことで、FutureVulsを活用した緊急時の一連のフローを確認することができました。 また、課題はいくつか見つかりましたが、運用でカバーできそうであることもわかりました。 FutureVulsはリリース頻度が高いため、このあたりの課題が機能アップデートによって解消されることに期待したいと思います! 私たちは同じチームで働いてくれる仲間を大募集しています!たくさんのご応募をお待ちしています。 セキュリティエンジニア 執筆: @fukuyama.kenta ( Shodo で執筆されました )
こんにちは。X(クロス) イノベーション 本部 ソフトウェアデザインセンター セキュリティグループの耿です。 2023年6月に Amazon Verified Permissions というサービスがGAしましたが、まだ利用している方は少ないのではないでしょうか。 アプリケーションとは切り離して認可ポリシーを管理できるこのサービスですが、ではどうやってポリシーや スキーマ を管理したら良いか考えたところ、 AWS CDK が便利だったので、今回の記事ではその方法を紹介します。 Amazon Verified Permissions とは スキーマ Amazon Verified Permissions を CDK でデプロイする ディレクトリ構成 Cedar 言語の VS Code 拡張 スキーマ定義 ポリシー CDK コンストラクト SDKで認可を判定させてみた さいごに Amazon Verified Permissions とは ポリシーを事前に登録することで、アプリケーションの認可の判定を、アプリケーションの外側で行うことができるマネージドサービスです。 ポリシーは Cedar という DSL で記述します。例えば次のようなポリシー: permit ( principal in MyApp::User::"alice", action in [MyApp::Action::"GET"], resource in MyApp::Album::"animals" ); これは alice というユーザーに animals というアルバムへの GET アクセスを permit (許可する)という意味になります。 principal 「誰に」、 resource 「どのリソースに対する」、 action 「どんな操作」を許可・拒否するかを基本的には書いていくことになります。 定義したポリシーに対して、アプリケーションコードから認可結果を判定させるリク エス トを送信できます。 例として次のように AWS SDK for JavaScript の IsAuthorizedCommand を使って、特定の状況における認可を判定させることができます。 // authorize.ts import { VerifiedPermissionsClient , IsAuthorizedCommand } from "@aws-sdk/client-verifiedpermissions" ; const client = new VerifiedPermissionsClient ( { region: "ap-northeast-1" } ); const command = new IsAuthorizedCommand ( { policyStoreId: "DUMMYSTOREID" , principal: { entityType: "MyApp::User" , entityId: "alice" } , action: { actionType: "MyApp::Action" , actionId: "GET" } , resource: { entityType: "MyApp::Album" , entityId: "animals" } , } ); client.send ( command ) .then (( result ) => { console .log ( result.decision ); // ALLOW } ); この場合ユーザーは alice 、操作対象のリソースは animals というアルバム、操作は GET なので、先ほど例に示した許可ポリシーに当てはまり、コマンドの結果の decision プロパティには ALLOW が返ってきます。(拒否される場合は DENY が返ります。) この結果を見て、後続の処理は完全にアプリケーション側の裁量で行うことになります。 ( principal を Cognito と連携したり、 principal や resource に属性を追加したり、 context でコンテキストを追加したりすることもできますが、今回はこれぐらいのシンプルな説明に留めておきます。) スキーマ Amazon Verified Permissions には スキーマ と呼ばれる概念があります。 スキーマ は前述の principal 、 resource 、 action のフォーマットを定義するものです。言葉で説明しても理解が難しいと思うので、実際にマネジメントコンソールで見てみると分かりやすいと思います。 定義済みの スキーマ の画面です。 principal と resource で使った User や Album は「エンティティタイプ」セクションで定義し、 action で使った GET は「アクション」セクションで定義します。マネジメントコンソールで追加した スキーマ 定義は JSON フォーマットと相互変換可能であり、上の スキーマ 定義は次の JSON と同等です。(画面の「 JSON モード」から確認でき、 決まったフォーマット が使われます) { " MyApp ": { " actions ": { " GET ": { " appliesTo ": { " context ": { " attributes ": {} , " type ": " Record " } , " resourceTypes ": [ " Album " ] , " principalTypes ": [ " User " ] } } } , " entityTypes ": { " User ": { " memberOfTypes ": [] , " shape ": { " attributes ": {} , " type ": " Record " } } , " Album ": { " shape ": { " type ": " Record ", " attributes ": {} } , " memberOfTypes ": [] } } } } Amazon Verified Permissions を CDK でデプロイする Amazon Verified Permissions の スキーマ ( JSON )とポリシー(Cedar)はいずれも宣言型のコードで表現されるので、そのデプロイを CDK で行うと相性が良いのではないかと思いました。そう考えた理由は以下です。 認可のための スキーマ やポリシーは、アプリケーションデータのように頻繁に変わるわけではない そのためコード リポジトリ で管理し、レビューと変更を確認できる状態にしたい コード リポジトリ で管理するなら、デプロイも自動化したい IaC でデプロイしよう まず、 Amazon Verified Permissions のリソース構築は CloudFormation ではサポート されています。しかし、 JSON のスキーマ定義 や Cedar のポリシー定義 を String で記載する必要があり、CloudFormation テンプレートで管理するのはつらそうです。そこで プログラミング言語 で IaC を実現できる CDK を活用して、管理しやすくしてみましょう。 ディレクト リ構成 以下の CDK アプリの リポジトリ 構成で話を進めます。(重要なファイル/ ディレクト リ以外は省略しています。) sample-app/  ├ .vscode/  │ └ settings.json <- VS Code で Cedar を書きやすくするための設定ファイル  ├ bin/  │ └ my-app.ts  ├ cedar/  │ ├ 0001.cedar <- ポリシーその1  │ ├ 0002.cedar <- ポリシーその2  │ └ cedarschema.json <- スキーマ定義  ├ lib/  │ ├ constructs/  │ │ └ my-construct.ts <- Verified Permissionsリソースをデプロイするコンストラクト  │ └ my-stack.ts  ├ cdk.context.json  ├ cdk.json  ├ package.json  ├ tsconfig.json  └ yarn.lock Cedar 言語の VS Code 拡張 Cedar 言語を書きやすくするための VS Code 拡張があります。とりあえず入れておきましょう。 https://marketplace.visualstudio.com/items?itemName=cedar-policy.vscode-cedar 続いて .vscode/settings.json に以下の設定を追加します。ポリシーや スキーマ 定義の文法が正しくないときや、 スキーマ 定義に一致しないポリシーを書いたときにエラーを出してくれるようになります。保存時にファイルのフォーマットもそろえてくれます。 // .vscode/settings.json { " [cedar] ": { " editor.tabSize ": 2 , " editor.wordWrapColumn ": 80 , " editor.formatOnSave ": true , " editor.defaultFormatter ": " cedar-policy.vscode-cedar " , } , " cedar.schemaFile ": " /cedar/cedarschema.json ", " cedar.autodetectSchemaFile ": true , } スキーマ 定義 前述の例の JSON スキーマ 定義をそのまま cedar/cedarschema.json に書きます。 cedarschema.json もしくは *.cedarschema.json というファイル名にすることで、 Cedar の JSON スキーマ ファイルとして VS Code 拡張に認識されるようになります。 // cedar/cedarschema.json { " MyApp ": { " actions ": { " GET ": { " appliesTo ": { " context ": { " attributes ": {} , " type ": " Record " } , " resourceTypes ": [ " Album " ] , " principalTypes ": [ " User " ] } } } , " entityTypes ": { " User ": { " memberOfTypes ": [] , " shape ": { " attributes ": {} , " type ": " Record " } } , " Album ": { " shape ": { " type ": " Record ", " attributes ": {} } , " memberOfTypes ": [] } } } } ポリシー ポリシーを2つ追加してみます。 *.cedar 拡張子のファイル名が Cedar のポリシーファイルとして VS Code 拡張に認識されます。1つの *.cedar ファイルには1つのポリシーしか書けないので、2つのファイルを追加します。 1つ目は alice というユーザーに animals というアルバムへの GET アクセスを許可するポリシーです。( cedar/0001.cedar ) コメントも自由に書けるので、ポリシーの説明などを記載しておくと後から分かりやすいでしょう。 // alice に animals アルバムへのアクセスを許可する permit ( principal in MyApp::User::"alice", action in [MyApp::Action::"GET"], resource in MyApp::Album::"animals" ); 2つ目は bob というユーザーに flowers というアルバムへの GET アクセスを許可するポリシーです。( cedar/0002.cedar ) // bob に flowers アルバムへのアクセスを許可する permit ( principal in MyApp::User::"bob", action in [MyApp::Action::"GET"], resource in MyApp::Album::"flowers" ); CDK コンスト ラク ト いよいよ Verified Permissions のリソースを CDK でデプロイするコンスト ラク トです。 CDK v2.94.0 では Verified Permissions のコンスト ラク トは4つ利用できますが、L2 コンスト ラク トはなく、いずれも L1 です。 CfnPolicyStore CfnPolicy CfnPolicyTemplate CfnIdentitySource 今回は上の2つを利用します。 まずは Verified Permissions のポリシーストアを作成します。 // lib/constructs/my-construct.ts import * as fs from "fs" ; import * as path from "path" ; import * as vp from "aws-cdk-lib/aws-verifiedpermissions" ; import { Construct } from "constructs" ; export class VerifiedPermissionsConstruct extends Construct { constructor( scope: Construct , id: string ) { super( scope , id ); const cedarDir = path.join ( __dirname , ".." , ".." , "cedar" ); // スキーマ定義をファイルから読み込む const schema = fs.readFileSync ( path.join ( cedarDir , "cedarschema.json" ), "utf-8" ); // ポリシーストア const policyStore = new vp.CfnPolicyStore ( this , "PolicyStore" , { validationSettings: { mode: "STRICT" } , schema: { cedarJson: schema } , } ); // ... } } スキーマ 定義はポリシーストア作成時に渡す必要があり、 fs モジュールの readFileSync メソッドで先ほど定義した cedarschema.json ファイルを読み込ませています。 デプロイすると、マネジメントコンソールでも作成されたポリシーストアを確認できました。ポリシーストア ID は自動で採番されます。 続いてポリシーを追加していきます。以下のコードは、 cedar ディレクト リにある *.cedar ファイルのみをループして読み込んで、ファイルの数だけポリシーをポリシーストアに追加しています。 // lib/constructs/my-construct.ts export class VerifiedPermissionsConstruct extends Construct { constructor( scope: Construct , id: string ) { // ... // cedar ディレクトリのファイル一覧を読み込む const files = fs.readdirSync ( cedarDir ); files .filter (( file ) => file.endsWith ( ".cedar" )) // .cedar ファイルのみを抽出 .map (( file ) => { const content = fs.readFileSync ( path.join ( cedarDir , file ), "utf-8" ); // ポリシー new vp.CfnPolicy ( this , `Policy- ${ file.split( "." )[ 0 ] } ` , { policyStoreId: policyStore.attrPolicyStoreId , // ポリシーストア ID を参照 definition: { static : { statement: content } } , // 静的ポリシーを追加 } ); } ); } } ポリシーのリソースIDはファイル名を利用して付けることで重複がないようにしています。また map 関数で cedar ディレクト リ内の全 Cedar ファイルをループして処理することで、ポリシーを追加・削除したいときは cedar ディレクト リ内を変更するだけでよく、CDK コードの修正は必要ありません。このようなことができるのも プログラミング言語 で処理を書ける CDK ならではの強みです。 デプロイすると、定義した通りのポリシーがコンソールでも確認できました。ポリシー ID は自動で採番されています。 以上で CDK を使った Verified Permission の構築は完了です。 SDK で認可を判定させてみた 構築した Verified Permissions を確認するために、簡単にローカル環境から SDK でリク エス トを投げてみます。 // authorize.ts import { VerifiedPermissionsClient , IsAuthorizedCommand } from "@aws-sdk/client-verifiedpermissions" ; const client = new VerifiedPermissionsClient ( { region: "ap-northeast-1" } ); const command = new IsAuthorizedCommand ( { policyStoreId: "DUMMYSTOREID" , // マネジメントコンソールから確認できるポリシーストアID principal: { entityType: "MyApp::User" , entityId: "alice" } , action: { actionType: "MyApp::Action" , actionId: "GET" } , resource: { entityType: "MyApp::Album" , entityId: "animals" } , } ); client.send ( command ) .then (( result ) => { console .log ( result.decision ); // ALLOW console .log ( JSON .stringify ( result.determiningPolicies )); // [{"policyId":"JLu29q39V62CChNcpFgk3x"}] } ); ユーザーが alice 、リソースが animals アルバムの場合、判定結果は ALLOW となり、どのポリシーで判定されたのかも determiningPolicies プロパティで確認できます。 今度は alice に許可していない flowers アルバムへの認可を判定させてみます。 // authorize.ts const command = new IsAuthorizedCommand ( { policyStoreId: "DUMMYSTOREID" , principal: { entityType: "MyApp::User" , entityId: "alice" } , action: { actionType: "MyApp::Action" , actionId: "GET" } , resource: { entityType: "MyApp::Album" , entityId: "flowers" } , } ); client.send ( command ) .then (( result ) => { console .log ( result.decision ); // DENY console .log ( JSON .stringify ( result.determiningPolicies )); // [] } ); どのポリシーにも当てはまらないため determiningPolicies は空の配列であり、判定結果はデフォルトの DENY となりました。 ちなみに GetPolicyCommand を使うことで、ポリシーの内容を SDK からも取得することができます。 // authorize.ts const command = new GetPolicyCommand ( { policyStoreId: "DUMMYSTOREID" , policyId: "JLu29q39V62CChNcpFgk3x" , } ); client.send ( command ) .then (( result ) => { console .log ( result.definition?. static ?.statement ); } ); // (結果) // // alice に animals アルバムへのアクセスを許可する // permit ( // principal in MyApp::User::"alice", // action in [MyApp::Action::"GET"], // resource in MyApp::Album::"animals" // ); さいごに まだまだ利用が少ないと思われる Amazon Verified Permissions ですが、CDK を使って管理・デプロイすることと相性が良く、使ってみたいという気持ちになりました。 DSL なので提供されている VS Code 拡張を利用したいですし、そうするとファイルの読み込みや、ポリシーファイルの数だけループ処理ができる CDK でデプロイするのが最も便利だと感じました。 Amazon Verified Permissions 自体も、工夫次第では様々な使い方ができそうなので、今後が楽しみなサービスです。 私たちは同じチームで働いてくれる仲間を大募集しています!たくさんのご応募をお待ちしています。 セキュリティエンジニア 執筆: @kou.kinyo 、レビュー: @yamashita.tsuyoshi ( Shodo で執筆されました )
こんにちは。X(クロス) イノベーション 本部 ソフトウェアデザインセンター セキュリティグループの耿です。 2023年6月に Amazon Verified Permissions というサービスがGAしましたが、まだ利用している方は少ないのではないでしょうか。 アプリケーションとは切り離して認可ポリシーを管理できるこのサービスですが、ではどうやってポリシーや スキーマ を管理したら良いか考えたところ、 AWS CDK が便利だったので、今回の記事ではその方法を紹介します。 Amazon Verified Permissions とは スキーマ Amazon Verified Permissions を CDK でデプロイする ディレクトリ構成 Cedar 言語の VS Code 拡張 スキーマ定義 ポリシー CDK コンストラクト SDKで認可を判定させてみた さいごに Amazon Verified Permissions とは ポリシーを事前に登録することで、アプリケーションの認可の判定を、アプリケーションの外側で行うことができるマネージドサービスです。 ポリシーは Cedar という DSL で記述します。例えば次のようなポリシー: permit ( principal in MyApp::User::"alice", action in [MyApp::Action::"GET"], resource in MyApp::Album::"animals" ); これは alice というユーザーに animals というアルバムへの GET アクセスを permit (許可する)という意味になります。 principal 「誰に」、 resource 「どのリソースに対する」、 action 「どんな操作」を許可・拒否するかを基本的には書いていくことになります。 定義したポリシーに対して、アプリケーションコードから認可結果を判定させるリク エス トを送信できます。 例として次のように AWS SDK for JavaScript の IsAuthorizedCommand を使って、特定の状況における認可を判定させることができます。 // authorize.ts import { VerifiedPermissionsClient , IsAuthorizedCommand } from "@aws-sdk/client-verifiedpermissions" ; const client = new VerifiedPermissionsClient ( { region: "ap-northeast-1" } ); const command = new IsAuthorizedCommand ( { policyStoreId: "DUMMYSTOREID" , principal: { entityType: "MyApp::User" , entityId: "alice" } , action: { actionType: "MyApp::Action" , actionId: "GET" } , resource: { entityType: "MyApp::Album" , entityId: "animals" } , } ); client.send ( command ) .then (( result ) => { console .log ( result.decision ); // ALLOW } ); この場合ユーザーは alice 、操作対象のリソースは animals というアルバム、操作は GET なので、先ほど例に示した許可ポリシーに当てはまり、コマンドの結果の decision プロパティには ALLOW が返ってきます。(拒否される場合は DENY が返ります。) この結果を見て、後続の処理は完全にアプリケーション側の裁量で行うことになります。 ( principal を Cognito と連携したり、 principal や resource に属性を追加したり、 context でコンテキストを追加したりすることもできますが、今回はこれぐらいのシンプルな説明に留めておきます。) スキーマ Amazon Verified Permissions には スキーマ と呼ばれる概念があります。 スキーマ は前述の principal 、 resource 、 action のフォーマットを定義するものです。言葉で説明しても理解が難しいと思うので、実際にマネジメントコンソールで見てみると分かりやすいと思います。 定義済みの スキーマ の画面です。 principal と resource で使った User や Album は「エンティティタイプ」セクションで定義し、 action で使った GET は「アクション」セクションで定義します。マネジメントコンソールで追加した スキーマ 定義は JSON フォーマットと相互変換可能であり、上の スキーマ 定義は次の JSON と同等です。(画面の「 JSON モード」から確認でき、 決まったフォーマット が使われます) { " MyApp ": { " actions ": { " GET ": { " appliesTo ": { " context ": { " attributes ": {} , " type ": " Record " } , " resourceTypes ": [ " Album " ] , " principalTypes ": [ " User " ] } } } , " entityTypes ": { " User ": { " memberOfTypes ": [] , " shape ": { " attributes ": {} , " type ": " Record " } } , " Album ": { " shape ": { " type ": " Record ", " attributes ": {} } , " memberOfTypes ": [] } } } } Amazon Verified Permissions を CDK でデプロイする Amazon Verified Permissions の スキーマ ( JSON )とポリシー(Cedar)はいずれも宣言型のコードで表現されるので、そのデプロイを CDK で行うと相性が良いのではないかと思いました。そう考えた理由は以下です。 認可のための スキーマ やポリシーは、アプリケーションデータのように頻繁に変わるわけではない そのためコード リポジトリ で管理し、レビューと変更を確認できる状態にしたい コード リポジトリ で管理するなら、デプロイも自動化したい IaC でデプロイしよう まず、 Amazon Verified Permissions のリソース構築は CloudFormation ではサポート されています。しかし、 JSON のスキーマ定義 や Cedar のポリシー定義 を String で記載する必要があり、CloudFormation テンプレートで管理するのはつらそうです。そこで プログラミング言語 で IaC を実現できる CDK を活用して、管理しやすくしてみましょう。 ディレクト リ構成 以下の CDK アプリの リポジトリ 構成で話を進めます。(重要なファイル/ ディレクト リ以外は省略しています。) sample-app/  ├ .vscode/  │ └ settings.json <- VS Code で Cedar を書きやすくするための設定ファイル  ├ bin/  │ └ my-app.ts  ├ cedar/  │ ├ 0001.cedar <- ポリシーその1  │ ├ 0002.cedar <- ポリシーその2  │ └ cedarschema.json <- スキーマ定義  ├ lib/  │ ├ constructs/  │ │ └ my-construct.ts <- Verified Permissionsリソースをデプロイするコンストラクト  │ └ my-stack.ts  ├ cdk.context.json  ├ cdk.json  ├ package.json  ├ tsconfig.json  └ yarn.lock Cedar 言語の VS Code 拡張 Cedar 言語を書きやすくするための VS Code 拡張があります。とりあえず入れておきましょう。 https://marketplace.visualstudio.com/items?itemName=cedar-policy.vscode-cedar 続いて .vscode/settings.json に以下の設定を追加します。ポリシーや スキーマ 定義の文法が正しくないときや、 スキーマ 定義に一致しないポリシーを書いたときにエラーを出してくれるようになります。保存時にファイルのフォーマットもそろえてくれます。 // .vscode/settings.json { " [cedar] ": { " editor.tabSize ": 2 , " editor.wordWrapColumn ": 80 , " editor.formatOnSave ": true , " editor.defaultFormatter ": " cedar-policy.vscode-cedar " , } , " cedar.schemaFile ": " /cedar/cedarschema.json ", " cedar.autodetectSchemaFile ": true , } スキーマ 定義 前述の例の JSON スキーマ 定義をそのまま cedar/cedarschema.json に書きます。 cedarschema.json もしくは *.cedarschema.json というファイル名にすることで、 Cedar の JSON スキーマ ファイルとして VS Code 拡張に認識されるようになります。 // cedar/cedarschema.json { " MyApp ": { " actions ": { " GET ": { " appliesTo ": { " context ": { " attributes ": {} , " type ": " Record " } , " resourceTypes ": [ " Album " ] , " principalTypes ": [ " User " ] } } } , " entityTypes ": { " User ": { " memberOfTypes ": [] , " shape ": { " attributes ": {} , " type ": " Record " } } , " Album ": { " shape ": { " type ": " Record ", " attributes ": {} } , " memberOfTypes ": [] } } } } ポリシー ポリシーを2つ追加してみます。 *.cedar 拡張子のファイル名が Cedar のポリシーファイルとして VS Code 拡張に認識されます。1つの *.cedar ファイルには1つのポリシーしか書けないので、2つのファイルを追加します。 1つ目は alice というユーザーに animals というアルバムへの GET アクセスを許可するポリシーです。( cedar/0001.cedar ) コメントも自由に書けるので、ポリシーの説明などを記載しておくと後から分かりやすいでしょう。 // alice に animals アルバムへのアクセスを許可する permit ( principal in MyApp::User::"alice", action in [MyApp::Action::"GET"], resource in MyApp::Album::"animals" ); 2つ目は bob というユーザーに flowers というアルバムへの GET アクセスを許可するポリシーです。( cedar/0002.cedar ) // bob に flowers アルバムへのアクセスを許可する permit ( principal in MyApp::User::"bob", action in [MyApp::Action::"GET"], resource in MyApp::Album::"flowers" ); CDK コンスト ラク ト いよいよ Verified Permissions のリソースを CDK でデプロイするコンスト ラク トです。 CDK v2.94.0 では Verified Permissions のコンスト ラク トは4つ利用できますが、L2 コンスト ラク トはなく、いずれも L1 です。 CfnPolicyStore CfnPolicy CfnPolicyTemplate CfnIdentitySource 今回は上の2つを利用します。 まずは Verified Permissions のポリシーストアを作成します。 // lib/constructs/my-construct.ts import * as fs from "fs" ; import * as path from "path" ; import * as vp from "aws-cdk-lib/aws-verifiedpermissions" ; import { Construct } from "constructs" ; export class VerifiedPermissionsConstruct extends Construct { constructor( scope: Construct , id: string ) { super( scope , id ); const cedarDir = path.join ( __dirname , ".." , ".." , "cedar" ); // スキーマ定義をファイルから読み込む const schema = fs.readFileSync ( path.join ( cedarDir , "cedarschema.json" ), "utf-8" ); // ポリシーストア const policyStore = new vp.CfnPolicyStore ( this , "PolicyStore" , { validationSettings: { mode: "STRICT" } , schema: { cedarJson: schema } , } ); // ... } } スキーマ 定義はポリシーストア作成時に渡す必要があり、 fs モジュールの readFileSync メソッドで先ほど定義した cedarschema.json ファイルを読み込ませています。 デプロイすると、マネジメントコンソールでも作成されたポリシーストアを確認できました。ポリシーストア ID は自動で採番されます。 続いてポリシーを追加していきます。以下のコードは、 cedar ディレクト リにある *.cedar ファイルのみをループして読み込んで、ファイルの数だけポリシーをポリシーストアに追加しています。 // lib/constructs/my-construct.ts export class VerifiedPermissionsConstruct extends Construct { constructor( scope: Construct , id: string ) { // ... // cedar ディレクトリのファイル一覧を読み込む const files = fs.readdirSync ( cedarDir ); files .filter (( file ) => file.endsWith ( ".cedar" )) // .cedar ファイルのみを抽出 .map (( file ) => { const content = fs.readFileSync ( path.join ( cedarDir , file ), "utf-8" ); // ポリシー new vp.CfnPolicy ( this , `Policy- ${ file.split( "." )[ 0 ] } ` , { policyStoreId: policyStore.attrPolicyStoreId , // ポリシーストア ID を参照 definition: { static : { statement: content } } , // 静的ポリシーを追加 } ); } ); } } ポリシーのリソースIDはファイル名を利用して付けることで重複がないようにしています。また map 関数で cedar ディレクト リ内の全 Cedar ファイルをループして処理することで、ポリシーを追加・削除したいときは cedar ディレクト リ内を変更するだけでよく、CDK コードの修正は必要ありません。このようなことができるのも プログラミング言語 で処理を書ける CDK ならではの強みです。 デプロイすると、定義した通りのポリシーがコンソールでも確認できました。ポリシー ID は自動で採番されています。 以上で CDK を使った Verified Permission の構築は完了です。 SDK で認可を判定させてみた 構築した Verified Permissions を確認するために、簡単にローカル環境から SDK でリク エス トを投げてみます。 // authorize.ts import { VerifiedPermissionsClient , IsAuthorizedCommand } from "@aws-sdk/client-verifiedpermissions" ; const client = new VerifiedPermissionsClient ( { region: "ap-northeast-1" } ); const command = new IsAuthorizedCommand ( { policyStoreId: "DUMMYSTOREID" , // マネジメントコンソールから確認できるポリシーストアID principal: { entityType: "MyApp::User" , entityId: "alice" } , action: { actionType: "MyApp::Action" , actionId: "GET" } , resource: { entityType: "MyApp::Album" , entityId: "animals" } , } ); client.send ( command ) .then (( result ) => { console .log ( result.decision ); // ALLOW console .log ( JSON .stringify ( result.determiningPolicies )); // [{"policyId":"JLu29q39V62CChNcpFgk3x"}] } ); ユーザーが alice 、リソースが animals アルバムの場合、判定結果は ALLOW となり、どのポリシーで判定されたのかも determiningPolicies プロパティで確認できます。 今度は alice に許可していない flowers アルバムへの認可を判定させてみます。 // authorize.ts const command = new IsAuthorizedCommand ( { policyStoreId: "DUMMYSTOREID" , principal: { entityType: "MyApp::User" , entityId: "alice" } , action: { actionType: "MyApp::Action" , actionId: "GET" } , resource: { entityType: "MyApp::Album" , entityId: "flowers" } , } ); client.send ( command ) .then (( result ) => { console .log ( result.decision ); // DENY console .log ( JSON .stringify ( result.determiningPolicies )); // [] } ); どのポリシーにも当てはまらないため determiningPolicies は空の配列であり、判定結果はデフォルトの DENY となりました。 ちなみに GetPolicyCommand を使うことで、ポリシーの内容を SDK からも取得することができます。 // authorize.ts const command = new GetPolicyCommand ( { policyStoreId: "DUMMYSTOREID" , policyId: "JLu29q39V62CChNcpFgk3x" , } ); client.send ( command ) .then (( result ) => { console .log ( result.definition?. static ?.statement ); } ); // (結果) // // alice に animals アルバムへのアクセスを許可する // permit ( // principal in MyApp::User::"alice", // action in [MyApp::Action::"GET"], // resource in MyApp::Album::"animals" // ); さいごに まだまだ利用が少ないと思われる Amazon Verified Permissions ですが、CDK を使って管理・デプロイすることと相性が良く、使ってみたいという気持ちになりました。 DSL なので提供されている VS Code 拡張を利用したいですし、そうするとファイルの読み込みや、ポリシーファイルの数だけループ処理ができる CDK でデプロイするのが最も便利だと感じました。 Amazon Verified Permissions 自体も、工夫次第では様々な使い方ができそうなので、今後が楽しみなサービスです。 私たちは同じチームで働いてくれる仲間を大募集しています!たくさんのご応募をお待ちしています。 セキュリティエンジニア 執筆: @kou.kinyo 、レビュー: @yamashita.tsuyoshi ( Shodo で執筆されました )
XI本部 スマート ソサエティ センターの飯田です。 私は「DigSports」というAIによって運動能力を測定し、どのスポーツに向いているかを提案する製品のプロダクトオーナーを担当しています。 DigSportsは、運動が苦手な子どもたちや運動から遠ざかってしまった働く世代の方々に対して、自分に合ったスポーツを見つけられる機会を提供し、運動を始めるきっかけや運動習慣化を後押ししています。 isid-ssc.jp そんなDigSportsなのですが、技術的な アーキテクチャ をガラッと変えた新しいバージョンをリリースしました。 AIで適性のあるスポーツを判定する「DigSports」の新バージョンを提供開始 本エントリーでは、新バージョン開発をプロダクトオーナーとして経験した悩みや苦悩を書いてみます。 不安との闘い 要約すると、「不安との闘い」が悩みの根源でした。 技術的なこと、BizDev的なこと、営業戦略、様々な部分で決断が求められました。 自分の選択が間違っていないか? 機能開発の優先度を間違えてないか? 「UX的に良いものをつくる」「技術的に良いものをつくる」「つくったものを広める」そのバランスが良いものになっているか? ...等です。 アジャイル で試行錯誤しながらプロダクトを カイゼン していけるとしても、投資対効果を最大にするために妥当な判断ができているか、「これでいい!」「あ、やっぱダメかも」を繰り返しながら、開発を進めていました。 その中で感じた書いてみます。 1. 資産を作っているか?負債を作っていないか? DigSportsは エンタープライズ なプロダクトと毛色が違うため、 エンタープライズ 製品に比べ、ソフトウェアの規模はそこまで大きくありません。そのため、開発にあたっては「修正対応のしやすさのため、シンプルさを維持する」ことを意識しています。 また、技術的な側面だけでなく、ビジネス開発の観点からもシンプルさを意識しています。 アジャイル など試行錯誤していく開発アプローチは、開発・修正のサイクルを短く回すことができますが、 一方、資産となる市場販売目的のソフトウェア開発にかかった費用は、 3年間の減価償却が行われます。 つまり、今回の開発コストが3年間に按分されることになるので、不要なものを開発すると“ゴミ”・“負債”を作っていることになるので、“資産”として意味のあるものを残していかないといけません。 「今、行おうとしている開発は、改善なのか?改悪なのか?」 もちろん不確実性の中での判断なので、正解はありませんが、3年後を意識して決断していくのは悩みがつきませんでした。 2. 同じ結論になったとしても、1周回ってくると景色やブレなさが違う そのように「資産を作れているか?」と悩みながら進めていく中で、ユーザー・顧客の反応や開発メンバーとの議論は、悩みながら決断をしていく際の大きな拠り所でした。 ユーザー・顧客の反応を見る前後でアイディアが変わらなかったとしても、 ヒアリ ングや議論を経てみると、一周回って自分自身への納得感(ひいては、他人に説得する際の自信)がついている感覚がありました。 3. 「ユーザーの声を聞いている」ということに逃げていないか プロダクト開発における教科書的な模範解答としては「ユーザーの声を聞いて、 アジャイル 的に PDCA を回して改善する」だと思います。実際、DigSportsのリニューアルにおいてもそこは意識しながら進めました。 しかし、ふとした時に、「ユーザーがXXXって言っていたから」というフレーズを多用している自分に気がつきました。 よくよく考えてみると「ユーザーの声を聞いている」という言い訳を手に入れたことによって、自分で意思決定せず、意思を持った決断から逃げていました。プロダクトオーナとしては、考え抜いて意思決定を全うするべきです。 それからは、“ ヒアリ ングの結果”という第三の何かに委ねてしまっていないか?という不安を意識して意思決定するようになりました。 迷ったら議論できる仲間・戻ってくれる軸があるといい プロダクト開発は、正解が見えない不確実性が高い中で判断を迫られることが多く、いろいろな不安と闘いながら意思決定をしました。判断に迷ったときや自信を持てない時、立ち戻ることができる基準や製品コンセプトを拠り所としました。 それでも自分の意思決定がブレてしまっていると感じた時は、一緒に開発していた社内のデザインチーム・社外の開発パートナーさんと相談し、自分の意思決定を整えてもらいました。 DigSportsのリニューアルは製品コンセプトや仲間のおかげで、悩みながらも良い意思決定・開発ができたと思っています。 機会があれば、リニューアルしたDigSportsをぜひご体験ください! www.isid.co.jp 最後に、私たちは一緒に働いてくれる仲間を募集しています! デジタル技術を社会課題解決につなげるようなプロジェクトを推進していきたいプロジェクトマネージャーやエンジニアを募集しています。 ぜひご応募ください! スマートシティ導入コンサルタント/スマートシティ戦略コンサルタント 執筆: @iida.michitaka 、レビュー: @takeda.hideyuki ( Shodo で執筆されました )
XI本部 スマート ソサエティ センターの飯田です。 私は「DigSports」というAIによって運動能力を測定し、どのスポーツに向いているかを提案する製品のプロダクトオーナーを担当しています。 DigSportsは、運動が苦手な子どもたちや運動から遠ざかってしまった働く世代の方々に対して、自分に合ったスポーツを見つけられる機会を提供し、運動を始めるきっかけや運動習慣化を後押ししています。 smart-society.dentsusoken.com そんなDigSportsなのですが、技術的な アーキテクチャ をガラッと変えた新しいバージョンをリリースしました。 AIで適性のあるスポーツを判定する「DigSports」の新バージョンを提供開始 | お知らせ | 電通総研 本エントリーでは、新バージョン開発をプロダクトオーナーとして経験した悩みや苦悩を書いてみます。 不安との闘い 要約すると、「不安との闘い」が悩みの根源でした。 技術的なこと、BizDev的なこと、営業戦略、様々な部分で決断が求められました。 自分の選択が間違っていないか? 機能開発の優先度を間違えてないか? 「UX的に良いものをつくる」「技術的に良いものをつくる」「つくったものを広める」そのバランスが良いものになっているか? ...等です。 アジャイル で試行錯誤しながらプロダクトを カイゼン していけるとしても、投資対効果を最大にするために妥当な判断ができているか、「これでいい!」「あ、やっぱダメかも」を繰り返しながら、開発を進めていました。 その中で感じた書いてみます。 1. 資産を作っているか?負債を作っていないか? DigSportsは エンタープライズ なプロダクトと毛色が違うため、 エンタープライズ 製品に比べ、ソフトウェアの規模はそこまで大きくありません。そのため、開発にあたっては「修正対応のしやすさのため、シンプルさを維持する」ことを意識しています。 また、技術的な側面だけでなく、ビジネス開発の観点からもシンプルさを意識しています。 アジャイル など試行錯誤していく開発アプローチは、開発・修正のサイクルを短く回すことができますが、 一方、資産となる市場販売目的のソフトウェア開発にかかった費用は、 3年間の減価償却が行われます。 つまり、今回の開発コストが3年間に按分されることになるので、不要なものを開発すると“ゴミ”・“負債”を作っていることになるので、“資産”として意味のあるものを残していかないといけません。 「今、行おうとしている開発は、改善なのか?改悪なのか?」 もちろん不確実性の中での判断なので、正解はありませんが、3年後を意識して決断していくのは悩みがつきませんでした。 2. 同じ結論になったとしても、1周回ってくると景色やブレなさが違う そのように「資産を作れているか?」と悩みながら進めていく中で、ユーザー・顧客の反応や開発メンバーとの議論は、悩みながら決断をしていく際の大きな拠り所でした。 ユーザー・顧客の反応を見る前後でアイディアが変わらなかったとしても、 ヒアリ ングや議論を経てみると、一周回って自分自身への納得感(ひいては、他人に説得する際の自信)がついている感覚がありました。 3. 「ユーザーの声を聞いている」ということに逃げていないか プロダクト開発における教科書的な模範解答としては「ユーザーの声を聞いて、 アジャイル 的に PDCA を回して改善する」だと思います。実際、DigSportsのリニューアルにおいてもそこは意識しながら進めました。 しかし、ふとした時に、「ユーザーがXXXって言っていたから」というフレーズを多用している自分に気がつきました。 よくよく考えてみると「ユーザーの声を聞いている」という言い訳を手に入れたことによって、自分で意思決定せず、意思を持った決断から逃げていました。プロダクトオーナとしては、考え抜いて意思決定を全うするべきです。 それからは、“ ヒアリ ングの結果”という第三の何かに委ねてしまっていないか?という不安を意識して意思決定するようになりました。 迷ったら議論できる仲間・戻ってくれる軸があるといい プロダクト開発は、正解が見えない不確実性が高い中で判断を迫られることが多く、いろいろな不安と闘いながら意思決定をしました。判断に迷ったときや自信を持てない時、立ち戻ることができる基準や製品コンセプトを拠り所としました。 それでも自分の意思決定がブレてしまっていると感じた時は、一緒に開発していた社内のデザインチーム・社外の開発パートナーさんと相談し、自分の意思決定を整えてもらいました。 DigSportsのリニューアルは製品コンセプトや仲間のおかげで、悩みながらも良い意思決定・開発ができたと思っています。 機会があれば、リニューアルしたDigSportsをぜひご体験ください! www.isid.co.jp 最後に、私たちは一緒に働いてくれる仲間を募集しています! デジタル技術を社会課題解決につなげるようなプロジェクトを推進していきたいプロジェクトマネージャーやエンジニアを募集しています。 ぜひご応募ください! スマートシティ導入コンサルタント/スマートシティ戦略コンサルタント 執筆: @iida.michitaka 、レビュー: @takeda.hideyuki ( Shodo で執筆されました )
こんにちは、X(クロス) イノベーション 本部 クラウド イノベーション センターの田村です。 Microsoft Fabric では Git 統合が提供されており、 ワークスペース 内のアイテムに対して Git によるソース管理が可能です。 本記事では、実際に Git 統合を利用したソース管理の手順や制約事項についてご紹介します。 「 Microsoft Fabric とは?」という方は下記の紹介記事や Microsoft Fabric のドキュメントをご参照ください。 Microsoft Fabric を利用して自分の勤怠データを分析する Microsoft Fabric とは なお、本記事に記載されている情報は 2023 年 8 月時点のものとなります。 Microsoft Fabric のアップデートや一般公開(GA)で情報が更新される場合もありますのでご注意ください。 Microsoft Fabric の Git 統合について 概要 ソース管理対象 制約事項 Git 統合の実践 Azure Repos の準備 Microsoft Fabric ワークスペースと Git リポジトリの接続 アイテムに対する変更適用 ソース管理時の注意点 まとめ Microsoft Fabric の Git 統合について 概要 Git 統合は Microsoft Fabric の ワークスペース と Git リポジトリ を接続することで実現します。 両者を接続することで ワークスペース 内のアイテムが Git リポジトリ と同期され、アイテムの変更差分が検出されます。 また、Git におけるコミットやコミット前の変更取り消しは Microsoft Fabric の UI 上から実施できるように設計されています。 ソース管理対象 Git 統合はプレビュー中のため、ソース管理がサポートされる Microsoft Fabric のアイテムは 2 つのみとなっています。 レポート:デー タセット をもとに Power BI により可視化されたグラフや表、マップなどのビジュアル群 デー タセット :Power BI での検出・可視化が可能となったデータソース 現時点ではデータ分析における可視化領域のみで Git 統合を利用できますが、 Microsoft のドキュメント には次の記載があるため、今後サポート対象となるアイテムの追加に期待したいと思います。 現在、プレビュー段階ではいくつかのアイテムのみがサポートされていますが、一覧のサポートされているアイテムは増えています。 制約事項 ワークスペース と接続できる Git リポジトリ は Azure Repos のみがサポートされており、 GitHub 上の リポジトリ は現在サポート外となっています。 Microsoft Fabric のコミュニティサイト では、 GitHub を含めたサポートの拡大要望が寄せられていますが、 Microsoft 側の対応可否や時期は不明です。 Support GitHub in the git integration for workspaces Support for git repositories other than Azure DevOps Git 統合の実践 Azure Repos の準備 前述したとおり Git 統合にてサポートされるのは Azure Repos のみであるため、そちらで Git リポジトリ を準備します。 Azure Repos とは、 Microsoft が提供する DevOps 支援サービスである Azure DevOps に含まれる Git の ホスティング サービスです。 Azure DevOps Services Azure Repos – Git リポジトリ 今回は検証のために Azure DevOps プロジェクトを作成し、Azure Repos 上で Git 統合用の リポジトリ を構成しました。 プロジェクト名と Git リポジトリ 名は msfabric-test としています。 Azure Repos の初期設定については下記ドキュメントをご参照ください。 Azure Repos の使用を開始する なお、以降 Azure Repos に対する操作はすべてプロジェクト管理者権限で実施しています。 Microsoft Fabric ワークスペース と Git リポジトリ の接続 こちら のドキュメントに従って接続設定を実施します。 以降の Microsoft Fabric における操作は、作業者アカウントに ワークスペース の管理者権限があることを前提としています。 Microsoft Fabric の[ ワークスペース の設定] > [Git 統合]より、接続先の Azure Repos の情報を入力し[接続と同期]を実行します。 同期が完了すると、 ワークスペース 内のレポートとデー タセット が Azure Repos の Git リポジトリ へ反映されます。 このとき、末尾が .Dataset の ディレクト リと .Report の ディレクト リにデー タセット とレポートの構成ファイルがそれぞれ格納されています。 アイテムに対する変更適用 レポートとデー タセット に対してそれぞれ変更を加え、ソース管理の流れを確認します。 検証用のデー タセット は Microsoft Fabric のチュートリアル で提供されている 卸売業の売上データ を利用しました。 売上データが格納された 1 つのファクトテーブルと、商品や顧客、従業員といった情報が格納された 5 つのディメンションテーブルで構成されています。 検証用のレポートは前述のデー タセット から自動生成しており、複数のグラフとカードおよびテキストビジュアルから構成されています。 まずはデー タセット に対して変更を加えてみます。 今回は、 Microsoft Fabric の GUI からデー タセット に構成されているリレーションシップを 1 件削除し、構成ファイルにどのような変更があるか確認しました。 デー タセット に変更を加えると、 ワークスペース のアイテム一覧画面で検出されます。 同画面でトピックブランチへチェックアウトして変更をコミットすると、同期先の Azure Repos にて変更された構成ファイルや箇所を確認できます。 検証用のデー タセット は 4 つのファイルで構成されており、リレーションシップの設定については model.bim というファイルのみに変更が適用されていました。 各ファイルの説明を下表に記載します。 ファイル名  必須  説明 model.bim 〇 データベースオブジェクトの定義が Tabular Model Scripting Language(TMSL)で記述されている definition.pbidataset 〇 デー タセット に関連付けられた Q&A や スキーマ 共有に関する設定が記述されている item.config.json ファイルのバージョン情報と同期先の ワークスペース ID が記述されている item.metadata.json Git 統合されているアイテムの種別(ここではデー タセット )とアイテム名、説明が記述されている 上記をふまえると、デー タセット に対して想定される下記のような操作については、その変更が model.bim の記述に反映されると推測できます。 テーブルの追加・削除 データの挿入・更新や削除 データモデルでのメジャー作成 リレーションシップの変更 次にレポートに対しても変更を加えます。 Microsoft Fabric の Power BI にて、前述したレポートに下図のカードとグラフビジュアルを追加しました。 デー タセット に対する変更と同様、上記の変更は ワークスペース のアイテム一覧画面で検出され、コミット後に Azure Repos 側で詳細を確認できます。 検証用のレポートは 5 つのファイルで構成されており、今回の変更については report.json というファイルのみに変更が適用されていました。 各ファイルの説明を下表に記載します。 ファイル名  必須  説明 CY23SU08.json レポートのカスタムテーマ、イメージ、カスタムビジュアルなどの固有情報が記述されている definition.pbir 〇 参照するデー タセット に関する情報が記述されている report.json 〇 レポートに含まれるページ、ビジュアルの情報が記述されている item.config.json ファイルのバージョン情報と同期先の ワークスペース ID が記述されている item.metadata.json Git 統合されているアイテムの種別(ここではレポート)とアイテム名、説明が記述されている 今回はレポートのビジュアルに関する変更のみを実施したため、 report.json の記述のみが影響を受けたと考えられます。 また、デー タセット およびレポートの設定によっては上記に加えて追加の構成ファイルが必要になる場合もあります。 詳細は下記ドキュメントをご参照ください。 Git 統合ソース コード フォーマット Power BI Desktop プロジェクト データセット フォルダー Power BI Desktop プロジェクト レポート フォルダー 変更内容をコミットした後は、Pull Request による一般的なレビュー手順に沿って main ブランチへ変更を適用できました。 トピックブランチとマージ先のブランチ( main )およびレビュアーを指定し、Pull Request を作成 レビュアーは Pull Request の内容を確認し、指摘やコメントをレビュイーに伝える レビューに問題がなければレビュアーの承認をもって Pull Request を完了し、変更を main ブランチへマージする また、今回は実施しませんでしたが Microsoft Fabric では Azure Pipelines を利用したテスト・デプロイの自動化についてもサポートしています。 Azure Pipelines は Azure Repos と同様 Azure DevOps に含まれるサービスのため、Git 統合とうまく組み合わせて CI/CD 環境を構築することで開発やテストの効率化が期待できます。 Azure Pipelines デプロイ パイプラインの概要 ソース管理時の注意点 Microsoft Fabric 上ではレポートやデー タセット といったアイテムの構成ファイルを管理していないため、Git クライアントアプリケーションのように具体的な変更箇所がわかりません。 そのため、作業者自身が変更内容を正しく把握し、適切なコミットメッセージの記述等で円滑なコミュニケーションを図るといった意識が重要になります。 また、 Microsoft Fabric の UI で可能な Git 操作は現状 git commit と git checkout のみです。 コミットの取り消しやリベースなどの操作が必要になった際は、Git コマンドライン ツールや Git クライアントアプリケーションを Azure Repos と併用する必要があります。 まとめ 本記事では、 Microsoft Fabric の Git 統合を利用したソース管理について、実際に利用した際の手順や注意事項、所感についてご紹介しました。 これまで Power BI のデー タセット やレポートといったアイテムはテキストベースでのソース管理ができませんでしたが、Git 統合により GUI 上で可能になった点は魅力的だと感じています。 一方で、一般的なソース管理ではコミットの取り消しやその他 Git コマンドを利用した作業も多いため、Git クライアントや コマンドライン ツールと併用した管理方法も選択肢になり得ます。 現時点では可視化領域のアイテムのみが Git 統合に対応していますが、将来的にはデータ加工や変換、分析といった領域で必要となる ETL パイプラインやデータフロー、各種クエリについてもソース管理の対象となることを期待します。 私たちは一緒に働いてくれる仲間を募集しています! クラウドアーキテクト 執筆: @tamura.kohei 、レビュー: @kano.nanami ( Shodo で執筆されました )
こんにちは、X(クロス) イノベーション 本部 クラウド イノベーション センターの田村です。 Microsoft Fabric では Git 統合が提供されており、 ワークスペース 内のアイテムに対して Git によるソース管理が可能です。 本記事では、実際に Git 統合を利用したソース管理の手順や制約事項についてご紹介します。 「 Microsoft Fabric とは?」という方は下記の紹介記事や Microsoft Fabric のドキュメントをご参照ください。 Microsoft Fabric を利用して自分の勤怠データを分析する Microsoft Fabric とは なお、本記事に記載されている情報は 2023 年 8 月時点のものとなります。 Microsoft Fabric のアップデートや一般公開(GA)で情報が更新される場合もありますのでご注意ください。 Microsoft Fabric の Git 統合について 概要 ソース管理対象 制約事項 Git 統合の実践 Azure Repos の準備 Microsoft Fabric ワークスペースと Git リポジトリの接続 アイテムに対する変更適用 ソース管理時の注意点 まとめ Microsoft Fabric の Git 統合について 概要 Git 統合は Microsoft Fabric の ワークスペース と Git リポジトリ を接続することで実現します。 両者を接続することで ワークスペース 内のアイテムが Git リポジトリ と同期され、アイテムの変更差分が検出されます。 また、Git におけるコミットやコミット前の変更取り消しは Microsoft Fabric の UI 上から実施できるように設計されています。 ソース管理対象 Git 統合はプレビュー中のため、ソース管理がサポートされる Microsoft Fabric のアイテムは 2 つのみとなっています。 レポート:デー タセット をもとに Power BI により可視化されたグラフや表、マップなどのビジュアル群 デー タセット :Power BI での検出・可視化が可能となったデータソース 現時点ではデータ分析における可視化領域のみで Git 統合を利用できますが、 Microsoft のドキュメント には次の記載があるため、今後サポート対象となるアイテムの追加に期待したいと思います。 現在、プレビュー段階ではいくつかのアイテムのみがサポートされていますが、一覧のサポートされているアイテムは増えています。 制約事項 ワークスペース と接続できる Git リポジトリ は Azure Repos のみがサポートされており、 GitHub 上の リポジトリ は現在サポート外となっています。 Microsoft Fabric のコミュニティサイト では、 GitHub を含めたサポートの拡大要望が寄せられていますが、 Microsoft 側の対応可否や時期は不明です。 Support GitHub in the git integration for workspaces Support for git repositories other than Azure DevOps Git 統合の実践 Azure Repos の準備 前述したとおり Git 統合にてサポートされるのは Azure Repos のみであるため、そちらで Git リポジトリ を準備します。 Azure Repos とは、 Microsoft が提供する DevOps 支援サービスである Azure DevOps に含まれる Git の ホスティング サービスです。 Azure DevOps Services Azure Repos – Git リポジトリ 今回は検証のために Azure DevOps プロジェクトを作成し、Azure Repos 上で Git 統合用の リポジトリ を構成しました。 プロジェクト名と Git リポジトリ 名は msfabric-test としています。 Azure Repos の初期設定については下記ドキュメントをご参照ください。 Azure Repos の使用を開始する なお、以降 Azure Repos に対する操作はすべてプロジェクト管理者権限で実施しています。 Microsoft Fabric ワークスペース と Git リポジトリ の接続 こちら のドキュメントに従って接続設定を実施します。 以降の Microsoft Fabric における操作は、作業者アカウントに ワークスペース の管理者権限があることを前提としています。 Microsoft Fabric の[ ワークスペース の設定] > [Git 統合]より、接続先の Azure Repos の情報を入力し[接続と同期]を実行します。 同期が完了すると、 ワークスペース 内のレポートとデー タセット が Azure Repos の Git リポジトリ へ反映されます。 このとき、末尾が .Dataset の ディレクト リと .Report の ディレクト リにデー タセット とレポートの構成ファイルがそれぞれ格納されています。 アイテムに対する変更適用 レポートとデー タセット に対してそれぞれ変更を加え、ソース管理の流れを確認します。 検証用のデー タセット は Microsoft Fabric のチュートリアル で提供されている 卸売業の売上データ を利用しました。 売上データが格納された 1 つのファクトテーブルと、商品や顧客、従業員といった情報が格納された 5 つのディメンションテーブルで構成されています。 検証用のレポートは前述のデー タセット から自動生成しており、複数のグラフとカードおよびテキストビジュアルから構成されています。 まずはデー タセット に対して変更を加えてみます。 今回は、 Microsoft Fabric の GUI からデー タセット に構成されているリレーションシップを 1 件削除し、構成ファイルにどのような変更があるか確認しました。 デー タセット に変更を加えると、 ワークスペース のアイテム一覧画面で検出されます。 同画面でトピックブランチへチェックアウトして変更をコミットすると、同期先の Azure Repos にて変更された構成ファイルや箇所を確認できます。 検証用のデー タセット は 4 つのファイルで構成されており、リレーションシップの設定については model.bim というファイルのみに変更が適用されていました。 各ファイルの説明を下表に記載します。 ファイル名  必須  説明 model.bim 〇 データベースオブジェクトの定義が Tabular Model Scripting Language(TMSL)で記述されている definition.pbidataset 〇 デー タセット に関連付けられた Q&A や スキーマ 共有に関する設定が記述されている item.config.json ファイルのバージョン情報と同期先の ワークスペース ID が記述されている item.metadata.json Git 統合されているアイテムの種別(ここではデー タセット )とアイテム名、説明が記述されている 上記をふまえると、デー タセット に対して想定される下記のような操作については、その変更が model.bim の記述に反映されると推測できます。 テーブルの追加・削除 データの挿入・更新や削除 データモデルでのメジャー作成 リレーションシップの変更 次にレポートに対しても変更を加えます。 Microsoft Fabric の Power BI にて、前述したレポートに下図のカードとグラフビジュアルを追加しました。 デー タセット に対する変更と同様、上記の変更は ワークスペース のアイテム一覧画面で検出され、コミット後に Azure Repos 側で詳細を確認できます。 検証用のレポートは 5 つのファイルで構成されており、今回の変更については report.json というファイルのみに変更が適用されていました。 各ファイルの説明を下表に記載します。 ファイル名  必須  説明 CY23SU08.json レポートのカスタムテーマ、イメージ、カスタムビジュアルなどの固有情報が記述されている definition.pbir 〇 参照するデー タセット に関する情報が記述されている report.json 〇 レポートに含まれるページ、ビジュアルの情報が記述されている item.config.json ファイルのバージョン情報と同期先の ワークスペース ID が記述されている item.metadata.json Git 統合されているアイテムの種別(ここではレポート)とアイテム名、説明が記述されている 今回はレポートのビジュアルに関する変更のみを実施したため、 report.json の記述のみが影響を受けたと考えられます。 また、デー タセット およびレポートの設定によっては上記に加えて追加の構成ファイルが必要になる場合もあります。 詳細は下記ドキュメントをご参照ください。 Git 統合ソース コード フォーマット Power BI Desktop プロジェクト データセット フォルダー Power BI Desktop プロジェクト レポート フォルダー 変更内容をコミットした後は、Pull Request による一般的なレビュー手順に沿って main ブランチへ変更を適用できました。 トピックブランチとマージ先のブランチ( main )およびレビュアーを指定し、Pull Request を作成 レビュアーは Pull Request の内容を確認し、指摘やコメントをレビュイーに伝える レビューに問題がなければレビュアーの承認をもって Pull Request を完了し、変更を main ブランチへマージする また、今回は実施しませんでしたが Microsoft Fabric では Azure Pipelines を利用したテスト・デプロイの自動化についてもサポートしています。 Azure Pipelines は Azure Repos と同様 Azure DevOps に含まれるサービスのため、Git 統合とうまく組み合わせて CI/CD 環境を構築することで開発やテストの効率化が期待できます。 Azure Pipelines デプロイ パイプラインの概要 ソース管理時の注意点 Microsoft Fabric 上ではレポートやデー タセット といったアイテムの構成ファイルを管理していないため、Git クライアントアプリケーションのように具体的な変更箇所がわかりません。 そのため、作業者自身が変更内容を正しく把握し、適切なコミットメッセージの記述等で円滑なコミュニケーションを図るといった意識が重要になります。 また、 Microsoft Fabric の UI で可能な Git 操作は現状 git commit と git checkout のみです。 コミットの取り消しやリベースなどの操作が必要になった際は、Git コマンドライン ツールや Git クライアントアプリケーションを Azure Repos と併用する必要があります。 まとめ 本記事では、 Microsoft Fabric の Git 統合を利用したソース管理について、実際に利用した際の手順や注意事項、所感についてご紹介しました。 これまで Power BI のデー タセット やレポートといったアイテムはテキストベースでのソース管理ができませんでしたが、Git 統合により GUI 上で可能になった点は魅力的だと感じています。 一方で、一般的なソース管理ではコミットの取り消しやその他 Git コマンドを利用した作業も多いため、Git クライアントや コマンドライン ツールと併用した管理方法も選択肢になり得ます。 現時点では可視化領域のアイテムのみが Git 統合に対応していますが、将来的にはデータ加工や変換、分析といった領域で必要となる ETL パイプラインやデータフロー、各種クエリについてもソース管理の対象となることを期待します。 私たちは一緒に働いてくれる仲間を募集しています! クラウドアーキテクト 執筆: @tamura.kohei 、レビュー: @kano.nanami ( Shodo で執筆されました )
はじめに ISID X(クロス) イノベーション 本部 の池田です。 Azure Portal から Azure Load Testing を操作する方法については以下の記事もご覧ください。 tech.isid.co.jp 負荷試験 の計画の中でいろいろな利用パターンでの試験により環境を分析するケースがあります。 しかし、Azure Portal からの操作では JMeter スクリプト のアップロードや参照できるリソース選択など選択項目が多く、複数パターンを何度も手動で作成するのは手間です。 そこで CLI から操作して複数テストを一括登録する方法を試しましたのでご紹介します。 利用ツール 通常のAzureリソースの CLI 操作としては、Azure CLI や Azure Power Shell, ARMテンプレート を利用するのが一般的です。しかし、2023年2月にGAしたばかりの Azure Load Testing においては 2023年5月時点でこれらのツールでAzureリソース作成はできるものの詳細な設定ができませんでした。Azure Load Testing REST API では先行してテスト作成の機能が提供されていたため、こちらを利用して作成します。(現在はAzure CLI によるテスト作成もサポートされるようになっています) 今回の スクリプト 実行環境は以下のとおりです。 スクリプト の記載は環境依存のものが含まれますので、参考にされる際はご自身の環境に合わせて調整してください。 PowerShell 7.3.4 azure-cli 2.49.0 curl 8.0.1 (Windows) libcurl/8.0.1 Schannel WinIDN 試験環境の概要 今回使用するテスト環境の構成は以下のとおりです。App Service 既定のWebサイトをテスト対象としてAzure Load TestingからHTTPリク エス トを連続送信します。その上でAzureリソースの負荷状況を Azure Load Testing の ダッシュ ボードに表示する構成となります。 Azure Load Testingリソースの作成 Azureリソース作成はAzure CLI で機能提供されていましたので、この部分はこちらのコマンドを利用して作成します。 az load create --name ${loadTestName} -- resource-group ${resourceGroupName} --location eastasia データプレーン URI の取得 Azure リソースマネージャーに対する要求では az rest コマンドを利用すると認証ヘッダーを自動付与できて便利です。 az rest で REST API を呼び出して作成されたリソースのデータプレーンエンドポイントを取得します。 $loadTest = ( az rest ` --method get ` --uri https: // management.azure.com / subscriptions / ${subscriptionId} / resourceGroups / ${resourceGroupName} / providers / Microsoft.LoadTestService / loadTests / ${loadTestName} ? api-version = 2022 - 12 - 01 ` | ConvertFrom-Json ) $Endpoint = $loadTest .properties.dataPlaneURI $Endpoint 以下のような出力が得られます。これでデータプレーン操作に必要なエンドポイントが取得できました。 XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.eastasia.cnt-prod.loadtesting.azure.com データプレーン用アクセス トーク ンの取得 ここからは Azureリソースマネージャー へのアクセスではなくデータプレーンエンドポイントへの操作となります。データプレーン用のアクセス トーク ンを取得する必要があります。 必要なアクセス トーク ン Azure Load Testing REST API のリファレンスを参照すると、「 https://cnt-prod.loadtesting.azure.com/.default%E3%80%8D%E3%82%92Scope%E3%81%A8%E3%81%97%E3%81%9F%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%81%8C%E5%BF%85%E8%A6%81%E3%81%A8%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82 Load Test Administration - Create Or Update Test アクセス トーク ンの取得 az account get- access -token コマンドを利用して、該当スコープに対するアクセス トーク ンを取得します。 ( 参考: az account get-access-token ) $accessToken = (az account get-access-token ` --scope 'https://cnt-prod.loadtesting.azure.com/.default' ` --query 'accessToken' ` --output tsv) テストの構成 データプレーンエンドポイントとアクセス トーク ンがそろいましたので、続いてデータプレーンの操作をします。 データプレーンはTemplateファイルを用意してそれを curl コマンドで投げ込む形で操作します。 ID採番 まずは、テストIDとして使用するGuidを採番します。 $testId = ( New-Guid ) テスト作成 実際にAzure Load Testing REST API を呼び出してテストを作成していきます。 (参考: Load Test Administration - Create Or Update Test ) curl ` --request PATCH ` --header "Authorization: Bearer $accessToken " ` --header "Content-Type: application/merge-patch+json" ` --url "https:// ${Endpoint} /tests/ ${testId} ?api-version=2022-11-01" ` -- upload-file TestTemplate.json 送信ファイルに記述するパラメータが以下となります。Azure Portal 上で作成したテストの内容を API で取得して参考にしつつ作るのがおすすめです。 (参考: Load Test Administration - Get Test ) { "displayName": "displayName_test1", "description": "", "keyvaultReferenceIdentityType": "SystemAssigned", "passFailCriteria": { "passFailMetrics": {} }, "loadTestConfiguration": { "engineInstances": 10, "splitAllCSVs": false, "quickStartTest": false } } アプリ コンポーネント 登録 次にテスト結果画面に表示するアプリ コンポーネント (Azure リソースのコレクション)を登録します。 (参考: Load Test Administration - Create Or Update App Components ) curl ` --request PATCH ` --header "Authorization: Bearer $accessToken " ` --header "Content-Type: application/merge-patch+json" ` --url "https:// ${Endpoint} /tests/ ${testId} /app-components?api-version=2022-11-01" ` -- upload-file AppComponents.json アプリ コンポーネント は以下のように列挙していく形で登録します。参考とする既存設定の取得 API は以下です。 (参考: Load Test Administration - Get App Components ) { "components": { "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-load-test/providers/Microsoft.Web/sites/app-demo-ikeda": { "resourceId": "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-load-test/providers/Microsoft.Web/sites/app-demo-ikeda", "resourceName": "app-demo-ikeda", "resourceType": "Microsoft.Web/sites", "resourceGroup": "rg-load-test", "subscriptionId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", "kind": "app" }, "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-load-test/providers/Microsoft.Web/serverfarms/plan-load-demo": { "resourceId": "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-load-test/providers/Microsoft.Web/serverfarms/plan-load-demo", "resourceName": "plan-load-demo", "resourceType": "Microsoft.Web/serverfarms", "resourceGroup": "rg-load-test", "subscriptionId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", "kind": "app" } } } メトリック登録 続いて、テスト結果画面に表示するメトリックを登録します。 (参考: Load Test Administration - Create Or Update Server Metrics Config ) curl ` --request PATCH ` --header "Authorization: Bearer $accessToken " ` --header "Content-Type: application/merge-patch+json" ` --url "https:// ${Endpoint} /tests/ ${testId} /server-metrics-config?api-version=2022-11-01" ` -- upload-file ServerMetricsConfig.json 前段で登録したアプリ コンポーネント に対するメトリックを列挙します。参考とする既存設定の取得 API は下記です。 (参考: Load Test Administration - Get Server Metrics Config ) { "metrics": { "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-load-test/providers/Microsoft.Web/sites/app-demo-ikeda/providers/microsoft.insights/metricdefinitions/Http5xx": { "id": "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-load-test/providers/Microsoft.Web/sites/app-demo-ikeda/providers/microsoft.insights/metricdefinitions/Http5xx", "resourceId": "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-load-test/providers/Microsoft.Web/sites/app-demo-ikeda", "metricNamespace": "microsoft.web/sites", "name": "Http5xx", "aggregation": "Total", "resourceType": "microsoft.web/sites" }, "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-load-test/providers/Microsoft.Web/sites/app-demo-ikeda/providers/microsoft.insights/metricdefinitions/Requests": { "id": "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-load-test/providers/Microsoft.Web/sites/app-demo-ikeda/providers/microsoft.insights/metricdefinitions/Requests", "resourceId": "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-load-test/providers/Microsoft.Web/sites/app-demo-ikeda", "metricNamespace": "microsoft.web/sites", "name": "Requests", "aggregation": "Total", "resourceType": "microsoft.web/sites" }, "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-load-test/providers/Microsoft.Web/sites/app-demo-ikeda/providers/microsoft.insights/metricdefinitions/HttpResponseTime": { "id": "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-load-test/providers/Microsoft.Web/sites/app-demo-ikeda/providers/microsoft.insights/metricdefinitions/HttpResponseTime", "resourceId": "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-load-test/providers/Microsoft.Web/sites/app-demo-ikeda", "metricNamespace": "microsoft.web/sites", "name": "HttpResponseTime", "aggregation": "Average", "resourceType": "microsoft.web/sites" }, "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-load-test/providers/Microsoft.Web/serverfarms/plan-load-demo/providers/microsoft.insights/metricdefinitions/CpuPercentage": { "id": "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-load-test/providers/Microsoft.Web/serverfarms/plan-load-demo/providers/microsoft.insights/metricdefinitions/CpuPercentage", "resourceId": "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-load-test/providers/Microsoft.Web/serverfarms/plan-load-demo", "metricNamespace": "microsoft.web/serverfarms", "name": "CpuPercentage", "aggregation": "Average", "resourceType": "microsoft.web/serverfarms" }, "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-load-test/providers/Microsoft.Web/serverfarms/plan-load-demo/providers/microsoft.insights/metricdefinitions/MemoryPercentage": { "id": "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-load-test/providers/Microsoft.Web/serverfarms/plan-load-demo/providers/microsoft.insights/metricdefinitions/MemoryPercentage", "resourceId": "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-load-test/providers/Microsoft.Web/serverfarms/plan-load-demo", "metricNamespace": "microsoft.web/serverfarms", "name": "MemoryPercentage", "aggregation": "Average", "resourceType": "microsoft.web/serverfarms" } } } JMeter スクリプト 登録 以下の操作でテストで実行する JMeter スクリプト をアップロードします。 (参考: Load Test Administration - Upload Test File ) curl ` --request PUT ` --header "Authorization: Bearer $accessToken " ` --header "Content-Type: application/octet-stream content" ` --url "https:// ${Endpoint} /tests/ ${testId} /files/ ${NAME_JMX} ?api-version=2022-11-01&fileType=JMX_FILE" ` -- upload-file lt-demo .jmx こちらが JMeter で作成した JMX ファイルです。今回はHTTP Getリク エス トをループするシンプルな スクリプト を使用しています。 <?xml version="1.0" encoding="UTF-8"?> <jmeterTestPlan version="1.2" properties="5.0" jmeter="5.5"> <hashTree> <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true"> <stringProp name="TestPlan.comments"></stringProp> <boolProp name="TestPlan.functional_mode">false</boolProp> <boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp> <boolProp name="TestPlan.serialize_threadgroups">false</boolProp> <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true"> <collectionProp name="Arguments.arguments"/> </elementProp> <stringProp name="TestPlan.user_define_classpath"></stringProp> </TestPlan> <hashTree> <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true"> <stringProp name="ThreadGroup.on_sample_error">continue</stringProp> <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true"> <boolProp name="LoopController.continue_forever">false</boolProp> <intProp name="LoopController.loops">-1</intProp> </elementProp> <stringProp name="ThreadGroup.num_threads">10</stringProp> <stringProp name="ThreadGroup.ramp_time">1</stringProp> <boolProp name="ThreadGroup.scheduler">false</boolProp> <stringProp name="ThreadGroup.duration"></stringProp> <stringProp name="ThreadGroup.delay"></stringProp> <boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp> </ThreadGroup> <hashTree> <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="HTTP Request" enabled="true"> <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true"> <collectionProp name="Arguments.arguments"/> </elementProp> <stringProp name="HTTPSampler.domain">app-demo-ikeda.azurewebsites.net</stringProp> <stringProp name="HTTPSampler.port">443</stringProp> <stringProp name="HTTPSampler.protocol">https</stringProp> <stringProp name="HTTPSampler.contentEncoding"></stringProp> <stringProp name="HTTPSampler.path"></stringProp> <stringProp name="HTTPSampler.method">GET</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> <boolProp name="HTTPSampler.auto_redirects">false</boolProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp> <stringProp name="HTTPSampler.embedded_url_re"></stringProp> <stringProp name="HTTPSampler.connect_timeout"></stringProp> <stringProp name="HTTPSampler.response_timeout"></stringProp> </HTTPSamplerProxy> <hashTree/> </hashTree> </hashTree> </hashTree> </jmeterTestPlan> テストの実行 テスト実行 ボディ部にテストIDを指定することで登録したテスト内容を実行できます。テスト表示名は スクリプト 内で日時から作成しています。 (参考: Load Test Run - Create Or Update Test Run ) curl ` --request PATCH ` --header "Authorization: Bearer $accessToken" ` --header "Content-Type: application/merge-patch+json" ` --url "https://${Endpoint}/test-runs/$(New-Guid)?api-version=2022-11-01" ` --data "{'testId': '${testId}','displayName':'TestRun_$((Get-Date).ToString("yyyy/MM/dd_HH:mm:ss"))'}" 実行結果の確認 Azure Portal での確認 Azure Portal 上で作成したテストが実行されていることを確認できます。 アプリ コンポーネント テスト画面の「アプリ コンポーネント 」から REST API で登録したアプリ コンポーネント が確認できます。 メトリックの構成 同じく「メトリックの構成」から表示メトリックも反映されていることが確認できます。 備考 ドキュメントが整備されていない場合、 API の利用方法を調べるのにブラウザのDevToolsでAzure Portal の通信内容を見るのも参考になります。今回もAzure Portal 上での設定項目と API 項目に差異があり、通信内容を見てみると新しい Preview バージョンの API を利用していました。新しいサービスではドキュメント化が遅れているケースもありますので必要に応じて参考にしましょう。 まとめ Azure Load Testing の操作を REST API を利用して スクリプト 化することで、複数パターンの試験登録が簡単にできるようになりました。新しいサービスでは周辺ツールがまだ提供されていないケースもありますが、ベースとなる REST API が先行して提供されていることがあります。 REST API による操作も活用することでAzureでできることが広がります。ご参考になれば幸いです。 私たちは同じチームで働いてくれる仲間を探しています。 クラウド アーキテクトの業務に興味がある方のご応募をお待ちしています。 クラウドアーキテクト 執筆: @ikeda.jun 、レビュー: @mizuno.kazuhiro ( Shodo で執筆されました )