TECH PLAY

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

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

1226

こんにちは。 Raspberry PiとAWSをつなげて何かできないかと思い、今回はRaspberry Piに気温/気圧/湿度センサーを接続して、取得した情報をAWS IoT Coreに送り、S3バケットに情報を保存するところまでやってみようと思います。 構成イメージ 今回AWS上で構築するリソースとデータの流れは以下のイメージです。 センサー ⇒ Raspberry Pi ⇒ AWS IoT Core ⇒ S3バケットの順でデータが流れる想定です。 Raspberry Pi上でPythonスクリプトを動かして取得データをMQTTでAWS IoT Coreに送り、AWS IoT CoreでメッセージをS3バケットに保存するようにルール設定をしてみようと思います。   用意するもの 今回使うものは以下の通りです。 ・Raspberry Pi 5 ・温湿度・気圧センサーモジュールキット (BME280使用) ・ジャンパーケーブル×5 ・ブレッドボード×1 (・AWSコンソール接続用PC)   Raspberry Pi 事前設定 今回やりたいことを実施するために、いくつかRaspberry Pi上で設定しておく必要があります。 ・I2C通信の有効化 ・必要なライブラリのインストール ・温湿度・気圧センサーモジュールキットとRasberry Piの接続 以上の設定方法を順を追って説明します。 ※今回は取得したデータをRaspberry Piから送り、AWS上へ保存することがメインのため簡単に説明します。 Raspberry Pi設定:I2C有効化 Raspberry Piとセンサーの通信を行うために、Raspberry Pi側でI2C通信を有効化します。 コンソールで以下のコマンドを実行します。 sudo raspi-config GUIが立ち上がったら以下の手順でI2C通信を有効化します。 ①「3.Interface Options」を選択して[ENTER]キーを押下 ②「I5 I2C」を選択し、[ENTER]キーを押下 ③ 確認画面が表示されたら<はい>を選択し、[ENTER]キーを押下 ④ I2Cが有効化されたメッセージが表示されたら[ENTER]キーを押下 ⑤ Raspberry Piを再起動する Raspberry Pi設定:ライブラリのインストール BME280センサーからデータを取得するために、以下のコマンドを実行して必要なライブラリを追加します。 sudo pip3 install smbus2 –break-system-packages sudo pip3 install bme280 –break-system-packages sudo pip3 install paho-mqtt –break-system-packages ※インストールオプションに「–break-system-packages」をつけないと、インストール時にエラーになります。 温湿度・気圧センサーモジュールキットとRasberry Piの接続 センサーをRaspbarry Piにつなぐため、まずはブレッドボードに温湿度・気圧センサーモジュールキットを接続します。 次に回路とRaspbarry Piを接続します。 センサー側 Raspberry Pi側 BME280 VDD 3.3V:1ピン BME280 GND GND:9ピン BME280 SDI GPIO2(SDA):3ピン BME280 SDO GND:6ピン BME280 SCK GPIO3(SDL):5ピン ちょっと見づらいですが、実物はこんな感じ↓です。   接続が終わったら、以下のコマンドを実行します。 sudo i2cdetedt -y 1 実行結果に「76」という表記があれば、正常に接続できています。   AWS設定 さて、Rasberry Piの下準備が完了したところで、次にAWSの設定を実施していきます。 今回AWS上で設定が必要なのは以下の通りです。 ・S3バケットの作成 ・AWS IoT Coreのポリシー作成 ・Raspberry Piの登録と接続用証明書発行 ・AWS IoT Coreのエンドポイント作成 ・AWS IoT Coreのルール設定 こちらも順を追って説明していきます。 S3バケットの作成 まずは、最終的にデータが保存されるS3バケットを作成します。 ※下図の赤枠部分 AWSコンソールにログインして、Amazon S3を開きます。 [汎用バケット]>[バケットを作成]からバケットを作成します。 ※今回は特別な設定は実施せず、すべてデフォルトのまま作成します。 AWS IoT Core:ポリシー設定 ここからはAWS IoT Coreの設定を実施します。 ※下図の赤枠部分 まずは、Raspberry PiがIoT Core向けに実施できる操作を制御する「ポリシー」を設定していきます。 ※このあと発行する証明書にポリシーをアタッチすることで、実施できる操作が制御されます。 AWSコンソールでIoT Coreを開いて、[管理]>[セキュリティ]>[ポリシー]を開いてください。 ポリシーが表示されたら、画面右上の[ポリシーを作成]からポリシーを作成していきます。 作成画面が表示されたら、ポリシー名と許可するアクションを設定します。 今回は一通りのMQTTアクションを許可するため、以下の許可設定とします。 すべて設定し終えたら、画面右下の[作成]でポリシーを作成します。 ポリシー効果 ポリシーアクション ポリシーリソース Allow iot:Connect * Allow iot:Publish * Allow iot:Receive * Allow iot:Subscribe * 以上でポリシーの作成は完了です。 AWS IoT Core:Raspberry Piの登録と接続用証明書発行 ポリシーの作成が完了したら、Raspberry PiをIoT Coreへ接続するための証明書を発行します。 [管理]>[すべてのデバイス]>[モノ]を開き、画面右上の[モノを作成]からデバイスを登録していきます。 作成するものの数は1つを選択し、次へ進みます。 モノのプロパティはデフォルト設定のまま、次へ進みます。 今回は、デバイスシャドウも「シャドウがありません」のままで問題ないです。 デバイス証明書の設定は「新しい証明書を自動生成 (推奨)」を選択したまま、次へ進みます。 ポリシーの選択では、先ほど作成したポリシーにチェックを入れ、「モノの作成」を押下してください。 「モノの作成」を押下すると、証明書ファイルのダウンロード画面が表示されますので、必要な証明書をダウンロードします。 今回利用するのは、以下の3ファイルです。 ・デバイス証明書ファイル (.crt) ・プライベートキーファイル (*****-private.pem.key) ・「Amazon ルートCA 1」のルートCA証明書ファイル 以上で証明書の発行は完了です。 AWS IoT Core:エンドポイント作成 続いて、Raspberry PiがMQTT接続する際の接続先になるエンドポイントを作成していきます。 IoT Coreコンソールの[接続]>[ドメイン設定]を開き、[ドメイン設定を作成]からエンドポイントを作成します。 作成画面が開いたら、以下の通り設定します。 ※記述の無い箇所はデフォルトのままで結構です。 ・ドメイン設定名:任意の名前 ・ドメインタイプ:AWSマネージドドメイン (カスタムドメインも利用できるようですが、今回はマネージドを利用します。) ・アプリケーションプロトコル:セキュアな Websocket 経由の MQTT ・ドメイン設定のステータス:有効にする 設定し終えたら、[ドメイン設定を作成]を押下します。 ドメイン設定が作成出来たら、作成したドメイン設定の「ドメイン名」を控えておいてください。 (後ほど作成するPythonスクリプトの中に記述します。) 以上でエンドポイントの作成は完了です。 AWS IoT Core:ルール設定 最後に、Raspberry Piから送信されてきたときのルール設定をします。 ルール設定では、ルールの対象とするメッセージをSQL形式で指定出来たり、 そのメッセージに対するアクションを設定することができます。 IoT Coreコンソールの[管理]>[メッセージのルーティング]>[ルール]を開き、[ルールを作成]からルールを作成します。 ルールのプロパティ設定画面が表示されたら、任意のルール名を入力して次へ進みます。 次に、SQLステートメントを設定します。ここで設定したSQLに従って、対象とするメッセージを抽出します。 今回は、「topic/」から始まるすべてのメッセージを対象としたいため、以下の通りSQLステートメントを入力し、次へ進みます。 SELECT * FROM ‘topic/#’ 続いて、ルールアクションを設定します。 ルールアクションでは、SQLに従って抽出したメッセージに対して、どのようなアクションを実行するかを設定できます。 今回は冒頭に説明した通り、受け取ったメッセージをS3バケットに出力したいため、以下の通りアクションを追加し、次へ進みます。 ・アクション:S3 bucket ・S3 URI:先ほど作成したS3バケット ・キー:iot/${topic()}/${timestamp()}.json ・IAMロール:アクションに必要なアクセス許可が付与されたロール キーの設定では、メッセージがS3バケットに保存される際のパスとファイル名を指定します。 今回は「iot/トピック名」の下に、「タイムスタンプ.json」というファイル名で、メッセージが保存されるように指定しています。 また、IAMロールについては、今回は「AmazonS3FullAccess」を付与したロールを指定しています。 ※作成されていない場合は、このタイミングで作成してください。 最後に設定確認画面が表示されますので、[作成]を押してルールを作成してください。 以上で、すべてのAWS設定が完了しました。   Pythonスクリプトの作成 ここまで来たら、残すはPythonスクリプトを作成して、Raspberry Pi上で動かすだけです。 Pythonスクリプトのコードを以下に記述します。 こちらのスクリプトでは、AWS IoT CoreのエンドポイントへMQTTクライアント接続し、 センサーで取得した情報を5秒おきにエンドポイント向けにパブリッシュします。 トピック名は「topic/raspi1」としているため、パブリッシュされたメッセージは先ほどのルール設定に引っかかって、 S3バケットに保存されるという算段です。          ※事前にRaspbarry Piにダウンロードした証明書ファイルを保存しておいてください。 ※以下はご自身の設定に合わせて置き換えてください。 ・IoT Coreのエンドポイントドメイン名 ・各種証明書ファイルのパス/ファイル名 import time import json import socket from datetime import datetime import ssl import paho.mqtt.client as mqtt from smbus2 import SMBus import bme280 #AWSエンドポイント情報 aws_endpoint = "********.amazonaws.com" #作成したエンドポイントのドメイン名 aws_port = 8883 #MQTTトピック設定 mqtt_topic = "topic/raspi1" #AWS証明書 ca_path = "*************.pem" #「Amazon ルートCA 1」のルートCA証明書ファイル crt_path = "*************.pem.crt" #デバイス証明書ファイル (.crt) key_path = "*************-private.pem.key" #プライベートキーファイル (*****-private.pem.key) # BME280のI2C定義(I2Cポート1、アドレスはSDOをGNDなら0x76) i2c_port = 1 i2c_address = 0x76 # I2Cバス・BME280初期化 bus = SMBus(i2c_port) bme280.load_calibration_params(bus, i2c_address) # キャリブレーション #MQTTクライアント接続 client = mqtt.Client() client.tls_set(ca_certs=ca_path, certfile=crt_path, keyfile=key_path, tls_version=ssl.PROTOCOL_TLSv1_2) client.connect(aws_endpoint, aws_port, keepalive=60) client.loop_start() time.sleep(1) hostname = socket.gethostname() try: while True: # BME280データ取得 data = bme280.sample(bus, i2c_address) temperature = data.temperature humidity = data.humidity pressure = data.pressure now = datetime.utcnow().isoformat() + "Z" payload = { "datetime": now, "hostname": hostname, "temperature": round(temperature, 2), "humidity": round(humidity, 2), "pressure": round(pressure, 2) } client.publish(mqtt_topic, json.dumps(payload), qos=1) print("published:", payload) time.sleep(5) except KeyboardInterrupt: print("終了します。") finally: client.disconnect() bus.close()   Pythonスクリプトの実行/動作確認 ここまでですべての準備が整いましたので、実際にRaspberry Pi上でPythonスクリプトを動かして動作を確認してみましょう。 Raspbarry Piでコンソールを開いて、以下のコマンドを実行してください。 今回はPythonスクリプトのファイル名を「sensor.py」としています。 python3 sensor.py スクリプトを実行すると、コンソール上で5秒おきにメッセージをパブリッシュした旨の出力がされます。 パブリッシュされたメッセージはIoT Coreで設定したルールの通り、指定のS3バケットへjson形式で保存されます。 ダウンロードしたファイルをメモ帳で開いてみると、気温/気圧/湿度が記述されたメッセージがそのまま保存されていることが 分かります。           以上で、Raspberry PiとAWS IoT Coreを連携し、センサーで取得したデータをS3バケットに保存することができました。   最後に 今回はRaspberry Piに気温/気圧/湿度センサーを接続して、取得した情報をAWS IoT Coreに送り、S3バケットに情報を保存するところまでやってみました。 個人的にはRaspbarry PiもAWS IoT Coreも初めて触る代物だったため、構成はかなり簡単めかな?と思っております。 皆様もぜひとも触ってみてはいかがでしょうか。 また、続きとして、今回S3バケットに保存したデータをQuickSightで可視化してみる記事もございますので、 ぜひともご覧ください。 https://blog.usize-tech.com/visualize-iot-data-raspberrypi-aws/ もっと詳しく調べたら色々できそうだと思ったので、まだまだたくさん触ってみたいと思います。 最後まで読んでいただきありがとうございました。
アバター
こんにちは。SCSKの松渕です。 Google Cloudで ファインチューニングが簡単に実装できる と聞いたので、実践してみたいと思います。 はじめに ファインチューニングとは ファインチューニングとは、 事前学習済みの大規模言語モデル(LLM)を、特定のタスクやデータセットに合わせて、追加で学習・調整する ことです。 これは、モデルの基本的な知識や言語能力を活かしつつ、特定の用途(例:社内文書の要約、特定のトーンでの応答、固有の知識の習得)に特化させるために行われます。 なんだか、RAGとの違いがよく分からないですね。ということでRAGとの違い、使い分けを整理します。 RAGとの違い Geminiに整理いただきました。 特徴 RAG (検索拡張生成) ファインチューニング (モデル調整) 目的 最新 ・ 専門 の 外部情報 に基づいて、正確な回答を生成すること。 モデルの 振る舞い (スタイル、トーン、出力形式)や ドメイン知識 を改善すること。 仕組み 質問と関連性の高い外部文書を 検索 し、その文書をプロンプトに 追記 してLLMに入力する。モデル自体は 変化しない 。 カスタムデータ を使ってモデルの 重み(パラメータ)を更新し、モデルを恒久的に変更 する。 必要なデータ 検索対象となる 参照文書 (PDF、社内文書、データベースなど)。 高品質 な 質問と回答のペア や 指示 データ。 コスト/時間 低い 。主に検索システム(ベクトルデータベースなど)の構築・維持費用。 高い 。大量のGPUリソースと時間が必要(特にベースモデルが大きい場合)。 更新頻度 容易 。参照文書を更新するだけで、即座に結果に反映される。 困難 。データが更新されるたびに、トレーニングをやり直す必要がある。 学習限界 モデルが参照文書に ない 情報を 生成 することはできない。 モデルが学習データに 含まれない 知識(新しい事実)を 知る ことはできない。 RAGのほうが向いているケース 情報が頻繁に更新 される 情報の 出典を明確化 したい ※どのドキュメントの何ページ目 まで出典明記したい場合、チャンク化やメタデータ設計を適切に実施する必要あり 事実の 正確性が最重要 (ハルシネーション対策) ファインチューニングのほうが向いているケース 特定の スタイルやトーンの統一 (jsonなどの出力形式の固定なども可能) トークン効率の改善。 モデルの プロンプトサイズを削減 し、コストとレイテンシを改善したい場合 ハイブリッド(RAG + ファインチューニング) 上記参照いただくとわかる通り、RAGとファインチューニングは 二者択一のものではありません 。これら二つを組み合わせることで、 ファインチューニング でモデルに 出力形式とスタイル を学習させ、 RAG でモデルに 最新かつ正確な事実 を提供する、カスタムAIシステムを構築できます。 今回実装する方式について 今回は、Google Cloudで 簡単にファインチューニングできる 教師ありファインチューニング サービス を利用します! ベースとなるモデルは、 Gemini とGemma、Llamaなどの一部のOSSのモデルでした。 詳細は以下参照ください。 Gemini モデルの教師ありファインチューニングについて(Google Cloud ドキュメント)   事前準備 やりたいことを整理 何より大事ですね。RAGとの使い分けの部分の調査から、 Geminiの応答口調を調整してみよう と思います。 小難しいカタカナ英語ばっかり使う ようにファインチューニングします。 データさえあれば、 「〇〇さんっぽく応答してくるAI」 とかは盛り上がること間違いなし! データの準備 学習大規模言語モデル(LLM)のファインチューニングには、 対話形式のデータセット を学習用データとして準備する必要があります。 特定のタスク(この場合は要約)をモデルに学習させるための 入力(ユーザーのプロンプト)と、それに対する理想的な出力(モデルの応答)のペア として構成されています。 Google社が提供している 学習データのサンプル が こちら 。JSON Lines形式で記載されています。 私が準備した学習データの一行抜粋します。(私は今回、 Gemini使って400行程度準備 してもらいました) {“contents”: [{“role”: “user”, “parts”: [{“text”: “業務の引き継ぎで失敗しないためには?”}]}, {“role”: “model”, “parts”: [{“text”: “タスクのスコープとネクストアクションをマストで文書化し、クリティカルなプロセスは複数のメンバーでコンセンサスを取るべきです。”}]}]} 実際に言われたら、私なら思わず聞き返してしまうかもしれません。 1行で対話のひとつのターン(発話)を表しています。 "role": "user" :この発話が ユーザー(入力側) からのものであることを示しています。 "parts": [...] :発話の 内容(テキストや画像など)を格納 する配列です。 "text": "..." :ユーザーがモデルに与えた 指示(プロンプト)の本文 です。 この例では、「業務の引き継ぎで失敗しないためには?」という文章です。 "role": "model" :この発話が モデル(出力側)の理想的な応答 であることを示しています。 "text": "..." :モデルがこのプロンプトに対して学習すべき 正解の回答 です。 小難しい横文字ばかり使ってますね。 データ準備についての各種注意事項は以下参照ください。 データ数としては、 100 個のサンプルから始めて、必要に応じて数千にスケールする ことをおすすめします。データセットは量よりも質のほうがはるかに重要です。 Gemini モデルの教師ありファインチューニング データを準備する(Google Cloud ドキュメント)   ファインチューニング実施 ファインチューニング開始 「Vertex AI」の「チューニング」画面から 、「チューニング済モデルを作成」を押下 します   作成画面に移ります。 モデル名は適当に入力 します。(キャプチャは入力前ですが) ベースモデルを選択 します。今回はgemini-2.5-flash-lightを選択します。 リージョンを選択 します。 日本のリージョンは選択できません でした。(2025/10現在) EUかアメリカのどこかを選択します。   エポック数、学習率の乗数など細かい設定も可能です。今回はデフォルトのまま進めます。   データセットを選択します。Geminiに作成してもらったデータから 一部(20サンプル)を検証用データセットとして設定 します。   検証をセットすると最後に 検証データを利用した評価まで自動で実施 してくれます。 マネージドのメリットを最大限生かすためにも、検証データセットを用意しましょう。 検証用データと学習データは重複しないよう に準備 します。   学習待ち 「Vertex AI」の「チューニング」画面に作成中のモデルの表示が出てきますので、完了まで待ちます。   今回のケースでは作成にかかった時間は 22分程度 でした。     結果確認とテスト 結果確認 テスト完了したら、結果を確認します。「成功」と表示されているので、大丈夫そうです。 そのほか、各種評価指標もよさげです。 正確性が1に近く、Lossも0に近い 。 ピンク(検証用データの値)と青(学習用データの値)も大きく差はなさそう に見えます。   テスト 「テスト」ボタン が上部にありましたので、押下します。 モデル選択画面が出てきますので、先ほど作成したモデルを選びます。 Google検索へのグラウンディング、RAGへのグラウンディングも可能 です。 今回は使わないのでOFFのまま。   温度(temperature)やTop-Pなどのチューニングも可能。 今回はデフォルトのままで進めます。   適当にプロンプト投げて応答の確認見てみます。左がモデルの応答で、右が私のプロンプトです。 いい感じに煩わしいですね!!大成功です!!   コストの確認 後日、コスト確認しました。合計  \161-  でした。(Gemini 2.5 flash lite tuning の料金) 安っ・・・!! まとめ 本ブログでは、Google CloudのVertex AIを活用し、 大規模言語モデル(LLM)のファインチューニング を実践しました。基本的な知識から実践的な手順、そして成功の鍵となるRAGとの使い分けまでを解説しました。 本ブログを書く中で、 RAGとファインチューニングの使い分け を整理、理解できた のは大きかったです。 また、ファインチューニングはハードル高い技術だと思ってましたが、ここまで 簡単に実装できる とは驚きが隠せません。 AutoML の時も、 コーディングAIエージェント の時も驚きでしたが、 AI周りの技術は本当に日々進歩してます ね。。 データ準備さえできたら、 「〇〇さんそっくりAI」 はいつか作ろうと思います!!
アバター
こんにちは。SCSKの安藤です。 「 Zabbix Conference Japan 2025 」にプラチナスポンサーとして出展します。 本カンファレンスでは、Zabbix社創設者兼CEO Alexei Vladishev による基調講演をはじめ、Zabbixメンバーによる最新機能の紹介、ユーザー企業による事例発表、関連ソリューションの紹介など、Zabbixをより深く理解できる多彩なプログラムをご用意しております。 Zabbixの魅力を再発見する機会として、ぜひご参加ください! 開催概要 事前ウェビナー   【日時】  11月4日(火) 10:30-17:00         11月5日(水) 10:30-17:00 【会場】  オンライン 本編   【日時】  11月6日(木) 10:00-17:20         11月7日(金) 10:00-17:10 【会場】  東京ポートシティ竹芝 ポートホール       (オンライン配信およびアーカイブ配信はございません。)   当社講演 事前セミナー 【タイトル】  ~限界シリーズ~ 第2弾 Zabbix7.0のパフォーマンス限界調査編(再) 【日時】 11月4日(火) 11:30-11:50 【概要】 Zabbix7.0LTSの新機能である、Pollerプロセスの並列処理実行について、どの程度処理性能向上に寄与しているのか、 実際に試してみました。昨年のZabbixカンファレンスでご好評いただいた講演を再度お届けします。 【登壇者】 上田 太一(ITインフラサービス事業グループ 基盤ソリューション事業本部 テクノロジーサービス部) 本編 【タイトル】  AIエージェントが変えるZabbix運用の未来 【日時】 11月7日(金) 11:25-11:55 【概要】 日々のZabbix運用において、監視対象の追加、監視設定、マップ作成、障害対応など、さまざまな業務があります。 本プレゼンテーションでは、AIにより、これらの業務が効率化できることをデモを交えて発表致します 【登壇者】 新沼 俊介(ITインフラサービス事業グループ 基盤ソリューション事業本部 テクノロジーサービス部)   詳細・お申込み 以下よりお申込みください。 Zabbix Conference Japan 2025|EventRegist(イベントレジスト) 「Zabbix Conference Japan 2025」の告知ページです。 eventregist.com   当日は皆さまのご来場を心よりお待ちしております!       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
アバター
こんにちは!Catoクラウド担当、佐藤と申します! 約1か月前に新人研修が終わり、初期配属でCatoクラウドを担当することになりました。 今回は、CatoクラウドのvSocket構築の手順を解説いたします。 私自身もまだまだ勉強中ですので、そういった目線で感じたことや、つまずいたポイントなどを共有できればと思います! はじめに 近年、クラウドサービスはますます進化しており、多くの組織でオンプレミスからクラウドへの移行が進んでいます。 その中で、AWSなどのクラウド環境とCatoクラウドを連携させたいと考えている方も多いのではないでしょうか? この記事では、 AWS環境上にvSocketを構築し、Catoクラウドと接続するまでの手順を紹介します。 手順説明では、実際に私が検証した際の設定を表示して進めていきますので、「簡単に試してみたい!」という方は、画像内で入力されている設定を参考にしていただけると幸いです。(小さくて見えずらいかもですが…) 事前準備 通常、組織のネットワーク環境をCatoクラウドへ接続するためには、Socketと呼ばれる実機アプライアンスが必要です。しかし、パブリッククラウド環境(今回はAWS)とCatoクラウドを接続する場合は、 vSocket(virtual Socket) という仮想アプライアンスをAWS環境上に構築し、Siteと接続することでクラウド環境をCatoネットワークに統合することができます。 AWS上にvSocketを構築するにあたり、以下3つのサブネットが必要です。 MGMTサブネット(public):vSocketの管理用 WANサブネット(public):vSocketとCatoクラウドを接続する外部通信用 LANサブネット(private):vSocketと内部環境を接続する内部通信用 全体の構成を以下に示します。      vSocket構築手順 vSocketの構築手順の解説をしていきます。 以下のステップで設定を進めます。 1. Catoクラウド vSocket Siteの設定 2. AWS設定  2-1. Elastic IPアドレス取得  2-2. VPC作成  2-3. サブネット作成  2-4. インターネットゲートウェイ設定  2-5. セキュリティグループ設定  2-6. インターフェイス設定  2-7. ルートテーブル設定(MGMT・WAN用)  2-8. ルートテーブル設定(LAN用)  2-9. インスタンス起動 3. 接続確認 本記事は2025年10月23日時点での構築手順です。 内容については今後変更の可能性がありますこと、ご了承ください。 図例は一例としてご参考いただけますと幸いです。          Cato社が提供する最新版の構築手順は下記となりますので、ご参照ください。 https://support.catonetworks.com/hc/en-us/articles/4413273479825-Configuring-an-AWS-vSocket-Site 本記事と上記ナレッジベースの内容に差異がある場合、ナレッジベースの内容を優先してください。   1. Catoクラウド vSocket Siteの設定 Catoクラウドの管理ポータルであるCMA(Cato Management Application)上でvSocketと紐づけるSiteの設定を行います。 1. CMAのメニューから、「 Network>Site 」をクリック 2.「 New 」をクリック   3. Add Siteウィンドウ設定をで各種設定を行い、「 Apply 」をクリックします。 • Site Name : ユニークなサイト名 • Site Type : 適切なものを選択 • Connection Type : vSocket AWSを選択 • Country : 使用する国を選択 • State : 使用する地域を選択 • Time Zone : 使用するタイムゾーンを選択 • License Type/Licence:利用可能なライセンスを選択 • Downstream : 利用帯域に従って設定 • Upstream : 利用帯域に従って設定 • Native Range : LANサブネットのIPレンジを設定 (今回は、10.10.3.0/24) • Local IP : 使用するLAN用ENIのIPアドレスを設定 (今回は、10.10.3.10) ※Licenseの選択で「Unassigned」のみの場合は利用可能なライセンスがない状況ですので、ご用意をお願いします。     4. 「 Network>Sites 」からAWS vSocket Siteの設定で作成したサイトをクリックします。 5. 「 Site Configuration>Socket 」をクリックし、シリアル番号(S/N)をコピーして控えておきます。 ※シリアル番号は、AWS上でvSocketを作成する際に使用します。 2. AWS設定 次に、AWS側の設定を行います。 設定手順内で明示している項目以外は、デフォルト値、もしくはご自身の環境に合わせた設定で問題ありません。 2-1. AWS設定-Elastic IPアドレス取得 MGMT用とWAN用のElastic IPアドレスの割り当てを行います。 1.AWS Management Consoleのホーム画面で「 VPC 」をクリックします。 2.左側のメニュー内の「 Elastic IP 」をクリックします。 3.「 Elastic IPアドレスを割り振る 」をクリックします。   4.パブリックIPv4アドレスプールという項目で、「 AmazonのIPv4アドレスプール 」を選択します。 5.「 割り振る 」をクリックします。 6.Elastic IPアドレスの設定画面で、作成したElastic IPアドレスの名前を変更します。 ※Nameにカーソルを合わせると編集アイコンが表示されます。判別しやすい名前への変更を推奨します。 7. 1~6と同様の手順で WAN用 のElastic IPの割り当てを行います。   2-2. AWS設定-VPC作成 vpcを新規作成します。 ※既存のVPCがある場合、本項目は省略してください。 1. AWS Management Consoleのホーム画面で「 VPC 」をクリックします。 2. VPC Management Console画面で「 お使いのVPC 」をクリックします。 3.「 VPCを作成 」をクリックします。   4. VPCの設定を入力後、「 VPCを作成 」をクリックします。 • 作成するリソース : 「 VPCのみ 」を選択 • 名前タグ : VPCの名前を入力 • IPv4 CIDRブロック : 「IPv4 CIDRの手動入力」を選択 • IPv4 CIDR : VPCのIPアドレス範囲を入力 • IPv6 CIDRブロック : 「IPv6 CIDRブロックなし」を選択 • テナンシー : デフォルト値のまま   2-3. AWS設定-サブネット設定 MGMT用のサブネットを作成します。 1. AWS Management Consoleのホーム画面で「 VPC 」をクリックします。 2. VPC Management Console画面で「 サブネット 」をクリックします。 3. 「 サブネットを作成 」をクリックします。 4. サブネットの設定を入力し、「 サブネットを作成 」をクリックします。 • VPC ID : 「2-2」で作成したVPCを選択 • サブネット名 : 任意の名前を入力 • アベイラビリティゾーン : 適切なものを選択 • IPv4 CIDRブロック : MGMTサブネットのIPアドレス範囲を入力 ※アベイラビリティゾーンはMGMT・WAN・LANの3つのサブネットで同じである必要があります。   5. 1~4と同様の手順で WAN用、LAN用サブネット の作成を行います。 ※IPv4 CIDRについて、WAN用はWANサブネットのIPアドレス範囲、LAN用はLANサブネットのIPアドレス範囲を入力してください。   2-4. AWS設定-インターネットゲートウェイ設定 インターネットゲートウェイを設定し、2-2で作成したVPCにアタッチします。 ※インターネットゲートウェイがすでにVPC内に存在する場合には、この手順は飛ばしてください。 1. AWS Management Consoleのホーム画面で「 VPC 」をクリックします。 2. VPC Management Console画面で「 インターネットゲートウェイ 」をクリックします。 3. 「 インターネットゲートウェイの作成 」をクリックします。   4. インターネットゲートウェイの設定後、「 インターネットゲートウェイの作成 」をクリックします。 • 名前タグ : 任意の名前を入力   5. 下図の画面に変わりましたら、「 アクション 」より「 VPCにアタッチ 」をクリックします。   6. アタッチするVPCを選択後、「 インターネットゲートウェイのアタッチ 」をクリックします。 • 使用可能なVPC : 2-2で作成したVPCを選択     2-5. AWSの設定-セキュリティグループの作成 後で作成する各ネットワークインターフェースに適用するセキュリティグループを作成します。 1. AWS Management Consoleのホーム画面で「 VPC 」をクリックします。 2. EC2 Management Console画面で「 セキュリティグループ 」をクリックします。 3. 「 セキュリティグループを作成 」をクリックします。   4. 希望するAWSセキュリティ要件に合わせて、 MGMT・WAN・LAN用のセキュリティグループ をそれぞれ作成します。 • セキュリティグループ名 : MGMT・WAN・LAN用とわかるもの • VPC : 2-2で作成したVPC          • インバウンドルール : MGMT・WAN用: インバウンド通信がないため、ルール不要 LAN用: vSocketと接続したいAWS環境内部のサーバセグメントからの通信を許可 • アウトバウンドルール : デフォルトのすべて許可で問題ありません。 厳しく制限を掛けたい場合は以下を参照してください。 MGMT・WAN用:TCP 443 / UDP 443 / UDP 53 / ICMP すべて宛先Any LAN用:AWS上のご自身のサーバの通信要件にあわせてご検討ください。   2-6. AWS設定-ネットワークインターフェイス設定 ネットワークインターフェイスの作成を行います。 ※MGMT・WAN用とLAN用で少し設定が異なりますのでご注意ください。 1. AWS Management Consoleのホーム画面で「 EC2 」を選択します。 2. EC2 Management Console画面で、「 ネットワークインターフェイス 」をクリックします。 3. 「 ネットワークインターフェイスの作成 」をクリックします。   4. ネットワークインターフェイスの設定を入力し、「 ネットワークインターフェイスを作成 」をクリックします。 • Description : 任意で入力 • サブネット : MGMTのサブネット を選択 • インターフェイスのタイプ: ENA • プライベートIPv4アドレス : 固定の指定があれば「カスタム」、なければ「自動割り当て」を選択 • セキュリティグループ : MGMT用のもの を選択 5. インターフェイス作成後、Name欄が空欄ですので、 MGMT用のインターフェイス であることがわかる任意の名前を設定します。 6. WAN用、LAN用インターフェイス も同様の手順で作成します。   7. ElasticIPアドレス(グローバルIPアドレス)の関連付けを行います。 作成したMGMT用インターフェイスを右クリックし、「 アドレスの関連付け 」を選択します。 8. 先程取得したElasticIPを選択し、「 関連付ける 」をクリックします。 9. 同様に、 WAN用インターフェイス にもElasticIPを関連付けします。( LAN用は不要 )   10. 作成した LAN用のインターフェイス を右クリックし「 送信元/送信先チェックを変更 」をクリックします。 11. 「 送信元/送信先チェック 」を外し(無効にし)、保存をクリックします。 ※このチェックが有効だとルーティングできません。   2-7. AWS設定-ルートテーブルの設定(MGMT・WAN用) MGMTおよびWANサブネットで使用するルートテーブルの設定を行います。 ※MGMTとWANサブネットはルートテーブルを共用します。 1. AWS Management Consoleのホーム画面で「 VPC 」をクリックします。 2. VPC Management Console画面で「 ルートテーブル 」をクリックします。 3.「 ルートテーブルを作成 」からルートテーブルを新規作成します。 4. 設定項目を入力し「 ルートテーブルの作成 」をクリックします。 • 名称 : MGMTおよびWAN用とわかる名称 • VPC: 2-2で作成したもの   5. 作成したルートテーブルを右クリックし、「 ルートを編集 」を選択します。 6. 「 ルートを追加 」からルートを追加します。 7.   0.0.0.0/0 を 2-4で作成したインターネットゲートウェイ(IGW)に向けるようルートを追加し保存します。     8. ルートテーブル一覧に戻り、作成したルートテーブルを再度クリックします。 9. 下部にある「 サブネットの関連付け 」タブから、「 サブネットの関連付けを編集 」をクリックします。 10. MGMTとWANの2つのサブネットを選択 し、「 関連付けを保存 」をクリックします。   2-8. AWS設定-ルートテーブルの設定(LAN用) LANサブネットで使用するルートテーブルの設定を行います。 1. 2-7の1~4の手順でLAN用のルートテーブルを作成します。 2. 作成したルートテーブル画面の下部に表示される「 ルート 」タブを表示します。  3. 「 ルートを編集 」からルートを追加します。   4. 0.0.0.0/0 を、先ほど作成したLANインターフェイスのENIに向けるようルートを追加し保存します。 ※この時点ではルートがブラックホールになっていても問題ありません。   2-9. AWS設定‐インスタンスの起動 AMIからインスタンスの起動を行います。 1. AWS Management Consoleのホーム画面で「 EC2 」を選択します。 2. 「 インスタンスを起動 」をクリックします。   vSocketとなるインスタンスの設定を行います。 1. 「 名前 」は任意のものを入力します。 2. 「 インスタンス数 」は1を入力してください。 3. OSイメージの検索欄に「 Cato 」と入力しEnterを押すと、AMIの選択画面に推移します。 4. AMIの選択画面にて「 AWS Marketplace AMI 」を選択します。 5. CatoのAMIが表示されますので、「 選択 」をクリックします。   6. 確認画面が表示されますので、 Cato Networks Virtual Socket であることを確認の上、「 今すぐ購読 」をクリックします。   7. 「 インスタンスタイプ 」はデフォルトで「 c5.xlarge 」が選択されています。 ※Cato社推奨:通常はc5.xlarge、契約帯域が2Gpbs以上の場合はc5n.xlarge 8. 「 キーペア(ログイン) 」より、「 キーペア名 」をクリックします。 9. 既存のキーペアを選択するか、または「 新しいキーペアの作成 」をクリックしてキーペアの作成を行ってください。   10.「 ネットワーク設定 」から「 編集 」をクリックし、設定を行います。 • VPC : vSocketのVPCを選択 • サブネット : MGMT用サブネット を選択 ※他のサブネットを選択すると正しく起動しません • パブリックIP自動割り当て: 「無効化」を選択 • ファイアーウォール : 「既存のセキュリティグループを選択する」 • 共通のセキュリティグループ : 空欄にします 11.「高度なネットワーク設定」をクリックし詳細設定に進みます。 12. ネットワークインターフェイス1の「 ネットワークインターフェイス 」をプルダウンし、 MGMTインターフェイス を選択します。 13.「 ネットワークインターフェイスを追加 」をクリックします。 14.ネットワークインターフェイス2が表示されます。 15.「 ネットワークインターフェイス 」をプルダウンし、 WANインターフェイス を選択します。 ※この指定を誤るとvSocketが接続されません 16.「 サブネット 」の項目で赤文字のエラーが出る場合には、プルダウンし、一番上の「 選択 」を選んでください。 17.さらに「 ネットワークインターフェイスを追加 」をクリックします。 18.ネットワークインターフェイス3が表示されます。 19.「 ネットワークインターフェイス 」をプルダウンし、 LANインターフェイス を選択します。 ※この指定を誤るとvSocketが接続されません 20.「 サブネット 」の項目で赤文字のエラーが出る場合には、プルダウンし、一番上の「 選択 」を選んでください。 以上でネットワークインタフェースの設定は完了です。 ネットワークインターフェース1、2、3がMGMT、WAN、LANの順になっていることを確認し、次の設定に進みます。   21. 「 ストレージを設定 」で、以下のように設定します。 • サイズ : 16GiB • タイプ : gp2 22.「 高度な詳細 」をクリックします。 23.一番下までスクロールし、「 ユーザーデータ 」に1のSite設定で控えた vSocketのシリアル番号(S/N) を入力します。 ※明示している項目以外は、デフォルト値で問題ありません。   24. 設定内容を確認し、「 インスタンスを起動 」をクリックします。   接続確認 vSocketが起動すると、自動でのアップグレードが走り、その後接続状態となります。検証時は、1分ほどで接続が確認できましたが、念のため5~10分程度お待ち下さい。 CMAのSite画面で以下のように「 Connected 」と表示されれば接続成功です。 以上でvSocket構築から接続の確認までが一通り完了しました。 補足として、AWS環境内の内部セグメントに対し、Catoモバイルクライアントから接続を試してみましたので紹介いたします。   補足:AWS内部サーバへの接続確認 今回はvSocketを構築するための最低限の構成(MGMT・WAN・LAN)を作成しましたが、実際にはAWS環境内に既存のサーバセグメントがあると思います。 今回の検証でも 内部サーバーをたて、Catoモバイルクライアントから接続ができるか確認 してみました。 以下追加項目と全体の構成図です。 <追加項目> サブネット:cato-subnet-test(10.10.4.0/24) EC2インスタンス:cato-vsocket-test (10.10.4.42) ルートテーブル:宛先 0.0.0.0/0  ターゲット LAN側ENI ※ルートテーブルのあて先はCatoクラウドを経由したい通信を設定してください。   モバイルクライアントからCatoクラウドに接続した状態で、SSH接続を試したところ、 追加した内部サーバへの接続を確認できました。   注意点 上記の補足確認は、AWSでルーティングを設定するだけではモバイルクライアントの接続が確立されません。 CatoクラウドのSiteに対してもルーティングの設定 が必要です。(私はここの部分がうまくできず、すこし苦戦しました…) 1. CMA上の「 Network 」>「 Networks 」>「 New 」から、ルーティングの設定が行えます。 2. 以下の項目を設定し、「 Apply 」をクリックします。 • Type:Routed • IP Ranges:内部サーバセグメントのIPアドレス範囲 • Gateway:LANサブネットの2つ目のIPアドレス(LANサブネットの範囲が10.10.3.0/24の場合、10.10.3.1) ※サブネット内の最初の4つと最後の1つのIPアドレスは以下のようにAWSに予約されています。 サブネット内の2つ目のアドレスがデフォルトゲートウェイに設定されています。 IPアドレス(例) 用途 .0 ネットワークアドレス .1 デフォルトゲートウェイ .2 DNSサーバー .3 予備 .255 ブロードキャストアドレス   おわりに 今回は、AWS環境でのvSocket構築手順について紹介しました。 本記事がこれから構築を始めようと考えている方々の一助になれば幸いです。 今後は、vSocketの冗長化などにもチャレンジしていきたいと考えています! 最後まで見ていただきありがとうございました!
アバター
こんにちは、SCSKの谷です。 オンプレ、AWS、Azure、Google Cloudといったハイブリッドで利用する環境では、監視対象が増えツールも分散しがちです。 Mackerelのインテグレーションを使えば、AWS・Azure・Google Cloudの標準監視サービスからメトリックを取得し、Mackerel上で一元管理できるため、マルチクラウド及びハイブリッド環境の監視を効率化できます。 以前、AWSのインテグレーションを使った監視を試しましたが、今回はGoogle Cloudのインテグレーションを実際に設定してみました。 Mackerel で AWS のサーバーレスサービスを監視してみた – TechHarmony 今回の記事では、Google Cloudインテグレーションの設定方法と実際にMackerelの管理画面でどのように見えるのかをご紹介します。 ぜひ最後までご覧ください! ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー 当部署では他にも記事を投稿していますので、よかったらご覧ください。 MackerelでSNMP監視を検証してみた – TechHarmony MackerelでAmazon Connectを監視してみた – TechHarmony ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー 監視対象について 今回監視対象としたのは、以下のサービスのリソースになります。 ・Compute Engine   仮想マシンを提供するIaaSサービスで、自由度の高いインフラ構築が可能 ・App Engine      アプリケーションを自動スケーリングするPaaSサービスで、                                   コードをデプロイするだけで運用できる ・Cloud SQL                フルマネージドなリレーショナルデータベースサービスで、                                    MySQLやPostgreSQLなどを簡単に利用可能 上記のサービスを選択した理由としては、2025年10月現在Mackerelでメトリックを収集することが可能なGoogle Cloudのサービスが上記3つのためです。 各サービスのリソースについては監視を実装するためにデプロイしており、最低限のスペックのものを使用しております。 MackerelでのGoogle Cloudインテグレーション設定手順 MackerelでGoogle Cloudのインテグレーションを利用して監視するための手順を説明していきます。 Mackerel上でGoogle Cloudのインテグレーションを設定するためには、事前にGoogle Cloud側で準備が必要となります。 内容としては同じですが、Google Cloud側の事前準備の方法として以下の2パターンがあります。 ・Cloud SDKを用いた連携方法 →Cloudshellを用いた方法。CLIを利用して設定するためGoogle Cloudに慣れている人におすすめです。 ・Google Consoleを用いた連携方法 →上記の通りGoogle Consoleを利用した方法です。GUIであるため分かりやすくGoogle Cloudに慣れていない人にもおすすめです。 私はGoogle Cloudを触るのが今回が初めてだったので、「Google Consoleを用いた連携方法」で事前準備を実施しました。 ここからは、Google Cloudの事前準備の手順の説明後、Mackerel上でのインテグレーション設定の登録方法を説明していきます。 Cloud APIの有効化(Google Cloud) まずはじめにMackerelにデータ連携するために必要なGoogle CloudのCloud APIを有効化します。 (1)Google Consoleへログインし、「APIライブラリ」に移動します。 (2)以下のCloud APIを有効化します(今回はすべて有効化しました) 必須 Cloud Resource Manager API   必須 Cloud Monitoring API   任意 Compute Engine API Compute Engineインスタンスの監視が必要な場合 任意 Cloud SQL Admin API Cloud SQLインスタンスの監視が必要な場合 任意 App Engine Admin API App Engineサービスの監視が必要な場合 サービスアカウント作成(Google Cloud) Mackerelがメトリックを取得するためのサービスアカウントを作成していきます。 (1)「IAMと管理>サービスアカウント」を選択し、サービスアカウントの管理画面を開きます。 (2)上部にある「サービスアカウントを作成」を選択します。 (3)必要な上を入力し、サービスアカウントを作成します。 ・サービスアカウント名 ・サービスアカウントID ・サービスアカウントの説明(任意) (4)Mackerelがメトリック取得に必要なロールを付与します。 必須 参照者   必須 モニタリング閲覧者   任意 Compute 閲覧者 Compute Engineインスタンスの監視が必要な場合 任意 Cloud SQL 閲覧者 Cloud SQLインスタンスの監視が必要な場合 任意 App Engine 閲覧者 App Engineサービスの監視が必要な場合 (5)完了ボタンを押し、サービスアカウントの設定を完了する。 サービスアカウントキー発行(Google Cloud) MackerelとGoogle Cloud間の認証のためのキーを発行します。 (1)作成したサービスアカウントの管理画面を開きます。 (2)「鍵」のタブを開き、「キーの追加>新しい鍵の作成」を選択します。 (3)キーのタイプとして「JSON」を選択し、「作成」ボタンをクリックします。 (4)作成後、秘密鍵のJSONファイルがローカルにダウンロードされます。 以上でGoogle Cloud側の設定が完了になります。ここからMackerel上でGoogle Cloudインテグレーションの設定をしていきます。 Google Cloudインテグレーション設定(Mackerel) 続いてMackerelの管理画面上でGoogle Cloudインテグレーション設定を登録していきます。 (1)Mackerelの管理画面に入り、Google Cloud インテグレーションタブを開きます。 (2)「新しいGoogle Cloudインテグレーション設定を登録」ボタンを選択します。 (3)プロジェクトの設定に連携対象のGoogle Cloudのプロジェクトコード及び先ほど作成したJSON形式の秘密鍵の中身をペーストします。 (4)メトリックを収集するサービスを選択し、作成ボタンをクリックします。 ※メトリック選択時に好きなサービス/ロールを紐づけることができます。 連携確認 以上でGoogle Cloudインテグレーションの設定は完了です。 Mackerel上でGoogle Cloudインテグレーションの設定直後の状態を見てみましょう。 ここまでの手順が完了すると、自動でMackerelにGoogle Cloud上のリソース情報が連携され管理画面の「ホスト」のところですぐに確認することができます。 以下の画像は今回Google Cloudで作成したリソースをMackerelの管理画面上のホスト一覧で表示したものです。 クラウドインテグレーションソートをすることにより、対象を絞っております。 今回作成したホストに対応するサービスは以下の通りです。 サービス名 ホスト名 App Engine 20251001t062902.default Compute Engine vm-demo-1 Cloud SQL pg-demo-1 Mackerel上での監視メトリック確認 初めてでしたが、設定作業はつまずくことなく設定することができました。 ここからは、Google Cloudから連携されたデータがMackerel上でどのように見えているかをサービスごとに載せていきます。 Mackerel上でのメトリック確認方法 Mackerelの管理画面から各ホストのメトリックデータのグラフを確認するためには、ホスト一覧から確認したい対象のホスト名をクリックすることで、メトリックデータ一覧の画面に遷移します。 メトリックデータ一覧の画面は以下のようになります。 Google Cloudから取得したホストの概要が載っております。画像では途切れていますが、初期状態ではMackerelの管理画面上で表示可能な全てのグラフが並んでおります。表示するグラフについては管理画面で調整可能です。 Compute Engine Mackerelでは様々なCompute Engineのメトリックを取得することが可能です。 MackerelからCompute Engineのリソースのメトリックを取得するには、「Compute Engine API」のAPIが有効化されている必要があります。 また、連携用のサービスアカウントに対して、「Compute 閲覧者」のロールを付与している必要がございます。 以下は代表的なメトリックになります。 グラフ名 メトリック 説明 CPU instance/cpu/utilization インスタンスのCPU使用率。負荷監視の基本指標。 Disk bytes instance/disk/read_bytes_count instance/disk/write_bytes_count ディスク読み込み量。I/O性能確認に重要。 ディスク書き込み量。ストレージ負荷の把握に利用。 Network bytes instance/network/received_bytes_count instance/network/sent_bytes_count ネットワークで受信したバイト数。トラフィック監視に使用。 ネットワークで送信したバイト数。外部通信の負荷確認に重要。 Firewall dropped packets count firewall/dropped_packets_count ファイアウォールでドロップされたパケット数。セキュリティ監視に重要。 Mackerelの画面で確認したところ合計11個のグラフが表示されていました。 今回はその中のCPUグラフをお見せします。 CPUの使用率を可視化したグラフとなっており単位は「%」です。今回16:25~16:35の時間帯にstressコマンドをVM上で実行し、CPUの使用率を意図的に上げ正しくメトリックが連携されているか確認しました。 App Engine MackerelからApp Engineのメトリックを取得するには、「App Engine Admin API」のAPIが有効化されている必要があります。 また、連携用のサービスアカウントに対して、「App Engine 閲覧者」のロールを付与している必要がございます。 理由が不明のため、偶々なのかもしれませんが、App Engineだけはインテグレーションを設定してからMackerelの管理画面のホスト上に表示されるまで他の2サービスと比べて時間がかかりました。(約20分くらい) 時間がたてば表示されメトリックが連携されていたので、連携されてこない場合でも30分程度待つことをおすすめします! 以下は代表的なメトリックになります。 グラフ名 メトリック 説明 CPU Usage system/cpu/usage インスタンスのCPU使用量。負荷監視の基本指標。 Memory usage system/memory/usage メモリ使用量。リソース不足やスケーリング判断に重要。 HTTP DoS intercept http/server/dos_intercept_count DoS攻撃を検知・遮断した回数。セキュリティ監視に重要。 HTTP Response count http/server/response_count HTTPレスポンス数。アプリのリクエスト処理量を把握。 Mackerelの画面で確認したところ合計8個のグラフが表示されていました。 今回はこの中のHTTP Response countグラフをお見せします。 こちらのグラフはHTTPレスポンス数を可視化したグラフになります。 初期の状態だとApp Engine宛へのアクセスがなかったため、Google Cloudから取ってくるメトリックが存在せず、グラフが表示されない状態でした。12時頃に繰り返しアクセスすることにより、以下のようにグラフが表示され正しくメトリックが連携できていることを確認できました。 Cloud SQL MackerelからCloud SQLのメトリックを取得するには、「Cloud SQL Admin API」のAPIが有効化されている必要があります。 また、連携用のサービスアカウントに対して、「Cloud SQL 閲覧者」のロールを付与している必要がございます。 以下は代表的なメトリックになります。 使用するDB(MySQLやPostgerSQL)により取得可能なメトリックに違いがあり、 今回はPostgerSQLを使用したので、PostgerSQLのメトリックを記載しております。 グラフ名 メトリック 説明 CPU database/cpu/utilization データベースのCPU使用率。負荷監視の基本指標。 Memory database/memory/usage database/memory/quota  メモリ使用量と割り当て容量。リソース不足の検知に重要。 Connections database/network/connections データベース接続数。接続プールやスロット枯渇の検知に利用。 PostgreSQL transaction database/postgresql/transaction_count  PostgreSQLのトランザクション数。処理負荷の把握に利用。 Mackerelの画面で確認したところ合計10個のグラフが表示されていました。 今回はこの中のPostgreSQL transactionグラフをお見せします。 こちらのグラフはPostgreSQLのトランザクション数を可視化したグラフになります。   まとめ 今回、MackerelのGoogle Cloudインテグレーションを使って監視を設定してみましたが、手順は非常にシンプルで、他クラウドと同様に迷うことなく進められました。初めての方でも問題なく導入できると思いますので、より詳しい内容を知りたい方は、公式のヘルプを確認してみることをお勧めします。 Google Cloudインテグレーション – Mackerel ヘルプ 設定後、App Engineのリソースがホスト一覧に表示されず少し戸惑いましたが、事前に認識しておけば大丈夫です。 他のクラウドサービスと比べると、現状Mackerelで監視できるGoogle Cloudのサービスはまだ3つのみです。Google Cloudの強みは機械学習やAI系のサービスなので、そのようなサービスも監視できるようになればいいなと思います。便利な機能だからこそ、さらに対応サービスが増えることに期待です。今後のはてなさんの動きに注目してください! 今後もMackerelに関する記事を投稿していきますので、よろしくお願いします!
アバター
こんにちは、山崎です。 最近、クラウドセキュリティに関する情報を調べていた中で、Cloud Security Alliance(CSA)が発表した「クラウドコンピューティングに対する重大な脅威 2024」レポートに出会いました。本記事ではその内容をもとに、クラウド環境における代表的なリスクと、実務で意識すべき対策のヒントを整理してご紹介します。 クラウドの活用はどんどん進んでいますが、利便性と引き換えに「セキュリティ」は常に意識すべき課題となっています。特にパブリッククラウドでは、どこにリスクが潜んでいるのかを正しく理解しておくことが、安全な運用の第一歩だと感じています。 クラウドコンピューティングに対する重大な脅威 2024 とは 「クラウドコンピューティングに対する重大な脅威 2024」は、クラウドを利用するうえで注意すべき最新のセキュリティリスクをまとめた国際的な報告書です。世界中の専門家への調査をもとに、実際に起きているトラブルや攻撃の傾向を分析し、「クラウドを安全に使うために何を気をつけるべきか」をわかりやすく整理しています。 たとえば、設定ミスによる情報漏えい、アクセス権限の管理ミス、不十分なAPIセキュリティ、サプライチェーン経由の攻撃、そしてAIや自動化の不適切な利用などが、近年の主要な脅威として挙げられています。これらの問題は、企業のセキュリティチームだけでなく、クラウドを使うすべてのユーザーに関係する内容です。 CSAの報告書では、それぞれの脅威について「なぜ起きるのか」「どんな影響があるのか」「どう防ぐべきか」を具体的に説明しており、クラウドの導入や運用を行う際の指針として役立ちます。初心者にとっても、クラウド利用のリスクを理解し、安全な運用の重要性を学ぶための入門資料となっています。   CSA(Cloud Security Alliance)とは Cloud Security Alliance(CSA) は、クラウドコンピューティングの安全性を高めることを目的とした国際的な非営利団体です。2009年に設立され、企業や政府、教育機関などがクラウドサービスを安全に利用できるように、ベストプラクティスやガイドラインの提供、調査研究、認証制度などを行っています。   「クラウドコンピューティングに対する重大な脅威2024」ランキング CSA(Cloud Security Alliance)が2024年に発表した「クラウドコンピューティングに対する重大な脅威」は、クラウド利用者が直面するリスクを体系的に整理したものです。本レポートでは、脅威ごとに具体的な事例や影響も記載されており、セキュリティ担当者にとって非常に有益なものになっていますので興味のある方は、以下のリンクから詳細をご覧ください。 [クラウドコンピューティングに対する重大な脅威2024]  Top Threats to Cloud Computing 2024 20240805   以下に、2024年版で取り上げられた11の主要な脅威を簡潔にまとめました。 順位 項目名 説明 1位 設定ミスと不適切な変更管理 クラウド環境の設定ミスや変更管理の不備により、意図しない情報漏洩や攻撃のリスクが高まります。 2位 アイデンティティとアクセス管理(IAM) 不適切な認証・認可設定により、内部・外部からの不正アクセスが発生する可能性があります。 3位 セキュアでないインターフェースやAPI 脆弱なAPI設計や管理不足により、攻撃者に悪用されるリスクが存在します。 4位 クラウドセキュリティ戦略の不適切な選択と実施 クラウド特有のリスクを考慮しない戦略では、セキュリティ対策が機能しません。 5位 セキュアでないサードパーティーリソース 外部ベンダーやサービスのセキュリティが不十分な場合、サプライチェーン攻撃の温床になります。 6位 セキュアでないソフトウェア開発  セキュリティを考慮しない開発プロセスは、脆弱性を含むアプリケーションを生み出します。 7位 偶発的なクラウドデータ公開 設定ミスや操作ミスにより、意図せず機密情報が公開されることがあります。 8位 システムの脆弱性 既知の脆弱性が放置されていると、攻撃者に悪用されるリスクが高まります。 9位 限定的なクラウド可視性/可観測性 クラウド環境の挙動を十分に把握できないと、異常検知や対応が遅れます。 10位 未認証のリソース共有 アクセス制御が不十分な共有設定により、情報漏洩のリスクが高まります。 11位 APT攻撃(高度持続的脅威) 長期間にわたって標的を監視・攻撃するAPTは、検知が難しく深刻な被害をもたらします。   重大脅威への対応策 ここでは、本レポートの上位3つの脅威に対して、組織が取るべき基本的な対策を簡潔にまとめます。これらの脅威は、クラウド環境におけるセキュリティ事故の多くに関係しており、早急な対応が求められます。   1. 設定ミスと変更管理の不備への対策 自動化されたセキュリティスキャンツール(例:AWS Config)を導入し、設定ミスを検出。 変更管理プロセスにセキュリティレビューを組み込み、変更前にリスクを確認する体制を整える。   2.ID・アクセス管理の不備への対策 最小権限の原則を徹底し、不要な権限を排除。 多要素認証(MFA)の全社的な導入。 定期的なアクセス権レビューと監査ログの分析を実施。   3.安全でないAPIとインターフェースへの対策 APIゲートウェイを活用し、認証・認可・レート制限を適用。 セキュリティテスト(例:OWASP API Security Top 10に基づく)を開発プロセスに組み込む。 APIキーやトークンの管理を厳格に行い、漏洩時には即時無効化できる体制を整備。   まとめ 調べてみた結果、クラウドセキュリティにおいて最も重要なのは「基本の徹底」だと改めて感じました。 しかしながら、この対策は人力のチェックだけではなかなか難しいとも思いました。なぜなら、人は必ずミスをするものだからです。 そのため、CSPM(Cloud Security Posture Management)製品を導入することが、より効率的に・確実に脅威へ対応する有効な方法だと思います。 CSPMを導入することで、自社の現状を正しく把握し、小さな改善から着実に取り組むことが、クラウド環境の安全性を高める第一歩になると考えています。 当社では、複数クラウド環境の設定状況を自動でチェックし、設定ミスやコンプライアンス違反、異常行動などのリスクを診断するCSPMソリューションを販売しております。 マルチクラウド設定診断サービス with CSPM| SCSK株式会社 マルチクラウド環境のセキュリティ設定リスクを手軽に確認可能なスポット診断サービスです。独自の診断レポートが、運用上の設定ミスや設計不備、クラウド環境の仕様変更などで発生し得る問題を可視化し、セキュリティインシデントの早期発見に役立ちます。 www.scsk.jp ご興味のある方は是非、お気軽にお問い合わせください。
アバター
こんにちは、クラウドサービス関連の業務をする予定の Yabu です。   社会人 1 年目として AWS や Google Cloud など、主要クラウドサービスの学習と認定資格取得を目指しています。 本記事では、認定資格取得中の方やこれから取得し始める方に向けて、試験の例題を基に、解き方の工夫と知識を深める方法を入門者なりにまとめてみました。 AWS 認定の問題を例に、 たった一問からどのように理解を深められるか、どのようなことが考えられるか を考えてみました。 例題 早速ですが、例題です。 特定の AWS リージョンにおいて、Web アプリケーションが Application Load Balancer(ALB)の後ろの Amazon EC2 インスタンスで稼働しています。この EC2 インスタンスは、1 つのアベイラビリティゾーン内の EC2 Auto Scaling グループで稼働しています。 Web アプリケーションの可用性を向上するために何をすべきですか? ※本来は、複数の選択肢が表示されていますが、以下に正解例のみ示します。 正解例(クリックで展開) Auto Scaling グループを更新し、同じリージョンの 2 つ目のアベイラビリティゾーンに新規インスタンスを配置する。 今回の記事では、正解についてはあまり説明しません。 この例題を基にして、理解をより深める方法を 5 つ考えてみたので紹介していきます。   アーキテクチャ図 1 つ目は問題が対象とするアーキテクチャ全体や構成要素をイメージすることです。   本例題のアーキテクチャ図は以下のようになります。 Web アプリケーションのユーザーや Application Load Balancer(ALB)、EC2 インスタンスといった主要 AWS サービスから構成されています。 例題のアーキテクチャ   問題の文章のみではなく、主要 AWS サービスがどう連携しているかを可視的に考えてみます。これによって、複雑で長い問題文が出題されたとしても、情報整理や全体の把握がしやすくなります。   正解例の対応を導入すると、以下のようなアーキテクチャに更新されます。 アベイラビリティゾーンが 1 つ追加されたことによって、一方のゾーンに障害が起きたとしても Web アプリケーションの可用性を維持できます。 可用性を向上した例題のアーキテクチャ   問題の分析 例題で問われているのは、「可用性を向上する方法」です。 特定の AWS リージョンにおいて、Web アプリケーションが Application Load Balancer(ALB)の後ろの Amazon EC2 インスタンスで稼働しています。 この EC2 インスタンスは 1 つのアベイラビリティゾーン内の EC2 Auto Scaling グループで稼働しています。 Web アプリケーションの可用性を向上するために何をすべきですか?   クラウド認定資格試験の場合、問題文が長かったり難易度が高い場合は、設問の核心(=「何を答えるべきか」)を明確に再確認することが重要です。さらに、仮に「セキュリティを向上する方法」を聞かれた場合に、どのような正解があり得るのかなども考えると役立つと思います。   例えば「セキュリティを向上する方法」であれば、アベイラビリティゾーンの追加だけではなく、Web 三層構造(Web、アプリケーション、データベース)の導入やファイアウォールルールの強化が考えられます。 Web 三層構造を導入した場合のアーキテクチャ図は、以下のようになります。 Web 三層構造を導入した例題のアーキテクチャ   不正解の選択肢の分析 3 つ目は他の選択肢が不正解になる理由を分析することです。   不正解の選択肢の例として、   インスタンスタイプを高性能なものに変更する Auto Scaling グループのインスタンス最小数を増やす などが挙げられます。 これらの選択肢では、物理的なゾーン障害(アベイラビリティゾーン全体の停止)が発生すると、すべてのインスタンスが停止してサービスを継続できません。そのため、高可用性にはつながらず不正解となります。   学習の方針や時間によっては、不正解の選択肢については分析しなかったり、後回しにしたりすることもあると思います。しかし、正解以外の選択肢も分析することによって、一問からの学習量を大いに増やすことができます。   公式ドキュメントの参照 4 つ目は公式ドキュメントを参考に、問題で出てきたサービスや場面について学習することです。   公式ドキュメントは、正確・最新・網羅的な情報を得ることができます。 問題を解いたことをきっかけに、読んだことのない公式ドキュメントの学習をしたり、部分的に再読したりすることによって、より理解が深まります。類似あるいは関連した問題への対応力向上も期待できます。   例題に関連したものとしては、EC2 や Elastic Load Balancing、Auto Scaling のドキュメントがあります。例えば、例題で問われている複数アベイラビリティゾーンの利用場面については、以下ページが参考になります。   https://docs.aws.amazon.com/ja_jp/autoscaling/ec2/userguide/auto-scaling-benefits.html   ハンズオンによる実現 5 つ目は実践的なハンズオンによって、問題で出てきたサービスの使用やアーキテクチャの実現をしてみることです。   公式ドキュメントを読むだけでなく、実際に手を動かして学習することで、より理解が深まります。忙しい場合は他者の構築記録や手順ブログを参考にするのも効果的です。以下は、AWS の ALB の作成画面です。 ALB の作成画面   まとめ 今回は、AWS 認定資格の問題を題材に、理解を深める具体的な学習方法を 5 つ紹介しました。公式ドキュメントの活用やハンズオンによる体験が、資格取得はもちろん実務で役立つ知識につながります。 今回の内容が学習の参考になれば幸いです。
アバター
こんにちは、2年目の加藤です! 私は現在、データエンジニアとして、Google Cloudを活用したデータの取得や加工、整形などを担当しています。データ取得をCloud Run上でPythonを動かしたり、リソースをTerraformで管理する上で、GitHubを利用しています。前回の記事では、GitHubを利用する上でのGitの概念やGitコマンドを書きましたが、本記事では、共同で開発を行う上でのGitHubの運用方法のお勧めを共有したいと思います。 おさらい 本記事では、ブランチという考えが多くでてきます。ブランチとは、1つのメインのプロジェクトとは異なる分岐を作り、プロジェクト本体に影響を与えずに開発を行える機能のことをいいます。端的に述べると、本番環境やテスト環境、ローカル環境などが一般にありますが、その「環境」のことをブランチと述べているという認識で問題ありません。 ブランチの実際の操作コマンドやGitのコマンド、概念などは 前回の記事 からご覧ください。 共同開発のベストプラクティス GitHubを使用する際に、何でこんなにブランチがあるんだろう?ブランチの運用ルールとかたくさんあって面倒くさい…などと思ったことはないでしょうか?私は思いました。なので、自分なりにブランチについて調べてみました。 ブランチにはブランチ戦略なるものがたくさんあるらしく、開発規模や開発環境によって適切なブランチ運用方法があるそうです。その中でも代表的なブランチ戦略として、下記3つを紹介したいと思います。 GitHub-Flow Git-Flow GitLab-Flow GitHub-Flow GitHub-Flowとは、GitHub社が開発を進める際に用いているワークフローです。登場ブランチとしては、2種類だけでとてもシンプルで分かりやすいものとなっています。具体的なブランチイメージ図は下記の通りです。 mainブランチ 本番環境にリリースするためのブランチ 常にリリースできる状態を保っているブランチ featureブランチ 各ユーザがそれぞれ開発を行うためのブランチ mainブランチからブランチを切り出し、開発が終わったらmainブランチへマージする mainブランチへの直接のプッシュは禁止で、mainブランチへマージする際にプルリクエストを送り、コードレビューが通るとマージすることができる GitHub-Flowの特徴は以下のものが挙げられます。 メリット デメリット シンプルなフローで理解しやすい 運用ルールが少ない 本番へのリリースが細かいスパンででき、開発を迅速に進めることができる 複数バージョンの並行管理ができない 本番環境の品質保証維持が大変 厳密なリリース計画を立てにくい GitHub-Flowの開発サイクル例は下記のようになっています。 mainブランチから、各ユーザの開発用作業ブランチ(feature)を作成する featureブランチで開発をする 作業が完了したら、コミット&プッシュをし、プルリクエストを作成、開発チームメンバーにコードレビューを依頼する レビューが承認されたらfeatureブランチをmainブランチへマージする mainブランチへマージ後ただちにデプロイをする Git-Flow Git-Flowとは、2010年にVincent Driessen 氏が提唱したワークフローです。GitHub-Flowとは異なり、主に5種類のブランチが登場します。具体的なブランチイメージ図は下記の通りです。 mainブランチ 本番環境にリリースするためのブランチ 常にリリースできる状態を保っているブランチ hotfixesブランチ 本番環境の緊急のバグ修正用ブランチ mainブランチから作成されるブランチ mainブランチと同時にdevelopブランチへマージさせる releaseブランチ 本番環境へリリースする前の最終確認を行うブランチ developブランチから作成されるブランチ 軽微なバグ修正、ドキュメントの更新などを行い、新機能は開発しない mainブランチと同時にdevelopブランチへマージさせる developブランチ 開発用のブランチ mainブランチから作成されるブランチ featureブランチのマージ先となる featureブランチ 各ユーザがそれぞれ開発を行うためのブランチ developブランチから作成されるブランチ developブランチにマージする Git-Flowの特徴は以下のものが挙げられます。 メリット デメリット 複数バージョンの並行管理ができる 本番環境の品質保証がしやすい 計画的なリリースができる Gitの履歴が整理され、追跡しやすい 運用が複雑で学習コストが高い コード同士のコンフリクトが起こりやすい リリースまでに時間がかかる プルリクエストひとつひとつが肥大化しやすい Git-Flowの開発サイクル例は下記のようになっています。 【新機能開発から本番環境へのリリース】 developブランチから、各ユーザの開発用作業ブランチ(feature)を作成する featureブランチで開発作業を行う 作業が完了したら、コミット&プッシュをし、プルリクエストを作成、開発チームメンバーにコードレビューを依頼する レビューが承認されたらfeatureブランチをdevelopブランチへマージする 不要になったfeatureブランチを削除する developブランチからreleaseブランチを作成 releaseブランチでリリース準備作業を行う リリース準備完了後、mainとdevelopにマージ mainへのマージに対して、マージしたコミットにバージョン番号のタグを付けます。 不要になったreleaseブランチを削除する GitLab-Flow GitLab-Flowとは、GitLab社が提唱しているワークフローです。Git-FlowとGitHub-Flowの中間的な位置づけのワークフローで、Git-Flowを少しシンプルにしたものです。GitLab-Flowに登場するブランチは主に4種類です。具体的なブランチイメージ図は下記の通りです。 mainブランチ 常にリリースできる状態を保っているブランチ productionブランチ 本番環境にリリースするためのブランチ 一度ブランチを作成したら削除しない pre-production/stagingブランチ リリース前の最終確認を行うブランチ mainブランチから作成されるブランチ 動作確認やテストを行う 一度ブランチを作成したら削除しない feature/hotfixesブランチ mainブランチからブランチを切り出し、開発が終わったらmainブランチへマージする 緊急のバグ修正もこのブランチで行う GitLab-Flowの特徴は以下のものが挙げられます。 メリット デメリット 比較的フローがシンプルで理解しやすい 本番環境の品質保証がしやすい 各環境が明確に分けられているので、デプロイやテストがしやすい productionブランチやpre-productionブランチでのコンフリクトが起こりやすい リリースまでに時間がかかる バグ修正に時間がかかる GitLab-Flowの開発サイクル例は下記のようになっています。 【新機能開発から本番環境へのリリース】 mainブランチから、各ユーザの開発用作業ブランチ(feature)を作成する featureブランチで開発作業を行う 作業が完了したら、コミット&プッシュをし、プルリクエストを作成、開発チームメンバーにコードレビューを依頼する レビューが承認されたらfeatureブランチをmainブランチへマージする 不要になったfeatureブランチを削除する (pre-productionブランチが未作成の場合)mainブランチからpre-productionブランチを作成 (pre-productionブランチが作成済の場合)mainブランチからpre-productionブランチへのプルリクエストを作成 レビューが承認されたらmainブランチをpre-productionブランチへマージする pre-productionブランチで最終確認を行う (pre-productionブランチが未作成の場合)最終確認完了後、mainブランチからproductionブランチを作成 (pre-productionブランチが作成済の場合)最終確認完了後、mainブランチからproductionブランチへのプルリクエストを作成 結局どれがいいの? 各ブランチ戦略とその特徴、ユースケースを下記に示します。 ブランチ戦略 特徴 ユースケース GitHub-Flow シンプルなワークフロー 複数リリースの並行管理ができない チーム規模が小さく、頻繁にリリースを行うプロジェクトの場合 Git-Flow 複雑なワークフロー リリースを厳格に管理することができる チーム規模が大きく、計画的に長期リリースするプロジェクトの場合 GitLab-Flow Git-FlowとGitHub-Flowの中間的な位置づけのワークフロー デプロイやテストをやりやすくしつつ、本番環境コードの品質をある程度担保したい場合 どれを使えばいいかは基本的にチームの規模やリリースサイクル、品質管理の厳密さなどによって変わってきますので、どれがいいとは言えず、ケースバイケースです。しかし、私個人の意見としては、GitLab-Flowをお勧めします。その理由としては、ある程度の品質保証を行いながらも、シンプルなワークフローで運用できるため、導入もそんなに大変ではないと考えるためです。GitHub-Flowはわかりやすいですが、私見に基づくに、本番環境へのバグ混入が多々見られたり、Git-Flowでは運用フローが複雑すぎて、学習コストが高く使いにくい印象を受けました。 まとめ 今回は、GitHubを共同開発で使用する際のブランチ戦略について紹介させていただきました。 本記事では、ブランチ戦略として3種類紹介いたしましたが、他にもあるのでご興味のある方は調べてみてください。 自分たちのプロジェクトに合うブランチ戦略を見つけ、効率的な開発を実現しましょう。
アバター
こんにちは、2年目の加藤です! 私は現在、データエンジニアとして、Google Cloudを活用したデータの取得や加工、整形などを担当しています。データ取得をCloud Run上でPythonを動かしたりすることがあるのですが、Pythonコードの品質担保のためにコードレビューを行っています。しかし、コードレビューだけではバグを見落としたり、コードレビュー者の経験や実力に依存したものとなってしまいます。そのため、私たちはSonarQubeを使用することでコードの品質を担保しています。そこで、本記事ではSonarQubeについて紹介したいと思います。 本記事でわかること SonarQubeの概要 SonarQubeでできること SonarQubeのCI連携方法 SonarQube Cloudとは ソフトウェアのコード品質とセキュリティを継続的に分析・評価するためのオープンソースのプラットフォームです。 SonarQube Cloudには下記のような特徴があります。 多くのプログラミング言語に対応 自動分析が可能で、導入が容易 コード品質の要件を自在に定義できる CIパイプラインとの統合が容易にできる SonarQube Cloudを導入することで、コード品質とセキュリティをコード変更のたびに自動的にチェックすることができ、コードの品質基準を容易に担保をすることができます。 SonarQube詳細内容 SonarQubeにはデフォルトで設定されているコード品質の要件があります。 評価指標 基準 説明 Reliability Rating A以上 コードのバグの数 A = バグなし B = 軽微なバグが1つ以上 C =メジャーなバグが1つ以上 D = クリティカルなバグが1つ以上 E = 最重要なバグが1つ以上 Security Rating A以上 脆弱性が検知された件数 A = 脆弱性なし B = 軽微な脆弱性が1つ以上 C =メジャーな脆弱性が1つ以上 D = クリティカルな脆弱性が1つ以上 E = 最重要な脆弱性が1つ以上 Maintainability Rating A以上 技術的負債の開発比率: 開発するためにかかる推定コストと、将来的に修正や改善が必要となる問題点のコストの比率 A ≤ 5% B ≥ 5% to <10% C ≥ 10% to <20% D ≥ 20% to < 50% E ≥ 50% Security Hotspots Reviewed 100%以上 発見されたセキュリティ上の懸念点(ホットスポット)のうち、どれくらいの割合がすでに確認・検討されたかを表す指標 Coverage (テスト網羅率) 80%以上 単体テストによってカバーされたコードの割合 Duplicated Lines (重複コード率) 3.0%以下 ソフトウェアのコード全体の中で、どれくらいの割合のコードが重複しているかを示す指標 SonarQube Cloudでは、単体テストまではサポートしていないので、サードパーティーの単体テストツール(Pytest、Jestなど)を使用して評価する必要があります。 SonarQubeのCI連携方法 モチベーション GitHubで管理しているコードをローカル上で、脆弱性の手動スキャンを行わなくても、GitHubへのプッシュをトリガーに自動で脆弱性スキャンをしてくれるようにしたい 脆弱性だけではなく、単体テストのカバレッジ結果もひとつの統合サービスから閲覧できるようにしたい 前提 CIツールとして、本記事ではGitHubとGitHub Actionsを使用します SonarQubeにてアカウントが作成されていること GitHubアカウントが作成されていること 手順 【SonarQube Cloud 導入方法】 詳細はこちら: SonarQube Cloud: 開発者ガイド |ソナー SonarQube Cloud にサインアップする サインアップは、GitHubのアカウントを使用してサインアップすることができます。 GitHubから組織をインポートするために、[Import an organization]を押下する 下記から、インストールするGitHubリポジトリを選択し、[Save]を押下する All repositories Only select repositories 「Create an organization」に移動後、組織の名前とキーを決定する 無料プランを選択する [Create Organization]を押下する 「Analyze projects」で脆弱性スキャン・単体テストを行いたい、リポジトリを選択する 上記で、SonarQube Cloudの初期設定は完了です。 【SonarQube Cloud CIへの適用方法】 CI(GitHub Action)で使用するトークンをSonarQube Cloudで発行する SonarCloudの画面右上の自分のアイコン > [My Account] > [Security] に移動します。「Generate Tokens」 で、トークン名(例: GITHUB_ACTIONS_TOKEN)を入力し、[Generate] を押下します。生成されたトークンをコピーして安全な場所に一時保管します。 SonarQube Cloudの下記情報をメモしておく キー 説明 Organization Key SonarCloudの組織名(通常はGitHubの組織名やユーザー名) Project Key SonarCloudがリポジトリに対して自動生成したキー(通常は GitHubユーザー名_リポジトリ名 のような形式) トークンをGitHub上のシークレットに登録する GitHubリポジトリに移動し、[Settings] > [Secrets and variables] > [Actions] を選択します。[New repository secret] を押下し、Name に「SONAR_TOKEN」 を入力します。Secretに先ほどSonarCloudで生成・コピーしたトークンを貼り付け、[Add secret] を押下します。 2でメモしたキーをGitHub上の変数として登録する [Settings] > [Secrets and variables] > [Actions] > [Variables] を選択し、[New repository variables]を押下します。 Name に「SONAR_ORGANIZATION」を入力し、Valueに先ほどメモしたキーを貼り付け、[Add variable]を押下します。同様にして、「Project Key」も変数として登録します。 GitHub Actionsのワークフローファイルを作成する GitHubリポジトリの[Actions]タブを選択し、Simple workflowの[configure]を押下します。 CI/CDを設定したいGitHubリポジトリのルートに、  .github  という名前のディレクトリを作成し、さらにその中に  workflows  という名前のディレクトリを作成します。GitHub Actionsはこのディレクトリ内のYAMLファイルを自動的に認識し、ワークフローとして実行してくれます。上記を手順5を行うことでディレクトリを自動で作成してくれます。 コードの単体テストを実施しない場合)ワークフローを定義する SonarQubeを動作させるための以下コードをコピー&ペーストし、[Commit changes…]を押下します。 name: SonarQube Scan on: pull_request: types: [opened, reopened, ready_for_review, synchronize] jobs: sonar_qube_scan: runs-on: ubuntu-latest name: SonarQube Scan steps: # リポジトリのソースコードをチェックアウト - name: Checkout uses: actions/checkout@v4 # SonarQubeスキャンを実行(カバレッジレポート無) - name: SonarQube Scan uses: SonarSource/sonarqube-scan-action@v4 env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} with: args: > -Dsonar.projectKey=${{ vars.SONAR_PROJECT_KEY }} -Dsonar.organization=${{ vars.SONAR_ORGANIZATION }} on では、ワークフローのトリガー条件を記載します。今回の場合では、プルリクエストが作成、再作成、ドラフト状態からレビュー待ち、コミットされた際に動作するように設定してあります。 jobs では、実際のワークフローを定義します。 (コードの単体テストを実施したい場合)ワークフローを定義する SonarQubeを動作させるための以下コードをコピー&ペーストし、[Commit changes…]を押下します。今回は、例としてJavaScriptコードを単体テストツールJestを使用して評価しています。 name: Run JavaScript Unit Tests on: pull_request: types: [opened, reopened, ready_for_review, synchronize] jobs: unit-tests-with-jest: name: unit tests with jest runs-on: ubuntu-latest steps: # 1. リポジトリのコードを取得 - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 # 2. Node.js 環境のセットアップ - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 18 # 3. Jestをインストール - name: Install Jest run: npm install --save-dev jest # 4. カバレッジレポートをcoverage/lcov.infoに出力 - name: Generate lcov report run: npm test -- --coverage --coverageDirectory=coverage --coverageReporters=lcov # 5. SonarQubeにカバレッジレポートを送信 - name: SonarQube Scan uses: SonarSource/sonarqube-scan-action@v4 env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} with: args: > -Dsonar.projectKey=${{ vars.SONAR_PROJECT_KEY }} -Dsonar.organization=${{ vars.SONAR_ORGANIZATION }} -Dsonar.sources=src -Dsonar.javascript.lcov.reportPaths=coverage/lcov.info 上記で、GitHub Actionsのワークフロー設定は完了です。 実行結果は下記のようになります。GitHub Actions上のワークフローでチェックマークが表示されていれば、解析が問題なく完了していることを表しています。SonarQubeスキャンログを下の方までいくと、SonarQube CloudへのURLが出力されており、そこから解析結果に遷移することができます。 まとめ 今回は、SonarQube Cloudのご紹介をさせていただきました。 最近、開発だけではなく、品質の担保も重要だということを学び、このサービス一つで全部できるじゃん!と改めて世の中便利なサービスが多いことを実感しました。 アプリ開発を担当している方は一度、コードの品質保証のためにSonarQubeの導入を考えてみてはいかがでしょうか?
アバター
皆さんこんにちは! ゲームを作るのもPythonもほとんど初心者ですが、AIの力を借りて挑戦してみました。 どうも、安藤です。 今年の6月、Amazon Web Services, Incが主催する『Amazon Q CLI でゲームを作ろう Tシャツキャンペーン』というイベントをきっかけに、Amazon Q CLIとChatGPTを使って、試しにダンジョン探索型RPGを作ってみました。 ルールとして「Amazon Qが生成したコードをそのまま使う(手動修正しない)」という制約があったので、どこまで動くものが作れるのかを実験する形です。 正直、私はゲームを作ったこともなく、ゲームプログラムの構造もよくわかっていません。 それでも、AIの力を借りればどこまでできるのか、興味本位で3日間やってみたところ、意外と動くゲームができてしまいました。 この記事では、そんな“素人の手探り体験”を通して、 Amazon Q CLIの導入でつまずいたところ 実際にAIでゲームを作ってみて感じた難しさ ChatGPTによるサポートでどう前に進めたか を、できるだけわかりやすく紹介していきます。 あくまで試しながらの学びですが、同じようにAIを使ってみたい方の参考になれば嬉しいです。   DAY1:AI開発のための環境づくり ― Ubuntu・Python・Pygameの壁を越えて Amazon Qを使ってコードを生成するには、まずPC上に動作環境を整える必要があります。 これが思った以上に大変で、最初は何度もつまずきました。 せっかくなので、どんな手順で構築したのかをここでまとめてみたいと思います。   (1)WSL2とUbuntuの導入 Amazon Q CLIを使うにはLinux環境が必要です。 Windows上でもLinuxを動かせるようにするため、まず WSL2(Windows Subsystem for Linux 2) を利用します。 PowerShellを開き、以下のコマンドを実行します。 wsl このコマンドを初めて実行する場合、Windowsが自動的にWSL2を有効化し、既定のディストリビューションとして Ubuntu をインストールします。 インストール後、自動的にUbuntuが起動し、初回セットアップ(ユーザー名とパスワードの設定)が始まります。 一度Ubuntuを導入すれば、次回からは以下のようにして直接Ubuntuを起動できます。 wsl -d Ubuntu ここで -d オプションは「どのディストリビューションを起動するか」を指定するもので、複数のLinux環境(例:DebianやKaliなど)を導入している場合でも、確実にUbuntuを選んで起動できます。 初回セットアップで作成したUbuntuユーザーは、Linux内で sudo apt install など管理者権限の操作を行う際に使用します。 これで、Windows上にLinuxターミナル環境が整い、以降の作業をこのUbuntu上で進められるようになりました。   (2) Python 環境と仮想環境(venv)の準備 Amazon Q CLI自体は独立したツールとして動作しますが、今回はゲームの実効環境にPythonを使うため、Python環境の準備をします。 Ubuntuを最新化した上で、Pythonと必要なパッケージをインストールしました。 sudo apt update && sudo apt upgrade -y sudo apt install python3 python3-pip python3-venv git -y 続いて、作業用ディレクトリを作成し、仮想環境を有効化します。 mkdir ~/game-dev && cd ~/game-dev python3 -m venv venv source venv/bin/activate 仮想環境を有効にしておくことで、システム全体に影響を与えずに開発できます。 再開時は、再度 source venv/bin/activate を実行するだけです。 (3) Pygame の導入 ゲーム開発にはPygameが必須なので、仮想環境の中でインストールします。 pip install pygame 最初の試行ではエラーが出たので、エラーメッセージを確認しながら、必要なライブラリを個別に追加していきます。 sudo apt install libsdl2-dev  # ベースのSDLライブラリ  sudo apt install libsdl2-image-dev  # 画像処理用  sudo apt install libsdl2-ttf-dev    # 文字描画用 Pygameが正しく動作するようになると、いよいよAmazon Qで生成されたコードを試す準備が整います。   (4) Amazon Q CLIの導入 Amazon Q CLIのインストールには AWS Builder ID が必要でした。 公式ページで登録を済ませ、案内に従ってインストールスクリプトを実行します。 当時はPowerShell上で以下を試しましたが、Windows環境ではエラーになりました。 curl -s "https://aws.amazon.com/q/dev/docs/install/cli/" | bash 「httpsドライブが存在しません」というメッセージが出たため、 Ubuntu環境に切り替えて以下を実行しました。 sudo apt install unzip curl -k -o q.zip https://desktop-release.codewhisperer.us-east-1.amazonaws.com/latest/q-x86_64-linux-musl.zip unzip q.zip cd q chmod +x install.sh ./install.sh インストーラーを2回実行し、途中で「Builder IDでログイン」を選択。 この手順でCLIが正常に動作するようになりました。   (5) 初期起動と認証 最後に、次のコマンドでAmazon Q CLIにログインします。 q login ログインが完了すると、ターミナル上でAmazon Qとのチャットが可能になりました。 記事だとすんなり進んだように見えるかもしれませんが、実際には試行錯誤を繰り返したため、環境構築だけで半日以上かかりました。ようやく「AIと会話しながらコードを生成する」というスタートラインに立てたのです!(長かった) (画像はAmazon Q CLIの起動画面)    (6) まずは“オセロ”で試してみる せっかく環境が整ったので、簡単なサンプルとしてオセロを作ってみることにしました。 Amazon Qに以下の指示を送ります。 Pygameでオセロを作ってください。  数分後、Pythonコードが生成されました。動かしてみると、石がパタパタと反転していく──まさに自動生成の威力を実感しました。 (画像はAmazon Q CLIが生成したオセロゲーム)    DAY2:Amazon Qとのすれ違い──プロンプトの重要さを認識する (7) RPG づくりを試してみるが オセロが動いた勢いで、次はもう少し複雑なものを試してみました。 Amazon Qに以下の指示を送りました。 ドラクエのようなRPGを作って 果たしてどんなゲームができるのでしょうか?わくわく感を抑えきれず、ゲームをスタートします。 ところが、出てきたのは“超”簡素な2Dマップ。 イベントも町も人もいない、ただの草地に、主人公とスライムのようなモンスターがいるだけのさみしい光景でした。(下図を参照) 流石にAmazon Qに対する期待値が高すぎた様です。 しかし、挑戦はまだまだこれからです。むしろここからが本番です。   (8) 追加指示とバグの連鎖 「町に宿屋を」「武器屋を」「山や川も」と少しずつ条件を追加していくと、確かに見た目は少しだけそれらしくなりましたが、別の問題が次々に発生。マップの一部が崩れたり、NPCに話しかけると落ちたりと、うまく動きません。 このあたりから、AIに頼むときは「欲しい結果をできるだけ具体的に言葉で表すこと」が重要だと感じ始めました。 改良の結果、最初に比べるとマップはずいぶん賑やかな感じになりましたが、「これじゃない」感は拭えません。(下図を参照)   (9) AI の応答に苦戦 修正を頼んでも、しばらく待って返ってくるのは「修正が確認できませんでした」のような返答。もしくは、修正後も事象が改善していな事の繰り返しで、どんどん時間が経過していきました。 エラー内容をもう少し詳しく伝えるべきだと分かっていても、どこからどう説明すれば伝わるのか手探りの状態でした。   (10) 試行錯誤の末に見えたこと 何度かやり取りするうちに、「AIは勝手に意図を補ってくれない」ことを実感しました。 こちらが正確に仕様を伝えない限り、出てくるコードも意図からずれてしまいます。 たとえば「敵を倒したあと進めない」という報告を送っても、AIは原因を推測してくれず「修正できませんでした」とだけ返してきます。ここで、もう少し構造的に説明してみる必要があると感じました。   (11) この日のまとめ この日の最大の学びはまさに 「適当な指示では、適当な結果しか得られない」 こと。  Amazon Qは優秀なツールですが、曖昧な指示はそのまま曖昧な結果を返します。 お試しとはいえ、プロンプトの精度が結果を大きく左右することを体感できた一日でした。   DAY3:ダンジョン探索型RPGの再出発 ― ChatGPTとAmazon Qが作る自動生成の世界 (12) 仕様を一新、ゼロから再スタート DAY2で作ったゲームは、まったく完成のめどが立ちません。 そこで、思い切って一度リセットし、 “ダンジョン探索型RPG”を新しく作り直す ことにしました。 今回のテーマは「マップが自動生成されるRPG」。 固定マップではなく、起動するたびにランダムで構造が変わり、キャラクターが勝手にダンジョンを探索してくれる、“自動探索ダンジョン”を目指しました。   (13) ChatGPT に仕様づくりを依頼 これまでの経験で、曖昧な依頼ではAmazon Qが混乱することがわかっていたため、まずChatGPTに「RPGの基本仕様書を作って」と頼みました。 ChatGPTは、ダンジョンRPGの最小構成をこう整理してくれました: マップは2次元リストで構成(壁・通路・階段の3種類) プレイヤーは矢印キーで移動、壁は通れない 階段に到達したら次の階層に進む モンスターはランダムに出現、戦闘結果でHP減少 HPが0になるとゲームオーバー この仕様をもとに、ChatGPTに「Amazon Qへ送るためのプロンプト」を自動生成 してもらいました。 プロンプトには、使用ライブラリ(Pygame)、データ構造(2Dリスト)、描画処理、イベントループなどが明記されており、Amazon Qでも誤解が少なくなりました。   (14) エラー修正もChatGPTが自動生成 それでも、実際にゲームを実行してみると、当然ながらバグは発生しています。 「敵を倒しても階段が出ない」「フロアの隅に閉じ込められる」「マップが生成されない」 といった、ユーザー体験を損なう致命的な問題です。  エラーそのものはPython側のログで明示されていないことも多く、 「プレイヤーが同じところを行ったり来たりしてゲームが進まない」「敵が表示されない」「フロアをクリアしても次に進めない」 といった“現象”ベースの問題が続出しました。  この状況を打破するために、ChatGPTを“プロンプトの翻訳者”として活用しました。  Amazon Qは、自然文をそのまま受け取って期待通りの出力を返してくれるとは限りません。 ChatGPTに自然文のプロンプトを渡し、そこから AIが解釈しやすい構造化された指示 に変換してもらう ようにしたのです。  この“ChatGPTの修正依頼文”をそのままAmazon Qに投げると、ちゃんと動くコードに置き換わりました。 こうして、ChatGPTがエラーを「翻訳」してAmazon Qに伝える――というAI同士の分業が形になったのです。   (15) まとめ:AI同士の共創が見せた新しい開発スタイル DAY3では、ChatGPTが「仕様や修正依頼を構造化」し、Amazon Qが「コードとして実装」する流れが確立しました。 それまでのように曖昧な会話で進めるよりも、 ChatGPTが“AI向けの言葉”で翻訳することで精度が劇的に上がった のが大きな成果です。 完成したのは、シンプルながら「ランダム生成」「自動探索」「階層移動」を備えた ダンジョン探索型RPGの原型 。 お試しで作っただけの小さなプログラムですが、AIツールの組み合わせ次第でここまで動くものが作れるのかと、純粋に驚かされました。(下図を参照)   おわりに ― 小さな一歩でも、確かな学び 今回は、AIの力を借りながら手探りでゲームづくりに挑戦してみました。 専門知識がなくても、少しずつ動かしながら仕組みを理解していくうちに、だんだんと形になっていくのが楽しかったです。 もちろん、思うように動かないことも多く、エラーの意味を調べたり、AIの提案を試しては失敗したりの繰り返しでした。 それでも、「こうやってAIと一緒に作るんだ」という感覚を掴めたのは大きな収穫でした。 もしこの記事が、これからAmazon QやChatGPTを使ってみようという方の背中を少しでも押せたなら、とても嬉しいです。 私自身もまだまだ学びの途中ですが、「試してみる」ことの大切さを改めて感じました。 読んでくださって、ありがとうございました。   (下図は、作ったゲームをクリアしたときの画面)
アバター
Catoクラウドのバイパス機能(Catoのネットワークを通さず外部接続させる機能)に、新たな設定方法が追加されました。本記事では、その紹介を行います。 はじめに:通信のバイパスを実現する機能 Site単位のバイパスを提供する「Bypass」機能 Catoクラウドは原則として全ての外部通信についてCato PoPを経由させ、ネットワークとセキュリティ双方の管理を行うよう設計されています。 とはいえ、例外的にCatoのネットワークを経由させたくない、させられないケースが発生する場合もあります。そうした場合の対応策の一つが、Site単位での「Bypass」機能です。 上図の通り、対象として指定した条件を満たした場合に限り、 Cato PoPを通らず直接インターネットへ通信を行います。 バイパスした場合はCatoの帯域を使用しない ため、安全であることが確定している、かつ大量の通信を要するケースでは帯域不足による遅延の対策として「Bypass」機能が有効な場合があります。 モバイル接続向けの「Split Tunnel」機能 上述の「Bypass」機能は、あくまでも特定のSite配下からの通信へ適用されるものです。 このため、モバイル接続を行う機器はその恩恵を直接受けることができません。 モバイル接続向けには、「Bypass」機能に近い役割を持つ 「Split Tunnel」 機能が存在します。 この機能は、条件を満たす通信について、「Catoを経由する」「Catoを経由しない」のいずれかを指定することが可能です。これによってCato PoPを通らず直接インターネットへ通信を行わせることが可能です。 モバイル接続の場合、帯域の上限はもともと気にする必要が無い ため、 Split Tunnel機能のユースケースはSiteの「Bypass」機能とは異なってくるでしょう。 具体的には、何らかの制約で、Cato経由ではどうしても接続できない…… といったケースなどが考えられます。 新機能:アプリケーションを対象指定 「Bypass」「Split Tunnel」共に従来はIPアドレスでのみ対象を指定できましたが、 新規に一部アプリケーションでの対象指定が可能となりました。 2025年10月現在、選択可能なアプリケーションは以下に限られます。 決して多くはありませんが、特に有名なオンラインミーティングサービスは概ね対応しています。 ・Zoom ・Microsoft Exchange (Outlook) ・Google Applications(Google Meet, Google Drive等) ・Microsoft Defender For Endpoint ・Sharepoint and Onedrive Business ・Skype and MS Teams 残念ながら、Windows Updateは対象に含まれていません。 代表的な「危険性が低く大量の通信を行う」処理の一つなので、ぜひ対応してほしいところです。 注意点:バイパスのリスクと無視されない機能 バイパスにより無効化される機能 「Bypass」および「Split Tunnel」機能は、Cato PoPを経由しない形での通信を実現します。 Catoの各種セキュリティ機能はCato PoPを経由する通信の過程で適用されているため、 バイパスした通信はCatoのほぼ全ての機能の適用対象外となります。 例えば、「Google Applications」に含まれるGoogle Driveを経由した情報漏洩や、これを悪用するサイバー攻撃を防ぐことはできなくなります。 また、CatoのCASB機能を活用すると「企業のアカウントへのログインのみを許可し、個人アカウントへの接続は禁止する」といった制御を行うことが可能ですが、これもバイパスしているサービスでは無効化されてしまいます。 あくまでも 原則は全ての通信をCatoのネットワーク経由とする 設計が望ましく、バイパスするのは最低限の通信にとどめるのがベターと言えます。 バイパスしても無効化されない機能 前述の通り、バイパスした通信はCatoの制御機能が基本的に適用されません。 しかし、実は 「Site配下からの上り通信に対するQoS制御」はバイパスしていても適用されます 。 (下り通信は適用されません。) 例えば、対象のアプリケーション宛の通信について「常に帯域の10%にUpload速度を制限する」 というPriorityを適用するようなNetwork Ruleが設定されている場合、 この影響を受けることになります。設計の際に注意しましょう。 参考:バイパス設定手順 Site単位での「Bypass」とモバイル接続向けの「Split Tunnel」それぞれの手順を紹介します。 Site向けの「Bypass」機能設定 Site向けの「Bypass」機能の設定は、個々のSiteで実施します。 CMAの[Network] > [Sites]から、バイパス設定を行いたい対象となるサイトを選択します。   Site個別ページの[Site Configuration] > [Bypass]にて設定を作成します。 今回のケースであれば、特定のアプリケーション宛の通信をバイパスしたいので 「Destination」の[New]を押下します。   以下の画像のように、新規ルールの作成画面が表示されます。 設定を入れて「Apply」をクリックします。 名称 役割 Name 任意の名称を入力します。 対象指定 まず対象の種別として「Application」「IP Range」のいずれかを選択し、 そのあとで具体的な対象を指定します。 複数の対象を指定することが可能です。 また、ApplicationとIP Rangeの両方を対象として加えることも可能です。              Application: 新しく追加された選択肢 です。 Catoが事前に指定したアプリケーション(前述)を選択可能 です。 IP Range: IPv4アドレス、またはIPレンジで指定します。 ドメイン指定には対応していない のでご注意ください。 Protocols 対象とする通信のプロトコルを制限したい場合に選択します。 TCP、UDP、ICMPのうち、チェックを入れたプロトコルに該当する通信のみが 対象とされるようになります。              なお、どれにもチェックを入れていない状態(デフォルト)では 全てのプロトコルの通信が対象となります。 Preferred Socket Port Socketの複数のWANポートを使用している際に、 いずれかのWANポートを優先して使用するよう設定できます。 デフォルト(Automatic)では、空き状況に応じて自動でポートが選択されます。              このオプションは、あくまでも「Preferred」、つまり優先する設定でしかありません。 指定したポートが切断されていたり著しく速度が低下したりしている場合、 別ポートでの通信を試みることがある ので注意が必要です。 作成したルールが表示されていることを確認してから、「Save」を押下しましょう。 モバイル接続向けの「Split Tunnel」設定 「Split Tunnel」機能の設定は、[Access] > [Split Tunnel Policy]より行います。 [New]を押下して新しいルールの設定を行います。 新規ルールの設定画面にて、まずは適用対象を絞り込みます。 名称 役割 General Name: 任意の名称を入力します。        Description: 必要に応じ、任意の説明文を入力します。 Position: 作成するルールの配置場所です。 Split Tunnel Policyは上から順に参照して最初にヒットしたルールを採用するため、特定の対象をとるようなルールは上に配置するようにしましょう。 Users/Groups ルールの適用対象とするモバイルユーザ/グループを指定します。 複数指定も可能です。 Platforms Windows, iOS, Androidなど、特定のOSからの接続のみを対象とする場合に指定します。 デフォルトでは全て対象となります。 Country 特定の国からの接続のみを対象とする場合に指定します。 デフォルトでは全ての国が対象となります。 対象を設定したところで、[Route Traffic]にて通信をバイパスさせるための設定を行います。 アプリケーション単位でバイパスする場合、 「Route all trafic to Cato」を選択 します。 その上で、Exception(例外)として対象アプリケーションを指定することで、 当該アプリケーション宛の通信はバイパスするように設定します。 あまり直感的ではない設定方法となるので、気を付けましょう。 「Save」を押下し、想定通りの内容が一覧に表示されたことを確認してから 「Publish」を実行しましょう。   終わりに 限定的ながらもアプリケーションを対象に指定した通信のバイパスが可能となったことで、従来SaaSを対象とするのが困難であったバイパスの実用性が向上しました。 特に、Zoomを始めとするオンラインミーティングサービスをバイパスしたいという要望は比較的多くみられたため、そういった状況下で活用するケースがあるかもしれません。 とはいえ、「Bypass」や「Split Tunnel」はセキュリティ面の機能低下を避けることができない機能です。あまり濫用せず、適切な運用にとどめるよう心掛けたいところです。
アバター
こんにちは SCSKの庄司です。 今回は、ServiceNowの複数行の変数セット(Multi-Row Variable Set)を紹介していきます。 本記事は執筆時点(2025年10月)の情報になります。最新の内容は製品ドキュメントを参考にしてください。 変数セットとは Servicenowではカタログアイテム画面(申請画面)上に、「変数」と呼ばれる入力項目を配置できます。 それらの「変数」を再利用可能なひとかたまりにしたものが変数セットです。変数セットには「単一行」と「複数行(MRVS)」の2種類があります。 以下、「単一行の変数セット」と「複数行の変数セット」の簡単な比較表になります。 項目 単一行の変数セット 複数行の変数セット 入力形式 単票(1セット=1件) 表形式(行を追加/削除して複数件登録可能) 画面の見え方 フィールドが縦並び テーブル(行×列) 値の実体 変数ごとの単一値 JSON文字列 (配列の中に行オブジェクト) バリデーション 変数単位でチェック 配列を走査 して行ごとにチェック 用途 単体の申請フォーム 一括登録、一覧表示など 本記事ではタイトルの通り、「複数行の変数セット」に絞って解説します。   複数行の変数セットの作成手順/オプション ①すべて > サービスカタログ > カタログ変数 > 変数セット に遷移し、[新規]を押下 ②「複数行の変数セット」を選択。 ③各項目を入力して送信。 今回はユーザー登録をするための申請を想定して作成します。 ④送信後、[変数]/[カタログクライアントスクリプト]\[カタログUIポリシー]などの関連リストが表示されるので、必要に応じて変数セット内の変数や処理を作成します。    複数行の変数セットのオプション  変数セットの属性 :max_rows=xx(任意の数字)を入力することで、複数行の変数セットの最大行数を指定することが可能です。(デフォルトでは50行) システムプロパティ「glide.sc.multirow_set.rows.size」でも上限設定は可能ですが環境全体に適用されるため、個別制御したい場合は変数セットの属性項目での指定が推奨です。 デフォルトでの上限値は50行です(バージョン等により異なる可能性があります)    画面上の挙動確認  サービスカタログ画面では表形式で項目が表示されています。 [追加]を押下すると入力項目が表示されます。 項目を入力して再度 [追加] を押すと、1行の値としてテーブルに追加されます。 同じ手順を繰り返すことで、複数行登録することも可能です。   複数行の変数セットの値の取り扱い-カタログクライアントスクリプト 比較表にも記載の通り、複数行の変数セットの値はフォーム上では1つの“ JSON文字列 ”として扱われます。 試しに、以下のonSubmitカタログクライアントスクリプトを実行して値がどうなっているかを確認してみます。 処理内容としては複数行の変数セットの値を取得して、画面上部に表示させるものです。 function onSubmit() { //Type appropriate comment here, and begin script below  var mrvs_value = g_form.getValue("u_register_user");  g_form.addInfoMessage(mrvs_value);  return true; } 以下のような値で表示されていました。 成形すると以下の通り、変数名:値の形です。 このままの状態では扱いずらいため、必要に応じて値を加工してあげてください。 {  "u_department": "5d7f17f03710200044e0bfc8bcbe5d43",  "u_first_name": "test1",  "u_mail_address": "test1@test.jp",  "u_telephone_number": "090-xxxx-xxxx",  "u_last_name": "test1" }, {  "u_department": "221f79b7c6112284005d646b76ab978c",  "u_first_name": "test2",  "u_mail_address": "test2@test.jp",  "u_telephone_number": "",  "u_last_name": "test2" }   複数行の変数セットの値の取り扱い-Flow Designer また、同様にフローでも複数行の変数セットは通常の変数や単一行の変数セットとは扱いが異なります。 例えば、「部署」項目の値をチェックし、その項目に「IT」があった場合に承認要求をする処理を作成しました。 フロー概要: 部門レコードを取得 カタログ変数を取得:複数行の変数セットの値を取得 For Each:複数行の変数セットを行ごとにループ 条件分岐:行の「部署」列が「IT」なら true 承認要求 肝になるのは2と3です。 複数行の変数セットを配列としてフローに渡しFor Eachで回すことで、1行目はfalse、2行目はtrueのような行別での判定が可能になります。   最後にフローの動きをチェックしてみます。 RITM0010006に対してフローのテストを実行します。 RITM0010006の内容は以下のようになっており、一行目の部署はDvelopmentで、二行目はITになっています。    テスト実行結果  一行目は4の判定がfalseになっていますが、二行目はtrueになっています。   各行の中身を除いて判定出来ていることが確認できました。   まとめ 以上、複数行の変数セットに関する紹介でした。 あまり出番が多くないかもしれませんが、使いどころを知っておくと設計の選択肢がぐっと広がります。 ぜひ参考にしてみてください。
アバター
こんにちは、ひるたんぬです。 最近は急に冷え込んできましたね。秋、というより冬が来た、という感じです。 全く関係ない話ですが、なぜ「醤油(しょうゆ)」は油ではないのに、醤 油 と書くのでしょうか。 ごま油、サラダ油、なたね油…分かります。でもなぜ…? 醤油の言葉の意味としては“醬(ヒシオ)を絞ってできた油(液)”です。 『漢字源 改訂第6版』(学研 2018年12月刊)の“油”(p.1055)によると、“ するすると滑らかで通りのよい液体を示す”とあり、“油”は“液体”という意味で使われている ようです。 引用…国立国会図書館「レファレンス協同データベース」| 醬油にはなぜ“油”という字が使われているのか。 油は油だけど、(私が認識しているような)油ではない…少し頭が混乱してしまいました。 さて、今回はタイトルにもありますように、「AWS WAFでブロックしていたはずなのに…見れてしまう!」となってしまう事例を簡単にご紹介します。 構成 今回はAmazon CloudFrontとAmazon S3を用いた静的コンテンツを公開する基盤を想定し、アクセス保護の目的でAWS WAFを前段に配置することにします。 検証 ここからは、実際に構築を行いながら検証をしていきます。 事前準備 まず静的コンテンツを公開するために、Amazon CloudFront ディストリビューションとAmazon S3 バケット、アクセス保護をするAWS WAFを作成します。 バケットの作成後、適当なコンテンツを用意して格納しておきましょう。 今回の検証では、404 Not Foundエラーを表示させたいため、S3のバケットポリシーにおいて、CloudFrontの当該ディストリビューションのListBucket権限を許可します。 関連サイト…aws re:Post – 画像が CloudFront からロードされないのはなぜですか? 一通り準備ができたら、アクセスしてコンテンツが表示されることを確認します。 無事に見れましたね。 続いて、存在しないアドレスにアクセスした際にコンテンツが存在しない旨を分かりやすく表示させます。 ここでは、CloudFrontのカスタムエラーレスポンスを設定し、404エラーに対して「notfound.html」を表示させるようにします。 設定が完了したら、実際に存在しないページにアクセスして確認をします。 しっかりエラーのメッセージが分かりやすく表示されていますね。 カスタムエラーレスポンスを設定しない場合、とてもシンプルなメッセージが表示されます。 WAF設定 ここからが本題です。 今現在の構成では最低限のアクセス保護のみが実施されています。 そこで、AWS WAFの設定を変更し、特定のIPアドレス以外からのアクセスを拒否するように設定します。 今回は検証目的のため、自端末に割り当てられているグローバルIPを拒否するよう設定しました。 これを実施することにより、不特定多数からのコンテンツ閲覧を制御することが可能です。 設定後、拒否されている環境から同じようにアクセスしてみると… WAFによってしっかりブロックされていることを確認できました。 ブロックされない!という方は、IPv6で通信している可能性があるため、IPv6のアドレスをブロックするよう設定してみてください。 そして…事件発覚 ここで私は「この403のページももっと親切な案内にしたい!」と思うようになりました。 そこで一番最初に思いついたのは、先程404 NotFoundのときに設定した「カスタムエラーレスポンス」です。 これは403でも同様に設定できるため、403エラーに対しては「accessdenied.html」を表示させるよう設定をしました。 実際に設定を終えて、表示を確認してみると… おぉ!なんか怖い画面ですが、しっかり日本語で表示されましたね!よしよし。。。 ……ん? 既にお気づきの方もいらっしゃるかもしれませんが、この挙動、何かおかしくないですか? 先程設定したのはCloudFrontのカスタムエラーレスポンスで、403 ForbiddenのときにはS3の中に格納されている「accessdenied.html」を表示させるようにすること… そして、今現在アクセスしているのは、AWS WAFにてブロックしている端末から… なぜCloudFrontに設定し、S3に格納されているコンテンツが閲覧できてしまうのでしょうか?? 調査 403エラー時のレスポンスである「accessdenied.html」以外は確かに表示できないようになっていますが、いかんせんWAFを通り越してCloudFront(S3)のコンテンツが閲覧できてしまっているのがとてもとても気になってしまったので、調べてみました。 すると、公式ドキュメントに以下のような記載がありました。 By default, when AWS WAF blocks a web request based on the criteria that you specify, it returns HTTP status code  403 (Forbidden) to CloudFront, and CloudFront returns that status code to the viewer. The viewer then displays a brief and sparsely formatted default message similar to the following: Forbidden : You don 't have permission to access /myfilename.html on this server. You can override this behavior in your AWS WAF protection pack (web ACL) rules by defining custom responses. For more information about customizing response behavior using AWS WAF rules, see  Sending custom responses for Block actions . 引用:AWS Docment | Common use cases for protecting CloudFront distributions with AWS WAF 日本語が機械翻訳で崩壊していたので英語を引用していますが、まとめると WAFでブロックされると、403(Forbidden)を CloudFrontに対して返す デフォルトのメッセージは上記のような表記となる(Forbidden: You don’t have…) カスタム(エラー)レスポンスを設定することで、この設定を上書きすることができる という動作になります。別のページにも分かりやすく整理されていました。 For web requests that AWS WAF blocks, the following shows the order of precedence. AWS WAF custom response  – If the AWS WAF Block action has a custom response enabled, the protected resource sends the configured custom response back to the client. Any response settings that you might have defined in the protected resource itself have no effect. Custom response defined in the protected resource  – Otherwise, if the protected resource has custom response settings specified, the protected resource uses those settings to respond to the client. AWS WAF default Block response  – Otherwise, the protected resource responds to the client with the AWS WAF default Block response  403 (Forbidden) . 引用:AWS Docment | Sending custom responses for Block actions つまり、WAFでブロックされた場合は、 AWS WAFに設定されたカスタムレスポンス 保護されたリソース(CloudFrontなど)で設定されているカスタムレスポンス AWS WAFに設定されたデフォルトレスポンス の優先順位で表示がされるようです。これで納得ですね。 つまり、AWS WAFでアクセスをブロックしたと言っても、CloudFrontのコンテンツの内容を表示できるケースが仕様として存在する、ということですね。 もちろんカスタマイズしたレスポンスを提供できることはメリットになりますが、その 設定を誤ってしまうと公開したくない(する予定のない)コンテンツを公開しかねないことになる ので注意が必要です。 今回は、この事象を「AWS WAFのすり抜け」と名付けました。 深堀り では、CloudFront(S3)のコンテンツを参照させることなくAWS WAFでブロックされたことを分かりやすく示す方法はないのでしょうか…? 引き続きドキュメントを見てみると、気になる表現がありました。 Responses that you customize using AWS WAF rules take precedence over any response specifications that you define in CloudFront custom error pages. 引用:AWS Docment | Common use cases for protecting CloudFront distributions with AWS WAF AWS WAFでレスポンスをカスタマイズすることで、CloudFrontのカスタムエラーレスポンスよりも優先して表示させることができる、と言ったような記載があります。 おぉ!これですね。早速設定してみます。 該当するWAFの設定項目から「Custom response bodies」のタブを選択し、「Create custom response body」をクリックします。 名前と表示させる内容を設定します。 内容はJSONの他、HTMLやプレーンテキスト形式で設定ができるようなので、今回はHTMLで設定してみます。 登録する内容には、4KBの制限があります。 設定が終わったら、下部の「Save」をクリックします。 次に、既に設定されているWAFのルールから、IP制限に関するルールを編集します。 中段に記載の「Custom response –  optional 」を有効化し、レスポンスコードと、先程登録したエラーレスポンスを選択します。 AWS WAFで設定するカスタムレスポンスは、自分で定義したルールにのみ適用することができます。 ルールごとに適用が必要になるため、複数ルールを定義している場合は注意が必要です。 また、マネージドルールに対してカスタムレスポンスを設定する場合は、別途設定が必要となります。 参考:AWSブログ | AWS WAFのAWS マネージドルールの動作をカスタマイズする方法 設定が完了したので、改めてアクセスしてみましょう。 …まぁ、なんとも仰々しい画面ですね。 しっかりとWAFにて設定したカスタムレスポンスがCloudFrontのカスタムエラーレスポンスよりも優先して表示されていることを確認できました。 ブロック検知ルールにXSSやSQLインジェクションとありますが、違いますね。 今回はここの内容は本質的ではないのでご承知おきください。 (生成AIに作ってもらったら、この部分を決め打ちで記載してくれていました。) おわりに 今回はAWS WAFを用いたコンテンツ公開基盤に対して、WAFがブロックしたときの挙動をご紹介いたしました。 最初にこの状況に遭遇したときはびっくりしましたが、冷静に考えるととても妥当な仕組みなのかなと思います。 余談ですが、タイトルにも「油断」、と油が入っていました。 こちらは仏教用語のようですね。
アバター
AWS Certificate Manager(ACM)と Amazon Route 53 を使用する際に発生した問題から、DNSに関して学べたので記事にします。 やりたいこと ACMのDNS検証で証明書の発行がしたいです。 しかし 「保留中の検証」 から 「発行済み」 にならず、苦労しました。 その原因はNSレコードで、DNSの権限委任について知識が不足していたことにありました。 ドメインの現状 親ドメイン:pri-tomioka.com お名前.comで購入したドメインです。 共通ホストゾーン:training.pri-tomioka.com Route53で、このホストゾーンが作成されている状態です。 ここまで作成済み。以下を新規作成。 サブドメイン:test01.training.pri-tomioka.com、test02.training.pri-tomioka.com、test03.train… といったサブドメインを順次追加していく予定です。 証明書発行してみたときの失敗談 Route53でホストゾーン test01.training.pri-tomioka.com を作成して、           バブリック証明書をDNS検証で作成します。                   Route53のサブドメインにCNAMEを設定します。       これで発行完了や!と思って待ってみましたが、検証が完了しませんでした。 ステータスが「保留中の検証」のまま何時間待っても成功しません。         原因はNSレコードにあり 設定としてはRoute53に問題があります。 サブドメインのトラフィックのルーティング - Amazon Route 53 acme.example.com や zenith.example.com などのサブドメインのリソースにトラフィックをルーティングする場合、次の 2 つの方法があります。 docs.aws.amazon.com サブドメインのトラフィックのルーティングが設定されておらず、ACMがサブドメインにアクセスするための名前解決ができていなかったのです。 nslookupで確認してみます。 nslookup -type=ns test01.training.pri-tomioka.com         解決策は以下の2点です。 共通ホストゾーンtraining.pri-tomioka.comにNSレコード作成し、サブドメインtest01.training.pri-tomioka.comのネームサーバを指定 親ドメインpri-tomioka.comにNSレコード作成し、サブドメイン(共通ホストゾーン)training.pri-tomioka.comのネームサーバを指定 1の設定               2の設定(画面はお名前.com)           nslookupを実行すると、NSレコードがDNSに登録されていることを確認できました。             そして少し待っていると、ついに証明書が「発行済み」になりました!!       さいごに この記事を書くに至ったきっかけを記載します。 昨年、私が受けていた「クラウド研修」で、今年はスクラムマスターとして新人たちを指導する立場になっています。 今年の研修で新人たちから、「証明書がいつまで経っても発行されない」と相談をいただきました。 調べてみると、親ドメインに共通ホストゾーンのネームサーバが指定されていないことが原因。 この親ドメインは新人たちは見ることができない環境だったため、スクラムマスター側で解決しました。 運営側の不備で申し訳ない反面、去年は触れなかった親ドメインの設定にも今回は関わることができ、少しうれしさも感じてます。 指導する立場ではありますが、私自身も新たな知識を得ることができ勉強になりました。   参考:去年受講者の記事を紹介 コンテナを理解して触ってみた! この記事は、コンテナ技術の基本概念を解説し、その利点や活用方法について説明しています。 具体的な技術例としてDockerを取り上げ、実際の使用方法を通じてその利点と可能性について述べています。 初心者にも分かりやすい内容で、コンテナを試したい方への一歩をサポートする内容です。 blog.usize-tech.com 2024.11.13 AWS CloudFormation と Ansible を使ってみた AWS CloudFormation と Ansible を使用した Web アプリケーションの自動実行を試してみました blog.usize-tech.com 2024.11.06 アプリケーション開発で使用した Spring Boot の紹介 AWS Cloud9上でWebアプリケーションの開発を行った際に用いた、Spring Boot というフレームワークを紹介します。 blog.usize-tech.com 2024.11.11 一瞬で記録するWinShotでの作業証跡 作業証跡に関して、画面キャプチャソフトであるWinShotをクラウド研修を元に紹介します。 blog.usize-tech.com 2024.10.29
アバター
こんにちは、SCSKでAWSの内製化支援『 テクニカルエスコートサービス 』を担当している貝塚です。 (生成)AIを使用したソフトウェア開発が盛り上がっていますね。AWSまわりを主戦場にしている我々の部署でも Amazon Q Developer や Kiro を使用した開発はホットな話題です。 私も顧客に提供するウェブサイトをインフラからアプリまで一式、Amazon Q Developerを使用して開発したので、その概要と所感を書いてみます。 開発概要 特定顧客向けのウェブサイトです。サイトの内容はQuickSightのURL埋め込み機能を使用してQuickSightダッシュボードを表示するだけのシンプルなものです。取得するダッシュボードのIDなどを取得するためにDynamoDBを、サイトアクセスの認証のためにCognitoユーザプールを使用しました。アーキテクチャ図は以下の通りです。 AWSリソースを作成するCloudFormationテンプレートと、Webサイトのソースコード、すべてを生成AIで開発しました。 開発体制 人数: 1人。テスト等でお手伝いしてもらったりしていますが、基本的には私だけです。 ツール: Windows上にインストールしたVSCode + Amazon Q拡張。使用MCPはAWS Knowledge MCP, Documentation MCPなど。WSL UbuntuをインストールしてVSCodeのターミナルからQ CLIを併用。バージョン管理システムはCodeCommitです。 開発期間: 言うのが割と本気で恥ずかしいので秘密です。多分、慣れてる人が作ったらあっという間じゃないかな……と。でも生成AIを使った開発のメリットは開発時間の短縮だけではないですよ……ということは後で書きます。 開発開始当初 開発開始当初はAmazon Q Developer Proのサブスクリプションがなかったので、Bedrock (Claude Sonnet 4)で開発していました。しかもマネジメントコンソールのプレイグラウンドを使って……もうこの環境には戻れないですね。 とにかくまずは動くものを作りたかったので、一番最初は 概要だけ与えてアーキテクチャを提案してもらう →何度かQ&Aや機能の追加・変更を要望してアーキテクチャを決定 →コードを生成してもらう →デプロイは自分で手作業(CI/CD環境は作りました) 機能追加・改善は 追加・改善したい機能を伝えてアーキテクチャ・設計を提案してもらう →何度かQ&Aしてアーキテクチャ・設計を決定 →現在のコードからの変更提案を作成してもらう →変更提案に納得出来たら修正版のコードを生成してもらう エラー対応は エラーメッセージを与えて原因を答えてもらう →何度かQ&Aや追加で調査した情報を与えて原因を推測し、修正方針を決定 →修正点について変更提案を作成してもらう →変更提案に納得出来たら修正版のコードを生成してもらう 修正する内容を、コードを実際に修正する前に変更提案という形でC1, C2 … のように通し番号をつけて作成してもらうようにしたのが工夫点でしょうか。例えばこの変更はいらないなという時に、番号が付いていれば指示が出しやすく紛れがないかなと考えました。 この頃は、ソースコードにも自分で識別子つけて管理していました。「ソースコードL1を変更提案に基づき修正してください。以後、修正後のコードをL2として参照します」という感じです。必要なことではあったのですが、本質的ではない部分に随分手間をかけていましたね。 問題点・不便だった点 変更提案(日本語+コード引用して修正内容を説明)にない変更を勝手にソースコードに加えてしまう。「ソースコード修正の際、変更提案にない修正は厳禁です」と指示してみるも、十分な効果が得られない。 ソースコードから大量のコードが消えている、使用されている関数が消えている、などが発生。コンテキストがあふれてソースコードの情報が失われたせいと思しきケースもあるが、そうではなさそうなケースもあり。 生成AIが返してくる内容が本当に正しいか分からない。細かく質問を繰り返していくとハルシネーションが判明することもあるが、そもそもそこまでやらないといけないというのが辛い。 AWSサービスについても得手不得手に濃淡がある。不得手なものもそれっぽいことを言ってそれっぽいコードを生成してくれるが、バグだらけの上にしばらくデバッグを続けていると別のアーキテクチャへの変更を提案してくることも。 デバッグはエラーメッセージを手動で与えなければならないし、デバッグ手順の示唆を与えてもらうにせよかなり人の手が必要。デプロイも手動で実施する必要あり。デバッグはそれでも生成AIによって大幅に楽になっているのですが、贅沢なものでデプロイ&テスト&デバッグはもっと生成AIにやってもらいたいと思っていました。 Amazon Q Developerによる開発への転換 Amazon Q Developerのサブスクリプションが手に入った頃、丁度AWSが提供する AI-DLC (AI駆動開発)のトレーニングを受けることができたので、本システムの開発もAmazon Q Developerを使用したAI-DLCに乗り換えることにしました。 AI-DLC 導入後のプロンプト まずはAI-DLCの趣旨に沿って作成したプロンプトをAmazon Q Developerで使用したときの使い勝手という観点から見て行きます。 作業計画の立案 AI-DLCのトレーニングで学んだ内容からだいぶ我流のカスタマイズを加えたプロンプトを使っていますが、個人的に肝だと感じているのは以下のような箇所です。 作業の計画を立て、各ステップにチェックボックスを付けて、作業ディレクトリ内の plan.md ファイルにステップを記載してください。(中略)計画を作成したら、私のレビューと承認を求めてください。承認後、計画を 1 ステップずつ実行できます。ステップごとに必ず私のレビューと承認を求めてください。各ステップが完了したら、計画のチェックボックスに完了マークを付けてください。 このプロンプトにより生まれる長所だと私が感じているものは以下の通りです。 1. 計画を立ててから実行させると全体的にだいぶ品質が上がる気がする 計画を立ててもらうと、何も言わなくとも調査→設計→コード作成→テスト・検証というステップを踏んでくれることが多いです(AI-DLCではユーザーストーリーの作成から始まるのですが、開発途中のシステムということもあり今回は省きました)。大きなタスクを細かいタスクに分割してやると生成AIの精度が良くなるというのはよく知られた話ですが、それだけではなくステップ間でレビュー・修正を入れられるのも大きいです。定量的に品質が上がりましたというデータを持っているわけではありませんが、効果は大きいように感じます。 2. 事前に計画を提示してくれるので計画の修正が容易 計画修正したいケースは様々考えられますが、たとえば「ここのテストは後でまとめてやろう」「ちょっとここの実装あやしいからドキュメント調査&設計見直しのステップを入れよう」などの意思が反映しやすいです。 3. セッションをまたいで開発を継続できる Amazon Q Developerの記憶力(会話履歴)には限界があり、しばらく開発を続けていると会話履歴が要約されたりクリアされたりしてしまいます。Amazon Q Developerでは会話履歴がクリアされる前に会話履歴の圧縮を勧めてくれますが、いずれにせよ文脈の一部が失われることは避けられません。その他にもツールの不具合であったり、開発に使用するPCを切り替えたりと、新たにセッションを開始しないといけない事態は発生します。 機能追加等の改修作業をひとつまるまる完了したタイミングであればよいのですが、トライアンドエラーを繰り返している最中に文脈が失われると手戻りが大きいです。 AI-DLCでは計画書がありその進捗状況が分かるようになっているので、セッションが別になってもタスクを再開することができます。 デプロイ、デバッグ 私が受けたAI-DLCのトレーニングでは、コードの作成まではAmazon Q Developerにやってもらっていましたが、AWS環境へのデプロイや、デプロイ時およびデプロイ後のテスト時にエラーが発生したときの調査、コードを修正して再デプロイなどには触れられていなかったので、これらは自分で追加しました。もちろんこれらも予め計画を立ててもらってから実行します。 コードの作成までとデプロイ以降とでセッションを分ける場合も分けない場合もあります。大きな機能追加の場合は分けることが多いですし、デバッグがうまく行かなかった時にセッションを変えて何度もデバッグを試みることもあります。 いずれにせよ、デプロイは(CI/CD環境を作成していたので)CodeCommitにコードをコミットするだけなので、カレントフォルダがgitリポジトリになっていることを説明するだけです。デバッグは、CodePipelineの名前だけ教えてあげればそこからCloudFormationのスタック名を、スタック情報から作成されたリソース名を芋づる式に調べてくれます。ただ、セッションを新たにしてデプロイ・デバッグする場合は、主要リソース名は予め与えるようにした方が余計な試行錯誤で時間を無駄にせずに済みます。 所感・工夫した点など Amazon Q DeveloperでAI-DLCを実践して、良かった点・使いづらかった点などいろいろ込みで感じたことや、工夫した点などを思いつくままに挙げてみます。 ドキュメント作成について ドキュメント作成について特にプロンプトで触れていないのですが、計画を立てて実行させることによって、途中の調査・検討結果をドキュメント化してくれるようになりました。改めて言うまでもないですが記録を残すのは非常に重要なのでありがたいです。 ドキュメントの整合性維持について 開発の中で次々ドキュメントが作成されていくのですが、工程を進めていくと、前に作成されたドキュメントに記載されている内容とは違う方向に進めたくなる/進んでしまうことがあります。その時、現在のステップで作成するドキュメントはもちろんその方向に沿って作成してくれるのですが、以前作成したドキュメントを整合性が取れるように修正してくれることはあまりありません。「ドキュメントを作成するたびに、以前作成したドキュメントを整合性が取れるように更新してください」のようなプロンプトを入れてあってもほぼ効果がありませんでした。現時点では、文書間の依存関係を自分で把握するようにしておいて、○○の文書を整合性を取れるように更新してください、と細かく指示を出すようにしています。 文書間の依存関係を記述したファイルを作成しておいて、ドキュメントの作成・更新時にそのファイルを参照して依存関係を特定し、関連ドキュメントを更新するようにうまく生成AIを誘導できるのではないか?と考えているので近いうちに試してみたいと思っています。 ドキュメントの管理について ステップごとに1つまたはそれ以上の数のドキュメントを作成してくれて、その場で読んでいるときはなるほどなるほどと読んでいるのですが、作成されるドキュメントの数がかなり多いです。作成するファイル名の命名規約等を与えていないのもあり、後から見るとどのファイルに何が書かれているのか分からなくなってしまいます。開発補助のエージェントとしてこの部分はこれから改善していく、またはプロンプトのノウハウが出回るのだと思いますが、ひとまずはドキュメントの種類などでディレクトリを分ける、ファイル名の先頭にステップ番号をつける、くらいの工夫で管理しています。 変更提案に基づくソースコード修正 Bedrock単体開発のところでも書きましたが、私は、ソースコード修正の際は変更提案というどこをどのように修正しその修正がなぜ必要なのかを説明するドキュメントを作成してもらい、その中から採用する変更提案を選んで修正してもらうという手順を採用しています。 先の所感で変更提案にない修正が行われると述べましたが、これはAmazon Q Developer + AI-DLC に移行した後もさほど改善されませんでした。承認していない変更が行われているだけではなく、ソースコードから大量の関数が消える事象もBedrock単体開発の頃と変わらず発生しました。 対策として「ソースコードの修正を行ったら変更前後のファイルでdiffを取り、変更提案の内容に過不足なく一致しているか確認してください」というような指示を与えています。ここでおかしい箇所に気づいてくれることもありますが、私から見ると明らかにおかしい場合でも「diffの結果、適切に変更されていることが確認できました」のようなことをしれっと返してくることもあります。もっとも、Bedrock単体で開発していた時は指示を出すのが面倒で差分確認をさせるということをしていなかったので、差分確認するようになっただけでも十分な進歩ではあります。また、diffが画面に表示されるので、私が異常に気付ける場合があるという点では、diffを毎回取らせるようにした意味はありました。 CodeCommitのコミットログ 過去に私が自分の手でコードを書いていた時は、一人で開発することが多かったので、バージョン管理システムのコミットログはかなり適当でした。それが、Amazon Q Developer + AI-DLC では、ソースコードを変更したらgitコミット用のコメントも出力してくださいと指示するだけでまともな変更履歴が出力されてきます。一人で小規模に開発している分にはなくてもなんとかなるかなという感覚なのですが、やっぱりあれば役に立ちます。これは個人的に非常に大きなメリットでした。 MCPの使用 プロンプトに「正確性の検証」という項目を入れて、「正確性を担保するためにAWSのサービスを使うときは必ずAWSドキュメントを調査して検証してください」と指示をしていますが、MCPを使ってくれたり使ってくれなかったりします。 これについては現状、調査して欲しいことが出てくる都度、AWSドキュメントを調査して裏を取ってください、と指示をするくらいしか対策が思いつきませんでした。AWSが提供するAIエージェントなのでここはぜひAWSさんに頑張って欲しいです!! チャット履歴・セッション引継ぎについて 設計決めのために何度も質問を繰り返したり、デプロイ・テスト時のエラーが解消できなくて何度も再デプロイ・再テストを繰り返していると、「チャット履歴が一杯になりそうです、履歴を要約して圧縮しますか?」と聞いてくれます。これを無視し続けるとコンテキストが一杯になってチャット履歴が強制クリアされます。私の場合、一つの機能の実装が完了する前にチャット履歴要約を勧められる多いです(周りの人の話を聞いていると、開発のやり方による個人差は大きそうです)。前述の通りセッションを引き継いでタスクを継続するのに計画書が役立つのですが、ときに重要な情報が抜けてしまうことがあります。 セッション終了時に、引き継いでほしい情報を指示して引き継ぎドキュメントや次回セッション開始時に与えるべきプロンプトを作成してもらうように追加で指示するようにしており、手ごたえは感じているのですが、まだまだ試行錯誤という状態です。 作業計画を外れた場合の対応について これはプロンプトでしっかり指示しようねという話に尽きるのですが、作成された作業計画にない指示をしてしまうことがあります。ちょっとこれも調査して欲しいな、とかです。あるいは、現在の作業計画は繰り返しを想定したものになっていないので、デプロイとデバッグを繰り返しているといつの間にか作業計画から外れてしまいます。そういう時、指示する側がきっちりと、こういうことをやりたいのでまずは作業計画を作成してください、とやればよいのです。それは分かっているのですが、ついうっかり(またはちょっと寄り道するだけだから大丈夫だろうと軽い気持ちで)作業計画にない指示をしてしまいます。その結果、実施したタスクの結果をドキュメントにしてくれなくなったり、ステップごとに承認を求めるように指示しているのに(ステップから外れた作業なのだから文字通りとらえれば指示違反ではないのですが)承認を求めずに次々と作業を進めたり……という状況になることがあります。 現在は、指示プロンプトを改めて入力してやり直す、というのが私の対応です。それでもうまく指示が伝わらないなと感じたときは、別のセッションを開始するようにしています。ここでセッション引継ぎのための準備が役に立ってくれます。 プロンプトの最適化について このように開発をしていると大小取りまぜ気になる部分が出てくるのでそれに対処するためにプロンプトに指示を追加していくのですが、ある程度プロンプトが長くなってくると、守ってもらえない指示が増えていきます。今のところ、優先度の低い指示は予めプロンプトとして与えず、問題が出たときに都度対応するようにしています。 最後に Amazon Q Developer, AI-DLCについての所感などをつらつらと書いてみました。 計画を立てて一つ一つステップを踏んで……と進めていると、自分が詳しい分野については自分の手でコードを書いた方が早いのでは?と感じることがありますが、自分に経験がなくAmazon Q Developerがなければ自分で調査と試行錯誤をする必要がある個所の開発は大幅に期間を短縮してくれています。また実際に動くモノの作成に比べて優先度低くなりがちなドキュメント作成・自然言語での説明をきっちりやってくれるので、自分の詳しい分野でもAmazon Q Developerに大幅に任せるようにした方が最終的に運用しやすいシステムが作れるのではないかな?という感覚があります。 生成AIは日進月歩なので、あっという間に状況が変わってしまい、この記事の賞味期限は非常に短いだろうなと思いますが……何らか、なるほどそういうこともあるのか、と感じて頂ければ幸いです。
アバター
今回はRaspberry Piのセンサーで取得したデータをAWS上で加工し、グラフ化してみたいと思います。 Raspberry Piで取得した気温・湿度のデータがAWS IoT Core等を通じて既にS3に入っている前提で、そのデータを加工していきます。 構成イメージ 今回構築するリソースと、データの流れは以下のイメージとなります。   構築してみる S3にjsonファイルを書き出す 以下のように気温・湿度情報のデータをAWS IoTCore等を使用してRaspberry PiからS3に格納します。Raspberry PiからS3への接続方法については、本記事では割愛します。 各ファイル内のデータは以下のような形式のデータとなっています。 {"thing_name": "my_dht22_sensor_pi5","timestamp": "2025-09-26 17:42:32","temperature_c": 25.3,"humidity": 60.5} Glue jobで複数のjsonファイルをまとめる Databaseを作成する GlueのDatabasesから「Add database」をクリックします。 データベース名を入力して「Create database」をクリックします。 作成したデータベースの画面から、「Add table」をクリックします。 以下を入力して「Next」をクリックします。 Name:任意のテーブル名 Database:作成したデータベース名 Schemaに以下を設定し「Next」をクリックします。 timestamp:string temperature_c:double humidity:double 最終確認画面で、「Create」をクリックします。 Glue jobを作成する Athenaで読み込みやすいように、①でS3に置かれている複数のjsonファイルをparquetファイルに成形するGlue jobを作成します。 Glueから「Script editor」をクリックし、EngineはSparkを選択して「Create script」をクリックします。   Scriptタブ 以下コードを入力します。各S3パス、Glue Data Catalog に登録するデータベース名とテーブル名は適宜変更してください。 import sys from awsglue.transforms import * from awsglue.utils import getResolvedOptions from pyspark.context import SparkContext from awsglue.context import GlueContext from pyspark.sql import SparkSession from awsglue.job import Job from pyspark.sql.functions import * from pyspark.sql.types import * from awsglue.dynamicframe import DynamicFrame # ジョブの引数を取得 args = getResolvedOptions(sys.argv, ['JOB_NAME']) # Spark および Glue のコンテキストを初期化 sc = SparkContext() glueContext = GlueContext(sc) spark = glueContext.spark_session job = Job(glueContext) job.init(args['JOB_NAME'], args) # --- 設定 --- # データのS3パス(Raspberry PiからIoT Core経由で来るJSON) raw_data_path = "s3://iot-raspberrypi/iot-before/" # 処理済みデータを保存するS3パス(Parquet形式) processed_data_path = "s3://iot-raspberrypi/iot-after/" # Glue Data Catalog に登録するデータベース名とテーブル名 glue_database_name = "raspberrypi" glue_table_name = "raspberrypitable" # --- データの読み込み --- print(f"DEBUG: Attempting to read data from: {raw_data_path}") # 明示的なスキーマを定義 source_schema = StructType([ StructField("thing_name", StringType(), True), StructField("timestamp", LongType(), True), StructField("temperature_c", DoubleType(), True), StructField("humidity", DoubleType(), True) ]) datasource = glueContext.create_dynamic_frame.from_options( connection_type="s3", connection_options={"paths": [raw_data_path], "groupFiles": "inPartition"}, format="json", format_options={"withHeader": "false", "inferSchema": "false"}, schema=source_schema, transformation_ctx="datasource_raw" ) df_raw = datasource.toDF() # デバッグ出力(変更なし) print("\nDEBUG: --- DataFrame Schema after reading JSON ---") df_raw.printSchema() print("\nDEBUG: --- First 5 rows of raw DataFrame (truncated=False) ---") df_raw.show(5, truncate=False) if "timestamp" in df_raw.columns: print("\nDEBUG: --- Sample values of 'timestamp' column in df_raw ---") df_raw.select("timestamp").limit(10).show(truncate=False) if df_raw.count() == 0: print("DEBUG: No new data to process. Exiting job.") job.commit() sys.exit(0) print(f"DEBUG: Found {df_raw.count()} new records.") # --- データ変換 --- print("\nDEBUG: --- Starting timestamp conversion ---") df_transformed = df_raw.withColumn( "timestamp_seconds", (col("timestamp") / 1000).cast(LongType()) ).withColumn( "timestamp_parsed", from_unixtime(col("timestamp_seconds")) ) # デバッグ出力 print("\nDEBUG: --- DataFrame Schema after timestamp conversion ---") df_transformed.printSchema() print("\nDEBUG: --- First 5 rows of transformed DataFrame (truncated=False) ---") df_transformed.show(5, truncate=False) # 最終的に保存したい列を選択 df_final = df_transformed.select( col("timestamp"), col("timestamp_parsed").alias("event_timestamp_utc"), col("temperature_c"), col("humidity") ) # --- データの書き出しとGlue Data Catalogの更新 --- print(f"Writing processed data to: {processed_data_path}") processed_dynamic_frame = DynamicFrame.fromDF(df_final, glueContext, "processed_dynamic_frame") glueContext.write_dynamic_frame.from_options( frame=processed_dynamic_frame, connection_type="s3", connection_options={ "path": processed_data_path }, format="parquet", transformation_ctx="datasink", ) job.commit() print("Glue Job finished successfully.")   job detailsタブ 以下の値を設定します。 Name:ジョブ名を任意の名前に指定します。 IAM Role:S3バケットへの読み書き権限とAWSGlueServiceRoleが付与されたIAM Roleを作成し、アタッチします。   画面右上の「Save」ボタンをクリックします。 Runsタブ 右上の「Run」ボタンをクリックします。Job runs一覧に実行した履歴が出力されますので、画面リフレッシュしつつステータスがSuccessになるまで待ちます。 ステータスがSuccessになったらGluejobの設定は完了です。 Quicksightでグラフを作成する データセットの作成 Quicksightアカウントにログインし、データセットタブから「新しいデータセットを作成」をクリックします。 「Athena」をクリックします。 データソース名に任意の名前を入力して「データソースを作成」をクリックします。 カタログはAwsDataCatalogを選択し、データベースとテーブルは②で作成したものを選択します。 「カスタムSQLを使用」をクリックします。 以下SQLを入力します。(データセット名、テーブル名は適宜変更してください) SELECT  CAST(timestamp AS TIMESTAMP) AS event_time_utc, temperature_c, humidity FROM  "raspberrypi"."raspberrypitable" 「迅速な分析のためにSPICEへインポート」を選択して「Visualize」をクリックします。 分析の作成 そのまま以下の画面に遷移しますので、グラフを作成していきます。 以下を選択します。 ビジュアルタイプ:折れ線グラフ X軸:event_time_utc Y軸:humidity、temperature_c グラフが表示されました! 終わりに 今回はRaspberry Piで取得したデータをAWS上でグラフ化してみました。 気温・湿度情報をリアルタイムに取得するとなるとファイル数が膨大になるため、今回はGlue jobを使ってデータをまとめる方法で構築してみました。 Raspberry PiのようなIoTとAWSなどのクラウドサービスの掛け合わせについては、更に実用的な構築が無いか今後も検証してみたいと思います。
アバター
今回は、Amazon GuardDuty による脅威検出と脅威通知を AWS CDK で実装する方法をまとめました。 はじめに 今回は、AWS GuardDutyを使用して、VPCフローログ、CloudTrail、DNSログを機械学習で分析し、悪意のある活動や異常な行動パターンをリアルタイムで検出して通知するリソースをAWS CDKで実装していきます。Guard Dutyによる脅威検出とS3への長期保存、EventBridge経由での即座な通知を組み合わせて実装します。 今回作成するリソース SNSトピック : GuardDuty脅威検出結果の通知 KMS暗号化キー : GuardDutyデータの暗号化 S3バケット : 検出結果の長期保存とアーカイブ AWS GuardDuty : 機械学習ベースの脅威検出エンジン EventBridge : 重要度別の自動通知ルール アーキテクチャ概要   AWS CDK ソースコード SNS通知設定 const emailAddresses = [ // SNS通知先メーリングリスト(通知先が複数ある場合はアドレスを追加) 'xxxxxx@example.com', 'xxxxxxx@example.com', ]; // GuardDuty用トピック const guardDutyTopic = new sns.Topic(this, 'GuardDutyTopic', { topicName: 'guardduty-alertnotification', // トピック名 displayName: 'GuardDuty Alert Notifications' // 表示名 }); // GuardDuty用サブスクリプション emailAddresses.forEach(email => { guardDutyTopic.addSubscription( new subscriptions.EmailSubscription(email) // プロトコル:EMAIL ); }); ポイント: 複数の管理者への通知配信 アラーム発生時に通知するメールアドレスを指定 KMS暗号化キー設定 const guardDutyKey = new kms.Key(this, 'GuardDutyKey', { alias: 'alias/guardduty-key', // エイリアス名 description: 'KMS key for GuardDuty encryption', // 説明 enableKeyRotation: true, // ローテーションの有効化 removalPolicy: cdk.RemovalPolicy.DESTROY // スタック削除時にキーを削除する ※デプロイ時にRETAINに変更 }); cdk.Tags.of(guardDutyKey).add('Name', 'guardduty-key'); // Nameタグ ポイント: セキュリティ強化 : GuardDuty専用の暗号化キー 自動ローテーション : セキュリティ基準に準拠した定期的なキー更新 アクセス制御 : 後述のキーポリシーで細かいアクセス制御 S3バケット設定(検出結果エクスポート) // GuardDuty用S3バケット const guardDutyBucket = new s3.Bucket(this, 'GuardDutyBucket', { bucketName: 's3b-guardduty', // バケット名 blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, // パブリックアクセスをすべてブロック encryption: s3.BucketEncryption.S3_MANAGED, // 暗号化タイプ:SSE-S3 enforceSSL: true, // SSL通信を強制 autoDeleteObjects: true, // スタック削除時にオブジェクトを自動的に削除 ※デプロイ時にコメントアウト removalPolicy: cdk.RemovalPolicy.DESTROY, // スタック削除時にバケットも削除 ※デプロイ時にRETAINに修正 lifecycleRules: [ // ライフサイクルルール作成 { id: 'Expiration Rule 12 Months', // ライフサイクルルール名 expiration: cdk.Duration.days(366), // オブジェクトの現行バージョンの有効期限:366日後にオブジェクトを削除 } ] }); guardDutyBucket.addToResourcePolicy(new iam.PolicyStatement({ // ポリシー追加1 sid: 'Deny incorrect encryption header', effect: iam.Effect.DENY, actions: ['s3:PutObject'], resources: [`${guardDutyBucket.bucketArn}/*`], principals: [new iam.ServicePrincipal('guardduty.amazonaws.com')], conditions: { StringNotLike: { 's3:x-amz-server-side-encryption-aws-kms-key-id': guardDutyKey.keyArn } } })); guardDutyBucket.addToResourcePolicy(new iam.PolicyStatement({ // ポリシー追加2 sid: 'Deny unencrypted object uploads', effect: iam.Effect.DENY, actions: ['s3:PutObject'], resources: [`${guardDutyBucket.bucketArn}/*`], principals: [new iam.ServicePrincipal('guardduty.amazonaws.com')], conditions: { StringNotEquals: { 's3:x-amz-server-side-encryption': 'aws:kms' } } })); ポイント: セキュア設計 : パブリックアクセス完全ブロック、SSL強制 暗号化必須 : KMS暗号化のみを許可するバケットポリシー 長期保存 : セキュリティ調査用の1年間保持 コンプライアンス : 暗号化されていないデータの拒否 AWS GuardDuty設定 const guardDutyDetector = new guardduty.CfnDetector(this, 'GuardDuty', { enable: true, // GuardDutyの有効化 findingPublishingFrequency: 'FIFTEEN_MINUTES', // 検出結果の更新頻度:15分 dataSources: { // データソースの設定 s3Logs: { enable: true // S3アクセスログの監視有効化 }, malwareProtection: { // マルウェア保護の設定 scanEc2InstanceWithFindings: { ebsVolumes: true // EBSボリュームのスキャン有効化 } } } }); const s3Export = new guardduty.CfnPublishingDestination(this, 'S3Export', { detectorId: guardDutyDetector.ref, // GuardDuty Detectorの参照 destinationType: 'S3', // 出力先のタイプ destinationProperties: { // 出力先のプロパティ destinationArn: guardDutyBucket.bucketArn, // 出力先:S3バケット kmsKeyArn: guardDutyKey.keyArn // KMSキーのARN } }); ポイント: 包括的監視 : VPCフローログ、CloudTrail、DNSログ、S3アクセスログ マルウェア保護 : EBSボリュームの自動スキャン機能 リアルタイム更新 : 15分間隔での検出結果更新 暗号化エクスポート : KMS暗号化でのS3保存 権限設定(KMS・S3ポリシー) // KMSポリシー guardDutyKey.addToResourcePolicy(new iam.PolicyStatement({ // ポリシー追加1 sid: 'Allow GuardDuty to encrypt findings', effect: iam.Effect.ALLOW, actions: ['kms:GenerateDataKey*'], resources: ['*'], principals: [new iam.ServicePrincipal('guardduty.amazonaws.com')], conditions: { StringEquals: { 'aws:SourceAccount': cdk.Stack.of(this).account }, StringLike: { 'aws:SourceArn': `arn:aws:guardduty:${cdk.Stack.of(this).region}:${cdk.Stack.of(this).account}:detector/${guardDutyDetector.attrId}` } } })); // GuardDutyポリシー guardDutyBucket.addToResourcePolicy(new iam.PolicyStatement({ // ポリシー追加3 sid: 'Allow PutObject', effect: iam.Effect.ALLOW, actions: ['s3:PutObject'], resources: [`${guardDutyBucket.bucketArn}/*`], principals: [new iam.ServicePrincipal('guardduty.amazonaws.com')], conditions: { StringEquals: { 'aws:SourceAccount': cdk.Stack.of(this).account, 'aws:SourceArn': `arn:aws:guardduty:${cdk.Stack.of(this).region}:${cdk.Stack.of(this).account}:detector/${guardDutyDetector.attrId}` } } })); // GuardDutyポリシー guardDutyBucket.addToResourcePolicy(new iam.PolicyStatement({ // ポリシー追加4 sid: 'Allow GetBucketLocation', effect: iam.Effect.ALLOW, actions: ['s3:GetBucketLocation'], resources: [`${guardDutyBucket.bucketArn}`], principals: [new iam.ServicePrincipal('guardduty.amazonaws.com')], conditions: { StringEquals: { 'aws:SourceAccount': cdk.Stack.of(this).account, 'aws:SourceArn': `arn:aws:guardduty:${cdk.Stack.of(this).region}:${cdk.Stack.of(this).account}:detector/${guardDutyDetector.attrId}` } } })); ポイント: 最小権限 : GuardDutyサービスのみに必要な権限を付与 アカウント制限 : SourceAccount条件でクロスアカウントアクセス防止 ソースARN制限 : 特定のGuardDuty Detectorのみからのアクセス許可 EventBridge統合 const guardDutyRule = new events.Rule(this, 'GuardDutyEventRule', { // GuardDuty用のEventBridge ruleName: 'eventbridge-rule-guardduty', // ルール名 eventPattern: { // イベントパターンを指定 source: ['aws.guardduty'], detailType: ['GuardDuty Finding'], // GuardDutyによって検出された結果(Findings)がインポートされた際に発行されるイベント detail: { severity: [ { numeric: [ '>=', 7 ] // 重要度高(7.0~8.9)を通知 } ] } }, targets: [ // ターゲットを指定 new targets.SnsTopic(guardDutyTopic) // ターゲットタイプ: SNSトピック、トピック: GuardDuty用のトピック ] }); ポイント: 重要度フィルタリング : 7.0以上の高リスク脅威のみ通知 今回実装したコンストラクトファイルまとめ import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; import * as sns from 'aws-cdk-lib/aws-sns'; import * as subscriptions from 'aws-cdk-lib/aws-sns-subscriptions'; import * as kms from 'aws-cdk-lib/aws-kms'; import * as s3 from 'aws-cdk-lib/aws-s3'; import * as iam from 'aws-cdk-lib/aws-iam'; import * as guardduty from 'aws-cdk-lib/aws-guardduty'; import * as events from 'aws-cdk-lib/aws-events'; import * as targets from 'aws-cdk-lib/aws-events-targets'; export interface GuardDutyConstructProps { // 必要に応じて追加のプロパティを定義 } export class GuardDutyConstruct extends Construct { constructor(scope: Construct, id: string, props?: GuardDutyConstructProps) { super(scope, id); //=========================================== // SNS //=========================================== const emailAddresses = [ // SNS通知先メーリングリスト(通知先が複数ある場合はアドレスを追加) 'xxxxxx@example.com', 'xxxxxxx@example.com', ]; // GuardDuty用トピック const guardDutyTopic = new sns.Topic(this, 'GuardDutyTopic', { topicName: 'guardduty-alertnotification', // トピック名 displayName: 'GuardDuty Alert Notifications' // 表示名 }); // GuardDuty用サブスクリプション emailAddresses.forEach(email => { guardDutyTopic.addSubscription( new subscriptions.EmailSubscription(email) // プロトコル:EMAIL ); }); //=========================================== // KMS //=========================================== const guardDutyKey = new kms.Key(this, 'GuardDutyKey', { alias: 'alias/guardduty-key', // エイリアス名 description: 'KMS key for GuardDuty encryption', // 説明 enableKeyRotation: true, // ローテーションの有効化 removalPolicy: cdk.RemovalPolicy.DESTROY // スタック削除時にキーを削除する ※デプロイ時にRETAINに変更 }); cdk.Tags.of(guardDutyKey).add('Name', 'guardduty-key'); // Nameタグ //=========================================== // S3 //=========================================== // GuardDuty用S3バケット const guardDutyBucket = new s3.Bucket(this, 'GuardDutyBucket', { bucketName: 's3b-guardduty', // バケット名 blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, // パブリックアクセスをすべてブロック encryption: s3.BucketEncryption.S3_MANAGED, // 暗号化タイプ:SSE-S3 enforceSSL: true, // SSL通信を強制 autoDeleteObjects: true, // スタック削除時にオブジェクトを自動的に削除 ※デプロイ時にコメントアウト removalPolicy: cdk.RemovalPolicy.DESTROY, // スタック削除時にバケットも削除 ※デプロイ時にRETAINに修正 lifecycleRules: [ // ライフサイクルルール作成 { id: 'Expiration Rule 12 Months', // ライフサイクルルール名 expiration: cdk.Duration.days(366), // オブジェクトの現行バージョンの有効期限:366日後にオブジェクトを削除 } ] }); guardDutyBucket.addToResourcePolicy(new iam.PolicyStatement({ // ポリシー追加1 sid: 'Deny incorrect encryption header', effect: iam.Effect.DENY, actions: ['s3:PutObject'], resources: [`${guardDutyBucket.bucketArn}/*`], principals: [new iam.ServicePrincipal('guardduty.amazonaws.com')], conditions: { StringNotLike: { 's3:x-amz-server-side-encryption-aws-kms-key-id': guardDutyKey.keyArn } } })); guardDutyBucket.addToResourcePolicy(new iam.PolicyStatement({ // ポリシー追加2 sid: 'Deny unencrypted object uploads', effect: iam.Effect.DENY, actions: ['s3:PutObject'], resources: [`${guardDutyBucket.bucketArn}/*`], principals: [new iam.ServicePrincipal('guardduty.amazonaws.com')], conditions: { StringNotEquals: { 's3:x-amz-server-side-encryption': 'aws:kms' } } })); //=========================================== // GuardDuty作成 //=========================================== const guardDutyDetector = new guardduty.CfnDetector(this, 'GuardDuty', { enable: true, // GuardDutyの有効化 findingPublishingFrequency: 'FIFTEEN_MINUTES', // 検出結果の更新頻度:15分 dataSources: { // データソースの設定 s3Logs: { enable: true // S3アクセスログの監視有効化 }, malwareProtection: { // マルウェア保護の設定 scanEc2InstanceWithFindings: { ebsVolumes: true // EBSボリュームのスキャン有効化 } } } }); const s3Export = new guardduty.CfnPublishingDestination(this, 'S3Export', { detectorId: guardDutyDetector.ref, // GuardDuty Detectorの参照 destinationType: 'S3', // 出力先のタイプ destinationProperties: { // 出力先のプロパティ destinationArn: guardDutyBucket.bucketArn, // 出力先:S3バケット kmsKeyArn: guardDutyKey.keyArn // KMSキーのARN } }); // GuardDuty Detectorへの依存関係を追加 s3Export.node.addDependency(guardDutyDetector); // S3バケットへの依存関係を追加(必要に応じて) s3Export.node.addDependency(guardDutyBucket); // KMSキーへの依存関係を追加(必要に応じて) s3Export.node.addDependency(guardDutyKey); //=========================================== // KMS/S3 一部ポリシー追加 //=========================================== // KMSポリシー guardDutyKey.addToResourcePolicy(new iam.PolicyStatement({ // ポリシー追加1 sid: 'Allow GuardDuty to encrypt findings', effect: iam.Effect.ALLOW, actions: ['kms:GenerateDataKey*'], resources: ['*'], principals: [new iam.ServicePrincipal('guardduty.amazonaws.com')], conditions: { StringEquals: { 'aws:SourceAccount': cdk.Stack.of(this).account }, StringLike: { 'aws:SourceArn': `arn:aws:guardduty:${cdk.Stack.of(this).region}:${cdk.Stack.of(this).account}:detector/${guardDutyDetector.attrId}` } } })); // GuardDutyポリシー guardDutyBucket.addToResourcePolicy(new iam.PolicyStatement({ // ポリシー追加3 sid: 'Allow PutObject', effect: iam.Effect.ALLOW, actions: ['s3:PutObject'], resources: [`${guardDutyBucket.bucketArn}/*`], principals: [new iam.ServicePrincipal('guardduty.amazonaws.com')], conditions: { StringEquals: { 'aws:SourceAccount': cdk.Stack.of(this).account, 'aws:SourceArn': `arn:aws:guardduty:${cdk.Stack.of(this).region}:${cdk.Stack.of(this).account}:detector/${guardDutyDetector.attrId}` } } })); // GuardDutyポリシー guardDutyBucket.addToResourcePolicy(new iam.PolicyStatement({ // ポリシー追加4 sid: 'Allow GetBucketLocation', effect: iam.Effect.ALLOW, actions: ['s3:GetBucketLocation'], resources: [`${guardDutyBucket.bucketArn}`], principals: [new iam.ServicePrincipal('guardduty.amazonaws.com')], conditions: { StringEquals: { 'aws:SourceAccount': cdk.Stack.of(this).account, 'aws:SourceArn': `arn:aws:guardduty:${cdk.Stack.of(this).region}:${cdk.Stack.of(this).account}:detector/${guardDutyDetector.attrId}` } } })); //=========================================== // EventBridge //=========================================== // GuardDuty用ルール const guardDutyRule = new events.Rule(this, 'GuardDutyEventRule', { // GuardDuty用のEventBridge ruleName: 'eventbridge-rule-guardduty', // ルール名 eventPattern: { // イベントパターンを指定 source: ['aws.guardduty'], detailType: ['GuardDuty Finding'], // GuardDutyによって検出された結果(Findings)がインポートされた際に発行されるイベント detail: { severity: [ { numeric: [ '>=', 7 ] // 重要度高(7.0~8.9)を通知 } ] } }, targets: [ // ターゲットを指定 new targets.SnsTopic(guardDutyTopic) // ターゲットタイプ: SNSトピック、トピック: GuardDuty用のトピック ] }); } } まとめ 今回は、AWS GuardDutyを活用した機械学習ベースの脅威検出システムをAWS CDKで実装しました。 皆さんのお役に立てば幸いです。
アバター
Amazon EC2のユーザーデータには16KBという制限があり、インフラ構築案件等での複雑なOS設定には不十分です。 本記事では、AWS CDK Assetを活用して、この制限を回避するアーキテクチャの実装方法を解説します。 ユーザーデータ入力を使用して EC2 インスタンスを起動するときにコマンドを実行する - Amazon Elastic Compute Cloud ユーザーデータスクリプトを入力として渡すことで、インスタンスの起動時にコマンドを実行して設定タスクを実行できます。 docs.aws.amazon.com   概要図 OS設定スクリプトをcdk bootstrap実行時に作成されるS3 assetに配置することでユーザーデータのサイズ制限を回避して、OS設定スクリプトをEC2にダウンロードさせています。           Assets and the AWS CDK - AWS Cloud Development Kit (AWS CDK) v2 Assets are local files, directories, or Docker images. docs.aws.amazon.com   aws-cdk-lib.aws_s3_assets module · AWS CDK Language | Package docs.aws.amazon.com   処理フロー   実装方法 必要最低限のリソース記述のみしていますので、実際に必要な情報などは補完してご利用ください。 処理の補足はコメントアウトに記載しています。 プロジェクト構造 project/ ├── lib/ │ ├── infra-stack.ts │ └── scripts/ │ ├── bootstrap.ps1 # ユーザーデータ(16KB以内) │ └── userdata.ps1 # OS設定スクリプト(16KB超可能) ├── bin/ │ └── app.ts └── package.json CDKファイル import * as cdk from 'aws-cdk-lib'; import * as ec2 from 'aws-cdk-lib/aws-ec2'; import * as s3 from 'aws-cdk-lib/aws-s3'; import * as iam from 'aws-cdk-lib/aws-iam'; import * as assets from 'aws-cdk-lib/aws-s3-assets'; import * as fs from 'fs'; import * as path from 'path'; import { Construct } from 'constructs'; export class InfraStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // =========================================== // 1. OS設定スクリプトAssetの作成 // =========================================== // 【CDK Asset の仕組み】 // - CDKデプロイ時に指定されたファイルを自動的にS3にアップロード // - バケット名・オブジェクトキーは CDK が自動生成 const osScriptAsset = new assets.Asset(this, 'OSScriptAsset', { path: path.join(__dirname, 'scripts', 'userdata.ps1'), // スクリプトのパス description: 'OS configuration script for EC2 instances' }); // =========================================== // 2. EC2用IAMロールと権限設定 // =========================================== // EC2インスタンスが使用するIAMロール const ec2Role = new iam.Role(this, 'EC2Role', { assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'), description: 'EC2 role for OS script execution', managedPolicies: [ iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore'), ] }); // CDK Assetへの読み取り権限を自動付与 osScriptAsset.grantRead(ec2Role); // =========================================== // 3. ユーザーデータ作成関数 // =========================================== // 【ホスト名設定】 // 1つのスクリプトで複数の異なるホスト名を設定できるように関数の引数としてホスト名を受け取る設計にしている // 例:Web-Server-01, DB-Server-01 など用途別のホスト名が可能 const createUserData = (hostname: string) => { // Windows用のユーザーデータオブジェクトを作成 const userData = ec2.UserData.forWindows(); // Asset情報とホスト名を環境変数として設定 // これらの環境変数はEC2起動時にユーザーデータスクリプトから参照される userData.addCommands( // CDKが自動解決するAsset情報を環境変数に設定 `$env:SCRIPT_S3_BUCKET="${osScriptAsset.s3BucketName}"`, // Assetが保存されたバケット名 `$env:SCRIPT_S3_KEY="${osScriptAsset.s3ObjectKey}"`, // Assetのオブジェクトキー(パス) `$env:SCRIPT_S3_REGION="${this.region}"`, // 現在のAWSリージョン `$env:TARGET_HOSTNAME="${hostname}"`, // 設定したいホスト名 `$env:LOGS_S3_BUCKET="${logsBucket.bucketName}"`, // ログ出力先バケット ); // bootstrap.ps1(ユーザーデータスクリプト)をユーザーデータに埋め込み userData.addCommands(fs.readFileSync( path.join(__dirname, 'scripts', 'bootstrap.ps1'), //ユーザーデータスクリプトのパス 'utf8' // テキストファイルとして読み込み )); return userData; }; // =========================================== // 4. EC2インスタンス作成 // =========================================== // 既存のキーペアを参照(事前にAWSコンソールで作成が必要) const keyPair = ec2.KeyPair.fromKeyPairName( this, 'KeyPair', `test-key` // 実際のキーペア名に置き換える ); //EC2インスタンス作成 const instance = new ec2.Instance(this, 'EC2Instance', { vpc, vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS }, instanceType: ec2.InstanceType.of( ec2.InstanceClass.T3, ec2.InstanceSize.MEDIUM ), machineImage: ec2.MachineImage.latestWindows( ec2.WindowsVersion.WINDOWS_SERVER_2022_JAPANESE_FULL_BASE ), securityGroup, keyPair, // Asset情報を含むユーザーデータを設定 // ここで設定されたホスト名がWindows側に反映される userData: createUserData('dev-server-01'), // ホスト名を指定 role: ec2Role requireImdsv2: true, blockDevices: [{ deviceName: '/dev/sda1', volume: ec2.BlockDeviceVolume.ebs(50, { encrypted: true, volumeType: ec2.EbsDeviceVolumeType.GP3, }), }], }); } } ユーザーデータスクリプト(PowerShell) # ログ設定 $logDir = "C:\temp\logs" New-Item -ItemType Directory -Force -Path $logDir | Out-Null $logFile = "$logDir\bootstrap.log" function Write-Log { param([string]$Message) $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $logMessage = "[$timestamp] $Message" Add-Content -Path $logFile -Value $logMessage Write-Host $logMessage } Write-Log "Bootstrap started" # ホスト名変更 if ($env:TARGET_HOSTNAME) { Write-Log "Setting hostname to: $($env:TARGET_HOSTNAME)" try { if ($env:COMPUTERNAME -ne $env:TARGET_HOSTNAME) { Rename-Computer -NewName $env:TARGET_HOSTNAME -Force Write-Log "Hostname changed successfully" $script:restartRequired = $true } } catch { Write-Log "Hostname change failed: $_" } } # AWS CLI インストール Write-Log "Installing AWS CLI" try { $client = New-Object System.Net.WebClient $client.DownloadFile( "https://awscli.amazonaws.com/AWSCLIV2.msi", "C:\temp\AWSCLIV2.msi" ) Start-Process -FilePath "msiexec.exe" -ArgumentList "/i C:\temp\AWSCLIV2.msi /quiet" -Wait Write-Log "AWS CLI installed" } catch { Write-Log "AWS CLI installation failed: $_" } # OS設定スクリプトのダウンロードと実行 Write-Log "Downloading OS configuration script" try { # CDKから渡された環境変数 $bucket = $env:SCRIPT_S3_BUCKET $key = $env:SCRIPT_S3_KEY $region = $env:SCRIPT_S3_REGION if (-not $bucket -or -not $key) { throw "Missing S3 information" } Write-Log "Downloading from s3://$bucket/$key" $scriptPath = "C:\temp\userdata.ps1" & aws s3 cp "s3://$bucket/$key" $scriptPath --region $region if (Test-Path $scriptPath) { Write-Log "Script downloaded successfully" # セキュリティブロック解除 Unblock-File -Path $scriptPath # スクリプト実行 Write-Log "Executing OS configuration script" & powershell.exe -ExecutionPolicy Bypass -File $scriptPath Write-Log "OS configuration completed" } else { throw "Script download failed" } } catch { Write-Log "OS script execution failed: $_" } Write-Log "Bootstrap completed" 注意事項 EC2インスタンスからインターネットアクセスが必要になります(NAT Gateway経由)   まとめ こちらの実装パターンの活用によりCDKでのEC2インスタンス構築時にOS設定まですることができ、テンプレートとなるOS設定スクリプトを作成することで再利用性のメリットを享受することが可能になります。
アバター
この記事では、Zabbix 7.4で登場した新機能である  ホストウィザード による、ホスト登録の手順をご紹介します。 ホストウィザードは、画面の案内にステップバイステップで従うだけで、迷うことなくホストを作成できる、初心者の方にオススメな機能です。   ホスト登録手順 データ収集 -> ホスト -> ホストウィザード からホストウィザード画面を開きます。 「ホストウィザードへようこそ」が表示されたら「次へ」を押下します。   テンプレートを選択 登録するホストに紐づけるテンプレートを選択します。 テンプレートを検索するためのキーワードを入力すると、キーワードの文字列を含むテンプレートが表示されるため、その中からホストに紐づけるテンプレートを選択します。 今回だとLinux by Zabbix agentのテンプレートを選択します。   ホストの作成または選択 登録するホストの、ホスト名とホストグループを作成または選択します。 今回は、新規にホストとホストグループを登録します。   Zabbixエージェントインストール ZabbixサーバーのIPアドレスを入力します。   ホストウィザードを使ったエージェント登録では、 ZabbixサーバーとZabbixエージェント間の暗号化が必須 となっております。 事前共有キー識別子に任意の文字列を入力し、事前共有キーを取得します。 監視対象のOSを選択します。今回のエージェントは、LinuxのためLinuxを選択します。   上記の項目を入力すると、Zabbixエージェントをインストールするコマンドが自動的に作成されます。 こちらのコマンドをコピーし、Zabbixエージェントを導入するサーバに貼り付けて実行します。 ※コマンドの実行に際して、対象のサーバーはインターネット疎通が必要となります。   コマンドを実行すると、Zabbixエージェントが導入されて、自動で起動してきます。   ホストインターフェースを追加 登録するZabbixエージェントのIPアドレスとポート番号を入力します。 ポート番号をデフォルトのポート番号から変更する場合は、/etc/zabbix/zabbix_agentd2.confのListenPortを、変更後のポート番号に書き換えてください。   ホストの設定 ホストの設定では、ホストマクロなどを定義します。今回はデフォルト値で進めます。   「作成する」を押下してホストを作成します。   作成確認 問題なく設定されていると、こちらのように設定完了画面が表示されます。   データ収集 -> ホスト から作成したホストが追加されているか確認します。   まとめ 今回はZabbixのホストウィザードを使ったホスト登録手順を解説しました。 ウィザードの案内に従い、設定値を入力するだけで、誰でも簡単かつ迅速に監視を開始できます。特に初心者の方にとって、ホスト登録のハードルを大きく下げてくれる強力な機能です。 この記事を参考に、ぜひご自身の環境でもホストウィザードを体験してみてください。 最後までお読みいただき、ありがとうございました!   ▼ Zabbixに関するおすすめ記事 【Zabbix】トリガーアクションでスクリプトを実行する方法 本ブログではZabbixのトリガーアクションで障害対応を自動化する方法を解説します。 今回はトリガーアクションの中でもスクリプトの実行方法について説明します。 blog.usize-tech.com 2025.06.10 スクリプトを用いてZabbixサーバのインストールを自動化してみた-RHEL系OS/MySQL編- Zabbixサーバのインストールを自動化するシェルスクリプトを紹介します!初心者でも簡単に短時間でZabbixサーバの構築が可能となります。スクリプトを用いた構築で効率化をしましょう! blog.usize-tech.com 2025.09.02 Zabbixにセキュリティパッチは無い?Zabbixにおける脆弱性対応とマイナーバージョンアップの方法 Zabbixってセキュリティパッチあるの?いえ、ないのでバージョンアップで脆弱性に対応します。マイナーバージョンアップ方法も紹介します。 blog.usize-tech.com 2025.07.17
アバター
こんにちは、SCSKの前田です。 いつも TechHarmony をご覧いただきありがとうございます。 今回は、Windows 版 LifeKeeper / DataKeeper の最新バージョン v8.11.0 に追加された新機能を中心に、製品の進化ポイントをご紹介します。 はじめに Windows 版 LifeKeeper 製品の最新バージョンでは、 新機能の追加 に加え、 バグ修正・機能強化 、そして アップグレード時の注意点 がリリースノートに記載されています。 本記事では、それらの内容をわかりやすく整理し、皆さまのシステム運用に役立つ情報をお届けします。 本記事公開時点での LifeKeeper 関連製品の最新バージョンは以下の通りです: LifeKeeper for Windows v8.11.0 DataKeeper for Windows v8.11.0 LifeKeeperとは?(おさらい) LifeKeeper は、ビジネスの継続性を支える 高可用性(HA: High Availability)クラスターソフトウェア です。 サーバーやアプリケーションに障害が発生した際、その影響を最小限に抑え、 システムが止まることのないよう自動で復旧・切り替え を行うのが LifeKeeper の主要な役割です。 具体的には、 複数のサーバー(ノード)でクラスターを構成 し、稼働系サーバーで障害が発生した場合、LifeKeeper がそれを検知し、 瞬時に待機系サーバーへ処理を移行 します。この一連の自動切り替え処理を「 フェイルオーバー 」と呼びます。 LifeKeeper の強みは、OS・ミドルウェア・データベース・アプリケーションなど、様々な 「保護対象リソース」 の状態を監視し、それらをグループ化して切り替え制御を行える点にあります。 この 柔軟なリソース保護 と、 複雑な設定なしに利用できる使いやすさ が、多くの企業に採用される理由です。 リリースノートでは、この LifeKeeper の 「保護能力」 や 「監視精度」 、そして 「フェイルオーバーの信頼性」 をさらに高めるための新機能や改善点、対応環境の拡充などが記載されています。 最新バージョンで、 より堅牢で効率的なシステム運用 を実現するための進化の全貌を、ぜひご覧ください。 新機能:LifeKeeper/DataKeeperの進化のポイント 本章では、Windows 版 LifeKeeper / DataKeeper の最新バージョンで追加された 注目の新機能 についてご紹介します。 企業システムの信頼性向上や運用効率化に直結する、 実用性の高い機能強化ポイント を中心に解説していきます。 ① Windows Server 2025 への対応強化 最新バージョンでは、 Windows Server 2025 が新たにサポート対象に加わりました。これにより、企業は次世代OS環境への移行をスムーズに進めながら、LifeKeeper / DataKeeper の高可用性機能を継続して活用できます。 特に、 汎用アプリケーション保護におけるVBスクリプト対応 については注意が必要です。Windows Server 2025では、VBスクリプトがオンデマンド機能として提供されており、 有効化されている場合のみ動作 します。これに対応するため、LifeKeeper内の既存VBスクリプトは、 サポートされるスクリプト言語へと変換 されており、より安定した運用が可能となっています。 この対応により、 将来のOS環境でも継続的なHA運用が可能 となり、企業のITインフラの長期的な信頼性確保に貢献します。 ② 障害解析を効率化するクラッシュダンプ収集機能 LifeKeeper v8.11.0 では、 障害発生時のトラブルシューティングを支援する新機能 として、 LK Core プロセスのクラッシュダンプ収集機能 が追加されました。 この機能により、LK Core プロセスに異常が発生した際、 クラッシュダンプが自動的に %LKROOT%/SUPPORT/ProcessDumps フォルダーに出力 されるようになります。 収集の有効・無効は、設定ファイル %LKROOT%\etc\default\LifeKeeper に追加された変数 ENABLE_CRASH_DUMPS によって制御され、デフォルトでは収集が有効(1)となっています。 さらに、 lksupport 実行時にクラッシュダンプが存在する場合、それを自動で回収する機能 も追加されており、障害調査の効率化に貢献します。 設定変更後は、LifeKeeper の再起動または ConfigureDumps.pl ユーティリティの実行により反映されます。 この機能追加により、 障害発生時の原因特定が迅速かつ確実に行えるようになり、システムの信頼性と保守性が大幅に向上 します。 ③ ミラーボリューム上のページファイル作成を制限 DataKeeper v8.11.0 では、 ミラーボリューム上でのページファイル(仮想メモリファイル)の作成を制限する機能 が追加されました。 ページファイルは、Windows が物理メモリを補うために使用する重要なシステムファイルですが、 冗長化されたミラーボリューム上に配置されると、不要な読み書きが発生し、クラスタ全体のパフォーマンスに悪影響を及ぼす可能性 があります。 本バージョンでは、ページファイルの作成がミラーボリューム上で実行された場合でも、 再起動時にはその配置が無効化されるよう制御 されており、意図しない構成による性能低下を防止します。 この機能により、 高可用性クラスタ環境におけるストレージ運用の最適化 が図られ、より安定したシステムパフォーマンスの維持が可能となります。 ④ 最新プラットフォームへの対応拡充 LifeKeeper v8.11.0 では、 企業インフラの最新化を支援する新たなプラットフォーム対応 が追加されました。 まず、 VMware vSAN 8.0 (2025年8月認定)への対応により、仮想化環境での高可用性構成がさらに柔軟に。vSAN は、ストレージの集約と効率化を実現するソリューションであり、これにLifeKeeperが対応することで、 仮想化基盤上でも安定したHAクラスタ運用が可能 となります。 また、 OpenJDK v24.0.1 のサポート追加により、Javaベースの管理ツールやスクリプト環境においても、 最新のセキュリティパッチや機能を活用しながら安定運用が可能 となりました。 これらの対応は、 将来のインフラ拡張やセキュリティ強化を見据えた運用設計 において、企業にとって大きなメリットとなります。 バグ修正・機能強化:システムの安定性と運用性を向上 ここでは、多岐にわたるバグ修正および機能強化について、主な項目を一覧でご紹介します。 LifeKeeper for Windows v8.11.0 No 項目 内容 1 QSPリソースのローカルリカバリー設定に関する修正: QSP(Quick Service Protection)リソースを拡張した際に、プライマリーノードの設定に関わらずバックアップノードのローカルリカバリーが無効になってしまう問題を修正しました。 2 QSPリソースプロパティのタイムアウト表示修正: QSPリソースのプロパティ画面でタイムアウト値を修正する際のエラーダイアログに表示される上限値が誤っていたのを修正しました。 3 Oracleリソース拡張失敗の問題を修正: Oracleリソース拡張が失敗する問題を修正しました。 4 IISリソース:FTPサイト匿名認証無効時のrestore処理修正(deepCheck間隔0): IISリソースでFTPサイトの匿名認証を無効にした際、deepCheck間隔を0にしていてもrestore処理に失敗する問題を修正しました。 5 IISリソース:FTPサイト匿名認証無効時のrestore処理修正(FTPログインスクリプト): IISリソースでFTPサイトの匿名認証を無効にした際、FTPログインスクリプトを作成してもrestore処理に失敗する問題を修正しました。 6 Windows Server 2025でのコミュニケーションパス作成問題を修正: Windows Server 2025環境でコミュニケーションパスの作成ができなくなる問題を修正しました。 7 SQL ARKのスクリプトにおけるパスワード表示問題を修正: SQL Server Recovery Kitのrestoreおよびdeepchkスクリプトでset-xトレース出力にデータベースパスワードが表示されてしまう問題を修正しました。 8 IISリソース:FTPサイトSSL必須時のrestore処理修正: IISリソースでFTPサイトのSSLを必須にした際、restore処理に失敗する問題を修正しました。 9 Windows Server 2025でのwmic有効化問題を修正: Windows Server 2025環境でwmicコマンドが有効にならない問題を修正しました。 10 v8.10.1からのアップグレード中のgetlocks失敗問題を修正: v8.10.1からのLifeKeeperアップグレード中にgetlocksコマンドが失敗する問題を修正しました。 11 QSPリソース変更画面の表示修正: ローカルリカバリーが無効な場合でも、QSPリソースの変更画面で「有効」と誤って表示されるのを修正しました。 DataKeeper for Windows v8.11.0 No 項目 内容 1 DataKeeper共有ボリュームのI/Oフェンシングメカニズムの改善: DataKeeper共有ボリュームのI/Oフェンシングメカニズムを改善しました。 2 IRP_MJ_SHUTDOWN処理の改善: IoRegisterShutdownNotification呼び出しを削除してIRP_MJ_SHUTDOWN処理を改善しました。   スムーズな移行のために:LifeKeeper/DataKeeper アップグレード時の重要事項 LifeKeeper 関連製品のアップグレードを安全かつ確実に実行していただくため、以下の重要な注意点をご確認ください。 LifeKeeper for Windows v8.11.0 共有ストレージリソースとDataKeeperの連携  LifeKeeper for Windows v8.9.0 以降では、共有ストレージを使用した 共有ボリュームリソースの作成・管理に DataKeeper for Windows が必須 となりました。LifeKeeper for Windows v8.9.2 以降のインストーラーには、LifeKeeperとDataKeeperの両方が含まれています。 【補足】 DataKeeper for Windows のミラーリング機能(データ複製機能)を利用しない場合は、DataKeeper のライセンスは不要です。共有ストレージ経由での共有ボリュームリソースの管理に必要なモジュールとして DataKeeper が導入されます。 Perlバージョンの変更とカスタムPerlコードへの影響 LifeKeeper for Windows v8.10.1 以降、同梱されるPerlが Perl 5.32.1 にアップグレード されています。LifeKeeper for Linuxの場合と同様に、 カスタムで Perl コード(Generic ARK など)を使用している場合は、この Perl アップデートに対応するためのコード変更が必要 になる可能性があります。 【対応】 アップグレード前に、ご利用のカスタム Perl コードが新しい Perl バージョンで正しく動作するか、互換性を十分に検証してください。詳細については、「 Perl 5.8.8からPerl 5.32.1へのアップグレード 」ドキュメントをご参照ください。 ライセンス形態の変更と更新(非ノードロックライセンス)  LifeKeeper for Windows および DataKeeper for Windows(Application Recovery Kit など関連製品含む)は、v8.9.1から HostID に依存しない非ノードロックライセンス を提供しています。LifeKeeper v8.9.0 / DataKeeper v8.9.0 までのノードロックライセンスはそのまま使用可能ですが、 新しい非ノードロックライセンスへ切り替える場合は、アップデート後にライセンスの更新作業が必要となります。 【対応】 既存のライセンスを継続利用するか、非ノードロックライセンスへ更新するかを検討し、更新が必要な場合はアップデート後に所定の手順でライセンスを更新してください。 ダウンロードした製品の整合性確認 ダウンロードした製品ファイルの整合性を確認するために、 md5sum を使用することをお勧めします。 【コマンド例】 certutil -hashfile <file> MD5 このコマンドを実行すると、ダウンロードしたファイルの MD5 ハッシュ値が出力されますので、提供されている .md5 ファイルの内容と比較して、ファイルが破損していないことを確認してください。 8.10.1 以前からのアップデート時の注意点(ローリングアップデート) v8.10.1 以前のバージョンからアップデートする際に、 クラスター内の片方のノードだけをアップデートし、その状態でリソースを In-service にすると、イベントログに 「lcdwait.exe: -R option is required」 というメッセージが出力される場合があります。 【対応】 このメッセージは、もう片方のノードも同じバージョンにアップデートすることで出力されなくなります。これは、ローリングアップデート中に一時的に発生する可能性のある警告であり、両ノードのアップデートが完了すれば解消されます。 DataKeeper for Windows v8.11.0 ローリングアップデートのサポート DataKeeper for Windows v8.11.0 では、対象システムを切り替えて更新する ローリングアップデートがサポートされています。   【補足】  これにより、サービス停止時間を最小限に抑えながら、クラスター内のノードを順番にアップデートすることが可能です。具体的な手順については、公式ドキュメントを参照してください。 まとめ 今回は、LifeKeeper製品の最新バージョンに記載されている新機能、バグ修正/機能強化、そしてアップグレードの注意点についてご紹介いたしました。 ビジネス継続性を支える高可用性(HA)クラスターソフトウェアとして、LifeKeeperは常に進化を続けており、およそ半年に一度のペースでアップグレードを実施しています。 今後もLifeKeeperの新機能や改善点、対応環境の拡充など、皆さまがより堅牢で効率的なシステム運用を実現できるよう、LifeKeeperに関する情報発信を続けてまいります。 最後までお読みいただき、誠にありがとうございました。 詳しい内容をお知りになりたいかたは、以下のバナーからSCSK LifeKeeper公式サイトまで
アバター