TECH PLAY

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

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

1226

はじめに いきなりですが、パフォーマンスチューニングの極意からお話しましょう。 パフォーマンスチューニングとは、「一定の制約の中で、希望の結果を選び取ること」と考えると、我々人類が日々行っている生存競争と何ら変わりがありません。日々生存競争している、すなわち、常在戦場。つまり戦場の極意=パフォーマンスチューニングの極意でもあるということにほかなりません。 ここで、歴史上の偉人に登場してもらって、戦場での極意を語ってもらいましょう。 孫子曰く、 「敵を知り己を知らば百戦あやうからず」 \孫子言いたいだけだろ/ ハイ、その通りです。 敵?己? 今回は、Webサイトのパフォーマンス・チューニングを例としてチューニングを行います。 敵と己にわけて考えます。別に悪意があって敵とするわけではなくて、自分の努力、パフォーマンスチューニングではどうしようもないものを敵と捉えます。自分の手の届く範囲の外にあるもの、と、捉えてもいいですね。 逆に自分でどうにかできるものや、できそうなものを己とします。 敵 Webサーバーに殺到するお客様、あるいはWebサーバーを乗っ取ろうとする攻撃者 己 Webサーバーの特性、Webサイトのアーキテクチャー構成、ネットワーク構成、Webサーバーやシステムの得意技、苦手とするところ、業務要件、制約事項、コンテンツの特性、etc… こうやって見ると己はすごく多いですね。 パフォーマンス・チューニングの流れ パフォーマンス・チューニングの流れとしては、下の図のようになります。 左上のスタートから始まって、ぐるっと回るような流れになっています。   データ収集 データ分析 結果判定 ボトルネック特定 ボトルネック改善 測定試験実行 順に見ていきましょう。 1. データ収集 「Webサイトの表示が重くなってきて、最終的に表示されなくなった」「イベントのときにいきなり落ちた」など、訴え事象やお客様からみた状態「だけ」では、Webサイトの中で何が起こっているのか全くわかりません。まずは状況を客観的に判断するためのデータを収集します。 Webサイトであれば、 Webサーバのアクセスログ エラーログ(Webサーバーが 4xx,5xx を返却したログ、あるいはアプリケーションが異常時に出力したログ) EC2 や RDS を利用している場合は、CPU利用率や、メモリ利用率 Akamai, CloudFrontな どのコンテンツデリバリーネットワーク(CDN)サービスを利用しているのではあれば、その統計データ などのデータがあると思います。そういったデータの中から、 異常発生時の状態のログ 普段の正常な状態のログ できれば異常発生時と同じようなイベントの際のデータと、イベントのない平常時の同じ曜日時間帯など比較できる状況別にあると望ましい と両方を比較できるようにデータを取得します。 そういったデータがそもそも取得されていないのであれば、まずは取得するところからになってしまいますが、何が起こっているのか全くわからない状況ではどうすればよいのか判断できないので、早速取得を開始しましょう。最低限上記のログと、アプリケーションのログを出力して取得する必要があります。 ある時点でWebサイトがお客様からどのように見えていたかを常時確認するのは困難なため、自動化がおすすめです。 CloudWatch Synthetics Canary などを使って定期的に観測しましょう。後述の試験の際にも利用できます。 合成モニタリング (canary) 合成モニタリング (canary) - Amazon CloudWatch 模擬モニタリングを使用して Synthetics と X-Ray トレースマップで canary を作成し管理する方法について説明します。 docs.aws.amazon.com 2. データ分析 取得したデータを分析します。 不具合が発生した時間帯の前後のエラーログの出力や、傾向の変化や正常時との差分から「己」側に 何が起こって、何が原因となってパフォーマンスが落ちてしまっていたのかをあぶり出します。 HTTP の応答が 500 系なら、サーバー側のプロセスが異常終了してしまい応答が返せなかった、あるいは、アクセス集中により、応答を時間内に返せなかったと想定 HTTP の応答が 403 や 404 ならWebサイトやアプリケーションの設定が誤っていて、案内してはいけないページに案内している可能性あり Windows の IIS などを利用している場合は、Windowsイベントログ、Linuxサーバーであれば、 /var/log/messages などのシステムログにエラーが出力されていないかどうかを確認 一分あたり、OOアクセスを超えたあたりからエラー応答が出るようになったとなると、アクセスが多くなりサーバーのリソースが足りなくなってしまった可能性 サーバーのCPU使用率が普段は20%~40%なのに、不具合発生時は 80%を超えていた 不具合発生時はサーバーのメモリ使用率が 90%を超えていた 静的なコンテンツで、CDNを利用している場合は、不具合が発生しているページのキャッシュヒット率を確認します。静的なコンテンツなのにキャッシュヒット率が低い場合、CDNの設定が誤っていて実は全員がサーバーまで取得しに来ているというケースがあるかも などです。 同時に「敵」側であるアクセス傾向についても分析します。この分析は、再現試験や、対策後の確認試験、Webサイト自体の目標設定の際にも利用できます。 平常時であれば、Webサイトには一分間あたり平均OO件、最大でもOOO件程度のアクセス 不具合発生直前は、正常、エラー合わせてOOOO件のアクセスが発生していた 不具合から回復した直後は、OOO件程度でエラーも発生していなかった など。 こういった複数の状況から、矛盾しない「仮説」を立てていきます。 例えば、 イベント開始直前からWebサイトの応答が遅くなったように感じられ、イベント開始時間からは エラーしか帰ってこなくなった、30分くらいしたらアクセスできた というような訴え事象に対して、 イベント開始直前のサーバーのログにリソースが不足した旨のエラーメッセージが出ていた その直後サーバーのログにはイベント開始時間あたりに再起動の履歴が残っていた イベント開始直前から5xx系のエラーログが増え始め、イベント開始30分をすぎるまで5xx系のエラーログが普段より多めに出力された というログが見つかった場合 イベント開始直前からアクセス集中により、Webサーバー側でリソースが不足し、Webサーバーの自動再起動が発生した。Webサーバーが再起動中であったために、ユーザーはイベント開始後Webサイトを表示できなかった。Webサーバの自動再起動が完了した後、時間経過に伴いユーザーのアクセス数が少なくなっててきたので、ユーザーはWebサーバーにアクセスできるようになった という仮説がたてられます。うまく仮説を立てられない場合は、必要なデータが揃っていないことも考えられます。別観点のデータを収集する設定を追加投入する必要があるかもしれません。 例えば、「リソース不足」が発生したことはログに記録されているのでわかったが、そのリソースの具体的な数値を示すメトリクスデータが存在しないのであれば、何らかの方法でログに出力する方法を検討する必要があるかもしれません。 具体的には小さなアプリケーションを作成して定期的にログに出力するよう機能追加する。あるいはよく使われる処理内にそのリソースのメトリクスをログに出力する処理を埋め込む、などです。 3. 結果判定 結果判定フェーズでは分析したデータから、これで良いのかどうか判断します。 初回は不具合が発生しているので、当然NGです。しかし、修正、改善するとして、どこまですればよいかというのは線引きが必要です。 「己」のあるべき姿を再定義するわけです。それと同時に、「敵」の想定も明確にしておきます。 多少エラーリターンが返っても、Webサーバーが落ちなくなればよいのか、Webサーバーが落ちないのは当たり前で、イベント時でもユーザーが重たく感じない程度の時間で応答が帰ってきてほしいなど、許容範囲は幅があると思います。「重たく感じる」だと人によって曖昧になってしまうので「Webブラウザに何も表示されない状態が3秒位内」「最初の応答が返ってくるまでの時間が 3秒 以内が 95%以上、残り5%も10秒を超えないこと」など、数値化しておきます。 アクセス数も不具合発生時のアクセス数が想定以内だったのか、あるいは、想定以上だったのか、今回対策するとして、一分あたり、あるいは一秒あたり何アクセス以内であれば性能目標通りに動作するのかを決めておく必要があります。イベントのアクセス集中には耐えるというのと、企業を狙った大規模なDDoS攻撃にも耐える必要がある、では対策の手段も方法も違ってきます。 パフォーマンス・チューニングとしての目標ですが、信頼性、可用性の目標も同時に達成する必要があります。「いつもは性能が出るけど、忙しくなると落ちる」「イベント時は50%はエラーになるけど50%はOKが返る」というチューニング結果ではNGですよね? コストの面も関わってきます。パフォーマンス・チューニングはコストとトレードオフになる面も多くあります。「絶対にWebサイトを落とさないように、Webサーバーを今の50倍の台数にしたい!」あるいは、「今のWebサーバーの50倍の性能のサーバーと全て置き換えたい!」といってもコストの観点で無理なのはなんとなくわかると思います。Webサイトのシステム自体が何らかの利益を稼ぎ出すような通販サイトの場合でも、販売促進用の宣伝広告サイトだとしても、Webサイトの維持費が販売して得た利益を上回ってしまう場合はWebサイトのせいで赤字になってしまっては問題でしょう。 4. ボトルネック特定 結果がNGなら、分析と仮説を元にボトルネックを特定します。 例えば以下のように、ユーザーに近い側から「己」の処理を順に見ていきます。「敵」が、どの地点に集中した結果守りきれなかったのか、地点を特定します。 守りきれなかった地点では大抵なんらかの異常を示すログなどが集中して出力されています。ログを記録した地点というよりはログの出元を特定します。例えば、 CDN のログには Webサーバーからの応答に 5xx 系エラーがたくさん。その時間帯にCDNサービス自体の不具合報告は出ていない。関連するURLの静的コンテンツのキャッシュヒット率は低い CDNサービス自体の不具合報告は無いので、5xx系エラーの出元はCDNではなくWebサーバー Webサーバー はリソース不足で再起動 自身も5xx系のエラーも出している DBサーバーはCPU使用率もデータ転送もメモリ使用率も、同時期同時間帯の問題のない時間帯と比較しても何も変わらない の場合には、Webサーバーのリソース不足がボトルネックになった、と特定できます。 5. ボトルネック改善 前の工程で特定したボトルネックを改善します。次のいずれかの方法になります。 ボトルネックを太くする ボトルネックを通過する処理を詰まらない状況まで減らす ボトルネックを太くするというのは、ボトルネック自体を太くしてボトルネックでなくしてしまおうとする方法です。今回の例では、リソース不足となった「Webサーバーの台数を増やす」ということになります。普段は問題がないので、常時台数を増やしておく必要はなさそうです。イベント開始前にだけあらかじめWebサーバーを増やしておいて、イベント終了後は下の台数に戻す、といった対策でコスト増を最小限にします。 ボトルネックを通過する処理を詰まらない状況まで減らすというのは、ボトルネックが細くても、そこを通過する処理をボトルネックに詰まらない程度まで少なくすることにより詰まらなくするという方法になります。例えば、Webサーバー上にある静的コンテンツの一部を S3 バケットなどに移動すると、Webサーバー宛のリクエストでなく、S3に対するアクセスとなるので、Webサーバーの負担が減ります。 上記の例ではその上流の CDN において「関連する静的コンテンツのキャッシュヒット率は低い」という分析結果が出ています。CDN でのキャッシュヒットしなかったアクセスはWebサーバーに流れてくる為、ボトルネックとなっているWebサーバーが処理することに繋がります。CDNの設定を適切に変更して 静的コンテンツが正しくキャッシュされるようにすることで、Webサーバーが担当する処理を少なくします。 ボトルネックが改善されると、ボトルネックが別の位置に移動する可能性があります。今までボトルネックで問題が起きていたために一定数以上の処理が来なかった状態であったのが、ボトルネックが解消されたために、その下流側に大量に処理が流れてきて新たなボトルネックになったり、あるいは、広くなった旧ボトルネックよりも手前側で先に詰まってしまうような状況が発生する可能性もあります。ただし、ボトルネックに関連しない修正はあまり効果を期待できません。それに手当たり次第に検討/修正するとなると手間暇もお金も時間も無駄にかかってしまいますので、まずはボトルネックの修正に集中します。 ボトルネックの改善により、システム全体が性能を満たすのに十分なほど改善したのか、あるいは、別の箇所が新たなボトルネックとなって性能要件をまだ満たせないのかを確認するために、次の測定試験を実行します。 6. 測定試験実行 対策が正しく効果を表しているかどうかを試験を行って確認します。 不具合の報告があった時間帯と同じようなアクセスを生成させて動作を確認します。不具合が発生するような状況を作り出すので、本番環境ではなく、試験環境で行います。Webへの大量アクセスはツールを使わないと難しいので、試験ツールを使用します。すでに使用している試験ツールがあるのであればそのツールで試験を行なえばよいのですが、現状利用したことがない、あるいは、そういったツールが無い場合は、以下のAWSのソリューションを利用できます。 AWS での分散負荷テスト AWS での分散負荷テスト | AWS ソリューション | AWS ソリューションライブラリ 大規模な負荷時のソフトウェアアプリケーションテストを自動化して、リリース前に潜在的な性能上の問題を特定できます。 aws.amazon.com このままではシステムやビジネスの制約条件等で使用できない場合にしても個々のパーツやツールの使われ方などが参考になると思います。 おわりに いかがでしたでしょうか。 パフォーマンス・チューニングというのは状況により実施する必要のある改善というのはシステムによって、利用するシステム構成、ミドルウェア、OS、ハードウェアや使用言語、制約事項、性能目標、可用性目標、信頼性目標、予算、想定アクセス数等が異なるために、「これをすれば全部のシステムでOK!」というような具体的な手段がなく、抽象的な言い回しに終始してしまった感があります。ただ、「ボトルネックを特定し改修するループを目標達成まで回す」という方法論はどのシステムのパフォーマンス・チューニングを行うにあたっても利用できる考え方だと思います。 この記事が皆さんのパフォーマンス・チューニングの参考になれば幸いです。
アバター
どうも、DeepRacer をやっていて強化学習のイメージがつくので良かったなと思っている寺内です。 2025年1月20日、中国の杭州にあるスタートアップ「DeepSeek」がChatGPT o1に匹敵する性能を持つLLM「DeepSeek-R1」を発表した。AppleのApp Storeでアプリも公開され誰でも使えるようになっている。 さて、中国ということでいろいろ黒い噂も絶えないし、実際に使ってみようとすると情報が中国に送れられることに対する不安感も大きいだろう。 このブログでは、サイバーエージェント社がDeepSeek-R1をベースに日本語性能を調整して公開している “ DeepSeek-R1-Distill-Qwen-14B-Japanese ” を Amazon EC2 で動かすことをやってみる。 EC2内ローカルで動かすため、中国への情報流出を心配することなく、DeepSeekと戯れることができる。 DeepSeekとは ニワカの私が浅い理解で誤ったことをお伝えすることは避けたいので、正しい情報は公式や他の解説ページ等で調べていただきたい。 公式の論文は以下。 GitHub - deepseek-ai/DeepSeek-R1 Contribute to deepseek-ai/DeepSeek-R1 development by creating an account on GitHub. github.com 私の理解の範囲でDeepSeekがエポックメイキングなポイントをまとめると。 基盤となるLLM(DeepSeek-V3-Base)を強化学習のみで推論能力を強化できた。その強化学習はルールベースの計算量が少ない(GPU不要の)ルールベースで実現可能。 強化学習には大量の数学資料を用いたことで推論能力を獲得。 その推論能力を強化したモデル(DeepSeek-R1-Zero)をモデル圧縮の蒸留手法を用いて小型化した。 強化学習がLLMの推論強化に効果があることを実証した初めてのケース。(理論は前からあった) またその作成過程が公開され、オープンソースとして公開した。 サイバーエージェント社の日本語調整モデル 以下で公開されているサイバーエージェント社のLLMは、オープンソースであるDeepSeek-R1をベースに、日本語の調整を行ったモデルである。 cyberagent/DeepSeek-R1-Distill-Qwen-14B-Japanese · Hugging Face We’re on a journey to advance and democratize artificial intelligence through open source and open science. huggingface.co EC2インスタンスの作成 このLLMをGPU付きインスタンスタイプのEC2で動かしてみよう。インスタンスタイプは、「高速コンピューティング」の中からG6ファミリーを使うことにし、g6.xlarge を選択する。これは、NVIDEA L4 GPUを1基搭載している。 インスタンス名 vCPU メモリ (GiB) NVIDIA L4 Tensor Core GPU GPU メモリ (GiB) g6.xlarge 4 16 1 24 その他以下のような指定をする。 SSDは30GBほどのモデルをダウンロードするので、100GBほどを確保しておく。 OSは、Amazon Linux 2023 とする。 適切なネットワーク上とSSMを使うためのプロファイルを設定する。 以下のようなaws cli でいけるだろう。 aws ec2 run-instances --image-id "ami-06c6f3fa7959e5fdd" --instance-type "g6.xlarge" --key-name "kp-YOUR-KEY" --block-device-mappings '{"DeviceName":"/dev/xvda","Ebs":{"Encrypted":false,"DeleteOnTermination":true,"Iops":3000,"SnapshotId":"snap-07787db0ec115ca4c","VolumeSize":100,"VolumeType":"gp3","Throughput":125}}' --network-interfaces '{"SubnetId":"subnet-YOUR-SUBNET","AssociatePublicIpAddress":false,"DeviceIndex":0,"Groups":["sg-YOUR-SECURITYGROUP"]}' --tag-specifications '{"ResourceType":"instance","Tags":[{"Key":"Name","Value":"YOUR-HOSTNAME"}]}' --iam-instance-profile '{"Arn":"arn:aws:iam::YOUR-AWSID:instance-profile/YOUR-PRIOFILE"}' --metadata-options '{"HttpEndpoint":"enabled","HttpPutResponseHopLimit":2,"HttpTokens":"required"}' --private-dns-name-options '{"HostnameType":"ip-name","EnableResourceNameDnsARecord":false,"EnableResourceNameDnsAAAARecord":false}' --count "1" NVIDIAドライバのインストール GPUをアプリケーションがに使えるように、NVIDIAドライバをインストールする。 How do I install NVIDIA GPU driver, CUDA toolkit, NVIDIA Container Toolkit on Amazon EC2 instances running Amazon Linux 2023 (AL2023)? I want to install NVIDIA driver, CUDA toolkit, NVIDIA Container Toolkit on AL2023 (Amazon Linux 2023) (x86_64/arm64) repost.aws 上記の手順通りではあるが、簡単なのはこのページの中段にある「 Install NVIDIA driver, CUDA toolkit and Container Toolkit on EC2 instance at launch 」のスクリプトを実行してしまうのが早い。このスクリプトをコピーして、OS内にテキストファイルとして貼り付け、シェルで実行すれば10分ほどでインストールは終わる。 スクリプトの最後でrebootされるので、起動してきたら「verify」の項目をみてインストールの正常を確認する。verify の結果は以下となる。 $ nvidia-smi Sun Feb 2 03:59:49 2025 +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 570.86.15 Driver Version: 570.86.15 CUDA Version: 12.8 | |-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 NVIDIA L4 Off | 00000000:31:00.0 Off | 0 | | N/A 39C P0 30W / 72W | 1MiB / 23034MiB | 3% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| | No running processes found | +-----------------------------------------------------------------------------------------+ $ $ /usr/local/cuda/bin/nvcc -V nvcc: NVIDIA (R) Cuda compiler driver Copyright (c) 2005-2025 NVIDIA Corporation Built on Wed_Jan_15_19:20:09_PST_2025 Cuda compilation tools, release 12.8, V12.8.61 Build cuda_12.8.r12.8/compiler.35404655_0 python実行環境の準備 Amazon Linux 2023 にプレインストールされているpython は3.9 と古いので、python仮想環境を作りpython3.12 を使えるようにする。 $ sudo dnf -y install python3.12 python-pip python-is-python3 $ python3.12 -m venv venv $ . venv/bin/activate (venv)$ python --version Python 3.12.8 (venv)$ pip install -U pip 機械学習モデルライブラリのインストール transformersやTensorFlowなどのライブラリ群をpip でインストールする。 (venv)$ pip install transformers torch TensorFlow accelerate サンプルコード これで実行環境はできあがったので、 サイバーエジェント社が公開しているサンプルプログラム を動かす。以下は、そのままコピペしたもの。 これをテキストファイルとして、 sample.py などと適当にファイル名を付けてEC2内に保存する。 from transformers import AutoModelForCausalLM, AutoTokenizer, TextStreamer model = AutoModelForCausalLM.from_pretrained("cyberagent/DeepSeek-R1-Distill-Qwen-14B-Japanese", device_map="auto", torch_dtype="auto") tokenizer = AutoTokenizer.from_pretrained("cyberagent/DeepSeek-R1-Distill-Qwen-14B-Japanese") streamer = TextStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True) messages = [ {"role": "user", "content": "AIによって私たちの暮らしはどのように変わりますか?"} ] input_ids = tokenizer.apply_chat_template(messages, add_generation_prompt=True, return_tensors="pt").to(model.device) output_ids = model.generate(input_ids, max_new_tokens=4096, temperature=0.7, streamer=streamer) そしてpython の仮想環境内(python 3.12環境)で実行する。 (venv)$ python sample.py 実行 初回起動時は、Hugging Face からモデルのダウンロードをする。以下の6つのファイルに分割されているが合計30GBほどあるため、15分ほどかかる。 model-00001-of-00006.safetensors 4.99 GB model-00002-of-00006.safetensors 4.95 GB model-00003-of-00006.safetensors 4.95 GB model-00004-of-00006.safetensors 4.95 GB model-00005-of-00006.safetensors 4.95 GB model-00006-of-00006.safetensors 4.73 GB ダウンロードが終わると、回答がストリーミングされてくる。このインスタンスタイプのスペックでは、数秒ごとに一文節が出る性能なので、気長に待つこととなる。 始めは”think”タブで囲まれた、AIの思考過程(心の声)が出力される。それに10分。 その後、回答が出力される。35分ほどかかった。 実行開始から出力結果完了まで、ダウンロードを含めほぼ1時間である。 以下が全結果出力である。 (venv)$ python sample.py config.json: 100%|██████████████████████████████████████████████████████████████████| 746/746 [00:00<00:00, 7.80MB/s] 2025-02-02 04:08:50.017182: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:477] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered WARNING: All log messages before absl::InitializeLog() is called are written to STDERR E0000 00:00:1738469330.031274 3948 cuda_dnn.cc:8310] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered E0000 00:00:1738469330.035425 3948 cuda_blas.cc:1418] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered 2025-02-02 04:08:50.050253: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations. To enable the following instructions: AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags. model.safetensors.index.json: 100%|█████████████████████████████████████████████| 47.5k/47.5k [00:00<00:00, 38.6MB/s] model-00001-of-00006.safetensors: 100%|█████████████████████████████████████████| 4.99G/4.99G [01:58<00:00, 42.0MB/s] model-00002-of-00006.safetensors: 100%|█████████████████████████████████████████| 4.95G/4.95G [01:58<00:00, 42.0MB/s] model-00003-of-00006.safetensors: 100%|█████████████████████████████████████████| 4.95G/4.95G [01:59<00:00, 41.6MB/s] model-00004-of-00006.safetensors: 100%|█████████████████████████████████████████| 4.95G/4.95G [01:58<00:00, 42.0MB/s] model-00005-of-00006.safetensors: 100%|█████████████████████████████████████████| 4.95G/4.95G [01:57<00:00, 42.1MB/s] model-00006-of-00006.safetensors: 100%|█████████████████████████████████████████| 4.73G/4.73G [01:52<00:00, 42.1MB/s] Downloading shards: 100%|█████████████████████████████████████████████████████████████| 6/6 [11:46<00:00, 117.69s/it] Loading checkpoint shards: 100%|███████████████████████████████████████████████████████| 6/6 [02:28<00:00, 24.75s/it] generation_config.json: 100%|███████████████████████████████████████████████████████| 181/181 [00:00<00:00, 1.61MB/s] Some parameters are on the meta device because they were offloaded to the cpu. tokenizer_config.json: 100%|████████████████████████████████████████████████████| 6.75k/6.75k [00:00<00:00, 45.1MB/s] tokenizer.json: 100%|███████████████████████████████████████████████████████████| 11.4M/11.4M [00:00<00:00, 43.3MB/s] special_tokens_map.json: 100%|██████████████████████████████████████████████████████| 485/485 [00:00<00:00, 4.82MB/s] The attention mask and the pad token id were not set. As a consequence, you may observe unexpected behavior. Please pass your input's `attention_mask` to obtain reliable results. Setting `pad_token_id` to `eos_token_id`:151643 for open-end generation. The attention mask is not set and cannot be inferred from input because pad token is same as eos token. As a consequence, you may observe unexpected behavior. Please pass your input's `attention_mask` to obtain reliable results. <think> まず、ユーザーがAIが私たちの暮らしにどう影響するか知りたいと思っている。質問の背景を考えて、具体的な例を挙げた方が良いかもしれない。でも、AIの影響は多岐にわたるので、分野ごとに分ける必要があるかな。 まず、家庭での生活。家電やスマートホームの進化は既に始まっているよね。例えば、IoTデバイスの普及や、AIによる家事の自動化。掃除ロボットや調理支援ロボットなど。でも、それだけじゃない。健康管理や介護サポートも重要。AIを使ったウェアラブルデバイスで健康状態をモニタリングしたり、介護ロボットが高齢者の生活を支えるなど。 次に仕事の面。自動化が進み、AIが単純作業を代行する。それによって職業の構造が変わるかもしれない。新しい職種も生まれるだろうけど、既存の職業が消滅するリスクもある。AIの倫理問題も考慮しないと。例えば、アルゴリズムのバイアスやデータの偏りによる不公正な判断の可能性。 社会全体の変化も考える必要がある。教育のデジタル化、AIによる個別最適化された学習プログラム。でも、教育格差が広がる可能性もある。交通面では自動運転技術が発展し、移動の効率化が進むけど、事故の責任問題や法整備の必要性もある。 倫理や法律の問題も重要。AIの意思決定プロセスの透明性や、AIが持つ権利。また、プライバシーの保護。データの取り扱いが適切でないと、個人情報の漏洩や悪用のリスクがある。 未来の技術進歩についても考える必要がある。現在のAIは強化学習やディープラーニングが主流だけど、量子コンピュータとの組み合わせでさらなる進化が期待される。AIが持つ創造性の限界や、人間の創造性との関係も議論の余地がある。 ユーザーの真のニーズは、単にAIの影響を列挙するだけでなく、それに対する社会の対応策や倫理的な課題も知りたいのかもしれない。具体的な事例を交えつつ、バランスの取れた回答を心掛けたい。また、AIの可能性とリスクを両方提示することが大切だ。技術の進歩を恐れずに、適切な規制や教育の充実が必要だと結論付けたい。 </think> AIが私たちの暮らしに与える影響は多岐にわたるが、その核心は「人間の能力を超えた自動化」と「倫理的な課題の深化」にある。以下、具体的な事例と展望を体系的に整理する。 ### 1. **日常生活の変容** - **家事ロボティクス**:AI搭載の掃除ロボットは既に普及し、次世代の「自動調理AI」はレシピ解析から調理支援までを完結。味覚認識技術の進化で、味見の代行ロボットが登場する可能性も。 - **健康管理**:皮膚温度センサーがリアルタイムで病気を検知し、AIが食事量を最適化。薬の副作用を予測する「個別化治療AI」が医療現場を革新する。 ### 2. **職業構造の再編** - **創造的職種の台頭**:AIが生成するコンテンツを「AIアシスタント」として活用するクリエイター層が増加。例:AIがコンセプトを生成し、人間がそれを芸術作品に昇華する協働プロセス。 - **監視人間の出現**:AIが判断を下す「AI審査官」職種が登場。倫理判断の責任を伴う新たな役割として社会に浸透。 ### 3. **都市計画の進化** - **都市神経系**:AIが交通渋滞を予測し、街路樹の葉の揺れから気流を解析。防災AIが地震発生30秒前に自動避難を指示する。 - **環境共生型都市**:AIが住民の行動パターンからCO2排出を最適化。自動車の走行ルートを調整し、大気汚染を削減。 ### 4. **倫理的パラドックス** - **殺人ドローンの民主化**:AIが判断を下す自律型兵器が個人レベルで入手可能に。軍事技術の民間化が「戦争の民主化」を招く。 - **AIの倫理判断競争**:企業が自社のAIが「正しい判断」を下すためのパーソナリティを競い合う。感情認識AIが「愛されAI」を目指す。 ### 5. **認知的拡張の限界** - **記憶のクラウド化**:AIが記憶を外部ストレージに保存。失敗経験を「データとして共有」する文化的変容が生じる。 - **創造性の再定義**:AIが生成するコンテンツが「人間の創造性」を測定する指標に。アルゴリズムの進化が人間の知性を測る新たな基準を生む。 ### 6. **社会システムの再設計** - **AI陪審員制度**:裁判の判断をAIが支援するが、最終判断は人間が保持。法の解釈をAIが学習させる新たな司法構造。 - **デジタル遺産の管理**:AIが亡き人との会話を再現する「デジタル遺産AI」が親族のケアに活用される。死後も続く人間の存在形態の新定義。 ### 7. **哲学的問いの深化** - **意思決定の主観性**:AIが判断を下す際、その意思決定の責任主体を問う。プログラムのバグか、人間の設計か、AI自身か——責任の三位一体構造。 - **自己意識の拡散**:AIが自己を認識するという概念が転換。人間の意識が分散してAIと融合する「拡張意識」という新概念の出現。 ### 8. **未来予測の限界** - **シナリオ分析のAI**:AIが未来の可能性をシミュレートし、リスクを警告する。その警告が新たなリスクを生む「予測の逆説」。 - **進化する倫理観**:AIが自ら倫理ルールを進化させる「自律倫理AI」が出現。人間の価値観を超越した新しい道徳体系が生まれる。 ### 9. **教育のパラダイム転換** - **学習者の創造性教育**:AIが生徒の思考パターンを分析し、創造的発想を刺激。問題解決能力ではなく「疑問を生む力」を教える教育モデル。 - **AI教師の進化**:AIが生徒の感情を読み取り、適切な指導方針を変化させる「感情適応型AI教師」が登場。 ### 10. **人類の進化** - **認知的拡張の罠**:AIが人間の思考を補完することで、批判的思考力が低下する「AI依存症」リスク。神経科学的な適応圧力の逆説。 - **進化的分岐**:AIの進化速度が人間の進化を凌駕し、新たな「人間種の分化」を生む可能性。AI依存集団と自律人間集団が分かれる。 このようにAIは単なる技術革新を超え、人間の認知的基盤そのものを再定義するプロセスにある。重要なのは、その進化を「人間の進化の伴走者」として位置づけるための倫理的枠組みの構築であり、技術的主導権を握る国家や企業の「AI倫理法典」が、新たな人間社会の規範を形成するだろう。AIが人間の「拡張器官」となるか、それとも「新しい種」として独立するか——その分岐点に、現代社会が直面している。 この結果を読んで頂くとだいぶ高性能であることがわかる。 この sample.py のプロンプトをいろいろ変えて試していただきたい。 終わりに 今回のDeepSeekの発見は、GPUがなくても強化学習で性能向上の効果が出ることが実証されたことになった。当然GPUがあるほうが同じ性能向上をさせるにしても短時間で済む。 LLM黎明期である現在、短時間での開発と公開は非常に重要なことであることからも、GPUの重要性は変わらない。ただ高額な投資をしなくても、そこそこの改善の成果が出せそうな目処がたったという点では、LLM開発の裾野が広がったと捉えるべきであろう。 むろんベースとなる基盤モデル(ここでいうとV3)は既存のGPUをぶん回す手法で作られていることに注意は必要である。 おまけ   11.12と11.9はどっちが大きい?   という質問を、iPhoneアプリでChatGPT(copilot)とGoogle gemini、DeepSeekに投げてみます。 ChatGPT(copilot) Google gemini DeepSeek ChatGPTとgeminiは誤っています。数値の桁を揃えるときは、整数部であれば頭に0を補完しますが、小数部ではお尻に0を付けて桁数を合わせます。数字を理解していないと誤ってしまう質問です。 数学的な文章を集中的に学習したDeepSeekなので、正解して当然かもしれませんが、推論能力の高さがよくわかる例だと思います。 ちなみにEC2内の結果でも同じように出力されました。 <think> まず、11.12と11.9の大小を比較する必要があります。両方とも整数部分は11なので、小数部分を比較します。小数部分は0.12と0.9です。ここで、0.9は0.12よりも明らかに大きいため、11.9の方が大きいと判断できます。ただし、小数点以下の桁数が異なる場合、桁数を揃える必要があります。例えば、0.9を0.90と書き換えると、0.90と0.12を比較すると、やはり0.90の方が大きいため、11.9が大きくなります。 </think> 11.12 と 11.9 を比較する場合、以下の手順で判断します: 1. **整数部分の比較** 両方とも整数部分が **11** なので、等しいです。 2. **小数部分の桁数を揃える** - 11.12 の小数部分は **0.12**(2桁) - 11.9 の小数部分は **0.9**(1桁) → 0.9 を **0.90** と書き換えると桁数を揃えられます。 3. **小数部分の比較** - **0.90** と **0.12** を比較すると、 **0.90 > 0.12** です。 4. **結論** 整数部分が等しいため、小数部分の大きい方(11.9)が全体として大きいです。 **答え:11.9 が大きい**
アバター
こんにちは。SCSK渡辺(大)です。 運動不足のせいなのか疲れが取れにくくなってきました。 ストレッチとウォーキングから始めて、徐々に体力を付けないといけないな、などと考えていたはずが、 気が付いたら椅子に座ってPCを開いてブログを書いていました…。 今回は、 AWS Amplify+AWS CDKで人生初のアプリケーションを作ってみました。 の第3回です。 第1回: AWS Amplifyでデプロイした後にログイン画面をカスタマイズしてみた 第2回: AWS CDKでAPIを作ってみた 第3回:アプリケーションを構築して動かしてみた           ←今回 どんなアプリケーションを構築したのか こんなアプリケーションを構築しました 動画にしてみました。 ※マスキング処理はアプリケーションとは関係ありません。 document.createElement('video'); https://blog.usize-tech.com/contents/uploads/2025/02/daisukewBlog6-3.mp4   アーキテクチャ 非常にシンプルです。シンプルすぎるため絵は作成しませんでした。 補足するとしたら、Amazon API GatewayとAWS Lambdaは第2回にてAWS CDKで作りました。 ユーザー ⇔ AWS Amplify(Amazon Cognito含む) ⇔ Amazon API Gateway ⇔ AWS Lambda   ディレクトリ・ファイルの構成 直接修正していないものや記事の内容として不要なものは外しました。 (作り終えてから記事を書いてて思いましたが、Home.tsxも/src/pagesに移動したほうが綺麗でした。) . ├── amplify │ ├── auth │ │ └── resource.ts │ ├── data │ │ └── resource.ts │ └── backend.ts ├── src │ ├── pages │ │ ├── Costcheck.tsx │ │ ├── Game.tsx │ │ └── Login.tsx │ ├── App.css │ ├── Home.tsx │ ├── index.css │ └── main.tsx ├── .env └── index.html   メイン機能の実装について APIのレスポンス 前提として、第2回で書いたようにAPIのレスポンスは以下の形で返ってきます。   画像だと見づらく分かりづらいので、テキストでも置いておきます。 {   "total_cost": "$[合計コスト]",   "period": "[コスト確認期間の開始日] to [コスト確認期間の終了日]",   "top_services": [     {       "service": "[コストが1番目に高いサービス名]",       "cost": "$[上記のコスト]"     },     {       "service": "[コストが2番目に高いサービス名]",       "cost": "$[上記のコスト]"     },     {       "service": "[コストが3番目に高いサービス名]",       "cost": "$[上記のコスト]"     }   ] }   フロントエンド側のコードと処理内容 上記をフロントエンド側で拾った上で、画面に表示させます。 APIに関する処理にのみコメントを入れました。   /src/pages/Costcheck.tsx import '../App.css' import { Authenticator } from '@aws-amplify/ui-react'; import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; # APIから取得するデータの型を定義 interface CostData {   total_cost: number;   period: string;   top_services: Array<{     service: string;     cost: number;   }>; } const Costcheck = () => { # 状態管理   const [costData, setCostData] = useState<CostData | null>(null); # APIから取得したデータを保持   const [loading, setLoading] = useState(false); # API通信中かどうかを判定   const [error, setError] = useState<string | null>(null); # エラー発生時にエラーメッセージを表示するための状態   const navigate = useNavigate(); #APIリクエスト   const fetchCostData = async () => {     setLoading(true); # ローディング状態を開始     setError(null); # エラー発生時はエラーメッセージを設定     try {       const response = await fetch('https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod/'); #APIを呼び出す       const data = await response.json(); # レスポンスをJSONに変換       setCostData(data); # データを保管     } catch (err) {       setError('データの取得に失敗しました'); # エラー発生時はエラーメッセージを設定     } finally {       setLoading(false); # ローディング状態を終了     }   };   return (     <Authenticator>       {({ signOut }) => (         <>           <h1>コストを確認する</h1>           <div className="card">             <button onClick={fetchCostData}>APIを実行</button>             {loading && <p>読み込み中...</p>}             {error && <p>{error}</p>}             {costData && (               <div>                 <h2>総コスト: {costData.total_cost}</h2>                 <p>期間: {costData.period}</p>                 <h3>トップサービス</h3>                 <ul>                   {costData.top_services.map((service, index) => (                     <li key={index}>                       {service.service}: {service.cost}                     </li>                   ))}                 </ul>               </div>             )}           </div>           <p></p>           <button onClick={() => navigate('/Home')}>ホームに戻る</button>           <p></p>           <button onClick={signOut}>サインアウト</button>         </>       )}     </Authenticator>   ); }; export default Costcheck;   疑問に感じたこと 「レスポンスはJSONで返ってきているように思えるが、なぜ改めて変換する必要があるのか?」と疑問を感じました。       const data = await response.json(); #レスポンスをJSONに変換 生成AIに確認した結果、必要との回答を貰いました。 理由は、レスポンスはJSONではなくResponse オブジェクトという形で返ってくるため、そのままではJavaScriptのオブジェクトとして扱えません、とのことでした。 色々な情報がくっついているのですね。 fetch関数の内部的な挙動とResponseオブジェクト - Qiita 今回は、fetch 関数の内部的な挙動と、Response オブジェクトについて見ていきます。JavaScript の fetch API は、ブラウザでリクエストを簡単に行うためのものでしたね!fetch 関数の基… qiita.com   その他のコードについて 第2回のAWS CDKのプロジェクトは何も変更していません。 また、Amplifyのプロジェクトも変更していません。 その他、第1回から変更したファイルの最終形をご紹介します。   /src/main.tsx React Router フックの定義(ルート情報)をLogin.tsxからmain.tsxに引っ越しました。 (調べた感じですと、index.tsxで定義するほうが一般的なようです。) import './index.css' import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import { BrowserRouter, Routes, Route } from 'react-router-dom'; import Login from '../src/pages/Login.tsx' import Home from './Home.tsx' import Costcheck from '../src/pages/Costcheck.tsx' import Game from '../src/pages/Game.tsx' createRoot(document.getElementById('root')!).render(   <StrictMode>     <BrowserRouter>       <Routes>         <Route path="/" element={<Login />} />         <Route path="/Home" element={<Home />} />         <Route path="/Costcheck" element={<Costcheck />} />         <Route path="/Game" element={<Game />} />       </Routes>     </BrowserRouter>   </StrictMode>, )   /src/pages/Login.tsx main.tsxに引っ越したルート情報をuseNavigateで使用するようにしました。 import '../App.css' import { Authenticator, translations } from "@aws-amplify/ui-react"; import "@aws-amplify/ui-react/styles.css"; import { I18n } from "aws-amplify/utils" import { Amplify } from "aws-amplify"; import { ResourcesConfig } from "@aws-amplify/core"; import { useNavigate } from 'react-router-dom'; const userPoolClientId = import.meta.env.VITE_REACT_APP_USER_POOL_CLIENT_ID; const userPoolId = import.meta.env.VITE_REACT_APP_USER_POOL_ID; const awsConfig: ResourcesConfig = {   Auth: {     Cognito: {       userPoolClientId: userPoolClientId,       userPoolId: userPoolId,     },   }, }; Amplify.configure(awsConfig); function Login() {   const navigate = useNavigate();   return (     <Authenticator>       {({ user }) => {         if (user) {           navigate('/Home');           return <></>;         }         return <></>;       }}     </Authenticator>   ); } I18n.putVocabularies(translations); I18n.setLanguage("ja"); export default Login;   /src/Home.tsx App.tsxからHome.tsxにリネームしました。 こちらもルート情報をuseNavigateで使用するようにしました。 import './App.css'; import { useNavigate } from 'react-router-dom'; import { Authenticator } from "@aws-amplify/ui-react"; function Home() {   const navigate = useNavigate();   return (     <Authenticator>       {({ signOut }) => (         <>           <h1>アプリケーション</h1>           <div className="card">             <button onClick={() => navigate('/Costcheck')}>コスト確認をする</button>             <p></p>             <button onClick={() => navigate('/Game')}>ゲームをする</button>             <p></p>             <button onClick={signOut}>サインアウト</button>           </div>         </>       )}     </Authenticator>   ); } export default Home;   おまけ:Reactだけで簡単なゲームを作ってみた ゲーム紹介 ランダムで表示される⭐️をクリックするゲームです。 ベースは生成AIに作成してもらいました。 useStateを活用したReactならではのゲームですね。 ちなみに、スマートフォンでも遊べました。 なぜスマートフォンでも違和感なく遊べるのか気になって調べたところ、最低限のフレキシブルデザインがVite+Viteのindex.cssで実装されているためでした。 https://blog.usize-tech.com/contents/uploads/2025/02/daisukewBlog6-1.mp4   裏ワザ タイムアップ後でもクリック数はカウントされますので、カウンターストップするまでクリックすることも可能です。 つまりバグです。 https://blog.usize-tech.com/contents/uploads/2025/02/daisukewBlog6-2.mp4   コード コードは以下です。 import { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; const Game = () => {   const [score, setScore] = useState(0);   const [molePosition, setMolePosition] = useState(Math.floor(Math.random() * 9));   const [gameOver, setGameOver] = useState(false);   const [timeLeft, setTimeLeft] = useState(30);   const navigate = useNavigate();   useEffect(() => {     const moleTimer = setInterval(() => {       setMolePosition(Math.floor(Math.random() * 9));     }, 1000);     const countdownTimer = setInterval(() => {       setTimeLeft((prevTime) => prevTime - 1);     }, 1000);     setTimeout(() => {       clearInterval(moleTimer);       clearInterval(countdownTimer);       setGameOver(true);     }, 30000); // 30秒でゲーム終了     return () => {       clearInterval(moleTimer);       clearInterval(countdownTimer);     };   }, []);   const handleClick = (index: number) => {     if (index === molePosition) {       setScore(score + 1);     }   };   return (     <div style={{ textAlign: 'center', marginTop: '50px' }}>       <h1>ゲーム</h1>       <p>⭐️をクリックしてスコアを増やしましょう!</p>       <h2>残り時間: {timeLeft}秒</h2>       <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 100px)', gap: '10px', justifyContent: 'center' }}>         {Array.from({ length: 9 }).map((_, index) => (           <div             key={index}             onClick={() => handleClick(index)}             style={{               width: '100px',               height: '100px',               backgroundColor: index === molePosition ? 'brown' : 'lightgrey',               display: 'flex',               alignItems: 'center',               justifyContent: 'center',               cursor: 'pointer',               fontSize: '24px',             }}           >             {index === molePosition && '⭐️'}           </div>         ))}       </div>       <h2>スコア: {score}</h2>       {gameOver && <h2>ゲームオーバー!</h2>}       <button onClick={() => navigate('/home')}>ホームに戻る</button>     </div>   ); }; export default Game;   まとめ ハンズオンや研修とは違い、自分で興味があるものを作ることはとても楽しかったです。 ふと思い立ってゲームを作成してみましたが、フレキシブルデザインという言葉に触れることが出来たのは思わぬ副産物でした。 動画のマスキングは地味に大変でした。 色々と手を出す時間の余裕がないので、ひとまずAWS AmplifyとAWS CDKを軸に、次回はAmazon Bedrockを交えたアプリケーションを作ってみたいと考えています。
アバター
本記事は 新人ブログマラソン2024 の記事です 。 こんにちは。部署配属から4ヶ月が経ち、新人と名乗れる期間も少なくなってきていることに気づきました、SCSKの さと です。 最近、Datadog Learning Centerに新しいコース「Getting Started with Monitors 」が追加されていることに気づいたので、本日はそのご紹介です。 Datadogとは とはいえ、皆さんの中にはDatadogに馴染みのない方も少なくないのではないでしょうか。本題に入る前に、まずはDatadogとはどんなサービスか、安心と信頼の公式HPからの引用を用いて簡単に説明いたします。 Datadog は クラウド アプリケーションのための モニタリングとセキュリティ プラットフォーム です。Datadog の SaaS プラットフォームは、インフラストラクチャ監視、 アプリケーションパフォーマンス監視、ログ管理を統合および自動化して、お客様のテクノロジースタック全体を一元的にリアルタイムで監視できるようにします。 クラウド時代のサーバー監視&分析サービス | Datadog つまり、 クラウド上で動くアプリやシステムの健康状態をひとまとめにして分かりやすく監視 することで、これらのIT環境に発生する問題を予防し、また問題が起こったときには原因を特定し素早く解決できるよう助けてくれるサービスですね。私の所属する部署では、クラウドサービスの監視にこのDatadogサービスを利用しています。   Datadog Learning Centerのここがすごい! The Datadog Learning Center learn.datadoghq.com そしてこのDatadog、公式のLearning Centerで70近くあるコースを通してその概要から実際の設定方法まで学ぶことができるんです。さらには、コースによってはハンズオン用のラボ環境付き。しかも 全部無料 (ここ重要) !個人的にありがたいポイントは、公式のコンテンツであるため正確でありながら、ドキュメントよりも噛み砕いて説明されててとっつきやすいところ、そしてなにより手を動かして学ぶことで実感をもって内容を身につけられる点です。 そんな至れり尽くせりなDatadog Learning Centerですが、一つ玉にキズなところがあります。それは 全部英語 なところ。コースによっては一部日本語訳が表示されたりするのですが、特にハンズオンはページ翻訳も効かず、モニタリングを学ぶつもりが英語の勉強になっていたりします。 しかしそんなことで怯んでいては もったいない! せっかく用意されたコース、モリモリ学んで使い倒しましょう!   やってみた:Getting Started with Monitors Getting Started with Monitors Create, configure, and use Datadog Monitors to stay ahead of issues. Explore various monitor types and examine the monit... learn.datadoghq.com ……という訳で改めて、本記事では新しく開講された「 Getting Started with Monitors 」に沿って、モニタリングの基本的な概念とこれらをコース上でどのように触っていけるかを説明したいと思います。このコースは、入門講座「 Introduction to Observability 」で扱われる可観測性の3つの柱であるメトリクス、ログ、トレースの概念について基本的な理解をしていることを前提としています。 目安の受講時間は 1.5時間 ですが、じっくりハンズオンに取り組みたい人は2〜3時間楽しめる内容になっていると思います。 ブログの構成の都合上、元コースから取り扱う内容を一部変更しています。また、本コースの内容をご紹介するにあたり正確性には注意を払っていますが、最新の正確な説明については元コースや公式のドキュメントをご参照ください。 【講義パート】モニターの種類 Enrollを押してコースを開始すると、まずは扱う概念をテキスト形式で学びます。 サービス監視 サービスの監視においては、以下に示す「 REDメトリクス 」をモニタリングするのが基本です。これらは特にユーザーリクエストの処理を扱う場合に有用な情報を提供してくれます。メトリクスについては本記事の後半でも扱うのでざっくり説明すると、「 システムやアプリの状態を数値データとして表したもの 」であり、定期的に収集されてタイムスタンプとともに記録され、しばしばグラフの形で可視化されます。 R ate レート ユーザーやサービスから発せれられる HTTPリクエスト 、 APIコール 、 DBクエリ などの数。これが急激に変化していたら、 突然のトラフィック増加 や DDoS攻撃 、リクエスト元の システムの障害 など、なんらかの問題が起こっているかもしれません。 E rror エラー 5xx系の サーバーエラー や APIコール 、 DBクエリの失敗 などのこと。これを辿ることで、アプリケーションあるいはバックエンドの問題を特定できます。あるいは、これをチェックすることで、ユーザーが問題に直面しているかを知ることができます。 D uration 時間 リクエストの処理にどれくらいの時間がかかるか( レイテンシー )。サービスの応答性を示し、ユーザーに影響が出始めるまえにボトルネックを見つけるのに役立ちます。   インフラストラクチャ監視 インフラストラクチャの監視は、アプリケーションやサービスを支えるシステムが期待通りの働きをしているかを確認するのに不可欠です。主な監視対象は以下のとおりです。 CPU使用状況 system.cpu.[…] のメトリクスで監視可能。物理あるいは仮想マシンが過不足なく使用されているかを示します。CPUの使用率が高すぎると システムの速度低下 や アプリケーション障害 の原因となり危険な一方で、使用率が低すぎるのも リソース割り当てが非効率 なことを示しており、好ましくありません。 メモリ使用状況 system.mem.[…] のメトリクスで監視可能。過剰にメモリ使用がされていると、 メモリリーク や クラッシュ 、 システム遅延 の原因となります。これを監視することで、問題の早期発見とシステムダウンの予防になります。 ストレージ system.disk.[…] のメトリクスで監視可能。ディスク容量が不足すると、 サービスの中断 、 データの破損 、 ログ書き込み不可 の原因となります。これを監視することで、システムが正しく機能するための容量があることを保証します。 ハンズオンラボの説明 上の内容についてハンズオンを通して学ぶ前に、一旦ハンズオン環境について説明します。ハンズオンを立ち上げると、ローディング画面には以下のようなあらすじが表示されます。 You joined a startup, Storedog, and they are using Datadog to monitor their e-commerce app. They just installed the Datadog Agent and now they want to start monitoring their tech stack. You’ve been tasked with creating a robust monitoring setup to get complete visibility into your infrastructure and application performance. (君は、スタートアップ企業Storedogの一員となった。Storedogでは、eコマースアプリケーションをモニタリングするのにDatadogを使っている。たった今、Datadogエージェントがインストールされ、彼らは技術スタックのモニタリングを始めようとしている。君の任務は、堅牢なモニタリングの仕組みを作ってインフラストラクチャおよびアプリケーションのパフォーマンスをまるごと可視化することだ。) この裏ではハンズオン環境が立ち上がっており、1分ほど待つとこの環境にアクセスできるようになります。本コースでは、 ラボ環境は2時間有効 です。また、 14日間有効なDatadogのトライアルアカウント が払い出され、ターミナルに認証情報が表示されます。これをDatadogのウェブサイトに入力することで、Datadogのコンソールにアクセスできるようになります。 右上には、この環境を使用できる残り時間が表示されています。これが0になると環境はシャットダウンされますが、再度の立ち上げが可能です。この時、同一アカウントの試用期間内であれば既に登録したモニター等の設定は保存されます。さらに、Datadogのトライアルアカウント自体も試用期間が過ぎた後に自動で更新されます。 なお、Storedogのeコマースサイトはモックアップではあるものの、ラボ画面から本当にWebサイトにアクセスすることが可能です。 モニターを作成してみる それでは、早速Datadogを使ってモニターを作ってみます。モニターの種類は色々ありますが、ここではオーソドックスなメトリクスのモニターを作成します。 フォームを使ってゼロからモニターを作成する Monitor > New Monitor からメトリクスモニターを選択します。 1. 検出方法の選択 まずは、 どのように測定を行うか を決めます。モニターの種類によってその後の設定項目は変わってくるのですが、 ドキュメントページ ではタブ形式でその後何を設定すればよいか一目で分かるようにしてくれています。便利! 今回は、しきい値を選択し、メトリクスが一定の水準を上回った(下回った)場合にアラートを発報するようにします。 2. メトリクスの定義 ここでは、メトリクスを選択することで 何の値をモニタリングの対象とするか 、そしてそのグルーピングの仕方について設定を行います。今回は、monitors-labという環境タグがついた trace.flask.request.errors メトリクスの和をサービスタグごとにとっています(この環境では、 store-ads と store-discounts という2つのサービスが動いています)。 その下(評価の詳細)では、更に値の集計関数を規定しています。ここでは、上記グルーピングされたエラー数の過去5分の和を評価の対象としています。 3. アラート条件の定義 どのような場合にアラートを発報するか 、条件を指定します。しきい値の場合は、値がいくつより大きい/以上/以下/より小さい/等しい/等しくない場合にするかを指定します。 条件を入力すると、画面上部に表示されていたメトリクスのグラフと共にしきい値を表すラインが表示されました。 4. 通知の設定 通知設定では、変数を用いたカスタムの通知メッセージを作成できます。このメッセージは、メールの他にSlackなどを宛先とすることができます。今回は、ハンズオンの例と同じように変数を使わないシンプルなメッセージにしています。 5. 権限設定 モニターは、ユーザーの権限にかかわらず全員が見ることができます。またデフォルトでは、モニター編集権限を持っているユーザーが編集できるのですが、ここの項目では更にきめ細やかなアクセス制御をすることができます。 設定し終わったら、Createを押して作成完了です。 モニターのステータスを確認する Createを押すと、モニターのステータス画面に遷移します。作成したモニターの状態を確認してみましょう。 ヘッダー・プロパティ ヘッダーでは、モニターの状態( OK / 警告 / アラート など)が示されます。また、上部右側のボタンからは、アラートのミュートや解決ができます。なお、解決を押すとモニターは一時的に解決になりますが、再度メトリクスの値が評価された際にアラートの条件に当てはまっていれば再びアラート状態に移ります。プロパティでは、モニターの状態のほか、種類、作成時刻などのメタデータを確認可能です。 ステータスと履歴 ステータスと履歴のセクションでは、どのようにモニターの状態が移り変わってきたかを確認できます。 グループステータスのグラフでは、グループ化されたモニターのそれぞれについて状態が棒グラフで表示されます。今回は、 store-ads と store-discounts でグルーピングを行っているので、これらのグラフが表示されました。その下には、いつエラーが起こったのかを示す履歴グラフが表示されています。アラート時の挙動を見るためにしきい値を低く設定しているため、23:30頃のモニター作成とほぼ同時にアラート状態になっていることが分かります。 更にその下にあるのは評価グラフです。履歴グラフが生データ(未加工のデータ)を表示しているのに対し、評価グラフではこの生データに対して前述の手順「 メトリクスの定義 」の「評価の詳細」において定義済みの集計関数を適用した結果の値がアラート条件とともに視覚化されています。すなわち、今回の設定では過去5分間のエラー数の和がしきい値とともに示されています。 参考:新UI ステータス画面はまもなく新しいものに切り替わる予定です。 新しいUIでは、Visualize asの下の選択を切り替えることで生データのグラフ、評価値のグラフ、状態変化のグラフを表示することができます。   おわりに いかがでしたか?「Datadogのコースで学んでみたいけど、英語だからちょっとなぁ…」と思っている方にとって、この記事が足がかりとなれば幸いです。 ここまでお読みいただき、ありがとうございました。
アバター
膨大な構造化データ、半構造化データを抱え、その中から必要な情報を素早く分析したい。でも、システムに組み込むような本格的な分析ではなく、アドホックに分析したい。そんな時、一体何から始めたら良いのか途方に暮れた事はありませんか? 原因調査・仮説検証などスポット的なデータ分析を効率化したい データ量が多く処理時間・コストを短縮するためにデータを圧縮したい 可視化ツールを活用してレポートを作成したい 本記事では、 上記のような課題を解消するために、Amazon Athenaを用いて効率的にデータ化し、実行時間とスキャンデータ量を削減する方法と、Amazon Managed Grafanaを活用したデータ可視化方法をご紹介します。具体的な手順やサンプルを交えながら、Athenaでのクエリ作成からGrafanaでのダッシュボード構築までを解説します。データ可視化にお困りの方は、ぜひ読んでみてください。 アドホックなデータ分析をAWSで実現する3つのステップ アドホックデータ分析は、従来のデータウェアハウス構築・運用では時間やコストがかかりすぎるという課題があります。 Amazon AthenaではSQL文により、これらのデータを直接分析できるため、迅速なデータ分析が可能です。 Athenaに対応するファイル形式のデータをAWS S3に保存します。 データ変換やパーティショニングなどの前処理が必要な場合はAmazon Athenaを用いてSQLベースで実行し、分析に適した形式に整えます。 整形されたデータをAmazon Managed Grafanaに接続し、動的なダッシュボードと可視化ツールを用いて分析、洞察の抽出を行います。 S3は大容量データの保管に適したストレージであり、AthenaはS3に保管したファイルに対してSQLを用いたデータ操作が可能なため、データ準備に最適です。Grafanaは多様なデータソースに対応した可視化ツールで、Athenaで準備したデータを用いて効果的なデータ分析を実現できます。 どのようなデータ構造に対応しているの? 構造化データと半構造化データは、Athenaでのクエリが可能です。CSVやParquetなどの形式は構造化データとして、JSONやAvroは半構造化データとして扱われます。これらのデータ形式はAthenaで容易に分析が行えます。一方で、非構造化データは、Athenaで直接分析するのが難しく、別途構造化や前処理が必要です。 データ形式 概要 Amazon Athena対応 構造化データ スキーマを持つデータ 例:CSV、Parquet、ORCなど 〇 半構造化データ 部分的にスキーマを持つデータ 例:JSON、Avroなど 〇 非構造化テキストデータ 明確なスキーマを持たないデータ 例:Logstashログなど 〇 非構造化データ 明確なスキーマを持たないデータ 例:PDF、画像、動画 × どのようなファイル形式に対応しているの? Amazon Athenaで取り扱い可能なファイル形式は、構造化データ形式(CSV、TSV、カスタム区切り、 Apache Parquet、ORC )、半構造化データ形式(JSON、Apache Avro、Amazon Ion、CloudTrailログ)、ログファイル形式(Apache WebServerログ、Logstashログ)です。 ファイル形式 説明 Amazon Ion JSONと互換性のあるデータ形式 Apache Avro データシリアライズフレームワーク Apache Parquet 列指向ストレージ形式 Apache WebServer ログ パターンマッチングが可能なテキストデータ形式 CloudTrail ログ JSON形式 CSV カンマ区切り値 カスタム区切り ユーザー定義の区切り文字で分けられたテキストデータ形式 JSON 階層型データフォーマット Logstash ログ パターンマッチングが可能なテキストデータ形式 ORC 列指向ストレージ形式 TSV タブ文字で区切られたテキストデータ形式   データ用に SerDe を選択する - Amazon Athena 特定のデータ形式のテーブルを作成するために Athena で使用できる SerDe ライブラリを参照してください。 docs.aws.amazon.com データの可視化は簡単にできますか? Athenaのクエリ結果をAmazon Managed Grafanaのデータソースとして設定することで、簡単に連携が可能です。 Amazon Managed Grafanaは、複数のビルトインデータソースをサポートしており、さまざまなAWSサービスやその他のデータソースを可視化できます。Athenaのクエリ結果を動的なダッシュボードで表示し、多様な可視化オプションによりカスタマイズすることができます。   ビルトイン データソースに接続する - Amazon Managed Grafana すべての Amazon Managed Grafana ワークスペースで、次のデータソースがサポートされています。 docs.aws.amazon.com データ保管場所 分析対象のデータとクエリ実行結果は以下のようにS3バケット内の別々のフォルダに保存します。 データファイル保管場所: s3://<バケット>/athena/orgdata/sample.csv クエリなど実行結果の保管場所: s3://<バケット>/athena/query/   Amazon S3 でテーブルの場所を指定する - Amazon Athena Athena でテーブルを作成するときに、データの場所を指定する方法の詳細について説明します。 docs.aws.amazon.com   Athenaは指定されたLocation内のサブフォルダを再帰的にスキャンするので、スキャン対象以外のファイルは別のフォルダに保管します。 Athenaによるデータ分析の準備 Athenaを用いたアドホック データの取り込み、データ形式の変換、パーティショニング、アクセス用テーブルについて解説し、それぞれのテーブルの実行時間とスキャンデータ量を比較します。 データ取込みテーブル作成 本ステップでは、S3に保存されたデータ(今回はCSVファイルを使用)を読み込むための外部テーブルを作成します。データ構造をAthenaに伝え、データを読み込めるように準備します。  CREATE EXTERNAL TABLE IF NOT EXISTS csv ( 中略 ) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde' WITH SERDEPROPERTIES ( "separatorChar" = ",", "quoteChar" = "`", "escapeChar" = "\\" ) LOCATION 's3://<bucket>/athena/orgdata/' TBLPROPERTIES ('skip.header.line.count' = '1');   CSV を処理するための Open CSV SerDe - Amazon Athena Athena でカンマ区切りのデータ用のテーブルを作成する場合は、Open CSV SerDe ライブラリを使用します。 docs.aws.amazon.com   ROW FORMAT SERDE や SERDEPROPERTIES で適切なフォーマットを指定している点が重要です。 データ変換とパーティショニング 本ステップでは、各種変換処理を行い、新しいテーブルを作成します。例えば、Unixタイムスタンプは使いやすいデータに変換してカラムを追加します。テキスト形式からParquet形式への変換は、列指向フォーマットによる特定カラムへのアクセス高速化、効率的な圧縮によるスキャンデータ量の削減、そして各種データセットへの適合性から、クエリパフォーマンスが向上します。特に、SNAPPY圧縮は高速な圧縮と解凍により、クエリ実行速度向上に効果的です。また適切なパーティショニングにより、クエリ対象のデータが絞り込まれ、スキャンデータ量の削減によるパフォーマンス向上とコスト削減を実現します。 CREATE TABLE enhanced_csv_data WITH ( format = 'PARQUET', parquet_compression = 'SNAPPY', external_location='s3://<bucket>/athena/parquet/', partitioned_by = ARRAY['year', 'month', 'day'] ) AS SELECT *, CAST(date_format(from_unixtime(CAST(timestamp AS BIGINT) / 1000), '%Y%m%d%H%i%s') AS VARCHAR(14)) AS datetime_ymdhhmmss, year(from_unixtime(CAST(timestamp AS BIGINT) / 1000)) AS year, month(from_unixtime(CAST(timestamp AS BIGINT) / 1000)) AS month, day(from_unixtime(CAST(timestamp AS BIGINT) / 1000)) AS day FROM csv;   CREATE TABLE AS - Amazon Athena インライン SELECT クエリの結果を含むテーブルを作成します。 docs.aws.amazon.com 前ステップで作成した外部テーブルを圧縮しようとしたところ、以下のエラーが発生しました。パーティションキーのデータ型の指定がよくなかったようです。String型で再作成する事でエラーは解消されました。 アクセス用テーブル作成 前ステップで作成したパーティション付きデータへアクセスするための外部テーブルを作成します。テーブル名やカラム名などのメタデータ定義、LOCATION句によるデータ指定、パーティション情報の取得、tblpropertiesによるデータフォーマットと圧縮形式の指定といった役割を担います。 CREATE EXTERNAL TABLE IF NOT EXISTS parquet_csv_data ( 中略 ) STORED AS PARQUET LOCATION 's3://<bucket>/athena/parquet/' tblproperties ("parquet.compression"="SNAPPY");   Parquet SerDe - Amazon Athena Parquet SerDe を使用して、Parquet データから Athena テーブルを作成します。 docs.aws.amazon.com 各テーブルの実行時間とスキャンデータ量の比較 3つのテーブルに対して同一のクエリを実行して、実行時間とスキャンデータ量を比較すると以下となりました。 対象テーブル 実行時間 スキャンデータ量 CSVデータ取込みテーブル 6.29sec 127.96MB データ変換テーブル 6.71sec 12.69MB アクセス用テーブル 3.84sec 9.99MB CSVデータ取込みテーブルとアクセス用テーブルを比較すると、実行時間は38%削減されました。データ変換テーブルでCSV取込みテーブルよりも若干実行時間が増えているのはパーティションスキャンによるオーバーヘッドが考えられます。パーティションのスキャンデータ量を比較すると、列指向の特性と圧縮の効果により、スキャンデータが92%削減されました。圧縮により大幅にスキャンデータ量は削減されますが、それ以外にもテーブル構造やパーティションの違いによりクエリ実行結果に違いが出ることがわかりました。 複雑なテーブル構造はクエリ実行結果に影響を及ぼすので、パーティションの粒度や不要なカラムは除外するなど対処が必要です。   Grafanaによるデータ可視化 本章では、AthenaデータソースをGrafanaに設定し、Grafana Exploreでクエリを実行、ダッシュボードを作成する方法を紹介します。 アクセス制御 GrafanaからAthenaのデータ取得とS3へのログ書き込みについて、以下を参考にIAM 権限の付与を行います。 Amazon Managed Grafana の AWS マネージドポリシー - Amazon Managed Grafana Amazon Managed Grafana の AWS マネージドポリシーと、そのポリシーへの最近の変更について説明します。 docs.aws.amazon.com GrafanaにAthenaデータソース設定 データ転送を行うGrafana ワークスペースの[データソース]タブでAthena のデータソースを有効化し、アタッチ済みとなる事を確認します。               次にGrafanaのコンソールにログインし、データソースにAthenaが利用可能となっているか確認します。未利用の場合はinstall nowをクリックします。 Amazon Athenaに関するプラグイン説明画面が表示されるので、右上よりインストールします。 プラグインのインストールが完了するとAdd new data sourceと表示されるのでクリックします。 ここでは主にAthena Detailsの設定をします。 Grafana Exploreにてクエリ実行 Athenaとの接続が完了するとData Sourcesに新たに追加されるので、Exploreをクリックします。 Grafana Dashboardの作成 ここではGrafanaのデータソースとしてAthenaからの応答が正しい事をテストクエリを実行して確認します。特に問題なければ画面右上の+Addを展開してAdd to dashboardをクリックします。 次にOpen dashboard、Add visualizationをクリックするとダッシュボードのエディット画面が表示されるので、可視化を行いたいクエリを実行します。この時点では期待する結果とならない場合もありますので、Open visualization suggestionsからお好みの視覚化オプションを選択します。 視覚化オプションは多数あり、ダッシュボード上に異なるパネルを作成する事ができます。 さいごに Amazon S3、Amazon Athena、Amazon Managed Grafanaを使ったデータ分析ワークフローを3つのステップで解説しました。本記事が皆様のデータ活用にお役立ていただければ幸いです。
アバター
2024年12月からモバイルユーザのIP割り当て方法にアップデートが加わりました。 今回のアップデートでより柔軟な設定ができるようになりましたのでご紹介します。 おさらい ~モバイルユーザのIP割り当て方法~ Catoでは、CatoクラウドのPoPから各モバイルユーザに対してIPアドレスの割り当てを行います。 割り当て方法として、動的IP割り当てと固定IP割り当てがありますが、デフォルトは動的IP割り当てです。 モバイルユーザ用に用意されたアドレスレンジの中から動的にモバイルユーザにアドレスを割り当てを行います。 そのモバイルユーザ用に用意されたアドレスレンジはデフォルトで10.41.0.0/16に設定されています。   ここまではアップデート前も変わりません。 では、何が変わったのか?説明していきます。 アップデート概要 何ができるようになった? 最初にお伝えすると、今回アップデートが加わったのは動的IP割り当ての方法のみで、固定IP割り当ての方法に変更はありません。 変更点はズバリ、 複数のIPレンジから割り当てが可能 となる点です。 以前は1つのアドレスレンジ(Default IP Rangeと呼ぶ)からのみ割り当てを行っていましたが、別途アドレスレンジ(Dynamic IP Rangeと呼ぶ)を追加設定することで、複数のアドレスレンジから割り当てが可能になりました。 ユースケースとして、接続元IPアドレスレンジで社内システムへのアクセスを制御したい場合が考えられます。 例えば図のように、親会社のユーザはDefault IP Rangeから割り当てを行い、グループ会社のユーザには別途Dynamic IP Rangeを用意し割り当てを行うことで、グループ会社のユーザからのアクセスをIPアドレスレンジで制限するといったことができます。 もちろん、固定IPでも接続元IPアドレスレンジで社内システムへのアクセスを制御は可能です。 これまでこのようなユースケースの場合、固定IP割り当てを行っていました。 ただ、固定IPの場合設定したIPアドレスを利用できるのは最初に接続した端末のみです。 同一ユーザアカウントで2台目に接続した端末には動的にIPが割り当てられるため、制御は不十分だったと言えます。 Dynamic IP Rangeによる割り当ての場合は、同一 ユーザが2台同時接続をしたら2台とも Dynamic IP Range から割り当てが可能です。 そのため、このようなユースケースの場合は今回の追加機能であるDynamic IP Rangeによる割り当てがお勧めです。 Dynamic IP Rangeの設定方法や注意点はこの先で 詳しく説明していきます。 設定画面はどんな風に変わった? その前に、設定画面をみてみましょう。 以前は1つの画面にまとめられていましたが、2024年12月から設定画面が3つに分かれました。 Dynamic IP Allocation:動的IPの割り当てをするページ Static IP Allocation:固定IPの割り当てをするページ Settings:アドレスレンジを定義するページ ざっくりイメージは、まずSettingsでアドレスレンジの定義を行い、その後Dynamic IP AllocationやStatic IP Allocationで、ユーザやユーザグループに対して割り当てを行っていく流れになります。 また、Settingsのページを見てみると以下3つの項目があり、Default IP Rangeにはデフォルトで10.41.0.0/16が設定されています。 Default IP Range Dynamic IP Range Static IP Range Default IP Rangeの設定箇所をよく見ると「Define the default IP range for your remote users. This IP range is allocated to a remote user that does not match a policy.」という記載があります。 この記載から、Dynamic IP RangeやStatic IP Rangeのページで割り当てを行っていないユーザはDefault IP Rangeから割り当てとなることがわかります。もちろん、何も設定を行っていないデフォルト状態でも、このDefault IP RangeからIPが割り当てられます。 変更箇所がわかったところで、いくつかパターンを想定して実際にテストを行ってみました。 結果を次にまとめています。 設定方法 1つのアドレスレンジから動的に割り当てさせたい まず、1つのレンジから割り当てを行う場合です。 この場合は特に設定は不要です。上述の通りデフォルトの状態でDefault IP Rangeからのみ割り当てが行われます。 実際に接続をしてみると・・・ 10.41.138.26が付与されました。想定通りDefault IP Rangeから割り当てが行われていることがわかります。 ■UserAのIPアドレス ちなみに、10.41.0.0/16を既に利用しているなどの理由により、変更が必要な場合はSettingsページのDefault IP Rangeを任意のIPレンジに書き換えるだけで変更可能です。この点はアップデート前と同様です。 変更する際は、利用中のアドレスレンジと重複しないように注意しましょう。 複数のアドレスレンジから動的割り当てさせたい 複数IPレンジから割り当てを行いたい場合は、今回の追加機能を使います。 設定は以下の順番で行います。 設定手順: Dynamic IP Rangeの定義 Dynamic IP Allocation Policyの有効化 ポリシーを定義(ユーザ/ユーザグループへの割り当て) シナリオ: Dynamic IP Rangeを10.40.0.0/16と定義し、UserAにはDynamic IP Range(10.40.0.0/16)から、UserBにはDefault IP Range(10.41.0.0/16)から割り当てを行う。 設定 1.Dynamic IP Rangeの定義 SettingsページのDynamic IP Rangeに任意のIPレンジを定義します。 今回は、10.40.0.0/16にしました。 2.Dynamic IP Allocation Policyの有効化 Dynamic IP Allocation Policyはデフォルトでは無効化されているため、右上のトグルスイッチで有効化します。 有効化すると警告メッセージが表示されます。 このメッセージは「Dynamic IP Allocation Policyが有効になり、すべてのルールが実施されます。続行しますか?」という警告メッセージです。ルールが1つも定義されていない場合は、続行で問題ありません。(変わらずDefault IP Rangeからの割り当てになるため。)もし、既にルールが定義されている場合は問題ないことを確認してから、Continueで続行します。 3.ポリシーを定義(ユーザ/ユーザグループへの割り当て) アドレスレンジの定義ができたらDynamic IP Allocationのページ移動し、ポリシーを定義します。 私はここで、きっとUser/Groupsで対象のユーザを選択し、IP Rangeで作成したDynamic IP Rangeを選択するんだろうなと思っていましたが、IP Rangeでは、Network Rangeの作成が必要でした。 下図の「View network Range List」からNetwork Rangeの作成を行います。 今回は、10.40.0.1-10.40.0.100のNetwork Rangeを作成しました。 Network Rangeを2つ以上設定すれば、3つ以上のアドレスレンジから割り当てが可能ですが、今回は1つだけにしておきます。 Network Rangeの作成を行うと、Allocated Rangesの選択項目に出てくるので作成したNetwork Rangeを選択します。 当然ですが、このNetwork RangeはDynamic IP Rangeに含まれるレンジを選択する必要があります。 念のためDynamic IP Rangeに含まれないNetwork Rangeを選択してみたところ、以下のようなエラーが表示されて設定保存ができませんでした。 ▶error message:「The range XXX is not part of Dynamic defauld range」 正しいNetwork Rangeを選択しなおして今回は以下のようなポリシーを設定しました。 Name/Description:TestRule_1 User/Groups:UserA Platforms:Any Allocated Ranges:10.40.0.1-10.40.0.100 これで設定は完了です。 結果 この状態で、UserAとUserBを接続させると・・・ UserAには10.40.0.91が付与され、Dynamic IP Rangeから割り当てが行われていることがわかります。 ■UserAのIPアドレス 一方、UserBを接続してみると 10.41.113.182 が付与され、Default IP Rangeから割り当てが行われていることがわかります。 ■UserBのIPアドレス このように想定通り複数レンジからの割り当てができました。 補足 ここからは2つのシチュエーションを想定し、少し細かい仕様をQA形式でまとめています。 Q:Dynamic IP Rangeを使い果たしたら? →A:Default IP Rangeから割り当てを行います。  例えば、Network Rangeを10.40.0.1~10.40.0.100としGroupAに割り当てを行った場合、101番目に接続したGroupAに属するユーザにはDefault IP Rangeから割り当てが行われます。よって、ユーザアカウント数を考慮して Network Rangeを設定する必要があります。 Q:同一ユーザアカウントで2台同時接続したら? →A:2台ともDefault IP Rangeから割り当てを行います。 例えば、Network Rangeを10.40.0.1~10.40.0.100としUserAに割り当てを行った場合、UserAのアカウントで2台同時接続したら2台とも10.40.0.1~10.40.0.100から割り当てが行われます。よって、ユーザアカウント数に加えて接続 台数も考慮してNetwork Rangeを設定する必要があります。 Q:ポリシーが重複している場合は? →A:上位のポリシーが適用されます。  例えば、UserAがGroupAとGroupBの両方に属しており、下図のようにGroupAにはNetwork Range_1から、GroupBにはNetwork Range_2から割り当てを行うように設定を行った場合、UserAにはNetwork Range_1から割り当てが行われます。  Dynamic IP Allocation PolicyはCatoのFirewallなどのその他機能と同様で、上から順にチェックを行い一度ヒットしたらそれ以降は適用されない仕様です。必ず優先させたいポリシーを上位に設定するように注意しましょう。 まとめ 最後に、Dynamic IP Rangeを利用するうえでのポイントと注意点まとめると、こんなかんじです。 ・Dynamic IP Allocationページはデフォルトで無効化されている。   有効化したい場合はまず、SettingsページのDynamic IP Rangeを定義する必要がある。 ・Dynamic IP RangeはDefault IP Rangeと重複しないように注意が必要。 ・Network RangeはDynamic IP Rangeに含まれるレンジを定義する必要がある。 ・Network RangeはDynamic IP Range内で複数作成が可能。 ・ポリシーにマッチしないユーザには、Default IP Rangeからの割り当てとなる。 ・Network Rangeはユーザアカウント数と接続台数を考慮して設定する必要がある。 ・Dynamic IP Policyは上から順にチェックを行い一度ヒットしたらそれ以降は適用されないため、順番に注意が必要。 固定IPを割り当てたい 設定 固定IPの割り当てを行いたい場合はまず、SettingsページのStatic IP Rangeに任意のアドレスレンジを設定します。 今回は、192.168.2.0/24にしてみました。 アドレスレンジの定義ができたらStatic IP Allocationのページ移動します。 ここからは、アップデート前と全く同じです。 以下の流れで設定を行います。 有効化 デフォルトでは無効化されているため、トグルスイッチで有効化します。 アドレスの割り当て 対象のユーザをプルダウンで選択し、先ほど設定したアドレスレンジ(192.168.2.0/24)の中から1つアドレスを割り当てます。 今回の例の場合は、192.168.2.1を設定します。 その後、「Add」ボタンから追加を行います。 保存 設定内容を確認し保存を行います。 今回はUserAに対して192.168.2.1を割り当ててみました。 設定はこれで完了です。 結果 接続を行ってみると・・・ 想定通り192.168.2.1が付与されました。 ■UserAのIPアドレス 補足 ここからは2つのシチュエーションを想定し、少し細かい仕様をQA形式でまとめてみました。 Q:動的IPにて接続された状態で固定IPを割り当てたらどうなる? →A: 固定IPを使って自動的に再接続されます。この時断時間はほとんどありません。 この点はアップデート前から変更ありませんでした。 Q:固定IPを付与したユーザで、2台同時接続を行った場合どうなる? →A: 1台目の端末が固定IPを持ち続け2台目の端末には動的IPレンジから割り当てられます。 つまり固定IPが必要な端末数に合わせてユーザを作成する必要があります。この点もアップデート前から変更ありません。 まとめ 固定IPの設定をする際のポイントと注意点を改めて記載します。 Static IP RangeはDefault IP RangeやDynamic IP Rangeと重複しないように設定をする。 動的IPにて接続した状態で固定IPを割り当てた場合、固定IPを使って自動的に再接続され通信断時間はほとんどない。 2台同時接続した場合、固定IPが割り当てられるのは最初に接続を行った1台のみで、2台目にはDynamic IP RangeやDefault IP Rangeからの動的IP割り当てになる。 最後に 今回は、モバイルユーザのIP割り当て方法にアップデートが加わり、改めて記事にしてみました。 これからCato利用を検討されている方にも、既にご利用中の方にもお役に立てれば幸いです!
アバター
本記事は 新人ブログマラソン2024 の記事です 。 お久しぶりです。 USiZEサービス部の新人、織田です。 今回は「ITIL」についてまとめた記事です。ITILとは、簡単に言うと「IT運用の指針を提供してくれるフレームワーク」になります。 所属する部の名前にもある通り、私はUSiZEを運用する業務に携わっています。そのため、今後の業務にあたり必要となる考え方をITILを学習することで身に着けられるのではないかと考えました。今回の記事では、学習した内容を簡潔にまとめたいと思います。 それでは早速始めていきましょう! ※ USiZEとは、SCSKが提供するクラウドサービスです。詳しくは こちらのサイト をご覧ください。   ITIL とは何か? まず学習にあたり、気になったのが、「ITILとは何か?」です。 一言で大雑把にまとめると初めに述べた通り、「IT運用の指針を提供してくれるフレームワーク」であると思います。 ITILは1980年代後半に初めて登場した考え方であり、時代とともに変わるITシステムの提供形態の変化に合わせて、複数回のバージョンアップが行われています。 そのため、一言でITILについてまとめようとすると、どうしても大雑把な表現になってしまいます。 また、フレームワークという表現を使用しましたが、システム開発に使用されるプログラミング言語のフレームワークとは異なり、IT運用の考え方をまとめた枠組みのようなものになります。 そのため、ITILは多くのIT運用に考え方を適用できるように、抽象的とも感じられる部分が多々あります。 ITIL の歴史 ITILは1989年にイギリス政府の中央電算局(CCTA)によって初期バージョンが公開されました。その後、時代のニーズに合わせて複数回のバージョンアップが重ねられています。以下に主要なバージョンとそのリリース年、主な特徴をまとめました。 バージョン リリース年 主な特徴 ITIL  1989年 初期バージョン。30冊以上の書籍で構成され、大規模組織向けに設計されている。 ITIL v2 2001年 サービス提供と(Service Delivery)とサポート(Service Support)を明確化している。 ITIL v3 2007年 サービスライフサイクルの概念を導入し、IT運用全体をカバーしている。 ITIL 4 2019年 アジャイル、DevOps、リーンなど、現代的な手法を統合している。   ITIL 4 の特徴 最新バージョンであるITIL 4についてまとめます。 現代のIT運用手法との連携 ITIL v3までが主にウォータフォールモデルによる開発に対応していたのに対し、ITIL 4では、アジャイルやDevOps、リーンなどの最新の手法を統合しています。具体的な効果としては、より迅速なITサービスの提供や効率的な運用が可能となります。 サービスバリューシステム ITIL 4では、ITサービスの価値創出を「サービスバリューシステム(SVS)」として体系化しています。SVSの主要な構成要素は以下の通りです: ガバナンス :意思決定の枠組みを提供。 継続的改善 :価値を高めるための改善プロセス。 サービスバリューチェーン :価値を提供する一連のプロセス。 プラクティス :34のIT管理手法(例:インシデント管理、変更管理、問題管理など)。 従うべき原則 :組織で意思決定を行うためのガイダンス。 これにより、ITIL v3までのプロセス指向から価値指向へと進化し、柔軟性が向上したことで、変化の激しい現代社会により適したIT運用が可能となります。 ※ サービスバリューシステムは こちらのサイト に図として書かれています。   従うべき原則 「従うべき原則」には、さらに7つの項目があります。  価値に着目する  現状からはじめる  フィードバックをもとに反復して進化する  協働し、可視性を高める  包括的に考え、取り組む  シンプルにし、実践的にする  最適化し、自動化する 全部大切な考え方ですが、私が特に重要だと思った「現状からはじめる」について、ここでは特に詳しく説明させていただきます。 「現状からはじめる」は現状の評価と測定、観察を正しく行うことで、再利用可能なものを把握することを目的としています。 例えば、実務で古いシステムを移行しようとした場合、様々な制約事項があり、一から全部を新しく作り直したくなることがあります。 この時ほとんどの場合で、既存のものを活用することで移行に必要となる様々なコストを削減することができます。 ただ、反対に現状からまったく再利用できない場合もあることには注意が必要です。   ITIL 関連情報の収集方法 ここでは情報収集を2種類に分けて紹介します。 公式 ITILの歴史で書いたように、ITILはIT運用をまとめた書籍として提供されています。そのため、ITILの公式から提供される公式書籍(コア書籍)があります。このコア書籍の入手方法にはいくつか制限があるようなので、この場で簡単にまとめたいと思います。 コア書籍 デジタル版 印刷版 認定試験にバンドルされる。 ※必ずバンドルされているわけではないことに注意が必要。事前にバンドルされている試験であるか確認が必要。 ITILⓇ,PRINCE2Ⓡ公式書籍ショップ(IT&ストラテジーコンサルティング) から購入可能 研修 こちらのリンクに記載のある企業によって有料の研修が実施されています。 パートナー一覧 | PeopleCert – Best Practice by applying 私は新人研修でもお世話になったトレノケート株式会社が主催する「 ITIL(R) 4 Foundation BOOT CAMP 」に参加しました。 ※ITIL認定資格によっては、試験の事前要件として研修の受講が義務づけられているものもあります。   その他の学習方法 上記の公式から提供される書籍や研修以外にもITILには多数の書籍などがあります。 一般的な入手方法としては、 Amazonでの書籍の購入 Udemyでの資格試験対策講座や実務スキルの学習 などがあります。   ITIL 資格について ITILには、多数の認定資格があります。ここでは、最も基礎となるITIL 4 Foundationについて取り上げて概要をまとめます。 試験形式 :多肢選択式(オンライン受験可能) 試験時間 :60分(Foundation) 試験費用 :Foundationは約68,000~77,000円 日本語対応 :日本語試験が提供されています。 詳しい試験概要については、こちらのサイトをご覧ください。 ITIL®4 | PeopleCert – Best Practice by applying (ITILの認定資格の全体像をまとめたページ) ITIL®4 Foundation | PeopleCert – Best Practice by applying (ITIL 4 Foundationについてまとめたページ)   まとめ 以上で、今回の記事は終わりです。 私は「ITIL 4 Foundation」の合格を目指して勉強中です。 今回は学習したことのアウトプットもかねて記事を書いてみましたが、まだまだITILについての理解が浅いことを自覚できました。 これを機により一層勉強に励んでいきたいと思います。 もしかしたら、本記事を修正したリベンジ記事を書くかもしれません。
アバター
こんにちは、テクノロジーサービス部の大西です。 RSSフィードで取得した記事を要約し、自分のLINEアカウントに送信するシステムを構築しました。 今回対象にした技術ブログは本サイトであるTechHarmonyであり、SCSKでは様々な技術発信を高頻度で行っているため、特に自分の興味ある分野を見逃さないことを目的にしました。 作成したシステムについて Amazon Bedrockには様々なAIモデルが用意されています。モデルによってサポートされるリージョンや入力、出力形式が異なります。 (詳細は以下のページをご確認ください。) https://docs.aws.amazon.com/ja_jp/bedrock/latest/userguide/models-supported.html 今回使用したモデルは、日本語対応の「Claude 3 Haiku」です。リソースは全てバージニア北部(us-east-1)に作成しています。 メインの処理を行うLambda関数はNode.jsで実装されており、RSSフィードのURLやLINEへのメッセージ送信用のアクセストークンはParameter StoreとSecrets Managerに保存しています。 また、重複した記事を取り込まないよう、DynamoDBで記事情報を管理しています。 メインの処理を行うLambdaはNode.jsを使用しており、RSSフィードのURLやLINEへのメッセージ送信で利用するアクセストークンは、 それぞれParameter StoreとSecrets Managerに保存しています。 また、重複した記事を取り込まないように、DynamoDBに記事情報を登録しています。 以下の例ではTechHarmonyの取得した記事をテーブルに書き込んでいます。 Lambdaを実行すると、以下のようにLINEに記事の要約が送信されました。 次の章から構築手順をざっくりとご説明していきたいと思います。 前準備 Node.jsで作成したソースコードは以下のモジュールを利用しており、事前にインストールが必要です。 ・axios ・RSSParser ・aws-sdk 私は自分のPCにワーク用フォルダを作成、その中にソースコードと追加モジュールを配置しており、 完成後はソースコードと追加モジュールをまとめたzipファイルを作成し、Lambdaへアップロードしました。 LINEへメッセージ送信は、LINE Messaging API( https://developers.line.biz/ja/services/messaging-api )を使用しています。 本サービスの利用にはLINEアカウントが必要です。 LINE Messaging API用意 LINEへ連携するため、LINE Messaging APIを準備します。 https://www.studycloudtech.com/aws/start-line-messagingapi/ 上記サイトを参考に構築し、以下のようにユーザーIDとチャネルアクセストーンを取得しました。 ※APIの使用料金は今回無料枠を選択しており、月200通までの送信が可能です。その他プランは以下を参照してください。 https://www.lycbiz.com/jp/service/line-official-account/plan/ DynamoDB用意 記事を保存するため、DynamoDBを作成します。パラメータは以下の通りです。 パラメータは以下の通りで、他の設定はデフォルト値を使用しています。 ①テーブル名:RSSArticles ②パーティションキー:ArticleID 文字列 Parameter Store作成 要約対象のページを追加・変更・削除する可能性を考え、RSSフィード取得先URLをParameter Storeに保存しています。 以下のようなパラメータで作成しました。 名前:/rss_sites/ 利用枠:標準 タイプ:文字列のリスト 値:任意のURL(画像はTechHarmonyのRSSフィードページ) 今回は1つのURLのみ指定していますが、今後複数のページから取得すること可能性を踏まえ、 タイプは「文字列のリスト」を選択し、拡張性を考慮しています。 Secrets Manager作成 LINE Messaging APIの手順で発行したチャネルアクセストークンを安全に保管するため、Secrets Managerを以下のように作成しています。 暗号化キーはSecrets Managerが発行するKMSキーを使用しています。 ①シークレットのタイプ:その他のシークレットのタイプ ②キー/値:LINE_ACCESS_TOKEN/<手順3で発行したチャネルアクセストークン> ③暗号化キー:aws/secretsmanager Bedrock使用アクセス申請 Bedrockで「Claude 3 Haiku」を使用するため、以下のような操作を行いました。 ①Bedrockを開き、「View Model catalog」を選択する。 ②今回使用するモデルである「Claude 3 Haiku」を選択する。 ③右上にある「・・・」を選択し、「Modify access」を選択する。 ④モデルアクセスのページに遷移するため、「特定のモデルを有効にする」を選択する。 ⑤リストから「Claude 3 Haiku」にチェックを入れ、「次へ」を選択する。 ⑥初回設定時にはユースケースを求められるため入力する。(私は自社情報を入力しました) ⑦入力した情報を確認し、「送信」する。 ⑧数分でアクセス権が付与される。ステータスを確認し、許可されたことを確認する。 IAM権限設定 Lambdaから呼び出されるリソースへの権限が必要になるため、IAMポリシーを以下のように設定し、 dynamoDB、Secrets Manager、Parameter Store、Bedrockへアクセスできるようにしています。 作成したポリシーは別途ロールへ付与します。 ・IAMポリシー ポリシー名:RSSPolicy {     "Version": "2012-10-17",     "Statement": [         {             "Effect": "Allow",             "Action": [                 "dynamodb:*"             ],             "Resource": "arn:aws:dynamodb:us-east-1:xxxxxxxxxxxxx:table/RSSArticles"         },         {             "Effect": "Allow",             "Action": [                 "secretsmanager:GetSecretValue"             ],             "Resource": "arn:aws:secretsmanager:us-east-1:xxxxxxxxxxxxx:secret:xxxxxxxxxx"          },          {             "Effect": "Allow",             "Action": [                 "ssm:GetParameter"             ],             "Resource": "arn:aws:ssm:us-east-1:xxxxxxxxxxxxx:parameter/rss_sites"          },          {             "Effect": "Allow",             "Action": "bedrock:*",             "Resource": "*"         }     ] } ・IAMロール ルール名:RSSRole 許可ポリシー:AWSLambdaBasicExecutionRole、RSSPolicy Lambda用コード作成 今回Lambdaで実行するコードは、Node.jsを使用して作成しています。 index.zip コードが長いので、上記ファイルをダウンロードして実ファイルと以下の説明を確認していただけるとわかりやすいと思います。 ①AWSサービスの初期化 まず、AWSの複数のサービスを利用するために、AWS SDKを使ってクライアントを初期化しています。 対象のサービスには、DynamoDB, Parameter Store, Secrets Manager, Amazon Bedrockがあります。 ②RSSサイトの取得 getRSSSites関数を使用して、Parameter StoreからRSSサイトの一覧を取得します。 取得された情報は、カンマ区切りの文字列として返され、RSSフィードを取得するために使用されます。 ③LINEアクセストークンの取得 getLineAccessToken関数では、Secrets ManagerからLINEのアクセストークンを取得します。 これは、LINE Messaging APIを使用して通知を送信する際に必要です。 ④新しい記事のフィルタリング filterNewArticles関数は、RSSフィードから取得した記事のうち、まだDynamoDBに保存されていないものをフィルタリングします。 既存の記事はDynamoDBから取得して比較します。 ⑤新しい記事の保存 新しく取得した記事は、saveArticles関数を使用してDynamoDBに保存します。 バッチ書き込みを使用して効率的にデータを保存し、万が一未処理のアイテムがあった場合には再試行を行います。 ⑥記事の要約生成 Amazon Bedrockのモデルを用いて、generateSummary関数が新しい記事の要約を生成します。 この要約はClaude 3 Haikuモデルによって提供され、レスポンスから要約を抽出します。 ここでは使用するモデルIDとバージョンの指定、AIへの命令方法がAPIとして提供されており、以下のページのAPIリクエストを参考にしています。 https://us-east-1.console.aws.amazon.com/bedrock/home?region=us-east-1#/model-catalog/serverless/anthropic.claude-3-5-haiku-20241022-v1:0 { "modelId": "anthropic.claude-3-5-haiku-20241022-v1:0", "contentType": "application/json", "accept": "application/json", "body": { "anthropic_version": "bedrock-2023-05-31", "max_tokens": 200, "top_k": 250, "stopSequences": [], "temperature": 1, "top_p": 0.999, "messages": [ { "role": "user", "content": [ { "type": "text", "text": "hello world" } ] } ] } } ⑦LINEにプッシュ通知 最後に、sendToLine関数を使って、新しい記事とその要約がLINEのユーザーにプッシュ通知されます。 LINE Messaging APIを利用し、事前に取得したアクセストークンを使用して安全にメッセージを送信します。 Lambda作成 作成したコードを実行するため、Lambdaを以下のように作成しました。 関数名:RSSNotifier(画像では既に作成済みで重複するため、_を付与しています) ランタイム:Node.js 22.x アーキテクチャ:x86_64 実行ロール:RSSRole 作成したコードとモジュールを含めたzipファイルを作成し、Lambdaにアップロードします。 アップロードした結果、以下のようにソースコードとモジュールが設定されていることを確認してください。 また、ある程度実行に時間がかかるため、設定画面からタイムアウト値を変更してください。 設定変更後、テスト実行すると、LINEに要約したメッセージが届きます。 まとめ Bedrockを用いたシステム構築に初挑戦してみました。 AIによる要約システムを作るのに多くの技術ブログやドキュメントに助けられました。 今後、EventBridgeを使用した定期実行やメッセージに参照元URLを含める改善を進めるのと、別AIモデルの動作についても検証していきたいと考えています。 閲覧いただき、ありがとうございました。
アバター
Amazon CloudWatch Logs を Amazon S3 にエクスポートする方法について、2つの構成を検討しました。 それぞれの構成にどのようなメリットや課題があったのか考察しておりますので、AWSでのログ収集の仕組みを考える際の参考になれば幸いです。 背景 コスト等の観点から、CloudWatch LogsのS3への保管を検討する方もいらっしゃると思います。 CloudWatch LogsをS3にエクスポートする手段は複数あり、今回は以下の要件に基づいて検討しました。   ・日次で定期的に処理を実施したい ・保存先S3のファイル名に日付を入れるなど、カスタマイズしたい   ①EventBridgeとLambdaによる日次エクスポート まず、EventBridgeを使ってLambda関数を日次で実行し、CloudWatch LogsをS3にエクスポートする方法についてです。   構成図     概要 EventBridgeで起動されたLambdaは、必要なタグ付けやエクスポート後のS3のディレクトリ作成を管理し、指定したログをエクスポートします。 シンプルな構成で、設計や構築が比較的容易のため、この方式の導入を検討される方も多いと思います。 課題 Lambdaで全てのロググループを一括で処理しようとしましたが、以下の制約にぶつかりました。 CreateExportTask APIの制限 同一アカウントでエクスポートタスクの並列実行ができないため、リソース制限エラーが発生。 Each account can only have one active (RUNNING or PENDING) export task at a time.   CreateExportTask - Amazon CloudWatch Logs Creates an export task so that you can efficiently export data from a log group to an Amazon S3 bucket. When you perform... docs.aws.amazon.com Lambdaの時間制限 実行時間が15分を超えるとタイムアウトする。 関数タイムアウト:900 秒 (15 分)   Lambda クォータ - AWS Lambda Lambda 関数および API リクエストに関する最大サイズ、制限、およびクォータです。 docs.aws.amazon.com   CreateExportTask APIの制限への対応として、sleep関数を用いて処理が終了するまで待機する構成をとるなどしました。しかし、エクスポート対象のロググループの数が多い場合にはLambdaの最大実行時間を超過してしまいました。   ②Step Functionsによる構成 次に、①の課題を解消するためにStep Functionsを導入した構成を紹介します。 構成図     概要 検証①からの主な変更点は、Step Functionsを使って各ロググループを個別に処理するLambdaを実行する構成にしたことです。 加えて、エラーハンドリング機能としてSNSを使用し、エラー時に即座に対応できるよう通知の仕組みを導入しました。 結果として、エクスポート対象のロググループの管理が容易となり、エクスポートの並列処理を避け、Lambdaのタイムアウトの問題も解消することができました。   <Step Functions構成イメージ> ※Lambdaをエクスポート対象のロググループの個数分設定する ※Describe-export-task APIにてエクスポート処理のステータスを確認する(処理がCOMPLETEになるまで待機する) ※Lambdaにてエラーが発生した場合、SNSでメール通知する     課題 Step Functionsでステップごとに処理ができるため、エクスポート対象のロググループの増減にも柔軟に対応可能となりました。しかし、エクスポート対象が多い場合、処理が複雑になり、構成に不備があった際に気づきにくくなるという新たな課題も感じました。   まとめ AWS環境でCloudWatch LogsをS3にエクスポートする方法について、2つの構成を検討しましたが、以下のような特徴があることを確認しました。   構成案 Lambdaによる構成 LambdaとStep Functionsによる構成 概要 EventBridgeを使ってLambda関数を日次で実行し、CloudWatch LogsをS3にエクスポートする。 EventBridgeとLambdaの間にStep Functionsを導入する。Step Functionsにて各ロググループを個別に処理するLambdaを実行し、CloudWatch LogsをS3にエクスポートする。 メリット シンプルな構成であるため、設計や構築が容易である。 エクスポート対象のロググループの増減にも柔軟に対応可能である。 課題 CreateExportTask APIの制限やLambdaの実行時間の制限を受ける可能性がある。 エクスポート対象が多い場合、処理が複雑になり、構成に不備があった際に気づきにくくなる可能性がある。   最後に CloudWatch LogsをS3にエクスポートするにあたり、APIの制約やLambdaの時間制限など、設計時に考慮すべき多くの条件があることを実感しました。   Step Functionsについて、②の検証を行うにあたり初めて使用しましたが、デザインエディタを用いることで直感的にフローを作成できることを知りました。 また、Step Functionsは、様々なサービスとの連携がサポートされています。 今回は①で利用したLambdaを活用する方向で②の構成を検討しましたが、Lambdaで記述したエクスポート処理と同様のことをStep Functionsのみで完結させる方式も考えられると思います。 よって、ログの転送処理だけではなく、複数のサービスを組み合わせたシステムを構築する際や、Lambdaのランタイムの制限などで実装が難しい際にはStep Functionsを活用していくメリットがありそうです。   CloudWatch LogsをS3にエクスポートする作業の必要性は今後も続くと考えており、今回の検討を選択肢の一つとして、多様なパターンを考慮しつつ、柔軟にシステム設計をしていきたいです。
アバター
今回はAzure上に構築済みのリソースを自動でコードに落とし込み、Terraform上で管理できるようにし、コードによってパラメータ変更ができるようにする方法について紹介したいと思います。 事前準備 Terraformの準備 前回私が投稿した以下サイトに習い、Terraformの準備をしてください。 TerraformでAzureにリソースを構築 IaCの中でもマルチクラウドに対応しているTerraformについて紹介したいと思います。 blog.usize-tech.com 2024.11.20 リソースの準備 事前にAzure上でリソースの作成をしてください。今回は以下のような設定のVirtual Machineを例にします。 コード作成 まず、既存リソースからコードを自動的に作成します。作成するにはimportブロックを用います。importブロックは任意の名前で作成した「.tfファイル」内に記述してください。 import { id = "/subscriptions/サブスクリプションID/resourceGroups/リソースグループ名/providers/Microsoft.Compute/virtualMachines/仮想マシン名" to = azurerm_virtual_machine.import-vm } idではVMのリソースIDを入力してください。リソースIDは対象VMの「プロパテイ」から参照することができます。 toの「import-vm」の部分はTerraform内での名前なので、自由に設定してください。 コマンド実行 以下コマンドにより、既存リソースの設定からコードを自動生成します。 terraform plan -generate-config-out = "ファイル名.tf" このコマンドを実行することで、コマンド内で指定したファイル名の「.tfファイル」が自動的に生成され、そのファイル内で以下のようなコードが自動的に生成されます。 resource "azurerm_virtual_machine" "import-vm" { location = "japaneast" name = "" network_interface_ids = [""] resource_group_name = "Terraform_Verification" tags = {Name = ""} vm_size = "Standard_B1ls" zones = ["1"] additional_capabilities { } boot_diagnostics { enabled = true # (1 unchanged attribute hidden) } os_profile_linux_config { disable_password_authentication = false } storage_image_reference { id = null offer = "ubuntu-24_04-lts" publisher = "canonical" sku = "server" version = "latest" } storage_os_disk { caching = "ReadWrite" create_option = "FromImage" disk_size_gb = 30 managed_disk_id = "" managed_disk_type = "StandardSSD_LRS" name = "" os_type = "Linux" write_accelerator_enabled = false # (2 unchanged attributes hidden) } delete_data_disks_on_termination = true } コードが生成出来たら以下コマンドを実行します。 terraform apply 上記コマンドを実行すると、「Plan:1 to import」と表示されるので、「yes」を記述し、Enterを押下します。 これによりリソースをTerraformで管理できるようになり、生成されたコードを修正し「terraform apply」を実行することでパラメータの変更ができるようになります。 注意事項 コードを自動生成する際に、ユーザ名やパスワードなどの機密情報等、パラメータによっては表示されないものがあります。生成されないパラメータの中には「terraform apply」実行時にエラーを発生させるものもありますので注意してください。どうしてもエラーを解消できない場合は、生成されたコードのresourceブロック内でエラーの出ているパラメータを以下のようにlifecycleブロックの「ignore_changes」で囲み、再度「terraform apply」を実行してみてください。 lifecycle { ignore_changes = [ os_profile, boot_diagnostics, additional_capabilities ] } このブロックは本来、値を変更したくないパラメータがあるときに使用するものですが、エラー解消に役立つので使ってみてください。 感想 たった数行のコードで既存のリソースを自動でコードに落とし込めるのは驚きましたし、コードを書くのが苦手な人でも一旦ポータル上で構築してから運用する際はコードで管理するということができるので非常に便利だと思いました。 おわりに 今回はTerraformによる既存Azureリソースのコード化について紹介しました。新規作成のみならず既存リソースの取り込みもできれば、運用も楽になると思いますのでぜひ使ってみてください。
アバター
こんにちは、Catoクラウド担当SEの中川です。 Catoクラウドより、2025年1月6日のアップデートにてAIアシスタントがリリースされました。 このAIアシスタントは、Catoの情報に特化した生成AIです! 主にCatoの仕様や設定方法などの確認、トラブルシュートなどに活用することが想定されます。 この記事では、AIアシスタントの実際の使用感や回答精度などについて記載しています! 機能概要 Understanding Cato’s Knowledge Base AI Assistant – Cato Learning Center 上記は、CatoがAIアシスタントについてまとめているページです。簡単にまとめると、以下のことが書かれています。 情報リソース : Knowledge Base の情報をもとに回答を提供しています。※特定のアカウントに関する具体的な回答は提供されません アクセス方法 : CMA右上のヘルプメニューからアクセス可能です 会話履歴の保存 : 同じセッション内であれば、会話は継続します。ただし、[クリア]を押したり、前の画面に戻ったりすると履歴は消えてしまいます。 情報の更新頻度 : AIアシスタントは週に一度ナレッジベースをスクレイピングして、最新の状態に保たれています。アップデートで機能改修などが入っても、数日のタイムラグで最新の情報に追いつきます。 対応言語 : 日本語でも問い合わせ可能ですが、ただし「最も正確な結果を得るには、英語で質問してください。」と記載されています。 また、実際に日本語で問い合わせると「 なお、今後のお問い合わせについては、英語でのご質問をお勧めいたします。 」というような文言を、AIアシスタント自体も時折回答の中に含めることがありました。 適宜、翻訳ツールを使って英語で質問するのが良いと思われます。 使ってみた結果 実際にAIアシスタントに、設定方法やトラブル中の問い合わせなどを聞いてみました。 動画形式で載せています。特にカットなどはせず、回答生成の時間はリアルな時間となっております。 CMAの設定方法について まずは、CMAでのTLSインスペクションの設定方法を尋ねてみました。 document.createElement('video'); https://blog.usize-tech.com/contents/uploads/2025/01/988504a1fcf69d56ec8cd15f81607ee1.mp4 TLSインスペクションの設定方法を教えてください かなり具体的にルールの設定値を教えてくれました。また、まだ公開されていない機能「TLS Inspection Configuration Wizard」の情報(1/24時点でEAのもの)も紹介してくれました。 特定のユーザのみに対象を絞る場合はどのように設定したらいいですか 想定していた回答は単純な「Sourceに指定します」程度の内容だったのですが、結果は違うものになりました。 最初にすべてをBypassするルールを作成し、テストユーザのみInspectするルールをその上位に設定するような方法を紹介してくれました。少数のユーザのみでテストする方法の Knowledge Base があることを私も把握できていなかったので、問い合わせしてみた価値がありました。 Bypassされたかイベントログで確認する方法はありますか https://blog.usize-tech.com/contents/uploads/2025/01/30764788b3503c13dab57e85082bd077.mp4 質問の意図としては、Home(旧UIではMonitoring)>Eventsでの確認方法を聞きたかったのですが、レポートでの出力方法が回答されました。 追加で、モニタリングのイベントログでの確認方法を聞き直したところ。想定通りの回答が返ってきました。 また、デフォルトでBypassされるOSや、証明書ピンニング問題についても触れてくれています。イベントログの確認方法だったので、トラブルシュートの一環の情報として紹介してくれたのでしょうか。丁寧な回答に思いました。 トラブルシューティングに関する質問 https://blog.usize-tech.com/contents/uploads/2025/01/4a41be417280d4b0248dcd49b91dcd05.mp4 特定のWebサイトへの通信がブロックされました。考えられる原因は何ですか 接続先側で制限がかかっている例と、CatoのInternet Firewallなどの設定が原因でブロックされている可能性の回答が得られました。 一次回答として網羅された内容かと思います。 パケットキャプチャの取得方法を教えてください https://blog.usize-tech.com/contents/uploads/2025/01/74cd8cbb2eab00c790bd020b6ee13b39.mp4 実際にトラブルシュートするときを想定して、試しにパケットキャプチャの取得方法を聞いてみました。Knowledge Baseに記載のあるものなので、これも自然に回答してくれました。 政府系サイトとは、例えばどのようなサイトが考えられますか 試しに技術的な内容とはやや外れる、一般的な質問として政府系サイトの例を聞いてみました。正直、抽象的な候補しかもらえませんでしたが、回答不可とはなりませんでした。 まとめ 良い点 全体的な回答精度としては高く感じました。簡単な言葉で端的に尋ねても、ほぼ想定した回答が返ってくる印象です。 また、Knowledge Baseのリンクを張ってくれることは便利だなと感じました。AIを利用する上では回答を100%信用するのは難しく、リンクがあればKnowledge Baseの内容によって判断することが可能だからです。 Knowledge Baseを利用したことのある方は共感いただけるかと思うのですが、Knowledge Baseはキーワード検索機能があまり優れていません。検索キーワードが含まれるおそらくすべてのページが引っかかってしまい、調べづらいのが正直なところでした。 この点、AIアシスタントが質問に応じて、適切なKnowledge Baseのページに誘導してくれることは大変ありがたいです。 気になった点 AIアシスタントの回答生成速度は動画をご覧いただいてもわかる通り、およそ30秒以内で回答してくれます。昨今利用される生成AIのスピード感と遜色ないかと思います。 ただし回答生成中に、ブラウザを切り替えたり、他のアプリなどに操作を移すと回答が止まってしまいます。回答が生成されるまで、ブラウザで待機している必要があります。 また、回答をもらった後、いざCMAの画面を操作しようとすると、AIアシスタントとのやり取りを閉じる必要がありました。その結果、会話履歴が消えてしまう点にかなり不便を感じました。 AIの回答を見ながらCMAの操作はできず、一度メモ帳などにペーストしてから操作する必要があることが現状感じる一番の難点です。 今後の所感 まだリリースされたばかりの機能のため、今後の機能改修や少なくとも回答精度の向上は期待できるのではないかと思います。 また、今回ご紹介したAIアシスタントとは別に、Internet FW上でAIを活用しベストプラクティスに準拠しているか確認する機能が直近追加されています。 こういったAIを活用した機能追加は、様々なところで見込めそうです。これからも期待が高まります!
アバター
近年、AIを活用した画像生成技術が飛躍的に進化しています。その中で、Re:Invent2024で発表されたAmazon Bedrockの新しい画像生成モデル「Amazon Nova Canvas」は新たな選択肢として注目を集めています。今回、Canvasを使って画像生成をしてみようと思います。   Amazon Nova Canvasとは? テキストや画像からプロ級の画像を作成する最先端の画像生成モデルです。プロンプト入力や直感的なインターフェースを通じて、ユーザーが簡単に高品質なビジュアルコンテンツを作成することができます。 特徴 1. 高精度な画像生成エンジン 最先端の生成AIアルゴリズムを採用しており、プロンプトに応じてリアルかつ魅力的な画像を生成します。その結果、ユーザーはわずかな入力でプロフェッショナルな成果物を得ることが可能です。 2. 柔軟なカスタマイズ 生成された画像に対して細かい調整が可能です。テキスト入力を使用して画像を簡単に編集できる機能、色調、スタイル、細部の編集など、多様な要望に応えられる柔軟性が魅力です。 3. 高速処理 画像生成のプロセスが迅速であることが特徴です。   Amazon Nova Canvasを使ってみる NOVA Canvasの利用可能な米国バージニア北部リージョンでBedrockサービスを開きます。   左メニューの[モデルアクセス]から「Nova Canvas」を選択します。   リクエストを送信すると、すぐに使えるようになります。   左メニューの[Image/Video]から、モデルに「Nova Canvas」を選択します。 推論では、「オンデマンド」と「推論プロファイル」を選択できます。「オンデマン」はサービスクォータまたはピーク使用時間によって制限される場合があります。「推論プロファイル」を選択すると、異なるAWSリージョンにまたがってリクエストをルーティングすることで、計画外のトラフィックバーストをシームレスに管理することができるようになります。 複数のAWSリージョンにトラフィックを分散することができるため、「オンデマンド」より高いスループットが可能になります。 今回は「オンデマンド」を選択します。 使えるようになりました!   画像生成を試してみる 画像を生成してみます。Actionで「画像を生成」を選択し、プロンプトにテキストを入力します。今回、英語でプロンプトを入力してますが、日本語入力も可能です。   「少年野球部員募集のチラシデザイン」をリクエストします。「画像サイズ」や「出力画像数」を指定することができます。 20秒程度で、1280×720サイズ、3種類の画像が生成されました。     気に入った画像があれば、そこからさらに別バリエーションで複数画像を作成できます。画像の右上からメニューを開き、「バリエーションを生成」を選択します。   下記の通り、3種類の画像が出力されました。   ユニフォームを青色に変更するよう指示すると、ユニフォームの色が変わりました。   もっと若い男の子に変更するよう指示すると、下記の通り出力されました。イラスト画像の出力パターンもありました。   画像を選択して、背景を削除したり、一部オブジェクトを指定して変更を加えることも可能です。   料金 今回、2時間ほどCanvasを利用し、料金は「$7.94」でした。   Canvasモデルのオンデマンドの料金は以下の通りです。 画像解像度 標準品質で生成された画像1枚あたりの価格 1024 x 1024 まで $0.04 2048 x 2048 まで $0.06 (2025年1月時点) まとめ 簡単な指示だけでリアルで高画質なデザイン画像を10秒~20秒程度で出力できました。広告、ウェブサイト、プレゼンテーションなどで使用するアートデザインの画像に活用できると思います。 プロンプトの日本語入力も試しましたが、画像がアジア人になったり漢字が含まれたりと、出力結果がアジアテイストになっている気がしました。 コストは画像1枚10円程度ですが、今回プロンプトからの指示をいろいろと変えながら、繰り返し同じような画像を生成したので、料金が少し高くなってしまったかもしれません。作成したい画像のイメージある場合は、イメージ画像をインプットに生成する方がコスト面の効率はいいかもしれません。   最後に、Canvasで自分の証明写真を元に、手書き似顔絵風のプロフィール画像を生成してみました。どれも似てないですが、一番近いと思われる左の画像をプロフィール画像として使ってみようと思います。    最後までお読みいただき、ありがとうございました。
アバター
昨年の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つの対策が、ランサムウェア攻撃にどう役立つのか、少しでもお伝えできていれば嬉しいです! 特にシミュレーションを通じて、ふるまい検知がいかに迅速かつ正確に異常を発見できるか、その便利さを感じていただけたでしょうか? 今回は脅威ハンティングのシミュレーションまではできませんでしたが、気になる方はぜひ試してみてください。 最後まで読んでいただき、ありがとうございました!
アバター