TECH PLAY

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

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

1236

こんにちは。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 参加レポート②」を頑張って書こうと思います!
こんにちは。SCSKの島村です。 Vertex AI(Gemini API)にて利用できる『関数呼び出し機能(Function Calling API )』についてご存知でしょうか?? 関数呼び出しを利用することで、LLMから 関連性の高いコンテキストに沿った回答 を提供することが可能となります。 本記事では、 『 Function Calling API 』について色々と調査し、実際に触ってみましたので、その魅力について少しだけご紹介させていただければと思います。 Function Calling APIとは?? 『Function Calling』とは、  LLMが質問の内容や文脈から必要な関数(外部の関数やAPI)を判断し呼び出すことで、回答の幅をさらに広げる機能 です。 従来のLLMは、与えられたプロンプトに対して、既に学習しているデータに基づき回答を生成することが主な役割でした。 しかし、Function Callingによって、LLMは単なるテキスト生成にとどまらず、以下のようなことができるようになります。 外部データの取得: 天気予報、株価、ニュース記事など、リアルタイムの情報を取得 計算: 複雑な計算やデータの分析を実行 外部サービスとの連携: 翻訳サービス、画像生成サービスなど、様々な外部サービスと連携してより高度なタスクを実行 Fanction Calling(関数呼び出し)を使用することで、生成 AI モデルに提供するための情報を外部もから取得可能となります。 Function Call(関数呼び出し)とモデル返答までのフロー:Google Cloudドキュメントより 詳細については、以下、Google Cloud公式ドキュメントからご確認ください。 関数呼び出し  |  Vertex AI の生成 AI  |  Google Cloud 利用ステップ Verte AI Geminiにて『Fanction Calling』を利用する手順は以下となります。 モデルを初期化する 。 ユーザー プロンプトを定義する 。 関数宣言を使用して、 使用可能な一連の関数を定義、記述する 。 ユーザーのプロンプトと関数宣言をモデルに送信する 。 モデルから出力された構造化データを使用して、 関数を呼び出す 。 関数の出力をモデルに提供する 。   Function Callingを実際に試してみた。 今回は「Function Calling API」を利用して、あらかじめ用意した簡単な関数を呼び出すことを試してみます。 実際の出力結果の一部を先にお見せします。 簡単な算数の問題をLLMに解かせてみました。 外部の関数を参考にして、LLMは回答を生成していることが分かります。 今回は簡単な算数の問題を例に試してみましたが、LLMに複雑な計算を実行してもらう場合、ハルシネーションの抑制にもつながる機能だと感じました。 Fanction Callingを実装してみる(コード例) 今回はコードについても少しだけ解説してみます。 1. 必要なモジュールのインポート import requests from vertexai.generative_models import (   Content,   FunctionDeclaration,   GenerationConfig,   GenerativeModel,   Part,   Tool, ) 2. プロジェクトの設定と言語モデル(Vertex AI)を使うための準備 import vertexai PROJECT_ID = ! gcloud config get-value project PROJECT_ID = PROJECT_ID[0] LOCATION = "us-central1" # @param {type:"string"} vertexai.init(project=PROJECT_ID, location=LOCATION) 3. LLMから呼び出す関数を定義(今回は簡単に「加算」「乗算」を実施する関数を作成します。) def add_fun(x,y):   print("---加算関数を呼び出しました.---")   return int(x)+int(y)  def multiply_func(x,y):   print("---乗算関数を呼び出しました.---")   return int(x)*int(y) 4. LLMから呼び出すための関数宣言 ・入力から判断するための「説明」と「取得する変数」を定義します。 詳細はリンクをご確認ください。: 関数宣言の例 add_function = FunctionDeclaration(   name="add",   description="質問から計算方法を判別し、加算を算出します。",   parameters={       "type": "object",       "properties": {           "x": {"type": "string", "description": "x."},           "y": {"type": "string", "description": "y."},       },   }, ) multiply_function = FunctionDeclaration(   name="multiply",   description="質問から計算方法を判別し、乗算を算出します。",   parameters={       "type": "object",       "properties": {           "x": {"type": "string", "description": "x."},           "y": {"type": "string", "description": "y."},       },   }, ) 5. Geminiモデル側の設定 tool = Tool(   function_declarations=[       add_function,       multiply_function,   ], ) model = GenerativeModel(   model_name="gemini-1.5-pro-001",   generation_config=GenerationConfig(temperature=0),   system_instruction=[       """       計算に関する質問の場合、自分で計算を行わないでください。       その他の質問の場合、ユーザーの質問に正しく答えてください。       """,   ],   tools=[tool], ) 6. おまけ)定義した2つの関数を直列に利用したい場合を想定して、レスポンスを再帰的に呼び出すための設定 def handle_response(response):   if response.candidates[0].function_calls:       function_call = response.candidates[0].function_calls[0]   else:       print(response.text)       return   if function_call.name == "add":       x_args = function_call.args.get('x')       y_args = function_call.args.get('y')       z_add = add_fun(x_args,y_args)  # Assuming a single string argument       response = chat.send_message(           Part.from_function_response(               name=function_call.name,               response={                   "content": z_add,               },           ),       )       return handle_response(response)   elif function_call.name == "multiply":       x_args = function_call.args.get('x')       y_args = function_call.args.get('y')       # Call your function       z_add = multiply_func(x_args,y_args)       response = chat.send_message(           Part.from_function_response(               name=function_call.name,               response={                   "content": z_add,               },           ),       )       return handle_response(response)   else:         print(function_call) 7. チャットモデルの開始 chat = model.start_chat() 以上で作成は完了です。 作成したモデルを利用して、実際にいくつか試してみます。↓↓↓ 質問の内容を理解し、計算(「乗算」「加算」)が必要な場合には適切に外部関数を呼び出していることが確認できます。 また、Fanction Callされた際のレスポンスを覗いてみると、、、、 利用した関数名( function_call { name: “multiply” } ・・・)が記載されていることが分かります。   最後に 今回は『 Function Calling API 』について実際のデモともにご紹介させていただきました。 簡単な計算問題を外部関数として定義し、LLMから呼び出して回答を補足する。  そんなデモを実感頂けたと思います。 外部データに対してAPIを経由してアクセスすることもでき、LLMの回答も大きく広がるそんな機能ではないでしょうか。 色んな関数を定義し、LLMのからの回答の幅を広げていくことができる『 Function Calling API 』のご紹介でした。 今後とも、AIMLに関する情報やGoogle CloudのAIMLサービスのアップデート情報を掲載していきたいと思います。 最後まで読んでいただき、ありがとうございました!!!
こんにちは。SCSKの吉田です。 今回は、ServiceNowⓇのNow Assist in Virtual Agentに関する記事となります。  生成AIが搭載されたチャットボット機能を活用して、どのように身の回りの業務を効率化できるか検証してみました。 本記事は執筆時点(2024年9月)の情報です。最新の情報は製品ドキュメントを参考にしてください。   Now Assist in Virtual Agentとは Now Assist in Virtual Agentは、ServiceNowのVirtual Agent(チャットボット)に生成AI機能が追加されたものになります。 これにより、ユーザーは会話形式でのVirtual Agent利用が可能となり、ナレッジの検索やサービスカタログのリクエストなどをより簡単に行えるようになりました。 時間を問わず利用可能なセルフサービスを提供することで、ユーザーの自己解決率を向上し、ヘルプデスクへの問い合わせ削減が期待できます。 ちなみに、ユーザーが自己解決し、チケットの作成を回避できた割合を「deflection rate」と呼び、Virtual Agentの導入効果を測定する上で重要な指標となります。 deflection rateの測定方法についても、勉強した内容を別記事でアウトプット予定です。 また、開発者目線でもメリットがあり、これまではVirtual Agentが返答する内容を事前に定義する必要がありましたが、生成AIが回答を生成してくれるので、構築に要する時間も短縮できそうです。 Now Assist in Virtual Agentを使ってみる まずは、前回の記事で作成したユーザーのアカウント登録申請をVirtual Agentから実施してみます。 ServiceNowⓇのNow Assistを活用してカタログアイテム(申請フォーム)とフローを効率的に作成する ServiceNowのNow Assistの機能を活用して、申請書とフローを作成してみました。非常に効率的に作成することができたので、そのプロセスをご紹介します。 blog.usize-tech.com 2024.08.27 Virtual Agentに「ユーザーアカウントを登録したい」とチャットすると、インスタンス内の存在するサービスカタログやナレッジを検索して、いくつかの候補を提示してくれます。 前回作成した「User Registration Request」がヒットしました。 申請を開始すると、「User Registration Request」フォーム内の各質問項目をVirtual Agentが会話形式で質問してくるので、チャット上で回答していきます。 入力内容を間違えた場合も、どの項目を修正したいか伝えることで、Virtual Agentが変更を反映してくれます。 最後に申請予定の内容を表示してくれるので、中身に問題なければSubmitして申請は完了です。 Virtual Agentと会話した通りに申請が作成されたことが確認できました。   身の回りの困り事をVirtuakl Agentで解決してみる シナリオ 【イベント】 新しい社員が自部署に配属される 【困りごと】 PCの調達など色々と準備が必用なのは認識しているけど、 何をすればよいか分からない、何処から申請すればよいか分からない。。 → Virtual Agentに必要なタスクを教えてもらおう、ついでに申請もまとめてVirtual Agentにやってもらおう 実践 今回「User Onboarding」という会話のフローを簡易的に作成してみました。 「User Onboarding」と入力すると、Virtual Agentが社員配属時に必要な申請の要否を順番に質問してくれるので、回答していきます。 回答した内容が一覧で表示されます。 今回はPC、業務携帯電話、名刺、個人ロッカーを用意したいと回答しました。 続いて、前の会話で必用と回答したものに対し、具体的な要望を質問されるので回答していきます。 (例)PCを調達するためにOS、CPU、ストレージを聞かれています。 (例)業務用携帯電話を調達するために、OS、ストレージ、本体のカラーを聞かれています。 申請毎に内容のサマリが表示されるので、問題なければSubmitを選択すれば申請が完了します。 その後、名刺、個人ロッカーについても同様に質問されるので、回答していけば申請は全て完了です。 結果を確認してみると、新しく部署に配属される社員向けに4つの申請をまとめて行うことができました。   開発内容 前セクションのVirtual Agentの会話内容のほとんどは生成AIによって生成されたものであり、非常に簡単に実装できました。 例えば前半でユーザーに対して各種申請の要否を確認している部分は、以下画像のDetailed descriptionにユーザーへ質問したいことを簡単に記載しているのみとなります。 記載した説明をもとに生成AIが会話文を考えてくれました。(もちろん、自分自身で会話文を事前に定義することも可能です)   後半の申請を行う部分に関しては、標準機能の「Request catalog item(LLM)」というトピックブロックと事前に作成したカタログアイテムを紐づけるのみとなります。 ユーザーへ質問したり、最終的に申請をあげる部分は開発不要になります。   まとめ Now Assist in Virtual Agentを触ってみて「何をすればよいのか分からない」という人に対して非常に便利なサービスを提供できると感じました。 今回の記事のように、業務上発生する様々なイベント(海外出張、育児休暇など)ごとに、Virtual Agentの会話フローを作成すれば、従業員体験の向上、ヘルプデスクへの問い合わせ削減など様々な良い効果がありそうです。 さらに生成AIの導入により、自然言語で検索をかけることも可能なので、実施したいことが不明瞭な人でも目的のナレッジやカタログアイテムにたどり着きやすくなったのではないかと思います。 ServiceNow ServiceNowは、企業の生産性向上や業務プロセス改善を支えるサービスマネジメントクラウドソリューションです。従業員満足度・顧客満足度の向上、業務効率化を強力に支援します。 www.scsk.jp
こんにちは。SCSKの江木です。 これまでDialogflow CXでAgentを構築していて、困ったことが多々ありました。 今回はこれまでの経験をもとに、スムーズな開発と高品質なチャットボットを実現するためのTipsをいくつかまとめました。 本記事がAgentを作成するためのヒントになれば幸いです。 Dialogflow CXとは Dialogflow CXとは、自然言語による対話をシステムに組み込む際に使えるプラットフォームです。高度なチャットボットや音声アシスタントを構築するためのツールであり、複雑な会話の流れや多様なユーザーの質問に柔軟に対応できることが特徴です。 Dialogflow CXの基本については以下のブログにまとめているので、ご参照ください。 Dialogflow CXの基本を整理してみました 今回は、Dialogflowの基礎知識を改めて整理して紹介していきます。この基礎知識があれば、Dialogflow CXでAgentを構築できるようになるので、最後までご覧ください。 blog.usize-tech.com 2024.09.09 Agentを作成するときのTips Route Groupを使いこなせ! Route Groupは、Routeを使いまわしたいときに使います。同じintentで遷移先が同じRouteが異なるPageで存在したとき、それぞれのページでRouteを作るよりも、Route Groupを使うことで開発を時間短縮することができます!! Route Groupは以下の手順で新たに作成することができます。設定の仕方はRouteと同様にintentとTransitionを設定すると、動作します。 Pageの詳細 [Add state handler]をクリック [Route groups]にチェックして、[Apply]をクリック [Route groups]右の[+]をクリック [Route group]の[Create new route group]を選択 Parameterを使いこなせ! Parameterを使うことで、Agentの実装の幅が大きく広がります。本節ではParameterについて説明した後、実装例について紹介していきます。 Parameterについて Dialogflow CXにおけるParameterは、セッション中にエンドユーザーが入力した値を取得または参照するときに使用します。Parameterには以下の3種類が存在します。 Intent parameter Form parameter Session parameter それぞれのParameterについて説明します。 Intent parameter Intentが一致した時にエンドユーザーが入力した値を抽出し、Intent parameterに設定されます。 以下のFlowを使用して、Intent parameterの取得方法を紹介します。 Page1の設定は以下の通りです。 curryというRouteに、curryというintentを設定しています。 以下のように、curryというintentにTraining phraseを入力し、curryという名前のIntent parameterを設定します。 続いて、Page2のFulfilmentにて、Intent parameterを取得します。   テストしてみると、以下のようにIntent parameterを取得できていることがわかります。 Form parameter Form parameterは 参照で使用されず 、パラメータの入力ステータスの確認で使われます。つまり、「$page.params.パラメータ名」といった記述はできません。 「$page.params.status = “FINAL”」のように現在のページですべてのパラメータが入力されているのか確認するために使用します。 以下のように、Conditionで設定することが多いです。 Session parameter 実行時に任意のパラメータが設定されると、Session parameterに設定されます。 Session parameterはPageのParameterで設定することが多いですが、Route、eventhandler、PageのFulfillmentのParameter presetsでも設定することができます。 以下のFlowを用いて、Session parameterの取得方法を紹介します。 Page1の設定は以下の通りです。 Parameterにdrinkというパラメータが設定されています。このパラメータに値が入ったときにSession parameterに値が入ります。 続いて、Page2のFulfilmentにて、Session parameterを取得します。 テストしてみると、以下のようにSession parameterを取得できていることがわかります。 Parameterを使った実装例 以下のフローチャートのようなコンサートのチケット申し込みを行うチャットボットを作る例を考えます。 また、以下の2つの機能が含まれるようにチャットボットを作成します。 チケットの確認を行う際に、申し込むチケットによってチャットボットの応答が変わる チケット申し込みと確認におけるループの上限回数が3回である 以降、上から機能1、機能2と記載します。 このフローチャートに従って作成したFlowは以下の通りになります。 このFlowにおけるPageの役割は以下の通りです。 Select Ticket 申し込むチケットをユーザーに選択させる 「男性アイドルグループMと女性アイドルグループWのどちらのチケットが欲しいですか?「M」か「W」で教えてください。」とユーザーに質問する Ticket Confirm 申し込むチケットの確認を行う 作成したFlowとPageについての説明が終了したところで、次は機能1と機能2をどのように実装したのかを説明します。 機能1 Intent parameterを使って、実装していきます。 以下のようにIntentを設定します。 「M」、「W」と入力されたときにきちんとIntent parameterに値が入るように設定しました。 先ほど設定したIntentであるticket.mとticket.wをSelect TicketページのRouteであるticket.mとticket.wに設定します。 次にこのIntent parameterを参照します。Ticket ConfirmページのパラメータであるresponseのAgent responsesという項目で下記のようにIntent parameterによって、チャットボットの返答が変わるように設定します。 ※パラメータであるresponseはエンドユーザーの返答である「はい」か「いいえ」を格納するために設定しています。「はい」ならばEnd Sessionページへ、「いいえ」ならSelect Ticketページに遷移するように設定しています。 機能1の実装は以上になります。 機能2 Session parameterを使って、実装していきます。 ループカウントするためのパラメータを用意するため、Start PageのルートであるtrueのParameter presetsにordercountというSession parameterを定義します。 ※trueは必ず遷移するルートで、遷移先はSelect Ticketに設定しています。 続いて、チケットの確認を行うたびにordercountがインクリメントされるように設定します。Select TicketページのFulfillmentのParameter presetsで以下のように設定します。 また、Select Ticketページのルートに、ordercountが4になったとき(つまり、3回申し込み確認を終えたとき)にEnd Sessionに遷移するようなルートを設定します。 ※ここでAgent responsesで「男性アイドルグループMと女性アイドルグループWのどちらのチケットが欲しいですか?「M」か「W」で教えてください。」と返答する条件として「ordercount < 3」と設定しているのは4回質問しないようにするためです。 機能2の実装は以上になります。 他の細かい設定は説明がかなり長くなってしまうので、今回は割愛させていただきます。 Start Pageのintentに注意しろ! Start Pageに設定したRouteのIntentはすべてのPageに伝播されます。 ある特定のPageからの遷移を設定したいときは、Start PageにIntentを設定しないように気を付けてください。 冒頭で紹介したブログにて作成した、以下のAgentで実際に挙動を確かめてみます。 AgentのPageに設定した項目の一部を以下に示します。 Page Fulfillment Route intent Training phrase Transition Start Page – store.location store.location 任意のお店の場所を聞く フレーズ Store Location store.hour store.hour 任意の営業時間を聞く フレーズ Store Hours Store Location Agent says: 東京都************です。その他ご用件はございますでしょうか。 Route Group: Closing – – – Store Hours Agent says: 月曜日から土曜日まで9:00 -19:00 で営業しています。日曜祝日は定休日です。その他ご用件はございますでしょうか。 Route Group: Closing – –   次にRoute Groupの設定を示します。 Route Group intent Training phrase Transition Closing closing いいえ、ありません等の否定のフレーズ End Session   それではAgentに会話してみます。お店の場所を聞いた後に、試しに営業時間を時間を尋ねたところ、以下のようにAgentが返答を返してきました。 Store LocationからStore Hoursへ遷移するようなRouteを設定していないのに、遷移してしまいました。Start Pageに設定したintentが効いているのが確認できますね!! おわりに いかがだったでしょうか。 今回はDialogflow CXでAgentを作成するときのTipsを紹介しました。 私が開発していて躓いたポイントを盛り込んでいるので、参考にしていただければと思います。 本記事が皆様のお役にたてば幸いです。 最後まで読んでいただきありがとうございました。
こんにちは。SCSKのふくちーぬです。 AWS Systems Managerのフリートマネージャーを利用して、Windowsサーバにブラウザベースでのリモート接続している方多いかと思います。今回は閉域網環境において、ローカル-サーバ間においてファイル共有するためにAWS Tools for Windows PowerShellを用いる方法をご紹介します。 AWS Tools for Windows PowerShellとは AWS Tools for Windows PowerShellは、PowerShell向けのサービスです。PowerShellからAWSサービスを利用するためのコマンドツール群です。 AWS Tools for PowerShellとは何ですか? - AWS Tools for PowerShell AWS Tools for PowerShell は、 によって公開される機能に基づいて構築された PowerShell モジュールのセットです AWS SDK for .NET。 AWS Tools for PowerShell を使用す... docs.aws.amazon.com Winsows Server 2022においては、”4.1.628″のバージョンがインストール済みとなります。 AWS Windows AMI version history - AWS Windows AMIs Find historical details about AWS Windows AMI version releases. docs.aws.amazon.com   アーキテクチャー 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    AWS Tools for Windows PowerShellを利用したローカル⇒サーバへのファイル共有 まず、ローカルからサーバ(EC2)へのファイル転送手順です。 S3へのアップロード まずはローカルのファイルをS3にアップロードします。 今回は、AWS-CLIの導入を対象とします。 AWS CLIの最新バージョンのインストールまたは更新 - AWS Command Line Interface AWS CLI をシステムにインストールまたは更新する手順。 docs.aws.amazon.com ローカルPC上でWindows (64 ビット) 用のインストーラをダウンロードします。 対象ファイルをS3に格納しておきます。 キーペアの値を確認し、EC2に接続 下記記事を参考に、同様の手順でEC2にフリートマネージャー経由で接続します。 フリートマネージャー経由でのWindowsサーバ接続時に、PowerShellのキーボード入力機能を動作させるためには AWS Systems Managerのフリートマネージャーを利用して、Windowsサーバにブラウザベースでのリモート接続している方多いかと思います。その際に、PowerShellでキーボード入力が機能しなかった事象が発生しましたので対処策をお話します。 blog.usize-tech.com 2024.09.09 Read-S3Objectコマンドの実行 PowerShellを開き、コピー&ペーストを使って下記コマンドを実行します。 Read-S3Object -BucketName <Bucket Name> -Key <Object Key> -File <Local File Path> 今回の場合は、以下のようなコマンドとなります。 Read-S3Object -BucketName fukuchi-s3-bucket -Key AWSCLIV2.msi -File C:\Users\Administrator\Downloads\AWSCLIV2.msi  Read-S3Object -BucketName <String> -Key <String> -File <String> -Version <String> -ModifiedSinceDate <DateTime> -UnmodifiedSinceDate <DateTime> -UtcModifiedSinceDate <DateTime> -UtcUnmodifiedSinceDate <DateTime> -ServerSideEncryptionCustomerMethod <ServerSideEncryptionCustomerMethod> -ServerSideEncryptionCustomerProvidedKey <String> -ServerSideEncryptionCustomerProvidedKeyMD5 <String> -ChecksumMode <ChecksumMode> -ClientConfig <AmazonS3Config> -UseAccelerateEndpoint <SwitchParameter> -UseDualstackEndpoint <SwitchParameter> -ForcePathStyleAddressing <Boolean> サーバ上にダウンロードできれば下記画面が表示されます。 AWS-CLIの導入 インストーラーをダブルクリックし、画面の指示に従って進めます。 “Next”を押下します。 チェックボックスにチェックを付与して、”Next”を押下します。 “Next”を押下します。 “Install”を押下します。 無事にインストールが完了しました。”Finish”を押下すると、画面が閉じます。 コマンドプロンプトを開き、下記のコマンドを実行します。 aws --version AWS-CLIをインストールすることができました。   AWS Tools for Windows PowerShellを利用したサーバ⇒ローカルへのファイル共有 今度は、サーバ(EC2)からローカルへのファイル転送手順です。 ファイルの作成 サーバ上の任意の場所でファイルを作成してください。 今回は、notepadを利用して”test.txt”ファイルを作成しておきました。 Write-S3Objectコマンドの実行 PowerShellを開き、コピー&ペーストを使って下記コマンドを実行します。 Write-S3Object -BucketName <Bucket Name> -Key <Object Key> -File <Local File Path> 今回の場合は、以下のようなコマンドとなります。 Write-S3Object -BucketName fukuchi-s3-bucket -Key "test.txt" -File "C:\Users\Administrator\Documents\test.txt" Write-S3Object -BucketName <String> -Key <String> -File <String> -CannedACLName <S3CannedACL> -PublicReadOnly <SwitchParameter> -PublicReadWrite <SwitchParameter> -ContentType <String> -StorageClass <S3StorageClass> -StandardStorage <SwitchParameter> -ReducedRedundancyStorage <SwitchParameter> -ServerSideEncryption <ServerSideEncryptionMethod> -ServerSideEncryptionKeyManagementServiceKeyId <String> -ServerSideEncryptionCustomerMethod <ServerSideEncryptionCustomerMethod> -ServerSideEncryptionCustomerProvidedKey <String> -ServerSideEncryptionCustomerProvidedKeyMD5 <String> -Metadata <Hashtable> -HeaderCollection <Hashtable> -TagSet <Tag[]> -ChecksumAlgorithm <ChecksumAlgorithm> -ConcurrentServiceRequest <Int32> -CalculateContentMD5Header <Boolean> -PartSize <FileSize> -IfNoneMatch <String> -Force <SwitchParameter> -ClientConfig <AmazonS3Config> -UseAccelerateEndpoint <SwitchParameter> -UseDualstackEndpoint <SwitchParameter> -ForcePathStyleAddressing <Boolean> S3上にアップロードできれば下記画面が表示されます。 S3コンソールを確認し、該当のファイルが格納されていますね。その後は、マネジメントコンソール等を利用してS3内のファイルをローカルにダウンロードすればOKです。   まとめ 閉域網環境のEC2(Windows)でも、AWS Tools for Windows PowerShellがインストール済みのため、各種AWSのAPIを利用することができます。 AWS Tools for PowerShell Reference docs.aws.amazon.com   最後に いかがだったでしょうか。 AWS Tools for Windows PowerShellを利用すれば、閉域網環境でも容易にファイル共有ができました。普段はAWS-CLIを使う機会が多いですが、これを機に積極的に利用してみようと思います。 本記事が皆様のお役にたてば幸いです。 ではサウナラ~🔥
こんにちは。SCSKの磯野です。 Dataplexにはデータリネージ機能があります。BigQueryでどのように加工したときがリネージ対象なのか、調べてみました。 データリネージとは? データリネージ とは、データがいつ、どこで、どのように取得され、今の状態にあるのかを追跡し、データの流れを可視化する機能です。データリネージは、DataPlex の機能名ではありますが、Google Cloud に限らず一般的に使われる用語です。   BigQueryでどのように加工したときにリネージされる? 公式ドキュメント には、以下の記載があります。 BigQuery プロジェクトでデータリネージを有効にすると、Dataplex によって次のリネージ情報が自動的に記録されます。 次の BigQuery ジョブの結果として新しいテーブルが作成されます。 コピージョブ Cloud Storage URI を使用して Cloud Storage から許可された形式でデータを読み込む 読み込みジョブ * Google 標準 SQL で次のデータ定義言語(DDL)を使用する クエリジョブ CREATE TABLE CREATE TABLE AS SELECT CREATE TABLE COPY CREATE TABLE CLONE CREATE TABLE FUNCTION CREATE TABLE LIKE CREATE VIEW CREATE MATERIALIZED VIEW Google 標準 SQL で次のデータ操作言語(DML)ステートメントを使用した結果としての既存のテーブル 次にリストされたテーブルタイプのいずれかに関連付けられた  SELECT 。 BigQuery ビュー BigQuery マテリアライズド ビュー BigQuery 外部テーブル INSERT SELECT MERGE 更新 削除 検証対象 実際にどのように加工するとリネージされるのか、以下の4パターンを調べてみました。 Python(BigQuery API、pandas) ※実行基盤はCloudRunまたはVertex AI Workbench Python( BigQuery DataFrame ) ※実行基盤はCloudRunまたはVertex AI Workbench magicコマンド ※実行基盤はVertex AI Workbench Dataform Python(BigQuery API、pandas) CloudRun・Vertex AI Workbenchの両方で試しましたが、リネージされませんでした。 from google.cloud import bigquery import pandas as pd import google.cloud.logging log_client = google.cloud.logging.Client() log_client.setup_logging() client = bigquery.Client() def main(): query = """ SELECT PassengerId, Survived, Name FROM xxx_dataset.transfer_titanic """ df = client.query(query).to_dataframe() client.load_table_from_dataframe(df,"xxx_dataset.dataplex_test_table_by_vertexai_pandas") if __name__ == '__main__': main() Python(BigQuery DataFrame) CloudRun・Vertex AI Workbench、どちらの環境でもリネージされました。 ※BigQuery DataFrameは2024年9月時点でプレビュー版であるため注意 import bigframes.pandas as bpd import google.cloud.logging log_client = google.cloud.logging.Client() log_client.setup_logging() def main(): query = """ SELECT PassengerId, Survived, Name FROM xxx_dataset.transfer_titanic_test_copy2 """ df = bpd.read_gbq(query) df.to_gbq("xxx_dataset.dataplex_test_table_by_vertexai_bpd", if_exists='replace') if __name__ == '__main__': main() magicコマンド Vertex AI Workbenchで実行したところ、リネージされました。 %%bigquery CREATE TABLE `dxr-poc.xxx_dataset.dataplex_test_magic` CLONE `dxr-poc.xxx_dataset.transfer_titanic_test_copy3`; Dataform 下記に従って検証したところ、リネージされました。 SQL ワークフローを作成して実行する  |  Dataform  |  Google Cloud   さまざまなユースケース スクレイピング等でGCP環境外のデータをBigQueryに格納する場合 リネージ対象はGCP環境内のみ。一度GCSを経由すれば、GCSーBigQuery間のみリネージされます。 プロジェクトをまたぐ場合 両方のプロジェクトにて以下のAPIが有効にされていればリネージ可能です。 Google Cloud Data Catalog API Data Lineage API   結論 GCP外のデータをリネージすることはできないものの、データ取得時に一度GCSへ格納しつつ、BigQuery DataFrameを使うことでデータリネージが可能でした。 pandas APIはリネージの対象外でした。 BigQuery DataFrameを使うことでリネージは可能ですが、実行基盤を特定することはできませんでした。また、実行の度にリネージが作成されるため、視認性は低いです。 Dataformやmagicコマンドはリネージの対象でした。 すべてのリネージ情報は  30 日間のみ システムに保持されます。 →定期実行しているものであれば問題ないですが、スポット実行のテーブルのリネージは消えてしまうため注意が必要です。 補足 カスタムリネージ について Dataplexがメタデータの自動収集の対象外としている処理については、リネージも自動作成できませんが、カスタムリネージを作成することで、表示することは可能です。 データリネージについて  |  Data Catalog のドキュメント  |  Google Cloud リネージが作成されるまで、少しタイムラグがあります。今回の検証では、ジョブが終わってから約10分ほどで生成されました。 ※公式ドキュメントには下記の記載があります。 BigQuery リネージは、BigQuery ジョブが完了してから 24 時間以内に表示されます。 リネージ情報は、関連するデータソースを削除した後も保持されます。つまり、BigQuery テーブルとその Data Catalog エントリを削除しても、API を使用して最大  30 日間 は、そのテーブルのリネージを読み取ることができます。