TECH PLAY

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

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

1141

どうも、SCSK齋藤です。 今回は、Amazon SQSから直接AWS Lambdaを呼び出す際に意識するポイントを3つ紹介します。(個人的につまづいたポイントです。。) Lambda側でSQSからのメッセージを受信する権限が必要 とっても当たり前ですが、忘れがちなポイントです。 具体的には、受信以外にもいろいろな権限が必要になります。 ざっくりと必要な権限は下記です。 {  "Version" : "2012-10-17",  "Statement" : [   {    "Effect" : "Allow",    "Action" : [     "sqs:ReceiveMessage",     "sqs:DeleteMessage",     "sqs:GetQueueAttributes",    ],    "Resource" : "*"   }  ] } SQSを受信するだけでなく、受信した後にメッセージを削除する権限と、SQSの属性の読み取りを行う権限が必要です。 ここら辺の権限については、AWSのマネージドポリシーである「AWSLambdaSQSQueueExecutionRole」を付与すれば一発で権限を充足できます。 AWSLambdaSQSQueueExecutionRole - AWS Managed Policy About the AWS managed policy: AWSLambdaSQSQueueExecutionRole docs.aws.amazon.com   SQSの可視性タイムアウトはLambdaの関数タイムアウト時間の6倍にすること。 SQSのタイムアウト時間を、Lambdaの処理が終了する時間より短く設定すると、Lambda関数が処理中にも関わらず、メッセージがSQSで再度利用可能となり、別のLambda関数が同じメッセージを処理し始めるという事態になります。 Lambda関数の実行中にスロットリングが発生するなどもあり得るため、十分な実行時間を確保しておく必要がございます。 そこで、AWSのドキュメントではLambdaのタイムアウトの6倍を割り当てることを推奨しております。 Lambda が有効な Amazon SQS メッセージを再試行する場合のトラブルシューティング Amazon シンプルキューサービス (Amazon SQS) キュー内のメッセージを処理するように AWS Lambda 関数を設定しました。有効な Amazon SQS メッセージの中には、maxReceiveCount まで複数回受信... repost.aws   SQSのリドライブポリシーでmaxReceiveCount属性を最低5にすること。 Lambdaの同時実行数が最大で、タイミング悪くLambdaが実行できない場合があります。 そういったケースの際に、すぐにDLQに転送するのではなく、合間を置いて再度Lambdaにメッセージを送信することで正しく処理を行うことが可能となります。 maxReceiveCountは、その再試行の回数を指定します。 AWSの推奨では、5以上とのことなのでそのように設定すると良いでしょう。   まとめ 今回は、SQS→Lambdaを呼び出す際に意識するポイントを勝手に3つ挙げました。 SQSもLambdaもいろいろな機能があるため、ユースケースによっては他にも意識することはあるかもしれませんので、引き続き勉強していきたいと思います。 今回あげたポイントは、CloudFormationなどでデプロイする際に、満たしていない場合はデプロイエラーになったりするポイントなので、意識してみることをお勧めします!
アバター
本記事はANGEL Dojo 2024参加者によるアドベントカレンダー「ANGEL Calendar」の最終日の記事になっております。 他のみなさんが書かれた記事は こちら からご覧ください! ※…ANGEL Dojo 2024に関しましては AWS JAPAN APNブログ をご覧ください。 こんにちは、ひるたんぬです。 今日で2024年度上半期が終わりますね。これを書いてふと思ったのですが、なぜ「YYYY年度」は4月始まりなのでしょうか? 1月から始めてくれていれば色々スッキリするのに…と思い、なぜ4月からになったのか調べてみました。 (前略)当初から4月始まりだったわけでなく、明治政府により会計年度が初めて制度化された明治2年(1869)は、10月始まり。続いて、西暦を採用した明治6年からは、1月始まりになりました。つまり、暦年と年度の始まりが同じ時代があったのです。明治8年からは、地租の納期にあわせるという目的で、7月始まりになりました。 次に会計年度を変更したのは、明治17年(1884)。その頃の日本は、 国権強化策から軍事費が激増し、収支の悪化が顕著に なっていました。当時の大蔵卿である松方正義は、 任期中の赤字を削減するために、次年度の予算の一部を今年度の収入に繰り上げる施策 を実施。この施策は珍しくなく、当時はよく行われていました。そして、 予算繰り上げによるやりくりの破綻を防ぐため 、松方は一策を講じました。明治19年度の会計年度のスタートを7月始まりから4月始まりに法改正したのです。(後略) 引用…国立公文書館ニュース「 会計年度はなぜ4月始まりなのか 」 何度も変更されており、その理由も予算の兼ね合いだったんですね。ちょっと予想外でした。 さて、今回はタイトルにもあります通り、Lambda関数を使わずにStep Functionsのみで完結できるケースについて簡単なアプリケーションの比較を通してご紹介します。 この記事は、ANGEL Dojo活動中に紹介された以下の記事に着想を受けて執筆しました。 AWS Step Functions の機能を活用して、Lambda 関数無しで実現できることを確認してみよう ! - builders.flash☆ - 変化を求めるデベロッパーを応援するウェブマガジン | AWS AWS Step Functions の機能を活用して、Lambda 関数を使用せずに様々なタスクを実行する方法をご紹介します。 aws.amazon.com 参考記事でも注意書きとして記載がありますが、本記事においても「全てにおいてStep Functionsを使え!Lambdaは悪!!」という主張はいたしません。私自身LambdaもStep Functionsも大好きです。 「Step Functionsだけでも処理が書けるケースがあるんだ~」くらいの感覚で読んでいただけますと幸いです。 Step Functionsとは? AWSのサーバレスサービスの一つです。複数のアプリケーションやサービスをつなぎ合わせる(オーケストレーション)機能を提供しています。また、コンソール上でビジュアルプログラミングのようにアプリケーションをブロックとして直感的に組み合わせることができるので、プログラミング言語が苦手な人や経験がない人でも触りやすいと思います。 より詳細な特徴などにつきましては、下記サイトをご覧ください。 特徴 - AWS Step Functions | AWS AWS Step Functions を使用して、AWS Lambda 関数や AWS の複数のサービスを、ビジネスクリティカルなアプリケーションに組み立てます。 aws.amazon.com Lambdaをなくしてみた 今回は簡単に、以下のアプリケーションを作ってみました。 ここでご紹介しているアプリケーションは本ブログ執筆のためだけに作ったものです。 Angel Dojoなどで作っているものではありません。 お出かけアシスタント このアプリケーションは今日お出かけしたい場所を入力として与えると、 お出かけしたい場所の最寄り駅 今日の気温に適した服装 を教えてくれます。最寄り駅や気温の取得には外部APIを使用し、気温に適した服装はBedrockに教えてもらうことにします。 Lambda まずはこれをPythonを使ってゴリゴリ書いていきましょう。 今回はStep Functionsの魅力を伝えるため上記要件の処理を並列で処理するようにしています。 Pythonの並列処理についてはいろいろな種類があります(厳密には並列処理でないものも)が、私はひとまずconcurrentというライブラリで書いています。 個人的には以下のサイトで各ライブラリの特徴を学びました。 その並列処理待った! 「Python 並列処理」でググったあなたに捧ぐasync, threading, multiprocessingのざっくりとした説明 - Qiita 対象読者「Python 並列処理」でググってたどり着いたPython, 並列処理の初心者の方。並列処理を使ったことはあるけど、概念をよく知らない方。async, threading, mult… qiita.com このようにして出来上がったのが以下のコードです。 import boto3 import requests import json from concurrent.futures import ThreadPoolExecutor from botocore.exceptions import ClientError def lambda_handler(event, context): # 並列処理 with ThreadPoolExecutor() as executor: near_station = executor.submit(get_near_station, event) outfit_prompt = executor.submit(suggest_outfit_flow, event) near_station_response = near_station.result() outfit_prompt_response = outfit_prompt.result() station = near_station_response["response"]["station"] outfit = outfit_prompt_response["content"] return { "station": station, "outfit": outfit } # 最寄り駅の取得 def get_near_station(location:dict) -> dict: url = "https://www.heartrails-express.com/api/json" params = { "method": "getStations", "x": location["longitude"], "y": location["latitude"] } try: response = requests.get(url, params=params) except requests.exceptions.RequestException as e: raise("Error: ",e) return json.loads(response.content.decode("utf-8")) # 気温の取得 def get_temperture(location:dict) -> dict: url = "https://api.open-meteo.com/v1/forecast" params = { "longitude" : location["longitude"], "latitude" : location["latitude"], "hourly": "temperature_2m", "timezone": "Asia/Tokyo", "forecast_days": "1" } try: response = requests.get(url, params=params) except requests.exceptions.RequestException as e: raise("Error: ",e) return json.loads(response.content.decode("utf-8")) # 服装の考案 def suggest_outfit(temp_data: dict) -> dict: client = boto3.client("bedrock-runtime") # プロンプトの生成 temp = str(temp_data["hourly"]["temperature_2m"]) prompt = "あなたは私の友人で、コーディネーターとして働いています。私は気温に応じて着たり脱いだりすることが嫌いです。今日0時から23時まで1時間ごとの気温は別のリストに与えるとおりです。1日通して私が外出するのに適した上下のコーディネートを簡潔に教えて下さい。" native_request = { "anthropic_version": "bedrock-2023-05-31", "max_tokens": 600, "temperature": 0.5, "messages": [ { "role": "user", "content": [ {"type": "text", "text": prompt}, {"type": "text", "text": temp} ], } ] } request = json.dumps(native_request) try: response = client.invoke_model( body=request, modelId="arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-3-haiku-20240307-v1:0" ) except (ClientError, Exception) as e: print(f"ERROR: Can't invoke '{model_id}'. Reason: {e}") raise(e) return json.loads(response["body"].read().decode("utf-8")) # 気温の取得 -> 服装の考案 def suggest_outfit_flow(location:dict) -> dict: temp_data = get_temperture(location) suggest_result = suggest_outfit(temp_data) return suggest_result …読めなくはないけど、めんどくさい。というのが正直な感想でしょうか。 プログラミングにあまり触れていない方は、この時点で手を離してしまうかもしれません。 また、今回のコードでは「requests」というライブラリを使用しており、これはLambdaで標準では使用できないため、レイヤーなどでライブラリが使用できるようにする必要もあります。 …これも面倒です。 【初心者向け】AWS Lambda Layerの作成方法をわかりやすく解説【Python3.9】 - Qiita 2024年春バージョン を作成しました。AWS Lambdaの開発をしてみようと思うんだけど、Layerって何?Lambdaにどうやったらpip installするの?と思って固まってしまった・… qiita.com Cloud9につきましては使用できない方もいらっしゃると思います。 経緯や代替策につきましては公式サイトなどをご確認ください。 ※ 本記事では本筋と逸れてしまうため割愛させていただきます。 Step Functions 次に同じ処理をStep Functionsで実装してみます。 …ん?それだけ?? そうなんです。こんなにシンプルに書けるのです。 出力結果は…? 両者で同じ入力を与えてみました。 { "latitude": "35.656315", "longitude": "139.795486" } Lambda 戻り値として以下が得られます。 { "station": [ { "name": "豊洲", "prefecture": "東京都", "line": "東京メトロ有楽町線", "x": 139.79621, "y": 35.654908, "postal": "1350061", "distance": "170m", "prev": "月島", "next": "辰巳" }, { "name": "豊洲", "prefecture": "東京都", "line": "新交通ゆりかもめ", "x": 139.795414, "y": 35.653792, "postal": "1350061", "distance": "280m", "prev": "新豊洲", "next": null }, { "name": "新豊洲", "prefecture": "東京都", "line": "新交通ゆりかもめ", "x": 139.789996, "y": 35.648718, "postal": "1350061", "distance": "980m", "prev": "市場前", "next": "豊洲" }, { "name": "越中島", "prefecture": "東京都", "line": "JR京葉線", "x": 139.792713, "y": 35.667946, "postal": "1350044", "distance": "1320m", "prev": "八丁堀", "next": "潮見" } ], "outfit": [ { "type": "text", "text": "はい、分かりました。気温の変化に合わせて、1日中快適に過ごせるようなコーディネートをご提案します。\n\n朝から夕方にかけては、半袖Tシャツに薄手のシャツやカーディガンを羽織るのがおすすめです。\n午後からは、Tシャツ1枚でも問題ありません。\n夕方から夜にかけては、長袖の薄手のシャツやブラウスを着用するのがよいでしょう。\n\n気温の変化に合わせて、上下を調整しながら過ごせば、1日中快適に過ごせると思います。\n軽めの上着を持参するなど、状況に応じて調整できるようにするのがポイントです。" } ] } Step Functions 処理の流れを視覚的に確認することができます。 また、出力「output」として以下が得られます。 { "output": [ { "outfit": [ { "type": "text", "text": "はい、気温の変化に合わせて以下のようなコーディネートをおすすめします。\n\n午前中(0時~11時)は長袖Tシャツとジーンズが適しています。\n午後(12時~17時)は半袖Tシャツとスカートやショートパンツがよいでしょう。\n夕方(18時~23時)は長袖Tシャツとジーンズに戻すのがおすすめです。\n\nコーディネートのポイントは通気性のよい素材を選び、日中は涼しげな服装で、外出時の気温の変化にも対応できるよう、外羽織りを持参することです。\n天候や活動内容によって微調整が必要かもしれませんが、この提案で1日中快適に過ごせると思います。" } ] }, { "station": [ { "name": "豊洲", "prefecture": "東京都", "line": "東京メトロ有楽町線", "x": 139.79621, "y": 35.654908, "postal": "1350061", "distance": "170m", "prev": "月島", "next": "辰巳" }, { "name": "豊洲", "prefecture": "東京都", "line": "新交通ゆりかもめ", "x": 139.795414, "y": 35.653792, "postal": "1350061", "distance": "280m", "prev": "新豊洲", "next": null }, { "name": "新豊洲", "prefecture": "東京都", "line": "新交通ゆりかもめ", "x": 139.789996, "y": 35.648718, "postal": "1350061", "distance": "980m", "prev": "市場前", "next": "豊洲" }, { "name": "越中島", "prefecture": "東京都", "line": "JR京葉線", "x": 139.792713, "y": 35.667946, "postal": "1350044", "distance": "1320m", "prev": "八丁堀", "next": "潮見" } ] } ], "outputDetails": { "truncated": false } } Bedrockの返答に差はあるものの、同じ構造で回答が得られていることが分かりますね。 脱いだり着たりするのが嫌いなのに、Step Functionsではパンツの履き替えまで要求されてますが… プロンプトに関する勉強がまだまだ足りていない模様です。 Step Functionsのここがすごい! ここからは、Step Functionsの個人的な魅力について、先程のアプリケーションをベースにご説明します。 直感的に作ることができる 先程のキャプチャでお分かりいただけたかもしれませんが、Step Functionsはデザインエディタを用いてブロックを並べるだけで処理が実現してしまいます。 特に各種AWSサービスを呼び出して行うものについては220のAWSサービス・10,000以上のAPIと直接統合されています。 ▼ 統合されているAWSサービスの一部 また、この他にも外部APIを叩く機能もあるので、AWSに閉じていないサービスであってもStep Functions上で完結してしまうケースもあります。 外部APIを使用するためには、「Amazon EventBridge Connection」の設定が必要です。 設定は煩雑ではなかったので、詳細は省略いたします。下記参考記事をご覧ください。 タスク状態のテストと外部エンドポイントが AWS Step Functions で利用できるようになりました | Amazon Web Services AWS Step Functions HTTPS エンドポイントでは、サードパーティー API と外部サービス aws.amazon.com プログラミングのような処理も可能 各種AWSサービスや外部APIとの統合に加え、Step Functionsでは「フロー」という項目でプログラミングのような以下の処理を行うことができます。 Choice if-then-elseロジックが実装できます。 Parallel 並列処理が実装できます。 Map 繰り返し処理が実装できます。 Pass 入出力のフィルタや書き換えを実装できます。 ※ 入出力のフィルタやマッピングなどは各処理ブロックでも行えます。 Wait 指定時間フローを停止できます。 Success / Fail フローの成功・失敗を定義できます。 私がLambdaの方でわざわざ並列処理を加えた理由も、このParallelを紹介したかったからです… この他にも各フローでエラー発生時の処理を定義することができますので、エラーハンドリングも実装可能です。 初心者にも上級者にも優しい デザインエディタで直感的に作ることができるメリットは先程ご説明したとおりですが、Step Functionsではフローを指定の言語で記載することもできます。この言語を「Amazon States Languages (ASL)」といいます。 これによりコードベースでの管理も可能ですし、これを利用してCloudFormationでのIaCも実現可能です。 Amazon States Language を使用した Step Functions ワークフローの定義 - AWS Step Functions Amazon States Language を使用して、 で AWS Step Functions ワークフローをタスク、選択肢、結果などの状態のコレクションJSONとして定義します。 docs.aws.amazon.com AWS CloudFormation を使用して Step Functions でワークフローを作成する - AWS Step Functions を使用して Step Functions AWS Lambda ステートマシンを作成する方法について説明します AWS CloudFormation。 docs.aws.amazon.com さらに、コードで作成・編集したものとデザインエディタで作成・編集したものは相互に変換可能です。 個々人にスキルや好みに応じてスタイルを自在に選べるのは嬉しいポイントですね。 本記事の最後に本アプリケーションのStep Functionsで記述したコードを載せます。 ランタイム・ライブラリを気にしなくて良い このポイントが個人的に大きなメリットかなと感じています。 特にPythonなどのプログラミング言語はアップデートも盛んで、当時最新のランタイムで実装していたアプリケーションが、いつの間にか数世代前…なんてことも。 ライブラリについても、標準で入っていないものについては自身で追加が必要など、少し手順が複雑になってしまいます。 Lambdaではレイヤーを導入することにより柔軟性が実現される、という考え方ももちろんできます。 その点Step Functionsではランタイムを気にする必要がなくなるので、その点においては運用上のコストやセキュリティ上のリスク低減に貢献するのではないかと考えています。 Step Functionsは銀の弾丸…? ここまで読むと「Step Functions最高!!」「Lambdaいらね!!!」と思われた方もいらっしゃるかもしれません。。 残念ながらそんなことはありません。 上記のアプリケーションの例でいいますと、Step Functionsを用いて1時間ごとの気温から平均気温を出すことはできないのです。 組み込み関数の機能により、数学的な処理も行えるようになっているものの、まだ加減算のみしかできません。 Step Functions ワークフローの Amazon States Language の組み込み関数 - AWS Step Functions 組み込み関数を使用して Step Functions ワークフローで基本的なデータ処理タスクを実行する方法について説明します。 docs.aws.amazon.com ここの部分に関しましては今後のアップデートで対応される可能性も大いにあると思いますが、個人的には AWSサービスとの連携にはStep Functions データの加工や処理にはLambda と、用途に応じて適切にサービスを組み合わせることが良いと感じました。 おわりに 今回はStep Functionsの魅力についてお伝えしました。 「思ったよりできること多い!」とというのが個人的な感想です。 今回利用させていただいた外部API 会員登録不要・かつ無料で利用できるAPIを使用しました。 このような便利なサービスが無料で使えることはとてもありがたいことだと実感しています。 天気予報:Open-Meteo( https://open-meteo.com/ ) 最寄り駅:HeartRails Express( https://express.heartrails.com/api.html ) Step FunctionsのフローのASL Amazon EventBridge ConnectionのARNについてはマスキングを行っています。 { "Comment": "A description of my state machine", "StartAt": "並列処理", "States": { "並列処理": { "Type": "Parallel", "Branches": [ { "StartAt": "気温の取得", "States": { "気温の取得": { "Type": "Task", "Resource": "arn:aws:states:::http:invoke", "Parameters": { "ApiEndpoint": "https://api.open-meteo.com/v1/forecast", "Method": "GET", "Authentication": { "ConnectionArn": "arn:aws:events:ap-northeast-1:XXXXXXXXXXXX:connection/Connect_name/abc123-456-7890" }, "QueryParameters": { "latitude.$": "$.latitude", "longitude.$": "$.longitude", "hourly": "temperature_2m", "timezone": "Asia/Tokyo", "forecast_days": "1" } }, "Retry": [ { "ErrorEquals": [ "States.ALL" ], "BackoffRate": 2, "IntervalSeconds": 1, "MaxAttempts": 3, "JitterStrategy": "FULL" } ], "Next": "服装の考案" }, "服装の考案": { "Type": "Task", "Resource": "arn:aws:states:::bedrock:invokeModel", "Parameters": { "ModelId": "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-3-haiku-20240307-v1:0", "Body": { "anthropic_version": "bedrock-2023-05-31", "max_tokens": 600, "messages": [ { "role": "user", "content": [ { "type": "text", "text": "あなたは私の友人で、コーディネーターとして働いています。私は気温に応じて着たり脱いだりすることが嫌いです。今日0時から23時まで1時間ごとの気温は別のリストに与えるとおりです。1日通して私が外出するのに適した上下のコーディネートを簡潔に教えて下さい。" }, { "type": "text", "text.$": "States.JsonToString($.ResponseBody.hourly.temperature_2m)" } ] } ] } }, "End": true, "ResultSelector": { "outfit.$": "$.Body.content" } } } }, { "StartAt": "最寄り駅の取得", "States": { "最寄り駅の取得": { "Type": "Task", "Resource": "arn:aws:states:::http:invoke", "Parameters": { "ApiEndpoint": "https://www.heartrails-express.com/api/json", "QueryParameters": { "method": "getStations", "x.$": "$.longitude", "y.$": "$.latitude" }, "Method": "GET", "Authentication": { "ConnectionArn": "arn:aws:events:ap-northeast-1:XXXXXXXXXXXX:connection/Connect_name/abc123-456-7890" } }, "Retry": [ { "ErrorEquals": [ "States.ALL" ], "BackoffRate": 2, "IntervalSeconds": 1, "MaxAttempts": 3, "JitterStrategy": "FULL" } ], "End": true, "ResultSelector": { "station.$": "$.ResponseBody.response.station" } } } } ], "End": true } } } 入力の場所は…? 今回は「35.656315,139.795486」を与えましたが、ここは…弊社の本社ビルです。 駅近が魅力的ですね!
アバター
こんにちは。SCSKの山口です。 今回は、 過去のブログ で作成したモデルが算出した予測値を説明させてみよう。の回です。 以前作成した線形回帰モデルで、工場の製造コスト、人件費、生産効率、従業員数から、工場の「原材料費」を予測するモデルを作成し、下記の予測値を出力として得ました。 この結果、 モデルがどうやって算出したのか 気になりませんか、、、? そんな時に役立つのが、 XAI とも呼ばれる BigQuery Explainable AI です。早速見ていきましょう。   BigQuery Explainable AI  BigQuery Explainable AI の概要  |  Google Cloud cloud.google.com Explainable AI は、データ行の各特徴がどのように予測結果に影響を与えるかを定義することで、予測 ML モデルが分類タスクと回帰タスクに対して生成する結果の理解を容易にします。この情報を 「特徴アトリビューション」 と呼びます。 カンタンにいうと 特徴アトリビューション = データ内の各特徴が予測値にどの程度影響を及ぼしたか です。特徴アトリビューションを活用することで、 モデルが 期待通りに動作していること の確認 モデルの バイアスを認識 すること モデルやトレーニングデータの 改善方法を知る こと が可能です。 ローカルとグローバルの説明可能性 説明可能性には、ローカルの説明可能性とグルーバルの説明可能性の2種類があります。 それぞれの説明可能性から「ローカルな特徴重要度」と「グローバルな特徴重要度」を得ることができます。 ローカルの説明可能性 説明された各列の特徴アトリビューション値を返します。 これらの値は、それぞれの特徴が ベースラインの予測に対してどの程度影響を及ぼすか を示します。 ローカル説明関数の「 ML.EXPLAIN_PREDICT 」を使用することで取得可能です。 グローバルの説明可能性 データセット全体の特徴アトリビューション を集計し、モデルに対する特徴の全体的な影響を返します。 絶対値が大きいほど、特徴がモデルの予測により大きな影響を与えたことを示します。 グローバル説明関数の「 ML . GLOBAL _ EXPLAIN 」を使用することで取得可能です。   ここから実践に入りますが、以前作成したモデルは単一のテーブルで学習させたので、今回はローカルの説明可能性を試してみます。   実践:ローカルな特徴重要度を取得 ローカル説明関数の「ML.EXPLAIN_PREDICT」を使った下記クエリを実行します。 SELECT * FROM ML.EXPLAIN_PREDICT( MODEL `yamaguchi_test_bqml.test_model_liner_reg`,   (   SELECT     IFNULL(cost_manufacturing, 0) AS cost_mf,     IFNULL(cost_material, 0) AS label,     IFNULL(cost_employees, 0) AS cost_emp,     IFNULL(manufacturing_line, 0) AS manu_line,     IFNULL(manufacturing_efficiency, 0) AS manu_eff,     IFNULL(employees, 0) AS emp   FROM     `yamaguchi_test_bqml.test`   WHERE     employees=476   ),   STRUCT(5 AS top_k_features)   ) 上記クエリのサブクエリのSELECT句 SELECT IFNULL… で評価データを生成するクエリを入力します。今回は以前のブログで実際の予測をする際に使用したクエリを流用します。 また、 STRUCT(5 AS top_k_features) の部分で、 影響力が上位何番目までの特徴を見るか を指定します。今回は上位5個(すべて)の特徴を出力します。 出力結果は下記のとおりです。 predicted_label: モデルが算出した予測値 top_feature_attributions.feature :特徴名(影響度で降順) top_feature_attributions.attribution :各特徴の影響度 baseline_prediction_value :モデルの予測におけるベースライン baseline_prediction_value についてちょっと寄り道します。 モデルを作成する際、最初にある程度の”アタリ”をつけたうえで、そこから微調整をかけていくのですが、baseline_prediction_valueは 「最初につけたアタリ」 を指します。 調べた結果、 モデル学習のトレーニングに使われたデータ内での 目的変数の平均値 が採用されていました。 このベースラインの値を基準として、モデルが 各特徴の影響度を加味して予測値を算出 してくれます。下記のイメージです。 最初にアタリをつけたベースライン(青矢印)に対して、各特徴の影響を与えていきます。するとベースラインの値の青丸が調整され、赤丸になっていきます。 こうしてベースラインの青矢印が各特徴に影響され、赤矢印のような動きをして予測値を算出してくれます。 今回はベースラインの方が正解値に近い残念な結果になっています。。。 ただ、 各特徴がどの程度影響を与えた結果、予測値がどう外れているか をある程度掴むことができました。 この情報をモデルの性能改善へと活用すること が可能です。 モデルの性能改善については今後ブログ化していきます。   まとめ 今回は、以前作成した線形回帰モデルの予測結果をExplainable AI(XAI)を使って説明させてみました。 どの特徴が予測結果にどの程度影響を与えているかが数値的につかめるので、かなり便利だと思いました。 この情報をどう生かすべきか。については今後検証してブログ化していこうと思うのでご期待ください。 最後までご覧頂きありがとうございました。
アバター
SASE に関する実態調査について 昨年(2023年)に引き続き、今年度(2024年)も、SASE実態調査を実施しました。 SASEの認知度、実際の導入企業はどれくらいなのか? SASE (Secure Access Service Edge)に関する実態調査結果と、Cato Networks社のCatoクラウドの認知度について blog.usize-tech.com 2023.09.01 SASE実態調査のきっかけは、SCSKで2021年より主要なSASE 4ソリューションを一同に紹介を行うオンラインセミナー「 SCSK SASE Solution Summit(通称 S4 エスフォー) 」となります。これまで 18 回開催しており、直近の2024年6月の開催では250名以上、延べ 1,800 名以上の方々にご参加頂いております。この S4 セミナー等を通じて多くの参加者の皆さまからのアンケートを集めると、SASEに関する世間の類似調査結果(例. SASE導入済み企業が4割、SASE導入着手企業が6割など)よりも、実際の認知度や導入率はもっと低いのではないかという仮説が上がっていました。 SASEは、昨年(2023年)より本格的な普及期に入ると予測されていましたが、海外と比べると日本国内でのSASE普及は遅れているとされていることもあり、2023年6月に外部調査企業の協力を得て、国内企業への実態調査を実施し、その調査結果(レポート)を無料公開しました。 昨年(2023年度)のレポートについては、以下のリンクよりダウンロードください。 https://www.scsk.jp/news/2023/pdf/20230809i.pdf そして、今年(2024年)も、普及期におけるSASE認知度・導入率がこの一年間でどれくらい増加したのかを把握するために、ちょうど一年後(2024年6月)に同じ調査を実施し、その調査結果(レポート)を同じく無料公開したものとなります。 2024年度の詳細なレポートについては、以下のリンクより是非ダウンロードください。 https://www.scsk.jp/news/2024/pdf/20240905.pdf SASE 認知度 SASE認知度が45%まで大きく向上しています。まだまだ認知度が低いのでは?、55%の人が知らないじゃないか?と言う方も居られると思いますが、このようなIT関連の調査において、特にITインフラに関する認知度は、50%を超えると非常に良い方で、60-70%に達成することはあまりありません。 「マイクロソフト」や「アップル」、「Windows」、「iPhone」であれば、認知度は90%を超える結果になると思いますが、例えば、「クラウド」、「AWS」、「Azure」、「GCP」などが 60-70%に達成することは、まずありえません。 広くIT関連業務へ従事する方へのアンケートとなりますので、インフラ業務に従事されていない方(ex. 開発業務の方)も含まれるからです。来年以降に同様の調査を実施すると、50%は超えるのでなないかと思いますが、60-70%に達するのはおそらく不可能だと思っています。 つまり、本調査での45%は、非常に高い認知度であることを示しています。 SASE 導入率(普及率) SASE導入率(普及率)については、導入済み企業が 10%(10.0%)から16%(15.5%)と1年で大きく向上しました。 キャズム理論における初期市場であるイノベーター(2.5%)、アーリーアダプター(13.5%)の計16%、市場普及の溝(キャズム)を超え、メインストリーム市場に入ったことが判明しています。 現在導入中・導入計画中の企業を考慮すると、導入率は今後も大きく向上すると判断できます。 Catoクラウド認知度 一方で、調査結果(レポート)には掲載していませんが、昨年度と同様にCato Networks(ケイトネットワークス)社 Catoクラウド(Cato Cloud/Cato SASE Cloud)について個別の認知度調査を実施しております。 2023年は、Catoクラウドを知っている方は 12% という結果でしたが、2024年は 16%(+4%)と少ないながら認知度が向上していることが判明していますが、まだまだ認知度が低いことが分かりました。 SASE 検討で気を付けるべきこと SASEの認知度が大きく向上し、普及(導入)率においてもキャズムを超え、メインストリーム市場に入ったことが分かりました。また、Cato Networks社、Catoクラウド(Cato Cloud/Cato SASE Cloud)も少しづつ認知度が上がってきています。 Catoクラウドを取り扱うパートナー(ディストリビューター、リセラー)も急激に増えてきており、今では100社近くの企業が取り扱いを始めています。一般的な製品やサービスであれば、パートナー企業数は概ね100社程度で上限になるのですが、SASE は、ネットワーク・セキュリティ分野になるので、システムインテグレータだけはなく、通信事業者(通信キャリア含む)、ネットワークインテグレータ、通信機器メーカ等も参入し始めており、今後どこまでパートナーの数が増えるのかは分かりません(AWSのように700-800社になるかもしれません) SASEは、企業ネットワークやセキュリティの代替となるサービスなのですが、単純な物販(モノ売り)として取り扱いをしているパートナーもあり、導入がきちんと行われておらず、その後のサポート・保守(マネージドサービス等)も提供されておらず、お客様が困って当社へご連絡が来る事例も増え始めています。 Catoクラウドのサービスを殆ど理解されず、多くの機能を活用できていない例もあります。 また、クラウドサービスなので、AWS等のパブリッククラウドと同じく、多くの場合はスモールスタートを行い、必要に応じて随時増速・アカウント追加を行うのが一般的なのですが、クラウド(AWS等)と異なるのは、お客様自身がクレジットカード決済で自由に増速・アカウント追加ができないことです。Catoクラウドでは、パートナー経由で、見積・注文を行うことが前提で、注文後にライセンス発行がされて初めて、増速・アカウント追加ができるようになっています。 つまり、パートナー(ディストリビューターおよびリセラー)の見積り作成・提示や、注文後の受注処理およびライセンス発行処理が遅いと、非常に困った事態になります。拠点の帯域が不足しているのに、いつまで経っても帯域増速ができない、従業員が増え、モバイルユーザのアカウントを付与したいのにできない等が発生します。 見積りの取得に数週間掛かったり、ライセンス発行に1ヵ月以上掛かる例もあるようです。 パートナーが急増し、Catoクラウドのエコシステムの形成がされ、全体のビジネスが拡大していますが、その一方で様々な弊害も出始めています。 弊害のひとつは、パートナー(ディストリビューターおよびリセラー)による 劣化コピーの問題 です。 劣化コピーとは、すでにある作品や表現などの、程度や品質が劣る模倣のことで、要するに出来の悪い二番煎じのことです。 例えば、当社の実施するCatoクラウドのお客様の導入事例(制作)や、2022年からリリースしているFAQシステムや、この技術ブログ(TechHarmony)を例にすると、後発でパートナー(ディストリビューターおよびリセラー)が、劣化コピーの導入事例を制作したり、劣化コピーFAQサイトをリリースしたり、劣化コピーブログ(?)をリリースしたりすることです。 劣化コピーではなく、お客様にとって「より良いもの」、今存在しているものより「さらに良いもの」をリリースして欲しいと思います。個人的には、そもそも同じようなものは、紛らわしく、混乱を招くだけなので不要だと思っていますので、全体のエコシステムを意識されるのであれば、劣化コピーを作る労力は、Catoクラウドに必要なもの(今は存在しないもの)をリリースすることに使って欲しいと思います。 全体の意識がなく、案件レベルでの競争(コンペ)としか見ることができないのだと思いますが。。。 最後に SCSKでは、SASE を単純な物販(モノ売り)ではなく、お客様のビジネスインフラの根幹となるネットワーク・セキュリティと捉えています。 きちんとしたサービスのご紹介から、PoCを含めサービスのレクチャーから技術検証のご支援、その後の設計/構築(移行)はもちろん、導入後の各種マネージドサービスもフルラインナップでご提供しております。毎週新たなサービスや機能がリリースされるため、その情報共有も積極的に実施し、FAQを始めとし、お客様自身(セルフ)で問題解決できる各種施策を提供しております。 また、見積りを含む受発注やライセンス発行などのリードタイム(LT)も常に改善を図っており、特にライセンス発行に関しては15時までにご注文書をいただければ、最短で当日中にライセンス発行を行っております。 パートナーが急増し、劣化コピーも増えていますが、お客様導入事例、FAQ、技術ブログについては、是非オリジナルをご覧いただければ幸いです。 ・SCSKが導入し、マネージドサービスを提供しているお客様の導入事例 Catoクラウド 導入事例 | よくあるご質問 | Cato Cloud ケイトクラウド - SCSK Catoクラウドのお客様導入事例ライオン株式会社 様株式会社 ブルボン 様 cato-scsk.dga.jp ・Catoクラウド FAQシステム よくあるご質問 | Cato Cloud ケイトクラウド - SCSK Cato SASE Cloud Platform. powered by SCSK cato-scsk.dga.jp ・SCSK技術ブログ(TechHarmony) Cato Cloud 「Cato Cloud」の記事一覧です。 blog.usize-tech.com ・Catoクラウド 導入・運用の悩みは“パートナー選び”で解決できる Catoクラウド導入・運用の悩みは“パートナー選び”で解決できる | SCSK株式会社 SASEプラットフォーム「Catoクラウド」の導入・運用の悩みを解決する“パートナー選び”のポイントを解説します。 www.scsk.jp ・SASEに関するセミナー、Catoクラウド各種セミナー Catoクラウド イベント・セミナー情報 | よくあるご質問 | Cato Cloud ケイトクラウド - SCSK 定期的にCatoクラウドをご紹介するセミナーを開催しております。・2024年9月26日(木)Catoクラウド ハンズオンセミナー【札幌開催分】 ~全国5都市開催(東京/大阪/名古屋/博多/札幌)~ ... cato-scsk.dga.jp
アバター
Azure では仮想ネットワーク (VNet) 内に配置されたリソースの名前解決を行う方法として、以下の 4 つの方法が用意されています。 Azure が提供する名前解決 プライベート DNS ゾーンによる名前解決 カスタム DNS サーバーによる名前解決 DNS Private Resolver による名前解決 本稿では、「 Azure が提供する名前解決 」の動作についてAzure 仮想マシン (VM) に注目して確認します。 同じ VNet に配置された VM を名前解決する 次の構成を用意して、同じ VNet に配置された VM の名前解決動作を確認します。 Windows VM からの名前解決とその設定を確認する Windows VM win-vm-1 から正引き/逆引きでの名前解決動作を確認してみます。   正引きの名前解決 正引き (前方参照) の名前解決を行うと、Azure 提供 DNS 168.63.129.16 が参照され各 VM のホスト名に対応する IP アドレスを応答します。 ホスト名で要求すると自動的に DNS サフィックス *.internal.cloudapp.net が付与されて名前解決が行われています。 この前方参照ゾーン *.internal.cloudapp.net は特にこちらでは構成しておらず MS によって自動作成され管理されています。 逆引きの名前解決 逆引きの名前解決を行うと、こちらも Azure 提供 DNS 168.63.129.16 が参照され各 VM の IP アドレスに対応するホスト名を応答します。 IP アドレスで要求すると対応する逆引きレコード  x.x.x.x.in-addr.arpa が参照されて名前解決が行われています。 この逆引きレコード  x.x.x.x.in-addr.arpa は特にこちらでは構成しておらず MS によって自動作成され管理されています。 DNS 参照設定の確認 Windows 上で DNS 参照設定がどのように構成されているかを確認します。 まずは、NIC の設定がどのように構成されているか確認します。 IP アドレスや DNS 設定は DHCP から自動的に配布されたものを利用する設定になっています。 DNS サフィックスは明示的に設定されていません。 続いて、 NIC に実際に反映された設定を確認します。 IP アドレスや DNS 設定は Azure 提供 DHCP 168.63.129.16 から配布されており、自動的に設定されています。 DNS サフィックスも NIC の Connection-specific DNS Suffix に MS 管理のゾーン *.internal.cloudapp.net が DHCP から配布されています。 Windows IP Configuration の DNS Suffix Search List に Connection-specific DNS Suffix の値が反映されています。 Linux VM からの名前解決とその設定を確認する Linux VM lin-vm-1 から正引き/逆引きでの名前解決を確認してみます。   正引きの名前解決 正引き(前方参照)の名前解決を行うと、スタブリゾルバ 127.0.0.53#53 が参照され各 VM のホスト名に対応する IP アドレスを応答します。 ホスト名で要求すると自動的に DNS サフィックス *.internal.cloudapp.net が付与されて名前解決が行われています。 この前方参照ゾーン *.internal.cloudapp.net は特にこちらでは構成しておらず MS によって自動作成され管理されています。 逆引きの名前解決 逆引きの名前解決を行うと、こちらもスタブリゾルバ 127.0.0.53#53 が参照され各 VM の IP アドレスに対応するホスト名を応答します。 IP アドレスで要求すると対応する逆引き参照ゾーン x.x.x.x.in-addr.arpa が参照されて名前解決が行われています。 この逆引き参照ゾーン x.x.x.x.in-addr.arpa は特にこちらでは構成しておらず MS によって自動作成され管理されています。 DNS 参照設定の確認 Linux (Ubuntu 24.04 LTS) 上で DNS 参照設定がどのように構成されているかを確認します。 まずは、NIC の設定がどのように構成されているか確認します。 IP アドレスや DNS 設定は、DHCP から自動的に配布されたものを利用する設定になっています。 DNS サフィックスは明示的に設定されていません。 続いて、 NIC に実際に反映された設定を確認します。 IP アドレスや DNS 設定は Azure 提供 DHCP 168.63.129.16 から配布されており、自動的に設定されています。 DNS サフィックスも NIC の DNS Domain に MS 管理のゾーン *.internal.cloudapp.net が DHCP から配布されています。 /etc/resolv.conf の search に DNS Domain の値が反映されています。 Ubuntu では、ローカルクライアントを systemd-resolved 内部の DNS スタブリゾルバに接続し、スタブリゾルバが名前解決を中継します。このため、 nslookup の結果ではスタブリゾルバのアドレス 127.0.0.53#53 が表示されますが、実際にはスタブリゾルバは resolvectl status で出力されている通り、DHCP から配布された DNS 参照先として Azure 提供 DNS 168.63.129.16 を参照しています。 DNS レコードの更新動作を確認する 新しい VM を作成する 新しい VM を作成した際に DNS レコードが自動的に登録されるかを確認します。 win-subnet に新しい Windows VM win-vm-2 を作成する lin-subnet に新しい Linux VM lin-vm-2 を作成する Windows VM win-vm-2 のレコード 正引き/逆引きともに自動的にレコードが追加されます。 Linux VM lin-vm-2  のレコード 正引き/逆引きともに自動的にレコードが追加されます。 IP アドレスを変更する 既存の VM の IP アドレスを変更した際に、DNS レコードが自動的に更新されるかを確認します。 Windows VM win-vm-2 の IP アドレスを 10.1.0.5 から 10.1.0.15 に変更する Linux VM lin-vm-2 の IP アドレスを 10.1.1.5 から 10.1.1.15 に変更する Windows VM win-vm-2 のレコード 正引き/逆引きともに自動的にレコードが更新されます。   Linux VM lin-vm-2 のレコード 正引き/逆引きともに自動的にレコードが更新されます。 ホスト名を変更する 既存の VM のホスト名を変更した際に、DNS レコードが自動的に更新されるかを確認します。 Windows VM win-vm-2 のホスト名を win-vm-2 から win-vm-2x に変更する Linux VM lin-vm-2 のホスト名を lin-vm-2 から lin-vm-2x に変更する Windows VM win-vm-2 のレコード 正引き/逆引きともに自動的にレコードが更新されます。(要再起動) Linux VM lin-vm-2 のレコード 正引き/逆引きともに自動的にレコードが更新されます。(要再起動) 仮想マシンを停止する 既存の VM を停止した際に DNS レコードがどうなるかを確認します。 Windows VM win-vm-2 を停止する Linux VM lin-vm-2 を停止する Windows VM win-vm-2 のレコード 正引き/逆引きともに名前解決ができなくなります。 Linux VM lin-vm-2 のレコード 正引き/逆引きともに名前解決ができなくなります。 異なる VNet に配置された VM を名前解決する 次の構成を用意して、異なる VNet に配置された VM の名前解決動作を確認します。 VNet vnet-1 の VM から名前解決する VNet vnet-1 の Windows VM win-vm-1 から VNet vnet-1 の名前解決を確認します。 同じ VNet の VM は正引き/逆引きともに名前解決できます。 VNet vnet-1 の Windows VM win-vm-1 から VNet vnet-2 の名前解決を確認します。 異なる VNet の VM は正引き/逆引きともに名前解決できません。 VNet vnet-2 の VM から名前解決する VNet vnet-2 の Windows VM win-vm-2 から VNet vnet-2 の名前解決を確認します。 同じ VNet の VM は正引き/逆引きともに名前解決できます。 VNet vnet-2 の Windows VM win-vm-2 から VNet vnet-1 の名前解決を確認します。 異なる VNet の VM は正引き/逆引きともに名前解決できません。 FQDN を指定して名前解決する VNet 毎に DNS ゾーンが異なることで、ホスト名 (サフィックスなし) での名前解決ができない可能性があるため、FQDN を指定して名前解決してみます。 VNet vnet-1 の VM win-vm-1 から VNet vnet-2 の VM を FQDN で名前解決してみます。 FQDN 指定でも異なる VNet の VM は名前解決できません。 VNet vnet-2 の VM win-vm-2 から VNet vnet-1 の VM を FQDN で名前解決してみます。 FQDN 指定でも異なる VNet の VM は名前解決できません。 カスタム DNS サーバーを中継して名前解決を試みる これまでの確認により、DNS 参照のスコープが VNet であり、異なる VNet 間での名前解決はできないことがわかりました。ここからは蛇足となりますが、異なる VNet に配置した DNS サーバーを中継することで名前解決ができるかを確認します。 VNet vnet-2 の Windows VM を DNS サーバーにして VNet vnet-1 の VM から名前解決する 次のような構成で、VNet を跨いで名前を参照できるか確認します。 VNet vnet-1 の Windows VM win-vm-1 から VNet vnet-2 の VM の名前解決を行います。 ホスト名 (DNS サフィックスなし) /FQDN ともに名前解決できません。 VNet または NIC の DNS 設定で、カスタム DNS サーバーを参照させると、DHCP から配布される DNS サフィックスは reddog.microsoft.com という存在しないゾーンになります。   VNet vnet-2 の Windows VM を DNS サーバーにして VNet vnet-1 の VM から名前解決する (DNS フォワーダーあり) 次に、すべてのリクエストを Azure 既定の DNS 168.63.129.16 に転送するように DNS サーバーを構成します。 VNet vnet-1 の Windows VM win-vm-1 から VNet vnet-2 の VM の名前解決を行います。 FQDN の場合は、正引きの名前解決ができます。 続いて、逆引きの名前解決についても確認します。 DNS サーバー自身の IP アドレスは逆引きに失敗します。 DNS サーバー以外の VM は、逆引きの名前解決ができます。 恐らく DNS サーバー自身の IP アドレスはフォワードせずに、自身のもつ逆引きゾーンで解決しようとして、ゾーンがないためエラーになる動きをしているように思えますが、本稿の本質ではないためここまでの確認とします。 まとめ 本稿では、Azure が提供する名前解決により、VM の名前解決がどのように行われるかを確認しました。 追加の構成や管理を行うことなく、正引き/逆引きともに名前解決することができ DNS レコードの更新も自動的に行われるため、とても便利で手軽ですが、VNet を跨いで名前解決を行うことができないことや VM 停止時には DNS レコードが参照できないなどの制約があることから、利用可能なシナリオが限定されることがわかりました。 特に、エンタープライズシナリオにおいて一般的な Hub & Spoke 型のネットワークトポロジーにおいては、DNS リゾルバを Hub VNet に配置して集中管理することが一般的ですが、このとき Azure が提供する名前解決では DNS リゾルバが存在する Hub VNet の VM しか名前解決できないことがネックになってくると思います。 Azure が提供する名前解決の特徴や考慮事項は次の公式ドキュメントにもまとめられています。 Azure 仮想ネットワーク内のリソースの名前解決 Azure IaaS、ハイブリッド ソリューション、異なるクラウド サービス間、Active Directory、および独自の DNS サーバーの使用に関係する名前解決シナリオです。 learn.microsoft.com 今回は以上です。次回は、プライベート DNS ゾーンによる VM の名前解決動作を確認してみたいと思います。
アバター
こんにちは。SCSK株式会社の安藤です。 10/2 に、 SCSK主催のZabbixセミナーを開催 します。(開催まであと1週間を切りました・・・!)   本セミナーでは、Zabbix 7.0の新機能と改善点について詳しくご紹介させていただきます。   特に今回は、以下のような点に焦点を当てて解説してまいります。 より直感的になったユーザーインターフェース 新しい監視機能と拡張された統合オプション パフォーマンスの大幅な向上 セキュリティ強化の取り組み   セミナーの後半では、実際にバージョンアップする際の要点についてご説明し、Zabbix 7.0への移行をスムーズに進めるためのヒントもお伝えいたします。   セミナー概要   主催 SCSK株式会社 日時 2024年10月2日(水) 15:00~16:00 (ログイン開始時間 14:45~) 会場 オンラインセミナー(お申し込み後、受講用URLをご案内致します。) 定員 100名 対象 Zabbixを導入済、導入ご検討中の方 Zabbixにご興味がある方 参加費 無料   プログラム詳細とお申込みは、以下ページをご参照ください。 Zabbix7.0セミナー~新機能とバージョンアップの要点~ 本セミナーでは、Zabbix 7.0の新機能と改善点について詳しくご紹介させていただきます。実際のアップグレード手順についてもご説明し、皆様のZabbix 7.0への移行をスムーズに進めるためのヒントもお伝えいたします。 www.scsk.jp   最後に 弊社ではZabbix関連サービスを展開しています。以下ページもご参照ください。 SCSK Plus サポート for Zabbix SCSK Plus サポート for Zabbix 世界で最も人気のあるオープンソース統合監視ツール「Zabbix」の導入構築から運用保守までSCSKが強力にサポートします www.scsk.jp   ★YouTubeに、SCSK Zabbixチャンネルを開設しました!★ SCSK Zabbixチャンネル 本チャンネルでは、SCSK株式会社でのZabbixに関するトレンド/事例紹介などを動画にまとめて取り上げております。 最新のトピックについては、以下の弊社HPもしくはツイッターアカウントをぜひ参照ください。 ツイッターアカウント: www.youtube.com   ★X(旧Twitter)に、SCSK Zabbixアカウントを開設しました!★ x.com x.com
アバター
こんにちは。SCSKの山口翔平です。 最近、大谷翔平選手の活躍が凄まじいので便乗してフルネームで名乗ってみました。 2024年9月20日。大谷翔平選手が前人未到の 【50-50】 を達成した裏で、私、山口翔平がひっそり GCP認定資格【11冠】 を達成しました。 2022年9月にGoogle Cloud の部署に新人として配属され、ちょうど二年後の2024年9月に 認定資格11冠(全冠) を達成しました。せっかくなので全冠までの2年間の軌跡をブログに残そうと思います。 試験の概要は 公式ドキュメント や SCSKの別社員の全冠ブログ に分かりやすく記載されており、これ以上のことは書けないので丸投げするとして、本ブログでは、 ・各資格の印象(受験した所感などを筆者の主観で) ・オススメの取得順序(これまた筆者の主観で) にフォーカスし、筆者の主観たっぷりで書きたいと思います。 では、山口翔平の記念すべき 【20本目】 のブログスタートです。 取得年表 フルネーム呼びがそろそろしんどくなってきたので早速内容に入ります。 説明に入る前に、長い資格名の略称を整理しておきます。 サイトごとに略称が異なりますが、当ブログでは以降下記略称を使います。 正式名称 略称(※大文字部分をとってます) Cloud Digital Leader CDL Associate Cloud Engineer ACE Professional Cloud Architect PCA Professional Cloud Developer PCD Professional Cloud DevOps Engineer PCDOE Professional Data Engineer PDE Professional Cloud Database Engineer PCDE Professional Cloud Security Engineer PCSE Professional Cloud Network Engineer PCNE Professional Google Workspace Administrator PGWA Professional Machine Learning Engineer PMLE   年表は下記のとおりです。 あらためて年表を見返してみて、一番の反省点は ACE→PCAの空白の4か月 です。 後ほど詳しく書きますが、 ACEとPCAは問題の類似度が非常に高い ため比較的学習がしやすくスムーズに取得を目指せるほか、PCAまで取ってしまうと 他のProfessional資格へのアクセルが踏みやすい です。 私はここで4か月の隙間が空いてしまったため、PCA受験前にACEと重複する部分も学習しなおす手間と時間がかかってしまいました。 ここからは、各資格試験の印象、オススメの取得順序について深掘りしていきます。   各試験の印象 各資格取得時の筆者の状況と、試験の印象を書きます。 (注)筆者が受験した当時の情報です。最新情報はドキュメントをご参照ください。 資格名 Google Cloud歴 (※m:months) 実業務で触っていたサービス等 所感 CDL 3 m VPC、GCE 配属から3か月が経ち、右も左もわからない状況から、 なんとなくクラウド(Google Cloud)がどういいうものか掴み始めたタイミング で受験+合格。 最近受検した人に聞くとAIに関することも聞かれたらしい。当時はそんなことなかった。 ACE 5 m VPC、GCE、Cloud Router、Cloud DNS、Cloud Interconnect 2つ目の受験にして 早速躓いた 。公式ドキュメントを見て かなり幅広いサービスに関する知識が必要 であることを知り、2か月間みっちり対策しなんとか合格。 PCA 9 m BigQuery、Data Fusion、Cloud Functions ACEの知識を取り戻すのに時間を要したが、学習にはそこまで苦労しなかった。あくまでACEの延長線上の印象。ACEの苦労の影響でかなりじっくり対策して臨んだ。 インフラ領域のサービスに加え、BigQueryを扱いだした経験が生きた。 「おめでとう」を言ってくれる人がCDL,ACEより格段に増えた。割と影響力のある資格なんだと感じたと同時にすこし一人前になれた気がした。 PDE 11 m BigQuery、Data Fusion、Cloud Functions Google Cloud歴も1年近くになり、扱うサービスも増えてきた段階で受験、カリキュラムの過渡期だったのか、 AI/ML関連の知識も多く問われた 印象。 筆者のメイン担当領域がDWH・ETLだったこともあり、勉強はサクサク進んだ。メイン領域が違う他の人は割と苦労しているようだった。 PCD 1y1m BigQuery、Data Fusion、Cloud Functions アプリケーション設計、CI/CDの領域 に親しみがなく苦労した。GKEやCloud Buildの問題が頻出+さわったことない状況だったので Skills Boostで実際にサービスに触れて 理解を深めた。 実際にサービスを触ると理解が加速する ことを改めて実感した。 PCDOE 1y5m BigQuery、Data Fusion、Cloud Functions PCDの出題内容とかなり似通っている印象。ここも4か月開けたことを後悔した。 PCDのおかげでスムーズに学習が進んだ。 PCNE 1y6m BigQuery、Data Fusion、Cloud Functions インフラ領域のサービスに関してはそこそこ触っている自負があったが、 NWの専門的な知識が必要 でかなり苦労した。 案件業務で Cloud DNS、Cloud Interconnect(検証環境で触れづらい) に触れていた経験にかなり救われた。 PCSE 1y7m BigQuery、Data Fusion、Cloud Functions 内容は PCNEと共通する部分が多い 印象。先にPCNEを取得済みだったので少し追加の学習をするだけで取得できた。 個人的には PCSE→PCNEの順序もオススメ。 PGWA 1y8m BigQuery、Data Fusion、Cloud Functions、Cloud Pub/Sub、VertexAI Google Wrokspaceの管理コンソールを触った経験がなかったためかなり苦労した。 公式ドキュメント に割と詳細な内容が書いてあったため、まずはここを読み込んで理解を深めた。 PCDE (英語) 1y9m BigQuery、Data Fusion、Cloud Functions、Cloud Pub/Sub、VertexAI PDE、PCNEの知識 があれば比較的楽に突破できる印象。初の英語試験だったが、問題文が理解できれば問題なく解けた。(筆者のTOEICスコアは630。) PMLE(英語) 2y BigQuery、VertexAI 所属部署がAI/ML関連部署になり、その3か月後に初受検。筆者にAI/MLの知識がほぼなかったこともあり一度目は撃沈。 その後、 AI/MLに関する基礎知識 と頻出だった BigQuey ML やパ イプラインの選定基準(VertexAI Pipeline、Kubeflow Pipeline TFXなど) について二か月間徹底的に調査・学習。その結果なんとか合格。 (AI/MLの知見がある先輩の力を借りて理解を深めた。) 個人的に躓いた資格を三つピックアップし簡単にコメントします。 Associate Cloud Engineer 意外に思われるかもしれませんが、一つ目はAssociateレベルの「ACE」です。 他のブログを見ると、あくまで中級の資格として紹介されていますが、 出題されるサービスも多く、かなり広範囲の知識必要になる 印象です。 Google Cloudの認定資格にはAssociateレベルの資格がこの一つしかないこともあり、カバー範囲が広くなっているのかもしれません。 一か月間勉強したら大丈夫だろうくらいで構えていましたが、時間が足りず一か月先延ばしして、二か月間の学習で合格できました。 ただ、この資格を突破すると、 PCAを突破するための知識がほとんど身についている状態 だと思います。 ACE→PCAは時間をあけず取得することを強くオススメします。 Professional Cloud Network Engineer 二つ目が「PCNE」です。 私の周りもここで躓いた人が多かった印象です。 ネットワークに関する専門知識が必要になることはもちろんですが、検証環境で実際に触ってみることが難しい Cloud Interconnect に関する具体的な手順等の知識なども求められます。 筆者は運よく案件業務でCloud Interconnect の実装に携わった経験があったためそれに救われましたが、経験がない方は公式ドキュメントを読み込んでおくことをオススメします。 加えて、下記に関する出題が多かったです。 ハブアンドスポークトポロジでのオンプレミス環境との接続 VPC Service Controlsと限定公開のGoogleアクセスによるアクセス制御 共有VPC Cloud Loadbalancing 上記に関する知識は持ったうえで受験することをオススメします。 限定公開のGoogleアクセスに関しては 過去にブログ にまとめているのでぜひご覧ください。 Professional Machine Learning Engineer 三つめは「PCMLE」です。 AI/MLの知識がほとんどなかった筆者にとっては一番難しかったです。 Google Cloud上で機械学習モデルを構築、トレーニング、デプロイ、管理する手順と、使用するサービス選定に関する知識が多く問われます。 ただ、それだけでなく AI/MLに関する一般的な知識 も多く問われます。 ユースケースに沿ったサービス選定をする問題が多く出題され、その中でAI/MLの「一般的な知識」と「Google Cloudサービスに関する知識」の両者が求められるイメージです。 各サービスで できる事、できない事、不向きな事 を一度頭の中で整理しておくことをオススメします。   オススメの取得順序 以上の内容をふまえた上で、オススメの取得順序をご紹介します。 筆者の主観が強く反映されているので、あくまで参考程度にご覧ください。 順序を整理するにあたって、各資格を 筆者の独断と偏見でグルーピング します。 各グループ内の順序は前後して問題ないですが、 同グループの資格は連続して(できれば短い期間で一気に)取得すること を強くオススメします。 上記グループをふまえて、筆者おすすめの順序は下記です。 「オススメの順序」とは言いましたが、データ系、運用系、NW(ネットワーク)系の三つはどれから攻めても問題ないと思います。 これら三つは全て PCAまでの内容を基礎として、それぞれの領域に発展した内容 が多いです。 各グループ内の資格は連続してとる 前提で、 どの系統から順に攻めても問題ない 。というのが私の考えです。 順序を考えるうえで一番悩んだのが PGWAとPMLE です。この二つは領域が異色なので、どこに挟むか悩みましたが、 Google Cloud全般の知識をつけた上で臨むのに越したことはない と思い、最後の方にプロットしました。 しいて言うなら、私が受験した時の PDEがAI/MLの内容が多かった ので、 データ系→PMLEの順序 もオススメです。 二年前に戻り、私が再度全冠を目指すのであれば、 CDL → ACE → PCA → [NW系] → [運用系] → [データ系] → PMLE → PGWA の順序で受けると思います。   まとめ 私が二年間かけてGoogle Cloud認定資格を全冠した軌跡と所感について書きました。 各試験の内容はかなり流動的なので、各資格の詳細というよりは全般的な内容にフォーカスして書きました。具体的な勉強法は 他社員のブログ で紹介されているのでぜひご覧ください。 全試験通じていえることですが、やはり 「実際にサービスを触ってみる」 ことが一番の近道です。 公式ドキュメントで出題サービスを確認する 各サービスに対する学習の中で、ピンと来ないところは Skills Boostで実際に触ってみる という流れを踏むことが効果的だと思います。 また、GoogleがAI/ML関連のビジネスに注力していることもあり、いろんな資格に AI/MLの問題が出題され始めている ように感じます。CDLにAI/MLの問題が出され始めたのが良い例ですね。 Google Cloudの認定資格を全冠するうえで、 AI/MLの知識はより強く求められるもの になっていきそうです。 私自身、今年度からAI/MLを専門とする部署に異動になったので、これからより一層AI/MLの知識をつけていこうと思っているのですが、その足掛かりとしてPMLEにも挑戦しました。 経験や知識をアウトプットする場として資格試験を活用することはもちろんですが、 新しい領域にチャレンジする足掛かりとして資格試験を活用する こともアリだと個人的には思います。 また、本ブログでも何度か引用していますが、同部署の一年後輩にあたる社員がすごいスピードで資格を取得していた(筆者の一年分を3か月で抜かれた)ので、密かにいい刺激をもらい、負けじと勉強頑張りました。誰かと競いあって全冠を目指すのもアリです。   最後までご覧いただきありがとうございました。 これからも役立つ情報を(大谷選手の本数に負けないよう)どんどん発信していきますのでご期待ください。  
アバター
こんにちは。SCSKの磯野です。 BigQueryでTBレベルの大きなデータを扱うとき、意図しない高額課金のリスクを抑えたいと思ったことはありませんか? 今回は、大きなテーブルを扱う上で、コスト削減につながるTipsをいくつかご紹介します。 BigQueryの課金体系 BigQuery の料金は主に次の 2 つの要素で構成されています。 コンピューティングの料金  は、SQL クエリ、ユーザー定義関数、 スクリプト、特定のデータ操作言語(DML)とデータ定義 言語(DDL)ステートメントがあります。 ストレージ料金 は、ストレージ BigQuery に読み込むデータを保存できます 本記事では、「コンピューティング料金」「ストレージ料金」それぞれのコストを削減する方法をご紹介します。   コンピューティング料金削減方法 その1:パーティショニングやクラスタリングを使用する BigQueryには、パーティショニングとクラスタリングという機能があり、テーブル作成時にそれらを設定することで、クエリ実行時のパフォーマンスを向上させることができます。 なお、BigQueryには パーティションとクラスタの Recommender という機能があり、過去のワークロードに基づいてテーブルのパーティショニングやクラスタリングの適切な設定を推奨してくれます。Recommender API を有効にすることで利用できるため、是非活用してみてください。 パーティションとクラスタの推奨事項を表示する  |  BigQuery  |  Google Cloud cloud.google.com その2:パーティションフィルタを必須とする パーティションを使用したテーブルであっても、適切なクエリを書かないとうっかりフルスキャンが走ってしまう可能性があります。 そこで、パーティションフィルタを必須としておくことで、where句を適切に指定していないクエリはエラーとなるため、フルスキャンを防止することが可能となります。 パーティション分割テーブルに対するクエリ  |  BigQuery  |  Google Cloud cloud.google.com その3:オンデマンドクエリの上限値を設定する BigQuery API には以下のような 割り当て  (Quota) が設けられています。これらは、プロジェクト単位で指定が可能です。  Query usage per day (1 日あたりのクエリ使用量)  Query usage per day per user(ユーザーごとの 1 日あたりのクエリ使用量) クォータと制限  |  BigQuery  |  Google Cloud BigQuery のジョブ、クエリ、テーブル、データセット、DML、UDF、API リクエストに適用される割り当てと上限について説明します。 cloud.google.com デフォルトでは「無制限」に設定されているため、割り当て (Quota) を設定することで上限を超えるクエリの実行を制限することが可能となります。   ストレージ料金削減方法 その4:ストレージ課金モデルの変更 BigQueryのストレージ料金には、2つの課金モデルがあります。 論理ストレージ(Logical Storage)課金 テーブルに格納されたデータの、 圧縮前 のデータサイズに対して課金するモデル 物理ストレージ(Physical storage)課金 圧縮後 のデータサイズに対して計算が行われる課金モデル。 BigQuery では、データは圧縮されて格納されています。圧縮率はデータによって異なりますが、4分の1〜12分の1程度、あるいはそれ以上に圧縮されている可能性があります。 デフォルトでは、 論理ストレージ (Logical Storage)課金が設定されています。 物理ストレージ 課金へ変更することで、圧縮後の小さいデータサイズに対して課金されるため、利用料金が削減できる可能性があります。 ただし、 物理ストレージ 課金の場合、データサイズあたりの単価は高くなります。また、データの性質によって圧縮率が異なるため、物理ストレージ課金に変更することで必ずしもコストが削減されるとは限りません。ご自身の環境で圧縮率やデータサイズを確認したうえで、課金モデルの変更をご検討ください。 新しい料金モデルで BigQuery の物理ストレージの費用を削減 | Google Cloud 公式ブログ お客様が BigQuery でクラウドのデータ ウェアハウジングを拡張するにつれて、スケーラブルなクラウドデータ ストレージに対する費用の最適化が重要になります。 cloud.google.com   まとめ いかがだったでしょうか。 BigQueryでTBレベルの大きなデータを扱うとき、費用を抑えるための方法をいくつかご紹介しました。 なお、万が一意図しない高額課金が発生してしまった場合、GCPのサポートに連絡すると、何らかの救済措置をしていただけるかもしれません。 本記事が皆様のお役に立てれば幸いです。
アバター
こんにちは。SCSKの磯野です。 BigQueryのパーティションフィルタについて、気になったことをいくつか調べてみました。 パーティションフィルタとは パーティションフィルタを有効にすると、パーティション列を適切に指定したWHERE句が存在しないときに、エラーとすることができます。これにより、必ずパーティションが効くクエリしか実行できなくなるため、フルスキャンによる高額課金を防止することができます。 パーティション分割テーブルの管理  |  BigQuery  |  Google Cloud cloud.google.com   パーティションフィルタを有効にする方法 terraformで管理している場合、以下の一文を追加することでパーティションフィルタを有効にすることが可能です。 require_partition_filter =  true   Terraform Registry registry.terraform.io なお、テーブル作成後でもパーティションフィルタを有効化することは可能です。 ( 参考 ) パーティション分割テーブルを作成するときに、 パーティション フィルタを要求する オプションを有効にしない場合でも、テーブルを更新してオプションを追加できます。   動作検証 検証方法 BigQueryの公開データセットを使っています。 bigquery-public-data.wikipedia.pageviews_2024 を自分のプロジェクトへコピーし、パーティションフィルタの設定を変えて検証してみました。 本テーブルはサイズが大きいため、パーティションフィルタを無効にした状態での実行は自己責任でお願いいたします。 パーティションフィルタを有効にすると? 有効化前(パーティションフィルタ省略可能) パーティションフィルタを省略可能な状態にしたままクエリを実行すると、フルスキャンが走ることが確認できました。 有効化後(パーティションフィルタ必須) パーティションフィルタを必須にした状態でクエリを実行すると、where句がないためエラーとなることが確認できました。 WHERE句を誤って指定していても、パーティションフィルタは効く? では、パーティションが効かないようなwhere句を指定した場合はどうなるでしょうか? 以下のようなクエリで試してみました。本クエリは、パーティション列(datehour)によるwhere句が記載されていますが、パーティショニングが効かず、フルアクセスとなってしまいます。 SELECT * FROM `myproject.mydateset.wikipedia_pageviews_2024` -- 公式データセットをコピーしたテーブル WHERE DATETIME_ADD(datehour, INTERVAL 9 HOUR) BETWEEN "2024-7-3 9:00:00" AND "2024-7-3 15:00:00"; 本データ場合、datehourはTIMESTAMP型であるためDATETIME_ADDではなくTIMESTAMP_ADDを使用するのが適切です。検証のために意図的にDATETIME_ADDを使用していますが、TIMESTAMP_ADDを使用すれば、パーティショニングが効き、フルスキャンを避けることができます。 有効化前(パーティションフィルタ省略可能) パーティショニングが効かないクエリのため、フルスキャンが走ることが確認できました。 有効化後(パーティションフィルタ必須) パーティションフィルタが効いており、エラーとなることが確認できました。 → パーティションフィルタは、where句が適切でないことを認識できています。 Jupyter Notebookからクエリを実行しても、パーティションフィルタは効く? import pandas as pd from google.cloud import bigquery client = bigquery.Client(project=project_id) # クエリを定義 query = """ SELECT * FROM `myproject.mydateset.wikipedia_pageviews_2024` WHERE DATETIME_ADD(datehour, INTERVAL 9 HOUR) BETWEEN "2024-7-3 9:00:00" AND "2024-7-3 15:00:00"; """ # クエリを実行して結果をDataFrameに読み込む df = client.query(query).to_dataframe() # 結果を表示 print(df.head()) Cloud Shellエディタより試しましたが、以下のようにエラーとなり、パーティションフィルタが効いていることが確認できました。 BadRequest: 400 Cannot query over table ‘myproject.mydateset.wikipedia_pageviews_2024’ without a filter over column(s) ‘datehour’ that can be used for partition elimination; reason: invalidQuery, location: query, message: Cannot query over table ‘myproject.mydateset.wikipedia_pageviews_2024’ without a filter over column(s) ‘datehour’ that can be used for partition elimination   結論 パーティションフィルタは、単純に 「パーティション列を使用したwhere句の有無」 をチェックしているのではなく、 「パーティションが効くクエリかどうか」 をチェックしていることがわかりました。 パーティション列を使用したwhere句を書いていても、不適切な書き方だとパーティションが効かないことがあります。そのような場合でも、パーティションフィルタを有効にしていればエラーとなるため、意図しないフルスキャンを防止することができます。 また、コンソールだけではなく ノートブックからの実行でも、パーティションフィルタは効く ことがわかりました。 本記事が皆様のお役に立てれば幸いです。
アバター
こんにちは。SCSKの磯野です。 Dataformで、同一のSQLXファイルから複数環境(dev、prod)向けにリリースを行う方法を記載します。 使用するプロジェクトが1種類( project-a -dev、 project-a -prd)であれば、下記公式ドキュメントの方法で問題ないと思います。 スキーマとプロジェクトごとに開発と本番環境を分割する | Dataform | Google Cloud 今回は、複数のプロジェクトかつ複数環境( project-a -dev、 project-a -prd、 project-b -dev、 project-b -prd)を使用する場合におけるリリース方法を記載します。 ユースケース 本記事は、以下のユースケースにおけるリリース方法を記載しています。 実行環境は、開発(dev)と本番(prod)の2つ 開発テーブルと本番テーブルで共通のSQLXファイルを使いたいが、プロジェクトは分けたい 1つのリポジトリで複数のプロジェクトへのリリースを管理したい   リリース方法概要 カスタムコンパイル変数 を使用します。主な手順は以下の通りです。 workflow_settings.yaml でコンパイル変数を定義する。デフォルトの値としてdev環境で使用する値を設定する dev環境でリリースする際は、デフォルトの値を使用する。 prod環境でリリースする際は、リリース構成にてコンパイル変数をオーバーライドする 設定 開発環境(dev) 本番環境(prod) Google Cloud プロジェクト project-a-dev project-a-dev project-a-prd project-a-prd Gitのブランチ ワークスペースの名前 main ワークスペースのコンパイルのオーバーライド なし なし リリース構成 なし ※ワークスペースから、手動で「実行を開始」する。 production ※カスタムコンパイル変数にてそれぞれのプロジェクトをオーバーライド   リリース方法詳細 事前準備 workflow_settings.yaml vars: projectADefault: "project-a-dev" projectBDefault: "project-b-dev" definitions/project_a/analytics/sample_table_a.sqlx config { type: "table", database: dataform.projectConfig.vars.projectADefault, schema: "analytics", name: "sample_table_a", } SELECT * FROM ${ref("sample_table_b")} definitions/project_b/mydataset/sample_table_b.sqlx config { type: "declaration", database: dataform.projectConfig.vars.projectBDefault, schema: "mydataset", name: "sample_table_b", } リリース構成 リリースID:production git Commitish:main コンパイル変数 キー 値 projectADefault project-a-prod projectBDefault project-b-prod これにより、コンパイル変数がオーバーライドされる。 手順 開発環境(dev)の場合 ワークスペースから、手動で「実行を開始」します。 カスタムコンパイル変数を上書きせずに実行することで、デフォルトのコンパイル変数の設定で実行可能です。 本番環境(prod)の場合 <手動実行の場合> 事前にmainブランチへマージ・コンパイルしておく 手動ワークフローの実行にて、リリース構成 production を指定して実行。 →オーバーライドされた状態で実行される <スケジュール実行の場合> リリース構成 production を指定してワークフロー構成を作成する   まとめ いかがだったでしょうか。 今回はDataformにて、カスタムコンパイル変数を使用する場合におけるリリース方法をご紹介しました。 本記事が皆様のお役に立てれば幸いです。  
アバター
こんにちは。SCSKのふくちーぬです。今回は、EC2(Amazon Linux 2023)にDockerをインストールする方法をご紹介します。 本手順は、閉域網環境を対象としてますが、もちろんインターネットゲートウェイまたはNatゲートウェイがあるパブリック環境に対しても有効なものとなります。 アーキテクチャー インターネットゲートウェイ、NATゲートウェイが存在しない閉域網ネットワーク(プライベート環境)とする。 Systems Managerの管理下にするために、EC2はマネージドインスタンスとする。また、OSはAmazon Linux 2023を利用します。 運用者は、セッションマネージャーを利用してEC2に接続します。 Run Commandを利用して、マネージドインスタンスに対してDockerインストールコマンドを実行します。 S3にRun Commandの実行ログを出力します。   完成したCloudFormationテンプレート 以下のテンプレートをデプロイしてください。 AWSTemplateFormatVersion: 2010-09-09 Description: CFN template EC2 Parameters: ResourceName: Type: String AMIId: Type: String Resources: # ------------------------------------------------------------# # S3 # ------------------------------------------------------------# S3BucketFor: Type: AWS::S3::Bucket DeletionPolicy: Delete Properties: BucketName: !Sub ${ResourceName}-s3-bucket AccessControl: Private PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true # ------------------------------------------------------------# # VPC # ------------------------------------------------------------# VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Sub ${ResourceName}-VPC # ------------------------------------------------------------# # Private Subnet # ------------------------------------------------------------# PrivateSubnet1a: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.1.0/24 AvailabilityZone: ap-northeast-1a MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub ${ResourceName}-subnet-Private-1a PrivateSubnet1c: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.11.0/24 AvailabilityZone: ap-northeast-1c MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub ${ResourceName}-subnet-Private-1c # ------------------------------------------------------------# # Route Table and Routes # ------------------------------------------------------------# PrivateRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: PrivateRouteTable PrivateSubnet1aAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet1a RouteTableId: !Ref PrivateRouteTable PrivateSubnet1cAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet1c RouteTableId: !Ref PrivateRouteTable # ------------------------------------------------------------# # VPC Endpoint # ------------------------------------------------------------# ssmEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Join - '' - - com.amazonaws. - !Ref 'AWS::Region' - .ssm SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref VPCeSecurityGroup PrivateDnsEnabled: true ec2messagesEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Join - '' - - com.amazonaws. - !Ref 'AWS::Region' - .ec2messages SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref VPCeSecurityGroup PrivateDnsEnabled: true ssmmessagesEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Join - '' - - com.amazonaws. - !Ref 'AWS::Region' - .ssmmessages SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref VPCeSecurityGroup PrivateDnsEnabled: true S3VpcEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Join - '' - - com.amazonaws. - !Ref 'AWS::Region' - .s3 VpcId: !Ref VPC VpcEndpointType: Gateway RouteTableIds: - !Ref PrivateRouteTable # ------------------------------------------------------------# # Security Group # ------------------------------------------------------------# SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: For EC2 VpcId: !Ref VPC VPCeSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: !Ref VPC GroupDescription: For VPCEndpoint SecurityGroupIngress: - SourceSecurityGroupId: !Ref SecurityGroup IpProtocol: tcp FromPort: 443 ToPort: 443 # ------------------------------------------------------------# # IAM Role and Instance Profile # ------------------------------------------------------------# SSMRole: Type: AWS::IAM::Role Properties: RoleName: !Sub ${ResourceName}-ec2-role AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: ec2.amazonaws.com Action: sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore - arn:aws:iam::aws:policy/AmazonS3FullAccess InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Roles: - !Ref SSMRole # ------------------------------------------------------------# # EC2 Instance # ------------------------------------------------------------# EC2Instance: Type: AWS::EC2::Instance Properties: InstanceType: t2.micro ImageId: !Ref AMIId SubnetId: !Ref PrivateSubnet1a IamInstanceProfile: !Ref InstanceProfile SecurityGroupIds: - !Ref SecurityGroup Tags: - Key: Name Value: !Sub ${ResourceName}-ec2    Dockerのインストール セッションマネージャーを利用してEC2に接続 セッションマネージャーを利用して、EC2に接続します。「接続」を押下します。 下記のコマンドを実行して、Dockerがインストールされていないことを確認します。 docker --version Run Commandの実行 Systems Managerのコンソールのペインから、Run Commandを選択します。「Run Command」を押下します。   Dockerをインストールするためのコマンドである”AWS-ConfigureDocker”を検索ボックスに入れて、選択します。 コマンドドキュメントプラグインリファレンス - AWS Systems Manager コマンドタイプ SSM ドキュメントでプラグインを指定して、マネージドインスタンスで実行するアクションを選択します。 docs.aws.amazon.com   インストールするEC2を選択します。   実行ログをS3またはCloudWatchロググループに出力することができます。 「実行」を押下します。 Run Commandが完了すると以下の画面になります。 インスタンスIDを選択すると、ログの内容が確認できます。 また今回は、S3バケットにもログを出力するように設定しているためファイルが格納されています。 Dockerのインストール確認 先程度同様にセッションマネージャーを利用して、EC2に接続します。 セッションマネージャーで利用しているユーザーに対して、sudo権限でDockerコマンドを操作できるように以下のコマンドを実行します。 sudo gpasswd -a ssm-user docker 設定を反映させるために「終了」を押下して一旦ログアウトした後に、再度EC2に接続します。 以下のコマンドを実行し、Dockerがインストールされたことを確認します。 docker --version sudo権限なしで実行できました。 docker images   最後に いかがだったでしょうか。 Systems ManagerのRun Commandを利用することで、手動でDockerをインストールするコマンドを実行することなく、容易にコンテナを利用できるようになります。他のRun Commandについても便利なため、是非ドキュメントも覗いてみてください。 本記事が皆様のお役にたてば幸いです。 ではサウナラ~🔥
アバター
こんにちは。最近BigQueryMLにハマっているSCSKの山口です。 もちろん今回もBigQueryMLに関するブログです。今回は 時系列予測 が可能な ARIMA+(ARIMA PLUS) でモデルを作成し、実際に使ってみようと思います。 時系列予測をするにあたって様々な知識が必要になりましたが、今回はできるだけ漏れなく最低限まとめています。少し長いですが最後まで読んでいただけると幸いです。 筆者はこんな人です。 ・Google Cloud歴:約2年 ・BigQueryのコンソール操作には慣れている ・ SQLが少し書ける ・AI/MLの知識はあまりない 時系列予測 読んで字のごとく。と言えばそこまでなのですが、せっかくなのでGeminiに聞いてみました。 時系列予測ってなんですか? 時系列予測とは、過去のデータの動きを分析し、将来の値を予測する手法です。例えば、過去の売上データから将来の売上を予測したり、過去の気温データから将来の気温を予測したりすることができます。 時系列予測の仕組み 時系列予測では、過去のデータに含まれるパターンやトレンドを捉え、それを未来に拡張することで予測を行います。 トレンド: データが長期的に上昇したり下降したりするような傾向のことです。 季節性: データが特定の周期で変動するパターンのことです。例えば、小売業の売上は季節によって大きく変動することがあります。 周期性: 特定の周期で繰り返されるパターンで、季節性よりも短い周期の変動を指します。 ノイズ: ランダムな変動で、予測を難しくする要因となります。 Geminiからの回答にもある通り、時系列予測は 「過去のデータの動きを分析し、将来の値を予測すること」 を指します。 ビジネス、経済、自然科学と幅広い分野で活用されています。 多変量時系列予測 BigQuery ML で多変量時系列予測を行う方法 | Google Cloud 公式ブログ cloud.google.com 時系列分析の中でも今回は 「多変量時系列予測」 にフォーカスします。 多変量時系列予測は 複数の変数間の時間的な関係をモデル化 し、将来の値を予測する手法です。 単一の変数の動きだけでなく、 複数の変数が互いにどのように影響を与えながら変化していくのか を分析します。 上記リンクではアイスクリームの売上を例に挙げられているのでそれになぞって説明します。 時系列予測で将来の売上データを予測する際、まず欠かせないのが 「過去の売上データ」 です。この情報だけでもある程度の予測はできます。たとえば上の図だと、1月~9月まで単調増加の傾向がみられるため、 橙色の予測データように10月以降も増加する という予測を立てることができます。 ただ、 寒くなり出す10月~12月にこれまで以上のアイスクリームの売り上げが望めるでしょうか 、、、? ここで 「気温」 という他の変数を考慮に入れてみましょう。 12月と比較的気温が近い1月のデータ等を考慮 すると、寒くなる10月以降に関しては、下記のような予測ができます。 このように、 「気温」という外部変数 と 「(過去の)売上」という目的変数 を使用して予測をすることを 「多変量時系列予測」 と言います。   実践 シアトルの大気質データからの多変量時系列予測  |  BigQuery  |  Google Cloud cloud.google.com 今回は上記ドキュメントに沿って時系列予測(多変量時系列予測)をやってみます。 テーブル作成 米国の複数の都市から日次で収集されたPM2.5、気温、風速の情報をもつepa_historical_air_quality データセットから、シアトルの情報を抽出したテーブルを作成します。 下記クエリでテーブルを作成します。 -- epa_historical_air_quality データセット内の *_daily_summary テーブルから各列を取得 CREATE TABLE `yamaguchi_test_bqml.seattle_air_quality_daily` AS WITH -- 各日の PM2.5 の平均値 pm25_daily AS (   SELECT     avg(arithmetic_mean) AS pm25, date_local AS date   FROM     `bigquery-public-data.epa_historical_air_quality.pm25_nonfrm_daily_summary`   WHERE     city_name = 'Seattle'     AND parameter_name = 'Acceptable PM2.5 AQI & Speciation Mass'   GROUP BY date_local ), -- 各日の平均風速 wind_speed_daily AS (   SELECT     avg(arithmetic_mean) AS wind_speed, date_local AS date   FROM     `bigquery-public-data.epa_historical_air_quality.wind_daily_summary`   WHERE     city_name = 'Seattle' AND parameter_name = 'Wind Speed - Resultant'   GROUP BY date_local ), -- 各日の気温 temperature_daily AS (   SELECT     avg(first_max_value) AS temperature, date_local AS date   FROM     `bigquery-public-data.epa_historical_air_quality.temperature_daily_summary`   WHERE     city_name = 'Seattle' AND parameter_name = 'Outdoor Temperature'   GROUP BY date_local ) SELECT pm25_daily.date AS date, pm25, wind_speed, temperature FROM pm25_daily JOIN wind_speed_daily USING (date) JOIN temperature_daily USING (date)   ARIMAモデル作成・トレーニング シアトルの大気質データからの多変量時系列予測  |  BigQuery  |  Google Cloud cloud.google.com それでは早速モデルを作成します。 -- pm25の量を予測するモデルを作成 CREATE OR REPLACE MODEL   `yamaguchi_test_bqml.seattle_pm25_xreg_model` -- 外部回帰モデルの'ARIMA_PLUS_XREG'を作成 OPTIONS(   MODEL_TYPE = 'ARIMA_PLUS_XREG',   time_series_timestamp_col = 'date',   time_series_data_col = 'pm25') AS SELECT date, pm25, temperature, wind_speed FROM `yamaguchi_test_bqml.seattle_air_quality_daily` WHERE date BETWEEN DATE('2012-01-01')   AND DATE('2020-12-31') 今回は 「多変量時系列予測」 が可能な 「ARIMA_PLUS_XREG」 をモデルとして採用しています。 上記クエリのOPTION句でモデルを指定していますが、デフォルトは auto_arima=TRUE が指定されています。これにより、 auto.ARIMA  アルゴリズムによって  ARIMA_PLUS_XREG  モデルのハイパーパラメータが自動的に調整されます。   auto.ARIMA 8.5 Non-seasonal ARIMA models | Forecasting: Principles and Practice (2nd ed) 2nd edition otexts.com auto.ARIMAはR言語のforecastパッケージに含まれる関数で、時系列データを自動的に分析し、最適なモデルを選定してくれるツールです。 auto.ARIMAを使用したトレーニングでは、最適な 非季節順序(p,d,q) が自動的に検出されます。   非季節順序性 非季節順序性とは、ARIMAモデルのパラメータのうち、上記で記述した( p,d,q )で表される部分のことで、時系列データの非季節的な特徴を捉えるために使用されます。   概要 解釈(大きい場合) p:自己回帰次数 過去のデータが現在の値にどれだけ影響を与えるか 過去のデータが現在の値に与える影響が大きい d:差分次数 データの非定常性を解消するために何回差分をとるか データに強いトレンド性がある(=トレンド性をなくすために多くの差分回数が必要だった) q:移動平均次数 過去の誤差が現在の値にどれだけ影響を与えるか 過去の予測誤差が現在の値に与える影響が大きい 定常性は、データの動き方がどの時点でも一定である状態をいいます。 逆に、非定常性は、時間経過による影響でデータが上昇/下降の傾向を見せる状態を指します。   ARIMAモデル概要 Introduction to ARIMA models people.duke.edu ここでARIMAモデルについて詳しく触れます。 ARIMAモデルは以下の三つの要素で構成されます。 自己回帰(AR)項 :過去のデータを予測変数として使用する。 p で表す。 差分(I)項 :データの定常化を行う。非定常性を解消するために実施した差分の次数。 d で表す。 移動平均(MA)項 :過去の予測誤差を予測変数として使用する。 q で表す。 ARIMAモデルはこれらの用をの次数を組み合わせることで「ARIMA(p,d,q)」のように表記されます。 ARIMAモデルは下記手順で構築されます。 データ定常化 :時系列データを定常化(非定常性を解消)する。I項の次数(d)を決定する モデル識別 :自己相関関数(ACF)と偏自己相関関数(PACF)を分析し、AR項、MA項の次数(p,q)を決定する モデル推定 :決定した次数に基づいてARIMAモデルを推定する モデル診断 :残差分析を行い、モデルの適合率を評価する 自己相関 についてちょっと寄り道します。 「自己相関」 とは、時系列データにおいて、 異なる時点におけるデータ間の相関関係 のことです。 つまり、 過去のデータと現在(将来)のデータの間にどの程度関連性があるか を示します。これを視覚化したものが「自己相関関数」になります。 一方で、「偏自己相関関数」は何を指すのでしょうか。日々の売上データ分析を例に考えていきます。 一昨日→昨日→今日の売上の推移です。「自己相関」で橙色の「一昨日→昨日」と「昨日→今日」のそれぞれのデータの関連性を説明できることを先に紹介しました。 では、 一昨日→今日のデータの関連性(緑色) を見たい場合はどうでしょうか? これを自己相関で見ようとすると、一昨日→今日の間にある「昨日」の時点の影響が含まれてしまいます。 これを取り除き、 時点間の直接的な相関を測定できる のが 「偏自己相関」 です。推移性のある影響を排除し、時点間の関連性を表現することができます。   以上の自己相関関数(ACF)、偏自己相関関数(PACF)を分析して、最適なモデルを識別します。 一般的に、 データが平均値から離れても再び平均値に戻ろうとする 「平均回帰性」 がある場合は AR 項 データにランダムな 「ショック」 があり、その影響が2つ以上の連続した期間続く場合は MA 項 が有効であると言われており、 ACFが徐々に減少し、PACFが特定の時点間で急激に0に近づく場合は AR モデル ACFが特定の時点間で急激に0に近づき、PACFが徐々に減少する場合は MA モデル が適していると言われています。 ARIMAモデルは以上の流れで最適な (p,d,q) を決定し、構築・選択されます。   ARIMAモデル評価指標調査 シアトルの大気質データからの多変量時系列予測  |  BigQuery  |  Google Cloud cloud.google.com では、ここまでの内容を踏まえたうえで今回作成したARIMAモデルを評価してみましょう。 ML.ARIMA_EVALUATE関数 を使用した下記クエリを実行します。 SELECT * FROM  ML.ARIMA_EVALUATE(MODEL `yamaguchi_test_bqml.seattle_pm25_xreg_model`) 結果には12の列が含まれています。 まず、auto.ARIMAアルゴリズムはKPSSテストと呼ばれる「データの非定常性を確認する」テストを行い、 【non_seasonal_d】 の値を決定します。 今回はこの値が「1」となっているため、データ内で 非定常性が検出 され、1回差分がとられています。 その後、先ほど説明した通り 【non_seasonal_p(AR項)】 、 【non_seasonal_q(MA項)】 を決定するためのACF、PACF分析が行われます。トレーニングパイプライン内のARIMAモデルは、 【non_seasonal_{p,d,q}】、【has_drift】 の四つの列で定義されます。今回は42個の候補モデルがトレーニング・検証されていますね。 気になる各候補モデルの性能は、 【AIC】 列で判断することができます。 AIC:赤池情報量基準 とは、統計モデルの予測性の良さを評価する統計量です。 AICが小さいほど当てはまりがよい と言えます。今回はクエリ結果の1行目の組み合わせが採用されています。   ARIMAモデル係数調査 シアトルの大気質データからの多変量時系列予測  |  BigQuery  |  Google Cloud cloud.google.com 次に、今回作成したARIMAモデルの係数を調査します。 ML.ARIMA_COEFFICIENTS関数 を使用した下記クエリを実行します。 SELECT * FROM ML.ARIMA_COEFFICIENTS(MODEL `yamaguchi_test_bqml.seattle_pm25_xreg_model`) 【ar_coefficients】、【ma_coefficients】 列はそれぞれAR項、MA項を指します。どちらも配列で、配列の長さは評価指標で出てきた 【non_seasonal_p(AR項)】 、 【non_seasonal_q(MA項)】 です。 今回最も性能の良い(AICが最小の)モデルは (non_seasonal_p , non_seasonal_q) = (0, 5) なので、 MA項が有効 と判断されているようです。 【processed_input】 列には外部変数が表示されており、 【weight】 列には外部変数がモデルの予測に与える影響の大きさ(重み)が示されています。具体的にみると、 temperature=0.038…(比較的小さな正の値):気温が上昇するとPM2.5もわずかに上昇する傾向がある wind_speed=-1.957…(負の値):風速が上昇するとPM2.5が大きく低下する傾向がある ということが考察できます。 【processed_input】列の「__INTERCEPT__」には比較的大きな正の値11.3243…が表示されています。これは他の外部変数の影響を考慮しない場合の予測値のベースラインが高いことを示しています。   ARIMAモデルを使用して時系列を予測する シアトルの大気質データからの多変量時系列予測  |  BigQuery  |  Google Cloud cloud.google.com 大変お待たせしました。今回作成したARIMAモデルを使って時系列予測してみます。 ML.FORECAST 関数 を使用した下記クエリを実行します。 今回、’2020-12-31’までのデータを使ってモデルをトレーニングしているので、’2020-12-31’以降のデータを予測してみます。 SELECT * FROM ML.FORECAST( MODEL `yamaguchi_test_bqml.seattle_pm25_xreg_model`,   STRUCT(30 AS horizon,     0.8 AS confidence_level),   (   SELECT     date,     temperature,     wind_speed   FROM     `yamaguchi_test_bqml.seattle_air_quality_daily`   WHERE       date > DATE('2020-12-31') )) 各列の見方は以下の通りです。(今回は箇条書きにします。) forecast_timestamp:予測対象の日時 forecast_value:モデルによって算出された予測値 standard_error:予測値の標準誤差。大きいほど予測値のばらつきが大きい confidence_level:予測値の信頼水準 prediction_interval_lower(upper)_bound:予測区間の下限(上限)値。この区間の間に、ある確率(信頼水準)で真の値が含まれると考えられる 1行目のデータを例に見てみます。 このデータは、 2021年1月1日の予測値が9.495…であり、80%の確率で真の値は6.883…と12.107…の間にあること を示しています。   実際のデータで予測精度を評価する シアトルの大気質データからの多変量時系列予測  |  BigQuery  |  Google Cloud cloud.google.com 実際のデータを使って、予測の精度を評価します。 ML.EVALUATE 関数 を使用した下記クエリを実行します。 SELECT * FROM ML.EVALUATE( MODEL `yamaguchi_test_bqml.seattle_pm25_xreg_model`,   (   SELECT     date,     pm25,     temperature,     wind_speed   FROM     `yamaguchi_test_bqml.seattle_air_quality_daily`   WHERE     date > DATE('2020-12-31') ),   STRUCT( TRUE AS perform_aggregation,       30 AS horizon)) 時系列モデルに対してML.EVALUATE 関数を使用した場合、下記の指標が得られます。 ・mean_absolute_error(MAE):平均絶対誤差 ・mean_squared_error(MSE):平均二乗誤差 ・root_mean_squared_error(RMSE):二乗平均平方根誤差 ・mean_absolute_percentage_error(MAPE):平均絶対パーセンテージ誤差 ・symmetric_mean_absolute_percentage_error(SMAPE):対称平均絶対パーセンテージ誤差 MAE,MSE,RMSEに関しては こちらのブログ をご覧ください。 MAPEは、 予測値と実測値の絶対誤差を、実測値で割った値の平均 です。相対的な誤差の大きさをパーセンテージで表します。ただし、絶対誤差を実測値で割るため、 実測値が0を取り得る場合は使用できません 。 SMAPEは、MAPEの改良版で、 実測値が0に近い場合に発生する無限大になる問題を改善した指標 です。MAPEが上手く機能しない場合はこちらを見ることがあります。 今回の結果のMAE,SMAPEに着目してみると、 平均的には予測値と実績値に約2.532の差がある 相対的な誤差は平均で約27.02%である であるということが言えます。 一般的には、今回得られた5指標が 小さい値の方が良い結果(予測精度が高い) ということが言えます。   まとめ 今回は時系列モデルのARIMA_PLUS_XREGを使用して時系列予測(多変量時系列予測)をやってみました。 今回は過去データに加えて「風速、気温」を外部変数として取り込み、将来のPM2.5の量を予測してみました。個人的にはML.ARIMA_COEFFICIENTS関数を使うことで 「各外部変数が予測に与える影響を数値化できる点」 が非常に興味深かったです。 多変量時系列予測においては、どの変数が目的変数に大きな影響を与えるか(≒外部変数に何を選ぶか)が重要になります。 今回は実践していませんが、モデルを作成する前に、 予測する時系列を可視化する方法 が公式ドキュメントで紹介されていました。これを活用することで目的変数に影響を与えている変数に事前にあたりをつけることもできそうです。 だいぶ情報量の多いブログになってしまいましたが、本記事が皆さんの時系列分析に役立つと嬉しいです。
アバター
こんにちは!Zabbixを担当している曽我です。 Zabbix構築サービス「Quick Start Package for Zabbix」のオプションメニューに Syslogサーバ導入サービスが追加されましたので、そのご紹介です。 Quick Start Package for Zabbixとは?と思われた方は以下のURLをご覧ください。 Quick Start Package for Zabbixサービスのご紹介 SCSKが提供するZabbixの新構築サービス「Quick Start Package for Zabbix」をご紹介いたします。 blog.usize-tech.com 2024.08.21 本サービスについて Zabbixサーバ自身には、Syslogの機能はないため、普段Syslogサーバを別で構築してそこにZabbixエージェントを導入し、 Syslogを監視します。ただ、この方法だけでは、Syslogで検知した障害情報が、Syslogサーバで発生したように なってしまいます。(参照:図1) 運用上、実際に障害が発生した機器で障害が起きたように検知したいですよね。 スクリプトを使って、実現することも出来ますが、本サービスで利用しているぷらっとホーム社のEasyBlocks Syslogを 利用することで簡単に実現することができます。(参照:図2) 図1:これまでのSyslog検知 図2:Syslogサービス利用した場合の構成   Syslogサーバ導入サービス概要 Syslogサーバ ぷらっとホーム社のEasyBlocks Syslogを利用します。 EasyBlock Syslogについては、以下のURLをご参照ください。 EasyBlocks Syslog シリーズ | ぷらっとホーム株式会社 EasyBlocks SyslogアプライアンスはSyslogサーバー専用機です。年々肥大化していくログ情報に対して、汎用サーバーでは、保存領域の問題や管理も容易ではありません。簡単に導入・設定作業ができる専用サーバーの導入で、ログ閲覧、ロ... www.plathome.co.jp 機器イメージ(EasyBlocks Syslog HX 2T) Syslogサーバ構築サービス 以下の作業を実施します。 Syslogサーバの基本設定作業 SyslogとZabbix連携設定 5件(最大20件まで) Syslog連携用Zabbix監視テンプレート作成作業 Syslog連携テスト 成果物 Syslogアプライアンスの監視設定手順書 Syslogアプライアンス設計書 Zabbixサーバテンプレート設計書 テスト仕様書兼結果報告書   価格 まとめ Zabbix導入時に、Syslog導入が必要な場合は、Quick Start PackageのオプションであるSyslog導入サービスをご選択ください   参考 弊社ではZabbix関連サービスを展開しています。以下ページもご参照ください。 ★SCSK Plus サポート for Zabbix★ SCSK Plus サポート for Zabbix 世界で最も人気のあるオープンソース統合監視ツール「Zabbix」の導入構築から運用保守までSCSKが強力にサポートします www.scsk.jp ★YouTubeに、SCSK Zabbixチャンネルを開設しました!★ SCSK Zabbixチャンネル 本チャンネルでは、SCSK株式会社でのZabbixに関するトレンド/事例紹介などを動画にまとめて取り上げております。 最新のトピックについては、以下の弊社HPもしくはツイッターアカウントをぜひ参照ください。 ツイッターアカウント: www.youtube.com ★X(旧Twitter)に、SCSK Zabbixアカウントを開設しました!★ x.com X.com
アバター
こんにちは。SCSKのふくちーぬです。私はコンテナを扱う際に、Dockerインストール済みのCloud9を頻繁に使っていました。 今回は、EC2(Windowsサーバ)にWSL+Dockerをインストールする方法をご紹介します。 EC2(Windowsサーバ)でDockerを利用するためには WindowsサーバでDockerを利用するためには、Docker Engineに加えてWSL2のインストールが必要になっています。WSLは、Windows上でLinuxを動作させる仮想化技術です。 しかし、 通常のEC2インスタンス では仮想化技術(ハイパーバイザー)を使用してAWSの物理ハードウェア上にVM(仮想マシン)を作成します。この仮想化環境では、VM(仮想マシン)自体に直接のハードウェアアクセスや仮想化の制御を加えることができません。そのためWSLのような仮想化必要とするソフトウェアの実行が制限されます。 一方、 ベアメタルインスタンスでは 、仮想化を使用せずに物理サーバー上で直接実行されます。これにより、ホストOSの仮想化機能に直接アクセスできるため、WSLが必要とする仮想化機能を利用できます。   つまりWindowsサーバでDockerを利用するためには、ベアメタルインスタンスを選定する必要があります。 WSL には、WSL 1 と WSL 2 の 2 つのバージョンがあります。 ・.metal EC2 インスタンスの場合は、WSL 1 または WSL 2 のいずれかをインストールできます。 EC2 Windows インスタンスに Windows Subsystem for Linux をインストールする - Amazon Elastic Compute Cloud Windows インスタンスに Windows Subsystem for Linux (WSL) をインストールする docs.aws.amazon.com   また料金は高額ですが、AWSではベアメタルインスタンスが提供されています。 インスタンス名 オンデマンドの時間単価 vCPU メモリ ストレージ ネットワークパフォーマンス c5n.large USD 0.108 2 5.25 GiB EBS のみ 最大 25 ギガビット c5n.xlarge USD 0.216 4 10.5 GiB EBS のみ 最大 25 ギガビット c5n.2xlarge USD 0.432 8 21 GiB EBS のみ 最大 25 ギガビット c5n.4xlarge USD 0.864 16 42 GiB EBS のみ 最大 25 ギガビット c5n.9xlarge USD 1.944 36 96 GiB EBS のみ 50 ギガビット c5n.18xlarge USD 3.888 72 192 GiB EBS のみ 100 ギガビット c5n.metal USD 3.888 72 192 GiB EBS のみ 100 ギガビット オンデマンドインスタンスの料金 - Amazon EC2 (仮想サーバー) | AWS オンデマンドインスタンスについては、お客様が使用された EC2 インスタンスの料金のみのお支払いとなります。オンデマンドインスタンスを使用することにより、ハードウェアのプランニング、購入、維持に伴うコストや手間が省け、高額な固定費となりがち... aws.amazon.com アーキテクチャー Systems Managerの管理下にするために、EC2はマネージドインスタンスとする。また、OSはWindows Server 2022を利用します。 運用者は、フリートマネージャーを利用してEC2に接続します。 EC2にDockerをインストールし、DockerHubからイメージを取得できるようにします。 完成したCloudFormationテンプレート 以下のテンプレートをデプロイしてください。 AWSTemplateFormatVersion: 2010-09-09 Description: CFN template EC2 Parameters: ResourceName: Type: String AMIId: Type: String Resources: # ------------------------------------------------------------# # VPC # ------------------------------------------------------------# VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Sub ${ResourceName}-VPC # ------------------------------------------------------------# # Internet Gateway # ------------------------------------------------------------# InternetGateway: Type: AWS::EC2::InternetGateway AttachGateway: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref VPC InternetGatewayId: !Ref InternetGateway # ------------------------------------------------------------# # Public Subnet # ------------------------------------------------------------# PublicSubnet1a: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.1.0/24 AvailabilityZone: ap-northeast-1a MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Sub ${ResourceName}-subnet-1a # ------------------------------------------------------------# # Route Table and Routes # ------------------------------------------------------------# PublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: PublicRouteTable PublicRoute: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway PublicSubnet1aAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnet1a RouteTableId: !Ref PublicRouteTable # ------------------------------------------------------------# # Security Group # ------------------------------------------------------------# SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: For EC2 VpcId: !Ref VPC # ------------------------------------------------------------# # IAM Role and Instance Profile # ------------------------------------------------------------# SSMRole: Type: AWS::IAM::Role Properties: RoleName: !Sub ${ResourceName}-ec2-role AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: ec2.amazonaws.com Action: sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Roles: - !Ref SSMRole # ------------------------------------------------------------# # EC2 Key Pair # ------------------------------------------------------------# KeyPair: Type: AWS::EC2::KeyPair Properties: KeyName: !Sub ${ResourceName}-key # ------------------------------------------------------------# # EC2 Instance # ------------------------------------------------------------# EC2Instance: Type: AWS::EC2::Instance Properties: InstanceType: c5n.metal ImageId: !Ref AMIId SubnetId: !Ref PublicSubnet1a IamInstanceProfile: !Ref InstanceProfile SecurityGroupIds: - !Ref SecurityGroup KeyName: !Ref KeyPair Tags: - Key: Name Value: !Sub ${ResourceName}-ec2  WSLのインストール キーペアの値を確認し、EC2に接続 下記記事を参考に、同様の手順でEC2にフリートマネージャー経由で接続します。 フリートマネージャー経由でのWindowsサーバ接続時に、PowerShellのキーボード入力機能を動作させるためには AWS Systems Managerのフリートマネージャーを利用して、Windowsサーバにブラウザベースでのリモート接続している方多いかと思います。その際に、PowerShellでキーボード入力が機能しなかった事象が発生しましたので対処策をお話します。 blog.usize-tech.com 2024.09.09 WSL2のインストール PowerShellを開き、コピー&ペーストを使って下記コマンドを実行します。 wsl --install インストールが完了したら、インスタンスを再起動します。 その後EC2に再接続し、Ubuntuがインストールされていることを確認します。 ベアメタルインスタンスのため接続までに30分ほど時間がかかるのでお待ちください。   自動的にWSLが立ち上がり、Ubuntuのインストールが始まります。 ユーザー名を入力します。その後、パスワードを入力します。 再度パスワードを入力します。 インストールが完了しました。 Dockerのインストール Ubuntuを開き、Dockerのリポジトリをセットアップするために以下のコマンドを実行します。 sudo apt-get update sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc echo \ "deb [arch= $( dpkg --print-architecture ) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $( . /etc/os-release && echo " $VERSION_CODENAME " ) stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update   続けて、Docker Engineをインストールします。 sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin   sudo権限なしにdockerコマンドを実行できるように、ユーザーに対して権限付与します。 sudo groupadd docker sudo usermod -aG docker <ユーザー名> su - <ユーザー名>   Dockerサービスを起動させておきます。 sudo service docker start   以下のコマンドを実行しDockerのバージョンとコンテナが稼働することを確認します。 docker -v docker run hello-world Ubuntu Jumpstart your client-side server applications with Docker Engine on Ubuntu. This guide details prerequisites and multip... docs.docker.com 最後に いかがだったでしょうか。 ベアメタルインスタンスを選定することで、Dockerを導入してコンテナを利用できるようになります。お値段は高いですが、Docker実行環境の一つの候補として検討いただければと思います。 本記事が皆様のお役にたてば幸いです。 ではサウナラ~🔥
アバター
こんにちは。SCSKのふくちーぬです。 前回、フリートマネージャー経由でのWindowsサーバ接続時にPowerShellのキーボード入力機能を動作させるための方法をご紹介しました。こちらの記事を読んでいない方は、是非ご一読ください。 フリートマネージャー経由でのWindowsサーバ接続時に、PowerShellのキーボード入力機能を動作させるためには AWS Systems Managerのフリートマネージャーを利用して、Windowsサーバにブラウザベースでのリモート接続している方多いかと思います。その際に、PowerShellでキーボード入力が機能しなかった事象が発生しましたので対処策をお話します。 blog.usize-tech.com 2024.09.09 今回は、閉域網環境内で実現させるための方法をご紹介します。 アーキテクチャー インターネットゲートウェイ、NATゲートウェイが存在しない閉域網ネットワーク(プライベート環境)とする。 Systems Managerの管理下にするために、EC2はマネージドインスタンスとする。また、OSはWindows Server 2022を利用します。 運用者は、フリートマネージャーを利用してEC2に接続します。 運用者は、マネジメントコンソールやAPIを利用してS3にアクセスしファイルのやり取りをします。 プライベートサブネット内のEC2は、VPCエンドポイント経由でS3にアクセスしファイルのやり取りをします。 完成したCloudFormationテンプレート 以下のテンプレートをデプロイしてください。 AWSTemplateFormatVersion: 2010-09-09 Description: CFN template EC2 Parameters: ResourceName: Type: String AMIId: Type: String Resources: # ------------------------------------------------------------# # S3 # ------------------------------------------------------------# S3BucketFor: Type: AWS::S3::Bucket DeletionPolicy: Delete Properties: BucketName: !Sub ${ResourceName}-s3-bucket AccessControl: Private PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true # ------------------------------------------------------------# # VPC # ------------------------------------------------------------# VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Sub ${ResourceName}-VPC # ------------------------------------------------------------# # Private Subnet # ------------------------------------------------------------# PrivateSubnet1a: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.1.0/24 AvailabilityZone: ap-northeast-1a MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub ${ResourceName}-subnet-Private-1a PrivateSubnet1c: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.11.0/24 AvailabilityZone: ap-northeast-1c MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub ${ResourceName}-subnet-Private-1c # ------------------------------------------------------------# # Route Table and Routes # ------------------------------------------------------------# PrivateRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: PrivateRouteTable PrivateSubnet1aAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet1a RouteTableId: !Ref PrivateRouteTable PrivateSubnet1cAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet1c RouteTableId: !Ref PrivateRouteTable # ------------------------------------------------------------# # VPC Endpoint # ------------------------------------------------------------# ssmEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Join - '' - - com.amazonaws. - !Ref 'AWS::Region' - .ssm SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref VPCeSecurityGroup PrivateDnsEnabled: true ec2messagesEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Join - '' - - com.amazonaws. - !Ref 'AWS::Region' - .ec2messages SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref VPCeSecurityGroup PrivateDnsEnabled: true ssmmessagesEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Join - '' - - com.amazonaws. - !Ref 'AWS::Region' - .ssmmessages SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref VPCeSecurityGroup PrivateDnsEnabled: true S3VpcEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Join - '' - - com.amazonaws. - !Ref 'AWS::Region' - .s3 VpcId: !Ref VPC VpcEndpointType: Gateway RouteTableIds: - !Ref PrivateRouteTable # ------------------------------------------------------------# # Security Group # ------------------------------------------------------------# SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: For EC2 VpcId: !Ref VPC VPCeSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: !Ref VPC GroupDescription: For VPCEndpoint SecurityGroupIngress: - SourceSecurityGroupId: !Ref SecurityGroup IpProtocol: tcp FromPort: 443 ToPort: 443 # ------------------------------------------------------------# # IAM Role and Instance Profile # ------------------------------------------------------------# SSMRole: Type: AWS::IAM::Role Properties: RoleName: !Sub ${ResourceName}-ec2-role AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: ec2.amazonaws.com Action: sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore - arn:aws:iam::aws:policy/AmazonS3FullAccess InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Roles: - !Ref SSMRole # ------------------------------------------------------------# # EC2 Key Pair # ------------------------------------------------------------# KeyPair: Type: AWS::EC2::KeyPair Properties: KeyName: !Sub ${ResourceName}-key # ------------------------------------------------------------# # EC2 Instance # ------------------------------------------------------------# EC2Instance: Type: AWS::EC2::Instance Properties: InstanceType: t2.micro ImageId: !Ref AMIId SubnetId: !Ref PrivateSubnet1a IamInstanceProfile: !Ref InstanceProfile SecurityGroupIds: - !Ref SecurityGroup KeyName: !Ref KeyPair Tags: - Key: Name Value: !Sub ${ResourceName}-ec2  解決策 PSReadlineモジュールをローカルでインストールします。その後サーバに移送し、モジュールを読み込ませることで対応できます。 PSReadlineの手動インストール 下記サイトにて、PowerShellモジュールをインストールすることができます。今回は、最新バージョンの2.3.5を選定しました。 PSReadLine 2.3.5 Great command line editing in the PowerShell console host powershellgallery.com “Manual Download”を押下します。 “Download the raw nupkg file”を押下して、バイナリファイルをダウンロードします。 ファイルの拡張子をzipに変更します。 S3へのアップロード S3に”psreadline.2.3.5.zip”ファイルをアップロードします。 キーペアの値を確認し、EC2に接続 下記記事を参考に、同様の手順でEC2にフリートマネージャー経由で接続します。 フリートマネージャー経由でのWindowsサーバ接続時に、PowerShellのキーボード入力機能を動作させるためには AWS Systems Managerのフリートマネージャーを利用して、Windowsサーバにブラウザベースでのリモート接続している方多いかと思います。その際に、PowerShellでキーボード入力が機能しなかった事象が発生しましたので対処策をお話します。 blog.usize-tech.com 2024.09.09 Read-S3Objectコマンドの実行 下記記事を参考に、同様の手順でPowerShellで下記コマンドをコピー&ペーストで実行します。 閉域網環境のEC2(Windows)においてファイル共有する方法 AWS Systems Managerのフリートマネージャーを利用して、Windowsサーバにブラウザベースでのリモート接続している方多いかと思います。今回は閉域網環境において、ローカル-サーバ間においてファイル共有するためにAWS Tools for Windows PowerShellを用いる方法をご紹介します。 blog.usize-tech.com 2024.09.09   Read -S3Object -BucketName <Bucket Name> - Key <Object Key > - File <Local File Path > 例として、以下のコマンドになります。 Read-S3Object -BucketName fukuchi-s3-bucket -Key psreadline.2.3.5.zip -File C:\Users\Administrator\Downloads\psreadline.2.3.5.zip   サーバ上にダウンロードできれば下記画面が表示されます。 モジュールの入れ替え ダウンロードしたzipファイルを解凍しておきます。   以下のディレクトリ配下の”PSReadline”フォルダを削除します。 └C:\Program Files\WindowsPowerShell\Modules その後、”psreadline.2.3.5″フォルダをコピーします。 再度PowerShellを起動し、キーボードから任意の文字を入力してみます。 無事にキーボード入力が機能しましたね。   最後に いかがだったでしょうか。 フリートマネージャー経由で閉域網のWindowsサーバに接続する必要がある場合でも、モジュールを持ち込むことでPowerShellを正常に機能させることができます。 本記事が皆様のお役にたてば幸いです。 ではサウナラ~🔥
アバター
本記事は、 ~Catoクラウド運用にあたって知っておくべきIT用語まとめ~ 【セキュリティ編】 – TechHarmony (usize-tech.com) の続編になります。 これまでCatoクラウドを運用するにあたって必要なIT用語として、『ネットワーク編』、『セキュリティ編』と題して解説してきました。 本記事は応用編と題して、これまで解説した用語よりも耳なじみのない用語を取り上げて解説したいと思います。 Catoクラウドとは何か、が知りたい方は以下の記事をご覧いただければと思います。 ・ 世界初のSASEプラットフォーム Catoクラウドとは? – TechHarmony (usize-tech.com) それでは早速、用語解説していきます。 SASEと関連する混同されやすい用語 応用編なのに、SASE?と思われた方も多いかもしれません。 なぜここで取り上げたかというと、後述するSASEと関連する英語の略語との違いがわかりづらく、ご質問いただくことが多いため、あえて応用編でご紹介させていただきます。 Cato社によれば、SASEとは「Secure Access Service Edge」の略称であり、「ネットワークとセキュリティの機能をクラウドベースの単一ソリューションに統合したもの」と説明されています。 その機能はというと、主に以下のことを指します。 ネットワーク機能:SD-WAN セキュリティ機能:ゼロトラストネットワークアクセス(ZTNA)、次世代ファイアウォール(NGFW)、セキュアWebゲートウェイ(SWG)など では、このSASEと混同されやすい用語を以下で詳しく解説していきます。 SD-WAN SD-WANとは、「Software-Defined Wide Area Network」の略称で、Cato社によれば「ブロードバンド、MPLS、5G/LTEなど複数の異なるメディアにおいて、最適なトラフィックルーティングを提供する仮想WANアーキテクチャ」と説明されています。 ネットワークをソフトウェアで制御するSDN(Software Defined Networking)を、ユーザーとアプリケーションを安全かつ効率的に接続するために拠点間接続のWANに適用した仮想的なWANのことです。 上述の通り、SD-WANは、SASEのネットワークの最適化機能の一部とご理解いただければと思います。 ZTNA ZTNAは、「Zero-Trust Network Access」の略称です。ゼロトラストの言葉からも分かる通り、明示的に許可されていない限りは、アプリケーションなどリソースへのアクセスをすべて拒否する、セキュアなアクセスを実現するソリューションのことを言います。 従来のVPNは、社内ユーザを信頼し、信頼できないユーザーは社外にいるとして想定されたネットワーク構成でした。 ですが、リモートワークという新しい働き方が波及した昨今では、この境界線はなくなりつつあります。 また、ユーザーの場所の変化だけではなく、アプリケーションやデータベースの所在もまたオンプレミスからクラウドへの移行が進んでいます。このような変化に対応するためのソリューションの一つとして、ZTNAの普及が進んでいます。 上述の通り、ZTNAも同じくSASEのセキュリティ機能のごく一部です。 SSE SSEは、SASEが登場した2019年の2年後 2021年に登場した用語で、「Security Service Edge」の略称です。 SSEは、SASEからネットワーク機能を除き、セキュリティ機能のみにフォーカスしたものです。 つまり、SSEもまたSASEの一部であり、一般的には、SWG、ZTNA/SDP、CASB/DLP機能のみを指すことが多いです。 このSSEとSASEの違いについては、以下の記事で詳しく解説されています。ご興味ある方はぜひご覧いただければと思います。 ・ SSEとSASEどちらを選べばよいのか? – TechHarmony (usize-tech.com) セキュリティ関連用語 ここからは、セキュリティ分野として証明書に関する理解しづらい仕組み「 証明書のピンニング 」と、 昨今話題に上がる違いがわかりづらいセキュリティ分野の英語の略語「 EPP・EDR・XDR・MDR 」を取り上げてご説明します。 証明書のピンニング ここで言う証明書は、 セキュリティ編 でご紹介したデジタル証明書を指します。 忘れてしまったという方は、リンクから一度振り返ってみていただければと思います。 証明書のピンニング(ピン留め)とは、Webサイトやソフトウェアの中で利用できる証明書が埋め込まれている状態のことを言います。 “埋め込まれている”とは、利用可能な証明書が “制限されている” 状態であり、ほかの証明書を利用しようとすると通信が拒否されます。 これは主にソフトウェア提供者が、偽造された証明書による中間者攻撃のリスクを減少させるために導入する、セキュリティ強化の仕組みです。 なぜこの証明書のピンニングをご紹介したかというと、CatoのTLS Inspectionという機能を利用する際に、証明書のピンニングが理由で通信できない事象が発生することが多くあるからです。 TLS Inspectionはセキュリティ強化のために多くのお客様で利用されている機能の一つで、事前にこの問題を知っておいていただければと思います。 TLS Inspectionの機能詳細や、どうして問題が発生するのか詳しく知りたい方は、 こちらのブログ をご参照いただければと思います。 EPPとEDR EPPとは、「Endpoint Protection Platform」の略称です。PCなどのエンドポイントデバイスを、サイバー脅威から保護するセキュリティ製品のことを言います。 一方で、EDRとは「Endpoint Detection and Response」の略称です。エンドポイント上の不審なふるまいやネットワーク上の異常を分析し、その対処までを行うソリューションのことを一般に指します。 EPPはエンドポイントに対する 攻撃を予防 することに重点を置き、EDRは 侵入後の対処 に焦点を当てているところに違いがあります。 2024年9月現在 Catoでは、EPPをWindowsデバイスに対して提供しています。そしてEDRとして、デバイスから取得した情報をもとに、潜在的な脅威の深刻度や影響度についての分析結果を提供しています。 XDR XDRは、「Extended Detection and Response」の略称です。 エンドポイントや、ネットワーク、セキュリティ、クラウドといった各種のログを収集・分析し、攻撃を可視化し、インシデント管理を一元化できるセキュリティソリューションのことです。 EDRが エンドポイントのログ から分析するのに対し、XDRは、 エンドポイントのほか、ネットワーク・セキュリティ製品のログからも分析し、かつインシデント管理が一元化 できることがポイントです。 CatoにもXDR機能が備わっています。CatoのXDRは、世界初のSASEベースのXDRソリューションで、Catoクラウドで検知したイベントをもとに分析した結果がCatoの管理コンソール上で確認可能です。また、その分析結果をもとに、Cato管理コンソール上でスムーズに必要な対処まで行うことができます。 CatoのEPPとXDRの詳細について、ご説明しているブログがございます。ぜひ合わせてご参照いただければと思います。 ・ CatoクラウドのEPPとXDRについて – TechHarmony (usize-tech.com) MDR MDRとは、「Managed Detection and Response」の略称です。 上記のEPP等のセキュリティ製品から検知したインシデント等の対応を行う マネージドサービス のことです。 CatoにもMDRが用意されています。 AIを活用し、Cato社の専門のセキュリティチームと連携し、脅威の調査と検証、お客様への通知などを行うサービスとなっています。 最後に 3編を通して、Catoクラウドを運用するにあたって必要なIT用語 をご紹介させていただきました。いかがでしたでしょうか。 正確にきちんと理解できていた用語もあれば、あやふやに理解していた用語もあったのではないでしょうか。 当社は豊富な運用実績がございますので、何かCatoクラウドの導入や運用にあたって、不明なことがありましたら、お気軽にお問い合わせいただければと思います。
アバター
こんにちは、広野です。 本記事はシリーズもので、以下の記事の続編です。 Amazon Bedrock RAG 環境用 AWS CloudFormation テンプレート series 1 VPC 編 Agents for Amazon Bedrock を使用した最小構成の RAG 環境を構築する AWS CloudFormation テンプレートを紹介します。3部構成になっており、本記事は1つ目、VPC 編です。 blog.usize-tech.com 2024.08.01 Amazon Bedrock RAG 環境用 AWS CloudFormation テンプレート series 2 Aurora 編 Agents for Amazon Bedrock を使用した最小構成の RAG 環境を構築する AWS CloudFormation テンプレートを紹介します。3部構成になっており、本記事は2つ目、Aurora Serverless 編です。 blog.usize-tech.com 2024.08.20 以前、以下の記事で Amazon Bedrock や Agents for Amazon Bedrock を使用した最小構成 RAG 環境構築を紹介しておりました。当時はAmazon Bedrock 関連のリソースを一部 AWS CloudFormation ではデプロイできなかったのですが、今はサポートされたためにできるようになりました。 React アプリに Agents for Amazon Bedrock への問い合わせ画面を組み込む [RAG・レスポンスストリーミング対応] Agents for Amazon Bedrock を使用して簡単な RAG をつくってみましたので、問い合わせ画面コードの一部を紹介します。 blog.usize-tech.com 2024.02.15 当時の構成を現在は変更しており、Knowledge Base に使用するデータベースを Amazon OpenSearch Serverless から Aurora Serverless v2 Postgresql に変更したり、モデルを Claude 3.5 Sonnet に変更したりしています。 本シリーズ記事では、環境構築用の AWS CloudFormation のサンプルテンプレートを 3 記事に分けて紹介します。説明を分割するため、テンプレートを3つに分けていますのでご了承ください。 3回目は Amazon Bedrock 編です。 本記事で取り扱う構成 RAG 環境全体の構成 以下のアーキテクチャで RAG アプリケーションを構築しています。このうち、赤枠の部分が本シリーズ記事で取り扱う箇所です。すみません、当初 Amazon SQS まで含んでおりましたが、コード量が多くなってしまうため今回から割愛いたしました。 series 3 Bedrock 編では、series 2 で構築した Amazon Aurora Serverless v2 Postgresql を Agents for Amazon Bedrock に Knowledge Base として登録し、RAG を使用しない問い合わせ (一般検索) 用の AWS Lambda 関数、および Agents for Amazon Bedrock に問い合わせるための AWS Lambda 関数 URL をデプロイします。 Agents for Amazon Bedrock の構成 Agents for Amazon Bedrock は、ユーザーからの問い合わせの内容から、裏にあるどのナレッジから回答を得るべきか仕分けの判断をしてくれます。ただし、判断基準となる情報は提供してあげないといけないので、それを自然言語で設定します。 「SCSK」に関する問い合わせであった場合は、Knowledge Base を確認するようにします。(RAG 検索ルート) それ以外の問い合わせであれば、AWS Lambda 関数を呼び出します。この関数は Amazon Bedrock Claude モデルに問い合わせます。(一般検索ルート) アプリから Agents for Amazon Bedrock に問い合わせるためには、それ用の AWS Lambda 関数が必要です。ただし関数だけでは API から問い合わせを受け付けられないので、Lambda 関数 URL で公開しています。代わりに API Gateway でもかまいませんが、ストリームレスポンスに対応していなかったため Node.js の関数 URL にしました。 AWS Lambda 関数 URL には、CORS 設定のためドメイン情報を設定しています。ドメイン名などの情報は、AWS CloudFormation テンプレートのパラメータとして入力するようにしています。 AWS Lambda 関数 URL の認証については本記事では割愛します。以下の参考記事をご覧ください。 やってみたら面倒くさい、React アプリからの Amazon Cognito 認証付き AWS Lambda 関数 URL 呼出 Amazon Cognito 認証を施した React アプリから、認証済みユーザのみ AWS Lambda 関数を呼び出せるようにする React コードを紹介します。 blog.usize-tech.com 2024.01.15 AWS CloudFormation テンプレート 図に掲載している赤字部分を今回のテンプレートで作成しています。一部、前回のテンプレートで作成したスタックからの情報をインポートしている箇所があります。 使用する Amazon Bedrock (一般検索用) のリージョンや Anthropic Claude モデルのバージョンは簡単に変更可能にするため、パラメータ化しています。技術の進歩が著しいので。 AWSTemplateFormatVersion: 2010-09-09 Description: The CloudFormation template that creates an Agent for Amazon Bedrock, a Bedrock Knowledge base, and a Lambda function URL. # ------------------------------------------------------------# # Input Parameters # ------------------------------------------------------------# Parameters: SubName: Type: String Description: System sub name of sample. (e.g. test) Default: test MaxLength: 10 MinLength: 1 DomainName: Type: String Description: Domain name for URL. Default: scskexample.com MaxLength: 40 MinLength: 5 AllowedPattern: "[^\\s@]+\\.[^\\s@]+" SubDomainName: Type: String Description: Sub domain name for URL. (e.g. xxx of xxx.scskexample.com) Default: xxx MaxLength: 20 MinLength: 1 BedrockAgentAliasName: Type: String Description: The Alias name of Agents for Amazon Bedrock. Default: Default MaxLength: 20 MinLength: 1 BedrockRegion: Type: String Description: The region name you use for Amazon Bedrock Claude 3 model. (e.g. ap-northeast-1) Default: ap-northeast-1 MaxLength: 50 MinLength: 1 ClaudeModelId: Type: String Description: The Claude 3 model ID. (e.g. anthropic.claude-3-5-sonnet-20240620-v1:0) Default: anthropic.claude-3-5-sonnet-20240620-v1:0 MaxLength: 100 MinLength: 1 Resources: # ------------------------------------------------------------# # Bedrock Knowledge Base # ------------------------------------------------------------# BedrockKnowledgeBase: Type: AWS::Bedrock::KnowledgeBase Properties: Name: !Sub sample-${SubName}-kb Description: !Sub RAG Knowledge Base for sample-${SubName} KnowledgeBaseConfiguration: Type: VECTOR VectorKnowledgeBaseConfiguration: EmbeddingModelArn: !Sub arn:aws:bedrock:${AWS::Region}::foundation-model/amazon.titan-embed-text-v1 RoleArn: Fn::ImportValue: !Sub sample-${SubName}-IAMRoleBedrockKbArn StorageConfiguration: Type: RDS RdsConfiguration: CredentialsSecretArn: Fn::ImportValue: !Sub sample-${SubName}-SecretAurora DatabaseName: bedrockragkb FieldMapping: MetadataField: metadata PrimaryKeyField: id TextField: chunks VectorField: embedding ResourceArn: Fn::ImportValue: !Sub sample-${SubName}-AuroraDBClusterArn TableName: bedrock_integration.bedrock_kb Tags: Cost: !Sub sample-${SubName} BedrockKnowledgeBaseDataSource: Type: AWS::Bedrock::DataSource Properties: Name: !Sub sample-${SubName}-kb-datasource Description: !Sub RAG Knowledge Base Data Source for sample-${SubName} KnowledgeBaseId: !Ref BedrockKnowledgeBase DataDeletionPolicy: RETAIN DataSourceConfiguration: Type: S3 S3Configuration: BucketArn: Fn::ImportValue: !Sub sample-${SubName}-S3BucketKbDatasourceArn # ------------------------------------------------------------# # Agents for Amazon Bedrock # ------------------------------------------------------------# BedrockAgent: Type: AWS::Bedrock::Agent Properties: AgentName: !Sub sample-${SubName} Description : !Sub The agent for sample-${SubName} to assign the appropriate knowledge base or action group. AgentResourceRoleArn: !GetAtt BedrockAgentRole.Arn FoundationModel: "anthropic.claude-v2:1" Instruction: | あなたは優秀なAIアシスタントです。ユーザーの指示には日本語で回答してください。SCSKに関する情報が必要な場合はナレッジベースから情報を取得してください。それ以外の問い合わせには、Action Group に設定している Claude foundation model を使用して回答してください。 KnowledgeBases: - KnowledgeBaseId: !Ref BedrockKnowledgeBase KnowledgeBaseState: ENABLED Description: Knowledge Base for the information related to SCSK ActionGroups: - ActionGroupName: UserInputAction ActionGroupState: ENABLED ParentActionGroupSignature: AMAZON.UserInput - ActionGroupName: LambdaBedrockAgentAgClaude ActionGroupState: ENABLED ActionGroupExecutor: Lambda: !GetAtt LambdaBedrockAgentAgClaude.Arn FunctionSchema: Functions: - Name: LambdaBedrockAgentAgClaude Description: "Lambda Function to invoke Bedrock Claude foundation model triggered from Bedrock Agent" Parameters: url: Description: "Invoke the Claude foundation model to answer for a general query except for the related to SCSK." Required: false Type: string Tags: Cost: !Sub sample-${SubName} DependsOn: - LambdaBedrockAgentAgClaude - BedrockAgentRole BedrockAgentAlias: Type: AWS::Bedrock::AgentAlias Properties: AgentAliasName: !Ref BedrockAgentAliasName AgentId: !Ref BedrockAgent Description: Default alias 2024-07-13 1 Tags: Cost: !Sub sample-${SubName} DependsOn: - BedrockAgent # ------------------------------------------------------------# # Bedrock Agent Role (IAM) # ------------------------------------------------------------# BedrockAgentRole: Type: AWS::IAM::Role Properties: RoleName: !Sub AmazonBedrockExecutionRoleForAgents_sample-${SubName} AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: "sts:AssumeRole" Principal: Service: bedrock.amazonaws.com Condition: StringEquals: "aws:SourceAccount": !Sub ${AWS::AccountId} ArnLike: "aws:SourceArn": !Sub "arn:aws:bedrock:${AWS::Region}:${AWS::AccountId}:agent/*" Policies: - PolicyName: !Sub AmazonBedrockExecutionPolicyForAgents_sample-${SubName} PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "bedrock:InvokeModel" Resource: - !Sub "arn:aws:bedrock:${AWS::Region}::foundation-model/anthropic.claude*" - Effect: Allow Action: - "bedrock:Retrieve" - "bedrock:RetrieveAndGenerate" Resource: - !Sub "arn:aws:bedrock:${AWS::Region}:${AWS::AccountId}:knowledge-base/${BedrockKnowledgeBase}" DependsOn: - BedrockKnowledgeBase # ------------------------------------------------------------# # Lambda Execution Role (IAM) # ------------------------------------------------------------# LambdaBedrockInvocationRole: Type: AWS::IAM::Role Properties: RoleName: !Sub sample-LambdaBedrockInvocationRole-${SubName} Description: This role allows Lambda functions to invoke Bedrock. AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess Policies: - PolicyName: !Sub sample-LambdaBedrockInvocationPolicy-${SubName} PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "bedrock:InvokeModel" - "bedrock:InvokeModelWithResponseStream" Resource: - !Sub "arn:aws:bedrock:${AWS::Region}::foundation-model/anthropic.claude*" LambdaBedrockAgentInvocationRole: Type: AWS::IAM::Role Properties: RoleName: !Sub sample-LambdaBedrockAgentInvocationRole-${SubName} Description: This role allows Lambda functions to invoke Bedrock Agent. AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess Policies: - PolicyName: !Sub sample-LambdaBedrockAgentInvocationPolicy-${SubName} PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "bedrock:InvokeAgent" Resource: - !Sub "arn:aws:bedrock:${AWS::Region}:${AWS::AccountId}:agent-alias/${BedrockAgent}/*" DependsOn: - BedrockAgent LambdaBedrockAgentAgClaudeInvocationRole: Type: AWS::IAM::Role Properties: RoleName: !Sub sample-LambdaBedrockAgentAgClaudeInvocationRole-${SubName} Description: This role allows Lambda functions to invoke Bedrock Claude FM. AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess Policies: - PolicyName: !Sub sample-LambdaBedrockAgentAgClaudeInvocationPolicy-${SubName} PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "bedrock:InvokeModel" - "bedrock:InvokeModelWithResponseStream" Resource: - !Sub "arn:aws:bedrock:${AWS::Region}::foundation-model/anthropic.claude*" # ------------------------------------------------------------# # Lambda # ------------------------------------------------------------# LambdaBedrock: Type: AWS::Lambda::Function Properties: FunctionName: !Sub sample-Bedrock-${SubName} Description: !Sub Lambda Function to invoke Bedrock for sample-${SubName} Architectures: - x86_64 Runtime: nodejs20.x Timeout: 180 MemorySize: 128 Role: !GetAtt LambdaBedrockInvocationRole.Arn Handler: index.handler Tags: - Key: Cost Value: !Sub sample-${SubName} Code: ZipFile: !Sub | const { BedrockRuntimeClient, InvokeModelWithResponseStreamCommand } = require("@aws-sdk/client-bedrock-runtime"); const bedrock = new BedrockRuntimeClient({region: "${BedrockRegion}"}); exports.handler = awslambda.streamifyResponse(async (event, responseStream, _context) => { try { const args = JSON.parse(event.body); if (args.prompt == '') { responseStream.write("No prompt provided."); responseStream.end(); } const body = { "max_tokens": 3000, "temperature": 0.5, "top_k": 250, "top_p": 1, "anthropic_version": "bedrock-2023-05-31", "system": "質問文に対して適切な回答をしてください。", "messages": [ { "role": "user", "content": [ { "type": "text", "text": args.prompt } ] } ] }; const input = { modelId: '${ClaudeModelId}', accept: 'application/json', contentType: 'application/json', body: JSON.stringify(body) }; const command = new InvokeModelWithResponseStreamCommand(input); const apiResponse = await bedrock.send(command); let completeMessage = ""; for await (const item of apiResponse.body) { const chunk = JSON.parse(new TextDecoder().decode(item.chunk.bytes)); const chunk_type = chunk.type; if (chunk_type === "content_block_delta") { const text = chunk.delta.text; completeMessage = completeMessage + text; responseStream.write(text); } } responseStream.end(); } catch (error) { console.error(error); responseStream.write('error'); responseStream.end(); } }); DependsOn: - LambdaBedrockInvocationRole LambdaUrlBedrock: Type: AWS::Lambda::Url Properties: AuthType: AWS_IAM Cors: AllowCredentials: false AllowHeaders: - "*" AllowMethods: - POST AllowOrigins: - !Sub https://${SubDomainName}.${DomainName} ExposeHeaders: - "*" MaxAge: 0 InvokeMode: RESPONSE_STREAM TargetFunctionArn: !GetAtt LambdaBedrock.Arn DependsOn: - LambdaBedrock LambdaBedrockAgent: Type: AWS::Lambda::Function Properties: FunctionName: !Sub sample-BedrockAgent-${SubName} Description: !Sub Lambda Function to invoke Bedrock Agent for sample-${SubName} Architectures: - x86_64 Runtime: nodejs20.x Timeout: 600 MemorySize: 128 Role: !GetAtt LambdaBedrockAgentInvocationRole.Arn Handler: index.handler Tags: - Key: Cost Value: !Sub sample-${SubName} Code: ZipFile: !Sub | const { BedrockAgentRuntimeClient, InvokeAgentCommand } = require("@aws-sdk/client-bedrock-agent-runtime"); const bedrockagent = new BedrockAgentRuntimeClient({region: "${AWS::Region}"}); exports.handler = awslambda.streamifyResponse(async (event, responseStream, _context) => { try { // Query Bedrock Agent const args = JSON.parse(event.body); if (args.prompt == '') { responseStream.write("No prompt provided."); responseStream.end(); } const agentInput = { "agentId": "${BedrockAgent}", "agentAliasId": "${BedrockAgentAlias.AgentAliasId}", "sessionId": args.jobid, "enableTrace": false, "endSession": false, "inputText": args.prompt, "sessionState": { "promptSessionAttributes": { "serviceid": args.serviceid, "user": args.username, "datetime": args.datetime } } }; const command = new InvokeAgentCommand(agentInput); const res = await bedrockagent.send(command); const actualStream = res.completion.options.messageStream; const chunks = []; for await (const value of actualStream) { const jsonString = new TextDecoder().decode(value.body); const base64encoded = JSON.parse(jsonString).bytes; const decodedString = Buffer.from(base64encoded,'base64').toString(); try { chunks.push(decodedString); responseStream.write(decodedString); } catch (error) { console.error(error); responseStream.write(null); responseStream.end(); } } responseStream.end(); } catch (error) { console.error(error); responseStream.write('error'); responseStream.end(); } }); DependsOn: - LambdaBedrockAgentInvocationRole - BedrockAgentAlias LambdaUrlBedrockAgent: Type: AWS::Lambda::Url Properties: AuthType: AWS_IAM Cors: AllowCredentials: false AllowHeaders: - "*" AllowMethods: - POST AllowOrigins: - !Sub https://${SubDomainName}.${DomainName} ExposeHeaders: - "*" MaxAge: 0 InvokeMode: RESPONSE_STREAM TargetFunctionArn: !GetAtt LambdaBedrockAgent.Arn DependsOn: - LambdaBedrockAgent LambdaBedrockAgentAgClaude: Type: AWS::Lambda::Function Properties: FunctionName: !Sub sample-BedrockAgentAgClaude-${SubName} Description: !Sub Lambda Function to invoke Bedrock Claude model triggered from Bedrock Agent action group for sample-${SubName} Architectures: - x86_64 Runtime: python3.12 Timeout: 300 MemorySize: 128 Role: !GetAtt LambdaBedrockAgentAgClaudeInvocationRole.Arn Handler: index.lambda_handler Tags: - Key: Cost Value: !Sub sample-${SubName} Code: ZipFile: !Sub | import boto3 import json bedrock = boto3.client('bedrock-runtime', region_name='${BedrockRegion}') def lambda_handler(event, context): print(event) # Invoke Bedrock body = { "max_tokens": 3000, "temperature": 0.5, "top_k": 250, "top_p": 1, "anthropic_version": "bedrock-2023-05-31", "system": "質問文に対して適切な回答をしてください。", "messages": [ { "role": "user", "content": [ { "type": "text", "text": event['inputText'] } ] } ] } res = bedrock.invoke_model( body=json.dumps(body), contentType='application/json', accept='application/json', modelId='${ClaudeModelId}' ) resbody = json.loads(res['body'].read())['content'][0].get('text', '適切な回答が見つかりませんでした。') return { "messageVersion": "1.0", "response": { "actionGroup": event["actionGroup"], "function": event["function"], "functionResponse": { "responseBody": { "TEXT": { "body": resbody } } } }, "sessionAttributes": event["sessionAttributes"], "promptSessionAttributes": event["promptSessionAttributes"] } DependsOn: - LambdaBedrockAgentAgClaudeInvocationRole LambdaBedrockAgentAgClaudePermission: Type: AWS::Lambda::Permission Properties: FunctionName: !GetAtt LambdaBedrockAgentAgClaude.Arn Action: lambda:InvokeFunction Principal: bedrock.amazonaws.com SourceAccount: !Sub ${AWS::AccountId} SourceArn: !Sub "arn:aws:bedrock:${AWS::Region}:${AWS::AccountId}:agent/${BedrockAgent}" DependsOn: - BedrockAgent # ------------------------------------------------------------# # Output Parameters # ------------------------------------------------------------# Outputs: # Lambda LambdaBedrockArn: Value: !GetAtt LambdaBedrock.Arn Export: Name: !Sub sample-${SubName}-LambdaBedrockArn LambdaBedrockUrl: Value: !GetAtt LambdaUrlBedrock.FunctionUrl Export: Name: !Sub sample-${SubName}-LambdaBedrockUrl LambdaBedrockAgentArn: Value: !GetAtt LambdaBedrockAgent.Arn Export: Name: !Sub sample-${SubName}-LambdaBedrockAgentArn LambdaBedrockAgentUrl: Value: !GetAtt LambdaUrlBedrockAgent.FunctionUrl Export: Name: !Sub sample-${SubName}-LambdaBedrockAgentUrl Agents for Amazon Bedrock 変更時の作業 上述の AWS CloudFormation テンプレートを流しただけで一旦 Agents for Amazon Bedrock の一連の構成が出来上がりますが、何か構成を変更したときには、バージョン管理の機能があるためにエイリアスの情報も更新しておく必要があります。以下の Description の部分を、何か記述ルールを決めて同時に変えていきましょう。 BedrockAgentAlias: Type: AWS::Bedrock::AgentAlias Properties: AgentAliasName: !Ref BedrockAgentAliasName AgentId: !Ref BedrockAgent Description: Default alias 2024-07-13 1 本記事の範囲はこれで終了です。 まとめ いかがでしたでしょうか? あまり説明はなく AWS CloudFormation テンプレートを読んで下さい的な内容になっていますが、そもそもテンプレート化したい人でないとこの記事は読まないと思いますので、ある程度読める方がいらっしゃっているのかな、と思います。その他、AWS Lambda 関数のつくりもなにげに参考になるかと思っております。 本記事が皆様のお役に立てれば幸いです。
アバター
こんにちは。SCSKの江木です。 皆さん、チャットボットの質に満足していますか? 従来のルールベースのチャットボットでは、複雑な質問に対応できず、チャットボット利用者の要望を叶えることが難しかったかもしれません。 今回は複雑な質問に対応できるような、より自然で人間らしい会話を実現するため、Dialogflow CXと生成AIを連携する方法を紹介します。 Dialogflow CXとは Dialogflow CXとは、自然言語による対話をシステムに組み込む際に使えるプラットフォームです。高度なチャットボットや音声アシスタントを構築するためのツールであり、複雑な会話の流れや多様なユーザーの質問に柔軟に対応できることが特徴です。 Dialogflow CXの基本については以下のブログにまとめているので、ご参照ください。 Dialogflow CXの基本を整理してみました 今回は、Dialogflowの基礎知識を改めて整理して紹介していきます。この基礎知識があれば、Dialogflow CXでAgentを構築できるようになるので、最後までご覧ください。 blog.usize-tech.com 2024.09.09 Dialogflow CXで生成AIを使う方法 Dialogflow CXで生成AIを使う方法を4つ紹介します。 Generatorを使う Dialogflow CXの中にGeneratorという機能があります。Generatorは要約、パラメータ抽出、データ変換などのタスクで使われることが多いです。 今回は漢字をひらがなに変換する機能をGeneratorで実装したので、実装したAgentを紹介します。 上図は実装したAgentで、Generatorsページにて、ひらがな変換を実装しています。Generatorsページの設定は以下の通りです。 ひらがなにしたい漢字をSession Parameterで受け取るようにしています。 続いて、Generatorの設定を見ていきます。 GeneratorはSession Parameterを受け取る必要があるので、「$page.param.status = “FINAL”」ルートにて設定します。設定は以下の通りです。 Generatorからの変換結果を$request.generative.answerで受け取り、Agent saysでAgentが変換結果を発話するように設定しています。 また、Generatorの細かい設定は以下の通りです。 使用したいモデルを選択することもできますし、プロンプトを自由に書き換えることも可能です。 それでは実装したAgentの動作を確認してみます。 無事、漢字をひらがなに変換することが確認できました。 Webhookを使用する 続いて、Webhookを使って、APIを叩くことで生成AIを利用する方法を2つ紹介します。 ※本節ではフローの全体像、Webhookのソースコードおよび実装結果を紹介します。Webhookの実装については以下のブログで紹介しているので、実装の詳細を知りたい方はご覧ください。 Dialoglflow CXのWebhookを使ってTranslation APIを叩いてみた Dialogflow CXで構築しているチャットボットに翻訳機能を追加するために、WebhookでTranslation APIを叩く方法を紹介します。 blog.usize-tech.com 2024.02.26 WebhookでGemini APIを使用する WebhookでGemini APIを叩く方法を、実装したAgentをもとに紹介します。実装したAgentのフローは以下の通りです。 GeminiページにてGeminiへの質問のパラメータ「$session.params.question」を取得し、APIを叩きます。 WebhookのPythonソースコードは以下の通りです。 ※requirement.txtにモジュールをインポートし忘れないように注意してください。 import functions_framework import requests import vertexai from vertexai.generative_models import GenerationConfig, GenerativeModel, Part def interview(project_id: str,location: str,model: str,text: str) -> str:   # Initialize Vertex AI     vertexai.init(project=project_id, location=location)   # Load the model     model = GenerativeModel(model_name=model)   # Generation Config   config = GenerationConfig(       max_output_tokens=2048, temperature=0.4, top_p=1, top_k=32     )   # Generate text   response = model.generate_content(       text, generation_config=config     )     return response.text @functions_framework.http def webhook(request):   response = request.get_json()   text = response["sessionInfo"]["parameters"]["question"]   tag = response["fulfillmentInfo"]["tag"]   model = "gemini-1.5-flash"   output_text = interview("プロジェクト名","リージョン",model,text)   response["fulfillmentResponse"] = {           "messages": [               {                   "text": {                       "text": [                           output_text                       ],                       "allowPlaybackInterruption": False                   }               }           ]       }     return response webhookをAgentに設定し、テストした結果は以下の通りです。         Geminiが質問に回答してくれました!! WebhookでAgent Builder Searchを使用する WebhookでAgent Builder Search APIをたたく方法を実装したAgentをもとに紹介します。実装したAgentのフローは以下の通りです。 Gemini APIを叩くときと同様に、searchページにて質問のパラメータ「$session.params.question」を取得し、APIを叩きます。 Webhookを紹介する前に、Agent Builder Searchのアプリを作成します。 以下のドキュメントにしたがって、アプリとデータストアを作成します。(説明が長くなるので、詳細は割愛します。) 今回は transformerの論文(pdf) をデータソースとして使用しました。 Get started with generic search  |  Vertex AI Agent Builder  |  Google Cloud Create a search app for a website, structured data, and unstructured data, then preview the results. cloud.google.com Agent Builder Searchの準備ができたので、Webhookのソースコードを紹介します。Pythonソースコードは以下の通りです。 ※requirement.txtにモジュールをインポートし忘れないように注意してください。 import functions_framework import vertexai from google.cloud import discoveryengine from vertexai.preview.generative_models import GenerativeModel, ChatSession from typing import List from google.cloud import storage from google.oauth2 import service_account import json import requests #Search用のparametersを定義 project_id = "プロジェクト名" location = "global" search_engine_id = "データストアのID" #configIDはAgent Builderのコンソール→アプリ→統合で確認することができます。 serving_config_id = "configID" location_v = "ロケーション" model_name = "gemini-pro" vertexai.init(project=project_id, location=location_v) model = GenerativeModel(model_name) chat = model.start_chat() def extract_path_from_link(link: str):     return "/".join(link[5:].split("/")[1:]) def search(   project_id: str,   location: str,   search_engine_id: str,   serving_config_id: str,   search_query: str     ) -> List[discoveryengine.SearchResponse.SearchResult]:     client = discoveryengine.SearchServiceClient()   serving_config = client.serving_config_path(       project=project_id,       location=location,       data_store=search_engine_id,       serving_config=serving_config_id,     )   request = discoveryengine.SearchRequest(       serving_config=serving_config,       query=search_query,       page_size=2,       content_search_spec=discoveryengine.SearchRequest.ContentSearchSpec(           extractive_content_spec=discoveryengine.SearchRequest.ContentSearchSpec.ExtractiveContentSpec(               max_extractive_segment_count=1,               max_extractive_answer_count=1,           ),           snippet_spec=discoveryengine.SearchRequest.ContentSearchSpec.SnippetSpec(               return_snippet=True,           ),           summary_spec=discoveryengine.SearchRequest.ContentSearchSpec.SummarySpec(               summary_result_count=5,               include_citations=True,           ),       ),     )     response = client.search(request)   search_result = {}   search_result = {       "answer": response.summary.summary_text,       "retrieved_texts": [           {               "document_path": extract_path_from_link(result.document.derived_struct_data["link"]),               "link": result.document.derived_struct_data["link"],               "snippets": result.document.derived_struct_data["snippets"][0]["snippet"],               "text": result.document.derived_struct_data["extractive_segments"][0]["content"],           }           for result in response.results       ],     }   search_result_text = search_result["answer"]     return search_result_text @functions_framework.http def search_document(request):   response = request.get_json()   sentence = response["sessionInfo"]["parameters"]["question"]     tag = response["fulfillmentInfo"]["tag"]     output_text= search(project_id, location, search_engine_id, serving_config_id, sentence)   response["fulfillmentResponse"] = {           "messages": [               {                   "text": {                       "text": [                           output_text                       ],                       "allowPlaybackInterruption": False                   }               }           ]         }     return response 上記のWebhookでは検索結果の要約のみをAgentに返すように設定しています。 WebhookをAgentに設定し、テストした結果は以下の通りです。 論文の内容であるAttentionについてしっかり回答してくれました!! Agent Builder Conversationを使用する 最後にAgent Builder Conversationを使用する方法を紹介します。 本サービスですが、2024年9月現在日本語版がプレビューであることに注意してください。 さて、Agent Builder Conversationにアクセスするわけですが、もちろんAgent Builderのコンソールからアクセスできます。しかし、今回はDialogflow CXのコンソールからアクセスする方法を紹介します。 まず、Dialogflow CXのコンソールにアクセスし、言語はja、ロケーションはglobalでAgentを作成します。作成したら、Start Pageの詳細を見ます。 [Add State handler]→[Data Stores]にチェック→[Apply]を押下します。 Data Storesの[+]を押下したのち、画面右の[Create Vertex AI Search and Conversation App]を押下します。 Agent Builderのコンソールが立ち上がるので、エージェントの構成を設定します。設定が終わったら[続行]を押下します。 データストアにインポートするデータを選択します。Agent Builder Searchの手法と同様に transformerの論文(pdf) をデータソースとしてインポートします。設定が終わったら[続行]を押下します。 データストアの設定を行い、[作成]を押下します。 作成したデータストアを選択し、[作成]を押下します。 作成が完了したら、画面左にある[プレビュー]を押下します。 Dialogflow CXのコンソールが立ち上がるので、Agent Builderのコンソールを開いたときと同様に[Add State handler]から以下のデータストア設定画面を開きます。Unstructured documentsから作成したデータストアを選択し、[Save]を押下します。 これで準備は完了です。Agentをテストしてみると、以下の結果となりました。 文章は短いですが、Attentionについて答えてくれました!! おわりに 今回はDialogflow CXで生成AIを使う方法をまとめてみました。 Dialogflow CXで生成AIを使う方法が多いと感じたのではないでしょうか? 2度目になりますが、2024年9月現在、Agent Builder Conversationは日本語がpreviewなので注意してください。 本記事が皆様のお役にたてば幸いです。 最後まで読んでいただきありがとうございました。
アバター
こんにちは、広野です。 AWS Cloud9 と AWS CodeCommit が新規 AWS アカウントで利用不可、という方針が AWS から打ち出されました。今後の代替ソリューションは色々なパターンがありますので調査もままならない、なかなか決めきれない状況の方が多いのではないかと想像します。 とは言え開発を進めなければならない状況はあり、私も取り急ぎタイトルに書いた対応を暫定的に実施しましたので、一度整理して残しておこうと思います。 置かれていた状況 以下のように、新規作成したアカウント A で AWS を活用してアプリ開発をしたかったが、AWS Cloud9 が利用不可になっていた、という状況です。AWS CodeCommit は利用可能でした。 実施したこと 既存のアカウント B では AWS Cloud9 が利用できたので、取り急ぎそちらを使うことにしました。 作業手順 1. アカウント A で AWS CodeCommit リポジトリを作成する これについては、AWS ドキュメント通りです。 Create an AWS CodeCommit repository - AWS CodeCommit Describes how to use the AWS Management Console or the AWS CLI to create a CodeCommit repository. docs.aws.amazon.com 2. アカウント A で AWS CodeCommit リポジトリにアカウント B からのアクセスを許可する こちらも AWS ドキュメント通りです。 Cross-account repository access: Actions for the administrator in AccountA - AWS CodeCommit To allow users or groups in AccountB to access a repository in AccountA, an AccountA administrator must: docs.aws.amazon.com アカウント A にアカウント B からのアクセスを許可する IAM ロールを作成します。コンソールで作成するのが面倒だったので、以下の AWS CloudFormation テンプレートでも作成できます。この IAM ロールの ARN をアカウント B に提供します。AWS CloudFormation テンプレートを使用した場合、対象の AWS CodeCommit リポジトリ名とアクセスを許可する AWS アカウント ID (ここではアカウント B の) をパラメータとして入力します。結果として、出力タブに IAM ロールの ARN が表示されます。 AWSTemplateFormatVersion: 2010-09-09 Description: The CloudFormation template that creates an IAM Role to allow the cross account access to the CodeCommit. # ------------------------------------------------------------# # Input Parameters # ------------------------------------------------------------# Parameters: SystemName: Type: String Description: System name. (e.g. example) Default: example MaxLength: 10 MinLength: 1 SubName: Type: String Description: System sub name. (e.g. dev) Default: dev MaxLength: 10 MinLength: 1 CodeCommitRepositoryName: Type: String Description: The target CodeCommit repository name. Default: MySharedDemoRepo MaxLength: 50 MinLength: 1 TargetAwsAccountId: Type: String Description: The target AWS account ID. Default: 999999999999 MaxLength: 12 MinLength: 12 Resources: # ------------------------------------------------------------# # CodeCommit Access Role (IAM) # ------------------------------------------------------------# CodeCommitAccessRole: Type: AWS::IAM::Role Properties: RoleName: !Sub ${SystemName}-${SubName}-CodeCommitAccessRole Description: This role allows the target AWS account to access the CodeCommit repository. AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: AWS: !Ref TargetAwsAccountId Action: - sts:AssumeRole Path: / Policies: - PolicyName: !Sub ${SystemName}-${SubName}-CodeCommitAccessPolicy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "codecommit:BatchGet*" - "codecommit:Create*" - "codecommit:DeleteBranch" - "codecommit:Get*" - "codecommit:List*" - "codecommit:Describe*" - "codecommit:Put*" - "codecommit:Post*" - "codecommit:Merge*" - "codecommit:Test*" - "codecommit:Update*" - "codecommit:GitPull" - "codecommit:GitPush" Resource: - !Sub "arn:aws:codecommit:${AWS::Region}:${AWS::AccountId}:${CodeCommitRepositoryName}" - Effect: Allow Action: "codecommit:ListRepositories" Resource: "*" # ------------------------------------------------------------# # Output Parameters # ------------------------------------------------------------# Outputs: # IAM CodeCommitAccessRoleArn: Value: !GetAtt CodeCommitAccessRole.Arn 3. アカウント B で AWS Cloud9 用カスタム IAM ロールを作成する こちらも AWS ドキュメント通りです。 Cross-account repository access: Actions for the administrator in AccountB - AWS CodeCommit To allow users or groups in AccountB to access a repository in AccountA, the AccountB administrator must create a group ... docs.aws.amazon.com 2. で作成したアカウント A の IAM ロール ARN が必要になります。それを使用して、AWS Cloud9 に関連付けるカスタム IAM ロールをアカウント B で作成します。この IAM ロール名をこの後の手順で使用します。以下の AWS CloudFormation テンプレートを使用した場合、IAM ロール名はパラメータに入力した文字列を使用して SystemName-SubName-Cloud9CodeCommitRole という名前で出来上がります。 AWSTemplateFormatVersion: "2010-09-09" Description: The CloudFormation template that creates an EC2 instantance profile and an IAM role to allow Cloud9 instances to access the CodeCommit repository across the account. # ------------------------------------------------------------# # Input Parameters # ------------------------------------------------------------# Parameters: SystemName: Type: String Description: System name. (e.g. example) Default: example MaxLength: 10 MinLength: 1 SubName: Type: String Description: System sub name. (e.g. dev) Default: dev MaxLength: 10 MinLength: 1 TargetAccountIamRole: Type: String Description: The IAM role ARN provided from the target AWS account. Default: arn:aws:iam::xxxxxxxxxxxx:role/xxxxxxxxxxxxxxxxxxx MaxLength: 100 MinLength: 1 Resources: # ------------------------------------------------------------# # EC2 Role / Instance Profile (IAM) # ------------------------------------------------------------# Ec2Role: Type: AWS::IAM::Role Properties: RoleName: !Sub ${SystemName}-${SubName}-Cloud9CodeCommitRole Description: This role allows Cloud9 instances to access the target CodeCommit repository across the account. AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/AWSCloud9SSMInstanceProfile Policies: - PolicyName: !Sub ${SystemName}-${SubName}-Cloud9CodeCommitPolicy PolicyDocument: Version: "2012-10-17" Statement: - Action: - "sts:AssumeRole" Resource: !Ref TargetAccountIamRole Effect: Allow - PolicyName: !Sub ${SystemName}-${SubName}-Cloud9QDeveloperPolicy PolicyDocument: Version: "2012-10-17" Statement: - Action: - "codewhisperer:GenerateRecommendations" Resource: "*" Effect: Allow Ec2InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: InstanceProfileName: !Ref Ec2Role Path: / Roles: - !Ref Ec2Role DependsOn: - Ec2Role このテンプレートには、おまけで Amazon Q Developer からのコード提案を受けられる権限も付けています。 Using CodeWhisperer with AWS Cloud9 - CodeWhisperer For CodeWhisperer to provide recommendations in AWS Cloud9 console, you must enable the correct IAM permissions for eith... docs.aws.amazon.com 4. アカウント B で AWS Cloud9 環境を作成する こちらも AWS ドキュメント通りです。 Step 1: Create an environment - AWS Cloud9 Learn how to create an environment docs.aws.amazon.com VPC とサブネットは、お使いの環境を適切に選択してください。ネットワーク設定で AWS Cloud9 環境へのアクセス方法を選択しますが、SSM を選択してください。その方が推奨ですし、上記で紹介したカスタム IAM ロールは SSM でアクセスする前提で作成しています。 5. アカウント B で AWS Cloud9 をセットアップする ここからは、いくつかのマニュアル手順を実施します。公式手順としては以下が参考になるのですが、若干カスタムしたものを後述しますのでご注意ください。 Cross-account repository access: Actions for the repository user in AccountB - AWS CodeCommit To access the repository in AccountA, users in the AccountB group must configure their local computers for repository ac... docs.aws.amazon.com AWS Cloud9 環境は Amazon EC2 インスタンスとして起動します。インスタンスに自動的に関連付けられている IAM ロールを 3. で作成したカスタム IAM ロールに変更します。 Cloud9 環境の画面から EC2 インスタンスの管理 を押し、EC2 インスタンス情報の画面に移ります。 IAM ロールを、3. で作成した IAM ロールに変更します。一度デフォルトの IAM ロールをデタッチしてからアタッチしないとエラーになることがあります。 AWS Cloud9 環境を起動します。画面左上の Cloud9 アイコンから Preference メニューを選択します。AWS Settings から Credentials メニューに進み、AWS managed temporary credentials の設定を OFF (赤) にします。 ターミナルから、Cloud9 環境内にコンフィグファイルを作成します。 ディレクトリを ~/.aws に移動し、config という名前のファイルを作成します。 cd ~/.aws vi config config ファイルの中身は以下のように記述します。 profile の CrossAccountCodeCommit の部分は任意の名前で良いですが、6. で登場するコマンドと合わせる必要があります。 role_arn は 2. で作成したアカウント A 側の IAM ロールの ARN です。 region も指定します。 [profile CrossAccountCodeCommit] role_arn = arn:aws:iam::xxxxxxxxxxxx:role/xxx-xxx-CodeCommitAccessRole credential_source = Ec2InstanceMetadata region = ap-northeast-1 以上で AWS Cloud9 環境のセットアップは完了です。 6. アカウント B の AWS Cloud9 からアカウント A の AWS CodeCommit に接続する environment ディレクトリに戻り、AWS Cloud9 のターミナルで git の初期設定をします。これは通常の git コマンドです。 git config --global user.name "名前" git config --global user.email メールアドレス この後 git clone をしますが、同一アカウントの AWS Code Commit に接続するときとコマンドが異なります。 先ほど作成した config ファイルに記入した内容に合わせます。@マーク以下は AWS CodeCommit のリポジトリ名を記入します。 git clone codecommit::ap-northeast-1://CrossAccountCodeCommit@CodeCommitのリポジトリ名 ここまで完了すれば、以降は通常の git コマンドを使用します。git add, git commit, git push, git pull など。 まとめ いかがでしたでしょうか。 AWS Cloud9 が新規アカウントで利用不可となったので今後長きに亘り重宝される情報ではないですが、一時的には役立つと思います。 Cloud9 って、AWS 上でアプリを公開していて、AWS CodeCommit を使用し、かつクラウド上に開発環境を置きたい人にとっては本当に便利だったんですけどね。今後の利用不可が残念でならないです。 本記事が皆様のお役に立てれば幸いです。
アバター
SCSKの江浜です。(初投稿です!) Oracle CloudWorld 2024 が 現地時間9月9日(火)から12日(木) の4日間にわたりラスベガスにて開催されております。 本記事では4日間に及ぶOracle CloudWorld 2024 現地からの情報をお届けします。 はじめに、、、「Oracle Database@AWS」が発表されました! Oracle社とAWS社が2024年9月9日(米国時間)「 Oracle Database@AWS 」を発表しました! AWS社のデータセンターを利用してOracle社が「Oracle Exadata Database Service」や「Oracle Autonomous Database」を提供する形になります。 今回私が参加している「Oracle CloudWorld 2024」でも2024年9月10日(米国時間)、Oracle社会長兼CTOであるLarry Ellison氏によるKeynoteで改めて紹介があったので後述します。 Oracle and Amazon Web Services Announce Strategic Partnership Customers can now access Oracle Autonomous Database and Oracle Exadata Database Service in AWS, simplifying the migratio... www.oracle.com   9/9(月) 受付・パートナーサミットへの参加 会場はアメリカ、ラスベガスの「The VenetIan Resort Las Vegas」です。 (行ったのは朝ですが夜はこんな感じです。)     初日は受付のために会場へ行ってきました。 会場の外は日中の気温が38度ほどですが日本と違って湿度が低く、数値ほどの暑さは感じません。 (ただとても乾燥しておりリップは必須でした。。。あと目薬。。。) ホテル併設のカジノを抜けて会場に入ると中は空調が効いており、快適でした。(部屋によってはむしろちょっと肌寒かったりしました) 会場入口はこんな感じです。初日は受付とパートナー向けのサミットに参加してきました。 会場に向かう様子   9/10(火) Keynote  概要 9/10(火)よりセッションが本格的に始まりました!人も多くなり盛り上がっています! 今日はその中で2つ参加レポート書きます! 【Keynote】Customers Winning with the Cloud and AI Oracle社CEOのSafra Catz 氏によるクラウドとAIで大きな課題をどのように解決しているかの紹介でした。 各業界のパートナーをゲストとして呼び、対話形式で紹介するような内容でした。 登壇するSafra Catz 氏 個人的にはCIAのCIOであるLa’Naia Jones氏との対話、特にセキュリティの話が印象的でした。 サイバーセキュリティのここ10年の変化に対して、迅速な意思決定をすることやベストでより安全な決定が必要であること、翻訳や要約に関しては生成系AIを取り入れていくことについて話されていました。 【Keynote】Oracle Vision and Strategy Oracle社の会長兼CTOであるLarry Ellison氏がOracleの差別化されたAIイノベーションについて語りました。 登壇する Larry Ellison氏 登壇すると会場では大きな歓声が上がりました! 内容は大きく2点についてでした。 マルチクラウド時代について AIを活用したセキュリティについて   マルチクラウド時代について 2024年6月にAWS社ののCEOに就任したMatt Garman氏がゲストで登場しました。 対談の内容はやはり先日9日に発表のあったAWS社との戦略的パートナーシップについての内容が多かったです。 多くの顧客がAWSを利用していることや、Oracle データベースを AWS に接続する際の課題(レイテンシ等)についても触れ、改めてOracle のサービスと AWS の統合、パフォーマンスの向上について強調していました。 AIを活用したセキュリティについて 大きく4つのセキュリティに分けて話がありました。 ①データセキュリティ ②アプリケーションセキュリティ ③ユーザID ④ネットワークセキュリティ 自律型のセキュリティ運用や、ネットワークセキュリティの 複雑化問題に対して ネットワークコンフィギュレーションとネットワークセキュリティを分離することが重要と強調されていたことが、個人的に印象に残りました。 ちなみにネットワークコンフィギュレーションとネットワークセキュリティの分離に関して、 本日話されたZRP(OCI Zero Trust Packet Routing)のプレスリリースでてました! オラクル、ネットワーク・セキュリティとネットワーク・アーキテクチャを分離してクラウド・セキュリティ体制を強化 OCI Zero Trust Packet Routing、ネットワーク構成とネットワーク・セキュリティを切り離し、人的ミスに起因するデータ漏洩を防止 www.oracle.com   最後に 今日書ききれなかったセッションの内容も含めて、「Oracle CloudWorld 2024 参加レポート②」を頑張って書こうと思います!
アバター