TECH PLAY

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

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

1226

CatoクラウドにおけるDHCPの仕様について、アップデートが行われたため解説いたします。 はじめに:DHCPとCatoクラウド DHCPは、ネットワークに接続する機器に対してIPアドレスなどの必要な情報を自動で配布する、非常に多くの環境で利用される機能です。ADサーバやルータ等の機器に搭載されていることが多いものですが、Catoクラウドにおいてルータに相当する役割となるCato Socketにも当然DHCP機能が存在します。 このCatoのDHCP機能、従来はかゆいところに手の届かない仕様だったのですが、近日のアップデートによって使い勝手が向上しました。この記事では、その内容について紹介していきます。 DHCPの機能強化:Site編 まず、Catoと接続された拠点(Site)におけるDHCP機能の強化を解説いたします。 複数のDHCPレンジ指定に対応! DHCPの設定を行う上では、DHCPレンジ、すなわち「どのIPアドレスを配布して良いか」の指定が必須となります。 CatoのSite配下におけるDHCP設定には「1つのサブネットにつき、連続した1つのDHCPレンジしか設定できない」という制約があったのですが、アップデートにより 複数レンジの設定が可能 となりました。 これが何を意味するのか、具体的な例を挙げて確認します。 Cato Socketを配置した拠点の内部ネットワークが、以下のような使われ方をしていたとします。 A拠点:192.168.1.0/24 Cato Socket:192.168.1.1 固定IPの機器(プリンタ、一部PC等)用レンジ:192.168.1.101 – 192.168.1.150 スイッチ類:192.168.1.251 – 253 この場合、「連続した1レンジしか設定できない」という従来の仕様では、DHCPレンジは広く取っても以下のいずれかということになります。 ・192.168.1.2 – 192.168.1.100 ・192.168.1.151 – 192.168.1.250 仮にDHCPでつなぐ機器が100を超えたら、従来の仕様では対応できなくなるわけです。 (※厳密には固定IP用レンジのIPすべてに「Static Host Reservation」を設定すれば対処可能ではあるのですが、少々厳しい対処方法です。) アップデートにより、上記のようなケースでも「2つのレンジを指定する」であっさり対応できるようになりました。IPアドレスの利用範囲が1か所に固まっていないケースは決して珍しくないため、うれしい仕様変更です。 DHCPに高度なセキュリティを!「Microsegmentation」機能 Site内のDHCPには、新たなオプション機能として「Microsegmentation」機能が追加されました。 デフォルトでは無効となっているこの機能を有効にすると、DHCPによってIPアドレスを配布するときに「/32」のセグメントとして配布を行うようになります。 ローカルネットワークにおいて、「同じサブネットであれば、通信はスムーズに通る」場合が大半です。これ自体は別に悪いことではないのですが、悪意のある利用者が存在する場合、同セグメント内の偵察や攻撃は比較的簡単にできてしまう、という構造上の弱点にもなりえてしまいます。 Microsegmentationを有効にすると、DHCPにより配布されたIPを使用する機器は、内部的には/32のセグメントに分割されているため、別の機器と通信する場合には必ずCato Socket、つまりLAN FirewallまたはWAN Firewallを経由することになります。これによって、確実にセキュリティチェックを行うことが可能となるのです。 注意点として、この機能の対象とするIPレンジは、全てCatoによるDHCPの対象レンジとなっている必要があります。上の図であれば、サーバである「192.168.x.a」も含めたDHCPレンジを設定したうえで、サーバには「Static Host Reservation」によってCatoから固定IPの払い出しをする必要があります。 また、LAN FirewallやWAN Firewallによる制御が必ず入る以上、許可設定が適切に行わなれなければ必要な通信もブロックされる恐れがあります。本機能の利用を検討する場合、少しずつテストを行いながら導入範囲を広げることが推奨されます。 決して必須の機能ではありませんが、セキュリティを更に高めたい場合には注目の機能です!   DHCPの機能強化:モバイル編 Cato Clientを用いてモバイル接続によってCatoを利用する場合、CMA上で事前に定義されたIPレンジからIPアドレスが割り振られます。DHCPと銘打たれている機能ではありませんが、類似した性質を持つので本記事でまとめて紹介いたします。 Dynamic IP RangeとStatic IPレンジが複数定義可能に! Cato Client向けに配布されるIPレンジは原則として単一のCIDRとなりますが、 これとは別に「Dynamic IP Range」「Static IP Range」という設定が存在します。 Dynamic IP Rangeは特定のユーザグループに、Static IP Rangeは特定のSDPユーザに、 それぞれ通常のIP配布レンジとは別のIPレンジからIPアドレスを配布することが可能です。 IPアドレスでアクセスを制限するような機器・サービスが存在する環境において、「特定のユーザ(管理者)やグループ(IT部門など)にだけアクセス可能なIPアドレスを配布したい」といった需要に応えられる機能となっています。 Dynamic IP RangeおよびStatic IP Rangeの概要については、 下記の記事もご参照ください。 【Catoクラウド】最新版!モバイルユーザのIPアドレス割り当て方法 – TechHarmony 従来はDynamic IP Range、Static IP Rangeそれぞれ一つずつしか作成できませんでしたが、 アップデートにより複数のレンジを定義可能になりました。 これにより、「複数のグループ会社について、モバイル接続時に会社によって別々のIPレンジを割り振る」といった運用が可能となりました。大きな組織でIPアドレスによる管理を行いたい場合には、ぜひチェックしておきたいアップデートです。   参考:DHCPの設定箇所 2026年1月現在の、DHCP設定を行うためのCMA上の設定箇所を提示します。 Site向けDHCP設定 CMAにログインし、[Network] > [Site]から設定を行いたいSiteを選択します。 Site画面の[Site Configuration] > [Networks]に移動し、 対象のNativeレンジもしくはVLANをクリックします。 開いた設定ウィンドウの「DHCP Type」を「DHCP Range」とすることで、任意の範囲を指定可能です。複数のレンジを指定したい場合は、「Additional DHCP Ranges」から追加していきます。 設定完了後、画面右上の「Save」の実行を忘れないようにしましょう。 モバイル向けIP Allocation設定 モバイルユーザ向けのIPレンジは、[Access] > [IP Allocation Policy]から設定します。 IPレンジの定義は、[Settings]タブで実施します。 Dynamic IP RangeやStatic IP Rangeを定義した場合、それぞれ[Dynamic IP Allocation] [Static IP Allocation]にて適用条件を指定しなければ割り振られることはありません。 複数のルールを設定することが可能ですが、上からチェックして最初に合致したルールだけが適用されるので注意しましょう。   おわりに Catoの他の機能と同じく、DHCP機能も繰り返しアップデートが行われています。 本記事で紹介したアップデートにより、Catoネイティブの機能でのDHCP実装のハードルは大きく下がったように思います。DHCP機能を兼ねたルータをCato Socketに置き換えたい場合など、ぜひ参考にしてみてください。
アバター
こんにちは!SCSKの野口です。 前回のプロローグでは、AP基盤ドキュメントに「必要な情報へたどり着きにくい」という課題があり、RAGで“探すコスト”を下げられないか、という問題意識を共有しました(連載の背景は前回のプロローグ記事をご覧ください) 「その質問、ドキュメントに書いてある」問題を終わらせたい:RAG連載を始めます 社内ナレッジをRAGで活用し、膨大なドキュメントから必要情報を素早く見つける仕組みを目指します。本記事では連載開始の背景と、RAG基礎〜Bedrock実装・アプリ/エージェント構築までの構成を紹介します。 blog.usize-tech.com 2026.01.27 本連載は4シリーズ構成で、今回から始まるシリーズ1では、RAGを実装手順ではなく「構成要素と設計判断」として理解するための基礎を整理します(RAG/チャンキング/評価/ベクトルDB/ハイブリッド検索/課題)。 第1回の本記事では、 RAGの定義、必要性、基本フロー(Indexing / Retrieval / Augmentation / Generation) を俯瞰し、次回以降の議論の土台を作ります。 それでは早速、RAGとは何かから見ていきましょう。 RAGとは RAG(検索拡張生成:Retrieval-Augmented Generation)とは、LLMが回答を生成する直前に、信頼できる外部データソースから関連情報を 検索(Retrieval) し、その結果を コンテキストとして付与(Augmentation) したうえで 回答を生成(Generation) させるアーキテクチャです。これはモデルの重みを更新する「ファインチューニング」とは異なり、推論時に動的なコンテキストを提供する「検索」と「生成」のハイブリッドソリューションとなります。 図解してみると下記のようになります。 要点は、LLMの パラメータに内蔵された知識 だけに依存せず、 推論時に必要な情報を動的に取り込む 点にあります。AWSブログでも、RAGについて下記のように説明されています。 (原文)  It allows LLMs to reference authoritative knowledge bases or internal repositories before generating responses, producing output tailored to specific domains or contexts while providing relevance, accuracy, and efficiency.  (日本語訳) RAGにより、LLMは応答を生成する前に信頼できる知識ベースや内部リポジトリを参照できるようになり、関連性、精度、効率性を維持しながら、特定のドメインやコンテキストに合わせた出力を生成します。 引用元: https://aws.amazon.com/jp/blogs/machine-learning/evaluate-the-reliability-of-retrieval-augmented-generation-applications-using-amazon-bedrock/   なぜRAGが必要か? LLMは非常に汎用的ですが、業務適用で問題になりやすい制約があります。 いくつかの例を挙げてみましょう。 答えがないにも関わらず、虚偽の情報を提示すること ユーザーが最新の応答を期待しているにも関わらず、古い情報を提示する ユーザーが社内規約などの特定の情報に関する応答を期待しているにも関わらず、一般的な情報を提示する 上記の例はつまるところ、下記のような問題が発生しているということです。 ナレッジカットオフ: モデルが学習した時点以降の出来事や、更新された規定・仕様をそのまま反映できない ハルシネーション: 根拠がない内容でも、それらしく断定してしまう 社内固有情報の欠如: 社内情報・手順書・契約・設計資料など、非公開データを参照できない RAGはこれらの課題を解決するための1つのアプローチです。信頼できるドキュメント等をナレッジソースとして保存しておき、LLMへの問い合わせを行う前にこれらのナレッジソースから関連情報を取得します。ユーザーは信頼できるドキュメントから得られた情報に基づいて生成された回答を受け取ることができます。   RAGの基本フロー RAGは大きく4つの工程に分解することができます。 インデックス作成(Indexing) 文書を検索しやすい単位に分割し(チャンキング)、埋め込み(Embeddings)に変換して保存します。 文書の分割粒度(どの程度のチャンクサイズとするか?)、文書構造の扱い(階層構造に意味を持たせるか等)、メタデータ付与など、ここでの設計が後続の検索品質に大きく影響します。 チャンキング手法・Amazon Bedrock Knowledge Basesで利用できるチャンキング戦略などについては別記事で詳しくまとめる予定ですので、そちらを参照いただければ幸いです。 検索(Retrieval) ユーザーの質問(クエリ)も埋め込みに変換し、意味的に近いチャンクを取得します。 このときにどの程度のチャンクを取得するかも回答品質に影響を与えます。単純に多くのチャンクを取得すればよいというわけではありません。取得したチャンクが全てユーザーのクエリに強く関連するものであれば問題ありませんが、そこまで関連性がないチャンクを取得してしまい、ユーザーが求めていた回答が得られない可能性もあります。 そのため、何件のチャンクを取得するかも重要な設計項目となります。 なお、「あえてRAGからの取得時は多くのチャンクを取得しておき、リランキングによって絞り込む」といった設計も可能となります。 こちらの詳細は下記ブログに書かれているので、一度目を通してみてください。 リランキング モデルによる RAG の日本語検索精度の向上 埋め込みモデルの Llama-3.2-NV-EmbedQA-1B-v2 およびリランキング モデルの Llama-3.2-NV-RerankQA-1B-v2 を利用して、日本語検索精度の高い RAG の構築方法を分かり易く解説します。 developer.nvidia.com コンテキスト構築(Augmentation) 取得したチャンクから、重複除去・整形・並べ替えなどを行い、LLMに渡すコンテキストを組み立てます。 生成(Generation) コンテキストと質問(クエリ)に基づき、LLMが回答を生成します。 重要なのは、 回答がコンテキストに接地(Grounding)していること です。 接地(Grounding:グラウンディング) とは、 モデルからの回答がソースに基づいて事実上正確であるか ということです。 詳しくはAmazon Bedrockの下記ユーザーガイドでご確認ください。 コンテキストグラウンディングチェックを使用して、レスポンスのハルシネーションをフィルタリングする - Amazon Bedrock Amazon Bedrock のガードレールは、リファレンスソースとユーザークエリが提供されたとき、モデルレスポンスのハルシネーションを検出してフィルタリングするためのコンテキストグラウンディングチェックに対応しています。サポートされている... docs.aws.amazon.com   RAGと似た概念とその違い RAGと似た概念として、「ファインチューニング」があります。 ファインチューニング :モデルの重み(パラメータ)を更新し、出力スタイル・形式・判断の癖を学習させる RAG :外部知識(ナレッジソース)を検索し、推論時に動的に与えて正確性・最新性・組織固有性を補う 上記からも分かる通り、ファインチューニングには学習させるための計算コストがかかりますが、RAGは外部知識をつなげるだけなので、ファインチューニングよりもコストが低くなります。 IBMの記事では、RAGとファインチューニングの比較を料理人に例えて比較しています。 (RAG) RAGを概念化するために、AIモデルをアマチュアの家庭料理人と想像してみてください。彼らは料理の基礎は知っていますが、特定の料理の訓練を受けたシェフの専門知識(組織独自のデータベース)が欠けています。RAGは、家庭料理人にその料理のレシピ本を提供するようなものです。料理に関する一般的な知識と料理本のレシピを組み合わせることで、家庭料理人は自分の好きな料理に特化した料理を簡単に作ることができます。 (ファインチューニング) もう一度、生成AIモデルを家庭料理人に例えると、ファイン・チューニングは特定の料理を作るためのコースとなります。コースを受講する前に、家庭料理人は料理の基礎について大まかな理解をしておく必要があります。しかし、料理の訓練を受けて分野特有の知識を習得すれば、その種類の料理をもっと上手に作れるようになるでしょう。 引用元: https://www.ibm.com/jp-ja/think/topics/rag-vs-fine-tuning   RAGとファインチューニングの比較表です。 比較項目 RAG ファインチューニング 主な目的 最新知識・情報の補強 回答スタイル・形式の習得 コスト 低い(既存モデルをそのまま活用) 極めて高い(再学習に莫大な計算資源が必要) 情報の更新頻度 リアルタイム(外部データを差し替えるだけ) 遅い(再学習に数日〜数週間かかる) 根拠(出典)の提示 明確に提示可能(引用へのリンクをつけるなど) 困難(モデルの記憶に依存するため) 専門性 特定のドキュメントに強い 専門的な口調や特定形式の出力に強い   RAGで重要な設計論点(どこで品質が決まるか) RAGで難しいのは、LLMの性能ではなく、取り込み・分割・検索・コンテキスト設計など“前段”で品質が大きく変わる点です。特に次の観点はRAGにおいて非常に重要です。 データ取り込み(Parsing / 整形) 表やPDF構造が崩れると、正しい情報が検索に乗りません チャンキング(チャンク化) チャンキングが大きすぎても小さすぎてもだめです。ユースケースに応じて適切なチャンキング戦略を考える必要があります 検索(Retrieval) top-kの取り方(いくつのチャンクを検索するか)、ハイブリッド検索、リランキングで適切な情報を「拾える / 拾えない」が変わります コンテキスト構築 (Augmentation) 重複除去・並び順・引用の付け方で、LLMが参照できる根拠が変わります 生成制御(Generation) 接地(Grounding)と棄却(わからないときは答えない)を設計しないと、もっともらしい誤答(ハルシネーション)が残ります 評価(Evaluation) 改善できているかを定量的に評価しなければ、主観的な評価のみとなってしまいます 次回記事では、上記の「チャンキング(チャンク化)」を取り上げ、チャンク化戦略と選択方法を整理します。   まとめ 本記事では、RAG(検索拡張生成)を「外部データソースを検索し、その結果をコンテキストとして付与して回答を生成する」仕組みとして整理しました。LLM単体では難しい、最新性・正確性・社内固有情報の参照を補ううえで有効なアプローチです。 また、RAGの品質はLLMの性能だけではなく、データ取り込み・チャンキング・検索・コンテキスト構築・生成制御・評価といった設計要素の組み合わせで決まります。 次回は、この中でも影響が大きい 「チャンキング(チャンク化)」 を取り上げ、チャンク化戦略と選択方法を整理します。 次回もぜひご覧ください。
アバター
こんにちは!SCSKの野口です。 早速ですが皆さんに質問です。 「業務でRAGを活用していますか?」 本記事は、これからTechHarmoneyでRAGに関する記事をシリーズとして執筆していくにあたり、 なぜ書こうと思ったのか 、 そして 今後どのようなテーマを扱う予定か を最初に整理する”プロローグ”です。 背景:ドキュメントはあるのに、探すのが難しい 私は普段、アプリケーション基盤(AP基盤)チームに所属しており、業務チームから基盤部品に関する質問を受けることがあります。 AP基盤部品は部品の提供だけでなく、方式書や開発ガイドも公開しており、業務チーム側でも参照できる状態です。 それでも、開発ガイドに書いてある内容であるにも関わらず、次のような質問を受けることが少なくありません。 「この部品の使い方は?」 「この部品のデフォルト設定値は?」 「急に動かなくなった」 「質問の前にドキュメントを確認してほしい」という気持ちがある一方で、 1つあたり何十~何百ページの資料が複数ある中から、必要箇所をピンポイントで探すのは大変 という事情も理解できます。私自身、配属後の研修中は同じように苦労した記憶があります。 つまり問題は、「ドキュメントがない」ではなく、” 必要なときに、必要な情報にたどり着きにくい ”にあります。   きっかけ:AP基盤ドキュメントをRAGで提供できないか この課題に対して、AP基盤チーム内で下記の議論を行いました。 “生成AI”を活用し、 質問から関連箇所を検索して提示 できれば、問い合わせの往復が減る 回答に根拠(引用元資料の章・節)を添えられれば、 再現性のあるナレッジ共有 になる 業務チームの自己解決率が上がれば、AP基盤チームの支援が”説明”から”改善”に寄る そこで、 AP基盤部品のドキュメントをRAGで提供しよう! となったわけです。 本連載は、その取組を進めるうえでの個人的な学習も兼ねて、RAGの理解と実装・運用の勘所を整理していくものです。   本連載で目指すこと 本連載を通じて狙っているのは、次の3点です。 社内ドキュメントの”検索体験”を改善するための考え方を整理する RAGの設計要素(チャンキング、評価、検索方式など)を分解し、 どこで精度が落ちるか / 何を改善すべきか の共通認識を作る 最終的に、Amazon Bedrock等を用いた構成で、 再利用可能な形の RAGアプリ / RAGエージェント  へ展開する   今後のシリーズ 記事は大きく4シリーズを予定しています。加えて、シリーズとは別枠でTips記事も各予定です。 シリーズ1:RAGに関する基本的知識 まずは、RAGの構成要素と設計判断として理解するための土台を作ります。 RAGとは チャンキング(チャンク化)とは RAGの評価方法 ベクトルデータベースについて ハイブリッド検索について RAGの課題 (シリーズ1:RAGの基本情報 / 第1回)RAGとは:全体像、なぜ必要か、基本フローと設計の勘所 RAG(検索拡張生成)の定義、なぜ必要か、基本フロー(Indexing/検索/補強/生成)を整理します。 blog.usize-tech.com 2026.01.27 シリーズ2:Tips(Amazon Knowledge Bases中心を予定) 「公式機能を理解して試す」「構築の手間を減らす」等を主眼に置き、検証記事をまとめる予定です。 Amazon Knowledge Basesで利用できるチャンク化戦略をすべて試してみる Amazon Knowledge Basesのコンソールで簡単にKnowledge Base作成(S3 Vectors) MCPサーバー経由でKB呼び出し ※上記は現時点(2026/1/24)での案です。追加検証は随時こちらにも反映していきます。 シリーズ3:RAGアプリケーション構築 + AWSデプロイ 構築対象を明確にし、実用を意識したアプリケーションを組み上げます。 構築していく予定のRAGアプリケーションについての説明 アプリケーション全体アーキテクチャ図についての説明 RAGアプリ構築(FastAPI編) RAGアプリ構築(LibreChat編) インフラ構築 シリーズ4:RAGエージェント構築 Strands Agents + Amazon Bedrock AgentCore + Amazon Bedrock Knowledge Basesを利用したRAGエージェント構築を予定しています。 こちらの詳細については現時点でまだ詰め切れていないので、決まり次第更新します。   シリーズ記事とは別に:Tipsも随時まとめます シリーズは体系立てて理解することを目的としていますが、実際の構築では「細かい詰まりどころ」が出てくると思います。 そのため、シリーズとは別に、RAGやAWS上でRAG環境を構築する際のTips(設定の落とし穴、検証観点、運用メモなど)も随時まとめる予定です。   まとめ 本記事では、AP基盤ドキュメントを扱う中で感じた「必要な情報にたどり着きにくい」という課題を出発点に、RAGを活用して“探すコスト”を下げられないか、という問題意識と、連載として整理していく方針を共有しました。 この連載では、まずシリーズ1でRAGの基本要素(チャンキング、評価、ベクトルDB、検索方式、課題)を分解し、 どこが品質を決めるのか を押さえます。その上でシリーズ2〜4で、Amazon Bedrock Knowledge Basesを中心に、検証・構築・デプロイ・エージェント化へと段階的に進めていく予定です。 次回からは、シリーズ1の第1回として、 「RAGとは」 をテーマに、RAGの定義、なぜ必要か、基本フローを整理していきます。続きもぜひご覧ください。 (シリーズ1:RAGの基本情報 / 第1回)RAGとは:全体像、なぜ必要か、基本フローと設計の勘所 RAG(検索拡張生成)の定義、なぜ必要か、基本フロー(Indexing/検索/補強/生成)を整理します。 blog.usize-tech.com 2026.01.27
アバター
LifeKeeperの『困った』を『できた!』に変える!サポート事例から学ぶトラブルシューティング&再発防止策 こんにちは、SCSKの前田です。 いつも TechHarmony をご覧いただきありがとうございます。 システムを長く安定して運用する上で、避けて通れないのが「OSのアップデート」や「セキュリティパッチの適用」です。「脆弱性が見つかったので、カーネルの更新をお願いします」といったタスクは、インフラエンジニアにとって日常茶飯事かもしれません。 しかし、HAクラスターシステム、特にデータをリアルタイムで保護するDataKeeper環境において、この「いつものアップデート」が思わぬトラブルの引き金になることがあります。「OSのメジャーバージョンは変わらないから大丈夫だろう」と高を括っていたら、 メンテナンス当日にリソースが起動せず 、顔面蒼白に…なんて事態は絶対に避けたいですよね。 本連載企画「LifeKeeper の『困った』を『できた!』に変える!サポート事例から学ぶトラブルシューティング&再発防止策」では、実際にサポートセンターに寄せられた「生の事例」を紐解き、安定運用のための知恵を共有していきます。 今回からは、多くの運用担当者が直面する「OSやLifeKeeper本体のバージョンアップ」に伴うトラブルにフォーカスを当てていきます。 その第一弾となる今回は、最も見落とされがちな「OSカーネルの更新」について。「OSのバージョン数値は変わっていないのに動かない!?」というミステリーの真相と、確実に成功させるための回避策について解説します。 はじめに:そのアップデート、「OSバージョン」だけ見ていませんか? 今回の記事のテーマは、ズバリ「OSのカーネルアップデート」です。 一般的に、OSのメジャーバージョンアップ(例:RHEL 8から9への移行)を行う際は、アプリケーションへの影響調査や入念な検証計画が立てられます。一方で、マイナーバージョン内でのカーネル更新や、パッケージのセキュリティパッチ適用( dnf update )は、比較的軽い気持ちで、あるいは自動的に実施されているケースも少なくありません。 しかし、LifeKeeper、とりわけデータをリアルタイムで複製する「DataKeeper」をご利用の環境において、この「軽微なアップデート」という認識は禁物です。なぜなら、DataKeeperは単なるアプリケーションではなく、OSのカーネルモジュールとして動作しており、 「OSのリリース番号(8.1など)」よりも「カーネルのバージョン(4.18.0-xxxなど)」に対して 非常に敏感に反応する からです。 本記事では、実際に発生した「OSのバージョン表記は変わっていないのに、LifeKeeperが起動しなくなった」という事例を通して、以下のポイントを解説します。 カーネル更新がLifeKeeperに与える影響のメカニズム サポートマトリクスの「注釈」に隠された重要な条件 トラブルを未然に防ぐための正しい確認プロセス 「手順通りやったはずなのに動かない…」と頭を抱える前に、ぜひ押さえておきたい勘所を整理しました。 その他の連載企画は以下のリンクからどうぞ! 【リソース起動・フェイルオーバー失敗の深層 #1】EC2リソースが起動しない!クラウド連携の盲点とデバッグ術 – TechHarmony 【リソース起動・フェイルオーバー失敗の深層 #2】ファイルシステムの思わぬ落とし穴:エラーコードから原因を読み解く – TechHarmony 【リソース起動・フェイルオーバー失敗の深層 #3】設定ミス・通信障害・バージョン違いの深層と再発防止策 – TechHarmony 実録!「困った」事例:事前確認は「OK」だったのに… 今回は、単なるエラー事例ではありません。運用担当者が「事前にベンダーへ確認し、お墨付きをもらっていた」にも関わらず発生してしまった、少し根が深いトラブルの事例です。 事象の概要:慎重に進めたはずのアップデート ある運用中のシステム(RHEL 8.1 / LifeKeeper v9.5.1)にて、セキュリティ要件を満たすため、OSの「カーネルとファームウェアのみ」をRHEL 8.3相当へアップデートすることになりました。 運用担当者は非常に慎重でした。作業前にベンダー(サポート)に対し、「RHEL 8.3へアップデートするが、LifeKeeperの動作に問題はないか?」と問い合わせを行い、「LifeKeeperの更新インストールを行えば問題ない」という回答を得ていました。 「これで準備は万端だ」 そう確信して臨んだ作業当日。カーネル更新とLifeKeeperの更新インストールを完了させ、いざサービスを起動しようとすると… 「DataReplication(データレプリケーション)リソースの開始に失敗しました」 発生時の状況:深まる謎と焦り ログを確認すると、データ同期に必要なミラーリングデバイスの作成部分でエラーが出ていました。 すぐにサポートへ問い合わせましたが、事態はすぐには収束しませんでした。 サポート側:  「RHEL 8.3へのアップデートであれば、通常はこの手順で動くはずです」 現場:  「手順通りやりました。でも動きません。OSのリリースファイル( /etc/redhat-release )は 8.1 のままですが、これが悪いのでしょうか?」 サポート側:  「8.1…? 8.3に上げたのではなかったのですか?」 実はここに、 「ボタンの掛け違い」 が潜んでいました。 原因究明のプロセス:言葉の定義の違い 何度かのやり取りの末、ようやく互いの認識のズレと、技術的な根本原因が判明しました。 「OSアップデート」の解釈違い 運用担当者 は、「カーネルとファームウェアを8.3相当にする」ことを指して「RHEL 8.3へのアップデート」と伝えていました。 サポート担当者 は、それを「OS全体(マイナーバージョン)をRHEL 8.3へ移行する」と受け取り、標準的な8.3用の手順を案内していました。 インストーラーの誤認 現場のOS環境は「見た目は8.1(リリースファイル等の表記)、中身は8.3(カーネル)」という特殊な状態でした。 LifeKeeperのインストーラーは「見た目(8.1)」を信じて、RHEL 8.1用の標準モジュールをインストールしていました。しかし、実際に動いているカーネルは8.3相当だったため、ドライバが噛み合わず起動に失敗していたのです。 判明した根本原因 最終的な技術的原因は、LifeKeeperの サポートマトリクスの「注釈(Notes)」 にありました。 RHEL 8.3相当のカーネルを使用する場合、標準のインストーラーに含まれるモジュールではなく、 「特定の修正パッチ(HADRモジュール)」を手動で適用する必要があった のです。 「OSは8.1だから」という安心感と、「事前に8.3で確認したから」という確信の狭間で、 「現在のカーネルバージョンに合致したパッチが必要」 という極めてピンポイントな要件が見落とされてしまった事例でした。 「再発させない!」ための対応策と学び 今回の事例は、最終的にサポートから提供された「当該カーネル専用の修正パッチ(HADRモジュール)」を適用し、不要な標準パッケージを削除することで解決に至りました。 しかし、ここで得られた学びは「パッチを当てれば直る」という技術的なことだけではありません。 今後、同様の「迷宮入り」を防ぐために、私たちが実践すべき防止策を整理しました。 1. サポートへの問い合わせは「カーネルバージョン」で語る 今回の最大の教訓は、 「OSのバージョン名(RHEL 8.3など)」だけで会話をしない ということです。 特にDataKeeperのようなカーネル依存の製品に関する問い合わせでは、以下の情報をセットで伝えることが、正確な回答を引き出す鍵となります。 現在のOS/カーネル:   uname -r  の結果(例: 4.18.0-147…) 更新予定のカーネル:  アップデート後に適用される具体的なバージョン数値(例: 4.18.0-240…) アップデートの手法:  「OS全体のマイナーバージョンアップ」なのか、「カーネルのみの個別更新」なのか 「RHEL 8.3相当にします」と伝えるよりも、「カーネルを 4.18.0-240 に上げます」と伝えていれば、サポート担当者も「そのカーネルバージョンなら、この注釈のパッチが必要です」と即座に案内できたかもしれません。 2. サポートマトリクスは「注釈」こそが本体 対応OS一覧表(サポートマトリクス)を見る際、どうしても「RHEL 8.3 … ○」という記号に目が行きがちです。しかし、トラブルの種は表の外側に書かれた小さな文字、 「注釈(Notes)」 や 「既知の問題(Known Issues)」 に潜んでいます。 「特定の手順に従う必要があります」 「追加のモジュールが必要です」 こうした記述を見つけたら、それは「ただの推奨事項」ではなく「必須要件」であると捉えてください。 3. 【保存版】アップデート前の確認チェックリスト 最後に、作業前の確認漏れを防ぐためのチェックリストをまとめました。 ■カーネルアップデート前の確認チェックリスト [  ] アップデート後の「カーネルバージョン」を特定しましたか? dnf check-update kernel 等で、適用されるバージョン数値(例: 4.18.0-xxx)を確認しましょう。 [  ] サポートマトリクスの「注釈」まで確認しましたか? 対象のOSバージョンに「※」や「Note」が付いていないか、欄外までスクロールして確認しましょう。 [  ] 「OSの更新方法」をベンダー/サポートへ正確に伝えましたか? 「カーネルのみ更新」「OSバージョンは維持」といった特殊な要件がある場合は、必ず背景として伝えましょう。 [  ] 作業前のバックアップ(lkbackup)は取得しましたか? 万が一の切り戻し手順も確立しておきましょう。 まとめ:DataKeeperは「カーネルの一部」と心得る 今回の事例を通じて、私たちが得た最大の教訓は、 「OSのアップデート」という言葉の裏にあるリスクの大きさ でした。 セキュリティ対策や機能要件でOSの更新は避けられませんが、DataKeeperを利用している環境において、それは単なるアプリの再起動では済みません。「OSの見た目(リリースバージョン)」が変わらなくても、「中身(カーネル)」が変われば、DataKeeperにとっては全く別の環境になり得るのです。 サポートマトリクスは、ただの「対応表」ではありません。安全に目的地へたどり着くための「地図」であり、そこに書かれた小さな「注釈」は、崖崩れや落とし穴を避けるための重要な道標です。 そして何より、 「正確な情報をサポートへ伝えること」 。これが、トラブルの迷宮から最短で脱出するための命綱となります。「カーネルバージョン」という共通言語を使って、ベンダーと認識を合わせることから始めてみてください。 日々の運用の中で、ふと「これ、バージョン上げても大丈夫かな?」と思った時、この記事のチェックリストが皆様の助けになれば幸いです。 次回予告 さて、今回の「OS周りのアップデート」に続き、次回はLifeKeeperそのもののバージョンアップに焦点を当てます。 「LifeKeeperを最新版に上げたいけれど、手順書通りにやってエラーが出たらどうしよう…」 「かなり古いバージョンからのジャンプアップ、本当に大丈夫?」 そんな不安をお持ちの方、必見です。次回は、「LifeKeeperバージョンアップ失敗事例と成功へのロードマップ」と題し、実際のバージョンアップ作業で発生したトラブル事例や、意外なハマりポイント、そして安全確実に移行するためのステップを解説します。 更新インストール時に出る「謎のエラーメッセージ」の正体とは? バージョンをまたぐ更新で注意すべき「廃止機能」や「仕様変更」 転ばぬ先の杖として役立つ情報をお届けしますので、ぜひお楽しみに! 詳しい内容をお知りになりたいかたは、以下のバナーからSCSK LifeKeeper公式サイトまで
アバター
こんにちは。SCSKの北川です。 今回はServiceNowでバージョンの異なるナレッジ記事を比較する方法をご紹介します。 前回の記事はこちら 【ServiceNow】ナレッジの活用② ナレッジフロー – TechHarmony 本記事は執筆時点(2026年1月)の情報です。最新の情報は製品ドキュメントを参考にしてください。 手順は以下の通りです。 ①ワークスペースからナレッジ記事を選択します。 ②画面右上の[Edit]を押下します。 ③[Related records]内の[Article Versions]を選択します。 ④比較したいバージョンをチェック後、画面右上の[Compare]を押下します。    ⑤変更箇所が色付けされて表示されます。 まとめ 今回はバージョンの異なるナレッジ記事を比較する方法をご紹介しました。 ワークスペースから操作することによって記事のどこに変更が加えられたのかが分かりやすく表示されます。 ぜひ活用してみてください!
アバター
こんにちは、SCSK齋藤です。 2025年の11月に AWS CloudFormation に関するアップデートが来ました。その内容について検証してみたいと思います。   ドリフト対応変更セット アップデートは、ドリフト対応変更セットというもので、これはテンプレートの内容と実際のインフラの状況を比較した上で、変更セットを立てるという内容です。 AWS CloudFormation のドリフト対応変更セットで設定のドリフトを安全に処理 - AWS AWS の新機能についてさらに詳しく知るには、 AWS CloudFormation のドリフト対応変更セットで設定のドリフトを安全に処理 aws.amazon.com 図解すると下記のようなイメージです。   これまでの変更セットは、現在のテンプレートと、新しいテンプレートを比較して差分を抽出します。 しかし、ドリフト対応変更セットは、それに加えて実際のインフラの状況も見た上で変更差分を抽出します。   試してみた 今回はLambda関数を定義したCloudFormationを使って、ドリフト対応変更セットとはどのようなものなのかみていきたいと思います。 ①Python3.11のランタイムのLambdaをデプロイ 下記テンプレートをまずデプロイしてみます。 AWSTemplateFormatVersion: '2010-09-09' Description: Simple CloudFormation Template to create one AWS Lambda function Resources: testlambda: Type: AWS::Lambda::Function Properties: FunctionName: "test-lambda" Handler: index.lambda_handler Runtime: python3.13 Architectures: - arm64 Role: !GetAttLambdaRole.Arn Code: ZipFile: | def lambda_handler(event, context): return { 'statusCode': 200, 'body': 'Hello from Lambda!' } LambdaRole: Type: "AWS::IAM::Role" Properties: RoleName: "my-function-role" AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Service: "lambda.amazonaws.com" Action: "sts:AssumeRole" Policies: - PolicyName: "MyPolicy" PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - logs:CreateLogGroup Resource: arn:aws:logs:ap-northeast-1:425086073817:* - Effect: Allow Action: - logs:CreateLogStream - logs:PutLogEvents Resource: - arn:aws:logs:ap-northeast-1:425086073817:log-group:/aws/lambda/test-lambda:* 上記をデプロイすることにより、Lambdaのランタイムは、3.11となります。   ②マネジメントコンソールで、Python3.12にランタイムを変更します。 CloudFormationを用いずに、ランタイムを変更します。 この状態では、CloudFormation上はまだPython3.11のままです。 ③CloudFormationを用いて、Python3.13にアップデートします。 ここからが本題です。 本ブログの①に記載したCloudFormationテンプレートをPython3.13に書き換えた上で実行します。   まず普通に変更セットを作成しようとします。 最初に、変更セットのタイプを指定しますが、そこでドリフト認識変更セットを選択します。 そして、新しいテンプレートをアップロードします。 この後の流れは、いつもの変更セット作成方法と同じため、変更セットの作成まで実施します。     変更セットを作成すると、下記のようなステータスとなり、「ドリフト済み」と表示されます。   JSONでも見てみますと、下記のようになります。(必要な部分のみピックアップしてます。) beforeValueは、マネジメントコンソール上で変更した実際のインフラのランタイム設定ですね。afterValueは、新しいテンプレートのランタイムです。 その後にdriftと記載があり、previousValueは現在のテンプレート上のランタイムであるPython3.11です。 actualValueは、マネジメントコンソール上で変更した実際のインフラのランタイム設定であることがわかります。 この状態で変更セットを実行したら問題なくPython3.13にアップデートできました。   まとめ 今回はインフラの実際の状態を変更セットとして差分確認する機能を、簡単にですが検証しました。 JSON形式で見てみると、現在のテンプレートと、実際のインフラ、そして新しいテンプレートの内容が3つ分しっかりと比較できていることがわかりました。 この機能により、過去にマネジメントコンソール上で変更してしまった設定も、変更セット時にしっかりと気づくことができるようになったので、想定外のデプロイが起こってしまうといったことが少しでも減らせると考えております。
アバター
こんにちはSCSK齋藤です。 今回は Amazon API Gateway の認証方法として、IAMを用いる方法を解説したいと思います。   概要 アーキテクチャ図は下に示す通りです。今回はAPI Gatewayの裏にLambdaを設けて、API呼び出しでLambdaが動くようにします。 なお、IAM認証の処理の流れは下記の通りとなります。 ①APIの呼び出し元がAPIの呼び出しを行う。 ②APIの呼び出し元に付与されているIAM Roleに対象API Gatewayを呼び出す権限があれば、APIを呼び出すことができる。     各リソースの作成 アーキテクチャ図を実現する、各リソースの作成をマネジメントコンソールベースで説明します。 Lambda 今回のAPI Gatewayの裏側にあるLambdaは、特に凝ったものにする必要がないので、デフォルトのソースコードそのままとします。 単純にステータスコード200と「Hello from Lambda!」と出力されるだけのシンプルなプログラムです。   API Gateway 最初は通常通りの作成を行います。   メソッドの作成も行います。今回は呼び出しができれば良いのでGetにし、先ほど作成したLambda関数を設定します。 作成後、認証設定を付与します。 まず、メソッドリクエストの編集ボタンを押下します。   認可の部分で、AWS IAMをクリックして、保存します。 APIの画面に戻るので、画面右上の「APIのデプロイ」をクリックします。 下記のような設定とし、デプロイをクリックします。   これにてAPI側の構築は完了です。 続いて、APIを呼び出す側のリソースを作成していきます。 今回は、呼び出し元はLambda関数を使いたいと思います。また、それに付与するIAM Roleも作成したいと思います。   Lambda(APIを呼び出す側) 今回は下記名前のLambdaを作成しました。Lambda関数の作成方法は、前述したものを同じなので省略します。 ここではソースコードを紹介します。 import boto3 import json import os from botocore.awsrequest import AWSRequest from botocore.auth import SigV4Auth from botocore.endpoint import URLLib3Session from botocore.credentials import Credentials import requests def lambda_handler(event, context): api_url = "https://XXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/dev" #①Lambdaに付与されたIAMロールをもとに、クレデンシャル情報を取得。 lambda_credentials = boto3.Session().get_credentials() credentials = Credentials(lambda_credentials.access_key, lambda_credentials.secret_key, token=lambda_credentials.token) #②安全にアクセスするために、AWS Signature Version 4に基づいたヘッダー情報を生成する。 request = AWSRequest(method="GET", url=api_url) SigV4Auth(credentials, "execute-api", "ap-northeast-1").add_auth(request) headers = { "Authorization": request.headers["Authorization"], "X-Amz-Date":request.context["timestamp"], "X-Amz-Security-Token": lambda_credentials.token } #③ヘッダー情報を付加してAPIへアクセスする。 api_response = requests.get(api_url, headers=headers) api_response_json=api_response.json() print(f'api_response is {api_response_json}')   ソースコードの中にコメントアウトしておりますが、流れを解説すると3点に分けられます。 ①Lambdaに付与されたIAMロールをもとに、クレデンシャル情報を取得。 boto3のライブラリを用いて、Lambdaのクレデンシャル情報を取得する処理を行います。   ②安全にアクセスするために、AWS Signature Version 4に基づいたヘッダー情報を生成する。 AWSへのアクセスへは安全である必要があります。 今回はSigV4Authというライブラリを用いて、先ほど取得したクレデンシャルをベースにヘッダー情報を生成します。   ③ヘッダー情報を付加してAPIへアクセスする。 ヘッダー情報を付加し、アクセスしたいAPIのURLへアクセスを行います。   IAM Role 呼び出し側LambdaのIAM Roleを編集し、APIGatewayを呼び出すための権限を付与します。 Lambdaの「設定」→「アクセス権限」からロール名をクリックします。 遷移したら、IAMRoleの画面が出るので、「アクセス許可を追加」→「インラインポリシーを作成」をクリックします。 ポリシーエディタで下記の条件で作成しました。 JSON形式にすると下記の通りです。 { "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "execute-api:Invoke", "Resource": "*" } ] }   挙動確認 これまでで準備は完了となります。 では、実際にLambdaのテストとして動作確認をしてみますと、ログ出力のところでAPIの裏側のLambdaとして実装したステータスコード200と「Hello from Lambda!」が出力されていることがわかります。 まとめ 今回はAPI GatewayのIAM認証を呼び出す方法について記載いたしました。 なお、補足ですが今回呼び出し側のLambdaにて、ライブラリにSigV4Authというものを利用しました。 これとは別にAWS4Authというライブラリもあり、こちらを使ってもアクセスは可能となります。 しかし、AWS4Authは2024年7月22日を最後にメンテナンスがされておらず、Python3.13以降には対応しておりません。 requests-aws4auth AWS4 authentication for Requests pypi.org   SigV4Authは、botocoreに内包されているため、Python3.13以降にも対応しております。そのため、今後のことを考えるとSigV4Authを利用することを推奨いたします。 botocore Low-level, data-driven core of boto 3. pypi.org
アバター
こんにちはSCSK齋藤です。 今回は Amazon API Gateway の認証方法として、Lambda カスタムオーソライザーを用いる方法を解説したいと思います。   概要 アーキテクチャ図は下に示す通りです。今回はAPI Gatewayの裏にLambdaを設けて、API呼び出しでLambdaが動くようにします。 なお、Lambdaカスタムオーソライザー認証の処理の流れは下記の通りとなります。 ①APIの呼び出し元がAPIの呼び出しを行う。 ②APIの呼び出し元に付与されているヘッダー情報を、Lambdaカスタムオーソライザーが認証する。 ③認証が通れば、APIを呼び出すことができる。   各リソースの作成 アーキテクチャ図を実現する、各リソースの作成をマネジメントコンソールベースで説明します。 Lambda(カスタムオーソライザー) 認証用のLambdaを作成いたします。 まず最初は通常通りLambdaを作成します。 さて、次はソースコードが重要となります。 カスタムオーソライザーのソースコードは、利用者にて自由に定義ができます。 今回は下記のようなソースコードとしました。 import json def lambda_handler(event, context): json_event = json.dumps(event) print(f"event: {json_event}") # リクエストからトークンを取得 token = event['authorizationToken'] # 判定結果の変数。リクエストされたトークンが一致していたら許可とする。初期値は拒否とする。 effect = 'Deny' # tokenを検証。指定の値であれば許可する。戻り値にはAPIを実行するIAMポリシーをJSON形式で渡してあげる if token == 'AccessToken': effect = 'Allow' return { 'principalId': '*', 'policyDocument': { 'Version': '2012-10-17', 'Statement': [ { 'Action': 'execute-api:Invoke', 'Effect': effect, 'Resource': event['methodArn'] } ] } }   ポイントとしては、アクセス許可を付与する際はIAMポリシーを返却することです。 このIAMポリシーにAPIGatewayの実行許可を付与することで、APIを実行することができます。   Lambda(APIに呼び出される側) 今回のAPIGatewayの裏側にあるLambdaは、特に凝ったものにする必要がないので、デフォルトのソースコードそのままとします。 単純にステータスコード200と「Hello from Lambda!」と出力されるだけのシンプルなプログラムです。   API Gateway 最初は通常通りの作成を行います。 メソッドの作成も行います。今回は呼び出しができれば良いのでGetにし、先ほど作成したAPIに呼び出される側のLambda関数を設定します。 作成後、認証設定を付与します。 まず最初に、API Gatewayの画面の左ベインからオーソライザーを選択し、オーソライザーを作成をクリックします。 オーソライザーを設定しますが、今回はLambdaを選択し、オーソライザー用のLambdaを選択します。 今回は、トークンをイベントペイロードとしますので、トークンのソースの部分を一般的な「Authorization」として、作成します。 その後、APIにオーソライザーを紐付けます。 APIのリソースの画面に戻り、メソッドリクエストの編集ボタンを押下します。   認可の部分で、先ほど作成したオーソライザーを選択します。 メソッドリクエストの認可にオーソライザーが付与されているのを確認したら、画面右上の「APIのデプロイ」をクリックします。   下記のような設定とし、デプロイをクリックします。   これにてAPI側の構築は完了です。 続いて、APIを呼び出す側のリソースを作成していきます。 今回は、呼び出し元はLambda関数を使いたいと思います。 Lambda(APIを呼び出す側) 今回は下記名前のLambdaを作成しました。Lambda関数の作成方法は、前述したものと同じなので省略します。 ここではソースコードを紹介します。 import requests def lambda_handler(event, context): api_url = "https://XXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/dev" #①ヘッダー情報を生成する。 headers = { "Authorization": "AccessToken", } #②ヘッダー情報を付加してAPIへアクセスする。 api_response = requests.get(api_url, headers=headers) api_response_json=api_response.json() print(f'api_response is {api_response_json}') ソースコードの中にコメントアウトしておりますが、流れを解説すると2点に分けられます。 ①ヘッダー情報を生成する。 今回はトークンのソースをAuthorizationとしましたので、Authorizationヘッダーを作成する必要があります。 Authorizationヘッダーの中身については、Lambdaのカスタムオーソライザーのソースコードで定義した「AccessToken」と同じ値を入れることで認証されるのでその値を設定します。 ②ヘッダー情報を付加してAPIへアクセスする。 ヘッダー情報を付加し、アクセスしたいAPIのURLへアクセスを行います。   挙動確認 これまでで準備は完了となります。 では、実際にLambdaのテストとして動作確認をしてみますと、ログ出力のところでAPIの裏側のLambdaとして実装したステータスコード200と「Hello from Lambda!」が出力されていることがわかります。   まとめ 今回は API Gateway のLambdaカスタムオーソライザー認証を呼び出す方法について記載いたしました。 Lambdaによって認証されるので、かなり自由度は高いと思います。 認証の部分は今回「AccessToken」という単語でハードコードしましたが、裏側にデータベースなどを実装し、リクエストされた値をもとにデータベースを照合して認証するなどするのが良いと考えております。 そちらについてはまた次回以降ブログにできたら良いと考えております。
アバター
こんにちは、SCSK齋藤です。 前回に引き続き、Amazon API Gateway の認証方式である、Amazon Cognito を用いたM2M認証の方法について解説いたします。 まだ未読の方は下記の前半のブログを一読してください。   今回は、プログラム側でAPIを呼び出す後半のブログとなります。   おさらい 前回のブログの概要として記載したアーキテクチャ図と処理の流れを再掲します。すでに理解している人は読み飛ばしてください。   M2M認証の処理の流れは下記の通りとなります。 ①APIの呼び出し元がCognitoにアクセストークンを発行しに行く。 ②受け取ったアクセストークンを、ヘッダーに付与してAPIGatewayへアクセスしに行く。 ③リクエストを受けたAPIGatewayは、リクエストに付加されたアクセストークンを検証するため、Cognitoに問い合わせをする。 ④アクセストークン検証の結果、問題なければ後続の処理を進める。(Lambdaの呼び出し。)   API呼び出し方法について 今回は、APIを呼び出すためのLambdaを作成し、そのLambda上でM2Mの認証とAPIの呼び出しを行いたいと思います。   ソースコードは下記のようなイメージです。 import requests def lambda_handler(event, context): #①Cognitoのアクセストークンを取得。 response = requests.post( 'https://ap-northeast-1yfo6hsrgq.auth.ap-northeast-1.amazoncognito.com/oauth2/token', data="grant_type=client_credentials&client_id=141ko0tsl9qpba05m4p19179m2&client_secret=76s7lr40s7jf96egk05i5snunn9v2l45icscj4hpj6a4ucf5abc&scope=default-m2m-resource-server-3dapgs/read", headers={'Content-Type': 'application/x-www-form-urlencoded'} ) cognito_response=response.json() access_token=cognito_response["access_token"] #②ヘッダーにアクセストークンを付与し、APIGatewayへアクセスするリクエストを送付。 api_response = requests.get( 'https://pqopqj9g2b.execute-api.ap-northeast-1.amazonaws.com/dev/', headers={'Authorization': access_token} ) api_response_json=api_response.json() print(f'api_response is {api_response_json}')   ソースコードの中にコメントアウトしておりますが、流れを解説すると2点に分けられます。 ①Cognitoのアクセストークンを取得。 Cognitoへアクセストークンを取得するためのURL、送付するデータ形式、ヘッダーが下記の通り決まっております。そのため、その通りにPostリクエストを送付するだけです。 URL:’https://{Cognitoのドメイン名}.auth.{リージョン名}.amazoncognito.com/oauth2/token’ 送付するデータ形式:”grant_type=client_credentials&client_id={CognitoユーザープールクライアントID}&client_secret={Cognitoユーザープールクライアンドシークレット}&scope={Cognitoリソースサーバー識別子}/{Cognitoリソースサーバーカスタムスコープ}” ヘッダー:{‘Content-Type’: ‘application/x-www-form-urlencoded’}   特にヘッダーは、下記ドキュメントに記載の通り、他のContent-Typeの指定ができないため、注意してください。 スコープ、M2M、リソースサーバー - Amazon Cognito ユーザー属性へのアクセスを許可し、Amazon Cognito ユーザープールによる API アクセス用にリソースサーバーを設定します。 docs.aws.amazon.com   ②ヘッダーにアクセストークンを付与し、APIGatewayへアクセスするリクエストを送付。 API GatewayのURLへアクセスをしますが、肝心なのがヘッダーです。 事前に取得した情報をもとに、ヘッダーを設定します。 前半のブログで、APIGatewayのオーソライザー設定時に「Authorization」をトークンのソースとして設定したので、これをヘッダーとして設定する必要があります。 例:headers={‘Authorization’: access_token}   挙動確認 では、実際にLambdaのテストとして動作確認をしてみますと、ログ出力のところでAPIの裏側のLambdaとして実装したステータスコード200と「Hello from Lambda!」が出力されていることがわかります。   まとめ 今回はAPIGatewayのM2M認証を呼び出す方法について記載いたしました。 前半の記事と合わせて、M2M認証の理解の助けになればと思います。
アバター
こんにちは、SCSK齋藤です。 今回は、Amazon API Gateway の認証方式である、Amazon Cognito を用いたM2M認証の方法について解説いたします。 本ブログは、APIを構築する前半と、プログラム側でAPIを呼び出す後半部分の2つに分けてブログを執筆します。 今回は、APIを構築する前半のブログとなります。   概要 アーキテクチャ図は下に示す通りです。今回はAPI Gatewayの裏にLambdaを設けて、API呼び出しでLambdaが動くようにします。 なお、M2M認証の処理の流れは下記の通りとなります。 ①APIの呼び出し元がCognitoにアクセストークンを発行しに行く。 ②受け取ったアクセストークンを、ヘッダーに付与してAPIGatewayへアクセスしに行く。 ③リクエストを受けたAPIGatewayは、リクエストに付加されたアクセストークンを検証するため、Cognitoに問い合わせをする。 ④アクセストークン検証の結果、問題なければ後続の処理を進める。(Lambdaの呼び出し。)   各リソースの作成 アーキテクチャ図を実現する、各リソースの作成をマネジメントコンソールベースで説明します。 なお、主にM2M認証の部分に焦点を置くため、あまり重要でない設定の作成過程は解説をスキップさせていただきます。 AWS Cognito Cognito関連のリソースは作成されるものが多く、下記4つとなります。 ユーザープール アプリケーションクライアント ドメイン リソースサーバー マネジメントコンソールで作成すると芋蔓式で複数のリソースが同時作成されますが、本ブログでは一つ一つどのようなリソースが作成されているかみていきたいと思います。 ユーザープール Cognitoのユーザープールの作成を行います。 ユーザープール画面にて、「ユーザープールを作成」をクリックします。   作成するユーザープールの種類を選択できるため、「Machine to Machineアプリケーション」を選択し、任意の名前を入力します。 その後、「ユーザーディレクトリを作成する」をクリックして、作成します。   作成後、ユーザープール一覧画面に遷移すると、作成したユーザープールが表示されます。 ユーザープール名をクリックします。 そうすると、概要が表示されます。 ユーザープール名が分かりづらいので、「名前の変更」をクリックして、好きな名前に編集します。   アプリケーションクライアント Cognitoの左ベインのところから、「アプリケーションクライアント」をクリックすると、最初にユーザープールを作成した時のアプリケーション名が存在します。それをクリックすると、アプリケーションクライアントの概要が表示されます。 マネジメントコンソールの場合、自動で作成されますので、明示的な作成が不要ですが、これらのクライアントIDやクライアントシークレットは呼び出す際に必要となります。   ドメイン 次にドメインについて見ていきましょう。 同じくCognitoの左ベインから、ドメインをクリックすると、作成されたドメイン情報が閲覧できます。 ここに記載されている、ドメインURLに対して、アクセストークンを発行しに行くことになります。 また、リソースサーバーというものも存在しています。 こちらについても、編集ボタンを押下して、内容を見ていきましょう。   リソースサーバー リソースサーバーの中には、重要なものが2つあります。 ・リソースサーバー識別子 ・スコープ名 どちらもすでに作成済みですが、これら2つの項目を合わせて、アクセストークン取得の際に必要となります。   Lambda 今回のAPIGatewayの裏側にあるLambdaは、特に凝ったものにする必要がないので、デフォルトのソースコードそのままとします。 単純にステータスコード200と「Hello from Lambda!」と出力されるだけのシンプルなプログラムです。   API Gateway これまで作ったリソースを、API Gatewayに統合していきます。 まず、RESTAPIを作成し、LambdaをGetで呼び出すようにします。(作成の過程は省略します。)   本題はここからです。認証にCognitoのM2Mを使います。 作成したAPIの画面の左ベインで、オーソライザーをクリックし、その後表示される画面でオーソライザーを作成をクリックします。 任意のオーソライザー名を設定します。 オーソライザーのタイプは、Cognitoを設定し、ユーザープールの選択画面で先ほど作成したユーザープールを選択します。 トークンのソースには、下記ドキュメントの内容を参考に「Authorization」というヘッダー名を入力します。 REST API と Amazon Cognito ユーザープールを統合する - Amazon API Gateway REST API と Amazon Cognito ユーザープールを統合する方法について説明します。 docs.aws.amazon.com そうすると、オーソライザーが作成されます。 最後に作成したオーソライザーを、APIに関連づけます。 まず、紐付けるAPIの左ベインのリソースをクリックし、その中からメソッド(今回はGET)の中のメソッドリクエストを選択し、設定の編集ボタンをクリックします。 認可の部分に、作成したオーソライザーを選択します。 そして認可スコープに、Cognitoのリソースサーバーで設定したリソースサーバー識別子とカスタムスコープ名を/で連結したものを入力します。 設定後、下の画面に戻るので、APIをデプロイします。 任意のデプロイステージ名を入力して、デプロイします。   まとめ 今回はAPIを認証部分含めて構築しながら解説しました。 後半となる別のブログでは、そのAPIを呼び出すプログラムの書き方について解説していきたいと思います。
アバター
カレーか、ラーメンか。それが問題だ。 こんにちは、佐藤です。 皆さんは、お昼ごはんのメニューが決まらずに貴重な昼休みを浪費してしまった経験はありませんか? 気づけば時計の針は12:15を回り、店選びの選択肢がどんどん狭まっていく絶望感…。 正直なところ、私自身何度もそんな経験があります。 はじめに 15分の使い方が人生(と仕事)を変える? そんな私ですが、先日Yahoo!ニュースでこんな興味深い記事を見かけました。 週明け15分の「デジタル断捨離」が、仕事のパフォーマンスを劇的に変える理由 (中略…記事の要約)…週明けのたった15分を使ってデスクトップのファイル整理やスマホのアプリ整理(デジタル断捨離)をするだけで、デジタルのノイズが減り、その後の生産性が劇的に向上するとのこと。 出典: Yahoo!ニュース(2026年1月11日配信) …待ってください。 記事によれば「たった15分」で仕事の生産性を劇的に向上させららしい。 それなのに私はその貴重な15分を「今日、麺にするか米にするか」という悩みだけで溶かしている。 そんなの許されるわけがありません。 ランチの決定ごときに時間をかけてはいけない、0秒で決めるべきです。 普段Javaなどを扱っているエンジニアなら math.random() を使おうとか思いつくかもしれません。 しかし PC内部の時計に依存した「疑似乱数」で、私の大切な胃袋の運命を決定していいはずがありません。 「真のランダムに、私の胃袋を委ねたい。」 そう決意した私は、とりあえずAWSを開きました(?) ということで今回は、 量子コンピュータを手軽に使えるサービス「Amazon Braket」を使って、 量子力学の「重ね合わせ」を利用し、今日のランチを文字通り一瞬で決定してみようと思います。 シュレディンガーのカレーとは? 皆さんは 「シュレディンガーの猫」 をご存知でしょうか? オーストリアの物理学者エルヴィン・シュレディンガーが提唱した思考実験で、 箱の中の猫が「生きている状態」と「死んでいる状態」が観測されるまで同時に存在するという、 量子力学の奇妙な性質(重ね合わせ)を表したものです。 コイントスなどを想像するとわかりやすいかと思います。 投げられたコインをハイスピードカメラで捉えると、きっと表か裏か、どちらかを向いていると思います。 ですが我々の目では、回っているコインの表裏を判別することができません。 その瞬間を、量子力学では「 表と裏が混ざり合っている『重ね合わせ』の状態 」と考えるのです。 ならば、 私のランチも量子力学の重ね合わせに委ねてみてはいかがでしょうか。 状態 |0>  : カレー 状態 |1> : ラーメン この2つの状態が、観測されるその瞬間まで同時に存在している。 要するに「店に入って券売機を見るまで、私のランチはカレーでもありラーメンでもある!」 という、優柔不断な状態を物理学的に正当化してみただけですね。 私のランチは、カレーでもありラーメンでもある。 これこそが「 シュレディンガーのカレー 」です(ここまで理解できましたか…?)   やってみた BedrockではなくあえてBraketを使ってみる さて、さっそくAWSで量子コンピューティングを始めてみましょう。 こういう話題はもっぱらAmazon Bedrockが話題ですが、今回使用するのは Amazon Braket です。 Braketとは、量子コンピューティングの調査、評価、実験のためのフルマネージドサービスです。 マネジメントコンソールから「Amazon Braket」を検索し、有効化していきます。 ちなみにリージョンは安定のバージニア北部(us-east-1)で。 案内に従ってノートブックインスタンスを作成し、JupyterLabを起動すれば準備はOK。 Notebookのconda_braketを選択すればOK。 ここまでの所要時間は数分。デジタル断捨離よりも早いです。。。 量子回路でランチを設計する…? 今回の検証で最も大切な部分、コードの実装です。 Jupyter Notebook上で、以下のようなロジックを組みました。 重ね合わせで「2つのメニューが混ざり合っている」状態へ まず、量子回路(Circuit)を作成し、1量子ビットを用意します。 ここに「 アダマールゲート(H) 」という操作を加えます。これが魔法のゲートです。 「0」という確定した状態をこのゲートに通すと、 量子の世界特有の 「0と1が半々で重なり合った状態 に変化します。 先ほどの例で言うところのコインを投げる行為に等しいと言えます。 # 量子回路の作成 circuit = Circuit().h( 0 ) このたった1行で、量子ビットは「0」と「1」の重ね合わせ状態になります。 つまり、 カレー(0)とラーメン(1)が50:50の確率で重なり合っている状態 を作り出すのです。 量子回路図で見るとこんな感じ。 シンプルですが、この中に宇宙の真理が詰まっています。 いざ、実機(IonQ)で運命の観測! ここでシミュレーター( LocalSimulator )を使えば、コストもかからず一瞬で結果が出ます。 しかし、それでは面白くありません。いえ、それでは「真のランダム」とは言えません。 自然界の真理に委ねるため、今回は妥協なく 実際の量子コンピュータ(QPU) を使用します。 デバイスには、イオントラップ方式の量子コンピュータ 「IonQ Forte-1」 を指定しました。 # 実機(IonQ)を使う場合 (有料かつ待ち時間あり) device = AwsDevice( "arn:aws:braket:us-east-1::device/qpu/ionq/Forte-1" ) タスクのショット数(試行回数)を100回に設定し、いざ実行! 「これで今日のランチ迷子とはおさらばだ!」と意気込んで実行ボタンを押しました。 print( "量子コンピュータ(またはシミュレータ)で測定中..." ) ※実機の場合、世界中の研究者からのジョブで順番待ちが発生するため、完了するまで待機する必要があります。 観測結果はいかに 待つこと… 1時間 。 ようやくIonQから観測結果が返ってきました。 私の胃袋の重ね合わせが収束した瞬間です。 結果はこちら↓ カレー ( 0 ) : 48回 ラーメン ( 1 ) : 52回 僅差ですが、「1」の勝利! ということで量子コンピュータは私にラーメンを食べるよう啓示を授けました。。。 デジタル断捨離4回分の代償は大きかった… 無事にランチが決まってよかった! …と、素直に喜べる状況ではありません。2つの悲惨な代償が襲いかかってきます。 まず、 金銭的コスト 。 今回の「IonQ」実機利用(100ショット)にかかった費用は… 30ドル(約4,732円) ランチ代より高くないですか!?ラーメン4杯分です。 そして何より、 時間的コスト 。 実行から結果が返ってくるまでの待ち時間、 60分 冒頭のニュースを思い出してください。 「15分のデジタル断捨離で、仕事のパフォーマンスは劇的に変わる」 私は、その 4倍 にあたる60分を、ただ「ラーメンを食べる」という決断のためだけに費やしました。 しかも、結果が出た頃には 昼休憩が終了 しているという失態ぶり…   まとめ 今回はAmazon BraketのIonQを使って、今日のランチを量子力学的に決定してみました。 結果として、厳正なる宇宙の法則によってランチメニューは決定されましたが、 「ランチを食べる時間」そのものがなくなり、結局パンを齧るのでした… 学び ・量子コンピュータは、ランチ決めにはまだ早すぎる。 ・実機(QPU)を使うと、お財布と時間に大ダメージを受ける可能性がある。 ・15分あるなら、量子計算を待つのではなく、デスクトップのファイルを整理すべき。 それでも軽い気持ちで量子コンピュータを試してみたい! そんな方はぜひシミュレーターを使って気軽に量子コンピュータを試してみてください! 私のような物好きはせめて時間に余裕がある休日に行うことを強くおすすめします! ぜひ、皆さんも お財布に気をつけて 楽しんでみてください!
アバター
こんにちは SCSKの庄司です。 先日ServiceNow環境で発生した「スクリプトを含むフローアクションが突然動作しなくなる」という事象について、注意喚起を込めて紹介します。 本記事は執筆時点(2026年1月)の情報になります。最新の内容は製品ドキュメントを参考にしてください。 発生した事象 これまでずっと安定して動作していたフローアクションが、突然正常に動作しなくなりました。 具体的には、以下のようなスクリプトで要求アイテム(RITM)の情報を取得し、カタログタスクを作成する処理を行っていました。 問題が発生したスクリプト(抜粋): var reqItemGR = new GlideRecord("sc_req_item"); reqItemGR.get(inputs.request_item); var reqItemId = reqItemGR.getValue("sys_id"); var requestId = reqItemGR.getValue("request"); var catalogItemId = reqItemGR.getValue("cat_item"); var requestor = reqItemGR.getValue("requested_for"); 二行目に記載のreqItemGR.get(inputs.request_item) が失敗するようになっており、sysIDが空のまま処理が続行されました。 その結果、「どの要求アイテムにも紐づかないカタログタスク」が作成され、要求アイテムとしてはカタログタスクが作成されなかったためそのままフローが終了してしまうという実務上のトラブルが発生しました。 該当のフローアクションは1年以上更新しておらず、フローやカタログアイテム側にも直近の変更はありませんでした。 直近の改修がないにもかかわらず挙動が変わったため、原因特定にそれなりに時間を要することとなりました。   対応策 修正として、get() メソッドの引数に渡す値を、明示的に sys_id の文字列として取得するように変更したところ、正常に動作するようになりました。 修正後のスクリプト(抜粋): var reqItemGR = new GlideRecord("sc_req_item"); reqItemGR.get(inputs.request_item.getValue("sys_id")); var reqItemId = reqItemGR.getValue("sys_id"); var requestId = reqItemGR.getValue("request"); var catalogItemId = reqItemGR.getValue("cat_item"); var requestor = reqItemGR.getValue("requested_for");   考えられる原因 前述した通り直近で変更はなかったにもかかわらずなぜこのような事態が発生したのか、調査の結果、事象発生の直前にYokohama Patch 10 Hotfix 1が適用されていたことが判明しました。 これまで inputs.request_item(参照型オブジェクト)をそのままget()に渡しても、プラットフォーム側でよしなにsysIDとして解釈してくれていたものが、Hotfix適用後の内部的な変更もしくは不具合により、「明示的な sys_id の指定」が必要になった可能性が高いと考えています。 本事象とYokohama Patch 10 Hotfix 1との関連性については、現在Now Supportに確認中です。 何かわかりましたら随時アップデートいたします。
アバター
こんにちは。廣木です。 Catoクラウドをご利用のお客様はすでにご存知の通りですが、2025年8月6日より、Catoクラウドでは XDR Security Core(無償版)とXDR Security Pro(有償版)が統合され、新しいセキュリティオプション「XOps」へ移行されました。 この変更に伴い、以下の UIで実装されていた機能は有償化され、XOPsをご契約されていない場合は利用不可となっております。 「XOps」へ移行 により有償化した機能 [Home] > [Stories Overview] [Home] > [Stories Workbench] [Home] > [Detection & Response Policy 特に、「SocketのLAN Portダウン時の通知」はこれまでDetection & Response Policy でのみ実装されていた機能であったことから、XOPsをご契約されていない場合は利用不可となりました。 弊社では、本件による影響を最小限に抑える目的で、XOps の提供期間を半年間延長し、 【2026年2月6日】 まで LAN Port ダウン通知機能をご利用いただけるよう対応しております。 一方で、先日 Link Health Rule の機能拡張が行われ、Socket の LAN Port ダウン時の通知を同機能にて実装できるようになりました。 本記事では、Link Health Rule によるLAN Port Disconnect 通知機能の設定方法ついてご紹介します。 Link Health Ruleとは? そもそもCatoのLink Health Ruleとは、Connectivity「接続性」やQuality「品質」の監視を行い、ルールに従って通知を行う機能です。 Link Health Ruleの種類 Connectivity Health Rules 接続性(Connectivity)を監視し、接続性に関するイベントをトリガーに通知を行います。 Quality Health Rules 品質指標(Quality)を監視し、設定した閾値を超えた場合に通知します。 今回、Connectivity Health Rulesにおいて、監視可能な接続性に関するイベントが追加され「SocketのLAN Portダウン通知」が可能になりました。 Link Health Ruleの詳細はこちらの記事をご参照ください。 【前編】CatoクラウドのLink Health Rules活用法 ~Connectivity Health Rules~ 「Connectivity Health Rule(接続性監視)」の概要と活用方法を解説します。 blog.usize-tech.com 2025.11.19 設定手順 それでは、設定手順を解説していきます。 ※Detection & Response Policyからの移行を行う場合は、 STEP0(事前準備~「Link Health Rule」の編集)から ご確認ください。 STEP 0:事前準備~「Link Health Rule」の編集 まずは、Detection & Response Policyの既存ルールを確認します。 以下のページから「Response Policy」のタブを開き、Indicationが「LAN port down」のルールを確認します。 ▼[Home] > [Detection & Response Policy] 以下項目は、Link Health Ruleの設定の際にも必要になるため、控えておきます。 確認項目 Source(対象サイト) Response(通知先) 次に、以下のページから「Connectivity Health Rules」のタブを開きます。 ▼[Network] > [Link Health Rule] 対象サイトにおけるルールが既に存在しており、通知先を同じにする場合は、監視対象 イベントを追加します。 対象サイトにおけるルールがない場合はSTEP1へ進みます。 設定内容 Condition On Event :「Lan Port Disconnect」を追加 追加したら「Apply」⇒「Save」で設定保存を行います。 反映まで5分程度待ったら、STEP2へ進みます。 STEP 1:「Link Health Rule」の新規作成 弊社の検証環境を下図のような構成とし、「SocketのLAN2ポートに障害が発生した」というシナリオを想定した設定を行っていきます。 「New」のボタンから 以下のように設定を行いました。 設定内容 General Name :「LINK_DOWN_TEST」と入力 Source Site :「検証環境」を選択 Condition On Event :「Lan Port Disconnect」を選択 Tracking Frequency :「 Immediate( 即時 )」を選択 Send notification to :「 Mailing List(ML_Test)」を選択 入力ができたら、「Apply」⇒「Save」で設定保存を行います。 保存したら、反映まで5分程度待ちます。。。 5分程度たったら、STEP2へ進みましょう。 STEP 2:動作確認 可能であれば実施いただくことを推奨しますが、業務影響が発生する場合があります。 事前に影響がないかご確認ください。 それでは、LANポート障害を発生させて想定通り通知が飛ぶか確認してみます。 LAN2ポートを抜線すると。。。 30秒ほど経過して、通知が届きました! ちなみに、再接続を行うと同じように30秒ほど経過後に、接続の通知も届きました。 無事想定通り、通知を受け取れることを確認したら「Link Health Rule」の設定は完了です。 Detection & Response Policyからの移行を行っていた場合は、さらにSTEP3に進みます。 STEP 3:既存設定の削除 最後に、STEP0で確認した既存のルールを削除します。これで、作業は完了です! 既にトライアル期間が終了している場合は、削除ができない場合がございます。 さいごに 今回は、Link Health Rule によるLAN Port Disconnect 通知機能の設定方法ついてご紹介しました。 本記事を参考に、貴社の運用にお役立ていただければ幸いです!
アバター
こんにちは。SCSKの北川です。 今回はServiceNowのナレッジ管理におけるナレッジフローについてまとめました。 前回の記事はこちら 【ServiceNow】ナレッジの活用① フィードバック – TechHarmony 本記事は執筆時点(2026年1月)の情報です。最新の情報は製品ドキュメントを参考にしてください。 デフォルトのナレッジフロー ナレッジベースから公開フロー・廃止フローを設定する際に選択できるデフォルトのナレッジフローは、4種類あります。 Knowledge – Approval Publish 公開承認 ①[公開]押下 ↓ ② レビュー ナレッジベースの 所有者/マネージャー に承認依頼 ↓ ③ 承認 or 却下 ◆ 承認の場合 予定公開日前→公開予定 予定公開日 が「空」 または 予定公開日後→公開済      ◆ 却下の場合 ドラフト に戻る Knowledge – Approval Retire 廃止承認 ①[廃止]押下 ↓ ② レビュー ナレッジベースの所有者/マネージャー に承認依頼 ↓ ③ 承認 or 却下 ◆ 承認の場合 廃止 ◆ 却下の場合 フロー開始前のステータスに戻る Knowledge – Instant Publish すぐに公開 ①[公開]押下 ↓ ②  予定公開日前→公開予定 予定公開日 が「空」 または 予定公開日後→公開済 Knowledge – Instant Retire すぐに廃止 ①[廃止]押下 ↓ ② すぐに廃止   カスタムナレッジフロー        条件や承認者など業務要件に応じて承認・廃止フローを変更したい場合は、カスタムナレッジフローを作成します。 手順は以下の通りです。 ①[Workflow Studio]の[Flows]からデフォルトのフローを選択します。      ②画面右上の[More Actions Menu]から[Copy flow]を押下します。 ③フローの名前を変更します。 ④コピーしたフローを編集後[Activate]を選択します。 ⑤ナレッジベースの「Publish flow」または「Retire flow」に④で編集したフローを設定します。 以上がナレッジフローを作成~設定の手順です。 まとめ 今回はナレッジ管理におけるナレッジフローをご紹介しました。 ナレッジフローを活用して、効率的にナレッジを運用しましょう。
アバター
こんにちは、SCSKで テクニカルエスコートサービス を担当している兒玉です。 前回は検証用リダイレクト先ドメインのサイトを作成するところまででしたが、今回は目的であるAPEXドメイン側の設定を行います。 前編は こちら APEXドメインの作成 今回は、いよいよAPEXドメインの仕組みを作成していきます。 前回紹介したアーキテクチャ図の左側になります。 東京リージョンでの証明書の発行 前編で発行した証明書ですが、CloudFrontで使用するために 米国東部(バージニア北部)(us-east-1) で発行していました。 一方、今回デプロイしようとしているAPEXドメインのALBは東京リージョン(ap-northeast-1) に作成予定です。 AWS Certificate Manager(ACM) にある証明書は同じリージョン内でないと使用出来ないため、今度は東京リージョンで発行する必要があります。 前編で行ったのと同様に、APEXドメイン名+サブドメイン名(ワイルドカード指定)、エクスポート無効、DNS検証としてリクエストを行います。秘密鍵のエクスポートを無効にすると無料なので、こういうケースでは助かりますね。 前編と同様に、DNS認証を行うのですが、設定すべきCNAME名、CNAME値のセットはドメインが同じ場合には同じ値になるようで、リクエスト後数分で証明書が「発行済み」となりました。 次のデプロイで使用するので、証明書のARNをコピーしてメモしておきます。   APEXドメイン転送システムをデプロイ デプロイに必要なファイルを準備します。 必要なファイルを zip 化したファイルのリンクです。 apex-domain-redirect-main-20260121-1.zip   sha256: 6fedb6a407248b58e402a7378af68196823584270b7d55643ea16cc4e80cebb3 ファイルをダウンロードし、AWS CloudShellにアップロードして zipファイルを展開して、フォルダを移動します。 ~ $ unzip apex-domain-redirect-main-20260121.zip -d ./apex-domain-redirect-main Archive: apex-domain-redirect-main-20260121.zip inflating: ./apex-domain-redirect-main/apex-domain-redirect-main.yaml inflating: ./apex-domain-redirect-main/deploy.sh inflating: ./apex-domain-redirect-main/README-jp.md inflating: ./apex-domain-redirect-main/PARAMETERS-jp.md ~ $ cd apex-domain-redirect-main apex-domain-redirect-main $ PARAMETERS-jp.md 、README-jp.md などを参考に、パラメータと共に、 deploy.sh を実行します。 –stack-name :  作成するCloudFormationスタックのスタック名 –apex-domain : 作成するAPEXドメイン名 –target-fqdn  : リダイレクト先となるドメインのFQDN –certificate-arn : 先程メモした 証明書のARN –prefix  : 作成するリソースにつくprefix –cost-tag : 属性名”Cost” のタグの値 ./deploy.sh --stack-name my-apex-redirect \ --apex-domain example.com \ --target-fqdn www.example.com \ --certificate-arn arn:aws:acm:ap-northeast-1:123456789012:certificate/abcd1234-ab12-cd34-ef56-abcdef123456 \ --prefix my-apex \ --cost-tag my-project 10-15分程度でデプロイが完了します。 成功すると、以下のようなメッセージが出力されるので、指示に従って他社DNSにAPEXドメイン用の Aレコードを 2 つ 設定します。 他社DNSにレコードを登録した後しばらく待ちます。 通常は数分から数時間ですが、最大48時間程度かかることもあるようですので、気長に待ちましょう。 dig コマンドなどで、APEXドメインに対してDNSクエリを行い、デプロイ結果で表示されたAPEXドメインのAレコード2つが表示されれば OK です。 APEXドメイン転送動作の確認 Webブラウザから、 APEX ドメイン名を入力してアクセスします。 Lambda関数が生成したAPEXドメインのHTMLが表示されます。ブラウザのアドレス欄の左端が錠マークになっているので、 APEXドメインのHTTPS 接続に転送されていることがわかります。 APEXドメイン転送の動作や、転送しようとしているFQDNがわかりやすいように、わざと転送まで10秒待ちをいれていますが、実際のWebサイトでは即時転送に変更してください。 10秒後に前編で構築した検証用リダイレクト先のWebページに無事転送されました! おわりに いかがだったでしょうか? DNS ALIAS非対応の他社DNSでも、APEXドメインへのアクセスをリダイレクトする処理をサーバレスに構築できることがお分かりいただけたと思います。 従来であれば、APEXドメインのトラフィックをリダイレクトするためだけにEC2でWebサーバーを構築し、OSやミドルウェアのパッチ適用などのメンテナンスを継続的に行う必要がありました。 しかし、このソリューションではCloudFormationテンプレートをデプロイするだけで、メンテナンスを極小化(Lambda関数のランタイム管理とWAFルールの調整程度)したサーバレス構成を実現できます。運用負荷の削減という点で大きな価値があるのではないでしょうか。 それでは、皆様も良いAPEXドメイン転送生活を。
アバター
こんにちは、SCSKで テクニカルエスコートサービス を担当している兒玉です。 Webサイトを作成する際に、APEXドメインへのアクセスを転送したい、と思うことはありませんか? APEXドメイン(アペックスドメイン、Zone APEX 、ネイキッドドメイン、ルートドメインとも呼ばれる)とは、「example.com」のようにサブドメイン(www.など)を含まない、ドメイン名そのもののアドレスを指します。 Webサイトにアクセスするユーザー側の立場として考えると、サブドメインあるいはサーバー名を指定してアクセスするのは入力するのが面倒ですし、通例として www に決まっているとしても、決まっているならそっちに自動的に誘導してほしいと考えるのは自然な考えだと思います。 ところが、DNSの仕組みからすると、APEXドメインはちょっと厄介で、APEXドメインには CNAME 適用できないという制約があります。 # これはできない(RFC違反) example.com. CNAME d123456789.cloudfront.net. # サブドメインならOK www.example.com. CNAME d123456789.cloudfront.net. CNAMEはそもそも「このドメインのことは全部あっちの窓口にお願いします」という記述なのですが、APEXドメインにはSOA(Start Of Authority) つまり「このドメインの責任者は私です」という名札をつけて立っている担当者がいる状況なわけです。 こんな矛盾した記述がされているドメインにDNSが問い合わせを行うと、混乱を招いてしまうため禁止されているんですね。 しかし、wwwなどサーバ名なしのドメインからそのドメインのホームページにたどり着きたいという動機もわかります。 では、どうすればよいか。 選択肢としては3つあります。 1. Amazon Route 53のALIASレコードを使う Route 53を使っている場合、ALIASレコードという特殊なレコードタイプが使えます。これはAWS独自の機能で、APEXドメインでもCloudFrontやALBを指定できます。 しかし、これはRoute 53を使っている場合のみ。DNSサーバーを移管したくない、あるいは移管できない状況ではこの選択肢は採用できません。 2. 外部DNSプロバイダーの独自機能を使う 一部のDNSプロバイダー(Cloudflare、DNSimpleなど)は、ALIAS相当の独自機能を提供しています。 しかし、全てのプロバイダーが対応しているわけではありませんし、移管できない状況であれば 1. のケースと同様にこちらも採用できません。 3. 固定IPアドレスを使う Aレコードで固定IPアドレスを指定する方法。これならどのDNSプロバイダーでも使えます。 仕方なく 3. を選ぶことになります。ところが、AWS上でベストプラクティスとされる CloudFront や ALBは動的IPなので、固定IPアドレスを持つサーバー(例えば Elastic IP + EC2)が別に必要になってしまいます。これをうまくサーバレスで解決するソリューションを考えます。 まとめると、こんな状況ではないでしょうか? 会社のポリシーでALIAS相当の機能に対応していない外部DNSプロバイダーを使わなければならない でもAPEXドメインでのアクセスを受け付けたい CloudFrontやALBなど、AWSのサービスにリダイレクトしたい サーバーの維持管理をしたくないのできればサーバーレスで実現したい  このソリューションでは、こんな状況を解決いたします! 前編では、検証用のリダイレクト先環境と証明書の準備までを行います。   ソリューションの全体像 ソリューションの全体像は以下のようになります。 他社DNSでのAPEXドメインレコードに対する要件(IPアドレスを直接設定)を満たすために、Network Load Balancer(NLB) に Elastic IP を付与し、Webサイトとして必要な証明書は Application Load Balancer(ALB) で行い、サブドメインに対するリダイレクト処理を行うHTML応答を Lambda関数内で生成、レスポンスとして返却することで、ブラウザにサブドメインへリダイレクトするよう促します。 この処理をフロー図にすると以下のようになります。 このソリューションの料金概算 前提条件 リージョン: ap-northeast-1(東京) 月間リクエスト数: 100万リクエスト(想定) 平均レスポンスサイズ: 10KB 稼働時間: 24時間365日(730時間/月) 使用サービスと料金 AWS Lambda 設定 メモリ: 128MB ランタイム: Python 3.12 平均実行時間: 100ms(想定) 料金 リクエスト料金: $0.20 per 1M requests 100万リクエスト × $0.20 = $0.20/月 コンピューティング料金: $0.0000166667 per GB-second 100万リクエスト × 0.1秒 × 0.125GB = 12,500 GB-秒 12,500 GB-秒 × $0.0000166667 = $0.21/月 Lambda合計: $0.41/月   Application Load Balancer (ALB) 料金 ALB時間料金: $0.0243 per hour(東京リージョン) 730時間 × $0.0243 = $17.74/月 LCU料金: $0.008 per LCU-hour 想定: 0.5 LCU/時間(低トラフィック) 730時間 × 0.5 LCU × $0.008 = $2.92/月 ALB合計: $20.66/月   Network Load Balancer (NLB) 料金 NLB時間料金: $0.0243 per hour(東京リージョン) 730時間 × $0.0243 = $17.74/月 NLCU料金: $0.006 per NLCU-hour 想定: 0.5 NLCU/時間(低トラフィック) 730時間 × 0.5 NLCU × $0.006 = $2.19/月 NLB合計: $19.93/月   Elastic IP Address 料金 Public IPv4アドレス料金: $0.005 per IP per hour 2個のElastic IP × 730時間 × $0.005 = $7.30/月 Elastic IP合計: $7.30/月   AWS WAF 設定  Web ACL: 1個 マネージドルール: 3個(AWSManagedRulesCommonRuleSet、SQLi、KnownBadInputs) カスタムルール: 1個(Rate-based rule) 合計ルール数: 4個 料金 Web ACL料金: $5.00 per month ルール料金: $1.00 per rule per month 4ルール × $1.00 = $4.00/月 リクエスト料金: $0.60 per 1M requests 100万リクエスト × $0.60 = $0.60/月 WAF合計: $9.60/月   VPC関連リソース 料金 VPC: 無料 Subnets: 無料 Internet Gateway: 無料 Route Tables: 無料 Security Groups: 無料 VPC合計:$0.00/月   その他料金 インターネットへのデータ転送(アウトバウンド): 最初の10TB/月: $0.114 per GB(東京リージョン) – 次の40TB/月: $0.089 per GB – 次の100TB/月: $0.086 per GB 100万リクエスト × 10KB = 10GB/月の場合 – データ転送料金: 10GB × $0.114 = $1.14/月 その他料金合計: $1.14/月   VPC関連リソース 月額料金合計   サービス 月額料金(USD) 月額料金(JPY)※ Lambda $0.41 ¥62 ALB $20.66 ¥3,099 NLB $19.93 ¥2,990 Elastic IP (×2) $7.30 ¥1,095 WAF $9.60 ¥1,440 VPC $0.00 ¥0 ACM $0.00 ¥0 IAM $0.00 ¥0 その他 $1.14 ¥171 合計 $59.04 ¥8,857 ※ 為替レート: 1 USD = 150 JPY で計算   検証用リダイレクト先(転送先ドメイン)の作成 本番では本来のWebサイト( 例えば www.example.com ) に転送するのですが、今回は記事用の検証なので転送先ドメインが必要です。検証用に CloudFront – S3 の環境を作成します。下図の右側の赤枠の範囲になります。 本筋でないコードを全部載せるとそれだけで記事が埋め尽くされてしまうので、必要なファイルのを zip 化したファイルのリンクを載せておきます。 test_environment.zip SHA256: 829899f97643f4dac1dff61e7600a42da4e5afd5e3f4b702cf010d95051eb960 ダウンロードしたファイルを CloudShell などにファイルをアップロードし、 zip ファイルの中身を展開してフォルダを移動します。 ~ $ unzip test_environment.zip -d ./test_environment Archive: test_environment.zip inflating: ./test_environment/deploy_test_environment.sh inflating: ./test_environment/test-environment.yaml inflating: ./test_environment/TEST_ENVIRONMENT_README.md ~ $ cd test_environment test_environment $   vim などで、 deploy_test_environment.sh の中のパラメータを修正します。 PROFILE は AWS が使用するプロファイル名でえすが、 CloudShellからの実行の場合は “” で良いです。 STACK_NAME は CloudFormationが作成するスタック名です。わかりやすい名前や環境の命名規則に沿った形に変更します。 COST_TAG はAWS内でのコスト配分タグとして使用されるタグの値を設定します。(タグの属性名は 内部では “Cost” と固定になっています。) deploy_test_environment.sh のパラメータ設定 パラメータを修正後、デプロイします。 test_environment $ ./deploy_test_environment.sh 10分くらいで、デプロイが完了するので  CloudFront Domain: abcdef01234567.cloudfront.net Test Website URL: https://abcdef01234567.cloudfront.net の箇所をメモしておきます。 これが転送先となる検証用リダイレクト先サイトのドメイン名とWebサイトの URL です。 Test Website URLにアクセスしてみると、 アクセスできましたね。(画像参照) これで検証用リダイレクト先ドメインの環境ができました。 APEXドメイン/サブドメイン用のサーバー証明書の準備 転送用の APEXドメインも https でアクセスが必要ならAPEXドメイン用の証明書が必要です。 サブドメインのワイルドカードも一緒に設定します。これは転送先(www.example.comなど)でも使えますので、AWS Certification Manager から 1枚にまとめて発行します。 CloudFront で使用するので、 証明書を作成するリージョンは 米国東部(バージニア北部)(us-east-1)  である必要があります。   エクスポート可能な証明書は有料ですが、AWS内でのみ使用する場合はエクスポート不要なので無料で利用できます。 料金 – ACM AWS Certificate Manager の料金 – アマゾン ウェブ サービス (AWS) aws.amazon.com リクエストをしただけでは、証明書は有効になりません。まだ、 「保留中の検証」というステータスになっているのがわかります。 ドメインの正当な持ち主であることを証明するために、 証明書をリクエストしたドメインのDNSの 指定された CNAME名 に指定された CNAME値 を設定する必要があります。 CNAME 名 と、 CNAME 値をコピーして、 DNS のプロバイダ画面から、 CNAMEレコードを追加して、 コピーしておいた CNAME名、対応する CNAME値 を設定します。 今回はAPEXドメイン用と、 そのサブドメイン用のワイルドカードで 2 レコードありますが、設定すべき値のセットは同じだったので 追加した CNAME レコードは 1 つでした。 DNSプロバイダの設定画面はUIが様々でどう設定すれば良いかはそのプロバイダ毎に異なるのですが、きちんと設定できているかは dig コマンドで検証すればわかります。 マスクされている箇所ばかりでわかりにくいですが、 dig cname _9c63abcdef0123456789abcdef01234.example.com. と打って、応答の ANSWER SECTION で、 CNAME名 の対となる CNAME値 が表示されれば OK です。 しばらくすると、Certificate Manager の証明書のステータスが「発行済み」に、ドメインのステータスが 「成功」 に変わります。 これで証明書は利用可能になりました。 検証用リダイレクト先サイトに ACM 証明書を設定 転送先となる検証用リダイレクト先(www.example.com) の CloudFront に、サブドメイン  www.example.com を担当してもらうために、担当するサブドメイン名とCertificate Managerから取得した証明書を設定します。 CloudFormationスタックに、先程作成した検証用リダイレクト先のスタックがありますので、 CloudFrontDistributionId の 値 にあるディストリビューションを覚えておいて、マネジメントコンソールの CloudFront の画面から開きます。 ディストリビューションの画面から Add domain をクリック www.example.com (実際は自分のドメイン名) を入力して、Next をクリック 先程作成した証明書が表示されるので、それをチェックして Next、 変更を確認してAdd domains  Distribution updated successfully と表示され、代替ドメイン名に www.example.com 、カスタムSSL証明書の欄がチェックマークになっていればOKです。 Route domains to CloudFront ボタンを押すと、DNSサーバーに設定する レコードの情報が表示されます。これを、利用しているDNSサーバーに設定します。 DNSプロバイダーによってはAレコードに値を直接入力できない場合がありますが、その場合はCNAMEレコードとして設定しても問題ありません。 今回はここまで。
アバター
こんにちは。SCSKで全世界のZabbixが止まらない事を祈っている、小寺です。 Zabbixの6.0から新しくHA機能が実装されています。このHA機能はZabbixServerのサービスのみを冗長化する機能の為、データベースの冗長化が別途必要な状況になっています。 ZabbixにおいてデータベースのI/Oがボトルネックになることが多い点を踏まえ、MySQLを用いてどの冗長化方式がパフォーマンスに優れているか、実機検証を行いました。 1. DRBD 9.0 の構築・設定 DRBD 9系で、Protocol A(非同期)と Protocol C(同期)を検証しました。 それぞれの方式を構築し、fioというツールを用いて速度を計測しました。 DRBD インストール rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org dnf install -y https://www.elrepo.org/elrepo-release-9.el9.elrepo.noarch.rpm dnf install -y kmod-drbd9x drbd9x-utils DRBD 設定ファイル /etc/drbd.d/res_async.res (非同期) resource res_async { protocol A; device /dev/drbd1; disk /dev/nvme1n1; meta-disk internal; on ip-10-0-2-127 { address 10.0.2.127:7788; } on ip-10-0-2-164 { address 10.0.2.164:7788; } } /etc/drbd.d/res_sync.res (同期) resource res_sync { protocol C; device /dev/drbd2; disk /dev/nvme2n1; meta-disk internal; on ip-10-0-2-127 { address 10.0.2.127:7789; } on ip-10-0-2-164 { address 10.0.2.164:7789; } } DRBDの初期化・有効化 # メタデータの作成 drbdadm create-md res_async drbdadm create-md res_sync # リソースの有効化 drbdadm up res_async drbdadm up res_sync # 片方(Primary側)でのみ実行 drbdadm primary --force res_async drbdadm primary --force res_sync mkfs.xfs /dev/drbd1 mkfs.xfs /dev/drbd2 # 両方で実行 mkdir /mnt/async_data mkdir /mnt/sync_data # 片方(Primary側)でのみ実行 mount /dev/drbd1 /mnt/async_data mount /dev/drbd2 /mnt/sync_data DRBD単体の性能検証 (fio結果) 計測対象 IOPS (Write) 帯域 (BW) 平均レイテンシ 標準比 (維持率) 標準ディスク 1,142 4,568 KiB/s 874.92 µs 100% (基準) DRBD 非同期 (Prot A) 1,125 4,503 KiB/s 887.10 µs 98.5%(▲1.5%) DRBD 同期 (Prot C) 1,037 4,150 KiB/s 962.66 µs 90.8%(▲9.2%)   2. MySQL 8.0 構築・設定 MySQL設定ファイル (/etc/my.cnf.d/mysql-server.cnf) [mysqld-nomal] port = 3306 socket = /tmp/mysql.sock3306 datadir = /var/lib/mysqld [mysqld-drbd-sync] port = 3307 socket = /tmp/mysql.sock3307 datadir = /mnt/sync_data/mysqld-drbd-sync [mysqld-drbd-async] port = 3308 socket = /tmp/mysql.sock3308 datadir = /mnt/async_data/mysqld-drbd-async [mysqld-rep-sync] port = 3309 socket = /tmp/mysql.sock3309 datadir = /var/lib/mysqld-req-sync log-bin = mysql-bin server-id = 1 rpl_semi_sync_source_enabled = 1 rpl_semi_sync_source_timeout = 10000 [mysqld-rep-async] port = 3310 socket = /tmp/mysql.sock3310 datadir = /var/lib/mysqld-req-async log-bin = mysql-bin server-id = 1 同期レプリケーション構築 SQL マスター側 で実行 -- 準同期用プラグインの有効化 INSTALL PLUGIN rpl_semi_sync_source SONAME 'semisync_source.so'; SET GLOBAL rpl_semi_sync_source_enabled = 1; -- レプリケーションユーザーの作成 CREATE USER 'repl_user'@'%' IDENTIFIED WITH mysql_native_password BY 'password'; GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%'; FLUSH PRIVILEGES; -- 現在のログファイル名とポジションを確認 SHOW MASTER STATUS; スレーブ側 で実行 -- 準同期用プラグインの有効化 INSTALL PLUGIN rpl_semi_sync_replica SONAME 'semisync_replica.so'; SET GLOBAL rpl_semi_sync_replica_enabled = 1; -- マスターへの接続設定 CHANGE REPLICATION SOURCE TO SOURCE_HOST='10.0.2.127', SOURCE_PORT=3309, SOURCE_USER='repl_user', SOURCE_PASSWORD='password', SOURCE_LOG_FILE='mysql-bin.000001', -- SHOW MASTER STATUSの結果に合わせる SOURCE_LOG_POS=157; -- SHOW MASTER STATUSの結果に合わせる -- レプリケーション開始 START REPLICA; -- ステータス確認 SHOW REPLICA STATUS\G 非同期レプリケーション構築 SQL マスター側 で実行 -- レプリケーションユーザーの作成 CREATE USER 'repl_user'@'%' IDENTIFIED WITH mysql_native_password BY 'password'; GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%'; FLUSH PRIVILEGES; -- 現在のログファイル名とポジションを確認 SHOW MASTER STATUS; スレーブ側 で実行 -- マスターへの接続設定 CHANGE REPLICATION SOURCE TO SOURCE_HOST='10.0.2.127', SOURCE_PORT=3310, SOURCE_USER='repl_user', SOURCE_PASSWORD='password', SOURCE_LOG_FILE='mysql-bin.000001', -- SHOW MASTER STATUSの結果に合わせる SOURCE_LOG_POS=157; -- SHOW MASTER STATUSの結果に合わせる -- レプリケーション開始 START REPLICA; -- ステータス確認 SHOW REPLICA STATUS\G 3. 性能検証結果 (sysbenchによるTPS計測) Zabbixのバックエンドとしての実用性を測るため、sysbenchを用いてスループット(TPS:1秒あたりのトランザクション数)を計測しました。さらに、実運用を想定した「DBチューニング後」の数値も比較しています。 構成案 デフォルト (TPS) チューニング後 (TPS) シングル比 (維持率) シングル構成 637.4 1,505.4 100% (基準) DRBD (同期) 597.6 1,439.4 95.6% DRBD (非同期) 610.8 1,463.9 97.2% MySQL同期(準同期) 521.7 1,384.7 92.0% MySQL非同期 635.1 1,494.6 99.3% ※チューニングにより、全構成でTPSが約2.3倍〜2.6倍に向上しています。 4. 結論:Zabbix DB冗長化の最適解は? 検証の結果、 「いずれの方式を選んでも、性能劣化は極めて軽微である」 という心強い結果が得られました。 今回のポイント DRBD同期モードの健闘: ストレージ層で完全に同期しているにもかかわらず、DBレベルでの劣化はわずか 4.4% でした。ファイルシステムレベルでの冗長化が必要な場合に非常に有力です。 MySQLレプリケーションの安定性: 非同期であればシングル構成と遜色ない性能を発揮します。同期(準同期)でも8%減に留まっており、チューニング次第でさらに差を詰められる「伸び代」を感じさせます。 【小寺流・選定のアドバイス】 性能劣化を過度に心配する必要はありません!「OSを含めた物理故障に備えたいなら DRBD 」、「DBの論理的な整合性や読み取り分散も考慮したいなら MySQLレプリケーション 」といったように、運用要件に合わせて柔軟に選択してOKです。 Zabbixを「止まらない監視システム」に育て上げるための参考になれば幸いです!   SCSK Plus サポート for Zabbix SCSK Plus サポート for Zabbix 世界で最も人気のあるオープンソース統合監視ツール「Zabbix」の導入構築から運用保守までSCSKが強力にサポートします。 www.scsk.jp ★YouTubeに、SCSK Zabbixチャンネルを開設しました!★ SCSK Zabbixチャンネル SCSK Zabbixチャンネルでは、Zabbixのトレンドや実際の導入事例を動画で解説。明日から使える実践的な操作ナレッジも提供しており、監視業務の効率化に役立つヒントが満載です。 最新のトピックについては、リンクの弊社HPもしくはXアカ... www.youtube.com ★X(旧Twitter)に、SCSK Zabbixアカウントを開設しました!★ https://x.com/SCSK_Zabbix x.com
アバター
こんにちは、SCSKの坂木です。 今回は、 生成AI(Gemini3.0)を活用して、フローチャートからAmazon Lexのチャットボットを自動構築 するという検証を行ってみました。 「AWSでチャットボットを作りたいけど、Lexの構築は設定項目が多くて難しい…」 「Lexのコンソール画面だけだと、会話全体の流れ(全体図)が見えづらい…」 そんな悩みを持つ方向けに、フローチャートさえあれば、あとはAIにお任せ というワークフローが可能か試してみた記録です。   Amazon Lexについて Amazon Lexは、音声やテキストを使用した会話型チャットボットを構築するためのフルマネージドサービスです。 主な特徴 フルマネージド :サーバーのプロビジョニングや管理が不要。 他サービス連携 :AWS Lambda等と統合し、会話に応じたバックエンド処理(データ取得や予約など)を簡単に実行可能。 コスト効率   :リクエスト数に応じた従量課金制。   Lexの課題:全体像の把握が難しい 一方で、Lexで開発を進める上での課題もあります。 Lexには「ビジュアルビルダー」という機能がありますが、これは特定のインテント内の細かい動きを見るのがメインです。「メニューAを選んだらBに飛び、そこからCに戻る」といったボット全体の遷移図を俯瞰して見る機能は標準ではありません。 そのため、全体像の把握にはExcelなどで別途フローチャートを作って構成を管理する必要があります。 「どうせExcelで全体図(フローチャート)を作る必要があるなら、そこからAIを使って直接ボットを作ってしまえばいいのでは?」 そう考えたのが、今回の取り組みのきっかけだったりします。   今回のアプローチ:フローチャート × Gemini そこで今回は、構築の難易度を下げるために、人間とAIの役割を完全に分けるアプローチを試しました。 人間(設計者):  「どんな会話にしたいか」を考えることに集中する(Excel作成) AI(エンジニア):  複雑なAWSの設定やコード記述を担当する(Terraform生成) これまでは、人間が「会話の設計」も「AWSコンソールの設定」も両方やる必要がありましたが、後者の面倒な作業を全てAIに丸投げしよう、という作戦です。 具体的な検証フローは以下の通りです。 【人間】設計図を作る  Excelで会話の流れ(フローチャート)とセリフ(管理表)を作成する。 【AI】コードに変換する ExcelデータでGeminiに渡し、Lex構築用のTerraformコードを書いてもらう。 【AWS】デプロイ  出力されたコードを実行し、AWS上にボットを自動生成する。 このフローにより、Lexの専門知識がなくても、「Excelさえ書ければチャットボットが作れる」という状態を目指します。   Excelでフローチャート+補足の表資料を作成する 今回は、 会話の流れ(遷移)を管理する「フローチャート」 と、 ボットのセリフを管理する「管理表」 の2つを使って設計します。   1. 会話の流れを整理する(フロー図) まずは、会話の地図となるフローチャートを作成します。 「どのボタンを押したら、次にどの画面に進むか」という会話のルートは、すべてこの図の中で管理 します。 Excelのセルに文字だけで「Aの次はBへ移動」と書くと複雑になりがちですが、こうして矢印を使った図にすることで、直感的に会話の流れを作ることができます。これが今回の設計のメインとなります。   2. Excelの表に落とし込む(管理表) 図で流れができたら、 各場面で「ボットが何と喋るか」をExcelの表に入力 します。 フローチャートの中に長いセリフを書くとゴチャゴチャしてしまうので、図をスッキリさせるために、メッセージ部分は表で分けて管理することにしました。   この表では、会話の1シーンごとに以下の3つの項目を埋めていくだけです。 項目 説明 インテント名(シーンのID) 会話の各シーンに付ける「名前」です(例:Iac_Menu) 他のシーンと区別するためのIDのようなもの 応答メッセージ そのシーンで「ボットが喋る言葉」です(例:「ご質問内容を選択してください」) 次の動作 ボタンが押された後に「次に移動するシーンの名前」を指定します (例:インストールを選んだら Iac_ZabbixInstall へ移動する、といった行き先案内です)   GeminiにTerraformコードを書いてもらう この章でやったことは非常にシンプルです。 前工程で作成したフローチャートと表が記載されたエクセルデータをコピーして、Geminiのチャット欄に貼り付け、以下のプロンプトを投げただけです。 #実際に使ったプロンプト 添付のフローチャート及び表から、Lexのチャットボットを作成するTerraformのコードを作成してください。 ボタンにおけるラベルと値は、フローチャートの分岐の文字列を用いてください。 ちなみに、最後の「ボタンにおける〜」という一文を加えたのには理由があります。 今回作成したExcelの管理表はシンプルさを優先し、「ボタンに表示する文字」の列を省いていました。そのため、Geminiがボタン名の実装で迷わないよう、「次の画面へつながる流れ(分岐)を見て、そこから適切なボタン名を自動で判断してね」 という意図を伝えています。   ちなにみ、GeminiはExcelには書かれていないLex構築に必要な設定を勝手に理解し、コードに落とし込んでくれました。 具体的には、以下の点を自律的に判断してくれました。 IAMロールの自動作成 Excelには「権限」の話など書いていませんが、Geminiは「Lexが動くためにはIAMロールが必要だ」と判断し、適切なポリシー(AmazonLexFullAccess)を持ったロールを作成するコードを追加してくれました。 ボットの基本構造(Bot / Locale)の定義  インテント(会話の中身)を作る前に、まず「ボット本体」と「言語設定(日本語)」の枠組みが必要であることを理解し、定義してくれました。 ボタンと次の会話の「つなぎ方」  フローチャートでは「Aボタンを押すとBへ行く」としか表現していませんでしたが、Geminiはこれを「Bのインテントの発話条件(Utterance)に、Aボタンのラベルを設定する」というLex特有の実装ロジックに変換してくれました。 レスポンスカードの適切な選択 「ボタンを表示する」という要件に対し、単なるテキストではなく、Lex V2における適切な形式である image_response_card を選択して実装してくれました。   もちろん、一発で完璧に動作したわけではありません。Terraformのプロバイダバージョンの違いによる記述エラーや、リソース名の重複エラーなどが発生しました。 しかし、ここでも専門知識は不要でした。出たエラー文をそのままコピーしてGeminiに貼り付けるだけで、「すみません、修正します」と正しいコードを書き直してくれたのです。 実際にGeminiと協力して完成させたTerraformコードの全文は、量が多いため記事の最後に掲載しています。   チャットボットの動作確認 Geminiが書いてくれたTerraformコードを実行(terraform apply)し、AWSの管理画面を確認してみました。 結果から言うと、 Lexの複雑な設定画面を一切触ることなく、想定通りの動きをするチャットボットが完成 していました。   1. 管理画面で「答え合わせ」 まずはAWSコンソールを開いて、作成されたボットの中身を見てみます。 私は特に指定していなかったのですが、Geminiが気を利かせて「ZabbixHelpBot」という、まさに用途にぴったりの名前を付けてくれていました。 さらに「インテント(会話のパーツ)」の一覧を確認すると、Excelのフローチャートで定義していた Iac_Menu や Iac_Server といった項目が、正しく生成されていることが分かります。   2. 実際の会話テスト 設定が合っていても動かなければ意味がありません。AWSコンソールのテスト機能を使って、実際にボットと会話してみました。 ケース①:インストール手順の案内 まずは「メニュー」から「インストール」を選び、さらに「Server」を選択するフローです。 Excelの矢印で描いた通りにボタンが次々と表示され、最終的に正しいURLが案内されました。「終了」ボタンで会話を終える動きも完璧です。   ケース②:別メニューへの遷移と「戻る」動作 次に、「ライブラリ」や「ホスト設定」といった別の質問を選んでみます。 こちらもURLの案内後に「メニューに戻る」ボタンが表示され、それを押すと最初の画面に戻るという、ループ構造も正しく機能していました。   まとめ 本ブログでは、 生成AI(Gemini)を活用して、ExcelのフローチャートからAmazon Lexのチャットボットを自動構築 する検証を行いました。 結果として、 専門知識が必要なAWSの管理画面を一切操作することなく、直感的な「お絵描き」だけでボットを作り上げることができました 。設計は人間、実装はAIという役割分担により、開発のハードルは劇的に下がります。 この手法の最大のメリットは、 「正」となるドキュメントが「フローチャート(Excel)」になること です。 Lexのコンソールは設定が複雑でブラックボックス化しがちですが、この方法なら「Excelを見れば全体の動きがわかる」「修正したければExcelを直してAIにコードを再生成させる」という運用が可能になります。 「会話をデザインする」ことさえできれば、あとはAIが形にしてくれる時代です。ぜひ皆さんも、手書きのメモからクラウド上のボットを作る体験を試してみてください。   ▼ AWSに関するおすすめ記事 Terraformで実装するAWSファイルストレージ入門:EFSとFSxを構築してみた Terraformを使い、AWSのファイルストレージであるEFSとFSx for Windowsの構築手順を解説します。Linux/Windowsそれぞれに最適なストレージをIaCでコード管理。インフラ構築の再現性を高め、効率化を実現したい方はぜひご覧ください。 blog.usize-tech.com 2025.12.15 【Amazon Bedrock】ナレッジベースを用いた社内資料管理ーめざせ生産性向上ー 社内資料の管理、効率的ですか?様々な形式の文書が散在し、必要な情報を探すのに時間を取られていませんか? ファイルサーバーの奥底に埋もれどこにあるか分からない、バージョン管理が混乱する、などといった課題を抱えていませんか?これらの非効率は、業務の生産性低下に直結します。 今こそ、社内資料の一元管理体制を見直しましょう!ということで、AWS Bedrockのナレッジベースを用いた資料の一括管理およびその検索方法をご紹介します! blog.usize-tech.com 2025.02.14 AWS DataSync を用いて Amazon EC2 の共有フォルダを Amazon FSx に転送してみた 本記事では、ファイルサーバーのデータを Amazon FSx へ移行するシナリオを想定し、AWS DataSync を使った具体的な設定手順をスクリーンショットを交えながら、一つひとつ丁寧に解説していきます。 blog.usize-tech.com 2025.10.02   (付録)完成したTerraformコード全文 最後に、今回の検証でGeminiが生成し、修正を加えた最終的なTerraformコードを掲載します。 以下のコードを保存し、terraform apply を実行するだけで、今回のZabbixヘルプボットがお使いのAWS環境に構築されます。 #provider.tf terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } } provider "aws" { region = "ap-northeast-1" }   #main.tf # -------------------------------------------------------------------------------- # IAM Role for Lex # -------------------------------------------------------------------------------- resource "aws_iam_role" "lex_role" { name = "LexV2BotRole" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = "lexv2.amazonaws.com" } } ] }) } resource "aws_iam_role_policy_attachment" "lex_policy_attach" { role = aws_iam_role.lex_role.name policy_arn = "arn:aws:iam::aws:policy/AmazonLexFullAccess" } # -------------------------------------------------------------------------------- # Lex Bot Definition # -------------------------------------------------------------------------------- resource "aws_lexv2models_bot" "zabbix_bot" { name = "ZabbixHelpBot" role_arn = aws_iam_role.lex_role.arn data_privacy { child_directed = false } idle_session_ttl_in_seconds = 300 } # -------------------------------------------------------------------------------- # Bot Locale (日本語) # -------------------------------------------------------------------------------- resource "aws_lexv2models_bot_locale" "ja_jp" { bot_id = aws_lexv2models_bot.zabbix_bot.id bot_version = "DRAFT" locale_id = "ja_JP" n_lu_intent_confidence_threshold = 0.40 } # -------------------------------------------------------------------------------- # Intent: Iac_Menu (トップメニュー) # -------------------------------------------------------------------------------- resource "aws_lexv2models_intent" "iac_menu" { bot_id = aws_lexv2models_bot.zabbix_bot.id bot_version = "DRAFT" locale_id = aws_lexv2models_bot_locale.ja_jp.locale_id name = "Iac_Menu" sample_utterance { utterance = "メニュー" } sample_utterance { utterance = "開始" } sample_utterance { utterance = "トップ" } initial_response_setting { initial_response { message_group { message { plain_text_message { value = "ご質問内容を選択してください" } } } message_group { message { image_response_card { title = "選択肢" button { text = "Zabbixインストールに関する質問" value = "Zabbixインストールに関する質問" } button { text = "Zabbixライブラリに関する質問" value = "Zabbixライブラリに関する質問" } button { text = "ホスト設定に関する質問" value = "ホスト設定に関する質問" } } } } } next_step { dialog_action { type = "ElicitIntent" } } } } # -------------------------------------------------------------------------------- # Intent: Iac_ZabbixInstall (サブメニュー) # -------------------------------------------------------------------------------- resource "aws_lexv2models_intent" "iac_zabbix_install" { bot_id = aws_lexv2models_bot.zabbix_bot.id bot_version = "DRAFT" locale_id = aws_lexv2models_bot_locale.ja_jp.locale_id name = "Iac_ZabbixInstall" sample_utterance { utterance = "Zabbixインストール" } sample_utterance { utterance = "Zabbixインストールに関する質問" } initial_response_setting { initial_response { message_group { message { plain_text_message { value = "インストールするコンポーネントを選択してください" } } } message_group { message { image_response_card { title = "コンポーネント選択" button { text = "Server" value = "Server" } button { text = "Agent" value = "Agent" } } } } } next_step { dialog_action { type = "ElicitIntent" } } } } # -------------------------------------------------------------------------------- # Intent: Iac_ZabbixLibrary (末端ノード) # -------------------------------------------------------------------------------- resource "aws_lexv2models_intent" "iac_zabbix_library" { bot_id = aws_lexv2models_bot.zabbix_bot.id bot_version = "DRAFT" locale_id = aws_lexv2models_bot_locale.ja_jp.locale_id name = "Iac_ZabbixLibrary" sample_utterance { utterance = "Zabbix要件" } sample_utterance { utterance = "Zabbixライブラリに関する質問" } initial_response_setting { initial_response { message_group { message { plain_text_message { value = "Zabbixに必要なパッケージはこちらのサイトをご確認ください。\nhttps://www.zabbix.com/documentation/current/jp/manual/installation/requirements" } } } message_group { message { image_response_card { title = "次の操作" button { text = "メニュー" value = "メニュー" } button { text = "終了" value = "終了" } } } } } next_step { dialog_action { type = "ElicitIntent" } } } } # -------------------------------------------------------------------------------- # Intent: Iac_Host (末端ノード) # -------------------------------------------------------------------------------- resource "aws_lexv2models_intent" "iac_host" { bot_id = aws_lexv2models_bot.zabbix_bot.id bot_version = "DRAFT" locale_id = aws_lexv2models_bot_locale.ja_jp.locale_id name = "Iac_Host" sample_utterance { utterance = "ホスト設定" } sample_utterance { utterance = "ホスト設定に関する質問" } initial_response_setting { initial_response { message_group { message { plain_text_message { value = "ホストの設定はこちらのサイトをご確認ください。\nhttps://www.zabbix.com/documentation/current/jp/manual/config/hosts/host" } } } message_group { message { image_response_card { title = "次の操作" button { text = "メニュー" value = "メニュー" } button { text = "終了" value = "終了" } } } } } next_step { dialog_action { type = "ElicitIntent" } } } } # -------------------------------------------------------------------------------- # Intent: Iac_Server (末端ノード) # -------------------------------------------------------------------------------- resource "aws_lexv2models_intent" "iac_server" { bot_id = aws_lexv2models_bot.zabbix_bot.id bot_version = "DRAFT" locale_id = aws_lexv2models_bot_locale.ja_jp.locale_id name = "Iac_Server" sample_utterance { utterance = "Server" } initial_response_setting { initial_response { message_group { message { plain_text_message { value = "zabbixサーバのインストール手順はこちらをご確認ください。\nhttps://www.zabbix.com/jp/download" } } } message_group { message { image_response_card { title = "次の操作" button { text = "メニュー" value = "メニュー" } button { text = "終了" value = "終了" } } } } } next_step { dialog_action { type = "ElicitIntent" } } } } # -------------------------------------------------------------------------------- # Intent: Iac_Agent (末端ノード) # -------------------------------------------------------------------------------- resource "aws_lexv2models_intent" "iac_agent" { bot_id = aws_lexv2models_bot.zabbix_bot.id bot_version = "DRAFT" locale_id = aws_lexv2models_bot_locale.ja_jp.locale_id name = "Iac_Agent" sample_utterance { utterance = "Agent" } initial_response_setting { initial_response { message_group { message { plain_text_message { value = "zabbixエージェントのインストール手順はこちらをご確認ください。\nhttps://www.zabbix.com/jp/download_agents" } } } message_group { message { image_response_card { title = "次の操作" button { text = "メニュー" value = "メニュー" } button { text = "終了" value = "終了" } } } } } next_step { dialog_action { type = "ElicitIntent" } } } } # -------------------------------------------------------------------------------- # Intent: Iac_End (終了処理) # -------------------------------------------------------------------------------- resource "aws_lexv2models_intent" "iac_end" { bot_id = aws_lexv2models_bot.zabbix_bot.id bot_version = "DRAFT" locale_id = aws_lexv2models_bot_locale.ja_jp.locale_id name = "Iac_End" sample_utterance { utterance = "終了" } sample_utterance { utterance = "ありがとう" } closing_setting { active = true next_step { dialog_action { type = "EndConversation" } } closing_response { message_group { message { plain_text_message { value = "ご利用ありがとうございました。" } } } } } }
アバター
こんにちは、SCSKの坂木です。 本記事では、 保存前処理 の中でも計算処理に焦点を当て、以下の3つの機能について、具体的な設定例を交えながら解説します。 乗数 差分 1秒あたりの差分   保存前処理について 保存前処理とは、Zabbixが監視対象から取得したデータを データベースに保存する直前に、その値を加工・変換するための機能 です。例えば、取得したデータの単位を変換(バイト→ビットなど)したり、累積し続けるデータから「前回からどれだけ増えたか」という差分や速度を計算したりできます。 これにより、不要なデータを保存せずに済むためデータベースの負荷を軽減できるほか、データを整形することで、より柔軟で高度な監視や分かりやすいグラフ描画を実現できます。 2 アイテムの値の保存前処理 www.zabbix.com   乗数 取得したデータに対して、 指定した数値を掛け算して保存する処理 です。整数だけでなく、小数(0.5など)や科学的表記(1e+2など)も使用可能です。   ユースケース 単位の変換 : バイト(B)をビット(bit)に変換する、ミリ秒を秒に変換する 倍率の調整 : 0.0~1.0で表される値を、0~100(%)の表記に直す 物理量の補正: センサー等の生データに係数を掛けて正しい電圧や温度にする   実例 byte単位で出力されるOSやネットワーク機器が返す生のデータを、bit単位で監視する設定をします。 アイテムおよび保存前処理の設定は以下のとおりです。   『乗数』の保存前処理では、パラメータに入力した数値を、取得した元データに掛けてデータベースに保存します。 今回設定した保存前処理は、取得した値に8を掛ける設定となっています。   こちらのように取得されます。   差分 (現在の値) - (前回の値) を計算し、その差分量を保存する処理 です。前回チェック時から「どれだけ値が増えた(または減った)か」を記録します。   ユースケース 累積カウンタの増加量監視: 「サーバ起動時からの総アクセス数」や「総エラー数」のような、累積していくデータに対して、 「前回の監視から何件増えたか」を知りたい場合 ファイルの増加サイズ  : ログファイルのサイズ監視などで、前回から何バイト書き込まれたかを知りたい場合   実例 ファイルサイズの差分を返す設定をします。 アイテムおよび保存前処理の設定は以下のとおりです。   『差分』の保存前処理は、パラメータを設定せず、名前の項目から『差分』を選択するだけとなっています。   こちらのように取得されます。   1秒当たりの差分 (現在の値 - 前回の値) ÷ (前回からの経過秒数) を計算する処理 です。いわゆる「速度(レート)」を算出するために使用します。   ユースケース トラフィック監視 (bps): 累積転送量から、現在の通信速度を算出する ディスクI/O (IOPS)   : 累積読み書き回数から、1秒間あたりの処理回数を算出する CPUスイッチ回数   : コンテキストスイッチの累積回数から、現在の負荷状況(毎秒の切り替え回数)を算出する   実例 『乗数』の実例で作成した受信した合計ビット数を取得するアイテムから、『1秒あたりの差分』を取ってインバウンド帯域(bps)を求める設定をします。 アイテムは『乗数』のものと同じであり、保存前処理は『乗数』の保存前処理に加えて『1秒あたりの差分』を追加した設定となっております。 『1秒あたりの差分』の保存前処理は、パラメータを設定せず、名前の項目から選択するだけとなります。 保存前処理は、設定したステップの上から順番に実行されます。今回の例では、まず『乗数』でバイトをビットに変換し、その変換後の値を使って『1秒あたりの差分』を計算しています。     こちらのように取得されます。   まとめ 本記事では、Zabbixの保存前処理機能の中から、計算処理を行う『乗数』『差分』『1秒あたりの差分』について解説しました。 監視対象から取得できるデータは、必ずしもそのまま監視やグラフ化に適した形式であるとは限りません。しかし、保存前処理を適切に組み合わせることで、以下のようなメリットが得られます。 データの意味付け: 単なる数値(バイト数など)を、直感的に分かりやすい単位(bpsなど)に変換できる 変化の可視化  : 累積値ではなく、増加傾向や速度を可視化することで、障害の予兆を捉えやすくなる DB負荷の軽減   : 不要な生データを保存せず、必要な加工済みデータのみを保存できる スクリプトやSQLでの加工に頼らず、Zabbixの設定だけで柔軟なデータ処理が可能です。ぜひこれらの機能を活用して、より効率的で精度の高い監視環境を構築してみてください。 最後までお読みいただきありがとうございました!   ▼ Zabbixに関するおすすめ記事 【Zabbix】保存前処理まとめ -テキスト編- Zabbixの保存前処理(テキスト編)を徹底解説。正規表現、置換、文字列削除など5つの手法を使い、コマンド出力やログから必要な値を抽出するテクニックを具体例で紹介。未加工のデータを整形し、監視の質を向上させたい方必見です。 blog.usize-tech.com 2025.12.04 【Zabbix】UserParameterでスクリプト実行結果を監視する方法 ZabbixのUserParameter設定ガイド。独自の監視項目を追加する方法、引数を使ったコマンドの使い回し、system.runとの違いを具体例で紹介。監視業務を効率化したい方はぜひ。 blog.usize-tech.com 2025.11.06 【Zabbix】system.runでスクリプト実行結果を監視する方法 Zabbixのsystem.run設定方法をステップバイステップで解説。標準アイテムにないカスタム監視を実現するため、zabbix_agentd.confの修正、安全なAllowKeyの使い方、スクリプトの権限設定までを網羅。初心者でも安心のガイドです。 blog.usize-tech.com 2025.11.04   弊社ではZabbix関連サービスを展開しています。以下ページもご参照ください。 ★Zabbixの基礎をまとめたeBookを公開しております!★ Zabbix資料ダウンロード|SCSK Plus サポート for Zabbix Zabbix監視構築に必要な知識と最新機能についての資料をダウンロードできるページです。世界で最も人気のあるオープンソース統合監視ツール「Zabbix」の導入構築から運用保守までSCSKが強力にサポートします。 www.scsk.jp   ★SCSK Plus サポート for Zabbix★ SCSK Plus サポート for Zabbix 世界で最も人気のあるオープンソース統合監視ツール「Zabbix」の導入構築から運用保守までSCSKが強力にサポートします。 www.scsk.jp   ★SCSK Zabbixチャンネル★ SCSK Zabbixチャンネル SCSK Zabbixチャンネルでは、最新のZabbixトレンドや実際の導入事例を動画で解説。明日から使える実践的なノウハウを提供します。 今すぐチャンネル登録して、最新情報を受け取ろう! www.youtube.com
アバター
こんにちは。SCSKの北川です。 今回はServiceNowのナレッジ管理におけるフィードバック機能についてまとめました。 本記事は執筆時点(2026年1月)の情報です。最新の情報は製品ドキュメントを参考にしてください。 ナレッジ記事のフィードバック 「フィードバック」は ユーザーがナレッジ記事の有用性や改善点を評価・コメントできる機能 です。この機能を活用することにより、記事の品質向上や継続的な改善が可能になります。 ナレッジ記事のフィードバックを送信する4つの方法 記事にフラグを設定する。 記事を評価する。  [役に立ちましたか?] の質問に [はい] または [いいえ] と回答する。 記事にコメントを追加する。 コメント追加後↓ ユーザーがナレッジ記事に関するフィードバックを送信後、ナレッジフィードバックテーブル (kb_feedback) にレコードが作成されます。   フィードバックタスク        ナレッジフィードバックタスクは、ユーザーからの改善要望や低評価をタスク化し、担当者が対応できるようにする仕組みです。 改善対応の漏れを防ぎ、ナレッジ記事の品質を継続的に向上させることができます。 タスクが作成される条件は以下のプロパティにて設定可能です。 glide.knowman.feedback.enable_actionable_feedback_for_helpful 記事が役に立たないとマークされている場合にアクション可能なフィードバックタスクを作成します。 glide.knowman.feedback.enable_actionable_feedback_for_rating 記事がこの値以下に評価されている場合、アクション可能なフィードバックタスクを作成します。0 または値が設定されていない場合、レートタイプのフィードバックに対してアクション可能なフィードバックタスクが有効になっていないことを示します。   まとめ 今回はナレッジ管理におけるフィードバック機能をご紹介しました。 フィードバックを活用し、ナレッジ記事の品質を継続的に向上させましょう。
アバター