TECH PLAY

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

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

1234

昨年のre:Invent 2024にて、Amazon Bedrockでのみ利用可能なモデルとしてAmazon Novaが発表されました。 本記事では、Amazon Novaシリーズの中でテキスト生成が可能な3つのモデルについてまとめました。 Amazon Novaを使用した画像生成や動画生成については、次回の投稿でご紹介します! Amazon Novaとは? Amazon Novaは、フルマネージドサービスであるAmazon Bedrockにて利用可能な、Amazonが開発したモデルです。 テキストや画像、動画をプロンプトとして与えることにより、テキスト生成だけでなく、画像生成や動画生成も可能です。 本記事投稿時点では、バージニア北部、オハイオ、オレゴンリージョンでのみ利用可能です。 ※オハイオ、オレゴンリージョンはテキスト生成が可能なMicro、Lite、Proのみ利用が可能です。画像生成が可能なCanvasや動画生成が可能なReelは、バージニア北部でのみ提供されています。 Amazon Nova Micro Amazon Novaシリーズの中で最も低コストで低レイテンシーなテキスト生成モデルです。 入力形式はテキストのみ、最大トークン数は128kと他のモデルの半分以下となっています。 言語理解、翻訳、推論、コード補完、ブレインストーミング、数学的問題解決が得意なモデルとのことです。 入力形式 テキスト 最大トークン 128k 言語 200+(日本語含む) Converse API 対応 1000入力トークンあたりの料金 USD 0.000035 1000出力トークンあたりの料金 USD 0.00014 Amazon Nova Lite テキストや画像、動画からテキストを生成するマルチモーダルなモデルです。 最大トークン数は300kとMicroの2倍以上となり、複数の画像や最大30分の動画を入力として受け付け可能です。 リアルタイム顧客対応、文書分析、質問応答タスクを高い精度で処理することができるとのことです。 入力形式 テキスト、画像、動画 最大トークン 300k 最大画像サイズ 25MB 最大動画サイズ 1GB 言語 200+(日本語含む) Converse API 対応 1000入力トークンあたりの料金 USD 0.00006 1000出力トークンあたりの料金 USD 0.00024 Amazon Nova Pro 2025年1月時点でGAされているMicro、Lite、Proの中で最も高性能なテキスト生成モデルです。 主要なベンチマークにおいてClaude 3.5 Sonnet V2やGPT-4oと比較しても遜色ない性能となっています。 複雑な文書分析、動画要約、数学的推論などを得意としているようです。 入力形式 テキスト、画像、動画 最大トークン 300k 最大画像サイズ 25MB 最大動画サイズ 1GB 言語 200+(日本語含む) Converse API 対応 1000入力トークンあたりの料金 USD 0.0008 1000出力トークンあたりの料金 USD 0.0032 Amazon Nova Premier 2025年初頭にリリース予定のテキスト生成モデルであり、最上位モデルとして登場予定です。 現時点で公開されている情報は少ないですが、複雑な推論タスクやカスタムモデルを精製するための最適な教師として使用できるとのことです。 実際に触ってみる モデルアクセス有効化 まずはモデルアクセスを有効化します。 リージョンをバージニア北部に変更し、Bedrockのメニューから「モデルアクセス」をクリックします。 以下のような画面が表示されたら「特定のモデルを有効にする」をクリックします。 「Nova Micro」、「Nova Lite」、「Nova Pro」にチェックを入れて「次へ」をクリックします。 「送信」をクリックします。 アクセスのステータスが「アクセスが付与されました」となっていればモデルアクセス有効化完了です。 Chat / Text playgroundからモデルを実行する 「モデルを選択」をクリックします。 実行したいモデルを選択して「適用」をクリックします。 チャットボックスにプロンプトを入力し、「実行」をクリックします。 今回はBedrockについて質問したいと思います。 Amazon Nova Micro Input:8トークン Output:554トークン Latency:3384ms 回答: Amazon Bedrockは、Amazon Web Services (AWS)が提供する新しいインフラストラクチャサービスです。これは、大規模言語モデル(LLMs)や他のAI/MLモデルを簡単に利用できるようにするインフラストラクチャを提供することを目的としています。以下に主な特徴を紹介します。 ### 1. **カスタマイズ可能なAI/MLモデル** Amazon Bedrockは、ベンダー固有のハードウェアやソフトウェアに依存せずに、カスタマイズ可能なAI/MLモデルを提供します。これは、ユーザーが特定のニーズに合わせてモデルを調整できることを意味します。 ### 2. **オープンで互換性のあるインフラストラクチャ** ベンダーロックインを避けるために、Amazon Bedrockはオープンで互換性のあるアーキテクチャを採用しています。これにより、ユーザーは異なるベンダーのツールやサービスを容易に統合できます。 ### 3. **開発者フレンドリーなツールとサービス** Bedrockは開発者に向けたツールやサービスを提供し、モデルのトレーニング、デプロイメント、管理を容易にします。これには、モデルのカスタマイズや効率的なトレーニングのためのフレームワークが含まれます。 ### 4. **高度なセキュリティとプライバシー** AWSの信頼できるセキュリティモデルを継承し、Amazon Bedrockはデータプライバシーとセキュリティの強化に重点を置いています。これにはデータの暗号化、アクセス管理、コンプライアンス機能が含まれます。 ### 5. **コスト効率の良い利用** AWSの従量課金制の価格モデルを採用しており、ユーザーは実際に利用したリソースに対してのみ支払います。これは、特に大規模なモデルのトレーニングやデプロイメントにおいて経済的に有利です。 ### 6. **エンドツーエンドのソリューション** Amazon Bedrockは、モデルのトレーニングからデプロイメントまでをカバーするエンドツーエンドのソリューションを提供します。これにより、開発者はモデルの開発サイクル全体をより効率的に管理できます。 ### 7. **継続的なアップデートとサポート** AWSは定期的に新しい機能やサービスをリリースし、ベンダー固有のハードウェアやソフトウェアに依存せずに、最新の技術トレンドに対応できるようサポートしています。 Amazon Bedrockは、開発者がAI/MLモデルを効果的に利用し、最適化できるよう設計されています。特に、特定のビジネスニーズに合わせたカスタマイズが容易な点が特徴的です。 Amazon Nova Lite Input:8トークン Output:475トークン Latency:3730ms 回答: Amazon Bedrockは、Amazon Web Services (AWS) が提供する新しい機械学習プラットフォームで、主に生成AIモデルの構築、カスタマイズ、デプロイをサポートする機能に焦点を当てています。以下は、Amazon Bedrockの主要な特徴です: 1. **カスタマイズ可能な生成AIモデル**: - 既存の生成AIモデル(例:テキスト生成、画像生成など)をカスタマイズして、特定の業界やアプリケーションに合わせて調整することができます。 2. **迅速なプロトタイピングと開発**: - 開発者が簡単にプロトタイプを作成し、モデルをテスト、評価できる環境を提供します。これにより、開発サイクルが短縮されます。 3. **幅広いモデルサポート**: - 様々な生成AIモデルに対応しており、ユーザーは自分のニーズに合わせて最適なモデルを選択できます。 4. **セキュリティとコンプライアンス**: - データのセキュリティとプライバシーを重視し、企業がコンプライアンス要件を満たすための機能を提供します。 5. **スケーラブルなインフラストラクチャ**: - 必要に応じてモデルのスケーリングが容易であり、大規模なデータセットや高負荷のアプリケーションに対応できます。 6. **統合性**: - AWSの他のサービス(例:Amazon S3、Amazon SageMakerなど)とシームレスに統合され、データ管理、モデルトレーニング、デプロイメントなどのプロセスを効率化します。 7. **カスタムエンドポイント**: - モデルをカスタムエンドポイントとしてデプロイし、アプリケーションやサービスに組み込むことができます。 8. **サブスクリプションベースのモデルアクセス**: - 特定のモデルへのアクセスは、サブスクリプションベースで提供される場合があり、柔軟な支払いオプションを提供します。 これらの特徴により、Amazon Bedrockは、企業や開発者が生成AIモデルを活用して、革新的なアプリケーションやサービスを構築するのに役立つ強力なツールとなっています。 Amazon Nova Pro Input:8トークン Output:512トークン Latency:6558ms 回答: Amazon Bedrockは、Amazon Web Services (AWS) が提供するサービスで、主に以下のような特徴があります: ### 1. **基盤となるモデルの統合** - 複数の先進的な大規模言語モデル(LLMs)へのアクセスを提供し、ユーザーは様々なモデルを比較・選択できます。 ### 2. **プライベートでセキュア** - データのプライバシーとセキュリティに重点を置いており、モデルのトレーニングに使用されるデータはユーザーのAWSアカウント内で管理されます。 ### 3. **簡単な統合** - AWSエコシステムとの深い統合により、他のAWSサービス(Lambda、S3、DynamoDBなど)とシームレスに連携できます。 ### 4. **カスタマイズ可能** - ユーザーは自分のデータを使用してモデルを微調整(Fine-tuning)でき、特定の用途や業界に合わせてカスタマイズが可能です。 ### 5. **プロンプトエンジニアリングの支援** - 効果的なプロンプトの作成を支援するツールやガイダンスを提供し、ユーザーがより良い結果を得られるようにサポートします。 ### 6. **パフォーマンスとスケーラビリティ** - AWSのインフラストラクチャを活用して、高パフォーマンスとスケーラビリティを確保します。需要に応じてリソースを自動的に調整できます。 ### 7. **コスト効率** - ペイ・アス・ユー・ゴーの課金モデルを採用しており、使用量に応じて支払うため、コストを最小限に抑えることができます。 ### 8. **監視とログ** - アプリケーションのパフォーマンスを監視し、必要に応じてログを記録できる機能を提供します。 ### 9. **幅広い利用シナリオ** - チャットボット、コンテンツ生成、推薦システム、カスタマーサポートなど、様々なアプリケーションに適用可能です。 ### 10. **コミュニティとサポート** - 活発なAWSコミュニティと充実したサポートリソース(ドキュメント、フォーラム、コンサルティングサービスなど)が利用可能です。 これらの特徴により、Amazon Bedrockは企業が機械学習と人工知能を活用し、革新的なソリューションを迅速に開発・展開できるように Converse APIから実行してみる ソースコード NovaはConverse APIにも対応しているので実際に実行してみます。 以下のコードをLambdaで実行します。 import boto3 def lambda_handler(event, context):   client = boto3.client("bedrock-runtime", region_name="us-east-1")   modelId_micro = 'amazon.nova-micro-v1:0'   modelId_lite = 'amazon.nova-lite-v1:0'     modelId_pro = 'amazon.nova-pro-v1:0'     prompt = "SCSK株式会社について簡潔に教えてください"   messages = [       {           "role": "user",           "content": [{"text": prompt}],       }   ]   inferenceConfig = {       "temperature": 0.1,       "topP": 0.9,       "maxTokens": 500,       "stopSequences":[]   }   response_micro = client.converse(       modelId=modelId_micro,       messages=messages,       inferenceConfig=inferenceConfig   )   response_lite = client.converse(       modelId=modelId_lite,       messages=messages,       inferenceConfig=inferenceConfig     )   response_pro = client.converse(       modelId=modelId_pro,       messages=messages,       inferenceConfig=inferenceConfig     )   print("-------------Nova Micro-------------")   print(f'latency : {response_micro["metrics"]["latencyMs"]}')     print(response_micro["output"]["message"]["content"][0]["text"])   print("-------------Nova Lite-------------")   print(f'latency : {response_lite["metrics"]["latencyMs"]}')     print(response_lite["output"]["message"]["content"][0]["text"])   print("-------------Nova Pro-------------")   print(f'latency : {response_pro["metrics"]["latencyMs"]}')   print(response_pro["output"]["message"]["content"][0]["text"]) 実行結果 -------------Nova Micro------------- latency : 867 SCSK株式会社は、日本の情報サービス会社で、主に情報技術(IT)ソリューションを提供しています。1972年に設立され、現在は東京証券取引所プライム市場に上場しています。主なサービスには、クラウドサービス、データセンター運用、セキュリティソリューション、ビジネスプロセスアウトソーシング(BPO)などがあります。SCSKは、企業のITインフラストラクチャの構築や運用、データの保護、効率的なビジネスプロセスの管理を支援しています。また、政府機関や大手企業向けにも幅広いサービスを提供しています。 -------------Nova Lite------------- latency : 2375 SCSK株式会社(エス・シー・エス・ケー、英文社名:SCSK Corporation)は、日本の情報技術(IT)サービス企業です。以下に主な特徴を簡潔にまとめました: 1. **設立**: 2011年4月にSCSK株式会社として設立されました。これは、日本システム開発株式会社(JSD)と日本ソフトバンク株式会社(SBB)の合併により設立されました。 2. **事業内容**:   - **システムインテグレーション(SI)サービス**: 企業のIT基盤の構築・運用管理など。   - **アウトソーシングサービス**: ビジネスプロセスアウトソーシング(BPO)やITアウトソーシングなど。   - **クラウドサービス**: クラウドコンピューティングサービスの提供。   - **セキュリティサービス**: 情報セキュリティ対策の提供。 3. **主要顧客**: 大企業や官公庁など幅広い顧客層を対象としています。 4. **株式上場**: 東京証券取引所プライム市場に上場しています。 5. **グループ会社**: 国内外に多数のグループ会社を持ち、幅広いITサービスを提供しています。 SCSKは、日本の主要なITサービスプロバイダーの一つとして、幅広いサービスを提供しています。 -------------Nova Pro------------- latency : 2105 SCSK株式会社は、日本の大手ITサービス企業で、SCSK Corporationとして知られています。主にシステムインテグレーション、ITコンサルティング、ソフトウェア開発、ネットワークサービスなどを提供しています。親会社は日本電気株式会社(NEC)で、SCSKはNECグループ内のITサービス部門を担う重要な企業です。SCSKは官公庁、金融機関、通信事業者、製造業など様々な業界のクライアントにサービスを提供しており、特に金融・公共セクターでの経験が豊富です。同社はITインフラの構築・運用、クラウドサービス、サイバーセキュリティ、デジタルトランスフォーメーション(DX)支援など、幅広いITソリューションを提供しています。 temperatureを0.1にしたからでしょうか、嘘の情報が混じってますね… Converse APIで実行できたので今回は良しとしましょう! 実際に使う時はパラメータやNovaシリーズのどのモデルを使うか検討が必要そうです。 まとめ Amazon Novaシリーズの中でテキスト生成が可能な3つモデルについてまとめました。 使い倒してどのユースケースにどのモデルを使うのが最適か検証していきたいと思います。 次回は画像生成ができるNova Canvasについて紹介します。
こんにちは。新人の加藤です! 前回投稿時は絶賛研修中でしたが、現在は初めての案件に入り、日々精進しております。 案件では、クラウドのリソース管理をIaC上で行っており、コードも含め全てGitHub上で管理を行っています。 今回は、そのGitHubについて色々とつまづいてしまった部分が多かったため、初心者による初心者のためのGitHubの情報共有を行えたらと思います! 何となくでGitHubを使用している方やこれから使用する人の手助けとなれば幸いです。 GitHubとは そもそもGitHubとは GitHubとは、 Gitをオンライン上で設置し、世界中からファイルを参照/編集できるようにしたWebサービス のことを指します。では、Gitとはどのようなものなのかを説明していきます。 Gitとは、 プログラムのソースコードやCloud Formationのテンプレートファイルなどの変更履歴を 分散型 で管理することができるシステム です。 従来までは1つのメインとなるディレクトリで中央集中的にコードを管理していましたが、その状況だとユーザ同士が同時にファイルを編集してしまうと、ファイルの競合などが起こりやすい環境でした。 分散型で処理をするようになったおかげで、ユーザが個々にディレクトリを持ち、変更履歴を管理できるようになりました。 Gitの特徴として以下が挙げられます。 ファイルの変更履歴を管理することができる ユーザ同士が同時にコードを参照し、作業することができる 過去のバージョンに戻すことができる 自分用の作業環境(ブランチ)を作成することができる このような特徴があるため、チームで開発する際にコードを管理する道具としてGitHubが優れているわけです。 Gitの構造 Gitの構造を紹介する前に、リポジトリとリモートリポジトリ、ローカルリポジトリという言葉だけ先に紹介します。 リポジトリ ファイルや変更履歴を管理するためのストレージ リモートリポジトリ Web上に置かれ、複数のユーザが参照する最もメインのリポジトリ ローカルリポジトリ 個々のユーザのPC上に置かれるリポジトリ ユーザはリモートリポジトリからメインとなるソースコードやファイルを自身のローカルリポジトリに持ってきて、そこでファイルの編集や追加を行います。このような構造となっているため、個々がファイルの編集を行っても、他のユーザが参照するメインのリモートリポジトリには影響がないため、競合が起きにくくなります。   Gitの基本的なアクション では実際はどのようにして、リモートリポジトリで管理されているファイルやフォルダを持ってきて、どのようにしてローカルリポジトリで自身が編集したファイルをリモートリポジトリに上げるのでしょうか? それはGitの基本的なアクションである「 pull 」「 add 」「 commit 」「 push 」をすることによって実現することができます。以下に図と共にそれぞれのアクションについて説明します。 ワークツリーとは、ユーザが編集している作業場所 インデックスとは、ローカルリポジトリとワークツリーの間の中間領域 【pull】 リモートリポジトリの内容をローカルリポジトリに持ってくること。 <コード> 【add】 ワークツリーで編集したファイルをインデックスに移すこと。簡易的に述べると、自身の作業場所からローカルリポジトリに保存したいファイルを選択すること。 <コード> 【commit】 addで選択したファイルをローカルリポジトリに反映させること。 <コード> 【push】 ローカルリポジトリの変更内容をリモートリポジトリに反映させること。 <コード> ブランチについて ブランチとは、 1つのメインのプロジェクトとは異なる分岐を作り、プロジェクト本体に影響を与えずに開発を行える機能 のことをいいます。例えば、メインのプロジェクトからブランチAとブランチBをそれぞれ作成することにより、ブランチAでは機能Aの開発をしブランチBでは機能Bの開発をする、という住み分けが可能になるということです。具体的なイメージは下記の通りとなります。 ブランチ、リポジトリのどちらも各ユーザが個別にファイルを変更できるようにした機能という観点では変わりはないですが、管理対象が明らかに異なります。リポジトリには複数のブランチを含めることができ、 プロジェクト全体(ディレクトリとファイル)を管理 しており、ブランチは リポジトリのバージョンを管理 しています。 よく使用するコマンド よく使用するコードについて、下記に記載します。 git clone <リポジトリのURL> 対象リポジトリのデフォルトブランチをローカルリポジトリに作成する git clone -b <ブランチ名> <リポジトリのURL> 対象リポジトリの対象ブランチをローカルリポジトリに作成する git branch  ローカルブランチの一覧を出力する git branch <ブランチ名> 対象ブランチを新規作成する git checkout <ブランチ名> 対象ブランチに切り替える git checkout -b <ブランチ名> 対象ブランチを新規作成し、切り替える(git branchとgit checkoutをまとめて行える) git status 変更したファイルの一覧を出力する git fetch <リモートリポジトリ名> <ブランチ名> 指定したリモートレポジトリの指定したブランチのみの最新のコミット履歴を取得 git fetch <リモートリポジトリ名> 指定したリモートリポジトリの最新のコミット履歴をまるごと取得 git merge <ブランチ名> 現在の作業ブランチに指定したブランチの内容を取り込む git reset HEAD <ファイル名> インデックスにある対象ファイルをワークツリーに戻す(git add <ファイル名> を取り消す) git reset HEAD インデックスにある全ファイルをワークツリーに戻す(git add -a を取り消す) まだまだこれ以上にコマンドはあるのでぜひ調べてみてください! GitHubを使用した開発の流れ ブランチとリポジトリを組み合わせた、主な流れは以下のようになっています。 リモートリポジトリからローカルリポジトリにフォルダやファイルを持ってくる(git clone) 開発用ブランチの変更(git branch) ブランチを切り替える(git checkout) ファイルの編集 編集したファイルの確認(git status) コミットしたい対象ファイルを選択(git add) ローカルリポジトリに対象ファイルをコミット(git commit) リモートリポジトリにローカルリポジトリの内容をプッシュ(git push) 自分が作成したブランチを開発で使用しているメインのブランチに統合 このとき、プルリクエストというメインのブランチに統合していいか許可をもらうリクエストを提出する 上記の流れで開発を進めることで、ひとつのリポジトリで複数人のユーザが同時にファイルを編集し、バージョンを管理することができます。 注意点 下記に私がGitHubを使用していて疑問に思ったことや注意点をつらつら書いていきたいと思います。 git pullとgit fetchの違い どちらもリモートリポジトリの内容をローカルリポジトリの持ってくるという意味では違いはありません。ではどこに違いかあるのかというと、持ってきたデータをどこに保存するかです。実は、リモートリポジトリにあるブランチ(リモートブランチ)からローカルリポジトリにあるブランチ(ローカルブランチ)に内容を同期する際には、直接ローカルブランチの内容を書き換えるのではなく、2つのブランチ間にある「リモート追跡ブランチ」の内容を更新し、そこからローカルブランチを更新しています。 git fetchはそのリモート追跡ブランチの内容を更新するコマンド で、その後にgit mergeを実行することによってローカルブランチの内容が更新されます。一方で、 git pullはgit fetchとgit mergeを合わせたコマンド です。 コミットする際にはコメントをつけよう 今まで私はコミットする際にコメント内容を変えずに、コミットしていました。リポジトリを使う人が自分自身だけなら中身を見ればすぐ分かるので問題はないのかもしれませんが、Gitは複数人で開発する際に最も有用なコード管理ツールのうちの1つです。自分だけではなく、他の方もリポジトリの更新内容やその修正差分を見ます。それらが分かるように “git commit -m <コメント>” で絶対コメントをつけるようにしましょう。 競合が起きた際の解決策 チームで開発をしている際に自身の作業内容をマージさせるためにプルリクエストを行うと、競合が発生することがしばしばあります。私も研修で初めて競合が出た際にはどうしたらいいか分からず、適当に「Resolve conflicts」ボタンをポチって直していました。後々調べてみるとあれは実は裏で、どのコミットを優先的に反映させるかを選び、マージをしていたそうです。基本的には、あなたのブランチの変更だけを保持したいか、他のブランチの変更だけを保持したいか、あるいは両方のブランチからの変更を取り入れられる新しい変更を作成するかの3つから選択します。基本的にはボタンを押せば解決するかもですが、どのコミットを優先するべきなのか考えるためにも、競合が発生した場所同士を把握することが最も大切です。 おわりに 研修では、AWS CodeCommitを使用してコードを管理していましたが、その際にはGitについてよく分からないまま、手順書通りにコマンドを打っていました。今回、このブログを通してGitについて調べ自身でまとめることにより、どこで何をしているのかが明確になり、Gitを使用する嬉しさみたいなものが理解できるようになりました。現在の案件ではコードの管理だけではなく、タスクの管理までGitHubで行っているのでそれについても調べていきたいと思います。 前回の投稿では、「AWSのナレッジ共有をします」といっていたにも関わらず、もはやクラウドの内容でもなかったので次こそはAWSの内容を投稿します!
こんにちは。SCSK渡辺(大)です。 ゴールデンウィークに大阪万博に行くことが決まりました。 3Dのクラゲに触れることができ感触を味わえるらしいので楽しみです。 今回は、 AWS Amplify+AWS CDKで人生初のアプリケーションを作ってみました。 の第2回です。 第1回: AWS Amplifyでデプロイした後にログイン画面をカスタマイズしてみた 第2回:AWS CDKでAPIを作ってみた    ←今回 第3回:アプリケーションを構築して動かしてみた   AWS CDK 使ってみた! (Pythonでインフラ構築) 今回はPythonを使ってAWS CDKのハンズオンに挑戦してみました。Cloudformationの場合、記載しなくてはならない量がそこそこ多く大変ですがCDKではコード量を抑えながら柔軟にAWSリソースを作成できることがわかりました。 blog.usize-tech.com 2022.01.07 試験日まで毎日励ますサーバーレスLINE Botを作ろう(AWS CDK編) AWS CDKを利用して、試験日まで毎日励ましてくれるLINE Botを作成しました。AWS CDKを利用してサーバーレスサービスを立ち上げて、LINE Botを簡単に実装することができます。マネジメントコンソール編の記事と合わせて読むと理解が深まります。 blog.usize-tech.com 2022.05.17 どんなAPIを作るのか 実際に利用することが目的ではなく、勉強が目的であるため簡単なものにすることにしました。 AWSアカウント全体の直近30日間の利用料金合計を取得する 利用料金が最も高いサービスTOP3とその利用料金を取得する 上記の2つを返す 準備 プロジェクトの雛形を作成する cdkという名前のフォルダを作成し、そこで作業しました。 プロジェクトの雛形を作成します。 $ cdk init app --language typescript Applying project template app for typescript # Welcome to your CDK TypeScript project This is a blank project for CDK development with TypeScript. The `cdk.json` file tells the CDK Toolkit how to execute your app. ## Useful commands * `npm run build` compile typescript to js * `npm run watch` watch for changes and compile * `npm run test` perform the jest unit tests * `npx cdk deploy` deploy this stack to your default AWS account/region * `npx cdk diff` compare deployed stack with current state * `npx cdk synth` emits the synthesized CloudFormation template Initializing a new git repository... Executing npm install... npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. npm warn deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported ✅ All done!   クレデンシャル情報を変更する aws s3 lsで結果が返ってくる状態になっていれば問題ありません。 $ aws s3 ls yyyy-mm- dd hh:mm: ss [ S3バ ケット名]   【AWS】ベストプラクティスに準拠してアクセスキーを利用したい Visual Studio CodeからAWSリソースにアクセスするには、アクセスキーが必要になります。今回は、ベストプラクティスに準拠してアクセスキーを利用する方法を考えてみました。 blog.usize-tech.com 2024.12.11   テストデプロイをする ブートストラップは既に別の利用者が実行していたため割愛しました。 cdk diffでメタデータ以外が作成されないことを確認します。 $ cdk diff Stack CdkStack Parameters [+] Parameter BootstrapVersion BootstrapVersion: {"Type":"AWS::SSM::Parameter::Value<String>","Default":"/cdk-bootstrap/xxxxxxxxx/version","Description":"Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"} Conditions [+] Condition CDKMetadata/Condition CDKMetadataAvailable: {"Fn::Or":[{"Fn::Or":[{"Fn::Equals":[{"Ref":"AWS::Region"},"af-south-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-east-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-northeast-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-northeast-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-northeast-3"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-south-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-south-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-southeast-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-southeast-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-southeast-3"]}]},{"Fn::Or":[{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-southeast-4"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ca-central-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ca-west-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"cn-north-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"cn-northwest-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-central-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-central-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-north-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-south-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-south-2"]}]},{"Fn::Or":[{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-west-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-west-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-west-3"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"il-central-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"me-central-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"me-south-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"sa-east-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-east-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-east-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-west-1"]}]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-west-2"]}]} ✨ Number of stacks with differences: 1   デプロイします。 $ cdk deploy ✨ Synthesis time: 8.96s CdkStack: deploying... [1/1] CdkStack: creating CloudFormation changeset... CdkStack | 0/2 | 0:20:52 | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | CdkStack User Initiated CdkStack | 0/2 | 0:20:58 | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | CdkStack User Initiated CdkStack | 0/2 | 0:21:01 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) CdkStack | 0/2 | 0:21:02 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated CdkStack | 1/2 | 0:21:02 | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) CdkStack | 2/2 | 0:21:03 | CREATE_COMPLETE | AWS::CloudFormation::Stack | CdkStack ✅ CdkStack ✨ Deployment time: 14.23s Stack ARN: arn:aws:cloudformation:ap-northeast-1:[アカウントID]:stack/CdkStack/xNNNNNNN-xxxxxxxxx-xxxx-xxxxxxxxxxx ✨ Total time: 23.19s   CloudFormationスタックが作成されたことを確認する AWSマネジメントコンソールでスタックが作成され、メタデータのみが作成されていることを確認します。   リソースを定義する AWS Lambda関数を定義する プロジェクトの直下にlambdaディレクトリを作成します。 その中にgetCostExplorer.pyを作成して、以下のように記述します。 (生成AIに沢山助けてもらいました。) import json import boto3 import logging from datetime import datetime , timedelta logger = logging . getLogger () logger . setLevel ( logging . INFO ) formatter = logging . Formatter ( ' %(levelname)s : %(message)s ' ) for handler in logger . handlers :     handler .setFormatter( formatter ) # CORSヘッダーを定数として定義 CORS_HEADERS = {   'Access-Control-Allow-Origin' : '*' ,     'Access-Control-Allow-Methods' : 'GET, OPTIONS' ,     'Access-Control-Allow-Headers' : 'Content-Type,X-Amz-Date,Authorization,X-Api-Key' ,     'Access-Control-Allow-Credentials' : 'true' } def handler ( event , context ):   logger . info ( "Lambdaハンドラが開始されました。" )   logger . info ( f "イベント: { json . dumps ( event ) } " )   ce_client = boto3 .client( 'ce' )   end_date = datetime . now ()   start_date = end_date - timedelta ( days = 30 )   time_period = {       'Start' : start_date . strftime ( '%Y-%m- %d ' ),       'End' : end_date . strftime ( '%Y-%m- %d ' )   }   granularity = 'MONTHLY'   metrics = [ 'UnblendedCost' ]     try :       # コストデータを取得       def fetch_cost_data ( group_by = None ):           params = {               'TimePeriod' : time_period ,               'Granularity' : granularity ,               'Metrics' : metrics           }           if group_by :               params [ 'GroupBy' ] = group_by           return ce_client .get_cost_and_usage( ** params )         total_cost_response = fetch_cost_data ()       service_cost_response = fetch_cost_data (           group_by = [{ 'Type' : 'DIMENSION' , 'Key' : 'SERVICE' }]       )         # 総コストを計算       total_cost = float ( total_cost_response [ 'ResultsByTime' ][ 0 ][ 'Total' ][ 'UnblendedCost' ][ 'Amount' ])       # サービスごとのコストを計算       services = {           group [ 'Keys' ][ 0 ]: float ( group [ 'Metrics' ][ 'UnblendedCost' ][ 'Amount' ])           for group in service_cost_response [ 'ResultsByTime' ][ 0 ][ 'Groups' ]       }       # コストが高い上位3つのサービスを抽出       top_services = sorted (           [{ 'service' : k , 'cost' : v } for k , v in services . items ()],           key = lambda x : x [ 'cost' ],           reverse = True       )[: 3 ]       return {           'statusCode' : 200 ,           'headers' : CORS_HEADERS ,           'body' : json . dumps ({               'total_cost' : f "$ { total_cost :.2f} " ,               'period' : f " { start_date . strftime ( '%Y-%m- %d ' ) } to { end_date . strftime ( '%Y-%m- %d ' ) } " ,               'top_services' : [{                   'service' : service [ 'service' ],                   'cost' : f "$ { service [ 'cost' ] :.2f} "               } for service in top_services ]           })       }     except Exception as e :       logger . error ( f "エラー: { str ( e ) } " )       return {           'statusCode' : 500 ,           'headers' : CORS_HEADERS ,           'body' : json . dumps ({ 'error' : str ( e )})       }   スタックを定義する プロジェクト直下のlibディレクトリにあるcdk-stack.tsを以下のように修正します。 この内容はCloudFormationのスタックに対応するものであると理解しています。 AWS CDKのメリットである抽象化により、CloudFormationよりも少ない文字数でリソースを定義することが出来ます。 プロジェクト先ではConstructs Levelを意識する必要があるのかと思いますが、今回は気にしません。 (もちろん、こちらも生成AIに助けてもらいました。) import { Stack , StackProps , Duration } from "aws-cdk-lib" ; import { Code , Function , Runtime } from "aws-cdk-lib/aws-lambda" ; import { Construct } from "constructs" ; import * as apigateway from 'aws-cdk-lib/aws-apigateway' ; import * as iam from "aws-cdk-lib/aws-iam" ; export class CdkStack extends Stack {   constructor ( scope : Construct , id : string , props ?: StackProps ) {   super ( scope , id , props );     // Cost Explorer Lambda関数     const getCostExplorerLambda = new Function ( this , "GetCostExplorerHandler" , {       runtime: Runtime . PYTHON_3_13 ,       code: Code . fromAsset ( "lambda" ),       handler: "getCostExplorer.handler" ,       timeout: Duration . minutes ( 1 )   // タイムアウトを1分に設定     });     // Cost Explorer用のIAMポリシー     const costExplorerPolicy = new iam . PolicyStatement ({       actions: [ "ce:GetCostAndUsage" ],       resources: [ "*" ],     });     getCostExplorerLambda . addToRolePolicy ( costExplorerPolicy );     // Cost Explorer API   const costApi = new apigateway . RestApi ( this , "CostExplorerApi" , {     defaultCorsPreflightOptions: {       allowOrigins: [ '*' ],       allowMethods: [ 'GET' , 'OPTIONS' ],         allowHeaders: [ 'Content-Type' ],         allowCredentials: true       }     });         const getCostIntegration = new apigateway . LambdaIntegration ( getCostExplorerLambda );         costApi . root . addMethod ( 'GET' , getCostIntegration );       }     }   App定義をする プロジェクト直下のbinディレクトリにあるcdk.tsを以下のように変更します。 このファイルはCDKの中で最上位の層であるApp定義をするものです。 複数のスタックの依存関係などを定義できますが、今回は1つのスタックしかないため内容は非常にシンプルです。 libディレクトリにあるcdk-stack.tsの内容をデプロイするだけの記述です。 import * as cdk from 'aws-cdk-lib'; import { CdkStack } from '../lib/cdk-stack'; const app = new cdk.App(); new CdkStack(app, 'CdkStack', { });   APIの結果を確認する 改めてデプロイする cdk deployでデプロイします。 ログは多すぎるため割愛しますが、デプロイが成功すると以下のようにAPIのリンクを教えてくれます。   そのリンクを開くと以下のように欲しい情報が取得できていることが確認できました。   CloudFormationスタックが更新されている確認する メタデータだけでなく、AWS LambdaとAmazon API Gatewayも作成されていました。   まとめ インフラ管理の方法は他にもありますが、今回はAWS CDKを選択してみました。 そもそも他の方法について知識が無いということや、AWS CDKを使えるようになったらAWS Amplify Hostingも抵抗なく使えそうであることが理由です。 リソースへのタグ付けなどのカスタマイズは次回以降でチャレンジしたいと思います。 また、初心者視点ですが、実際に触って感じたAWS CDKのメリット以下です。 変更前後の差分が分かって良い(cdk diff) CloudFormationテンプレートの生成も出来る(cdk synth) デプロイ後にAPIのリンクを教えてくれる 環境破壊が楽(cdk deploy) いよいよ次回で完結です。
本記事は 新人ブログマラソン2024 の記事です 。 こんにちは。新人の曲渕です。 今回の記事ではタイトルにあります通り、Microsoft Teams の便利な機能についてご紹介させていただきます。業務で使うことが多いのでご存じの方もいらっしゃるかと思いますが、参考になれば幸いです。 チャット・チームとチャネル編 チャット・チームとチャネル内のメッセージ検索 「 Ctrl+F」 を押します。そうすると右側に以下の画像のような検索ボックスが出力されます。これにより、今見ているチャットやチャネルの過去のメッセージを検索することができます。 あいまい検索 検索ボックスで*(アスタリスク)を末尾に付ける ことで、アスタリスクの前の文字を含むメッセージの検索ができます。例えばセキュリパッチの期限を確認したいときは、以下の画像のように検索すれば画面をスクロールせずに確認することができます。 日付で検索 検索ボックスで「Sent:西暦/月/日」を入力 します。これで指定した日付のメッセージを検索することができます。(あいまい検索と組み合わせることはできません。例:Sent:2025/1/*) 書式モードで改行 Teamsで改行を行うには「Shift+Enter」を押すか書式モードに変更するかの二つの方法があります。特に書式モードを使うことによりEnterキーで改行できるようになるため、誤送信を防ぐことができます。書式モードには 「Ctrl+Shift+X」を押すか画像のアイコンをクリック して変更できます。 日時を指定して送信 デスクトップ版のTeamsでは日時を指定してメッセージを予約送信できます(7日後まで)。以下の画像のように 送信ボタンを右クリック して送りたい日時(時間は30分刻み)を選択します。 ファイル編 チャット内で削除したファイルの復元 チャットで誤って削除したファイルは OneDriveのごみ箱から復元 することが可能です。 削除したファイルを選択して 「復元」 をクリックします。 チームとチャネル内で削除したファイルの復元 チームとチャネルで削除したファイルは SharePointのごみ箱から復元 することが可能です。SharePointへは以下の画像のようにTeamsから移動することができます。 「ごみ箱」から削除したファイルを選択して 「復元」 をクリックします。 チャット内で上書き保存したファイルを変更前の状態に戻す チャットにアップロードしたファイルはOneDriveに保存 されます。そのためチャットで上書き保存したファイルを変更前の状態に戻すにはまずOneDriveの 「Microsoft Teamsチャットファイル」 に移動します。 変更前に戻したいファイルを選び 「バージョン履歴」 をクリックします。 元に戻したいバージョンをクリックして 「復元」 を押します。これによって上書き保存する前のファイルに戻すことができます。 チームとチャネル内で上書き保存したファイルを変更前の状態に戻す チームとチャネルにアップロードしたファイルはSharePointに保存 されます。そのため、まずTeamsからSharePointに移動します。あとはチャット内で上書き保存したファイルと同様の手順でチームとチャネルにアップロードしたファイルを変更前の状態に戻すことができます。 ファイル編集の制限 Teamsの「ファイル」タブから制限をかけたいファイルを選択します。 三点リーダーの「その他」から「チェックアウト」を選択 します。これによってチェックアウトしたユーザー以外はファイルが読み取り専用になります。元に戻すときは同様の手順で「その他」から「チェックイン」もしくは「チェックアウトの破棄」を選択します。 ※「チェックアウトの破棄」を選ぶと編集した内容が失われてしまいます。そのため、チェックアウト後に編集したものを保存したい場合は「チェックイン」を選択します。 通知編 リアクションの通知をオフにする 自分のメッセージに対するリアクションの通知をオフにしたいときは、 Teamsの設定から「通知とアクティビティ」にある「いいね!とリアクション」の項目を「オフ」 にします。 一時的に通知をオフにする Teamsのステータスを「応答不可」にする ことで通知を非表示にすることができます。これにより会議中などにバナーが表示されるのを防ぐことができます。また、「期間」からステータスを指定した時間だけ固定することもできます。 ※ステータスを元に戻すことを忘れないようご注意ください。 アプリ編 Visio Visioは簡単に図を描画できるアプリです。Teamsの左画面にある三点リーダーからVisioを起動させることができます。 Visioには3つのプランがあり、Visio Plan1ではAWSのアーキテクチャのアイコンを使うことができるようですが、 Microsoft 365のVisioでは使える図形に制限 があります。以下、用意されている図形の一例になります。 Visioを使ってみた 実際にVisioを使ってWeb3層の簡単なアーキテクチャを書いてみました。 触ってみた感想としては、 あらかじめ図形のテンプレートが用意されている のと、 ドラッグアンドドロップで図形を描画できる こと、 図形から直接矢印を引っ張ってくることができる ため、ネットワーク構成図やフローチャートを書く分にはPowerPointよりも使いやすいのかなという印象です。ただ、用意されている図形以外を使う場合、貼り付けのオプションが図としてしか貼り付けることができません。そのため、Microsoft365のVisioでAWSのアーキテクチャを書きたい場合などに、他のところからグループ化されたオブジェクトを持ってくる際にはVisio側でグループ化を解除できない点に注意が必要です。 おわりに ご紹介させていただいたもの以外にもいろいろな機能があるので、ぜひ以下の参考サイトをご覧ください。 ここまで読んでくださりありがとうございました! 参考サイト 【Teams】機能一覧:仕事で活躍する便利な機能をまとめて紹介 | OFFICE54
皆様ご無沙汰しております。SCSK LifeKeeper担当 池田です。 最近は、ニューフェイスの勢いに押され気味でしたが、負けじと頑張りたいと思います! さて、今回はWindows版のLifeKeeperとして先月(2024年12月12日)リリースされた「LifeKeeper for Windows v8.10.2」の変更点のなかでも、特に皆さんにご伝えしたい内容について解説していきたいと思います。 それでは張り切ってまいりましょう! Amazon EBSマルチアタッチ機能をサポート! まず、ご紹介したい新機能としては、「Amazon EBSマルチアタッチ機能」をサポートした点です。 Amazon EBSマルチアタッチ機能とは? 「Amazon EBSマルチアタッチ」とはなんぞや?という方もいらっしゃるかと思います。 AWS公式サイトによると Amazon EBS Multi-Attach enables you to attach a single Provisioned IOPS SSD (io1 or io2) volume to multiple instances that are in the same Availability Zone. You can attach multiple Multi-Attach enabled volumes to an instance or set of instances. Each instance to which the volume is attached has full read and write permission to the shared volume. Multi-Attach makes it easier for you to achieve higher application availability in applications that manage concurrent write operations. と書かれており、簡単にいうと「Amazon EBSマルチアタッチを使用すると、プロビジョンドIOPS SSD (io1 または io2) ボリュームを、同じAZにある複数のインスタンスにアタッチできるようになる」とのことです。 イメージはこんな感じです。 従来のオンプレミス環境における「共有ディスク構成」、あるいはMicrosoft Azureでは「Shared Disk」という機能がありますが、そのAWS版とでも言えますでしょうか。 EBSマルチアタッチ機能のサポートでこう変わる! これまで、AWS環境において、LifeKeeperを用いたHAクラスタを構成する際は、異なるアベイラビリティゾーン(Availability Zone(以下、AZ))にEC2インスタンスを配置する必要がありました。 イメージはこんな感じです。 この構成のメリットは、なんと言ってもAZ障害時に耐えられるという点です。HAクラスタでEC2あるいは実装するミドルウェアの可用性を高めるだけではなく、AZ、言い換えるとデータセンター規模の障害にも耐えることができます。 一方で、デメリットがないわけではありません。 EBS間でデータ同期を取る必要がある場合、どうしてもAZ間のネットワークを介す必要があります。 AZ間は低レイテンシ(低遅延)の回線で接続されているとは言われていますが、単一AZ間に比べると、物理的にもネットワーク的にも距離が離れてしまうため、例えばデータベースの更新系処理が頻繁に実行されるシステムの場合、レスポンスへ影響を与える可能性があります。 今回ご紹介する「Amazon EBSマルチアタッチ機能」を利用すると、AWSの単一AZ内でHAクラスタを構成することができようになります。 イメージはこんな感じです。 とてもシンプルになりましたね。 もちろん忘れてはいけないのは、単一AZ内で構成されている為に、AZ規模の障害には対応できないという点です。 簡単にメリット・デメリットを整理してみます。   メリット デメリット 複数AZ構成 ・AZ障害に耐えられる ・AZ間通信が必要な為、レスポンスが遅くなる可能性がある ※事前に実測することをお勧めします ・データ同期ソフトが必要 単一AZ構成 ・レスポンスが早い ・データ同期ソフトが不要 ・AZ障害に耐えられない このようにAZ障害に耐えられるか否かと、レスポンスがトレードオフの関係になっていることに注意してください。 いわば、下のイメージのように天秤のような関係性にあります。 レスポンスを重視すれば、高可用性が少し損なわれるといった具合です。 今回ご紹介した「AWS EBSマルチアタッチ機能」を用いてLifeKeeperのHAクラスタ構成を採用するシーンですが、 例えば、既存のオンプレ環境(共有ディスク構成)を、AWSにシフトしないといけない、AWS上での可用性も考慮しないといけないが、パフォーマンスが落ちることは許されない、と言ったパフォーマンスの要件が高いシステムにおける場面が想定されます。 まとめ 今回は、2024年12月12日にリリースされたLifeKeeper for Windows v8.10.2で強化されたポイントの一つである「Amazon EBSマルチアタッチ機能がサポートされた」点について解説しました。 これまでAZ間のデータ同期によるレスポンスの問題でAWSへの移行を躊躇していたシステムをお持ちのお客様にとって、今回のサポート追加はうれしいお知らせではないでしょうか。 従来の構成との、メリット・デメリットの違いを十分に理解した上で、そのシステムに最適な構成を選択してください。  
こんにちは。SCSKの磯野です。 Google Workspaceの監査ログは、保持期間が6か月程度のものがほとんどです。 例)SAML のログイベント データ:6か月 データの保持期間とタイムラグ - Google Workspace 管理者 ヘルプ レポート、セキュリティ調査ツール、監査と調査ページタイムラグにより、セキュリティ調査ツールと ページのレポートや検索結果で最新のデータが表示されない場合があります。また、ログイベント データは、利用できなくなる前に一定期間保持されます。 管... support.google.com しかし、社内ルール等で1年以上の監査ログ保管が義務付けられているようなケースは多いと思います。 今回は、Google Workspaceの監査ログの保持期間延長のために、Google Cloudへログを共有する方法をご紹介します。 基本的にはGoogle Workspaceの監査ログはGoogle Cloudと共有される 次のログイベント データが Google Cloud と共有されます。 Groups Enterprise のログイベント 管理ログイベント ユーザーのログイベント Enterprise Standard、Enterprise Plus、Education Standard または Education Plus、Voice Premier、Cloud Identity Premium Edition(※) をご利用の場合は、下記すべてのログイベントデータが Google Cloud と共有されます。 OAuth のログイベント SAML ログイベント アクセスの透明性に関するログイベント(Enterprise Plus と Education エディションのみ) Google Cloud サービスとデータを共有する - Google Workspace 管理者 ヘルプ 管理コンソールで、Google Workspace、Cloud Identity、Essentials アカウントのデータを組織の Google Cloud アカウントのサービスと共有できます。共有データには Google Cloud Au... support.google.com Google Cloudとの Google Workspace データの共有を有効 にすることで、Google Workspace の監査ログがGoogle Cloudへ共有されます。監査ログはログバケットに保管されるため、Google Workspaceの保持期間よりも長くログを保管することが可能です。 なお、監査ログを デフォルトの保持期間 より長く保持するには、 カスタム保持 を構成してください。 課題:Google WorkspaceプランによりGoogle Cloudに共有されないログも Business Standardプランなどの Google Cloud共有対象(※) 外のプラン を利用している場合、 SMALログイベント等の一部のログイベントはGoogle Cloudと共有されません。 課題へのアプローチ案 Business Standardプランなどの Google Cloud共有対象(※) 外のプラン を利用しており、SMALログイベントの保持期間を延長したい、といった場合はどのように保持期間を延長したらよいのでしょうか。 以下のようなアプローチが考えられます。 Google Workspaceの監査ログは特権管理者あるいはレポート管理者が「管理者コンソール画面>レポート」という画面より手動でログのダウンロードを行う Reports API  を使用してGoogleドライブへ転送するスクリプトを開発する Reports API  を使用してBigQueryへ転送するスクリプトを開発する 運用面や検索のしやすさの観点から、今回は3つ目の「BigQueryへ自動保管するスクリプトを開発する」方法について詳しく説明します。 Google Cloud共有対象のプラン(※)の場合 冒頭に記載した通り、Google Cloud との Google Workspace データの共有を有効にすることで Google Cloudへログの転送 が可能のため、個別のスクリプト開発は不要です。 なお、   Reports APIを使用してGoogle Workspaceの監査ログをBigQueryへ転送する 構成 日次で実行し、前日分の監査ログをBigQueryへ格納するCloudFunctionsを作成します。 例として、SAMLログを取得するコードを紹介します。 CloudFunctionsのコード 1度に取得するログは1000件以下を想定しています。 1000件以上のログが想定される場合はpageTokenの処理が必要です。 冪等性は加味していません。再実行すると重複してデータが格納されます。 from googleapiclient.discovery import build from oauth2client.service_account import ServiceAccountCredentials from flask import Flask, jsonify from google.cloud import bigquery import pandas as pd from datetime import datetime, timedelta import pytz app = Flask(__name__) def insert_into_bigquery(dataset_id, table_id, df): client = bigquery.Client() # データを挿入 job = client.load_table_from_dataframe(df, f"{dataset_id}.{table_id}") job.result() # Wait for the job to complete. @app.route('/', methods=['POST']) def get_gws_logs(request): # サービスアカウントの資格情報を取得 SERVICE_ACCOUNT_FILE = '/mnt/secrets/token.json' credentials = ServiceAccountCredentials.from_json_keyfile_name( SERVICE_ACCOUNT_FILE, scopes=['https://www.googleapis.com/auth/admin.reports.audit.readonly']) # Google Admin SDKのサービスオブジェクトを作成し、権限委任 # Google Workspaceの監査ログ閲覧権限のあるユーザー(特権管理者あるいはレポート管理者)のメールアドレスを使用する credentials = credentials.create_delegated('xxx@sample.com') service = build('admin', 'reports_v1',credentials=credentials) # 日本時間のタイムゾーンを設定 JST = pytz.timezone('Asia/Tokyo') now_jst = datetime.now(JST) # 前日の日付範囲を日本時間で設定 start_date_jst = now_jst - timedelta(days=1) start_time_jst = start_date_jst.replace(hour=0, minute=0, second=0, microsecond=0) end_time_jst = start_time_jst + timedelta(days=1) start_time = start_time_jst.isoformat() end_time = end_time_jst.isoformat() # SAMLログの取得 # https://developers.google.com/admin-sdk/reports/reference/rest/v1/activities/list?hl=ja results = service.activities().list( userKey='all', applicationName='saml', startTime=start_time, endTime=end_time ).execute() print(f"{start_time}から{end_time}までのログの取得が完了しました") if 'items' not in results or not results['items']: # 結果が空の場合 return jsonify({'status': 'success', 'message': 'No logs found for the previous day'}) data = [] for activity in results.get('items', []): for event in activity['events']: row = { 'date': activity['id']['time'], 'event_name': event['name'], 'description': event['type'], 'actor': activity['actor']['email'], 'application_name': next((param['value'] for param in event['parameters'] if param['name'] == 'application_name'), None), 'initiated_by': next((param['value'] for param in event['parameters'] if param['name'] == 'initiated_by'), None), 'failure_type': next((param['value'] for param in event['parameters'] if param['name'] == 'failure_type'), None), 'response_status': next((param['value'] for param in event['parameters'] if param['name'] == 'response_status'), None), 'second_level_status': next((param['value'] for param in event['parameters'] if param['name'] == 'second_level_status'), None), 'ip_address': activity.get('ipAddress') } data.append(row) df = pd.DataFrame(data) # 日付カラムをDATETIME型に変換し、日本時間に変換 df['date'] = pd.to_datetime(df['date']) df['date'] = df['date'].dt.tz_convert('Asia/Tokyo') #DATETIME型はタイムゾーンを考慮しないため、日本時間のままタイムゾーン情報を削除 df['date'] = df['date'].apply(lambda x: x.replace(tzinfo=None)) # データセットとテーブルの指定 dataset_id = 'xxx' table_id = 'xxx' insert_into_bigquery(dataset_id, table_id, df) return jsonify({'status': 'success', 'message': 'Logs inserted into BigQuery successfully'}) if __name__ == '__main__': app.run(debug=True)   デプロイ方法 サービスアカウントのキーはSecret Managerへ格納しています。Secret Managerの作成方法は以下の通り。 gcloud secrets create {secret名} gcloud secrets versions add {secret名} --data-file="./token.json" CloudFunctionsのデプロイ gcloud functions deploy {cloud functions名} \ --region=asia-northeast1 \ --runtime python310 \ --memory 512MB \ --gen2 \ --source=. \ --trigger-http \ --entry-point=get_gws_logs \ --service-account {サービスアカウント名} \ --set-secrets '/mnt/secrets/token.json={secret名}:latest' Cloud Schedulerのデプロイ(略) まとめ いかがだったでしょうか。 今回は、Reports APIを使用してGoogle Workspaceの監査ログをBigQueryへ転送する方法をご紹介しました。 本記事が皆様のお役に立てれば幸いです。  
SCSKの畑です。9回目の投稿です。 今回は、 6回目 のエントリで少し言及したアプリケーションの初期化処理について、詳細について記載してみます。 アーキテクチャ概要 そろそろ食傷気味かもしれませんがいつもの図を。今回はほとんどアプリケーション側の話題ですが、一部 Amazon Cognito 認証の話が出てきます。 背景 これまでのエントリで説明した通り、本アプリケーションではテーブルのステータス(編集状態)管理が重要となりますが、中でもステータスの初期化をどのタイミングで実施するかというのが特に重要となります。同エントリで言及した通り、ステータスをアプリケーションのルーティングや画面制御に使用するため、できる限り早いタイミングで初期化するのが実装上望ましいです。 このため、フレームワーク (Nuxt3) のライフサイクルを確認の上、具体的には Nuxt3 の Plugin 内で初期化するような方針としました。Nuxt3 を SSR で使用していることもあり、サーバサイドとクライアントサイド両方から実行され得るため、両対応した上でなるべく早いタイミングで実行できる方法として最適であると考えました。 aws-amplify における SSR 対応についても、公式ドキュメント内では Plugin を使用しているというのも判断材料の一つになりました。 https://nuxt.com/docs/guide/going-further/hooks 問題発生 ということで、この実装においてしばらく開発を続けていたのですが、アプリケーションにおける Cognito ユーザ/グループ権限周りの機能を実装し始めたタイミングで問題が発生しました。 同機能の動作確認を実施するにあたり、当然ながら複数のユーザでログイン/ログアウトを繰り返しながら画面を操作する必要があるため、一度ログアウトしてから別ユーザでログインしたところ・・ あれ、左ペインのメニューが空になっている。本来は赤枠部分にメンテナンス対象のテーブルが一覧表示されるはず・・ということでブラウザのコンソールを見てみたところ、以下のようなエラーが出ていました。(当時は開発真っ最中だったこともあり、エラー出力用の汎用コンポーネントなどはまだ用意していませんでした) UserUnAuthenticatedException: User needs to be authenticated to call this API. 見た通り、AppSync API が Unauthorized で叩けないというエラーで、これがステータス初期化関数内での AppSync API 実行時に出力されていたのが本事象の原因でした。ただ、ステータス初期化処理や Cognito 認証周りの実装は変更していなかったので、最初は何故こういうエラーが発生したのか分かりませんでした。 しかも、この画面でリロードすると正常に画面表示されるんですよね。そうだよね、実装変えてないんだから問題ないはずよね・・というところまで確認したところでようやく気づきました。 あ、Plugin 内でステータス初期化されるタイミングで、まだユーザが Cognito 認証されていないのでは、と・・ 2回目 のエントリで AppSync API の認可方式を説明した通り、本アプリケーションにおいては IAM を使用しています。では、この IAM 権限はどこから付与されるのかというと、Cognito ID プールの「認証されたアクセス」を通してとなります。つまり、当然ですが Cognito 未認証の時点(=未ログイン時点)ではこの AppSync API を叩ける権限が付与されていません。Plugin が実行されるタイミングは Nuxt.js のライフサイクルにおけるアプリケーションの作成時であり、Cognito の認証画面の表示前に実行されるため、上記のエラーが出力されたという流れになります。 Nuxt3入門(第7回) - Nuxt3のプラグイン・ミドルウェアを使う | 豆蔵デベロッパーサイト 前回はNuxt3のエラーハンドリングについて見てきました。今回はプラグインとミドルウェアを見ていきます。両方とも必須という訳ではありませんが、うまく使えばアプリケーション開発を効率化できます。プラグインはNuxtアプリケーション初期化時に実... developer.mamezou-tech.com ただ、アプリケーションの実装として plugin で初期化する考え自体は先般の通り間違っていないと考えていたため、未ログイン(未認証)の場合はログイン直後に初期化するようなロジックを追加しようと考えました。ログイン(認証)した状態でアプリケーションを使用することが前提である以上、ログイン直後のタイミングで初期化できていれば問題ないだろうという判断です。 2回目のエントリで記載したCognito ID プールのゲストアクセスを使用して、 ゲストアクセス経由で付与される IAM ロールにステータス初期化で使用する graphql query のみ許可するような IAM 権限を割り当てることで、未ログイン時でもステータス初期化を行えるようにする 、というのも今振り返ると一つの手ではあったと思います。ただ当時はそこまで発想が及ばなかったというのが正直なところです。 また、その場合は以下項目について考慮・検討しておく必要があったと考えています。 IAM ポリシーにおいて resource 句内の type や field を同クエリのみ許可するよう正確に設定する cognito 未認証(≒本アプリケーションを使用する権限の無いユーザも含む)がどこまでアプリケーション内部で情報を取得できてよいのかの検討 試行錯誤その1 ではログイン画面のロジックを変更して問題解決・・と一筋縄にはいきませんでした。理由は、ログイン画面の実装でお馴染みの Amplify UI モジュールを使用していたためです。こちらも改めて説明の必要がないくらいには便利なモジュールですが、自前で実装していない以上簡単に変更できない&変更できたとしてもモジュールを使用する以上保守の観点からソースコード自体を変更したくありませんでした。 そこで公式ドキュメントを改めて調べたところ、ログイン直後に任意の処理を実行するような「Override Function Calls」という機能がありました。正に今回のようなシチュエーションで欲しかった機能であり、さすがに広く使われているモジュールだなあと感心したのですが・・ https://ui.docs.amplify.aws/vue/connected-components/authenticator/customization この機能、私が試した限りでは Nuxt3 (Vue3) では動作しませんでした。。。 文字通り、対象の関数をオーバーライドするような仕組みだったので、動かした結果何かしらのエラーが出るのであればデバッグのしようもあるなと思ったのですがうんともすんとも言わず、ほぼサンプルコード通りの実装でも NG。同機能を使ってみたような事例自体は WEB 上からいくつか見つかったのですがほぼ Next.js (React ) だったので、ひょっとするとこれ Nuxt.js (Vue) で動作した実績が少ないのではないかと邪推して、この機能を使うのは一旦諦めました。 なお、本件について試行したのは数ヶ月前のことになるため、もし現時点で正常に動作するという情報をお持ちの方がいればご教示頂けますと幸いです。 試行錯誤その2 それでは仕方がないので、ログイン画面を自前で実装するしかないか・・とも考えたのですがこちらは割とすぐに諦めました。理由は明快で 、Amplify UI の作りというか機能性が単純に優れていたためです。 単純な Cognito の認証画面であれば作れると思っていたのですが、実際の認証フローを想定すると、メールアドレスの検証やパスワード変更・リセットのようなケースについても対応する必要があるため、それらの画面なりロジックを用意するとなると一から作るのはそれなりのコストがかかりそうだなと。元々ログイン画面は Amplify UI に任せるつもりで実装の計画を立てていたこともあり、 やはり公式のライブラリ/モジュールを使用しておくのがベターと判断しました。 解決 とは言え、先述の通り Amplify UI の機能で解決することもできそうにないし、どうしたものか・・ということで、一時は完全にスタックしていたのですが、方向性自体は先般の通り「ログイン直後のタイミングで初期化する」が正しいと考えていたため、それを実現するための方法をあれこれ考えた結果、最終的に以下のように解決することができました。 ログイン直後に実行したい処理を実行するための、画面なしページを用意 未ログイン時は必ず同ページにリダイレクトするように middleware でルーティング(ルートミドルウェアを使用) ログインして同ページ内の処理を実行後、トップページに遷移 まず前提として、Amplify UI & Nuxt3 (Vue3) における Cognito 認証は app.vue に以下のようなコードを実装することで実現しています。 <Authenticator> タグで囲われている要素が Cognito 認証されていないと見えなくなり、代わりにログイン画面が表示されます。以下実装例の場合は実質的にアプリケーション上の全ページ/コンポーネントが認証の対象となります。 そして、ログインに成功するとアクセスしている URL に対応したページに遷移するというような挙動となります。このため、少なくとも以下実装例においては、いわゆるログインページのような固有の URL パスは存在しません。 <template>   <Authenticator :hide-sign-up="true">       <NuxtLayout>           <NuxtPage />       </NuxtLayout>   </Authenticator> </template> <script setup lang="ts"> import { Authenticator } from "@aws-amplify/ui-vue"; import "@aws-amplify/ui-vue/styles.css"; </script> Authenticator | Amplify UI for Vue Authenticator component adds complete authentication flows to your application with minimal boilerplate. ui.docs.amplify.aws このため、未ログイン状態でも事実上全ての URL にアクセスすること自体はできてしまい、「ログイン直後に特定の処理を実行する」ような実装が難しい原因となっていたのですが、それを middleware を使用したルーティングにより解決することができました。同処理のためのページに画面は不要なので、そのままトップページにリダイレクトするような実装としています。 最後にそれぞれ実装例を示して本エントリを終わりたいと思います。 ログイン直後の処理実行用ページ (login.vue) 先述の通り、本ページにおける処理内容はシンプルです。updateTableStatusDict() でテーブルステータスの初期化を実施した後、実行後にトップページにリダイレクトするような処理となっています。なお、実案件事例では他情報の初期化なども合わせて実施していますが、説明のため省略します。 また、Nuxt3 の Layout で各ページのレイアウトを制御していますが、本ページにはメニューバーやナビゲーションバーのような共通表示コンポーネントも不要なため、専用レイアウトを適用して非表示としています。 <template></template> <script setup lang="ts"> definePageMeta({ layout: 'login' }) const { updateTableStatusDict } = useTableStatus() onMounted(async () => { await updateTableStatusDict() return navigateTo('/') }) </script> middleware によるルーティング (auth.global.ts) こちらも実装例に落とすと内容はシンプルです。ルートミドルウェアの定義が defineNuxtRouteMiddleware に対応します。引数の to が遷移先のルート(パス)、 from が遷移元のルート(パス)を示しており、他の情報(ユーザのアプリケーション権限や、テーブルのステータスなど)と組み合わせてルーティングの制御を行っています。 ただ、この短いコードの中で躓いたポイントが実は2つほどあったため、以下にまとめました。 Cognito ユーザ認証済みかどうかを直接確認するメソッドは aws-amplify/auth には存在しないようです。このため、未認証時に実行した場合例外がスローされるようなメソッド(以下実装例の場合は getCurrentUser())を実行し、その例外を catch することでユーザ認証済みかどうかの判定をしています。 error を catch した場合は Cognito ユーザ未認証のため、上記で説明したログイン直後の処理実行用ページに対応するルート(以下実装例の場合は /login)に遷移させたいのですが、ルートミドルウェアはページの遷移ごとに呼び出されるため、単純に実装すると未認証時のルーティングが無限ループしてしまいます。このため、遷移先が /login でない場合のみ遷移するようにすることで、無限ループを抑止しています。 export default defineNuxtRouteMiddleware( async(to, from) => {   try { if ( await useNuxtApp().$Amplify.Auth.getCurrentUser() ) {       // Cognitoログイン済みの場合       //// 以下、ユーザのアプリケーション権限に応じたルーティングを制御 //// }   } catch (error) {       // Cognito未ログインの場合       // ルーティングの無限ループを防ぐため、ログインページへの遷移は一度だけにする       if (to.path !== '/login') {           return navigateTo('/login')       }   } } まとめ 今振り返ると意外とあっさり解決したように思えるのですが、開発中はあれこれ思い悩んでいた記憶があります。一時は AppSync の認可方式から見直すことも考えていましたが、先述したような ID プールのゲストアクセスを使用する発想には至らず。最悪 Lambda に変更すれば力業でどうにかなるんじゃないかと思ったりもしましたが、さすがに筋が悪すぎであろうと言うことで結局脳内で却下しました。 というか、アプリケーション開発においてこういう話って正直あるあるというか、真っ先に考えておかないといけないことの一つではないかと思い至り、改めて私自身の開発経験不足を実感した次第です。 最終的に当初の方向性で解決策に辿りつけたこと自体は良かったと思うのですが、もっと精進したいですね。。 本投稿がどなたかの役に立てば幸いです。
本記事は 新人ブログマラソン2024 の記事です 。 こんにちは!SCSKの新人、黄です。 前回の記事では、Rubrikというバックアップデータ管理に特化したIT企業と、その主要製品や機能についてご紹介しました。 多くの方に読んでいただき、とても嬉しかったです! 「まだ読んでいない!」という方は、ぜひ以下の記事をご覧ください。 Rubrikとは?クラウド&オンプレにも対応する次世代バックアップ管理を紹介 – TechHarmony さて、今回は前回少し触れた「Rubrikのランサムウェア対策」をさらに掘り下げ、自分でも実際に試してみた結果を共有したいと思います。 それでは、さっそく始めましょう! はじめに ランサムウェアという言葉、きっと一度は耳にしたことがあるのではないでしょうか? データを暗号化し、その解除のために身代金を要求するサイバー攻撃で、ここ数年、その被害は世界中で広がり続けています。 これだけでも十分厄介ですが、実は 攻撃者の狙い は、通常のデータだけに留まりません。 なんと バックアップデータまで標的 にしているのです! 「バックアップがあれば安心」と考えるのは当然ですが、攻撃者たちはその油断をついてきます。 一例として、下記のような手口でバックアップを狙ってきます: バックアップデータの暗号化 バックアップデータを暗号化し、復旧を不可能にします。 バックアップデータの削除 大切なバックアップデータを削除し、復元手段を完全に奪います。 バックアップソフトの停止 バックアップ機能そのものを無効化します。 こうした脅威に対応するために、Rubrikは「保存するだけ」ではない多角的な対策を提案しています。 その詳細について、次の章で詳しく解説します。 Rubrikのランサムウェア対策の概要 Rubrikのランサムウェア対策には、主に三つのキーワードがあります: 不可変バックアップ ふるまい検知(異常検知) 脅威ハンティング(脅威追跡) 前回の記事では、不可変バックアップとふるまい検知・脅威ハンティングを並列に紹介しましたが、実際のところ、 不可変バックアップはRubrikのランサムウェア対策の「土台」 となる存在です。 不可変バックアップ:Rubrikが独自に開発したOSによって、データがRubrikに保存される際に 不変の形式でロック される仕組みです。 この仕組みにより、攻撃者がバックアップデータを改ざんしたり削除したりすることは物理的に不可能となります。 不可変バックアップにより、「バックアップが改ざんされるかも……」という不安を取り除き、安全にデータを保管することができます。 さらに、この仕組みがあるからこそ、Rubrikの ふるまい検知 や 脅威ハンティング が最大限に効果を発揮します。 ふるまい検知(Anomaly Detection) Rubrikのふるまい検知は、 メタデータ監視 と エントロピー解析 を組み合わせた多層的な仕組みで、ランサムウェア攻撃を早期に検知することができます。 では、「どうやって異常を検知するの?」その仕組みを詳しくご紹介します。 メタデータを活用した監視 まず最初に注目すべきポイントは、ふるまい検知がデータそのものではなく、 メタデータ を監視の対象としていることです。 メタデータ:ファイル名、ディレクトリ構造、サイズ、UUIDなどの情報を指します。 メタデータを活用することで、データそのものには触れずにプライバシーを保護しながら、正確な監視を実現します。 そして、Rubrikのふるまい検知では主に以下の方法で異常を見つけます: 機械学習で長期的な変更パターンの分析 Rubrikは、過去のバックアップデータをもとに、通常のデータ変更のパターンを学習します。そのパターンを超えるような突然の大規模な変化をキャッチする仕組みです。 たとえばこんな場合に検知します: 毎日数MB程度しか変更のないデータが、ある日突然数GBの変更を記録した場合。 「2025年度計画」というフォルダに10個のファイルが保存されていたのに、次のバックアップではそのフォルダが丸ごと消えていた場合。 これらのケースでは、「異常な変化」としてRubrikが警告を出します。 エントロピー解析による異常検知 しかし、メタデータだけを基にした異常検知には限界があります。例えば、 攻撃者の手口が巧妙だった場合 攻撃者がローカル環境でファイルを暗号化してからバックアップが行われた場合、メタデータには特に目立った変化が現れない。 利用者の行動による誤検知 正常な操作の一環として大量のファイルを追加した場合でも、異常と判断されてしまう。 このようなケースに対応するために、Rubrikは エントロピー を利用しています。 エントロピー:データのランダム性を表す指標です。データがどれくらいバラバラで規則性がないかを示します。 暗号化されたデータはランダム性が高まるという特徴を活かし、この変化をキャッチすることで、ランサムウェア攻撃の兆候を検知します。 例として: 攻撃前のファイル名:「顧客情報.xlsx」「見積書.pdf」 攻撃後のファイル名:「abc123.xyz」「xyz789.enc」 暗号化されたファイルの名前や構造が大きく変わると、エントロピーが急激に増加します。Rubrikはこの変化をいち早く検知し、警告を発することで早期対応を促します。 脅威ハンティング (Threat Hunting) 脅威ハンティング は YARAルール のような具体的な痕跡情報を基に、バックアップデータを詳細にスキャンし、 感染源や侵入時期を特定する 機能です。 ふるまい検知との違い: ふるまい検知 :機械学習を活用してバックアップデータの変更パターンを分析し、 ランサムウェア攻撃後 に発生する異常(大量の変更や暗号化)を検知する。 脅威ハンティング :具体的な痕跡情報を基に、 攻撃を受けたかどうかに関係なく 、感染源やランサムウェアの侵入時期をチェックする。 脅威ハンティングでは、以下のプロセスでバックアップデータを解析します: 痕跡情報を入力 まず、ランサムウェアに関連する YARAルール を入力します。 YARAルールとは、攻撃者が使用する特定の暗号化方法や拡張子(例:「.encrypted」や「.lock」)を検出するためのルールセットです。 もしご興味があれば、下記のドキュメントをご参照ください。(おそらく英語版のみですが、ご参考になるかと思います。) Welcome to YARA’s documentation! — yara 4.5.0 documentation ユーザーが自身で入力する必要がありますが、RubrikはあらかじめデフォルトのYARAルールも提供しており、初めての方でもスムーズに利用を開始できます。 バックアップデータを照合 次に、Rubrikが入力された情報を基にバックアップデータをスキャンします。例えば以下のようなことをチェックします: 特定のファイルやフォルダが存在していないか。 ランサムウェアによる暗号化の痕跡がないか。 感染システムの特定 スキャンが完了すると、もしランサムウェアが侵入していた場合、その 侵入タイミング や 感染したシステム が特定されます。 これにより、問題が発生した箇所やその影響範囲が明確になり、適切な対策を講じやすくなります。 Rubrikのランサムウェア対策を実際に試してみた これまでRubrikのランサムウェア対策についてご紹介してきましたが、「実際にどのように動くのか?」と思った方も多いのではないでしょうか? 今回は、その仕組みを確かめるために、 ふるまい検知 を使ったシミュレーション を行いました。 Rubrikはオンプレミス環境だけでなく、AWSやGoogle Cloud、vSphereなど、さまざまなクラウド環境に対応していますが、 今回はその中でも vSphereの仮想マシン を使用して実験を行いました。その様子をぜひご覧ください! シミュレーション方法 Rubrikのふるまい検知は、 大量のファイル追加や暗号化などの異常な動き を検知する仕組みなので、 今回のシミュレーションでは、以下の手順で検証を進めました。   目的 手順 1 正常時の状態取得 正常なバックアップデータを複数回取得し、RSC(Rubrik Security Cloud)に連携する。 2 ランサムウェア攻撃の再現 仮想マシン内で大量のファイルを追加し、それらを暗号化する。 3 異常検知の確認 再度バックアップを取得し、RSCでどのように検知されるかを確認する。 シミュレーション結果 正常時の状態取得 まずは、バックアップデータの長期的なパターンを学習できるように、正常な状態のバックアップデータを 5回分 取得しました。 これらのデータはRSC上にも反映されており、Rubrikはこれらをもとに機械学習で 通常の動き を学習します。 以下の図は、正常時のバックアップがどのように記録されているかを示しています: ランサムウェア攻撃の再現 次に、仮想マシン内で大量のファイルを追加し、それらを暗号化しました。 以下の図にある 「xxxxx.encrypted」 のようなファイルは、暗号化されたことを示しています: その後、もう一度バックアップを取得し、Rubrikがどのように反応するかを確認しました。 異常検知の確認 結果は期待通りでした! 大量のファイル変更や暗号化 を素早く感知し、異常として Event に記録しました。 以下の図のように、 Event Timeline に、今回の変更内容( 5003件の追加、17件の変更、2件の削除 )が詳細に記録されています: また、RSCではふるまい検知の結果が下の図のように、可視化されて表示されます。 便利なのは、 Anomaliesセクション を見るだけで、過去24時間以内に 1件の異常 が検知されていることを簡単に確認できます! さらに、そのAnomaliesをクリックすることで、 どの機器のどのフォルダ内のどのファイルが影響を受けたのか まで特定することができました。 最後にメールを確認すると、検知アラートが届いていました。便利で、状況をすぐに把握することができました。 最後に 今回の記事では、Rubrikのランサムウェア対策について、仕組みの解説とシミュレーションの結果を交えながらお届けしました。「ふるまい検知」と「脅威ハンティング」の2つの対策が、ランサムウェア攻撃にどう役立つのか、少しでもお伝えできていれば嬉しいです! 特にシミュレーションを通じて、ふるまい検知がいかに迅速かつ正確に異常を発見できるか、その便利さを感じていただけたでしょうか? 今回は脅威ハンティングのシミュレーションまではできませんでしたが、気になる方はぜひ試してみてください。 最後まで読んでいただき、ありがとうございました!
本記事は、「 AWS User Notifications で EC2 の AWS Health イベントを通知してみた! 」の続編となります。 前回の記事で実装したAWS User Notificationsをテストするため、AWS Health イベントを発生させ、Eメールで通知が届くことを確認したいと思います。 実施内容 概要 以下の内容でテストを実施します。 EC2に関するAWS Health イベントを発生させる EC2に関するAWS Health イベントがEメールで通知されることを確認する それでは早速ですが、実際にテストしていきましょう!! 1. EC2に関するAWS Health イベントを発生させる AWS Healthテストイベントを発生させたい場合は、AWSサポートにリクエストすることができます。 ※リクエストをするためには、デベロッパー、ビジネスまたはエンタープライズサポートプランに加入している必要があります。 ※本記事はAWS User Notificationsをテストを目的としているため、AWSサポートへのリクエストの詳細な手順については割愛いたします。リクエストを行う場合は、以下リンクをご確認いただき実施することをおすすめします。 テスト用の AWS Health イベントをリクエストする AWS Health イベントを使用して AWS Health との統合をテストしたいと思います。 repost.aws 今回は、以下のAWS Health イベントをAWSサポートにリクエストしました。 リージョン東京リージョン: ap-northeast-1 イベントタイプのカテゴリー: accountNotification イベントタイプのコード: AWS_EC2_OPERATIONAL_NOTIFICATION EC2のサービスに問題がある場合に発生するイベントを指定しています。 どのようなイベントタイプがあるのかについては、「 AWS User Notifications で EC2 の AWS Health イベントを通知してみた! 」の事前確認で紹介したAWS Health APIで確認することが可能です。 2.EC2に関するAWS Health イベントがEメールで通知されることを確認する AWSサポートへのリクエスト時に、テストイベントを作成させたい日時を指定したので、指定した時間にAWS Health イベントが発生していることを確認します。 ※テストイベントを作成させたいイベントの日時は、希望の日時での対応を約束するものではないため、テストイベントの発行まで最大3営業日かかることがあるようです。 指定した日時に以下のようなメールを受信しました。こちらで問題なく、AWS User Notificationsが設定できていることが確認できました。 ちなみに、コンソールからもAWS Health イベントを確認することができます。 まとめ AWS Healthイベントを利用することで以下のようなメリットを得ることができます。 障害発生時の切り分けを素早く行うことができる 障害やメンテナンスの通知を受け取ることで、準備や対処ができる サービスの可用性を高めることができる さらにAWS User Notificationsを利用して通知機能を実装することで、比較的容易に設定することが可能だと思います。 皆さんもAWS User Notificationsを利用したAWS Health イベントの実装をしてみるのはいかがでしょうか。 皆様のお役に立ちましたら、嬉しいです。 最後までお読みいただきありがとうございました。
ServiceNowのUI Builderを触る機会があったため、一部ですがその機能を紹介させていただきます。 本記事は執筆時点(2025年1月)の情報です。最新の情報は製品ドキュメントを参考にしてください。 UI Builderとは UI Builderとは、ワークスペースなどのユーザーインターフェースを作成することができるローコードツールです。 様々な種類のコンポーネントが標準で用意されており、これらを使用してレイアウトやスタイリング、インスタンス内に蓄積されたデータを可視化することで、各ユーザーに対してパーソナライズされたエクスペリエンスを提供することができます。 実際に触ってみる レイアウト UI Builderで画面を作る際は、まずレイアウトを決めて、コンポーネントを配置していく流れとなります。 画像のようにフレキシブルにレイアウトを設定することが可能です。   データの可視化 ServiceNow上に蓄積されたトランザクションデータを視覚的に分かりやすくユーザーに対して表示することができます。 画像のように自分にアサインされたタスク、今週期限のインシデント対応状況など、各ペルソナの目的に応じて柔軟に可視化することができます。(ログインしているユーザーにより、値は動的に変化します) ログイン後の最初の画面で表示すれば、ユーザーは瞬時に自身、自身が所属するグループのタスク状況を把握することができます。 また、画面をクリックすることで対象のレコードに遷移することも可能です。   メニュー・リスト 自由にメニューを設定できます。各ペルソナが業務を遂行する上で必要なテーブルのみをメニューとして用意すれば、より効率的に作業を進めることができそうです。 インスタンスにログインした際に画面左に表示されるアプリケーションナビゲーターでは、閲覧権限のあるモジュールが全て表示されるので、目的のモジュールの場所が覚えられない、検索するのが大変といった場合に活用できそうと思いました。 カレンダー カレンダー形式で自身のタスクを管理することが可能です。 画像では自身のタスクについて、起票日から対応期限までを帯としてカレンダー表示させています。   サポートセンター的なページを作成してみる 標準で用意されているコンポーネントを使用するだけなので、30分程度で簡単に作成することができました。 ・画面上部 マニュアルをツリー形式で表示しています。リンクをクリックすると外部URLに遷移できます。 ・画面中央 ServiceNow上に作成されたナレッジ記事をFAQとして一覧表示しました。ボタンをクリックすることでナレッジ記事を閲覧できます。 ・画面下部 問合せフォームを表示しています。マニュアルやFAQで解決しない場合にサポートへ問合せすることができます。 感想 今回記事にしたのは一部のコンポーネントのみであり、他にも沢山の機能が用意されています。(数えてみると約150個ありました) 企業内でServiceNowを使用していく際、様々なペルソナが登場します。各々が見たい情報や業務の遂行に必要な機能を一つの画面に表示するなどなど、パーソナライズされたエクスペリエンスをユーザーに提供できることが利点と思いました。 ServiceNow ServiceNowは、企業の生産性向上や業務プロセス改善を支えるサービスマネジメントクラウドソリューションです。従業員満足度・顧客満足度の向上、業務効率化を強力に支援します。 www.scsk.jp
こんにちは、広野です。 AWS AppSync は Amazon API Gateway と同様に API を公開してくれるサービスですが、必ず何かしらの認証がないと動かないサービスです。私は Amazon Cognito 認証を使用することが多いのですが、Amazon Cognito で認証されたユーザーであれば誰でも実行できるクエリもあれば、例えば管理者のみに実行させたいクエリもあります。 そんなときに Amazon Cognito ユーザーの属性としてグループがあり、それを拠り所にして権限を分ける方法が最も簡易です。AWS IAM ロールを使用した方法も実装可能だと思いますが、IAM ロールをグループごとに用意しないといけないので面倒です。 今回は、AWS AppSync Lambda リゾルバ (JavaScript) の標準的な書き方説明も兼ねて、権限分けの書き方も紹介したいと思います。ちなみに本件は AWS 公式ドキュメントでは以下のページが関連します。 AWS AppSync JavaScript リゾルバーの概要 - AWS AppSync AWS AppSync の JavaScript リゾルバーの概要 docs.aws.amazon.com リクエストとレスポンスを保護するためのアクセスコントロールのユースケース - AWS AppSync AWS AppSync の承認シナリオ。 docs.aws.amazon.com サンプルアーキテクチャ 以下の構成例で紹介します。主に緑色の線の部分にフォーカスします。 AWS AppSync は Amazon Cognito 認証です。基本的に、Amazon Cognito 認証を受けたユーザーは AWS AppSync にアクセスできる構成です。 AWS AppSync に Lambda リゾルバを作成し、AWS Lambda 関数を関連付けます。 AWS Lambda 関数は、Amazon Cognito ユーザーのリストを取得します。 AWS AppSync では、データベースへの読み書きは AWS Lambda 関数抜きで基本的なことはできるので、AWS Lambda 関数を使用する機会が少ないです。そして、AWS Lambda 関数が無い方がレスポンスが速くなります。なので、AWS Lambda 関数を使用する例として Amazon Cognito ユーザーのリストを取得することを採用しています。 この例のように Amazon Cognito のユーザーリストを取得して良い人は、一般的には管理者に限られているはずです。そのため、この Lambda リゾルバは管理者用の Amazon Cognito グループに所属している人でないと実行できないようにしたいです。 実装するもの 権限関連設定について少しブレークダウンして説明します。 まず、アプリ側では、管理者以外に見せたくない画面は表示させないようにします。アプリ内で Amazon Cognito ユーザーの属性は取得できるので、Cognito グループ属性をもとに表示する/しないを判別させます。 ただし、それはあくまでもアプリによる表面的な表示制御だけです。ユーザーに無用な API アクセスをさせないためだけの。AWS AppSync に何らかの形で直接命令が来てしまったときは許可してしまうので、AWS AppSync 側でも Cognito グループによる実行制御を入れます。Lambda リゾルバ内で Amazon Cognito 認証に使用されたトークンの内容を取得できるので、それをもとに判別します。AWS Lambda 関数を呼び出す前にリゾルバ内で処理します。 アプリ側の画面表示制御 本記事の本題ではないですが、一応 React アプリを例としてコードを載せます。 前提として、以下の記事で紹介しているような React アプリから AWS AppSync に Amazon Cognito 認証でアクセスする設定が済んでいることとします。 AWS AppSync のリゾルバ内で Amazon Cognito ユーザーの email 属性やカスタム属性を取得する AWS Lambda 関数を使用せずに実現する方法がわかったので紹介します。 blog.usize-tech.com 2025.01.08 まず、React アプリ内で Amazon Cognito の属性情報は以下のコードで取得できます。書き方はいろいろあるので、一例です。 //必要モジュールインポート import { fetchAuthSession } from 'aws-amplify/auth'; //state初期化 const [email, setEmail] = useState(); //ユーザーのメールアドレス const [authToken, setAuthToken] = useState(); //ユーザーのトークン const [groups, setGroups] = useState(); //ユーザーのCognitoグループ //セッション情報取得 const getSession = async () => { const { tokens } = await fetchAuthSession(); setEmail(tokens?.idToken?.payload.email); //メールアドレスはこれで取得 setGroups(tokens?.idToken?.payload["cognito:groups"]); //Cognitoグループはこれで取得 setAuthToken(tokens?.idToken?.toString()); //IDトークンはこれで取得 }; useEffect(() => { getSession(); }, []); こうして取得した groups の中にユーザーが所属する Cognito グループが配列で格納されているので、(複数所属している可能性もあるので) この情報を活用して該当の画面を表示/非表示を制御できます。 例えば、管理者用のグループ名が ADMIN だったとすると、シンプルに以下のように書きます。メニュー画面のうち、管理者用画面へのリンクを表示制御する例です。groups に ADMIN が含まれているかどうかを条件にしています。 {/* ホーム画面ボタン */} <Button to="/" onClick={handleCloseNavMenu} component={Link} sx={{mr:2,color:"white",display:"block"}}>ホーム</Button> {/* 設定メニューボタン */} <Button to="/config" onClick={handleCloseNavMenu} component={Link} sx={{mr:2,color:"white",display:"block"}}>設定</Button> {/* Adminメニューボタン */} {(groups.includes("ADMIN")) && ( <Button to="/admin" onClick={handleCloseNavMenu} component={Link} sx={{mr:2,color:"white",display:"block"}}>Admin</Button> )} {/* サインアウトボタン */} <Button onClick={signOut} sx={{mr:2,color:"white",display:"block"}}>サインアウト</Button> もちろん、リンク先のパスを知られていたら意味がないので、リンク先の方でも画面全体に同様の表示制御条件をかけます。 管理者用画面では、Amazon Cognito ユーザーリストを取得するためのクエリを書きます。 ここで、想定するリクエストとレスポンスの書式を整理します。 以降、このデータ授受をする前提で AWS AppSync の設定を書きます。 AWS AppSync の設定 スキーマ 必要な箇所を抜粋します。 schema { query: Query mutation: Mutation subscription: Subscription } type CognitoUsersItems { id: Int email: String createddate: String status: String } type CognitoUsers { items: [CognitoUsersItems] } type Query { queryListCognitoUsers(dummy: String!): CognitoUsers } リクエストで dummy というパラメータを渡すので、Query の定義に入れています。 レスポンスは items というキーで配列を格納する階層構造になっているので、それを表現しています。 データソース AWS AppSync の Lambda リゾルバを使用する場合、データソースのタイプを Lambda にする必要があります。データソースの設定で、関連付ける AWS Lambda 関数や、その AWS Lambda 関数を呼び出せる権限 (IAM ロール) を設定します。この詳細は割愛します。 Lambda リゾルバ リゾルバの設定で、データソースを上述のものを指定します。これにより、そのリゾルバがデータソースで設定された AWS Lambda 関数と連携できるようになります。記事の本題の1つでもある、このリゾルバの書き方を説明します。 JavaScript リゾルバでは、マッピングテンプレートのリクエスト、レスポンスは 1 つの JavaScript コードの中で表現します。VTL ではそれぞれが分かれていましたが。 今回のリクエスト、レスポンス仕様を実現すると、以下のコードになります。 //リゾルバ内で使用可能なユーティリティ関数をインポート import { util } from '@aws-appsync/utils'; //リクエストマッピングテンプレート export function request(ctx) { //ctx の中にアプリから渡された引数(args)やヘッダー情報が格納される const groups = ctx.identity.claims['cognito:groups'] //ここで、トークンに格納された Cognito グループを取得 if (groups.indexOf('ADMIN') === -1) { //Cognitoグループに ADMIN が含まれているかチェック util.unauthorized(); //ADMIN が含まれていなければ、認証エラーとして返す } else { return { operation: 'Invoke', //Lambda関数を呼び出すオペレーション定義 payload: { ctx.args //Lambda関数に渡すペイロード、ここではアプリからもらった値(dummy)をパススルーする } }; } } //レスポンスマッピングテンプレート export function response(ctx) { //ctx の中にLambda関数のレスポンスが格納される if (ctx.error) { util.error(ctx.error.message, ctx.error.type); //レスポンスにエラーが含まれていればエラーで終了させる } return ctx.result; //Lambda関数から return で返した値は ctx.result に格納される、ここではそのまま AppSync にパススルーする } ctx.identity.claims[‘cognito:groups’] に格納されているグループ名の配列に ADMIN が含まれているかチェックするのに includes を使用したいところですが、JavaScript リゾルバではサポートされていないので、代わりに indexOf を使用しています。JavaScript の機能は何でもリゾルバ内で使えるかと言うと全然そうではなくて、かなり限定されているので注意が必要です。 リゾルバーおよび関数の AWS AppSync JavaScript ランタイム機能 - AWS AppSync AWS AppSync の JavaScript リゾルバーユーティリティヘルパーについて説明します。 docs.aws.amazon.com このリゾルバ構成は、結構標準的に使えるのではないかと考えています。 AWS Lambda 関数 リゾルバから呼び出された AWS Lambda 関数は、AWS AppSync 経由でアプリから渡された引数 (ここでは dummy の値) を取得できます。コード内では表現していませんが、本記事のリクエスト仕様では、event[‘dummy’] で “dummy” を取得できます。 また、レスポンスとして想定しているフォーマットでレスポンスを返すよう、書いたものが以下のコードになります。Python です。 Amazon Cognito ユーザープール ID は環境変数にしています。IAM ロールは割愛します。 import json import boto3 import os LIMIT = 60 # Amazon Cognito の list_users は最大60件しか一度にデータを取得できない USER_POOL_ID = os.environ['CognitoUserPoolID'] client = boto3.client('cognito-idp') def lambda_handler(event, context): try: response = client.list_users( UserPoolId=USER_POOL_ID, AttributesToGet=['email'], Limit=LIMIT ) user_records = response['Users'] while True: # PaginationToken が無くなるまで(データを全て取得するまで)データ取得処理を繰り返す if 'PaginationToken' not in response: break # PagenationToken がある限り、データを取得する response = client.list_users( UserPoolId=USER_POOL_ID, AttributesToGet=['email'], Limit=LIMIT, PaginationToken=response['PaginationToken'] ) user_records.extend(response['Users']) # user_records に最終的に全データが格納される except Exception as e: print(e) reserr = { "items": [ { "id": 0, "email": "Error", "createddate": None, "status": "Error" } ] } return reserr # エラー発生時はエラー用のレスポンスを AppSync に返す else: output = [] # Amazon Cognito から返ってきた生データを、必要なデータだけ抽出する for i, row in enumerate(user_records): transformed = { "id": i, "email": next(attr["Value"] for attr in row["Attributes"] if attr["Name"] == "email"), "createddate": str(row["UserCreateDate"]), "status": row["UserStatus"] } output.append(transformed) return { "items": output # 抽出したデータ(配列)を items に格納して AppSync に返す } 最後、return で items を返しています。これが、AWS AppSync をパススルーしてアプリに返ってきます。 アプリ側の AppSync クエリ実行 アプリ側では、上述のレスポンスを取得するためのクエリを実行します。本記事のシナリオでは、管理者用画面で実行するものです。 AWS AppSync スキーマの仕様に合わせて記述します。前述のスキーマ設定と照らし合わせるとわかりやすいと思います。記述箇所が離れててすみません。リクエスト、レスポンスのデータ定義がスキーマの仕様と少しでも合わないとエラーになります。厄介です。 //AppSync呼出用モジュールインポート import { generateClient } from 'aws-amplify/api'; import gql from 'graphql-tag'; //AppSync Client const client = generateClient(); //Cognitoユーザーリスト取得関数 const listCognitoUsers = async () => { const queryListCognitoUsers = gql` query queryListCognitoUsers($dummy: String!) { queryListCognitoUsers(dummy: $dummy) { items { id email createddate status } } } `; const res = await client.graphql({ query: queryListCognitoUsers, variables: { dummy: 'dummy' //dummyをAppSyncに渡す(本記事の説明用途で) } }); return res.data.queryListCognitoUsers.items; //AppSyncからのレスポンスは、data.Query名に格納される }; この listCognitoUsers 関数で、アプリから Amazon Cognito ユーザーのリストを配列で取得できます。フォーマットは必要情報を抽出したものになっていますが。 まとめ いかがでしたでしょうか。 アプリ、AWS AppSync、AWS Lambda 関数の間でデータを授受する仕様が理解できるのではないかと思います。同時に、Amazon Cognito グループによるリゾルバの実行制御を簡易に仕掛けることができています。 本記事が皆様のお役に立てれば幸いです。
本記事は 新人ブログマラソン2024 の記事です 。 皆さんこんにちは!入社して間もない新米エンジニアの佐々木です。 前回、前々回と2回に渡って、Snowflake CortexAIを使ってドキュメント検索アシスタントを構築するチュートリアルに挑戦し、その様子を記事にまとめさせていただきました。多くの方々に読んでいただき、大変嬉しく思っています。 まだ読めていないという方は、以下の記事をまずは読んでいただけると幸いです!! 新米エンジニアが挑む!Snowflake CortexAIでドキュメント検索アシスタントを構築してみる – TechHarmony 新米エンジニアが挑む!Snowflake CortexAIでドキュメント検索アシスタントを構築してみる【チャットボットバージョン】 – TechHarmony さて今回の記事は、ようやくこのチュートリアルの 最終話 となります。最終話の立ち位置としては、前回までの内容にオプション機能を追加するライトな内容となります! 具体的には、前回まででチャットボットバージョンのドキュメント検索アシスタントの構築が完了したため、今回は 新しいドキュメントの自動処理 に踏み込んでみたいと思います。 それでは早速行きましょう!! 前回までの振り返り 前回、前々回と以下の公式チュートリアルをハンズオン形式で実践し、 Snowflake Cortex AIのベクトル埋め込み機能を利用して、ドキュメント検索アシスタントを構築 しました! Build A Document Search Assistant using Vector Embeddings in Cortex AI 特に前回は、前々回の内容にプラスして より高度なチャットボットバージョンのドキュメント検索アシスタントの構築 をしました! 具体的なStreamlitのコード解説が気になる方は前回の記事を参照していただきたいのですが、最終的には以下のようなアプリを構築することができました! 上記を見てわかる通り、 ユーザーとの会話内容を記憶して、チャットボットのように会話できるアプリ となっています。 なぜこのようなチャットのような会話が実現できるのかについて簡単に説明します。 まず、ユーザーが質問を投げかけると予めSnowflake上に格納されたドキュメントをもとにLLMが回答を作成(RAG)し応答します。このとき、ユーザーの質問と作成された回答をペアとしてStreamlitのセッション領域に一時的に格納します。 次に、ユーザーが続いて質問をすると、セッションに格納した チャット履歴と質問内容を組み合わせて要約された内容がLLMに渡され、回答作成および応答するという仕組みです。 これにより、前回の会話内容を記憶した会話形式が実現できるわけです。 大雑把な説明とはなってしまいましたが、詳細が気になる方は前回の記事をぜひご覧ください!! 今回実施するチュートリアルの概要 前回実施したチュートリアルでは前述したとおり、ユーザーとの会話内容を記憶して、チャットボットのように会話できるアプリを構築しました。 ここまでの内容でドキュメント検索アシスタントの9割以上は構築完了しているのですが、1つだけ不便な点があります。 それは 新しいドキュメントを追加したいとき です。 現状だと、Snowflakeのステージ上に新しいドキュメントを追加しただけでは、RAGで検索対象のドキュメントとはなりません。なぜなら、ドキュメントを検索する際にはステージ上のドキュメントそのものを参照するのではなく、ドキュメントのチャンクが格納された独自のテーブル(docs_chunk_table)を参照するためです。このようにしている理由は、検索効率を向上させるためです。 つまり、現状だと新しいドキュメントをRAGの検索対象にしたいのであれば、ドキュメントをもとに分割されたチャンクをdocs_chunk_tableにinsertするコマンドを手動で実行しなくてはならないという不便さがあります。 そこで、より快適な運用に向けて 新しいドキュメントを自動処理する仕組みを構築 していきたいと思います! 実際に挑戦してみた!! ワークロード定義 新しいドキュメントの自動処理を実現するために、今回はSnowflakeの ストリーム と タスク という2つを用います! 早速ですが、Snowflakeワークシートで以下のコードを実行します。 create or replace stream docs_stream on stage docs ; create or replace task task_extract_chunk_vec_from_pdf warehouse = COMPUTE_WH schedule = '1 minute' when system$stream_has_data ( 'docs_stream' ) as insert into docs_chunks_table ( relative_path , size , file_url , scoped_file_url , chunk , chunk_vec ) select relative_path , size , file_url , build_scoped_file_url ( @docs , relative_path ) as scoped_file_url , func . chunk as chunk , SNOWFLAKE . CORTEX . EMBED_TEXT_768 ( 'e5-base-v2' , chunk ) as chunk_vec from docs_stream , TABLE ( pdf_text_chunker ( build_scoped_file_url ( @docs , relative_path ))) as func ; alter task task_extract_chunk_vec_from_pdf resume ; 上記のコードについて補足説明をします。 コード全体としては、 新しいPDFファイルがステージに追加されるたびに、自動的にテキストチャンクを抽出し、埋め込みベクトルを生成するというワークロードを定義しています。 では具体的に、各行がどのような処理を行っているのかについて触れていきます。 1行目: create or replace stream docs_stream on stage docs ; docs_streamという名前のストリームを新たに作成しています。 ストリームは、テーブル、ビュー、またはスキーマに加えられたDML変更(挿入、更新、削除)の変更履歴を記録する役割を持ちます。これにより、新しいPDFファイルがdocsステージに追加されると、docs_streamはこれらの変更を記録することができます。 3行目: create or replace task task_extract_chunk_vec_from_pdf task_extract_chunk_vec_from_pdfという名前のタスクを作成しています。 タスクは、SQLステートメント(クエリ、DML操作、ストアドプロシージャの実行など)を自動的に実行するようにスケジュールできるデータベースオブジェクトです。 4行目~6行目: warehouse = XS_WH schedule = '1 minute' when system$stream_has_data ( 'docs_stream' ) 上記タスクを実行するウェアハウス、頻度、条件を定義しています。 具体的には以下の定義です。 ウェアハウス:COMPUTE_WH 頻度: 毎分 条件:docs_streamストリームに新しいレコードがある場合に実行 9行目~19行目: insert into docs_chunks_table ( relative_path , size , file_url , scoped_file_url , chunk , chunk_vec ) ・・・ タスクで実行するSQLステートメントを定義しています。 具体的には、docs_chunks_tableテーブルにデータを挿入するクエリを定義しています。テーブルには、ファイルパス、サイズ、URL、チャンクテキスト、そして埋め込みベクトルなどの情報が格納されます。 21行目: alter task task_extract_chunk_vec_from_pdf resume ; タスクを再開するための処理です。 タスクは手動停止やエラー発生時など様々な理由で一時停止状態になることがあります。そのため、一時停止状態のタスクを再開し、スケジュールされた通り、またはトリガー条件が満たされたときに実行されるようにできます。 検証 では実際に新しいドキュメントをステージ上にアップロードすることで、自動的にタスクが実行されるかについて確認してみましょう! 具体的には、ドキュメントをアップロードする前と後の状態でドキュメントに関連する質問を投げかけ、的確な回答が返ってくるか否かを確認してみます。想定としては、ドキュメントをアップロードする前の状態だと的確な回答が返ってこないのに対して、アップロードした後の状態だと的確な回答が返ってくるはずです。 では実際にアップロードするドキュメントについてですが、今回は公式チュートリアルから拝借した「The_Xtreme_Road_Bike_105_SL.pdf」というエクストリームロードバイクに関するPDFファイルを使用したいと思います。 そして、このドキュメントに関連する「Is there any discount for the Xtreme Road Bike?(エクストリームロードバイクの割引はありますか?)」という質問をチャットで投げかけてみたいと思います。 ドキュメントアップロード前 まずは、ドキュメントをアップロードする前の状態でチャットに質問を投げかけてみます。 投げかけた結果、以下のような回答が返されました。 上記のチャット内容を日本語に訳すと以下の通りです。ここで、黒文字が質問、赤文字が回答となります。 エクストリームロードバイクの割引はありますか? エクストリーム・ロードバイクの割引情報はありません。最も正確で最新の価格情報については、メーカーのウェブサイトを確認するか、カスタマーサービスに問い合わせることをお勧めします。 上記の通り、ドキュメントアップロード前では、ドキュメントに関するユーザーの質問に対して適切な回答を返せていないことがわかります。 ドキュメントアップロード後 次に、ドキュメントをアップロードした前の状態でチャットに質問を投げかけてみます。 投げかけた結果、以下のような回答が返されました。 上記のチャット内容を日本語に訳すと以下の通りです。ここで、黒文字が質問、赤文字が回答となります。 エクストリームロードバイクの割引はありますか? はい、割引の話があります。自分のサドルを持参すると100ドル割引になります。 上記の通り、ドキュメントアップロード後では、ドキュメントに関するユーザーの質問に対して割引額も含めた適切な回答が返せていることがわかります。 つまり、新しいドキュメントをステージ上にアップロードするだけで、自動的にドキュメントのチャンク分割やテーブル挿入、そして結果的にRAGの検索対象にできていると言えます! まとめ 本記事では、前回の記事までで作成したチャットボットUIに対して、 新たなドキュメントを自動処理するためのワークフローについて解説 しました。 従来、ドキュメントの検索や分析には、手動でのアップロードやインデックス作成が必要で、時間と労力を要していました。しかし、Snowflakeが提供するストリームやタスクの機能を使うことで、これらのプロセスを自動化できることが分かりました! これにより、迅速な情報検索が可能になり、業務効率の大幅な向上が期待できるというメリットがあります。 さらに、様々なファイル形式に対応しているため、様々な種類のドキュメントを統一的に管理・検索できる点も大きなメリットだと考えられます。そのため、大量のドキュメントを扱う企業にとって、この機能は業務効率化の強力なツールとなるでしょう。 ぜひ、前回、前々回で紹介したCortexAIを用いたドキュメント検索アシスタント、本記事で紹介したドキュメントの自動処理機能を参考にして、RAGシステムの構築や情報検索の効率化に活かしてみてください!
こんにちは、SCSK株式会社の嶋谷です。2024年度入社の新入社員です。 現在私は、AIプラットフォームやWebサーバ・監視サーバの構築といったインフラ基盤の構築業務に携わっています。 今回は、Docker上に構築したAIプラットフォーム基盤をMackerelで監視してみたいと思います。 Mackerelとは Mackerelは、株式会社はてなが提供するSaaS型の監視ツールです。 サーバの状態(CPUやメモリ)を監視し、事前に設定された閾値を超えたときにオペレータや管理者に通知を行うことができるツールです。加えて、オンプレミス環境だけでなくクラウド環境やコンテナ環境も監視することができます。 Mackerelの詳細情報については、下記リンクをご参照ください。 Mackerel(マカレル): 始めやすくて奥深い、可観測性プラットフォーム Mackerel(マカレル)は誰でも簡単に始めやすく奥深い可観測性プラットフォーム。運用をイージーにするオブザーバビリティを高め、未知の問題に立ち向かう開発者に力を与えます。サーバー監視をMackerelではじめてみませんか?無料プランや2... ja.mackerel.io MackerelでDockerを監視する記事が数少ないため、今回実際に実装して記事を書きたいと思いました。 Dockerを監視してみた(監視対象について) 今回の検証では、Dockerを監視するためにコンテナを作成する必要があります。そこで、今流行りのLLMやRAGを活用し、簡単にアプリ開発が可能なAIプラットフォーム「Dify」をAWS環境に構築しました。 監視対象の構成図は以下の通りで、AWSのEC2上にDocker環境を構築し、Docker上でDify環境を構築しています。 Difyについては本記事の主要なトピックではないため、興味がある方は下記リンクをご参照ください。 Dify.AI · 先進的なAIアプリケーションのためのイノベーションエンジン 先進的なAIアプリケーションのためのイノベーションエンジン dify.ai Dockerを監視してみた(設定方法) それでは、MackerelでDockerを監視する方法を説明していきます。(今回はAmazonLinux2のOSを使用しているため、その方法について記載します。) エージェントのインストールと起動 まずは、監視対象ホストにエージェントをインストールします。 以下のコマンドを実行してインストールと起動を行います。  APIキーはMackerelのWebコンソールから参照しています。               curl -fsSL https://mackerel.io/file/script/amznlinux/setup-all-yum-v2.sh | MACKEREL_APIKEY='YOUR_API_KEY' sh sudo systemctl start mackerel-agent 起動するとMackerelに監視対象ホスト(EC2)が登録されます。 Mackerelの画面では以下の表示になり、ホスト名・ホストの情報・取得したメトリックのグラフが表示されています。 ドキュメントどおりにコマンドを実行するだけでホストを登録できました。 ドキュメントどおりに設定しても動作しない作業も経験してきたので、この作業はサクッと完了して感激しました。 公式プラグインのインストール Dockerを監視するために公式プラグインをインストールする必要があります。 以下のコマンドを実行して公式プラグインをインストールします。(プラグインを3の手順で使用します。)                                        sudo yum install mackerel-agent-plugins この作業もドキュメントどおりにコマンドを実行するだけで完了します。 設定ファイルの修正 最後に設定ファイルに以下のプラグインを追記します。        [plugin.metrics.docker] command = ["mackerel-plugin-docker", "-name-format", "name_id"] -name-formatではコンテナ名(name)やコンテナID(id)やコンテナ名+コンテナID(name_id)など複数のオプションを設定することができます。このオプションによってMackerel上のグラフ表示に違いがあります。 ここで注意が必要です! 安易にオプションをコンテナIDに設定してしまうとMackerel上でコンテナIDしか表示されず、何の機能を持つコンテナかわからなくなります。 そのため今回はコンテナ名+コンテナID(name_id)に設定することで名前とIDをグラフ上で紐づけています。 プラグインを追記後、エージェントを以下のコマンドで再起動します。 sudo systemctl restart mackerel-agent すると、Mackerel上でDockerコンテナのCPUの使用率がグラフとして表示されました! 今回作成した環境はコンテナが9つ作成されており、グラフはコンテナ毎に折れ線グラフとして表示されています(下記グラフは視認性のために2つのコンテナのグラフを表示しています)。それぞれの折れ線グラフの名前が手順3の-name-formatで設定したコンテナ名+コンテナID(先頭6文字)になっています。グラフの縦軸は使用量(%)、横軸は時刻となっています。 ちなみに-name-formatをコンテナID(id)に設定するとMackerel上では以下の画像のように表示されます。非常に見にくく、IDとコンテナの役割を紐づけることが困難です。みなさんも設定するときは気をつけましょう。 MackerelのDocker監視ではCPU・メモリ・I/O操作の3つのメトリックを監視することができます。ログ監視はできません。それぞれの詳細なメトリックについては下記をご参照ください。 mackerel-agent-plugins/mackerel-plugin-docker at master · mackerelio/mackerel-agent-plugins Plugins for mackerel-agent. Contribute to mackerelio/mackerel-agent-plugins development by creating an account on GitHub... github.com おわりに MackerelでDocker環境を監視することができました。Mackerel上での監視設定はドキュメント通りに作業を進めることで簡単に設定することができました。しかし、-name-formatの設定によるMackerel上での表示内容の違いは、オプションを変更してみたことで気づくことができました。やってみないとわからないことがあり、とても勉強になりました。 今回はDocker環境を監視しましたが、Mackerelはオンプレミス環境だけでなくクラウド環境も監視することができるためさまざまな環境を監視してみようと思います。 次回は、Mackerelと弊社の統合監視基盤FusionCOREとの連携についてのブログを投稿したいと思います。
SCSKの畑です。8回目の投稿です。 今回は、 初回のエントリ で少しだけ触れた、AWS Amplify が生成した AWS AppSync リソースの手動移行に関する備忘録のような、Tips のような内容になります。如何せんこのような作業が必要となるような案件もといシチュエーション自体が珍しいと思いますので、ニッチな内容になるとは思いますが御覧頂ければ幸いです。 なお、タイトル通り Amplify と AppSync の話題に閉じているのでアーキテクチャ図は載せません。それも何気に今回が初めてですね・・   前提条件(初回エントリのおさらい含む) お客さんが主体的に管理している AWS 環境上で各種 AWS サービスやリソースの構築・実装を行った、 CloudFormation や AWS CDK、terraform などの使用は原則 NG。AWS マネジメントコンソールの使用を使用した構築が基本。 Amplify についてはお客さんの環境ポリシー上導入 NG だったため、弊社の AWS 環境上で Amplify により作成された各種 AppSync リソースを、お客さんの AWS 環境に手動移行する必要があった。 移行対象はスキーマ、リゾルバ、関数の3つ。 データソースについては上記3つと比較して変更のタイミングが限定的であり、かつリソースとなる DynamoDB のテーブルや Lambda 関数についても申請の上お客さん側で作成頂く必要があるため、設定情報をお客さんに連携して作成頂く形式とした。 以上の内容を踏まえて、いくつかの観点から備忘録替わりに記載していきます。   余分な query や mutation を Amplify に生成させない まずは Amplify スキーマ定義上の工夫から。 @model として定義すると、テーブルだけでなく対応した query なり mutation を自動生成してくれるのが Amplify の便利な点なのですが、アプリケーションから使用しないことが明確なものもあるため、そのような不要なものは生成しないようにすることで移行作業の対象を減らすのが目的です。具体的には、スキーマ定義において生成対象の type を指定することで実現できます。 排他制御の実装例(第一回) で例示した TableInfo において、query は list、mutation は create のみをそれぞれ生成するようにする場合は以下のように定義することで実現できます。 type TableInfo @ model ( queries: { list: "listTableInfos" }, mutations: { create : "createTableInfo" }, ) @ auth ( rules : [ { allow : public, provider : apiKey}, { allow : private, provider : iam}, ]) { name : String! @primaryKey status : TableStatus! editor : String locked_by : String }   手動移行時に設定変更が必要なマッピングテンプレートの整理 次に、実作業についてですが・・こちらは単純に AWS マネジメントコンソールを弊社の AWS 環境とお客さんの AWS 環境で2画面開いて、愚直に手動で移行(もといコピペ)していただけなので、特に内容として取り上げたいものはありません。もっと楽なやり方を採用したかったとは思いますが。。 ただ、AWS 環境が異なる以上、移行時に変更する必要がある項目も幾つかあったためその点には留意しました。特に、リゾルバのリクエストマッピングテンプレートについては VTL を書き換える必要があったため、備忘録として以下に記載しておきます。逆に言うと、注意深く変更する必要があったのはこの項目くらいだったため、移行自体は思っていたほど時間がかからなかったのは幸いでした。 例えば、データソース名はお客さんに作成頂く必要があることもあり、Amplify による生成時の名称から意図的に変更していますが、データソースを意図的に指定する必要があるのは関数やリゾルバ作成時程度なので、あまり気になりませんでした。 下記例の通り、大体コピペのままで行けるのですが以下2点については修正の必要がありました。 authRole, unAuthRole を使用しないため、マッピングテンプレートから削除 adminRoles の AWS アカウント ID をお客さんの AWS 環境のものに変更 ## [Start] Stash resolver specific context.. ** $util.qr($ctx.stash.put("typeName", "<Query or Mutation or Subscription>")) $util.qr($ctx.stash.put("fieldName", "<QueryName or MutationName or SubscriptionName>")) $util.qr($ctx.stash.put("adminRoles", ["arn:aws:sts::<AWS Account ID>:assumed-role"])) {} ## [End] Stash resolver specific context.. **   手動移行した AppSync リソースの設定チェックにおける工夫 最後に、手動移行後の AppSync 設定確認方法について。 手動で移行したこともあり、環境間で移行したリソース設定をどのように比較チェックするのかがちょっとした課題でした。スキーマは画面からコピペしたものを diff 比較すれば良いとしても、関数/リゾルバのマッピングテンプレートで都度それをやるのはさすがに面倒だし、マッピングテンプレート内の関数実行順などは画面上で比較するしかないということで、どうしたものかと。当初は目視確認もやむなしかと思っていたのですが、案の定設定ミスで動作しなかった mutation が出てしまい、ある程度はちゃんと機械的に比較できる方法を考える必要がありました。 と言っても、先述の通り IaC に該当する仕組みは使用できなかったので、大人しく Python/Boto3 で AppSync の設定を一覧化して S3 に出力するようなコードを書くことにしました。弊社/お客さんの AWS 環境で出力したものを diff 比較するようにすれば、AWS アカウント ID など差異が発生する項目は出るにせよ、画面の目視確認よりは大分マシだろうなと。 なお、順番が前後してしまいますが、現在は Amplify スキーマ更新時などにどこが変更されたのか(=どのリゾルバ/関数を手動移行する必要があるのか)を検出するためにも使用しています。単純な type の追加程度なら何を移行すれば良いのかある程度直感的に分かると思うのですが、変更(更新)とかになるとリゾルバ内のどの関数なりマッピングテンプレートが変更されたか分からないですからね。。 ということで内容は大したことないのですが、以下 Lambda による実装例です。幸い Boto3 にそのものズバリなメソッドが揃っていたため、それらを順次実行した結果を S3 に出力しているだけの簡単仕様ですが、少しだけ補足です。 get_introspection_schema() と list_types() が返す情報はほぼ同義ですが(スキーマ設定により各 type が定義されるので)、一応両方出力するようにしています。 前者は JSON ではなく SDL で出力しているので、streamingBody を read() したものをそのまま出力しています。 list_resolvers() の引数として、リゾルバを実装した type 名を指定する必要があります。Amplify を使用していることもあり、graphql のクエリ言語に対応するものをそのまま直指定しています。 また、出力結果はフォルダごと Winmerge などの diff ツールで比較するような使い方をしていますが、functionID 絡みで比較に支障があった部分については以下のように変換、ソート処理を入れています。 list_functions() の結果がどうやら functionId でソートされて返ってくるようなのですが、ID は当然ながら環境間で異なるためこのままだと有意な比較ができません。よって、 name(関数名)でソートし直したものを出力しています。 リゾルバ内の関数実行定義も functionId による表現となっているため、functionId から name を導出できるような dict を用意の上、定義内容を置換しています。 他にも、マッピングテンプレートや types における definition の出力結果を整形するなど、もうちょっと頑張りどころはありそうなんですが、それらの内容で差分が生じてもそこまで比較に支障が出なさそうだったので、一旦そのまま出力してしまっています。 import json import datetime import boto3 import botocore BUCKET_NAME = '<BUCKET_NAME>' API_ID = '<APPSYNC_API_ID>' appsync = boto3.client('appsync') s3 = boto3.resource('s3') bucket = s3.Bucket(BUCKET_NAME) def put_json_to_S3(obj_key, json_data):   obj = bucket.Object(obj_key)   obj.put(Body = json.dumps(json_data, indent=4, sort_keys=True, separators=(',', ': '))) def lambda_handler(event, context):   obj_key_prefix = f'appsync_setting_dumps/{datetime.datetime.now().strftime("%Y%m%d_%H%M%S")}'   # 情報取得(functions)   response = appsync.list_functions(       apiId=API_ID   )   # functionの名前でソート   sorted_func_json = sorted(response['functions'], key=lambda x: x['name'])   put_json_to_S3(f'{obj_key_prefix}/functions.json', sorted_func_json)   # 情報取得(resolvers)   id_name_dict = {item['functionId']: item['name'] for item in sorted_func_json}   for typename in ['Query', 'Mutation', 'Subscription']:       response = appsync.list_resolvers(           apiId=API_ID,           typeName=typename       )       # functions実行定義をIDから名前に変換       converted_resolvers_json = response['resolvers']       for item in converted_resolvers_json:           pipeline_config = item["pipelineConfig"]           if "functions" in pipeline_config:               pipeline_config["functions"] = [id_name_dict[id] for id in pipeline_config["functions"]]       put_json_to_S3(f'{obj_key_prefix}/resolvers_{typename}.json', converted_resolvers_json)     # 情報取得(types)   response = appsync.list_types(       apiId=API_ID,       format='JSON'   )   put_json_to_S3(f'{obj_key_prefix}/types.json', response['types'])     # 情報取得(schema)   response = appsync.get_introspection_schema(       apiId=API_ID,       format='SDL'   )   obj = bucket.Object(f'{obj_key_prefix}/introspection_schema.json')   obj.put(Body = response['schema'].read()) なお、この方向性で AppSync リソースの作成や更新も自動化すればいいじゃんというセルフツッコミが成立しそうなのですが、車輪の再発明感がものすごかったので今回はやめました。もっと対象のリソース数が多かったりしたら検討したかもしれませんが、それよりはお客さんに Amplify の使用許可を貰えるよう交渉を頑張るとか、Amplifyをやめて自前でリゾルバを実装するようにした方が色んな意味で健全かなと思います。。。   余談 Amplify の自動生成が便利とはいえ手動移行に手間をかけるより、自分でリゾルバを書けば良いんじゃないの?と疑問を持たれた方もいるかと思うのですが、その考え自体は正しいと思います。何故それでも Amplify を採用したのかというと、単純に期間や工数との兼ね合いからでした。AppSync を本格的に扱うのが初めてだったということもあるのですが、リゾルバの作成を未経験の言語(VTL or AppSync JS)で頑張るのはちょっと現実的ではなかったです。特に VTL は正直構文とか見てもあまり好きになれず・・ データソースが全て Lambda になるようなアプリケーションであれば、AppSync をやめて API Gateway + Lambda という構成でもよかったのですが、その場合はアプリケーションで使用するDBをどのように用意するか、というのがネックでした。なるべくサーバレスのサービスで構成しようとすると結局一番筋が良さそうなのは DynamoDB になりますが、それなら AppSync 及び Amplify と組み合わせて使った方が筋が良いのではないかと。Aurora Serverless も選択肢ではありましたが、さすがに今回の用途だとオーバースペックでしたし。後は、別エントリで説明した通り AppSync の Subscription をアプリケーション側で活用することを念頭に置いていたという要因も大きいです。   まとめ 本来であればこのような対応を取らないに越したことはないのですが、手動移行したことによりリゾルバや関数の仕組みや実装について理解が深まったことも確かなので、トータルでは良かったのかもしれません。現在もアプリケーションの開発は継続しており、ちょくちょく弊社環境からお客さん環境に AppSync 更新分を移行する機会はあるのですが、これらの取り組みにより移行自体にかかる工数は大分削減できるようになりました。ただ、もし別の案件で同じような対応を迫られた場合は、もっとラクなやり方を検討したいところではあります。。 本記事がどなたかの役に立てば幸いです。
企業ネットワークにおけるクラウドサービス利用のリスク対策として、Cloud Access Security Broker(CASB)の導入が増えています。 CASBは「可視化(Visibility)」「アセスメント(Assessment)」「強制(Enforcement)」「防御(Protection)」の4つのプロセスで説明されます。このうち「強制」では、クラウドサービスの利用許可・拒否等のルールを設定することとなりますが、具体的にどういったルールにするべきか、ご相談をいただくことが多いです。 そこでこの記事では、 実際に設定されることの多いCASBルールの例をご紹介します。 設定はSASEソリューションである「Catoクラウド」のCASB機能に沿ってご紹介しますが、他のCASB製品においてもルール検討のご参考にしていただけましたら幸いです。 なお、CatoクラウドのCASB機能については、以下の記事もご参照ください。 CatoクラウドのCASBについて Catoクラウドのセキュリティオプション CASB について解説します。 blog.usize-tech.com 2023.09.12 Catoクラウドでアプリケーションを制御するには CASB機能のApplication Controlの設定方法や実際にどのような制限ができるのかについて解説していきたいと思います。 blog.usize-tech.com 2023.11.02 CASBではどんな制御ができる? CASBでの制御は、次世代ファイアウォール(L7FW、NGFW)でのアクセス制御とは少し違います。 次世代ファイアウォールでの制御 アプリケーション識別をして、そのアプリケーションへの通信を許可・拒否することができる。 例) X(旧Twitter)へのアクセスを拒否する。閲覧も投稿もできない。 CASBでの制御 アプリケーション識別をして、そのアプリケーションの 特定の 操作を指定して許可・拒否 することができる。 例) X(旧Twitter)の閲覧は許可するが、投稿のみ禁止することができる。 このような違いがあるため、CASBのルール作成においては、許可・拒否するアプリケーションに加えどの操作を許可・拒否するかを検討する必要があって、検討が難しく感じられるのではないかと思います。 なお、Catoクラウドにおいては、CASBはオプション機能となっています。CASBオプションを追加することで、クラウドサービスに対する操作など、詳細な情報が取得できるようになります。 CASBでのよくある制御ルール例 では、CASBを導入されている企業ではどのような制御をされているのでしょうか。SCSKで実際にご相談を受けたり、設定をご案内する中で多い例をご紹介します。 クラウドサービスでの個人アカウント利用の制限 会社で利用するクラウドサービス、具体的にはMicrosoftのM365やGoogle Workspaceについて、 会社のメールアドレスでのログインを許可するが、その他のメールアドレスでのログインを拒否する という設定です。 この設定により、会社の端末から個人のGoogleDriveに業務情報をアップロードするといった操作を抑止できます。 また、同様にChatGPTへの社内情報のアップロードを抑止する目的で、OpenAIへのログインを制御しているご利用例もあります。 Catoクラウドでの設定例 以下は、CatoクラウドのCASB機能であるApplication Controlでの設定例です。それぞれ上の行で会社アドレスでのログインを許可し、下の行でその他のすべてのログインを拒否する設定です。 なお、Catoクラウドではこの他にTenant Restriction(旧名称:Header Injection)機能を利用し、特定のサービスへの通信時にHTTPヘッダを挿入することが可能です。これにより、クラウドサービス側で、アクセス可能なアカウントやテナントを制限するなどの動作が可能です。詳細は下記記事をご参照ください。 Catoでやる「Microsoft 365」のテナント制御~「Header Injection」機能の紹介~ Catoの「Header Injection」機能を使って「Microsoft365」のテナント制御を実施する方法を紹介します。 blog.usize-tech.com 2024.07.12 ファイル共有サービスへのアップロードの制限 Dropbox、boxなどといった、 ファイル共有サービスやオンラインストレージに対し、アップロードのみを拒否する 設定です。 これらのサービスは、取引先等からのファイル送付に利用されることもあるため、アクセス自体を拒否してしまうとやりとりに支障が出てしまいます。このため、以下のようなルールにされる場合が多いです。 自社で契約しているファイル共有サービスは全アクションを許可 それ以外のファイル共有・オンラインストレージは、アップロードのみを拒否 (閲覧・ダウンロードは可能) Catoクラウドでの設定例 Custom Categoriesにて、アップロード拒否対象とするカテゴリを作成し、 Application Controlにて、Dropboxのみ全アクションを許可、その他Custom Categoriesに対するUploadのみを拒否とします。 ※2025年1月現在の仕様で、Application Categoriesに対してはActivitiesが指定できないため、Custom Categoriesを作成しています。 SNS投稿の制限 XやInstagram等の SNSに対し、投稿のみを拒否する 設定です。 情報収集のため閲覧は許可したいが、リスク管理上、社内からの投稿はできないようにしたいという場合に有効です。 Catoクラウドでの設定例 例として、広報担当のみは投稿含めすべての操作を許可し、その他ユーザは投稿を拒否する設定です。 リスクが高いクラウドサービスの利用制限 世の中にはクラウドサービスが無数にあり、利用者がその一つ一つの安全性を判断したり、ルールを設定するのは現実的に不可能です。 この問題への解決策として、各CASBではクラウドサービスに対し独自のリスク判定を行っており、このリスク判定をもとに、利用者がルールを設定することが可能です。 Catoクラウドでの設定例 Catoクラウドでは、クラウドサービスの認定取得やセキュリティ対策状況をもとに、1(低)~10(高)のリスクスコアをつけています。例として、Gmailのリスクスコアは「4」です(2025年1月時点)。 このリスクスコアを元に、 スコア8以上のクラウドサービスはアクセスを拒否する などの設定を行うことで、セキュリティリスクが高いと判定されたサービスの利用を制限することができます。 すべてのクラウドサービスへのアップロードをログに記録 クラウドサービスごとのCASBルールを設定した上で、その他すべてのクラウドサービスに対し、 ファイルのアップロード動作をログに残す設定 です。 万が一情報の持ち出し等があった場合に、ログから追えるようにしたいという目的です。 Catoクラウドでの設定例 すべてのクラウドサービスへのUploadを、許可はするが、Event(ログ)に残すという内容です。 補足 CatoクラウドのCASB機能では、ルールを全体にかけるだけでなく、ユーザやグループを指定して設定することもできるので、例えば個人情報を扱う部署にはより厳しいルールを適用したり、特定のユーザはルールの対象外にしたりといった、細かな設定が可能です。 また、設定例の中にもあるように、指定の動作について、拒否ではなく「許可するがログに残す」「許可するが管理者にメール通知する」といった指定も可能です。 拒否ルールを急に設定すると業務に支障が出る場合もあることから、 まずは「ログに残す」設定でルール適用し、その後ログ状況を見て拒否に変えていく運用がおすすめ です。 最後に 本記事では、実際にCASBで設定されることの多いルールをご紹介しました。CASB導入時のルール検討にご活用いただけますと幸いです。 自社環境に合ったCASB制御を行うには、クラウドサービスの実際の利用状況を定期的に確認し、自社のポリシーと照らし合わせてルールをブラッシュアップしていく必要があります。「可視化(Visibility)」「アセスメント(Assessment)」「強制(Enforcement)」「防御(Protection)」のサイクルの運用です。 SCSKでは、運用経験豊かなエンジニアが多数在籍しており、お客様にあわせたご支援が可能です。お困りごとなどございましたら、ぜひご相談ください。
Amazon Athena と AWS Glue を使用して、Amazon S3 上にある CSV データに対してクエリを実行してみたので、その手順をまとめます。 AWS Glue と は AWS Glueは、Amazon Web Servicesが提供するフルマネージドのETL(抽出、変換、ロード)サービスです。このサービスは、大量のデータを効率的に準備し、変換し、異なるデータストア間で移動させることを目的としています。 Glueを利用するにあたり、登場する用語について簡単に説明します。 ETL(Extract, Transform, Load): データを抽出(Extract)し、変換(Transform)し、ロード(Load)するプロセスを指します。AWS GlueはこのETLプロセスを自動化および簡素化するためのサービスです。 AWS Glue Data Catalog: AWS Glue Data Catalogは、メタデータを管理するための中心的なサービスです。データストアのスキーマ情報、データの場所、その他のメタデータを保持し、データの整理と管理をサポートします。 AWS Glue データベース: AWS Glueデータベースは、Data Catalog内でテーブルをグループ化するための論理的なコンテナです。データベースはスキーマを含んでおり、データの整理とスキーマの一貫性を保つために使用されます。 AWS Glue テーブル: AWS Glueテーブルは、データとその構造に関するメタデータを表します。通常は特定のデータセットのスキーマ情報を含み、データドリブンなアプリケーションで使用されます。 クローラー: クローラーは、自動的にデータソースを探索し、データカタログにメタデータを登録するためのコンポーネントです。クローラーはデータの構造を解析し、テーブル定義を生成または更新します。 AWS Glue ジョブ: AWS Glueジョブは、ETL(抽出、変換、ロード)プロセスを実行するための基本単位です。ジョブを作成して、データを変換し、必要な出力先にロードすることができます。 AWS Glue 接続: AWS Glue接続は、Glueがデータストアにアクセスする際の接続情報を保存します。ホスト名、ポート番号、認証情報などが含まれ、データアクセスを安全かつ効率的に行えます。 Amazon Athena とは Amazon Athenaは、Amazon Web Services(AWS)が提供するサーバーレスのインタラクティブクエリサービスです。Athenaを使用すると、Amazon S3に保存されているデータに対して直接SQLクエリを実行し、複雑なETLプロセスを必要とせずにデータを分析できます。 Amazon Athenaには、以下の特徴があります。: サーバーレス: Athenaは完全にサーバーレスであるため、インフラストラクチャの管理が不要です。ユーザーはクエリの実行に対してのみ料金を支払います。 SQLサポート: Athenaは標準SQLを使用してクエリを記述できるため、SQLに精通したユーザーが簡単に利用できます。 データソースのサポート: 主にAmazon S3に保存されたデータに対してクエリを実行しますが、Athenaを他のデータソースに接続することも可能です。 使いやすさ: ノードやクラスタの管理が不要で、クエリを書くだけでデータ分析を始められます。 統合機能: Amazon QuickSightなどの他のAWSサービスと統合しやすく、ダッシュボードを通じたビジュアル分析が可能です。 データ形式のサポート: AthenaはCSV、JSON、ORC、Avro、Parquetなど、さまざまなデータ形式に対応しています。 これらの特徴により、Amazon Athenaはデータアナリストやデータサイエンティストにとって、スピーディーで効果的なデータ分析ツールとなっています。 やってみた AWS Glue 1.データベースの作成 まずはクローラの出力先となるデータベースを作成します。 ここでは名前のみ指定しました。 2.クローラーの作成 クローラーの名前を入力します。   「Add a data source」からデータソースを指定します。 今回はS3のデータを利用したいので、データを配置したS3のパスを指定します。 また、「Subsequent crawler runs」では、クローラーの再実行時にどのフォルダをクロールするかを選択できます。 今回は、全て再クロールする「Crawl all folders」を選択しました。   データソースを指定できたら「Next」へ進みます。 IAMロールを選択します。 今回は「AWSGlueServiceRole」およびソースデータを配置したS3へのアクセス権限を付与しました。 クローラの出力先を指定します。 「1.データベースの作成」で事前に作成したデータベースを指定します。 設定に問題がなければ「Create crawler」をクリックします。 以上でクローラの作成は完了です!   3.クローラの実行 早速クローラを実行してみます。 作成したクローラの詳細画面から「Run crawler」クリックします。 出力先に設定したデータベースを確認すると、クローラによりS3上のデータが自動で読み取られ、構造化されたインデックスがカタログ(Glue Data Catalog)として保存されています。 Amazon Athena クエリの実行 Athenaでクエリを実行してみます。 Athenaでのクエリ実行時に、データベースにGlue Data Catalogのデータベースを指定することで、データベース内のテーブルやテーブル内の項目名を使うことができます。 データソース欄で「AWSDataCatalog」を指定すると、データベース欄からGlueで作成したデータカタログ内のデータベースが選択できます。   クエリを実行してみました。 select文を実行して、テーブル内の項目を抽出することができました! さいごに S3のデータをGlueでデータベースに格納して、Athena で必要なデータを取得するまでの手順をまとめました。Glueを利用することで簡単にS3上のデータを構造化し、容易に必要な値を取得することができました。 次回はAthenaのデータをQuickSightに連携し、可視化してみたいと思います。
こんにちは。ひるたんぬです。 本年もよろしくお願いいたします。今年は巳年ですね。 小さい頃に「十二支は神様の号令の下、競争して早い順に決まった」と言われた記憶があるのですが、実際に本当に早い順に十二支を並べるとどのようになるのか、ふと気になってしまいました。 調べたところ、すでにこの疑問に対して調査をしてくださっていた記事がありましたので一部を抜粋してご紹介します。 本やネットに速度が出ているものは、それを採用し、それ以外のものは、筆者の経験その他から強引に算出するなどした結果、13匹の動物たちの速度は以下のようになった。 子=鼠:時速10km 丑=牛:時速4km(注1) 寅=虎:時速64km 卯=兎:時速72km 辰=竜:時速360km以上(注2) 巳=蛇:時速16km(注3) 午=馬:時速68km(注4) 未=羊:時速13km(注5) 申=猿:時速30km(注6) 酉=鶏:時速18km(注7) 戌=犬:時速36km(注8) 亥=猪:時速45km 猫:時速48km(注9) 引用:Yahoo! ニュース「 「十二支」の順番がナットクできない。実際の動物のスピードを考えると、どんな順番になるか? 」 上記から、令和版の十二支は「辰卯午寅猫亥戌申酉巳未子」となるようですね。竜が圧勝のようです。 戦略を練って二位に漕ぎ着けていた牛は、スタメンから外れてしまいました。 また、これを元に考えると、今年は亥年ということになりますね。 …さて、今回はIaCというものを少し使いこなせるようになって調子に乗っていた結果、大きな落とし穴にはまってしまったので、自戒の意味も込めてご紹介いたします。 やりたいこと とあるログをEventBridgeを経由してCloudWatch Logsに送ろう!というよくあるものです。 せっかくなのでマネジメントコンソールからではなく、IaC(CloudFormation)を使用して構築しよう!ということになりました。 やったこと マネジメントコンソールではEventBridgeのルール作成とCloudWatch Logsのロググループ作成のみで実施できたので、同じようにCloudFormationを書いてみました。今回は検証のため、EC2に関する任意のイベントをCloudWatch Logsのロググループへ転送することにします。 AWSTemplateFormatVersion: '2010-09-09' Resources: RuleEC2Activity: Type: AWS::Events::Rule Properties: EventPattern: { "source": ["aws.ec2"] } Targets: - Arn: !GetAtt LogEC2Activity.Arn Id: LogGroup LogEC2Activity: Type: AWS::Logs::LogGroup Properties: RetentionInDays: 14 LogGroupName: /aws/events/EC2Activity 上記のファイルのデプロイは問題なく完了しました。 起きたこと ログへ転送がされるかを確認するために、EC2インスタンスを立ち上げました。しかし、待てど暮らせどログは出力されません。 おかしいな…と思い、EventBridgeの当該ルールのモニタリングをチェックすることにしました。すると… EventBridgeのルール自体は動いていたのですが、そのすべての実行が失敗(FailedInvocationsに記録)していたのです。 原因調査 こんなときに役に立つのは、インターネットに広がる知識の海です。調査してみたところ、公式ドキュメントに気になる記載がありました。 CloudWatch Logs がルールのターゲットである場合、EventBridge がログストリームを作成し、CloudWatch Logs がログエントリとしてイベントからテキストを保存します。EventBridge がログストリームを作成してイベントを記録するためには、EventBridge が CloudWatch Logs に書き込むことを可能にするリソースベースポリシーを CloudWatch Logs に含める必要があります。 AWS Management Console を使用して、CloudWatch Logs をルールのターゲットとして追加する場合、リソースベースのポリシーは自動的に作成されます。AWS CLI を使用してターゲットを追加し、ポリシーがまだ存在しない場合は、作成する必要があります。 引用:AWS「 Amazon EventBridge ユーザーガイド:Amazon EventBridge のリソースベースのポリシーを使用する 」 今までの私は前者(マネジメントコンソールでの操作)しか行ったことがなかったので気づかなかったのですが、実はリソースベースポリシーの設定が必要なようですね。言われてみれば、権限も設定していないのに書き込めるのは不思議ですもんね。。。 解決に向けて… リソースベースポリシーをIaCにて設定 後述する参考記事によると、CloudFormationでリソースベースポリシーを設定できるようなので、まずはこちらを試してみます。 下記のテンプレートファイルを作成し、新規でスタックを作成してデプロイします。 PolicyDocument内のアカウントIDやロググループ名などは適宜修正してください。 AWSTemplateFormatVersion: '2010-09-09' Resources: EventBridgeToCWLPolicy: Type: AWS::Logs::ResourcePolicy Properties: PolicyDocument: "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"TrustEventsToStoreLogEvent\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"delivery.logs.amazonaws.com\",\"events.amazonaws.com\"]},\"Action\":[\"logs:CreateLogStream\",\"logs:PutLogEvents\"],\"Resource\":\"arn:aws:logs:ap-northeast-1:123456789012:log-group:/aws/events/*:*\"}]}" PolicyName: TrustEventsToStoreLogEvents これにより、正常にログが転送されました! また、このスタックを削除することによりポリシーがなくなり、ログ転送ができなくなる点も確認できました。 リソースベースポリシーをマネジメントコンソールにて設定 では、マネジメントコンソールでルールを作成した場合はどうなるのでしょうか。 リソースベースポリシーが裏で設定されているとのことだったので、その挙動を中心に確認してみます。 ルールを作成した後にCloudShellにてリソースベースポリシーの有無を確認してみると… 先ほどIaCにて設定したポリシーと同様のものが付与されていました。 知らないところで動かせるようにしてくれていたのですね。 …ここで気になった点がありました。 「このマネジメントコンソールで作ったルールを消したらリソースベースポリシーはどうなっちゃうの問題」です。 実際にやってみる他ありませんね!やってみました。 …残っていました。そのため、 マネジメントコンソールからEventBridgeのルールを一度でも作成している場合、このブログのような症状には出会わない可能性もある ということですね。 おわりに 改めて、AWSの権限に対する考え方を痛感する良いきっかけとなりました。 何事にも許可がいる…現実でもクラウド上でもそんな認識でいるのが大事なのかなと思います。 また、今回の記事は以下を参考に作成いたしました。Web上の皆さまの記事にはいつも助けられてばかりです。。 CloudWatch LogsをターゲットとするEventBridgeルールをCloudFormationで作成するには | DevelopersIO dev.classmethod.jp 上記サイトにも記載がありましたが、このリソースベースポリシーはマネジメントコンソール上から確認することができないようです。(CLIを用いて確認する) あまり需要はないかもしれませんが、これも気軽に確認できるようになるとより良いのかな…と思った次第です。 余談ですが、十二支の昔話はYouTubeでも観れるのですね。
みなさん、Amazon Redshift Serverlessを使ったことはありますか? プロビジョンドタイプと異なり、サーバレスの強みを生かした高可用性、高スケーラビリティ、コストメリット有りと使いやすさ抜群のサーバレスタイプですが、 サーバレス特有のコンピューティングキャパシティの考え方を理解すると、よりメリットを享受することが出来そうです。 今回自分が携わったプロジェクトでRedshift Serverlessを構築したので、その際に分かったこと・試したことを記事にまとめてみました。 ※最新情報についてはAWS公式ドキュメントを参照ください。 Redshiftプロビジョンドタイプとサーバレスタイプの違い まずRedshiftとは、 フルマネージド型のデータウェアハウスサービス です。 高速なリアルタイム分析が得意で、BIツールと連携も可能なため、企業の意思決定に大いに役立つサービスです。 プロビジョンドタイプはクラスタの管理が必要で、クラスタのサイズを手動で設定する必要がありますが、サーバレスタイプは ワークロードに応じて自動でスケーリング します。 後に説明する「ベース容量」から「最大容量」までの範囲で自動でスケーリングがおこなわれるため、コスト効率化、運用負荷削減に有効です。 コンピューティングキャパシティの考え方 Redshift Serverlessでは、コンピューティングキャパシティを RPU(Redshift Processing Unit) という単位で設定します。 1つのRPUは16GBのメモリを提供します。 設定箇所としては「ベース容量」、オプションで「最大容量」、「使用制限」があるので、それぞれワークロードのクエリパフォーマンスや目標コストに応じてRPUを設定していきます。 ベース容量(設定はマスト) クエリの処理に使用するコンピューティングリソースの基本容量をここで設定します。 デフォルト値は128RPUで、8RPU から512RPU まで8単位で調整可能です。 ベース容量を大きく設定することで、クエリのパフォーマンスが向上します。 最大容量(設定はオプション) Redshiftが スケールアップできるRPUの上限 をここで設定します。 クエリ実行開始時は「ベース容量」で設定したRPUで処理が実行されますが、クエリの負荷に応じてこの「最大容量」まで自動でスケーリングされます。 使用制限(設定はオプション) Redshiftの 使用を制限したい場合 はここで設定します。 頻度(毎日/毎週/毎月)、制限RPU数、アクション(ログ出力/アラート/クエリ無効)が設定できます。 Redshiftはクエリの実行に使用されたRPU時間に応じて課金されるため、これ以上コストをかけたくない、という目安がある場合には設定がお勧めです。 ベース容量と最大容量の決め方 ベース容量と最大容量はどのように定めるのが良いでしょうか? また設定後に「容量を変更すべき」という判断の基準をどのように持っておけば良いのでしょうか。 ここからは自分が実際に試してみた設定値決めの方法をご紹介します。 ざっくりとRPU設定値を決める RPUは基本的には、 「データ量」 と 「クエリの複雑さ、頻度」 で考えていきます。 仮で、以下要件の場合のベース容量を考えてみます。 ・Redshiftでの分析の元となるデータ量は3TB程度。 ・分析のために実行するクエリは集計などのSQL文。実行時間は平日の勤務時間内。 「データ量」で考えると、公式ドキュメントで「8、16、24RPU の基本RPU容量は、128TB 未満のデータが必要なワークロードを対象としています。」との記載があり、今回の対象データは3TBであることから、8~24RPUを選択の候補とします。 「クエリの複雑さ、頻度」で考えると、正直どの程度データ分析でRedshiftを使用するかによるため、一旦16RPUを選択し、検証の中で設定値を調整していく形とします。 検証で設定値をチューニングする 上記の形で一旦設定したRPUが適切かどうかを実際の利用シーンを想定してクエリを実行してみることで、設定値の妥当性を判断します。 RPU値をチューニングする時には、以下2点をポイントとしてチェックすると良いです。 ComputeCapacityメトリクス クエリ実行すると様々なメトリクスが取得できますが、その中の[ComputeCapacity]メトリクスをCloudWatchで確認することで、クエリ実行時に使用されているRPUが分かります。 メトリクスの値がベース容量のRPUから最大容量のRPUにスケールアップし、最大容量に近い時間が多い場合は「ベース容量が足りていない」と判断する材料になります。 ただし、クエリについては単一のクエリからの負荷増加に応じたRPUスケールアップはおこなわれず、 同時実行クエリのみがスケールアップの対象 であることを念頭においておくことが必要です。 クエリ実行時間 以下の方法でクエリ実行時間を確認し、 想定内の実行時間であるか を評価する方法も有効です。                SYS_QUERY_HISTORYビュー Redshift内でSQLを実行しビューを表示させ、クエリ実行に関する詳細情報を確認する方法。 例えば「elapsed_time」を表示させると、クエリの実行時に消費した合計時間がわかります。 elapsed_time :クエリの実行が消費した合計時間(マイクロ秒)。           監査ログ 監査ログを有効にし、クエリ実行時間に関する情報を確認する方法。 QueryDuration :クエリを完了するまでの平均時間(マイクロ秒)。 QueryRuntimeBreakdown :クエリステージごとの、クエリが実行された合計時間(ミリ秒)。   まとめ コンピューティングキャパシティの考え方を理解して、パフォーマンス的にもコスト的にも有効に使用できると良いですね。 最後まで読んでいただきありがとうございました! この記事が皆さんのお役に立てれば幸いです。
こんにちは、2024年度入社の秋葉です! 2025年の1月14日を持ちまして、約3ヶ月のクラウド人材研修が終了いたしました。 クラウドは利用しているけど、”クラウド人材研修”って一体何?と疑問に思っているあなたに向けてクラウド人材研修とは何か、その具体的な内容、そして研修によって何を得ることができたのか記載していきます! クラウド人材研修の背景・目的 近年の急速なデジタル化は、市場や社会の変化を激化させており、顧客のDX推進を支援するためには、クラウドネイティブな知識とアジャイルな開発スタイルを備えた、即戦力となる人材が不可欠です。 しかし、経験豊富なクラウドエンジニアは不足しており、育成が急務となっています。特に、アプリケーション開発とインフラ運用、双方の知識とスキルを兼ね備えた「 フルスタック人材 」の育成は喫緊の課題です。 この背景から、SCシステム事業本部では新人育成プログラムとしてクラウド人材研修を実施しています。本研修の目的は、将来的なフルスタック人材育成を視野に入れ、クラウド基盤技術の習得、アジャイル開発手法の実践を通じて、クラウドネイティブな開発スタイルを早期に経験させることです。 技術スタック フルスタックを目的とした技術スタックはAWSを基本に以下のように構成されていました! Javaアプリケーション SpringBoot IaC クラウド(AWS CloudFormation)                                   コンテナ(Docker/Amazon ECR/Amazon ECS) CI / CD イミュータブルインフラストラクチャ ビルド/デプロイ自動化(AWS CodePipeline) ステートレス(Amazon ElastiCache) 負荷分散 / 冗長化 ロードバランサー(Elastic Load Balancing ALB) 監視 / 通知 監視(Amazon CloudWatch Alarm) 通知(Amazon SNS) 研修内容 CNCF Cloud Native Trail Map をベースに構成したLesson0~Lesson9までの全10レッスンのカリキュラムで、クラウドネイティブの基礎から応用までを網羅的に学習してきました! 各Lessonのテーマは以下のようになっています。研修は、2人1チームの計8チームで進められておりチーム内だけでなく各チーム間で協力して研修に取り組んだことで全チームが期間内にすべてのLessonを終えることができました! Lesson Theme Lesson 0 Preparation Lesson 1                  Introduction Lesson 2                  IaC Level 1 Lesson 3                  IaC Level 2 Lesson 4                  Redundancy Lesson 5 Containerization and Orchestration Lesson 6                      CI/CD Lesson 7                  Observability Lesson 8          Operations Automation Lesson 9               Disaster Recovery 全Lessonが終了すると以下のような構成図になります。 この一連のレッスンでは、Spring Bootを用いたWebアプリケーションをAWSクラウド上で構築し、CI/CDパイプラインによる 自動デプロイ と 監視機能 を備えた、 堅牢なシステム の実現を目指します。 Lesson0では、Spring Boot・AWS・Gitなど開発に必要なツールの使い方や学習から始まり、最後の Lesson 9 では、災害などに備えて、システムをより堅牢にするための仕組みを作りました。具体的には、Lesson9ではDNS Failoverを実現することで東京リージョンで障害が発生した場合に備え、Webアプリケーションを自動的に別のリージョン(バージニア北部)に切り替えて、静的なエラー画面を表示する仕組みを構築しました。 このように、この研修を通して、Webアプリケーションの 開発 から 運用 、そして 災害対策 まで、一連の流れを学ぶことができたと思います! 研修を終えた新人たちの声 Kさん 当たり前のことだがコミュニケーションを密に取ることが大切だということを再実感した。また、問題が発生した際に原因の切り分けを行いながらトラブルシューティングを行うスキルが身に染み付いたと思っているので今後の業務に活かしていきたい! Sさん 権限の管理に関して、必要最低限のポリシーをアタッチすることが簡単なようでとても難しかった。必要以上のポリシーを付与してついつい楽をしがちだが、不要なポリシーが無いか確認し同じロールを使いまわさないことを意識して業務に臨みたい。 Tさん エラー発生時に画面共有しながら、ペアプログラミングできた経験はすごく良かったと感じた。今後の案件では研修を通して身に着けた、明確な作業内容報告の実施をチームメンバーに対して心がけていきたい! Oさん   研修を通して一番忍耐力が身についたと思いました。開発中1つエラーを解決したら別のところでまたエラー、エラー三昧になってしまうこともあったけどそれに負けず最後までやり遂げれました。今後の業務にもエラー三味に負けない心で挑みたい!     終わりに 3ヶ月間のクラウド人材研修は、私にとって大きな経験であり、同時に大きな成長の機会となりました。右も左も分からない状態からスタートしましたが、CNCF Cloud Native Trail Mapをベースとした体系的なカリキュラム、そしてチームメンバーや講師の方々のサポートのおかげで、クラウドネイティブ開発の基礎をしっかりと築くことができました。 研修を通して特に印象に残っているのは、実践的な課題を通じて、座学だけでは得られないリアルな経験を積むことができた点です。エラーに遭遇した時の原因究明やトラブルシューティング、チームでの協力作業など、実際の開発現場で直面するであろう課題に取り組むことで、問題解決能力やコミュニケーション能力を向上させることができました。また、Kさんが述べているように、チームメンバーと密にコミュニケーションを取りながら課題に取り組む重要性を改めて認識しました。 最後に、この研修に関わってくださった全ての方々に感謝申し上げます。ありがとうございました!
AWS System Manager (SSM) の Patch Manager 機能を利用すると、OS パッチ適用を自動化できるそうです。 すごく便利だと思ったので、設定手順をまとめてみました。   アーキテクチャ 今回は、下図の構成で実装してみました。   Systems Managerとは、 オンプレミスでもマルチクラウド環境でも、AWS 内のノードを広範囲にわたって一元的に表示、管理、および運用できます。統合コンソールエクスペリエンスのリリースにより、Systems Manager では AWS アカウントとリージョン全体にわたってよく使用するノードタスクを完了できるさまざまなツールが統合されています。 AWS Systems Manager とは – AWS Systems Manager   Patch Managerとは、 オペレーティングシステムとアプリケーションの両方にパッチを適用することができます。 AWS Systems Manager Patch Manager – AWS Systems Manager   設定手順 今回は、以下手順でOS「Windows2022」のEC2に、毎月第4月曜日の9:00にパッチ適用する手順をまとめました。 1.パッチベースラインの作成 2.パッチグループの作成 3.メンテナンスウィンドウの作成 4.ターゲットの登録 5.Run Commandタスクの登録   1.パッチベースラインの作成 AWS System Managerの左メニュー「パッチマネージャー」をクリックし、「パッチベースライン」>「パッチベースラインを作成する」をクリックします。   ▼ パッチベースラインの詳細 「名前」欄は、任意のパッチベースライン名を入力します。 「オペレーティングシステム」欄は、パッチ適用対象のインスタンスのOSを選択します。 今回は、windowsを選択しました。   ▼ オペレーティングシステムの承認ルール 「製品」欄は、パッチ適用対象のインスタンスのOSイメージを選択します。 「分類」欄は「CriticalUpdates」、「SecurityUpdates」を選択します。 「重要度」欄は「Critical」、「Important」を選択します。 「コンプライアンスレポート」欄は、「重大」を選択します。 そのほかはデフォルトのままにします。   以下の欄はデフォルトのままにし、「パッチベースラインの作成」をクリックします。 ▼アプリケーションの承認ルール ▼パッチの例外 ▼タグの管理   2.パッチグループの作成 作成したバッチペースラインのIDをクリックし、「アクション」>「パッチグループの変更」をクリックします。   「バッチグループ」欄に任意のパッチグループ名を入力し、「追加」をクリックします。 入力したパッチグループ名が追加されたことを確認後、「閉じる」をクリックします。   3.メンテナンスウィンドウの作成 AWS System Managerの左メニュー「メンテナンスウィンドウ」をクリックし、「メンテナンスウィンドウの作成」をクリックします。   ▼ メンテナンスウィンドウの詳細の入力 「名前」欄は、任意のメンテナンスウィンドウ名を入力します。 そのほかはデフォルトのままにします。   ▼ スケジュール 「次で指定」欄は、「CRON/Rate 式」を選択し、実行させる時間帯をcronで記載します。 ※今回は第4月曜日の9時に実行させたいので、cron(00 09 ? * MON#4 *)で登録してみます。 「期間」欄は、「3」時間を選択します。 「タスクの開始を停止する」欄は、「0」を選択します。 「スケジュールのタイムゾーン」欄は、任意のタイムゾーンを選択します。 ※今回は「(GMT+09:00) Asia/Tokyo」を選択しました。 そのほかはデフォルトのままにします。   ▼ スケジュール デフォルトのままにし、「メンテナンスウィンドウの作成」をクリックします。   4.ターゲットの登録 作成したメンテナンスウィンドウのIDをクリックし、「アクション」>「ターゲットの登録」をクリックします。   ▼ Maintenance window target details 「Target name」欄は、任意のターゲット名を入力します。 そのほかはデフォルトのままにします。   ▼ ターゲット 「ターゲットの選択」欄は、「インスタンスタグを指定」を選択します。 「インスタンスタグを指定」欄は、パッチ適用対象のインスタンスにアタッチしている任意のタグを入力し、「Add」をクリックします。 入力したタグが追加されたことを確認後、「Register target」をクリックします。   5.Run Commandタスクの登録 作成したメンテナンスウィンドウのIDをクリックし、「アクション」>「Run Commandタスクの登録」をクリックします。   ▼ メンテナンスウィンドウタスクの詳細 「名前」欄は、任意のメンテナンスウィンドウタスク名を入力します。 そのほかはデフォルトのままにします。   ▼ コマンドドキュメント 「ドキュメント」欄は、「AWS-RunPatchBaseline」を選択します。 そのほかはデフォルトのままにします。   ▼ ターゲット 「登録済みターゲットグループの選択」を選択し、「4.ターゲットの登録」で設定したターゲットを選択します。   ▼ レート制御 「同時実行数」欄は、「1」ターゲットを選択します。 「エラーのしきい値」欄は、「1」エラーを選択します。 ▼ IAM サービスロール パッチ適用用のIAMロールを選択します。   ▼ 出力オプション 「CloudWatch output」を選択し、任意のロググループ名を入力します。 ※パッチ適用の実行結果がCloudWatch logsに出力されます。   ▼ SNS通知 デフォルトのままにします。 ▼ パラメータ 「Operation」欄は、「Install」を選択します。 「Snapshot Id」欄は、「 {{WINDOW_EXECUTION_ID}} 」を入力します。 そのほかはデフォルトのままにします。 ▼ CloudWatch alarm デフォルトのままにします。 すべての項目を設定後、「Run Commandタスクの登録」をクリックします。   パッチ実行結果確認 パッチ適用結果は以下の方法で確認することができます。 ①「メンテナンスウィンドウ」>「履歴」 ②CloudWatch logsに出力する設定をした場合は、 「ロググループ」>「ロググループ名」>「ログストリーム」   まとめ 今回は、Windowsのパッチ適用を設定するところまでをまとめてみました。 適用結果をSNSで通知させる方法もあるみたいなので、次の記事でご紹介します。 パッチ適用以外にもSSMの機能でいろいろできそうだと思ったので、もう少し調べてみようと思います。