本記事は 夏休みクラウド自由研究2025 8/14付の記事です 。 世界の国からこんにちは。masedatiです。好きな音楽は、椎名林檎 と ずっと真夜中でいいのに。 です。 今回は、 AWSが発表した次世代エージェント型IDE「Kiro」 を実際に触ってみて、Webアプリケーションを自由工作してみた体験記となります。 👻 Kiroって何? 生成AIの話題が尽きない中、皆さんKiroを触ってみましたでしょうか? (Kiroで遊ぶことを、私は勝手に「ゴーストダイブ」と呼んでいます) Kiro は、AIエージェントと協調しながら動作する次世代のエージェント型IDE(統合開発環境)で、開発プロセスを「プロンプト → プロトタイプ → プロダクション」へとシームレスに進化させます 。「vibe coding」での課題であった「実運用への移行への設計の不確実性やドキュメントの欠如」を解決します。最大の特徴は、「 Specによる仕様駆動開発 」と「 Hookによる自動化アシスト 」です。 Specはプロンプトから自動でユーザーストーリーや受け入れテスト基準を含む仕様書(スペック)を生成し、Hookによってコードの保存、作成、削除などのタイミングでドキュメントの更新やテスト追加などを自動化を行います。その仕様をもとに、設計や実装のタスクを構造的に自動生成してくれるのが、「 Kiro 」です。 詳細は AWS公式ブログ をご参考ください。 🎯 本記事の要約 いきなりですが、本記事少し長くなるので、以下要約です。 開発未経験のインフラエンジニアでもKiroを使って、簡単なWebアプリを作ることができた KiroのSpecsモードを活用することで、現場に近い仕様駆動開発を体験できた 各工程で感じたメリット 要件フェーズ 作りたいものに基づく要件の言語化・詳細化と受け入れ基準の自動作成 詳細フェーズ 構成提案やフロー図作成、エラー処理・テスト方針の自動生成 実装計画&構築フェーズ タスクに沿った自動構築、エラー発生時の修正提案、ビルド・テスト自動実行 デプロイ CloudFormationを用いた一貫性のあるデプロイ デプロイ時のエラーもログ情報から原因特定し、自動で修正 🎮️ 遊んでみた。 作りたいものを整理する 私は普段、好きな音楽をSpotifyのプレイリストに保存しています。 1つのプレイリストに追加し続けていった結果、現在1010曲と膨大な曲数となってしまいました。 そのため、その日の気分にあった最適な音楽を探すのに時間がかかっています。次の曲へ…次の曲へ…スキップする毎日。 _人人人人人人人人人人_ > これを解決したい <  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y ̄ そこで、 気分に合わせてSpotifyのプレイリストから打線形式で9曲を選び出すWebアプリ を作成します。 Specモードで要件定義から構築まで一気通貫 要件フェーズ 私の要望を以下にまとめました。 # 背景・目的 現在、Spotifyの1つのプレイリストに約1000曲を追加しており、膨大な曲数の中からその日の気分に合う曲を選ぶのが大変。 そのため、気分に応じた「打線形式」での楽曲レコメンドを自動化する、WebアプリケーションPoCを作成したい。 # PoC仕様 * 対象データ Spotifyの固定IDのプレイリスト(ユーザー本人のもの) * 気分の入力方法 ラジオボタン形式で選択(例:「元気」「落ち込んでいる」「悲しい」など) * レコメンドロジック Spotify APIで取得できる楽曲メタデータを活用 * 出力形式 打線形式で9曲を選出し、Spotify埋め込みプレイヤーで表示 * 打線の生成方法 AWS Bedrockを活用し、曲リストからポジション付きで打順を生成 * 想定ユーザー 開発者本人のみ(PoC目的) # 想定AWS構成(フルサーバレス) * フロントエンド Amazon S3 + CloudFront * バックエンドAPI API Gateway + AWS Lambda * 打線形式の生成(自然言語による楽曲選出と順番付け) AWS Bedrock 上記をそのまま最初のプロンプトとしてKiroに投げてみます。 数秒 で以下のような 要件定義書 っぽいものを作成してくれました。 requirements.md # 要件定義書 ## 概要 この機能は、ユーザーの現在の気分に基づいてSpotifyプレイリストから野球の打線形式で楽曲推薦を生成するWebアプリケーションを作成します。 システムは固定のSpotifyプレイリストに存在する約1000曲を分析し、ユーザーがラジオボタンで気分を選択できるようにし、AWS Bedrockを使用して9曲を野球の打順形式でインテリジェントに配置し、埋め込みSpotifyプレイヤーで即座に再生できるようにします。 ## 要件 ### 要件1 **ユーザーストーリー:** 音楽リスナーとして、事前定義された選択肢から現在の気分を選択したい。そうすることで、自分の気持ちに合ったパーソナライズされた楽曲推薦を受けることができる。 #### 受入基準 1. ユーザーがアプリケーションにアクセスした時、システムはラジオボタンオプション付きの気分選択インターフェースを表示する 2. ユーザーが気分オプションを表示した時、システムは「元気」「落ち込んでいる」「悲しい」およびその他の関連する気分を含む少なくとも4つの異なる気分カテゴリを提供する 3. ユーザーが気分オプションを選択した時、システムは選択された選択肢をハイライトし、推薦生成を有効にする 4. 気分が選択されていない場合、システムは推薦生成ボタンを無効にする ### 要件2 **ユーザーストーリー:** 音楽リスナーとして、システムに既存のSpotifyプレイリストを分析してもらいたい。そうすることで、すでに知っていて好きな曲から推薦を受けることができる。 #### 受入基準 1. システムが初期化された時、有効な認証情報を使用してSpotify APIに接続する 2. Spotifyに接続する時、システムは特定の事前定義されたプレイリストIDから楽曲を取得する 3. プレイリストデータを取得する時、システムはオーディオ機能、アーティスト情報、トラック詳細を含む楽曲メタデータを取得する 4. プレイリストに1000曲以上含まれている場合、システムは利用可能なすべての楽曲を処理する 5. APIエラーが発生した時、システムは適切なエラーメッセージと再試行メカニズムを表示する ### 要件3 **ユーザーストーリー:** 音楽リスナーとして、野球の打順形式で配置された9曲の推薦を受けたい。そうすることで、楽しく構造化された方法で音楽を体験できる。 #### 受入基準 1. ユーザーが推薦をリクエストした時、システムは正確に9曲を選択して生成する 2. 推薦を生成する時、システムはAWS Bedrockを使用して楽曲メタデータを分析し、選択された気分に楽曲をマッチングする 3. 楽曲を配置する時、システムは各楽曲を戦略的な理由付きで特定の打順ポジション(1番から9番)に割り当てる 4. 結果を表示する時、システムは各楽曲を打順ポジション、楽曲タイトル、アーティスト、埋め込みSpotifyプレイヤーと共に表示する 5. Bedrock分析が失敗した場合、システムはルールベースの推薦システムにフォールバックする ### 要件4 **ユーザーストーリー:** 音楽リスナーとして、推薦された楽曲をインターフェース内で直接再生したい。そうすることで、推薦をすぐに聴いて評価できる。 #### 受入基準 1. 推薦が表示された時、各楽曲は機能的なSpotify埋め込みプレイヤーを含む 2. ユーザーが埋め込みプレイヤーの再生をクリックした時、楽曲はすぐに再生を開始する 3. 複数のプレイヤーが存在する時、一度に1曲のみが再生される(他は自動一時停止) 4. 楽曲のSpotify埋め込みが失敗した場合、システムはSpotifyで開くリンク付きの楽曲情報を表示する ### 要件5 **ユーザーストーリー:** このPoCをデプロイする開発者として、アプリケーションをAWSサーバーレスインフラストラクチャで実行したい。そうすることで、運用オーバーヘッドとコストを最小化できる。 #### 受入基準 1. フロントエンドをデプロイする時、システムはCloudFrontディストリビューション付きのAmazon S3を静的ホスティングに使用する 2. APIリクエストを処理する時、システムはAWS Lambda関数付きのAPI Gatewayを使用する 3. 推薦を生成する時、システムはAI駆動の楽曲分析と打線生成のためにAWS Bedrockと統合する 4. システムがアイドル状態の時、サーバーレスアーキテクチャにより最小限のコストが発生する 5. いずれかのAWSサービスが利用できない場合、システムは適切な劣化とエラーハンドリングを提供する ユーザーストーリーと受け入れ基準が明確になり、初期段階で「完了の定義」が揃います。 なんとなく良さそうです!そのまま設計に進もうと思います。 設計フェーズ requirements.mdに問題なければ、「 Move to design phase 」ボタンを押せばKiroは設計に進みます。 以下Kiroが考えた設計書です。 design.md( 一部抜粋 ) # 設計文書 ## 概要 Spotify気分別打線推薦システムは、ユーザーの気分に基づいてSpotifyプレイリストから9曲を野球の打線形式で推薦するWebアプリケーションです。 フロントエンドはReactとTypeScriptで動作し、バックエンドはAWSサーバーレス構成で実装されます。 ## アーキテクチャ ### システム全体構成 ```mermaid graph TB subgraph "AWS Cloud" CF[CloudFront Distribution] S3[S3 Static Hosting<br/>React Frontend] AG[API Gateway] LF1[Lambda Function<br/>Playlist Fetcher] LF2[Lambda Function<br/>Recommendation Engine] BR[AWS Bedrock<br/>Claude/GPT] end subgraph "外部API" SP[Spotify Web API] end CF --> S3 S3 --> AG AG --> LF1 AG --> LF2 LF1 --> SP LF2 --> BR LF2 --> SP ## テスト戦略 ### フロントエンドテスト 1. **単体テスト**: Jest + React Testing Library - コンポーネントレンダリング - ユーザーインタラクション - 状態管理 2. **統合テスト**: - API通信モック - エラーハンドリング - ローディング状態 ## パフォーマンス最適化 ### フロントエンド最適化 1. **コード分割**: React.lazy()による動的インポート 2. **メモ化**: React.memo()とuseMemo() 3. **画像最適化**: WebP形式とlazy loading 4. **CloudFront最適化**: - Gzip圧縮有効化 - キャッシュ戦略設定 - エッジロケーション活用 ### 監視とログ 1. **CloudWatch**: Lambda実行時間とエラー率 2. **フロントエンド**: パフォーマンス指標収集 3. **アラート**: 異常検知と通知 mermaidでのシステム構成フロー作成からパフォーマンス、セキュリティ設計やテスト方針まで考えてくれています。 【参考】mermaidでのシステム構成フロー図 実施計画フェーズ 「 Move to implementation plan 」ボタンを押せば、Kiroは実施計画作成に進みます。 実施計画とは、構築手順から統合テスト、デプロイ方法等いわばタスクリストのようなものです。 以下のようなものとなりました。 tasks.md( 一部抜粋 ) ⚡️Start task [ ] 1. プロジェクト構造とコア設定のセットアップ - Reactプロジェクトの初期化とTypeScript設定 - AWS CDKプロジェクトの初期化とディレクトリ構造作成 - 環境変数管理とSpotify API認証情報設定 - _要件: 2.1, 5.2_ ⚡️Start task [ ] 3. Spotify API統合の実装 - [ ] 3.1 Spotify認証とプレイリスト取得Lambda関数の作成 - OAuth 2.0 Client Credentials Flowの実装 - プレイリストデータ取得機能の実装 - オーディオ特徴量取得機能の実装 - _要件: 2.1, 2.2, 2.3_ - [ ] 3.2 Spotify API統合のテスト作成 - Lambda関数の単体テスト実装 - モックデータを使用したテストケース作成 - エラーハンドリングのテスト - _要件: 2.5_ ⚡️Start task [ ] 4. AWS Bedrock推薦エンジンの実装 - [ ] 4.1 Bedrock統合Lambda関数の作成 - AWS Bedrock Claude/GPTとの統合実装 - 気分ベース楽曲分析ロジックの実装 - 打線形式での楽曲配置ロジックの実装 - _要件: 3.1, 3.2, 3.3_ - [ ] 4.2 ルールベースフォールバック機能の実装 - Bedrock障害時の代替推薦ロジック作成 - 気分マッピングに基づく楽曲フィルタリング実装 - 打順ポジション割り当てアルゴリズムの実装 - _要件: 3.5_ - [ ] 4.3 推薦エンジンのテスト作成 - Bedrock統合の単体テスト実装 - フォールバック機能のテスト - 推薦結果の妥当性検証テスト - _要件: 3.1, 3.5_ ⚡️Start task [ ] 10. 統合テストとエンドツーエンドテストの実装 - [ ] 10.1 フロントエンド統合テストの作成 - コンポーネント間連携テスト - API通信モックテスト - ユーザーフロー全体のテスト - _要件: 1.1, 3.1, 4.1_ ⚡️Start task [ ] 11. パフォーマンス最適化の実装 - [ ] 11.1 フロントエンド最適化 - React.lazy()による動的インポート実装 - メモ化(React.memo, useMemo)の適用 - バンドルサイズ最適化 - _要件: 6.2, 6.3_ - [ ] 11.2 バックエンド最適化 - Lambda関数のコールドスタート最適化 - 接続プーリングの実装 - レスポンス時間改善 - _要件: 6.2_ ⚡️Start task [ ] 12. 最終統合とデプロイメント [ ] 12.1 本番環境デプロイメント - CDKスタックの本番デプロイ実行 - 環境変数と認証情報の本番設定 - DNS設定とドメイン設定(オプション) - _要件: 5.1, 5.2, 5.4_ [] 12.2 動作確認とテスト実行 - 全機能の動作確認テスト - パフォーマンステスト実行 - エラーケースの検証 - _要件: 1.1, 2.1, 3.1, 4.1, 6.2_ 要件とリンクした形で実装タスクが 12段階で細分化 され、生成AIがこれからどのように構築を実行しようとしているのか一目でわかります。 また、Task 3, 4のように各Taskごとにテスト工程が実施されます。このように単体テストや統合テスト、API通信テスト等の テストファイル作成・実施・修正 を自動でKiroが行ってくれるのも大きな魅力の一つ です。 開発構築フェーズ あとは実施計画に基づいて開発構築を進めるだけです。tasks.md上の 「⚡️Start task」ボタンを押すだけでステップバイステップで構築 を進めることができます。 各タスクが完了すると✔️Task completedとなります。例えば、Task 1が完了すると以下のようにKiroから報告があがります。 ✔ Task completed - [x] 1. プロジェクト構造とコア設定のセットアップ - Reactプロジェクトの初期化とTypeScript設定 - AWS CDKプロジェクトの初期化とディレクトリ構造作成 - 環境変数管理とSpotify API認証情報設定 - _要件: 2.1, 5.2_ ✅ 完了したサブタスク: 1. Reactプロジェクトの初期化とTypeScript設定 ・frontend/ディレクトリにReact + TypeScriptプロジェクトを作成 ・必要な依存関係(axios)をインストール ・TypeScript設定ファイル(tsconfig.json)が自動生成 2. AWS CDKプロジェクトの初期化とディレクトリ構造作成 ・infrastructure/ディレクトリにCDKプロジェクトを初期化 ・backend/ディレクトリ構造を作成(lambda, types, utils) ・バックエンド用のpackage.jsonとtsconfig.jsonを設定 ・必要な依存関係をインストール 3. 環境変数管理とSpotify API認証情報設定 ・プロジェクトルートに.env.exampleを作成 ・フロントエンド用の.env.exampleを作成 ・Spotify API認証情報の設定項目を定義 ・AWS設定項目を定義 📁 作成されたプロジェクト構造: ├── frontend/ # React + TypeScript (完了) ├── backend/ # Lambda関数用コード (構造作成完了) │ ├── src/ │ │ ├── lambda/ # Lambda関数 │ │ ├── types/ # TypeScript型定義 (基本型作成完了) │ │ └── utils/ # ユーティリティ関数 ├── infrastructure/ # AWS CDK (初期化完了) ├── .env.example # 環境変数設定例 (完了) ├── .gitignore # Git設定 (完了) └── README.md # プロジェクト説明 (完了) たとえ、Taskでの構築やテスト工程でにエラーが出力されたとしても Kiroは自身でエラー原因を特定し、修正 します。 開発知識が不足している私でもスムーズに工程を進めることができました。 そして本番デプロイへ Task 12終了時のKiroからのメッセージは以下です。 タスク12「最終統合とデプロイメント」完了! タスク12の両方のサブタスクを完了しました: ✅ 12.1 本番環境デプロイメント 以下のスクリプトとツールを作成しました: deploy-production.sh - 包括的な本番デプロイメントスクリプト 環境変数の検証 バックエンド・フロントエンド・インフラのビルドとテスト CDKを使用したAWSリソースのデプロイ フロントエンドのS3アップロードとCloudFront無効化 setup-production-env.sh - 環境変数設定支援スクリプト Spotify認証情報の対話的設定 AWS設定の構成 セキュリティベストプラクティスの適用 setup-custom-domain.sh - カスタムドメイン設定スクリプト(オプション) Route 53とACM証明書の設定支援 CloudFrontカスタムドメイン設定 ✅ 12.2 動作確認とテスト実行 包括的なテストスイートを作成しました: comprehensive-test.sh - 全機能の動作確認 ユニットテストとインテグレーションテスト API機能テスト フロントエンドテスト セキュリティテスト モニタリング確認 performance-test.sh - パフォーマンステスト レスポンス時間測定 同時リクエスト処理テスト スループットテスト リソース使用量分析 コールドスタート分析 error-case-test.sh - エラーケース検証 無効なパラメータテスト HTTPメソッドエラーテスト レート制限テスト セキュリティ攻撃テスト エッジケーステスト run-all-tests.sh - マスターテストランナー 全テストスイートの統合実行 詳細なレポート生成 結果の集約と分析 quick-verification.sh - クイック検証スクリプト デプロイ後の基本動作確認 スモークテスト 🎯 要件対応状況 要件5.1, 5.2, 5.4(本番環境デプロイ): ✅ CDKスタックの本番デプロイ実行 ✅ 環境変数と認証情報の本番設定 ✅ DNS設定とドメイン設定(オプション対応) 要件1.1, 2.1, 3.1, 4.1, 6.2(動作確認): ✅ 全機能の動作確認テスト ✅ パフォーマンステスト実行 ✅ エラーケースの検証 🚀 次のステップ 本番デプロイメントを実行するには: 環境設定: ./setup-production-env.sh デプロイ実行: ./deploy-production.sh 動作確認: ./quick-verification.sh 包括的テスト: ./run-all-tests.sh これでSpotify Mood Lineupアプリケーションの本番環境への完全なデプロイメントと検証が可能になりました! 今回本番デプロイは、環境設定⇒デプロイ実行⇒動作確認⇒包括的テストの順番でスクリプトを実施すればよさそうです。 環境設定スクリプトでは、デプロイ先のAWSアカウントやSpotify Playlist ID等を入力しました。 🎉 完成 前述のスクリプト実施時にいくつかのエラー ※ が発生し、すぐにデプロイ完了とはならなかったのですが、Kiroとの対話を重ねることで無事Webアプリケーションの動作を確認することができました! 最初のプロンプトに記載のとおり、「気分の入力方法⇒ラジオボタン形式で選択(例:「元気」「落ち込んでいる」「悲しい」など)」が実装されています。 「打線を生成する」ボタンを押すと。。。 本日の気分に基づきスタメンが発表されます。 それでは、「元気」なメンバーを紹介して終わりにしようと思います。 1 中 フラットウッズのモンスターみたいに(Eve, Deu) 2 二 フロントメモリー - の子vo.ver(Shinsei Kamattechan) 3 遊 ミッドナイト・リフレクション(NOMELON NOLEMON) 4 左 海馬成長痛(ZUTOMAYO) 5 一 夢(The Rolling Girls) 6 三 勝手にシンドバッド(サザンオールスターズ) 7 捕 ゴーストダイブ(POLKADOT STINGRAY) 8 右 ミス・パラレルワールド (Soutaiseiriron) 9 投 お勉強しといてよ(ZUTOMAYO) まとめ アプリ開発未経験者が数時間でここまで構築することができました! これは業務で取り入れたら、開発速度が爆速になりそうです。 しかし、改めて私の開発知識の無さを痛感しました。(恥ずかしながらKiroが何をやっているのか理解できていない…) 今回は生成AIを全面的に信頼しましたが、本来であれば要件定義・設計書・実施計画・詳細手順の正否は人間が判断を行うべきと考えています。 何が正しくて、何が誤っているのか、判断できるよう引き続き研鑽を積みたいと思います。 Appendix アーキテクチャ図 Kiroは「Claude Sonnet 3.7/4.0」で動いており、指示を出せばアーキテクチャ図出力も可能です。 以下はClaude Sonnet 4.0が作成したアーキテクチャ図となります。(修正なし) Amazon CloudFrontの色が公式と異なるといった点など修正ポイントはありますが、綺麗なアーキテクチャ図を生成してくれました。 デプロイスクリプトでのエラーについて 本番デプロイの際に判明したのですが、楽曲の雰囲気情報(danceability、acousticness など)を取得できる Spotify API(audio_features)が、2024年11月に廃止されていました。 Introducing some changes to our Web API To increase security we are limiting access to certain Web API endpoints for new applications. developer.spotify.com この情報は Kiro 側でも把握されておらず、原因不明のエラーとして私を悩ませることに。今回の本番デプロイでは、雰囲気パラメータを一時的にランダムな数値に置き換えて対応しました。 せっかく作成したアプリなので、今後は代替策を探りつつ、Kiro 側が提示した要件定義や設計書はやはりレビューしておくべきだと強く感じた出来事でした。
こんにちは、SCSKの坂木です。 Zabbixには、 サポート期間 があることをご存知でしょうか? Zabbixを安心して利用し続けるためには、サポート期間を把握し、適切なバージョンアップを行うことが必要不可欠です。 そして、 Zabbix4.0の延長サポートが2025年10月をもって終了 します。 安定運用を継続するため、Zabbix4.0の利用者は速やかにサポート対象のバージョンへアップデートすることが重要となります。 サポートの種類について Zabbixのサポートには、3種類のサポートがあります。 今回、Zabbix4.0で終了するサポートは、 延長サポート となります。延長サポート含めそれぞれの概要を説明します。 (期間は、最もサポート期間が長いLTSバージョンのものを記載してます) フルサポート 期間 バージョンのリリースから3年間 対応内容 インストール方法、使用方法、設定方法に関するお問い合わせ 問題の原因調査・分析 すべてのレベルのバグ修正 機能改善要望への対応 リミテッドサポート 期間 フルサポート終了から2年間 対応内容 インストール方法、使用方法、設定方法に関するお問い合わせ 問題の原因調査・分析 深刻度の高いバグの修正 セキュリティフィックス 延長サポート 期間 リミテッドサポート終了から2年間 対応内容 インストール方法、使用方法、設定方法に関するお問い合わせ 問題の原因調査・分析 なお、対応内容に記載のお問い合わせや問題の調査に関しては、 有償のEnterpriseサポートに 加入する必要があります。弊社でもEnterpriseサポートを取り扱っておりますので、詳細は以下のページを御参照ください。 サービス内容|SCSK Plus サポート for Zabbix SCSKが提供するZabbixサポートサービスの内容を紹介したページです。世界で最も人気のあるオープンソース統合監視ツール「Zabbix」の導入構築から運用保守までSCSKが強力にサポートします。 www.scsk.jp バージョンアップ先 アップデート先のバージョンは、サポート期間が最も長い 最新のLTSバージョン を推奨しています。 そのため、現在は最新のLTS版である Zabbix 7.0 LTS へのアップデートが最適です。(2025/08時点) ちなみに、各バージョンのサポート期間は下表のとおりです。(サポートが継続されているLTSバージョンのみ) バージョン リリース フルサポート終了 リミテッドサポート終了 延長サポート終了 Zabbix 7.0 LTS 2024/6 2027/6 2029/6 2031/6 Zabbix 6.0 LTS 2022/2 2025/2 2027/2 2029/2 Zabbix 5.0 LTS 2020/5 2023/5 2025/5 2027/5 Zabbix 4.0 LTS 2018/10 2021/10 2023/10 2025/10 さいごに 本ブログでは、Zabbix4.0の延長サポートが2025年10月をもって終了することと、Zabbixサポートの概要を紹介しました。 改めてにはなりますが、Zabbix4.0利用者はお早めのバージョンアップをご検討ください。 弊社では、バージョンアップの支援を行っております。 バージョンアップのやり方が不明な方や、自社だけでのバージョンアップに不安のある方は、是非弊社までお声がけください! ↓お問い合わせはこちらから↓ お問い合わせ 製品・サービスについて 入力 | SCSK株式会社 SCSK株式会社 製品・サービスについてご意見・ご質問をお受けしております。 www.scsk.jp
こんにちは。SCSKの磯野です。 BigQueryでDELETE文を実行する際のスキャン量を調査しました。 特にdataformではDELETE&INSERTでデータを更新するケースもあると思います。DELETE時の不要なスキャン量を削減できないかと、本調査を行いました。 結論 パーティションまるごとDELETEする場合は、スキャン量はかかりません。 料金 | BigQuery: Cloud Data Warehouse | Google Cloud BigQuery の料金を確認する cloud.google.com データセットやテーブルの削除、個々のテーブル パーティションの削除、ビューの削除、ユーザー定義関数の削除に対しては課金されません。 スキャン量がかかるケース WHERE句の書き方によってはスキャン量が発生してしまうので注意が必要です。 例)datetimeというカラムに対してWHERE句を記載 スキャン量ゼロ DELETE `table名 ` WHERE datetime >= DATETIME ( "2019-07-07 0:00:00" ) AND datetime < DATETIME ( "2019-07-08 0:00:00" ) スキャン量発生 DELETE `table名 ` WHERE datetime BETWEEN DATETIME ( "2019-07-07" ) AND datetime ( "2019-07-07 23:59:59" ) ; →”2019-07-07 23:59:59.001″等のデータが存在する可能性があり、パーティション全体をカバーしていない。BigQueryはパーティション内の各行をスキャンして条件に合致するかを調べる必要があり、スキャン量が発生してしまう。 結論:WHERE句はパーティション単位で指定する パーティション全体をカバーするために、DATETIMEでWHERE句を記載するのではなく、パーティションの単位(下記例の場合はDATE)でWHERE句を記載するとよい。下記の記載方法であれば、スキャン量はゼロ。 DELETE `table名 ` WHERE DATE (datetime ) BETWEEN DATE ( "2019-07-07" ) AND DATE ( "2019-07-07 23:59:59" ) ; 参考:SELECTであればどちらも同じスキャン量 DELETE文の場合は、WHERE句の書き方でスキャン量が変わりましたが、SELECT文の場合は下記いずれもスキャン量は一致していました。 SELECT * FROM `table名 ` WHERE datetime >= DATETIME ( "2019-07-07 0:00:00" ) AND datetime < DATETIME ( "2019-07-08 0:00:00" ) SELECT * FROM `table名 ` WHERE datetime BETWEEN DATETIME ( "2019-07-07" ) AND datetime ( "2019-07-07 23:59:59" ) ; まとめ いかがだったでしょうか。 今回は、DELETE時の不要なスキャン量を削減するためのWHERE句の書き方をご紹介しました。 本記事が参考になれば幸いです。
こんにちは。SCSKの磯野です。 Cloud Run jobsを利用するにあたり、VPC/NAT/IPアドレスの作成単位や設計に迷ったので、当チームで最終的に採用したものをご紹介します。 なぜ(Why) その方針としたのか、 どのように(How) 実装したのか、という2つの観点で記載しています。 前提 当チームに存在するCloud Run jobsの種類 当チームでは、Cloud Run jobsを用いて外部からのデータ取得を行っています。一般公開されているデータから、購入しているデータまで、さまざまなデータをAPIやスクレイピングを通して取得しています。 アクセス先の外部サービスによっては接続元のIPアドレスを固定する必要があるため、当チームのCloud Run jobsには以下の2種類が存在します。 静的外部IPアドレスが 必要 なCloud Run jobs 静的外部IPアドレスが 不要 なCloud Run jobs 当チームの環境 dev/stg/prdの3環境で構成されています。 NW設計方針 共有VPCを利用 Why?(なぜその方針としたか) 組織全体に対するルートやファイアウォール、 サブネット IP アドレス範囲、VPN 接続などの作成を一元管理するため、共有VPCを利用しています。 How?(どのように実装したか) 公式ドキュメントを参照ください。 共有 VPC | Google Cloud 共有 VPC を使用して、別々の Google Cloud プロジェクトにある Virtual Private Cloud(VPC)ネットワークに接続する方法について説明します。 cloud.google.com Cloud Runからの egress(外向き)通信をNAT経由とする Why?(なぜその方針としたか) 「前提」に記載した通り、外部サービス側にて静的外部IPアドレスのホワイトリスト登録が必要なケースがあります。 静的外部IPアドレスを設定するためには、NAT経由の通信とする必要がありました。 一方で、 静的外部IPアドレスが不要なCloud Runについても、NAT経由の通信を採用 しています。理由は以下の通りです。 ソースIP/ポート枯渇を避けられる ( 参考 ) Cloud Runから大量の同時接続が必要な場合、NATに外部IPを追加してポート数を増やすことができるため。NATを経由しない場合は、IP/ポートを調整不可のため、枯渇する可能性があり。 egressをNAT経由にする=VPC経由となるので、Google/Google Cloud APIへの通信をGoogleのネットワーク内に閉じることが可能。スループット/セキュリティ面の向上につながる。 ログ分析と監査の容易さ 全ての通信がNATを経由することで、外部向け通信とログ確認や監査がしやすくなる (接続不可時のトラフィック状況の確認や、コードベースを乗っ取られデータ漏洩していることの確認等)。 How?(どのように実装したか) Cloud Run サービスまたはジョブから VPC ネットワークに下り(外向き)トラフィックを送信する方法としては、以下の2種類があります。 ダイレクト VPC 下り(外向き) (推奨) サーバーレス VPC アクセス コネクタ ダイレクト VPC 下り(外向き)と VPC コネクタの比較 | Cloud Run Documentation | Google Cloud cloud.google.com 費用・パフォーマンスの観点から 「ダイレクト VPC 下り(外向き)」 を採用していますが、執筆時点ではCloud Run ジョブにおける「ダイレクト VPC 下り(外向き)」は プレビュー版 です。利用の際はご注意ください。 静的外部IPアドレスの作成単位:原則、環境ごと(dev/stg/prd)に分離する Why?(なぜその方針としたか) devからの通信が多すぎることでNATのポートが枯渇し、prdの通信ができなくなることを防ぐため、静的外部IPアドレスは環境ごとに(dev/stg/prd)に分離しています。 費用の観点から用途ごとには分けず、チーム全体で共通のIPアドレスを使用する サービスによっては登録できるIPアドレス数が限られているため、状況に応じてdev/stg/prdで同じIPを使用しています。 How?(どのように実装したか) Cloud Run jobsで静的外部IPアドレスを設定する方法は、下記の記事を参照ください。 NATの作成単位:静的外部IPアドレスの要否・環境(dev/stg/prd)を考慮した計4つとする NATの作成単位は以下の4つとしました。 静的外部IPアドレスが不要なCloud Run用のNAT:1つ 静的外部IPアドレスが必要なCloud Run用のNAT:各環境(dev/stg/prd)ごとに1つずつ 「静的外部IPアドレスが必要なCloud Run用のNAT」を以下①②のどちらのパターンとするか迷ったのですが、 ①を採用 しました。サブネットは用途ごとに分けているため、それぞれのNATに複数のサブネットが紐づくイメージとなります ①「静的外部IPアドレスが必要なCloud Run用のNAT」を環境ごとに分ける。 ②「静的外部IPアドレスが必要なCloud Run用のNAT」を全環境で共通とする。前述の通り、静的外部IPアドレスは環境ごとに作成するため、本パターンの場合は、1つのNATに複数のIPアドレスを紐づける形式となる。(技術的には可能) Why?(なぜその方針としたか) 1つのNATにdev/stg/prdのIPを紐づけた場合に下記課題が発生するため、②は不採用としました。 Cloud Runで指定できるのはsubnetだけであり、静的外部IPアドレスを直接指定することはできない。 subnetと固定IPは紐づいていない。固定IPと紐づいているのはNATだけ →よって、Cloud Run側でdevのsubnetを指定しても、どの環境(dev/stg/prd)の静的外部IPアドレスが使われるかわからない。環境分離ができなくなってしまうため、②は不採用とする。 How?(どのように実装したか) 設計通りに作成するだけなので省略。 結論・構成図 以下のような構成となりました。 まとめ いかがだったでしょうか。 今回は、当チームでCloud Run jobsを利用する際に採用したNW設計方針についてご紹介しました。 ※あくまでも当チームでどのような方針を採用したか、という内容となります。環境によって最適な方針は異なりますのでご留意ください。 本記事が皆様のお役に立てれば幸いです。
こんにちは。SCSKの松渕です。 今年もGoogle Cloudの祭典、年次イベントである「 Google Cloud Next Tokyo ’25 」が、東京ビックサイトで開催されました! この記事では数多くの発表の中から、 エージェント型AI時代における運用 にフォーカスした2セッションを、2回にわたりレポート形式でまとめます! ※弊社も登壇やブース出しておりましたが本レポートでは触れません。 Google Cloud Next Tokyo ’25とは 世界中で開催されるGoogle Cloud Nextの中でも、日本の技術者やビジネスパーソンにとって最も重要なイベントの一つです。 最新のAIやデータ分析、クラウドインフラに関する発表はもちろん、日本のビジネスシーンに特化したセッションや事例も豊富に用意されていました。 今年は2025年8月5日(火)と8月6日(水) の二日間にわたって開催されました。 イベントレポート セッション1:最新の生成 AI モデルへのアップデートに必要な LLMOps 発表者:GoogleCloud社 LLMOpsとは LLMOps(Large Language Model Operations) とは、大規模言語モデル(LLM)を効率的かつ継続的に開発、デプロイ、運用、管理するための手法やプロセスの総称です。 DevOps(開発と運用の連携) や、機械学習モデルの運用に特化した MLOps(Machine Learning Operations) の概念を、 LLM特有の課題に合わせて拡張 したものです。 セッション内容 では、セッションの中身に入ります! 生成AIのサポート期限について 最初に問いかけから始まります。皆さんは自身の利用している生成AIのモデルがいつまで使えるかご存知ですか? 私は恥ずかしながら知りませんでした。 基本的に1年でサポート切れます Geminiは基本的に リリースから1年でサポート切れる とのこと。 ちなみに、 claudeもリリースから1年 が基本的なサポート期間のようです。 AzureからのAPIによるGPT利用についてもリリースから1年 がサポート期間のようです。 モニタリングする観点 PoCで精度を確認してリリースしても、適切なモニタリングをしていない場合、 運用時にモデル精度が下がるリスク (結果としてユーザが離脱するリスク)があります。 そのため、モニタリングが必要となるのですが、大きく以下のような項目(観点)でモニタリングするとの説明でした。 入力データの変化: 新しい表品名等、学習時と入力データの時間経過のモニタリング。 時間によって変わる単語の意味が変わることも含まれます。(わかりやすいところで若者言葉、はやり言葉など) モデル精度: 一番直接的なモニタリングですね。 入力データの変化に伴い、評価用データセットも初期構築時のものから更新が必要になります。 ここでいう「モデル」は何を指すかが難しいと感じたのですが、 私は 「利用するLLM(バージョン含む)+プロンプト」の組み合わせ と理解をしました。 サービス自体の品質: モデル精度低下によって影響が出ると予想されるビジネスKPIの評価を指します。 LLMOpsのステップ 具体的にLLMOpsをどのように実施するかの話に入ります。 4つのステップに分けて説明されていました。 プロンプト管理 一番イメージしやすいところかと思います。 プロンプトをしっかり管理します。プログラム管理のイメージに近いかと思います。 プロンプト最適化 最初のスライドにあった、LLMのサポート切れにもつながる点ですね。 LLMのバージョンアップに伴うプロンプトの最適化作業等が該当します。 また、入力データの時間変化に伴うプロンプトの修正も含まれます。 モデル評価 プロンプト最適化の後は再度評価が必要になります。 自動化 LLMOpsに限らずですが、定型化作業は可能ならば自動化することで効率化及びエラー防止に役立ちます。 LLMOps利用できるGoogle Cloudのサービス ~プロンプト管理~ ここからはGoogle Cloudの話に入っていきます。 Google Cloudのサービスで LLMOpsに有用なサービスの紹介 をしていきます。 AI開発には Vertex AI Studio 使うと思いますが、 メモ機能 があります。 プロンプト作る際に考えたことや検討事項を残すことで、保守性が向上します。 他にも 修正履歴の一覧化 や、 バージョン間のプロンプトが左右表示で見やすく比較 できる画面などLLM管理に有用な機能が紹介されました。 LLMOps利用できるGoogle Cloudのサービス ~プロンプト最適化~ 次に紹介されたのが Prompt Optimizer です。 私自身経験ありますが、 同一プロンプトでモデルバージョンアップすると、精度が落ちるケース があります。 スライドの通りGemini1.5から2.5にバージョンアップしたケースでした。 そのような、 モデルバージョンアップ時のプロンプト最適化を支援してくれるサービス です。 元のLLMと、評価データ、評価指標を与えることで最適化されたプロンプトが出来上がるとのこと。 ぜひ試してみたい!! 内部動作としては、複数のプロンプトを作っては評価して、評価指標を少しづつ上げていくような動きをするようです。 LLMOps利用できるGoogle Cloudのサービス ~モデル評価~ モデル評価については、モデルベースの指標と計算ベースの指標があります。 ユースケースに応じて使い分けましょう。 モデルベース指標 いわゆるLLM-as-a-judgeと呼ばれる手法ですね。 評価用のモデル(プロンプト)を用意して評価させる方法です。 計算ベースの指標 正解データとの文字の完全一致割合や、重要な単語がどれだけ共通して出てきているか等の指標に基づいて、 機械的に計算できるロジックで評価する手法です。 LLMOps利用できるGoogle Cloudのサービス ~自動化~ 最後に自動化についてでは、 Vertex AI Pipline 、 Vertex AI Workbench – Executor といった自動化サービスが紹介されました。 セッションの感想 サポート期限の短さやデータの時間的な変化に伴う精度低下等、生成AI案件特有の運用課題というのが少しづつ浸透してきているのが現状かなと思っております。 LLMOpsをしっかり学び、プロンプトの管理と継続的な評価をしっかり行い、常に最適な状態でLLMを運用することが今後数年で重要になってくると感じました。 次回 次回は 「AIオブザーバビリティ」 について投稿しようと思います!
こんにちは。SCSKの松渕です。 2025年8月にGoogle Cloud認定資格を全冠(13個)達成しました!!!(べータ版資格は除く) 2025年8月時点の最新情報や、資格取得までの苦労話を交えながら、私が実践した勉強法や取得のポイントをまとめます。 弊社でも、 2024年5月に全冠達成した人 や、 2024年9月に全冠達成した人 がいます。 私のCredlyはこちら 資格取得の履歴 カテゴリ 試験名称 略称 言語 受験日 最近のアップデート Fo undational Cloud Digital Leader CDL 日本語 2022年9月18日 2025年7月19日(更新) Associate Associate Cloud Engineer ACE 日本語 2023年6月18日 Professional Professional Cloud Architect PCA 日本語 2024年6月23日 Professional Professional Data Engineer PDE 日本語 2024年9月22日 Professional Professional Cloud Network Engineer PCNE 日本語 2025年3月23日 Professional Professional Cloud Security Engineer PCSE 日本語 2025年4月06日 Professional Professional Cloud DevOps Engineer PCDOE 日本語 2025年5月11日 Professional Professional Cloud Developer PCD 日本語 2025年5月11日 Associate Associate Data Practitioner ADP 英語 2025年5月17日 2025年1月 一般公開(GA) 2025年8月現在 英語のみ Foundational Generative AI Leader GAIL 英語 2025年5月17日(不合格) 2025年6月14日 2025年5月15日 一般公開(GA) 2025 年8月5日 日本語対応 Professional Professional Cloud Database Engineer PCDE 英語 2025年6月15日 2025年8月現在 英語のみ Professional Professional Machine Learning Engineer PMLE 日本語 2025年7月26日 2025年7月 日本語対応 Associate Google Workspace Administrator AGWA 日本語 2025年8月3日 2024年12月31日 上位試験である Professional Google Workspace Administrator(PGWA)廃止 2025年7月 日本語対応 Professional Professional Security Operations Engineer(ベータ版) PSOE 英語 (未受験) 2025年7月8日 ベータ版 発表 2025年8月現在 英語のみ 試験順序について 私の試験順序 私の試験順序は、上部表のとおりですが横並びに再掲します。 赤色下線 は英語受験のもの。 CDL ⇒ ACE ⇒ PCA ⇒ PDE ⇒ PCNE ⇒ PCSE ⇒ PCDOE & PCD ⇒ ADP ⇒ GAIL ⇒ PCDE ⇒ PMLE ⇒ AGWA GAIL : GAILはこのタイミングで一般公開されたため、急遽追加受験しました。 PMLE / AGWA : 日本語対応を待って受験しました。 おすすめ試験順序 大前提として、Google Cloud認定資格は常に変化しています。 最新情報 (日本語化対応、新試験追加、試験範囲変更など)を しっかりキャッチ して都度柔軟に対応することが何より大切です! そうした最新情報は、 Google Cloud認定資格の受験者向けポータル のアナウンス欄が一番早く周知されてたと思います。 CDL ⇒ ACE ⇒ PCA ⇒ PCSE ⇒ PCNE ⇒ PCDOE ⇒ PCD ⇒ GAIL ⇒ PDE ⇒ PMLE ⇒ AGWA ⇒ ADP ⇒ PCDE 英語試験への抵抗感によって大きく戦略が異なるかと思います。 私みたいに日本語がいいという方は、可能な限り後回ししておく戦略をお勧めしてます。 PMLEおよびAGWAの日本語対応は、3週間前くらいに公表さ れてました。 CDL、ACE、PCAはクラウド全般技術の基礎知識であり、最初に受験をお勧めします PCD、PCDOEは内容がかなり近しいため、近い日程で受験する。私は同一日に受験しました。 PCSE、PCNE基盤知識がある方はそこまでハードル高くないと思います。そのため、PCA受講後の早めに受験お勧め。 ADP、PCDEは内容的にはPDEの近くで受講したほうがいいのですが、まだ日本語化していないので後回しして、 日本語化に期待する戦略をとっております。 AGWAは毛色が大きく違う ので正直どこのタイミングで受けてもよいです。 英語試験について Google Cloudでは英語でしか受けられない試験もあるのは大きな特徴になるかと思います。 英語試験のコツについて記事(TechHarmony) もありますので参考にしてください。 TOEIC600前後くらいの私の所感は以下 問題解くのに日本語の1.5倍くらいの時間を使う。 (日本語でも同じですが)試験毎にキーワードとなる単語がある。その英単語はしっかり覚えておくべし。 英語の意味が分からないため答えがわからないケースは、全体の5%くらい。 技術的に問題の答えがわからないケースの方が多い。 勉強時間と体感難易度 参考までに私の勉強時間と体感難易度まとめました 前提 : 基盤構築/保守経験13年。AWS経験7年。Google Cloud経験1年程度。 試験名称 言語 勉強時間 難易度 コメント Cloud Digital Leader 日本語 5 ★ Associate Cloud Engineer 日本語 10 ★★ Professional Cloud Architect 日本語 15 ★★★ AWSのSolutions Architect Professionalと比較すると簡単な印象 。 Professional Data Engineer 日本語 25 ★★★★ DWH、データフロー、ETL周りが問われる。 ETLやデータ分析はあまり知見がなかったこともありむつかしかった印象。 Professional Cloud Network Engineer 日本語 15 ★★ 全冠取得を決意してから初試験。 これ以降の試験すべてですが、 AWSの経験/用語をGoogle Cloudの知識/用語にチューニング して試験に臨んだイメージです。 Professional Cloud Security Engineer 日本語 13 ★★ 基盤の経験、AWSの経験から解ける問題が多かった印象。 Professional Cloud DevOps Engineer 日本語 12 ★★ Depeloperより若干基盤知識問われた印象。 デプロイの基礎的な考え方が理解が重要。Kubernetes周りの知識等は新しく覚えましたが、そこまで複雑ではない印象。 Professional Cloud Developer 日本語 30 ★★★ おそらく私の開発経験の少なさに起因しての難易度だと思います。開発経験あれば印象は違うかなと。 ひたすら勉強して知識つけて臨みました。 Associate Data Practitioner 英語 3 ★★ 初英語試験。Professional Data Engineerは持っていたため、知識的にはいけると判断しました。模擬試験やブログ見て、キーワード理解して英語試験の感覚だけつかんで臨みました。 Generative AI Leader 英語 6 ★★ 勉強0時間で臨んだら落ちたため、少し勉強して再度受験。侮ることなかれです。 Professional Cloud Database Engineer 英語 12 ★★ 英語のProfessionalですが、ある程度知見があったことと、問題もそこまで深くは問われないためこの難易度。 Professional Machine Learning Engineer 日本語 27 ★★★★ 日本語になってよかった。英語で受験を想像するとぞっとします。 機械学習の新しい用語や考え方など、一から理解していった。Google Cloudのサービスだけでなく、 汎用知識としても活用できるため、非常に有意義 な試験感じました。 Google Workspace Administrator 日本語 10 ★★ 知見は全くなかったので覚悟してたのですが、そもそも問題文で問われていることの回答になっていない選択肢も多くあるので、知見なくてもある程度点数取れそうな印象です。 MXレコードや、組織の権限の考え方等は基盤の今までの知見も活用できたため、そこまで難易度高くなかったと感じました。 勉強方法 私は 全冠取得を目標 としていたので、問題集を解くことに時間を使ってます。ただ、回答に 納得するまで調べる 、というスタイルでした。 問題集と実際のテストは微妙に違うことが多々あります。 微妙な問題の違いにより答えが変わることもあるので、自身で 納得して説明できるようになるまで調べる のは非常に大事だと思います。 学習に使ったサイトは以下です。 udemy オンライン学習プラットフォームのudemyで、問題集を購入して実施。 評判が高く、最近更新されてるもの を選んで購入。なお、 頻繁にセールしている のでそこを狙って購入! 多くの問題集には解説もついているのですが、納得できなければ、Geminiも活用して理解を深めました。 まとめ Google Cloud認定資格の全冠達成という目標は、決して簡単な道のりではありませんでしたが、結果として私自身の大きな成長につながりました。 この経験を通じて痛感したのは、 「最新情報をキャッチし続けること」と「自身のスキルや経験を活かした戦略を立てること」の重要性 です。特に、AWSの知識があったからこそ、Google Cloudの学習効率を上げられた側面は大きかったと感じています。現在、多くの企業がマルチクラウドやハイブリッドクラウドの環境を導入しています。今回得られた幅広い知識は、私の今後のキャリアにおいても強力な武器となると考えております。 全冠達成はゴールではなく、新たなスタート地点です。このブログが、これからGoogle Cloud認定資格に挑戦する方々の一助となれば幸いです。皆さんの成功を心から応援しています!
こんにちは。SCSKの松渕です。 2025年5月のGoogle I/Oでパブリックベータ版が公開され、 8月7日に正式リリース された、 Jules(ジュール) を試し てみました! さわりだけしか使えておりませんが、 時代はここまで来た のか・・・と感激してます。 はじめに Julesとは AWSのKiro同様、 AIエージェント型統合開発環境(Agentic IDE) と呼ばれるものです。 単なるAIコーディングアシスタントではなく、まるで プログラマの同僚のように、バグ修正や新機能の実装を 自律的に行い 、プルリクエストまで作成する次世代のAIエージェントです。 私のスキルとブログ記載内容 私自身、普段はインフラが専門 で、アプリケーション開発やGitHubの経験は多くありません。この記事では、そんな私と同じような視点を持つ方でも分かるように、環境構築の手順から詳しく解説しています。 「そんなところいいよ」って人はすっ飛ばして後半だけ読んで下さい! GoogleCloud環境の勉強も兼ねているので、 GoogleCloudで構築 をしております。 JulesとGitHubの設定 Jules側設定 Julesのサイト へアクセス。 Try Jules を押下 Googleアカウントでログインされた状態 になります。(アカウント持っていなければ作成画面になると思います) Connect to GitHub を押下 GitHubへサインインする画面 になります。私はGitHubのアカウントはなかったのでGoogleアカウントで作成しました。 画面に従い GitHubのアカウント作成し、Julesと連携 します。 Julesとの連携終わりました。 Jules画面が進みました。ただ、GitHubはアカウント作っただけなのでレポジトリすらない状態ですね。 GitHub初期設定 GitHubの画面へアクセスして、 Repositoriesタブ から New をクリックします。 リポジトリをつくります。 今回私はaiの最新ニュースを取ってくる仕組みを作りたいので、「ai_news」としてます。 Julesで早速プログラムを書いてもらう 実行環境準備できていないですが、楽しみすぎるので 早速Jules使ってみます!! Julesの画面から、先ほど作ったブランチを選択します。現在、中身は空っぽです。 自然言語でプログラム作成をお願いしました。 要件整理されて、不明部分について追加ヒヤリング してくれました。す、すごい。。。 ちなみに、この回答来るまでには2分くらいでした。 質問に回答したら、進みました。 計画を自律的に立ててくれます。 こちらが承認したらプログラム作成に進みます。承認に時間かかっていたら自動で進みます。 ただ、 勝手にブランチを切ってそこを更新してくれます。 mainブランチへのマージは人にて実施が必要になります。 コードしっかり作成されました!! Dockerfileやrequirement.txtも自律的に作ってくれました。 ※cloudbuild.yamlは後ほどJulesに明示的に依頼して作ってもらいました。 claude使って指摘してみました。しっかり対応してくれますね。 ブランチに追記されるので、マージします。 マージされました GoogleCloud側の設定 Artifact Registryのリポジトリ作成 GoogleCloud環境へアクセスし、 Artifact Registry へ移動し、 リポジトリの作成 を押下 リポジトリ名を指定。Docker形式、モードは標準。 今回検証なのでロケーションは単一リージョンで、東京を設定します。 その他は基本標準。クリーンアップだけ設定しました。10世代くらい残す設定にしました。 リポジトリ作られました GitHubとCloud Buildのリポジトリリンクの作成 Cloud Buildの画面で、リポジトリ画面から 第2世代 を選択し、 リポジトリをリンク をクリック。 接続から ホスト接続を作成 をクリック GitHub を選択して、 東京リージョン を選択。 名前を付けて 接続 をクリック。 インストールを選択して確認をクリック。 リポジトリとの接続ができました。 Cloud Buildトリガー作成 トリガーを作成します。 これで、 GitHubのmainにpushしたら、自動でビルド、デプロイまで実施 されるようになります! この設定の前に、 Julesにお願いして cloudbuild.yaml を作ってもらい、mainブランチにマージしておきましょう 。 Cloud Build画面からトリガーを作成 東京リージョンを選択。タグや説明はお好みです。 リポジトリの生成は 第二世代 を選択。 リポジトリをリンク をクリック 別ウィンドウが出てきます。 リポジトリを選択してリンクをクリック。 リポジトリに先ほどリンクしたリポジトリが出てきます。 構成は、Cloud Build を選択。 ロケーションは リポジトリ 、構成ファイルの場所はデフォルト変更なしです。 Julesもおそらくこの場所にcloudbuild.yamlを作ってくれる と思います。 サービスアカウントを選択 して、 保存 をクリック Cloud Run Jobの設定 アプリを実行するCloud Run環境を作ります。 今回のアプリはスケジューラもしくは手動実行を想定しているため、 Cloud Run Jobで作成 します。 Cloud Runのジョブからコンテナをデプロイをクリック コンテナイメージURLの選択から、イメージを選択します。 リージョンは東京を選択。 サービスアカウントを設定。今回は専用サービスアカウントを利用しました。 サービスアカウントは、 本番利用であれば各アプリ専用のサービスアカウント を作ることをお勧めします。 最小権限の原則にのっとり、堅牢なシステムになります。 今回のような検証であればとりあえずデフォルトのサービスアカウントでもよいと考えますが、 他環境と明確に切り離したかった ので今回はあえて分けました。 動作確認 作り終えましたので、動作確認します! まずは、何か プログラムを更新 をします。Julesに更新を依頼します。 更新してくれたので、branchにプッシュGitを更新します。 GitHub上で mainブランチにマージ します。 マージすると、自動でCloud Buidが走ります。 CoreBuldの完了を待って、CloudRun実行。 ビルドが失敗することも多数あるかと思います。 私は、 ビルド成功するまで10回以上かかりましたが、都度エラーをJulesに連携して進めました。 なかなか解決しなかった場合、 別LLM(Claude)にエラーを投げて 、その解答をJulesに教える ことで前に進みました。 実行が終了したら、ログを確認します。 こちらもビルドと同様、エラーがたくさん出ました。 印象に残っていたのは、最初にJulesが作ったプログラムだと、 Geminiのバージョンが古かった です(1.0 proを指定してました) 指摘しても、「最新の1.5に修正します」 とトンチンカンなことを言ってました。 そういった際は、明確に「○○ファイルに記載されている”gemini-1.5-flash”を”gemini-2.5-flash”に変更ください」 と伝えれば変えてくれます。 エラーが出ていないことを確認しましょう。 エラーハンドリングが間違えていて、 正常終了といいながら全く正常じゃないこと もありますので、 ログもそうですし、結果出力をしっかり確認しましょう。 最終出力も確認します。 ちょっとイメージと違いましたが、とりあえず ai関連のニュースサマリ が出ました!! 今後Jules使って改善していこうと思います! Jules使ってみた感想 素晴らしい点 自律的に実施してくれる 自然言語で依頼したら、 自身で考えて計画を立て、プログラム作成/修正 まで実施してくれます。 バグが多かったので 「ちゃんとテストしてよ」 と言ったところ、以下のようなことを言ってくれます。 そこまで考えてくれる んですか・・・!!( できるなら最初からやってよ とも思いますが) 私の手元にあるサンドボックス環境では 外部のネットワーク、特にあなたのGoogle Cloudプロジェクト (GCSやVertex AI Searchなど)に 直接接続することは許可されておりません。 ~(中略)~ そのため、外部サービスとの連携部分を模倣した 「ユニットテスト」を導入することをご提案します。 Julesでできないことを明確にして依頼してくれる 今回でいうと、 Google Cloudとの連携部分はJules単体では実施できません。 その際、こちらで必要な作業を明確にして依頼してくれます。 「プログラムのここに、作成したGoogle Cloudのサービスアカウント名を入力してください」 といった依頼をしてくれました。 プログラミングだけでないサポート GoogleCloudの設定方法についても教えてくれます。 ある要件の実現方法が、プログラムなのか基盤側の設定なのかよくわからないケースもあると思いますが、 それも いったんJulesに投げれば、どうすればいいか回答 してくれます。 1日の利用上限が多い 1日15回タスクが上限なのですが、「1タスク」とは1回の指示という意味ではなく、「1つづきの会話」のようです。「さっき言ってたのやったけど失敗したんだけど」と会話の続きであれば、1タスク内です。 もったいない点 過去の指摘を忘れてくる。 少し触れましたが、JulesはGeminiのバージョンを間違えてきました(1.0 pro)が、それを指摘して修正(2.5 flash)した後、 別の箇所の修正するときに合わせて Geminiのバージョンを 元の間違った値に修正 されました(1.0 pro) 。 RSSのURLでも同様の事象があり、おそらく 内部のAIが学習した時点の古い情報に戻ってしまう ことが散見されました。 応答時間にかなりのムラがある。 簡単な修正であれば平均2-3分で修正までしてくれますが、 まれに20分程度応答がない こともありました。ネット上では5時間待ちという話もあります。 通知設定もできる ので、応答ない場合は気長に待ちましょう。 良くも悪くも気を利かせすぎ 今回、aiでのnews要約システムを作りました。その際のプロンプトは私が何も指定せずにJules側決められました。Julesの作成したプロンプトは 「以下の記事を300字程度の日本語で要約してください」 でした。 300文字は私のイメージより長すぎでした 。 このように、 明確に指示のない箇所をある程度自律的に設計 してくれるのですが、 イメージとずれている ことも結構あり ます。 英語で応答を返してくる LLMあるあるではありますが、 日本語で聞いているのに日本語で返ってこない ケースが、一般的なLLMより多いと感じました。 おそらくですがコードやエラーログなど、英語の情報を渡すことが多いので英語で返ってきてしまうのだろうと思います。 まとめ 今回は、GoogleのAIエージェント「Jules」を使って、AIニュースの要約システムを構築する過程をご紹介しました。 私自身、プログラミングやGitHubの知識がほとんどない状態からスタートしましたが、 Julesがまるで同僚(いや、技術力のある大先輩)のように自律的にコードを生成・修正してくれた おかげで、無事システムを完成させることができました。 プログラミング以外の領域でも Julesが次にやるべきことを明確に示してくれた ため、スムーズに進めることができました。 もちろん、応答時間にムラがあったり、こちらの意図と少し違う実装したりといった改善点も感じましたが、それを差し引いても、Julesは非常に強力で、 今後の開発のあり方を大きく変える 可能性を秘めたツール だと確信しています。 技術の進化のスピードは驚くほど速く、ついていくのが大変だと感じることもありますが、JulesのようなAIエージェントをうまく活用すれば、 私のようなインフラエンジニアでも、プログラミングの世界に飛び込んでいける時代 になったのだと実感しました。 一方で、 Julesの作った計画/方針やプログラムを 理解する能力 も同様に重要 だと感じました。検証なのであまり考えずデプロイしてましたが、セキュリティ観点、コスト観点、etc…と、 仮に正常に動作したとしても本番化には様々考えること があります。その観点でJulesの出力を 理解しなければ、指摘ができません。指摘できなければ、Julesも修正はしてくれません 。 これを読んでくださった皆さんも、ぜひ一度Julesを試してみてはいかがでしょうか。
こんにちは、広野です。 AWS Cloud9 は研修用途では非常に使い勝手が良かったのですが、AWS が新規アカウントへの提供を終了してしまいました。今回は私が試みた代替ソリューションの実装編です。本記事は Application Load Balancer とその周辺設定を対象にします。デプロイ先の VPC が完成していることが前提になります。 code-server と ALB で AWS Cloud9 代替の研修用 IDE を提供する - アーキテクチャ概要編 AWS Cloud9 の代替 IDE を作成しました。私が試みた設計を紹介したいと思います。本記事はアーキテクチャ概要編です。 blog.usize-tech.com 2025.08.12 code-server と ALB で AWS Cloud9 代替の研修用 IDE を提供する - 実装編1 VPC AWS Cloud9 の代替 IDE を作成しました。私が試みた設計を紹介したいと思います。本記事は実装編 1、VPC です。 blog.usize-tech.com 2025.08.13 アーキテクチャ アーキテクチャ概要編で、以下の図を紹介しておりました。 code-server サーバを配置する VPC です。何の変哲もない一般的なサブネット構成にしています。 NAT Gateway は課金節約のため、1 つのパブリックサブネットにしか配置していません。 code-server サーバは 1 ユーザーあたり 1 台を割り当てます。図では 1 つしかありませんが、人数分作成される想定です。ALB はユーザー全体で共用します。 code-server のログインパスワードはインストール時に設定しますが、AWS Secrets Manager で生成したものを使用します。 ALB には HTTPS アクセスさせるため、図には書いていませんが独自ドメインを使用します。そのための SSL 証明書はそのリージョンの AWS Certificate Manager で作成されていることが前提になります。 ALB から EC2 インスタンスへの通信は 80 番ポート (HTTP) を使用します。 ALB はインターネットに公開されますが、研修用途を想定して会社のソース IP アドレスからのみアクセスできるようにセキュリティグループを設定しています。 使用する VPC 新たに VPC を作成する場合 前回記事を参考に、作成してください。 code-server と ALB で AWS Cloud9 代替の研修用 IDE を提供する - 実装編1 VPC AWS Cloud9 の代替 IDE を作成しました。私が試みた設計を紹介したいと思います。本記事は実装編 1、VPC です。 blog.usize-tech.com 2025.08.13 既存 VPC を使用する場合 以下の条件であれば、既存 VPC を使用することが可能です。 パブリックサブネットが 2 つある。(ALB 用) プライベートサブネットからインターネットにアクセスできる。(NAT Gateway がある) ソフトウェアのインストールや、AWS Systems Manager, AWS Secrets Manager のエンドポイントへのアクセスに使用する。 AWS CloudFormation テンプレートの構成 テンプレートは 3 つに分けています。 VPC Application Load Balancer ← 今回はここ Amazon EC2 インスタンス このうち、VPC と ALB はユーザー共用になるので 1 回のみ実行します。Amazon EC2 インスタンスはユーザーごとに実行が必要です。 作成する ALB は本体 1 つとリスナーのみ作成します。ターゲットグループやリスナールールはぶらさがる Amazon EC2 インスタンスごとに作成しますので、続編記事で紹介します。 ALB にはターゲットグループからの HTTP レスポンスヘッダーをオーバーライドする機能があります。今回の構成ではそれを使用して若干セキュリティを高めています。 Amazon EC2 インスタンスの共通設定となる起動テンプレートとセキュリティグループもここで共通設定として 1 回だけ作成します。 テンプレートの範囲を図にすると、以下のようになります。ここに書かれているリソースが作成されます。 AWS CloudFormation テンプレート AWS CloudFormation テンプレートです。AWS Secrets Manager は、続編記事のテンプレートに入ります。 Amazon EC2 の起動テンプレートは、インスタンスの共通設定としてボリュームサイズを可変にしています。とりあえず 10 GB あれば余裕はありますが、インストールするモジュール等により変更は必要です。インスタンスタイプは t3.micro, t3.small からの 2 択にしていますが、必要に応じて変更してください。 その他細かいことはインラインのコメントで補足します。 AWSTemplateFormatVersion: "2010-09-09" Description: The CloudFormation template that creates a S3 bucket for logging, an EC2 Security Group, a Launch template and an ALB for common code-server configurations. # ------------------------------------------------------------# # Input Parameters # ------------------------------------------------------------# Parameters: SystemName: Type: String Description: System name. use lower case only. (e.g. example) Default: example MaxLength: 10 MinLength: 1 SubName: Type: String Description: System sub name. use lower case only. (e.g. prod or dev) Default: dev MaxLength: 10 MinLength: 1 VpcId: Type: AWS::EC2::VPC::Id Description: Choose a existing VPC ID you deploy the EC2 instance in. AlbSubnet1: Type: AWS::EC2::Subnet::Id Description: Choose an existing Public Subnet ID you deploy the Application Load Balancer in. AlbSubnet2: Type: AWS::EC2::Subnet::Id Description: Choose an existing Public Subnet ID you deploy the Application Load Balancer in. InstanceSubnet: Type: AWS::EC2::Subnet::Id Description: Choose an existing Private Subnet ID you deploy the EC2 instance in. LogRetentionDays: Type: Number Description: The retention period (days) for entire log data. Enter an integer between 35 to 540. Default: 400 MaxValue: 540 MinValue: 35 InstanceType: Type: String Description: EC2 instance type for code-server. Default: t3.small AllowedValues: - t3.micro - t3.small InstanceVolumeSize: Type: Number Description: The volume size in GB Default: 10 # ALB を HTTPS アクセス可能とするため、独自ドメインを使用します。 DomainName: Type: String Description: Domain name for URL. xxxxx.xxx Default: example.com MaxLength: 40 MinLength: 5 # ドメインの SSL 証明書を ACM で登録していることが前提です。証明書の ARN を記入します。 CertificateArn: Type: String Description: ACM certificate ARN. Default: arn:aws:acm:ap-northeast-1:xxxxxxxxxxxx:certificate/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx MaxLength: 128 MinLength: 10 # ALB へのアクセスを許可するソース IPv4 サブネットを指定します。 AllowedSubnet: Type: String Description: Allowed source IPv4 subnet and subnet mask. (e.g. xxx.xxx.xxx.xxx/32) Default: xxx.xxx.xxx.xxx/32 MaxLength: 18 MinLength: 9 Resources: # ------------------------------------------------------------# # S3 # ------------------------------------------------------------# S3BucketLogs: Type: AWS::S3::Bucket Properties: BucketName: !Sub ${SystemName}-${SubName}-code-server-logs LifecycleConfiguration: Rules: - Id: AutoDelete Status: Enabled ExpirationInDays: !Ref LogRetentionDays OwnershipControls: Rules: - ObjectOwnership: BucketOwnerEnforced PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true Tags: - Key: Cost Value: !Sub ${SystemName}-${SubName} # for ap-northeast-1 region S3BucketPolicyLogs: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref S3BucketLogs PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: # 東京リージョン以外で使用するときは、以下のアカウント番号を変更する必要があります。AWS 指定のものです。 AWS: "arn:aws:iam::582318560864:root" Action: s3:PutObject Resource: !Sub "${S3BucketLogs.Arn}/*" DependsOn: - S3BucketLogs # ------------------------------------------------------------# # EC2 Launch template # ------------------------------------------------------------# EC2LaunchTemplate: Type: AWS::EC2::LaunchTemplate Properties: LaunchTemplateName: !Sub code-server-${SystemName}-${SubName} LaunchTemplateData: InstanceType: !Ref InstanceType # AMI は Amazon Linux 2023 の最新版を使用するようになっています。 ImageId: >- {{resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64}} BlockDeviceMappings: - Ebs: VolumeSize: !Ref InstanceVolumeSize VolumeType: gp3 DeleteOnTermination: true Encrypted: true DeviceName: /dev/xvda NetworkInterfaces: - SubnetId: !Ref InstanceSubnet Groups: - !Ref Ec2SecurityGroup DeviceIndex: 0 AssociatePublicIpAddress: false MetadataOptions: HttpTokens: required Monitoring: Enabled: true TagSpecifications: - ResourceType: volume Tags: - Key: Cost Value: !Sub ${SystemName}-${SubName} DependsOn: - Ec2SecurityGroup # ------------------------------------------------------------# # EC2 Security Group # ------------------------------------------------------------# Ec2SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: !Ref VpcId GroupDescription: Allow code-server access via ALB only SecurityGroupIngress: - Description: Allow HTTP from ALB FromPort: 80 IpProtocol: tcp ToPort: 80 SourceSecurityGroupId: !GetAtt AlbSecurityGroup.GroupId SecurityGroupEgress: - Description: Allow all outbound traffic IpProtocol: -1 CidrIp: 0.0.0.0/0 Tags: - Key: Cost Value: !Sub ${SystemName}-${SubName} - Key: Name Value: !Sub SG-code-server-${SystemName}-${SubName} DependsOn: - AlbSecurityGroup # ------------------------------------------------------------# # ALB Security Group # ------------------------------------------------------------# AlbSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: !Ref VpcId GroupDescription: Allow access via HTTPS. SecurityGroupIngress: - CidrIp: !Ref AllowedSubnet FromPort: 443 IpProtocol: tcp ToPort: 443 Tags: - Key: Cost Value: !Sub ${SystemName}-${SubName} - Key: Name Value: !Sub SG-alb-${SystemName}-${SubName} # ------------------------------------------------------------# # ALB # ------------------------------------------------------------# ApplicationLoadBalancer: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Name: !Sub alb-code-server-${SystemName}-${SubName} Type: application IpAddressType: ipv4 LoadBalancerAttributes: - Key: deletion_protection.enabled Value: false - Key: access_logs.s3.enabled Value: true - Key: access_logs.s3.bucket Value: !Ref S3BucketLogs - Key: access_logs.s3.prefix Value: albAccessLogs - Key: idle_timeout.timeout_seconds Value: 60 - Key: routing.http.desync_mitigation_mode Value: defensive - Key: routing.http.drop_invalid_header_fields.enabled Value: true - Key: routing.http.preserve_host_header.enabled Value: false - Key: routing.http.x_amzn_tls_version_and_cipher_suite.enabled Value: false - Key: routing.http.xff_client_port.enabled Value: false - Key: routing.http.xff_header_processing.mode Value: append - Key: routing.http2.enabled Value: true - Key: waf.fail_open.enabled Value: false Scheme: internet-facing SecurityGroups: - !GetAtt AlbSecurityGroup.GroupId Subnets: - !Ref AlbSubnet1 - !Ref AlbSubnet2 Tags: - Key: Cost Value: !Sub ${SystemName}-${SubName} - Key: Name Value: !Sub alb-code-server-${SystemName}-${SubName} DependsOn: - AlbSecurityGroup - S3BucketLogs # HTTPS listener for routing AlbListenerHttps: Type: AWS::ElasticLoadBalancingV2::Listener Properties: LoadBalancerArn: !Ref ApplicationLoadBalancer Port: 443 Protocol: HTTPS SslPolicy: ELBSecurityPolicy-TLS13-1-2-2021-06 Certificates: - CertificateArn: !Ref CertificateArn DefaultActions: - Type: fixed-response FixedResponseConfig: StatusCode: 404 ContentType: text/plain MessageBody: Not Found ListenerAttributes: # frame タグは SAMEORIGIN でないと許可しないようにしています。DENY だと code-server でエラーが発生します。 - Key: routing.http.response.x_frame_options.header_value Value: SAMEORIGIN - Key: routing.http.response.server.enabled Value: false - Key: routing.http.response.strict_transport_security.header_value Value: max-age=31536000; includeSubdomains; preload; - Key: routing.http.response.x_content_type_options.header_value Value: nosniff # CSP は code-server の動作に抵触しないよう調整しています。もしエラーが発生したら都度調整が必要です。 - Key: routing.http.response.content_security_policy.header_value Value: "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; script-src-elem 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https://open-vsx.org https://marketplace.visualstudio.com; worker-src 'self' blob:; font-src 'self' data:; frame-src 'self';" DependsOn: - ApplicationLoadBalancer # ------------------------------------------------------------# # Route 53 # ------------------------------------------------------------# Route53RecordA: Type: AWS::Route53::RecordSet Properties: HostedZoneName: !Sub ${DomainName}. Name: !Sub code-server-${SystemName}-${SubName}.${DomainName}. Type: A AliasTarget: HostedZoneId: !GetAtt ApplicationLoadBalancer.CanonicalHostedZoneID DNSName: !GetAtt ApplicationLoadBalancer.DNSName DependsOn: ApplicationLoadBalancer # ------------------------------------------------------------# # Output Parameters # ------------------------------------------------------------# Outputs: # Ec2 Ec2LaunchTemplateId: Value: !Ref EC2LaunchTemplate Export: Name: !Sub ec2LtId-code-server-${SystemName}-${SubName} Ec2LaunchTemplateVersion: Value: !GetAtt EC2LaunchTemplate.LatestVersionNumber Export: Name: !Sub ec2LtVersion-code-server-${SystemName}-${SubName} # S3 S3BucketLogsName: Value: !Ref S3BucketLogs Export: Name: !Sub S3BucketLogsName-code-server-${SystemName}-${SubName} S3BucketLogsArn: Value: !GetAtt S3BucketLogs.Arn Export: Name: !Sub S3BucketLogsArn-code-server-${SystemName}-${SubName} # ALB AlbUrl: Value: !Sub https://code-server-${SystemName}-${SubName}.${DomainName} Export: Name: !Sub AlbUrl-${SystemName}-${SubName} AlbListenerArn: Value: !GetAtt AlbListenerHttps.ListenerArn Export: Name: !Sub AlbListenerArn-${SystemName}-${SubName} 続編記事 code-server と ALB で AWS Cloud9 代替の研修用 IDE を提供する - 実装編 3 EC2 AWS Cloud9 の代替 IDE を作成しました。私が試みた設計を紹介したいと思います。本記事は実装編 3、EC2 です。 blog.usize-tech.com 2025.08.14 まとめ いかがでしたでしょうか。 今回は実装編 2 Application Load Balancer でした。まだソリューションの核心には触れられていませんが、ベースはできてきています。続編記事で、パスベースルーティングや nginx に触れます。 本記事が皆様のお役に立てれば幸いです。
こんにちは、広野です。 AWS Cloud9 は研修用途では非常に使い勝手が良かったのですが、AWS が新規アカウントへの提供を終了してしまいました。今回は私が試みた代替ソリューションの実装編です。本記事は VPC を対象にします。特別な設計はないので、別件でも使用可能だと思います。 code-server と ALB で AWS Cloud9 代替の研修用 IDE を提供する - アーキテクチャ概要編 AWS Cloud9 の代替 IDE を作成しました。私が試みた設計を紹介したいと思います。本記事はアーキテクチャ概要編です。 blog.usize-tech.com 2025.08.12 アーキテクチャ アーキテクチャ概要編で、以下の図を紹介しておりました。 code-server サーバを配置する VPC です。何の変哲もない一般的なサブネット構成にしています。 NAT Gateway は課金節約のため、1 つのパブリックサブネットにしか配置していません。 code-server サーバは 1 ユーザーあたり 1 台を割り当てます。図では 1 つしかありませんが、人数分作成される想定です。ALB はユーザー全体で共用します。 code-server のログインパスワードはインストール時に設定しますが、AWS Secrets Manager で生成したものを使用します。 ALB には HTTPS アクセスさせるため、図には書いていませんが独自ドメインを使用します。そのための SSL 証明書はそのリージョンの AWS Certificate Manager で作成されていることが前提になります。 ALB から EC2 インスタンスへの通信は 80 番ポート (HTTP) を使用します。 ALB はインターネットに公開されますが、研修用途を想定して会社のソース IP アドレスからのみアクセスできるようにセキュリティグループを設定しています。 既存 VPC を利用する場合 以下の条件であれば、既存 VPC を使用することが可能です。本記事の内容は飛ばすことができます。 パブリックサブネットが 2 つある。(ALB 用) プライベートサブネットからインターネットにアクセスできる。(NAT Gateway がある) ソフトウェアのインストールや、AWS Systems Manager, AWS Secrets Manager のエンドポイントへのアクセスに使用する。 AWS CloudFormation テンプレートの構成 テンプレートは 3 つに分けています。 VPC ←今回はここ Application Load Balancer Amazon EC2 インスタンス このうち、VPC と Application Load Balancer はユーザー共用になるので 1 回のみ実行します。Amazon EC2 インスタンスはユーザーごとに実行が必要です。 AWS Secrets Manager のシークレットはユーザーごとに作成するので、Amazon EC2 インスタンスと同時に実装します。 テンプレートの範囲を図にすると、以下のようになります。ここに書かれているリソースが作成されます。 AWS CloudFormation テンプレート AWS CloudFormation テンプレートです。AWS Secrets Manager は、続編記事のテンプレートに入ります。 AWSTemplateFormatVersion: 2010-09-09 Description: The CloudFormation template that creates A VPC, Subnets, an Internet Gateway, a single NAT Gateway in AZ A and Routings. # ------------------------------------------------------------# # Input Parameters # ------------------------------------------------------------# Parameters: SystemName: Type: String Description: System name. use lower case only. (e.g. example) Default: example MaxLength: 10 MinLength: 1 SubName: Type: String Description: System sub name. use lower case only. (e.g. prod or dev) Default: dev MaxLength: 10 MinLength: 1 VPCCIDR: Type: String Description: IP Address range for your VPC (16 bit mask) Default: 192.168.0.0/16 MaxLength: 14 MinLength: 10 AllowedPattern: ^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){2}0\.0/16$ PublicSubnetACIDR: Type: String Description: IP Address range for your public subnet A (24 bit mask) Default: 192.168.1.0/24 MaxLength: 16 MinLength: 10 AllowedPattern: ^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}0/24$ PublicSubnetCCIDR: Type: String Description: IP Address range for your public subnet C (24 bit mask) Default: 192.168.2.0/24 MaxLength: 16 MinLength: 10 AllowedPattern: ^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}0/24$ PrivateSubnetACIDR: Type: String Description: IP Address range for your private subnet A (24 bit mask) Default: 192.168.101.0/24 MaxLength: 16 MinLength: 10 AllowedPattern: ^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}0/24$ PrivateSubnetCCIDR: Type: String Description: IP Address range for your private subnet C (24 bit mask) Default: 192.168.102.0/24 MaxLength: 16 MinLength: 10 AllowedPattern: ^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}0/24$ Resources: # ------------------------------------------------------------# # VPC # ------------------------------------------------------------# VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VPCCIDR EnableDnsSupport: true EnableDnsHostnames: true InstanceTenancy: default Tags: - Key: Name Value: !Sub vpc-${SystemName}-${SubName} - Key: Cost Value: !Sub ${SystemName}-${SubName} InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: !Sub igw-${SystemName}-${SubName} - Key: Cost Value: !Sub ${SystemName}-${SubName} InternetGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref InternetGateway VpcId: !Ref VPC # ------------------------------------------------------------# # Subnet # ------------------------------------------------------------# # Public SubnetA Create PublicSubnetA: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select - 0 - Fn::GetAZs: !Ref AWS::Region CidrBlock: !Ref PublicSubnetACIDR MapPublicIpOnLaunch: true VpcId: !Ref VPC Tags: - Key: Name Value: !Sub public-a-${SystemName}-${SubName} - Key: Cost Value: !Sub ${SystemName}-${SubName} # Public SubnetC Create PublicSubnetC: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select - 1 - Fn::GetAZs: !Ref AWS::Region CidrBlock: !Ref PublicSubnetCCIDR MapPublicIpOnLaunch: true VpcId: !Ref VPC Tags: - Key: Name Value: !Sub public-c-${SystemName}-${SubName} - Key: Cost Value: !Sub ${SystemName}-${SubName} # Private SubnetA Create PrivateSubnetA: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select - 0 - Fn::GetAZs: !Ref AWS::Region CidrBlock: !Ref PrivateSubnetACIDR VpcId: !Ref VPC Tags: - Key: Name Value: !Sub private-a-${SystemName}-${SubName} - Key: Cost Value: !Sub ${SystemName}-${SubName} # Private SubnetC Create PrivateSubnetC: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select - 1 - Fn::GetAZs: !Ref AWS::Region CidrBlock: !Ref PrivateSubnetCCIDR VpcId: !Ref VPC Tags: - Key: Name Value: !Sub private-c-${SystemName}-${SubName} - Key: Cost Value: !Sub ${SystemName}-${SubName} # ------------------------------------------------------------# # RouteTable # ------------------------------------------------------------# # Public RouteTable A Create PublicRouteTableA: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub rtb-public-a-${SystemName}-${SubName} - Key: Cost Value: !Sub ${SystemName}-${SubName} # Public RouteTable C Create PublicRouteTableC: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub rtb-public-c-${SystemName}-${SubName} - Key: Cost Value: !Sub ${SystemName}-${SubName} # Private RouteTable A Create PrivateRouteTableA: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub rtb-private-a-${SystemName}-${SubName} - Key: Cost Value: !Sub ${SystemName}-${SubName} # Private RouteTable C Create PrivateRouteTableC: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub rtb-private-c-${SystemName}-${SubName} - Key: Cost Value: !Sub ${SystemName}-${SubName} # ------------------------------------------------------------# # Routing to Internet # ------------------------------------------------------------# # PublicRouteA Create PublicRouteA: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PublicRouteTableA DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway # PublicRouteC Create PublicRouteC: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PublicRouteTableC DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway PrivateRouteA: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PrivateRouteTableA DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref NatGatewayA PrivateRouteC: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PrivateRouteTableC DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref NatGatewayA # ------------------------------------------------------------# # RouteTable Associate # ------------------------------------------------------------# # PublicRouteTable Associate SubnetA PublicSubnetARouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnetA RouteTableId: !Ref PublicRouteTableA # PublicRouteTable Associate SubnetC PublicSubnetCRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnetC RouteTableId: !Ref PublicRouteTableC # PrivateRouteTable Associate SubnetA PrivateSubnetARouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnetA RouteTableId: !Ref PrivateRouteTableA # PrivateRouteTable Associate SubnetC PrivateSubnetCRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnetC RouteTableId: !Ref PrivateRouteTableC # ------------------------------------------------------------# # Elastic IP address for NAT Gateway # ------------------------------------------------------------# EipNatGatewayA: Type: AWS::EC2::EIP Properties: Domain: vpc Tags: - Key: Cost Value: !Sub ${SystemName}-${SubName} - Key: Name Value: !Sub eip-ngw-a-${SystemName}-${SubName} # ------------------------------------------------------------# # NAT Gateway # ------------------------------------------------------------# NatGatewayA: Type: AWS::EC2::NatGateway Properties: AllocationId: !GetAtt EipNatGatewayA.AllocationId ConnectivityType: public MaxDrainDurationSeconds: 350 SubnetId: !Ref PublicSubnetA Tags: - Key: Cost Value: !Sub ${SystemName}-${SubName} - Key: Name Value: !Sub ngw-a-${SystemName}-${SubName} # ------------------------------------------------------------# # Output Parameters # ------------------------------------------------------------# Outputs: # VPC VpcId: Value: !GetAtt VPC.VpcId 続編記事 続編記事が出来次第、この章を更新します。 まとめ いかがでしたでしょうか。 今回は実装編 1 VPC でした。一般的な内容なので得るものは少ないと思いましたが、絶対に必要だったので紹介しておきました。 本記事が皆様のお役に立てれば幸いです。
本記事は 夏休みクラウド自由研究2025 8/13付の記事です 。 Catoのサポート窓口では、日々たくさんのお問い合わせをいただいています。 機能の仕様から、実際にご利用中に発生したトラブルまで、その内容はさまざま。 中でも特に多いと感じるのが、 Catoクライアントの接続不具合に関するお問い合わせ です。 そこで本ブログでは、 これまでに多く寄せられた接続トラブルの原因TOP5 をご紹介します! また、こうしたトラブルが発生した際に役立つ基本的な切り分け方法についてもご紹介します。 このブログが少しでもお役に立てれば嬉しいです! 本ブログのランキングは2024年4月から2025年4月まで1年間の問い合わせから集計しております! Catoクライアントで接続できない状況とは? Catoクライアントの接続不具合といっても、具体的にどのようなケースが多いのでしょうか? すべてのケースを網羅するわけではありませんが、代表的な例をいくつかご紹介します。 よくある接続トラブルの例: 「Connecting」「Authenticating」の状態のまま進まず、接続できない アプリにエラーが表示され、接続できない 接続できても不安定で、すぐに切断されてしまう このように、接続できない・不安定な状況が発生した場合、まず何を確認すればよいのか? 次の項目では、いよいよ実際に多かった原因TOP5をご紹介します。 1位: Cato接続に必要な通信がユーザ環境側でBlockされていた 接続ができないという不具合に関して、ユーザーのネットワーク環境側でCato接続への通信がBlockされていた。。 という原因が最も多いと感じました。 なんとクライアントの不具合に関する問い合わせで約5割程度がこの事象に該当します。 特に原因となっているのが ファイアウォール/プロキシ等のセキュリティ機器や、端末内のセキュリティソフト等でCato宛ての通信が許可されておらず通信が制限されている ことによる原因が多いです。 許可が必要な通信は以下の通りです。 利用前に確認が必須なので、この機会に確認いただくのもよいかと思います! 許可が必要な通信 Cato PoPのIPアドレス Cato接続に関係するドメイン・URL 53/udp、443/udpの通信 CHECK! ファイアウォールやプロキシーでブロックされていたと判明するのに 詳細な切り分けやトラブルシューティングなどかなりの時間を要します。。 以下のナレッジにはCatoクライアンインストール時に許可すべきドメインなどOS、機種ごとに紹介されています。 Catoクライアントを利用する際は一度ナレッジを確認し、前提条件がそもそも満たされているのか、、を確認することでトラブルの迅速な解決につながるかと! Installing the Cato Client 2位:非推奨のアプリケーションがインストールされていた Catoクライアントを利用する端末側で、 非推奨とされるサードパーティ製のアプリがインストールされている場合、接続不具合を引き起こす場合があります。 サードパーティ製VPNクライアント例: Cisco AnyConnect GlobalProtect Ivanti Secure Access (旧 Pulse Secure) Catoクライアントとサードパーティ製VPNクライアントが同じPCにインストールされると、 設定が競合し接続不具合を引き起こす 場合があります。 そのため、ご利用端末にてサードパーティ製のVPNクライアントがインストールされている場合は、アンインストールし、削除後にPCを再起動することを推奨しています! CHECK! サードパーティ製のVPNソフトの他に、 ウイルス対策ソフトがCatoクライアントの通信を誤って悪意のあるトラフィックと判断し、Blockしてしまう ことがあります。 切り分けとして、一時的にウイルス対策ソフトを無効化し、Catoクライアントの通信がBlockされているかを確認することもできます。 もしもウイルス対策ソフトがCatoクライアントをブロックしていると判断できた場合は、以下の方法をお試しください! 対策例: ウイルス対策ソフトの設定を変更し、Catoクライアントを例外リストに追加する Cato Networksのサポートに連絡し、アンチウイルスソフトのホワイトリスト登録を依頼する 3位: ログイン情報の入力ミス 急に単純な内容になってしまいますが、 パスワードやユーザ名の入力ミスによる接続エラー も散見されました。 以下のLoginエラーが表示された場合、入力にミスがあると思われるため再度正しい値が入力されているか確認してみましょう! 2025年7月28日以前のパスワード条件は、「8文字以上32文字以下で、英大文字、英小文字、数字」でしたが、現在の仕様では「特殊文字」も追加されております。新たにパスワードを作成する際はご注意ください!!(例:!,@,#,$,%など) ※2025年7月28日以前に作成されたパスワードは引き続き利用可能です。 4位:Catoクライアントアプリが最新の状態ではなかった Catoクライアントのバージョンが古いと不具合が生じる可能性がございます。 そもそも Catoクライアント最新バージョンはこれまでの不具合やバグを修正したもの になります。 そのため、Catoクライアントをご利用する場合、 基本的には最新バージョンにしておくことが推奨 です! 最新版Catoクライアントのダウンロード方法 1.クライアントダウンロードサイトで最新のクライアントをインストールする ダウンロードサイトにて各OSの最新バージョンをダウンロードすることができます。 なお、最新バージョンをインストールする際、古いバージョンをアンインストールする必要はありませんので、 以下のダウンロードサイトから最新バージョンをインストールしてください! ダウンロードサイト 2.CMAからダウンロード Access>Client Rolloutから該当するOSの最新バージョンインストールすることができます。 Download ClientのプルダウンからDownload EXE or Download MSI等をクリックことで最新バージョンをダウンロード、 配布することが可能です! ※CMAへのアクセス権が必要です。 5位:ネットワーク機器にて問題があった 社内ネットワークにてCatoクライアントを利用する際、そもそも Catoクライアントではなくネットワーク機器に問題 があった、、 などの事象が見受けられます。 具体的にはLANケーブルの断線、スイッチ、ハブの故障、そもそも終端装置にネットワーク機器が繋がっていなかったなど。。 また、ネットワーク機器のOSをアップグレードした結果、Catoクライアントが正常に繋がったなどもあります。 Catoクライアントを利用する際は、クライアントアプリだけではなく そもそものネットワーク環境を疑ってみる のも切り分けの一つとなります。 ネットワーク環境の切り分けを行う際は以下を確認してみましょう! 確認項目 LANケーブルの交換 ネットワーク機器OSのアップグレード ハブ、スイッチの交換 インターネットに繋がるか Tips! Catoクライアントのエラーに関して、様々なエラーメッセージが表示される可能性がありますがCatoのアップデートに伴い、表示される文章や意味が変わる可能性があります。 以下のKB「 エラーメッセージ」「原因」「切り分け」 がまとめられております。 トラブル発生時はこちらのKBをご参考に! Cato-Client-Login-Errors また、弊社ではCatoクライアントのトラブルシューティングに関する記事が他にもまとめられております! ぜひこちらもご確認いただけますと幸いです! Catoクラウド トラブルシュート ~Catoクライアントが繋がらないお悩みの方へ~ Catoクラウドをご利用いただいてるお客様から、よくいただくご質問に「Catoクライアントが繋がらないです」といったお問い合わせを頂きます。対処法や問題の切り分け方をご紹介いたします。 blog.usize-tech.com 2023.12.15 それでもどうにもならなければ… これまでご紹介した対処案でも改善されない場合、以下をお試しください! 端末の再起動 Catoクライアントの再インストール 端末の再起動やクライアントの再インストールで解決されることが多々あります。 ただ、詳細な原因を調査する際、再インストールを行うとクライアントアプリのログが削除されてしまうため、 再インストール前にクライアントログを取得していただけますと幸いです。 VPN Clientの接続ログを取得する方法を教えてください 最後に 大抵の場合、ご紹介しましたトラブルシューティングで解決することが多いです。 サポートとしても、 まずご紹介したトラブルシューティングを実施いただいているか、という確認から入ります ので、実施している場合はその旨、問い合わせ時にご連絡いただけると時間短縮につながります。 弊社のサポート窓口までご相談いただく際は、早期解決のため是非ともご協力のほどよろしくお願いいたします!
こんにちは、広野です。 AWS Cloud9 は研修用途では非常に使い勝手が良かったのですが、AWS が新規アカウントへの提供を終了してしまいました。今回は私が試みた代替ソリューションの設計を紹介したいと思います。実装編は AWS CloudFormation テンプレートになりますが、続編記事として作成します。 インスピレーションを受けた記事 多くの有志の方々が AWS Cloud9 代替品の作成方法を記事にしてくれていまして、大変参考になりました。ですが中でも一番参考にしたのは AWS が提供してくれているハンズオンに含まれている IDE 作成テンプレートでした。 Workshop Studio Discover and participate in AWS workshops and GameDays catalog.workshops.aws Coder code-server という、VSCode を WEB UI で使用できるソフトウェアを Amazon EC2 インスタンスにインストールし、AWS CloudFront および nginx 経由で公開する構成になっていました。 私はそれを Elastic Load Balancing の ALB 経由で研修受講者に使用してもらいたいと思い、そのように作成しました。 アーキテクチャ VPC 周り code-server サーバを配置する VPC です。何の変哲もない一般的なサブネット構成にしています。 NAT Gateway は課金節約のため、1 つのパブリックサブネットにしか配置していません。 code-server サーバは 1 ユーザーあたり 1 台を割り当てます。図では 1 つしかありませんが、人数分作成される想定です。ALB はユーザー全体で共用します。 code-server のログインパスワードはインストール時に設定しますが、AWS Secrets Manager で生成したものを使用します。 ALB には HTTPS アクセスさせるため、図には書いていませんが独自ドメインを使用します。そのための SSL 証明書はそのリージョンの AWS Certificate Manager で作成されていることが前提になります。 ALB から EC2 インスタンスへの通信は 80 番ポート (HTTP) を使用します。 ALB はインターネットに公開されますが、研修用途を想定して会社のソース IP アドレスからのみアクセスできるようにセキュリティグループを設定しています。 ALB 周り ユーザーは、ALB に自分専用の URL でアクセスします。ただし、ドメインは共通で、パスに自分用の番号が入ったもの (ide1 など) を指定します。 ALB はパスベースルーティングで受け取ったパスからそのユーザーの Amazon EC2 インスタンスが所属しているターゲットグループに通信をルーティングします。 code-server 周り ALB はパスベースルーティングで通信を送信するとき、パスは受け取ったまま (図のケースでは /ide2/) でターゲットに送信します。code-server には存在しないパスなので、そのまま通信を code-server で受けてしまうと当然 not found エラーになります。 この問題を解決するために、nginx を間に挟み、ポート番号の変更とパスの削除をしています。やりたいことはパスの削除だけなのですが、1台のサーバ内に nginx と code-server が共存するためにはポート番号を別々のものにしないといけないため、nginx を 80、code-server を 8008 でオープンするようにしています。 出来上がり 出来上がると、以下のログイン画面が表示されます。 ログインすると、以下のように VSCode の画面がブラウザ上に表示されます。ホームディレクトリは AWS Cloud9 を意識して environment にしています。OS のターミナルも ec2-user で開いているのが見えますね。めでたし、めでたし。 続編記事 実装編記事が出来次第、この章を更新します。 まとめ いかがでしたでしょうか。 今回は概要編でしたので内容は浅いですが、設計の要点はご理解いただけるのではないかと思います。実装編では、具体的な設定に踏み込んで紹介します。 本記事が皆様のお役に立てれば幸いです。
本記事は 夏休みクラウド自由研究2025 8/12付の記事です 。 どうも、Catoクラウドを担当している佐々木です。 最近Catoクラウドを導入した複数の顧客で、導入時に同じトラブルが発生したので紹介します。 ※画⾯は2025年8⽉時点のものです。機能アップデート等で変わる場合がありますので、あらかじめご了承ください。 トラブル事例 Catoクラウドを導入した際、iPhoneやMac端末から社内リソース(社内サーバやADなど)にアクセスできないという事例です。 Windows端末では問題なく接続できる一方、Appleデバイスのみ接続に失敗するケースです。 ▼構成イメージ 発生する現象 iPhone、macOS端末から 社内サーバ(ファイルサーバ、AD、内部Webアプリ)へアクセスができない Catoクラウドには正常に接続され、インターネットアクセスは可能 IPアドレスを直打ちするとアクセスできる 一方、Windows端末ではすべて問題なくアクセスできる 原因 macOS/iOSの仕様が原因です。 「macOS Ventura」、および「iOS 16」以降 では、DNS over TLS(DoT)やDNS over HTTPS(DoH)に準拠したDNSサーバを検出すると、CatoのDNSサーバを含む他の DNSサーバを無視し、DoTおよびDoH対応のDNSサーバを利用します。 通常、社内リソースへのアクセスが必要な場合、Catoクラウド(CMA上)のDNS設定で社内リソース(ドメイン)宛のDNSフォワーディング設定を行いますが、 Catoの場合、DoTやDoHでのDNSフォワーディングをサポートしていません。 結果、インターネット上にあるパブリックなドメインに対するアクセスは可能ですが、社内サーバなどプライベートなドメインに対する名前解決はできなくなり、この事象が発生します。 DoH/DoTの主な制限事項 ・ DNSフォワーディングがサポートされていない ・ ドメイン名やアプリケーションベースのファイアウォールルールマッチングが正常に動作しない ・ DNSプロテクションが適用されない 解決策 Catoクラウド(CMA)で行える解決策が、 「2つ」 あります。 どちらか1つを設定すれば改善できますが、2つ同時に設定しても問題ありません。 Internet FirewallルールでDoT / DoHをブロックする DoTとDoHをInternet Firewallでブロックし、Cato経由でアクセスできないようにします。 Apple端末はDoT/DoHを利用できなくなり、代わりに UDPベースの通常DNS(CMAの設定値) を使うようになります。 結果、DNSフォワーディングが正しく動作し、内部リソースの名前解決が成功します。 ▼設定例 Security > Internet Firewallから以下のように設定します。 DNSの固定 Catoクラウド(CMA)で、DNSサーバを明示的に設定します。 例:Cato DNS(10.254.254.1)をPrimaryDNSとして設定し、Secondaryには何も設定を入れない。 この設定により、8.8.8.8など外部のDNSがクライアントで自動的に設定されなくなり、DoT/DoHを利用できなくなります。 ▼設定例 Access > DNS Settings Policyから以下のように設定します。 Network > DNS Settingsから設定すると、すべての端末(Windows端末含む)に設定が反映されるので注意! まとめ 今回は導入時のトラブル事例共有でした。 ポイントをまとめると以下になりますが、本件に限らず事前検証は念入りに実施することを(個人的には)推奨します。 ・Appleデバイスから社内リソースにアクセスできない原因はAppleの仕様 ・ただし、Catoの設定で回避可能 ・事前にiPhoneやMacで接続テストを行って確認したほうがいいかもね! 上記以外の情報についても弊社の 「Catoに関するFAQサイト」 に多数情報ございますのでご参考にください。 よくあるご質問 | Cato Cloud ケイトクラウド - SCSK Cato SASE Cloud Platform. powered by SCSK cato-scsk.dga.jp 最後に、SCSKではPoCから導入、運用まで幅広くCatoに関する支援を行っております。 本番構成への移行を見据えたPoC構成や、PoCでつまづきやすい点のサポートなど、豊富な導入実績を基にご支援いたします。 ぜひお声がけください!
本記事は 夏休みクラウド自由研究2025 8/11付の記事です 。 こんにちは。角田です。 これまでSASEの概要やメリットなどを解説する記事を書いてきましたが、今回はその第3弾となります。 ※過去の解説記事は以下をご参照ください。 【SASE簡単解説】SASEとは? 初心者が1から解説 SASE簡単解説シリーズ第1弾! 「近年バズワードとして注目されていることは知っているが、調べてみてもよく分からない。」これを機にSASEを理解したい、という方に向けて、超初心者向けの「SASEとは?」を1から丁寧に説明していきたいと思います。 blog.usize-tech.com 2025.03.24 【SASE簡単解説】SASEのよくある懸念点と、導入しやすいタイミングを解説! SASE簡単解説シリーズ第2弾! SASE導入を考える上で、誰もが気になる点を丁寧に解説します。「コストが高くなりそう」や「セキュリティが不安」といった懸念点の解消から、後半では、SASE導入を検討しやすいタイミングまで、具体例も交えて説明していきます。 blog.usize-tech.com 2025.05.02 今回は、SASEの中でも 今後特に市場拡大が見込まれる「シングルベンダーSASE」 について、そうでないSASEとの違いも含めて、以下のテーマでご説明します。 シングルベンダーSASEとは? シングルベンダーSASEのメリット SASEの市場動向と今後について シングルベンダーSASEとは? まずは簡単に振り返りとなりますが、SASEとは「“ネットワーク”と“ネットワークセキュリティ”をクラウドベースで統合したもの」です。 2019年に、有名な調査会社であるGartnerによって提唱されました。 では、その中でも「シングルベンダーSASE」とは一体どういったものなのでしょうか。 深堀りして解説していきます。 シングルベンダーSASEとは? まず、シングルベンダーSASEは「単一ベンダーにより、統合されたプラットフォームで、ネットワークとセキュリティの両機能をネイティブに提供することができるSASE」であると言われています。 少し難しい言い回しですが、分かりやすく言うと 「1つの会社でSASEの機能全てを提供できているサービス」 です。 ただし、単に“1社で全部入り”のサービスではなく、 “最初から統合されたプラットフォームとして設計されている”ことがポイント となります。 ※詳しくは後述します。 マルチベンダーSASEとの違い シングルベンダーSASEがいれば、もちろん「そうでないSASE」、つまり「マルチベンダーSASE」も存在します。 マルチベンダーSASEとは、「様々な会社の製品を組み合わせてパッケージ化されたSASE」です。 例えば、SD-WANはA社製、SWGはB社製、CASBはC社製という構成で、これを1つの自社サービスとして提供しているような形態がマルチベンダーSASEとなります。 このようなサービスでは、以下のような課題が発生します。 管理コンソールやログがバラバラで、運用が煩雑 ポリシー設定が製品ごとに分かれ、整合性がない アップデートや障害も製品ごとに発生するため、利便性が低い 昨今多くの企業がSASEソリューションを提供していますが、その中にもマルチベンダーSASEは数多く存在します。 そして、そういったマルチベンダーSASEは、往々にして 「統合されていない」 ことが課題になりがちです。 シングルベンダーSASEの本質 では、「1つの会社で全て提供されているSASEであればよいのか」というと、それは本質的ではありません。 重要なのは ”最初から統合されたプラットフォームとして設計され、1つのエンジンで動いている” ことです。 例えベンダーが1社であったとしても、内部で使っているエンジンが“M&Aによる買収や機能追加による ”継ぎはぎの構成”であった場合、本来の意味で「統合されている」とは言えません。 このような構成では、 結局上記で述べたような課題は 発生 しますし、 各機能間で通信の復号化と暗号化を繰り返す必要があるため、大きなオーバーヘッドも発生 します。 “最初から統合されたプラットフォームとして設計され、単一のエンジンで動いている”、 真に統合されたSASE は意外にも少ないのですが、 これこそが、シングルベンダーSASEの本質であると考えています。 世の中にはシングルベンダーSASEを謳う製品が多数ありますが、SASEを比較検討する際には、 「シングルベンダーSASE」という言葉だけに惑わされず、「真に統合されたSASEなのか」ということを意識して検討いただければと思います。 シングルベンダーSASEのメリット ここまで、シングルベンダーSASEの概要やマルチベンダーSASEとの違いを説明してきました。 続いては、マルチベンダーでなく、シングルベンダーSASEを選択することのメリットを以下3つご紹介します。 ① 全ての機能が完全統合されている ② 機能追加が迅速に可能 ③ どの拠点でも同じ機能/品質を提供可能 メリット①:全ての機能が完全統合されている 前述の通り、 全ての機能が統合されていることが、シングルベンダーSASEの最大の特徴でありメリットです。 これにより、 ネットワーク、セキュリティのポリシーを簡単に統一 することができますし、 ログも一元化 されるため、 分析やトラブルシュートも効率的 に行うことができます。 また、 管理コンソールが統合されていることも大きなメリット です。 マルチベンダー型のSASEは、利用する機能によって管理コンソールが分かれていたりすることがあります。 利用者の立場からすると、“コンソールが統合されていて使い勝手の良い”という点も非常に重要なポイントとなります。 メリット②:機能追加が迅速に可能 シングルベンダーSASEは、統合されたエンジンを持っています。 そのため、新たな基盤の開発やアプライアンスの調達などをすることなく、容易に新機能の追加が可能です。 拡張性に優れ、IT概況の変化や新たなサイバー攻撃の流行に合わせて迅速に機能追加ができる という点も、シングルベンダーSASEの大きな魅力となっています。 メリット③:どの拠点でも同じ機能/品質を提供可能 マルチベンダーSASEの場合、各種機能が他社製品や他社基盤に依存するため、一部地域では拠点間通信ができない、あるいはセキュリティ機能(IPSやCASBなど)が利用できない といった制約が発生してしまうことがあります。 そして、例えば「日本にはCASBが提供されていないけど、どうにか使いたい」という場合には、一度CASB機能がある地域(海外など)にトラフィックを飛ばし、CASBによるセキュリティチェックや可視化を行った上で、また日本にトラフィックを返す、といった方法を取ることになりますが、この方法では非効率な通信が頻発し、 通信遅延や帯域の無駄使い が発生します。 シングルベンダーSASEであれば、サービスを提供するすべての地域に同一のプラットフォームを展開していますので、 どの拠点からでも同じ機能を、同じ品質で利用することができる のです。 SASEの市場動向と今後について ここまでシングルベンダーSASEの概要とメリットを説明してきました。 最後は、そんなシングルベンダーSASEの 市場動向や今後の動き についてお話したいと思います。 シングルベンダーSASEのリーダー Catoクラウドについて シングルベンダーSASEの市場動向ということで、まずは Catoクラウド についてご紹介させてください。 Catoクラウドは、GartnerがSASEを定義した2019年よりも前から、SASEのアーキテクチャでサービスを提供している、世界初のシングルベンダーSASEとなります。 全世界90拠点以上に完全統合されたプラットフォームを展開しており、どこからでも同一のネットワーク/ネットワークセキュリティ機能を適用することが可能です。 Catoクラウド 変化する働き方に必要な「ゼロトラスト」を実現する「ネットワークとセキュリティを統合したクラウドサービス(SASE)」であるCatoクラウドをご紹介しています。 www.scsk.jp Gartnerのレポートでは、Catoクラウドの提供ベンダーである Cato Networks社は、シングルベンダーSASEのリーダーに認定 されています。 SASEを検討する際には、ぜひCatoクラウドにご注目ください。 Cato Networksが2025年度Gartner® Magic Quadrant™のシングルベンダーSASE部門でリーダーに再び選ばれました SASEのリーダーであるCato Networksは、2025年Gartner® Magic Quadrant™のSASEプラットフォーム部門で再びリーダーに選ばれたことを発表しました。 www.catonetworks.com シングルベンダーSASEの市場動向 はじめに宣伝から入ってしまいましたが、 シングルベンダーSASE全体の市場動向 としてはどうでしょうか。 上記Gartnerのレポートでは、2028年までに新しくSD-WANを購入する企業の70%がシングルベンダーSASEを採用するという市場予測がされています。 ※2025年現在では25%のようです。 また、SCSKでは日本企業を対象とした独自の「SASE実態調査」を毎年実施しているのですが、SASEの認知度や導入率に関しても、年々増加傾向にあります。 今後、 シングルベンダーSASEを採用する企業は大きく増えていく ものと考えられます。 SASEの領域拡大について 近年のSASE全体の動きとしては、どんどん機能拡充が進み、既存領域(ネットワークやネットワークセキュリティ)から新たな領域に進出し始めているような印象を受けます。 実際にCatoクラウドでは、すでにエンドポイントであるEPPや、各種セキュリティログを統合分析するXDRの機能がリリースされています。 その他にも、クラウドセキュリティであるCSPMと統合したり、生成AIを取り入れた機能拡充の動きも見受けられます。 SASEソリューションのカバーする領域がどんどん広がってきているからこそ、“統合されたプラットフォーム”を持つシングルベンダーSASEの価値は、今後より高まっていくと考えています。 おわりに いかがでしたでしょうか? 今回は第3弾ということで踏み込んだ内容になってしまいましたが、「もっと基礎から知りたい!」という方は、冒頭に紹介した第1弾、第2弾のブログ記事に加え、SCSKのYoutubeチャンネルで公開している初心者解説動画も参考にしてみてください。 - YouTube YouTube でお気に入りの動画や音楽を楽しみ、オリジナルのコンテンツをアップロードして友だちや家族、世界中の人たちと共有しましょう。 www.youtube.com - YouTube YouTube でお気に入りの動画や音楽を楽しみ、オリジナルのコンテンツをアップロードして友だちや家族、世界中の人たちと共有しましょう。 www.youtube.com また、SCSKは長年に渡りSASEやCatoクラウドに関するセミナーも定期開催しています。 直近では 2025/8/27(水) に、Catoクラウドのデモセミナーを開催します。 Catoクラウドの主要機能をたっぷり2時間 ご覧いただけますので、ご興味がある方は、ぜひご参加ください。 Catoクラウドデモセミナー ver.3 ~Catoクラウドの主要機能を2時間で網羅~ 本セミナーでは、世界初のSASEである「Cato(ケイト)クラウド」の主要機能をたっぷり2時間、デモ形式でご覧いただけます。今回のCatoクラウドデモセミナーは、これまでのデモセミナーから更に最新機能等の情報を盛り込み、ver3にリニューア... www.scsk.jp もちろん、個別のご紹介・ご説明も可能です。 ご要望の場合は、 問合せフォーム からお気軽にご連絡ください。
本記事は 夏休みクラウド自由研究2025 8/10付の記事です 。 こんにちは SCSK中山です。 今回は夏休みの自由研究ということで、自由研究チックな内容にしたいと思いまして、AWS上でCloud InterConnect × vSocketで冗長構成を組めるかを試してみようかと思います。 通常、Cato Networksを利用してAWSなどのクラウドサービスと接続する場合、「Cloud InterConnect」または「vSocket」のどちらかを選択します。冗長化を組む際も、Cloud InterConnectであればDirect Connect回線を2本に、vSocketであればvSocketインスタンスを2台に、といった形で同一の接続方式で構成するのが標準的です。 これら2つの異なる接続方式を組み合わせて冗長化に利用することは、Catoの推奨構成ではありません。 しかし、「 技術的には本当に不可能なのか? 」という純粋な好奇心から、今回はその実現可能性を考察し、記事にまとめてみることにしました。 先に申し上げますと、本記事は現時点では 机上考察 です。検証はこれからとなりますので、あらかじめご了承ください。 考慮すべきポイント :動的なルーティング切り替え この構成を実現する上での鍵は、「 どのようにしてルーティングを動的に切り替えるか 」です。 Catoでは、Cloud InterConnectとvSocketを利用する場合、それぞれ別の「Site」として登録・管理します。 今回の構成では、通常時はCloud InterConnectを利用するSite(以下、Site A)をメイン経路とし、Site Aの障害時にのみvSocketを利用するSite(以下、Site B)へルーティングを自動で切り替える必要があります。この自動切り替えをどう実現するかが、最大のポイントとなります。 案①BGPを使った方法 ネットワークの経路を動的に切り替えるといえば、まず思い浮かぶのが BGP (Border Gateway Protocol) です。 CatoはBGPをサポートしているため、AWS側との連携が焦点となります。 1. Cloud InterConnect (Site A) 側 こちらは比較的シンプルです。AWS Direct ConnectおよびTransit GatewayはBGPによるルート伝播に標準で対応しているため、Site AとAWS間の経路交換(青色矢印)はBGPで問題なく実現できるでしょう。 参考: BGP for AWS(クラスメソッド) TransitGWを通してDirectConnectが生きているときは通信を可能としてくれるはずです。 2. vSocket (Site B) 側 ここが難関です。vSocketはVPC内に配置される仮想アプライアンスであり、それ自体がBGPスピーカーとして機能するわけではありません。そのため、AWSからCatoのSite BへBGPで経路情報を広報するには、何らかの仕組みをVPC内に別途構築する必要があります。 考えられる方法は以下の通りです。 BGPソフトウェアを搭載したEC2インスタンスを立てる VPC内にBGPルーティングソフトウェアをインストールしたEC2インスタンスを別途用意し、AWSのネットワークとCato Site Bの間でBGPピアを確立させる方法です。 Amazon VPC Route Serverを利用する AWSのマネージドサービスである「 Amazon VPC Route Server 」を利用する方法も考えられます。これは、VPC内のネットワーク仮想アプライアンス(NVA)とBGPで動的にルーティング情報を交換するためのサービスです。私も詳細は分からないので、以下記事などを見て貰えればと思います。 参考: VPC Route Server の設定を一通りやってみた(サーバワークス) …と、これでCatoへのルート伝播はできたとして、話は終わりませんでした。。 実はもう一つ、大きな課題があります。それは「 AWS内でのvSocketへの経路 」です。AWS上のEC2などからCato側へ通信するとき、通常はDirectConnectへ、障害時にはvSocketへ向かうように経路を切り替える必要があります。この切り替えをTransit Gatewayにお願いしたいのですが、vSocket側の経路をTransit Gatewayに動的に伝えるのが、だーいぶ厳しそうです。 この課題を解決する方法を、2つほどを考えてみました。 BGPだけで頑張る方法(GREトンネル活用) 1つ思いついたのが、BGPを話せるインスタンスを立てる方法の応用です。 Transit Gatewayは、実は「 Transit Gateway Connect 」という機能を使うと、 GREトンネル 経由でVPC内のインスタンスとBGPを話すことができます。 これを利用して、 VPC内にBGPとGREに対応したインスタンス(NVA)を立てる このNVAとTransit Gatewayの間でBGPピアを張る NVAからvSocketへの経路を広報するときに、 ASパスプリペンド (ASパスを長くして経路の優先度を下げる技術)を設定する こうすれば、通常時はASパスが短いDirectConnect側が優先され、障害時にだけvSocket側の経路が使われる、という自動切り替えが実現できる(?)気がします。。 BGPは諦めて、障害検知で静的ルートを操作する方法 BGPだけで全部やろうとすると複雑すぎるのでBGPに固執せず、別の方法を組み合わせる手もあります。 これは案②にも通じる話ですが、 「DirectConnectがダメになったことをCloudWatchなどで検知して、Lambdaを動かし、Transit GatewayのルートテーブルにvSocket向けの静的ルートをAPIで追加/削除する」 というやり方です。 これなら、複雑なBGP設定を回避しつつ、やりたいことは実現できそうですね。 CatoのSource NATを活用する方法 こちらの方法は かなり条件付き になりますが、AWS側の複雑な設定を回避できる面白い案なので紹介してみます。 AWSをCatoで利用する場合って、多くはAWS上にいるサーバーにWAN側からアクセスしたい、というケースかと思います。この「 外から中への通信 」がメインなら、使えるかもしれない技です。 どうやるかというと、vSocketが持っている「 Source NAT 」機能を使います。 CatoのSocket(vSocket含む)は、通過する通信の送信元IPアドレスを、Socket自身のIPアドレスに変換するNAT機能を持っています。 これを利用して、 WAN側から来た通信がvSocketを通過するときに、送信元IPをvSocketのIPアドレスにNATで書き換えてしまいます。 AWSのサーバーから見ると、通信は「vSocketから来た」ように見えます。 サーバーからの応答(戻りの通信)は、当然vSocketに向かいます。Transit GatewayもvSocketのいるVPCへの経路は知っているので、問題なくルーティングできます。 応答を受け取ったvSocketは、元の送信元IPアドレスにちゃんと戻してからWAN側に返してくれます。 こうすれば、Transit GatewayでBGPや静的ルートをごちゃごちゃ設定しなくても、戻りの経路をvSocketに強制的に向けることができる、というわけです。Catoの機能をうまく使った裏技的な感じですね。 ただ、最初に「条件付き」と言った通り、大きな制約があります。 この方法は、 AWS側から自発的にWAN側へ通信を始める場合には使えません。 (Transit Gatewayのルートテーブルには他拠点宛のルーティング情報がないため) あくまで「 外から中 」へのアクセスがメインで、「 中から外 」への自発的な通信がない、という環境であれば、かなりシンプルな解決策になるかもしれませんね。 色々書いてきましたが、正直なところ調べながら書いたので、実現度はだいぶ低いのかなと思ってます。 # @Amazon Q ファクトチェックして 案②Catoのルーティングを無理やり変更する方法 BGPを使わない方法も一応、思いつきました。 最初に述べた通り、この構成のポイントはルーティングを切り替えることになります。 CatoではSiteへのルーティングは各Siteの設定よりできるので、手動でもそこの設定を切り替えることでSite AからSite Bへルーティングを切り替えることができます。 ただ、それでは芸がないので、何とか自動化する方法がないかを考えてみました。 このアプローチのポイントは、「障害検知」と「ルーティング変更の実行」を自動化することです。 1.障害の検知方法 まず、Cloud InterConnectがダメになった時を検知する方法はないかを考えてみます。 Cloud InterConnect(Site A)の障害を検知する方法として、以下の2つが考えられます。 Cato側での検知: Catoの「 Link Health Rule 」機能を利用します。Siteのダウンといったイベントを検知し、指定したWebhook宛に通知を送信できます。 AWS側での検知: Amazon CloudWatchを利用します。Direct Connectのメトリクス「 ConnectionState 」(0=down, 1=up)を監視し、CloudWatch Alarmを発報させます。 参考: Monitoring with Amazon CloudWatch – AWS Direct Connect 2. ルーティング変更の実行方法 続いてSiteのルーティングの変更の自動化方法について考えてみます。 こちらはCatoのAPIを使えばいけそうです。 参考: Cato API Documentation 障害を検知したら、Cato APIを呼び出し、以下の通りルーティング設定を書き換えるLambdaを作成します。 障害発生時: Site Aから対象VPC/SubnetへのルートをAPIで削除し、Site Bへ同じルートを追加する。 障害復旧時: 上記とは逆の処理(Site Bのルートを削除し、Site Aのルートを再追加)を実行する。 これだけだと「案①」でも触れたAWSからCatoへの戻りの通信経路が切り替わりませんので、LambdaでAWSのAPIも叩いてもらい、Transit Gatewayのルートテーブルを書き換えてもらいます。 具体的には、Lambdaのプログラムの中で、 障害発生時: Transit Gatewayのルートテーブルに、Catoのネットワーク宛てのネクストホップをvSocket側に向ける静的ルートを追加する。 障害復旧時: 追加した静的ルートを削除する。 という処理を追加します。 全体像としては、以下のようになるかと思います。 障害検知: CloudWatch Alarm (Direct Connect) または Cato Link Health Rule (Webhook) トリガー: CloudWatch Alarm Action または Amazon API Gateway 実行: AWS Lambda 処理内容: Lambda関数が Cato API をコールし、Cato側のルート情報を書き換え Lambda関数が AWS API をコールし、 Transit Gatewayのルートテーブル を書き換え こっちはいけそう度高めで自信はあるのですが、Lambdaがやることも増えますし、プログラムを書かないとなので、そこだけハードルは高そうです。 #AI時代ならLambdaぐらいのコーディングだったら余裕だったりしますかね。。 まとめ 今回は、Cato Cloud InterConnectとvSocketを組み合わせたハイブリッドな冗長構成について考察しました。 どちらの案も、Cato単体の機能というよりは、AWSのサービス(BGP関連サービスやLambda、CloudWatchなど)を深く活用する高度なアプローチとなりました。 しかも、今のところ机上の話なので、実際に実現できるか怪しいので、 Catoが公式に推奨する標準構成(Cloud InterConnectであれば回線の冗長化、vSocketであればインスタンスの冗長化)を選択することが、最もシンプルかつ確実な方法 で、やはり一番良さそうです。 #検証はできたら追記していく所存ではあります。
本記事は 夏休みクラウド自由研究2025 8/9付の記事です 。 この記事では、CatoクラウドでのBGPの使用事例をご紹介します。 早速ですが、Socketに設定するLAN側のルーティングは「Static Route」と「BGP」が使用できます。 Catoクラウド内はBGPでルート交換がされており、お客様拠点のCato Socketに設定するLAN側のルーティング情報をCatoクラウド側に再配送することで、ネットワーク全体で到達性が確保できるという仕組みです。 ただ、お客様拠点内でBGPを使用しているケースは多くはなく、実際にもStatic Routeの利用がほとんどです。 Static RouteによるSocket拠点のルーティング 図.1は、データセンターの3スイッチに複数のVLANが設定されており、Cato SocketからL3スイッチにVLAN-a/b向けのルーティングを設定している例です。Socketに設定したルーティングは、自動的にCatoクラウドに再配送されるので拠点XYZのSocketはその経路を認識しており、DC拠点のVLAN-a/b宛ての通信が発生した場合は、DC拠点のSocketに転送します。 図.1 Static Routeの再配送 では、BGPの使用例を3つ紹介します。 BGPの使用例 – Socket拠点のルーティング 図.1で示したDC拠点内のStatic RouteをBGPに置き換えることもできますが、VLAN数が少なければStatic Routeで十分です。 ただし、VLAN数が多い場合や、Catoクラウド移行時には、BGPによるルーティング制御の方が手間がかかりません。 図.2は、既存ネットワークからCatoクラウドへの移行時の例です。DCをハブ拠点として、DC内のL3スイッチでルーティングを制御している場合、拠点Xを既存WANからCatoクラウド接続に切り替える際に、Static Routeであれば拠点切り替えの度にDCルータでルート切り替え作業が発生しますが、BGPを使用していればその作業が不要になります。 図.2では、拠点Xを既存WAN→Catoクラウドの移行を示しているのですが、WANルータをCato Socketに変更し、WANルータのLAN側アドレスをCato Socketに踏襲すれば、ルーティングに関する作業は一切不要となります。 図.2 Socket拠点のBGP利用イメージ 補足すると、このように拠点LAN内の構成やルーティング設定の変更なく移行できる点は、Catoクラウドの強みです。 BGPの使用例 – IPsecサイトの冗長 CatoクラウドとIPsecで接続するサイトのリンクの冗長化を目的として、BGPを使用する例をご紹介します。 実際の事例としては、このパターンが一番多いと思われます。 現在、CatoのvSocketは、AWS, Azure, GCPで作成する事が可能ですが、その他のクラウドをプライベート接続する際は、IPsecによる接続となります。(クラウド側でIPsec接続するサービスがある事が前提です) Socket / vSocketはCato PoP間のトンネル接続が切れると自動で別のPoPに接続しますが、IPsec接続はトンネルが切れたら切れっぱなしです。これを避けるために、Catoは別PoPに2本のトンネルを張っておくことを推奨しています。 その時、Cato~クラウド間でBGPを使用しておけば、トンネルが1本切れても残りのトンネルに自動で迂回させることができます。 図.3はOCIとの接続で、OCIのSite-to-Site VPNを使用して2つのIPsecトンネルで冗長リンクを構成した例です。 図.3 OCIとのIPsec接続例 BGPの使用例 – Cloud Interconnectサイトの冗長 Cloud Interconnectは、Cato版ダイレクトアクセスです。現在はAWS, Azure, GCP, OCIとCatoクラウドを専用線で接続できます。 この場合も、上記図.3と同様の構成となります。 Cloud Interconnectについては、次の記事を参照下さい。 Catoクラウド の Cloud Interconnect(旧 Cross Connect) について Catoクラウドの Socket/vSocket、IPsec以外の拠点接続方法である”Cross Connect”のサービス概要について紹介します。 blog.usize-tech.com 2023.08.25 vSocket × Cloud Interconnect 徹底比較 パブリッククラウドをCatoクラウドへ接続する方法「vSocket」と「Cross Connect」を性能面・コスト面等から比較します。 blog.usize-tech.com 2023.11.29 BGPのパラメータ では、BGPのパラメータを見てみましょう。ここでは、Socket拠点のルーティグでBGPを使用する場合を例にします。 設定箇所は各サイトのSite Configuration >BGPで、設定項目は以下の通りです。 内容 General Name L3機器(BGPネイバー)毎にBGPピアを設定できるので、その識別の為にユニークな名前をつけます。 ASN Peer L3機器側のAS番号を設定します。プライベート空間なので64512~65534の中から割り当てます。既にBGPを使用している場合、既存のAS番号を設定可能ですがCato側のAS番号を被らない事、またBGPピアの拡張性を考慮したナンバリングにする必要があります。 Cato Cato側のAS番号を設定します。Catoのデフォルト値は64515なので、既存ネットワーク側と重複しなければデフォルト値で登録します。 IP Peer L3機器のアドレスを設定します。もちろんSocketのNative IP Ranges内でないとエラーとなり設定できません。 Cato 自動設定なので設定する必要はありませんが、結局のところSocketのLANアドレスが割り当てられます。 注)SocketのHA構成時はVRRPの共有アドレスとなります。Socketの実アドレスではBGPネイバーを確立する事ができません。 Policy Advertise Default route SocketからL3機器にデフォルトルートを広告します。 All routes Catoに接続する拠点やモバイルアドレスレンジの全ルートを広告します。 Summary routes 複数ルートを単一のサマリールートとして広告できます。 Accept Dynamic routes BGPネイバーからCatoが動的に学習するIPレンジを指定できます。所謂ルートフィルタの設定がここで出来ます。 NAT Perform NAT to public IPs この設定を有効にすると、そのBGPネイバー経由で送信される全ての送信トラフィックに対してSource NAT(SNAT)が実行されます。 Catoからのトラフィックの送信元IPアドレスを統一する事ができます。 Additional Settings MD5 Auth BGPセッションでMD5認証を使用できます。事前共有秘密鍵を使用してBGPピア間の認証を行う事ができます。 Metric BGPネイバーの優先度を決定する値で低い方が優先されます。デフォルト値は100です Hold time BGPネイバーがダウンしていると判断するまでに待機する時間です。デフォルト値は60秒です。 Keepalive interval BGPセッションを維持するために、BGPネイバーにキープアライブメッセージを送信する間隔です。デフォルト値は20秒です。 Track Email Notification BGPセッションの確立や切断が発生した際に、設定してあるメーリングリスト等に通知メールを送信する事ができます。 最近のBGPに関するアップデート情報 毎週公開されるCatoのアップデート情報から、BGPに関するものを拾ってみました。 以下は2024年後半から現在までのものです。利用ニーズはそんなにないと思うのですが、その割には機能強化されてるなという印象です。 ・サイト接続の制御を強化するために、BGPの構成および監視をサポートするAPIを追加 ・BGPルートを1つのサマリールートに集約 ・BFDによるBGPコンバージェンスの高速化 ・4 Bytes-ASNピアでBGPを確立する さいごに BGPの利用は、Socket拠点のルーティングよりもIPsecサイトの冗長化の方がニーズが高いように思われます。現在vSocketが利用できるAWS、Azure、GCPではvSocket接続すればよいのですが、その他のクラウドとの接続はIPsec接続になります。IPsecのシングル接続の場合、Cato PoPのメンテナンスによりリンク断となるので冗長化は必須です。その時にはこの記事を参考にしていただければ幸いです。
こんにちは。SCSK 青島です。 先日6月25,26日の2日間、幕張メッセで開催されたAWS Summit Japan 2025に参加しました。 私にとっては今回が初参加でした。 ▲会場の様子 AWS Summit Japan | 2025 年 6 月 25 日(水)、26 日(木) AWS Summit Japan(AWSサミット)とは、AWSのサービスに関する今を知ることができる、AWSを学ぶ日本最大のイベントです。基調講演をはじめとしたさまざまなセッション(講演)や、さまざまな企業の展示を見られるExpoエリア、そのほかにも楽しいイベントが用意されています。 参加前は「生成AI」や「DX」といったトレンドキーワードが並び、どんな難しい技術を使うんだろう、、と少し身構えていました。 しかし実際にセッションを聞いてみると、技術そのものよりも「人と組織」の課題について語られており、そこに生成AI活用やDX推進の本質があるように感じました。 そこで印象的だった3つの事例をご紹介します。 損保×デロイト 「クラウドで変える損保業界のサプライチェーン -業界共通基盤の第一歩、レンタカー手配 DX-」 概要 損保とデロイトによる業界横断DXのセッションです。 自動車事故時のレンタカー配車業務において、業界初となる共通プラットフォーム構築の挑戦について紹介されました。 課題とアプローチ 従来は、各損保会社が個別にレンタカー会社と電話やFAXでやり取りしていました。 <各社の課題> レンタカー会社:各社との個別対応が負担 損保会社:配車業務が煩雑、運用コストに課題 ⇒レンタカー手配を非競争領域として位置付け、損保ジャパン主導のもと業界共通基盤としてシステムを統一 業界全体の課題解消、価値拡大に貢献 工夫 「直感的、シンプル」な 機能に絞り込む ことでシステム利用率向上 共通的な機能は共通部に集約し、システムの再利用性を向上 個社特有の情報を処理するワークロードは個別に構築し、共通部からも分離 塩野義製薬 「SHIONOGI における生成 AI 活用~全社的な道筋と医薬開発領域での事例紹介~」 概要 塩野義製薬の生成AI活用に関する取り組みについてです。 製薬開発における文書作成の膨大な時間と費用という課題に対し、生成AIを活用した文書作成支援の事例が挙げられました。 課題とアプローチ 臨床試験時に成果物として提出される様々な規制文書の作成には、膨大な時間(数十~数百時間/文書)を要する 製薬業界のミッションは、新薬発売までのリードタイムをいかに短く、効率的にできるか ⇒文書作成支援や文書検索・分析等様々な生成AIアプリを開発 工夫 人間によるチェックプロセスを残し、 リスクが高いレビューは人がやる すべての工程で生成AIを使用するのではなく、 要所要所で必要な技術を掛け合わせる 例:文書生成にはLLMを、フォーマット調整などの定型作業にはPythonを組み合わせることで安定性を図る プロアクティブな運用でハルシネーションを監視 ANA 「ANA の挑戦! AI とデータ活用を牽引するデータ基盤の拡大戦略」 概要 ANAの生成AI活用事例とデータマネジメント基盤 「BlueLake」に関するセッションです。 4 万人規模の組織におけるデータ民主化を通じた、AI やデータの活用事例が紹介されました。 課題とアプローチ 数千件/月ほどの「お客様の声」を人手で分類、担当者による主観が入り判断基準が曖昧 表やグラフ、数字の人手による更新が都度必要 手作業が多く、施策検討までたどり着けない ⇒CAがカテゴライズする際の頭の中のロジックを言語化 経験や勘に基づく「暗黙知」を引き出すことで精度を向上 工夫 「小さく始めて、大きく育てる」 アプローチ 経験や勘に基づく「暗黙知」 を引き出し、プロンプトに組み込むことで精度を向上 個人情報の有無判定にも Amazon Bedrockを活用することでフリーテキスト内に存在する個人情報の取り扱いも可能に 自社アプリ「BlueLake AiVO」によるモニタリング体制 まとめ 3社の事例を通じて、生成AI活用・DX推進における成功ポイントを考えてみました。 現場の具体的な課題が起点 技術先行ではなく、現場の身近な課題から始まることで、現場の人にも「自分事」としてとらえやすい 現実的かつ実用的なアプローチ 「小さく始めて、大きく育てる」段階的な推進 機能を絞り込んだり、適宜技術を掛け合わせたり 人間の知恵×技術の効果的な組み合わせ 暗黙知のプロンプト化 人間のチェックプロセスは残す 堅実な構築と運用 共通部分と個別部分の分離 個人情報保護のための2層構造 最後に 今回のAWS Summit では上に挙げた3社以外のセッションも拝聴しましたが、 技術そのものの活用以上に、組織全体で生成AI活用・DX推進に取り組む文化の醸成が難しく、大切なのだと気づかされました。 そしてその文化醸成は、現場の身近な課題解決から小さく始まり、その成功の積み重ねによって大きな成果が実現できると思います。結局人が主役となって進んでいくんだなあと感じました。 技術トレンドを追うだけでなく、現場に寄り添った地に足の着いた改善を意識していきたいです。 最後までお読みいただきありがとうございました。
こんにちは、SCSKの前田です。 私が携わった LifeKeeper の案件で導入を行った ARK について紹介をかねてお話したいと思います。 今回は、SQL Server 編と言うことで、マイクロソフト社が開発したリレーショナルデータベース管理システムを簡単に冗長化するための ARK の導入事例について、ご紹介していきます。 注意 マイクロソフト によると、SQL Server フェイルオーバークラスターインスタンス (FCI) では、クラスターノードがドメインに参加している必要があります。この制限により、Windows 版の LifeKeeper を使用し、ワークグループ環境で SQL Server フェイルオーバークラスターインスタンスを保護することはできません。 おさらい LifeKeeperのARKについて、おさらいしたいと思います。 ARK とは、Application Recovery Kits の略で、LifeKeeper が特定のアプリケーション(オープンソースソフトウェアや商用アプリケーション)を容易にリソースとして組み込むことが可能になる製品です。 ARK による、アプリケーションのリソースへの組み込みはウィザード形式(GUI上で設定)で作業が可能となり、ARK には、アプリケーションを操作(起動・停止・監視・再起動)するための4つのスクリプトがあらかじめ準備されているため、スクリプトを設計・作成するための開発工数の削減や人的なミスを防止することが出来ます。 概要説明 SQL Server ARK では、SQL Server 本体を保護対象リソースとして登録し、下記表にまとめたオプションサービス(必要に応じ選択が可能)を含めて保護する機能を提供します。 オプションサービス名 備考 SQL Server Agent SQL Server Reporting Services Distributed Transaction Coordinator SQL Server Browser SQL Server VSS Writer SQL Server Integration Services SQL Server 2014 より利用可能 SQL Full-text Filter Daemon Launcher SQL Server 2016 より利用可能 SQL Server Launchpad SQL Server 2016 より利用可能 SQL Server PolyBase Data Movement SQL Server 2016 より利用可能 SQL Server PolyBase Engine SQL Server 2016 より利用可能 SQL Server CEIP service SQL Server 2016 より利用可能 注意 SQL Server ARK では、SQL Server の次の機能を利用できません ・SQLレプリケーション(スナップショット、マージ、トランザクション) ・SQL のログ配布 ・SQL データベースのミラーリング ・SQL Server AlwaysOn 可用性グループ また、分散トランザクションはサポートされません。 SQL Server ARK は、汎用アプリケーション(Generic Application)リソースの導入とは違い、起動・停止・監視・再起動を行うためのスクリプトを明示的に指定することはなく、リソースの作成に必要な項目に対するパラメータをウィザード形式で入力または、選択することでリソースを作成することが出来ます。 SQL Server ARK として SQL Server の処理内容は以下の通りとなります。 SQL Server の処理 処理名 処理内容 起動処理 ① sc query コマンドによるサービス名を取得 ② ARK の内部処理($LKBIN/ScQueryState.exe)によってサービスの起動状態を取得 ③ サービスの状態が RUNNING 以外の場合、sc start コマンドによりサービスの開始を実施 ④ オプションサービスも保護する場合、オプションサービスに対して②と③を実施 ⑤ 起動した SQL Server 本体のサービスに対し、管理ユーザで接続出来るか確認を実施 停止処理 ① オプションサービスも保護する場合、ARK の内部処理($LKBIN/ScQueryState.exe)によってオプションサービスの起動状況を取得 ② オプションサービスの状態が RUNNING か PAUSED の場合、sc stop コマンドによりオプションサービスの停止を実施 ③ ARK の内部処理($LKBIN/ScQueryState.exe)によって SQL Server 本体サービスの起動状況を取得 ④ SQL Server 本体サービスの状態が RUNNING か PAUSED の場合、sc stop コマンドにより SQL Server 本体サービスの停止を実施 ⑤ ④で SQL Server 本体サービスが停止出来なかった場合、net stop コマンドにより SQL Server 本体サービスの停止を実施 ⑥ ⑤で SQL Server 本体サービスが停止出来なかった場合、もう一度④で SQL Server 本体サービスの停止を実施 監視処理 sc query コマンドにより、SQL Server 本体 及び、オプションサービスの起動状態の確認を実施 詳細監視処理 ① SQL Server 本体のサービスに対し、管理ユーザで接続出来るか確認を実施 ② マスター DB にクエリーを発行し、結果が取得できるか確認を実施 再起動処理 起動処理と同一の処理を実施 SQL Server ARK の構築例 それでは、実際に SQL Server ARK の構築についてお話していきたいと思います。 SQL Server ARK のパラメータ項目 SQL Server のリソース作成時に設定する特有のパラメータを一覧表にまとめました。 項目 説明 Microsoft SQL Server のインスタンスの選択 LifeKeeper for Windows で保護する Microsoft SQL Server のインスタンスを選択 Microsoft SQL 管理ユーザ名の入力 このサーバで Microsoft SQL の管理権限を持つユーザの名前を入力。(マスタデータベースに対する SA 権限が必要) パスワードの入力 入力したユーザアカウントの管理パスワードを入力 保護対象のオプショナルサービスの選択 この階層で保護されるオプションの SQL サービスを選択(リストには LifeKeeper の保護に適したサービスのみが表示される) 保護された IP アドレス インスタンスで保護する IP アドレスを選択(名前付きパイプだけを使用する場合、IP アドレスは不要) 名前付きパイプのエイリアス 名前付きパイプの別名を入力 SQL Server リソースの作成 SQL Server リソースを LifeKeeper の GUI によって作成する流れを例として紹介します。 注意 SQL Server で使用する共有ディスクリソースと、 IP リソース、及び、別のリソース等、それぞれの依存関係がある状態で SQL Server リソースを作成した場合、SQL Server リソース作成時の自動による依存関係の作成が失敗する可能性があるため、必要に応じて依存関係を削除する必要があります。 以降の例では、共有ディスクリソースと IP リソースの依存関係がない状態で SQL Server リソースの作成を実施しています。 処理内容 GUI画面例 リソース作成前のツリー構造 冗長化対象ノードの選択 保護アプリケーションの選択(MS SQL Server) Microsoft SQL Server のインスタンスの選択 Microsoft SQL 管理ユーザ名の入力 管理ユーザのパスワードの入力 データベースの設定の確認 保護対象のオプショナルサービスの選択 保護する IP アドレスの選択(例では「なし」を選択) 名前付きパイプのエイリアスの選択(例では「なし」を選択) Microsoft SQL Server リソースのタグ名の入力 稼働系ノードのリソース作成結果 待機系ノードのリソース作成準備の確認結果 待機系ノードの優先順位の設定 ※デフォルト:10 待機系ノードのリソース作成結果 リソース作成後のツリー構造 これで、LifeKeeper による SQL Server のリソースが完成です。 依存関係の作成 SQL Server リソースを作成した後、全リソースの起動(停止)する順序を定義するため、必要に応じてリソース間の依存関係(リソースツリーの下から起動され、上から停止される)を作成する必要があります。 例として、別で作成していた仮想 IP リソースを始めに起動させるようリソースツリーの下部に配置させ、その後に共有ディスクリソースと SQL Server が起動されるように依存関係を作成します。 処理内容 GUI画面例 依存関係作成前のツリー構造 SQL Server リソースの依存関係作成後 これで、SQL Server に関連する LifeKeeper によるリソース構成ツリーの完成です。 まとめ 今回は LifeKeeper ARK の導入事例と言うことで、SQL Server のリソース作成について紹介してみました。 SQL Server ARK は、汎用アプリケーション(Generic Application)リソースとは違い、起動・停止・監視・再起動を行うためのスクリプトを準備する必要がなく、リソースを作成することで意識することなく自動でスクリプトが導入されます。 また、SQL Server ARK では、SQL Server 本体を保護サービスとしてリソースに登録すると共に、必要なオプションサービスを保護する機能も提供しています。システムの要件に合わせ、保護対象のサービスを選択することが可能になっています。 SQL Server ARK を導入するための手順を纏めます。 ・SQL Server として保護対象とするオプションサービスを決定する ・SQL Server のリソース固有のパラメータの設定値を検討する ・LifeKeeper GUI を用いて、SQL Server のリソースを作成する ・仮想 IP リソース含め、リソースの起動順序を定義するため依存関係を作成する LifeKeeper では SQL Server 以外にも多数の ARK が用意されていますので、また次の機会に別の ARK について紹介していきたいと思います。 その他 ARK の導入事例に関しては以下のリンクからどうぞ! LifeKeeper ARK の導入事例を紹介<JP1/AJS3編> – TechHarmony LifeKeeper ARK の導入事例を紹介<Oracle編> – TechHarmony 詳しい内容をお知りになりたいかたは、以下のバナーからSCSK LifeKeeper公式サイトまで
こんにちは、SCSKの齋藤です。 本記事では、 Terraform を使ってBigQueryのリソース(データセット・テーブル・スキーマ)を Infrastructure as Code(IaC) として管理する方法を解説します。 そもそもBigQueryとは? BigQueryは、Google Cloudが提供するサーバーレスなデータウェアハウスです。 特徴は以下の通りです。 SQLで大規模データを高速分析 標準SQLでペタバイト級のデータを数秒〜数分で集計・分析。 サーバーレス インフラ管理不要。ストレージやクエリのリソースは自動でスケール。 コスト効率 ストレージとクエリ課金が分離されており、使った分だけ支払う従量課金。 GCPサービスとの連携 Cloud Storage、Dataflow、Looker Studio など、他の GCP サービスとシームレスに連携。 これにより、データの収集、処理、可視化を統合的に行うことが可能。 なぜTerraformでBigQueryを管理するのか? BigQueryはGCPコンソールやbqコマンドで手軽にテーブル作成できますが、 TerraformでIaC化することで以下のメリット があります。 環境ごとの再現性 開発 (dev)、ステージング (stg)、本番 (prd) など、異なる環境で同じ構成をコードで再現できます。環境の違いによる「あれ?動かない…」を撲滅! スキーマや設定のバージョン管理 テーブル定義、パーティション設定、クラスタリング設定などの変更履歴を Git で管理できます。 これにより、変更の追跡、ロールバック、監査が容易! 自動化・レビュー Pull Request (PR) ベースでレビューを行い、CI/CD (Continuous Integration/Continuous Delivery) パイプラインによる自動反映が可能です。 これにより、変更の品質を向上させ、デプロイメントの効率アップ! ヒューマンエラー防止 手作業による設定ミスや漏れを防ぐことができます。 コードによる定義は、人為的な誤りを減らし、一貫性を保証! ディレクトリ構造例 本記事で紹介する構成は、 プロジェクトごと・データセットごとにモジュールを分割 し、環境(dev/stg/prd)ごとにパラメータを切り替えられるようにしています。 terraform-bigquery/ └── プロジェクト名/ ├── envs/ │ │── dev/ │ │ ├── main.tf │ │ ├── backend.tf │ │ ├── provider.tf │ │ ├── terraform.tfvars │ │ └── variables.tf │ └── stg/ │ └── prd/ └── module/ └── dataset1/ ├── table1.yaml # テーブルスキーマ(YAML) ├── dataset1.tf # データセット・テーブル定義 └── variables.tf # モジュール変数 各ファイルの役割: envs/dev/main.tf : 環境固有の設定を適用し、データセット構築に必要な各モジュールの呼び出しとその引数を定義 envs/dev/backend.tf : Terraform State を安全かつ共有可能な場所に保存するための設定(GCSバケットなど) envs/dev/provider.tf : GCP プロバイダの認証情報、対象プロジェクト、リージョンなどを設定 envs/dev/terraform.tfvars : プロジェクトID、リージョン、サービスアカウントメールアドレスなど、環境によって異なる変数値の定義 envs/dev/variables.tf : main.tf で使用する変数の型、デフォルト値、説明などを定義し、外部からの入力インターフェースを提供 module/dataset1/table1.yaml : テーブルのカラム名、データ型、nullable 属性、説明などを記述した YAML 形式のスキーマ定義ファイル module/dataset1/dataset1.tf : データセット自体の定義、および table1.yaml からスキーマを読み込んでテーブルを定義するTerraformリソース定義 module/dataset1/variables.tf : モジュール内で使用する変数(プロジェクトID、データセット名など)の型、デフォルト値、説明などを定義 実装例 envs/dev/main.tf このファイルは、各データセットに対応するモジュールを呼び出す役割を担います。 source パラメータでモジュールの場所を指定し、 project_name と region 変数を渡します。 環境ごとに異なる terraform.tfvars ファイルを使用することで、 同じコードで異なる環境 をデプロイできます。 module "table1" { source = "../../module/table1" project_name = var.project_name region = var.region } module "table2" { source = "../../module/table2" project_name = var.project_name region = var.region } module/dataset1/table1.yaml このファイルは、テーブルのスキーマを YAML 形式で定義します。 name 、 type 、 mode 、 description などの属性を定義することで、テーブルのカラム構造を明確に記述できます。 YAML 形式を使用 することで、可読性が向上し、メンテナンスが容易になります。 - name: extraction_time type: DATETIME mode: NULLABLE description: "データ抽出日時" - name: value type: STRING mode: NULLABLE description: "値" # ...(以下略) module/dataset1/dataset.tf このファイルは、データセットとテーブルのリソースを定義します。 google_bigquery_dataset リソース: project 、 location 、 dataset_id などの属性を定義して、 データセットを作成 します。 google_bigquery_table リソース: project 、 dataset_id 、 table_id 、 description などを定義して、 テーブルを作成 します。 。 schema 属性: YAML ファイルからテーブルスキーマを読み込み、 yamldecode 関数で YAML 形式 から Terraform で使用できる形式に変換し、さらに jsonencode 関数でJSON形式にエンコードします。 time_partitioning ブロック: クエリのパフォーマンスを向上 させるために、時間ベースのパーティショニングを設定します。 type (この例では “MONTH”) と field (パーティションキーとなるカラム名) clustering 属性: クエリのパフォーマンスを向上 させるために、クラスタリングキーとなるカラム名を指定して、クラスタリングを設定します。 deletion_protection 属性: テーブルの削除保護を有効にします。 true に設定することで、 誤ってテーブルを削除するのを防止 。 resource "google_bigquery_dataset" "dataset1" { project = var.project_name location = var.region dataset_id = "dataset1" } resource "google_bigquery_table" "table1" { project = google_bigquery_dataset.dataset1.project dataset_id = google_bigquery_dataset.dataset1.dataset_id table_id = "table1" description = "情報を取得" schema = jsonencode(yamldecode(file("${path.module}/table1.yaml"))) time_partitioning { type = "MONTH" field = "extraction_time" } clustering = ["value"] deletion_protection = true } envs/dev/variables.tf このファイルは、 main.tf やモジュールで使用する変数を定義します。以下の変数は、GCP プロジェクト ID とリージョンを指定するために使用されます。 variable "project_name" { type = string } variable "region" { type = string } envs/dev/terraform.tfvars このファイルは、環境固有の変数の値を定義します。以下の変数に、それぞれ GCP プロジェクト ID とリージョンの値を設定します。 project_name = "project1" region = "asia-northeast1" envs/dev/provider.tf このファイルは、GCP プロバイダを設定します。 以下の属性に、それぞれ project_name と region 変数を設定します。 provider "google" { project = var.project_name region = var.region } 工夫ポイント スキーマをYAMLで管理 テーブルのカラム定義を YAML で記述し、Terraform で yamldecode → jsonencode して渡すことで、スキーマの可読性・メンテナンス性が大幅に向上します。 YAML は、構造化されたデータを記述するための人間にとって読みやすい形式であり、複雑なスキーマを管理するのに適しています。 パーティション・クラスタリングもIaCで管理 time_partitioning や clustering もコードで明示することで、クエリコスト最適化や運用ルールの徹底ができます。 time_partitioning { type = "MONTH" field = "extraction_time" } clustering = ["value"] deletion_protection = true 部分的なplan/applyで安全に反映 以下のように、特定のデータセットやテーブルだけを対象に plan/apply できます。他のリソースに影響を与えないので安心です。 bash terraform plan -target=module.dataset1 terraform apply -target=module.dataset1 テーブルの削除保護 deletion_protection = true を設定しておけば、間違ってテーブルを削除してしまうのを防げます。本番環境では必須の設定です。 運用・変更の流れ スキーマ追加・変更: 該当する YAML ファイルにカラムを追加・修正。 テーブル追加: module/dataset名/ に新たな YAML ファイルとリソース定義 ( .tf ファイル) を追加。 環境ごとに反映: dev/stg/prd の main.tf で必要なモジュールを呼び出し、 terraform apply を実行。 バージョン管理: すべての変更を Git で管理。 Pull Request ベースでレビューを行い、CI/CD パイプラインを使用して自動的にデプロイ。 まとめ BigQueryのテーブルやスキーマ、パーティション設定を TerraformでIaC化 することで、 再現性・自動化・レビュー性・ヒューマンエラー防止 など多くのメリットが得られます。 スキーマはYAMLで管理し、Terraformで読み込むと可読性・保守性が高まる パーティションやクラスタリングもコードで明示し、運用ルールを徹底 dev/stg/prdなど複数環境も同じ構成を再現できる すべてgitでバージョン管理し、Pull Requestベースで安全に運用 BigQueryの運用に課題を感じている方、これからIaCに取り組みたい方は、ぜひTerraformによるBigQuery管理を試してみてください! 参考リンク Google BigQuery 公式ドキュメント Terraform Google Provider BigQuery Table TerraformでBigQueryを管理するベストプラクティス YAMLスキーマ管理のアイデア
こんにちは、SCSKの齋藤です。 Google Cloud Platform (GCP) の Identity and Access Management (IAM) は、クラウドリソースへのアクセス制御を行う重要な機能です。しかし、組織が大きくなり、複数のフォルダとプロジェクトを管理するようになると、IAMの管理は複雑化し、手動での運用では限界が見えてきます。 本記事では、実際にGoogle Cloud組織全体のIAMをTerraformで自動化し、組織レベルからフォルダ、プロジェクトまでを一元管理できるシステムを構築した経験を紹介します。 なぜIAMのTerraform化が必要なのか? GCPをはじめとするクラウド環境では、リソースのデプロイや設定変更の速度が非常に速く、手動での変更管理では追いつかないのが現状です。これはIAM権限についても同様で、特に大規模な組織や多くのプロジェクトが稼働している環境では、権限管理の複雑性が増大し、以下のような課題に直面しがちです。 手動でのIAM管理が抱える課題 可視性の欠如 : 誰が、いつ、どのような権限を、どのリソースに対して付与したのかが、コンソールや監査ログを手動で確認するだけでは把握しにくい。 複数のプロジェクトやフォルダにまたがる権限の全体像を俯瞰することが困難。 一貫性の欠如と設定ミス : 手動での権限付与は、ヒューマンエラーを誘発しやすく、意図しない権限の付与や、必要な権限の漏れが発生しやすい。 プロジェクトや環境ごとに同様の権限設定が必要な場合でも、手動では一貫性を保つのが難しい。 レビュープロセスの困難さ : 変更内容を第三者がレビューする仕組みがない、あるいは機能しにくい。 権限変更が組織のセキュリティポリシーに準拠しているかを確認するのに時間がかかる。 変更履歴の追跡とロールバックの難しさ : 特定の変更がいつ、誰によって行われたのかを追跡するのが難しい。 誤った変更があった場合に、迅速かつ安全に元の状態に戻す(ロールバックする)ことが困難。 セキュリティドリフトの発生 : コードで管理されていない場合、一時的な手動変更が恒久化し、定義されたセキュリティポリシーと実際の環境との間に乖離(ドリフト)が生じやすい。これにより、意図せず広範な権限が付与されたままになる「過剰な権限」が発生する可能性があります。 これらの課題は、セキュリティリスクの増大だけでなく、運用の非効率性、コンプライアンス違反のリスク、そして監査対応時の大きな負担へと繋がります。 TerraformによるIAM管理のアーキテクチャと実装 ここでは、TerraformでIAMを管理するための推奨されるディレクトリ構造、GCPリソースの動的な取得、そしてYAMLファイルによる設定管理の具体例を紹介します。 ディレクトリ構造 TerraformでIAMを効果的に管理するためには、明確でスケーラブルなディレクトリ構造が重要です。以下にその一例を示します。 terraform-iam/ ├── main.tf # メイン設定ファイル (モジュールの呼び出しなど) ├── variables.tf # 変数定義ファイル ├── outputs.tf # 出力値定義ファイル ├── backend.tf # Terraform Stateのバックエンド設定 ├── provider.tf # GCPプロバイダー設定 ├── terraform.tfvars # 変数のデフォルト値または環境固有の値 ├── modules/ │ └── folder_hierarchy/ # フォルダ・プロジェクト階層のIAM管理用モジュール │ ├── main.tf # モジュール本体 │ ├── variables.tf # モジュール変数定義 │ └── outputs.tf # モジュール出力値 └── iam_configs/ # IAM設定を記述するYAMLファイル群 ├── organization/ # 組織レベルのIAM設定 │ └── organization.yaml ├── folders/ # フォルダレベルのIAM設定(フォルダごとにファイル分割) │ ├── production.yaml │ ├── analytics.yaml │ └── development.yaml └── projects/ # プロジェクトレベルのIAM設定(特定のプロジェクト用) ├── project_alpha.yaml └── project_beta.yaml この構造により、IAM設定の責任範囲を明確にし、再利用性を高め、管理の複雑性を低減できます。 GCP IAMとTerraformリソースの対応 GCP IAMは階層的な構造(組織 > フォルダ > プロジェクト > リソース)を持っています。Terraformでは、この階層に応じて異なるリソースタイプが提供されます。 組織 (Organization) レベル : google_organization_iam_member , google_organization_iam_policy フォルダ (Folder) レベル : google_folder_iam_member , google_folder_iam_policy プロジェクト (Project) レベル : google_project_iam_member , google_project_iam_policy 特定リソース (Resource) レベル : google_storage_bucket_iam_member , google_bigquery_dataset_iam_member など、各サービス固有のリソース。 サービスアカウント (Service Account) レベル : google_service_account_iam_member , google_service_account_iam_policy (サービスアカウント自身への権限) 承知いたしました。ご提供いただいた詳細なコードとディレクトリ構成、運用面の考慮事項などを盛り込み、「IAMをTerraform化してみた」の記事を再構築します。前回の記事との依存関係をなくし、TerraformによるIAM管理に特化した内容とします。 IAMをTerraform化してみた こんにちは、SCSKの齋藤です。 クラウド環境、特にGoogle Cloud (GCP) におけるIdentity and Access Management (IAM) の管理は、組織のセキュリティと運用効率の要となります。しかし、多くの企業でIAM権限の管理は複雑化し、セキュリティリスクや運用上の課題を抱えがちです。手動での権限付与は、ヒューマンエラー、変更履歴の追跡困難、コンプライアンス遵守の課題など、様々な問題を引き起こす可能性があります。 本記事では、GCP環境におけるIAM権限の管理をより効率的かつ安全に行うため、 TerraformによるInfrastructure as Code (IaC) を導入する具体的なアプローチについて解説します。IAM設定をコードとして管理することで、手動運用が抱える様々な課題を解決し、堅牢でスケーラブルなセキュリティ基盤を構築できます。 第1章:はじめに – なぜ今、IAMのTerraform化が必要なのか? GCPをはじめとするクラウド環境では、リソースのデプロイや設定変更の速度が非常に速く、手動での変更管理では追いつかないのが現状です。これはIAM権限についても同様で、特に大規模な組織や多くのプロジェクトが稼働している環境では、権限管理の複雑性が増大し、以下のような課題に直面しがちです。 1.1. 手動でのIAM管理が抱える課題 可視性の欠如 : 誰が、いつ、どのような権限を、どのリソースに対して付与したのかが、コンソールや監査ログを手動で確認するだけでは把握しにくい。 複数のプロジェクトやフォルダにまたがる権限の全体像を俯瞰することが困難。 一貫性の欠如と設定ミス : 手動での権限付与は、ヒューマンエラーを誘発しやすく、意図しない権限の付与や、必要な権限の漏れが発生しやすい。 プロジェクトや環境ごとに同様の権限設定が必要な場合でも、手動では一貫性を保つのが難しい。 レビュープロセスの困難さ : 変更内容を第三者がレビューする仕組みがない、あるいは機能しにくい。 権限変更が組織のセキュリティポリシーに準拠しているかを確認するのに時間がかかる。 変更履歴の追跡とロールバックの難しさ : 特定の変更がいつ、誰によって行われたのかを追跡するのが難しい。 誤った変更があった場合に、迅速かつ安全に元の状態に戻す(ロールバックする)ことが困難。 セキュリティドリフトの発生 : コードで管理されていない場合、一時的な手動変更が恒久化し、定義されたセキュリティポリシーと実際の環境との間に乖離(ドリフト)が生じやすい。これにより、意図せず広範な権限が付与されたままになる「過剰な権限」が発生する可能性があります。 これらの課題は、セキュリティリスクの増大だけでなく、運用の非効率性、コンプライアンス違反のリスク、そして監査対応時の大きな負担へと繋がります。 1.2. IAMをTerraformで管理するメリット Infrastructure as Code (IaC) ツールであるTerraformを利用してIAMを管理することで、上記の手動管理の課題を解決し、以下のようなメリットを享受できます。 可視性と一元管理 : IAMポリシーがコードとしてTerraformファイルに明示的に記述されるため、権限の付与状況が一目で把握できます。 組織、フォルダ、プロジェクト、リソースレベルなど、すべてのIAM設定を一元的に管理できます。 バージョン管理と変更履歴 : Gitなどのバージョン管理システムと連携することで、IAMポリシーのすべての変更が履歴として残り、誰が、いつ、何を、なぜ変更したのかを追跡できます。 必要であれば、特定の時点の構成に迅速にロールバックすることも可能です。 レビューと承認プロセス : 権限の変更は、コードとしてプルリクエスト(Pull Request)を通じて提出され、チームメンバーやセキュリティ担当者によるコードレビューを受けることができます。 これにより、変更内容の妥当性、セキュリティポリシーへの準拠、ベストプラクティスとの整合性を確保できます。 自動化と再現性 : Terraformによって、IAMポリシーのデプロイや更新を自動化できます。 これにより、同じポリシーを複数の環境(開発、ステージング、本番)に一貫して適用し、環境間の差異をなくすことが容易になります。 セキュリティドリフトの検出と修正 : Terraform Stateファイルと実際のクラウド環境の状態を比較することで、手動で行われた変更(ドリフト)を検出し、コードに定義された状態に戻すことが可能です。 これにより、常にコードが「真実の源 (Source of Truth)」となり、セキュリティポリシーが強制されます。 コンプライアンスと監査対応の簡素化 : コード化されたポリシーは、監査証跡として機能し、特定の規制(GDPR、PCI DSSなど)への準拠状況を証明しやすくなります。 監査担当者は、コードリポジトリを参照することで、権限設定の詳細を容易に確認できます。 第2章:TerraformによるIAM管理のアーキテクチャと実装 ここでは、TerraformでIAMを管理するための推奨されるディレクトリ構造、GCPリソースの動的な取得、そしてYAMLファイルによる設定管理の具体例を紹介します。 2.1. 推奨されるディレクトリ構造 TerraformでIAMを効果的に管理するためには、明確でスケーラブルなディレクトリ構造が重要です。以下にその一例を示します。 python コードを実行 コードをコピーする terraform-iam/ ├── main.tf # メイン設定ファイル (モジュールの呼び出しなど) ├── variables.tf # 変数定義ファイル ├── outputs.tf # 出力値定義ファイル ├── backend.tf # Terraform Stateのバックエンド設定 ├── provider.tf # GCPプロバイダー設定 ├── terraform.tfvars # 変数のデフォルト値または環境固有の値 ├── modules/ │ └── folder_hierarchy/ # フォルダ・プロジェクト階層のIAM管理用モジュール │ ├── main.tf # モジュール本体 │ ├── variables.tf # モジュール変数定義 │ └── outputs.tf # モジュール出力値 └── iam_configs/ # IAM設定を記述するYAMLファイル群 ├── organization/ # 組織レベルのIAM設定 │ └── organization.yaml ├── folders/ # フォルダレベルのIAM設定(フォルダごとにファイル分割) │ ├── production.yaml │ ├── analytics.yaml │ └── development.yaml └── projects/ # プロジェクトレベルのIAM設定(特定のプロジェクト用) ├── project_alpha.yaml └── project_beta.yaml この構造により、IAM設定の責任範囲を明確にし、再利用性を高め、管理の複雑性を低減できます。 2.2. GCP IAMとTerraformリソースの対応 GCP IAMは階層的な構造(組織 > フォルダ > プロジェクト > リソース)を持っています。Terraformでは、この階層に応じて異なるリソースタイプが提供されます。 組織 (Organization) レベル : google_organization_iam_member , google_organization_iam_policy フォルダ (Folder) レベル : google_folder_iam_member , google_folder_iam_policy プロジェクト (Project) レベル : google_project_iam_member , google_project_iam_policy 特定リソース (Resource) レベル : google_storage_bucket_iam_member , google_bigquery_dataset_iam_member など、各サービス固有のリソース。 サービスアカウント (Service Account) レベル : google_service_account_iam_member , google_service_account_iam_policy (サービスアカウント自身への権限) 特に、 _iam_member リソースは既存ポリシーに影響を与えず追記・削除を行うため推奨されますが、 _iam_policy は既存ポリシーを上書きするため注意が必要です。 組織配下のすべてのリソースを動的に取得する仕組み 大規模なGCP環境では、個々のフォルダやプロジェクトを手動で指定するのではなく、組織内の既存リソースをTerraformで動的に取得し、IAM管理の対象とすることが効率的です。 data ブロックを利用してこれを実現します。 # main.tf (または適切な場所に配置) # 組織配下の直属のフォルダを動的に取得 data "google_folders" "organization_folders" { parent_id = "organizations/${var.organization_id}" } # 組織配下のすべてのサブフォルダを再帰的に取得(各直属フォルダの子フォルダを対象) # mapのkeyは直属フォルダのIDになります data "google_folders" "all_subfolders" { for_each = toset([for folder in data.google_folders.organization_folders.folders : folder.folder_id]) parent_id = "folders/${each.key}" # 'each.key' は親フォルダのID } # 組織配下のすべてのプロジェクトを取得 data "google_projects" "organization_projects" { # フィルタで組織IDを直接の親、または祖先に持つプロジェクトを指定 filter = "parent.id:${var.organization_id} OR ancestors.id:${var.organization_id}" } この設定により、TerraformはGCP環境から最新の組織、フォルダ、プロジェクトの情報を取得し、IAM設定の基盤として利用できるようになります。 ローカル値による論理構造の構築 取得した動的なデータを、Terraformの locals ブロックを使って管理しやすい論理構造に変換します。これにより、YAMLファイルで定義するIAM設定と、Terraformリソースを柔軟に連携させることができます。 # main.tf (localsブロックの例) locals { # 組織直下のフォルダ(IAM設定のターゲット指定用) root_folders = { for folder in data.google_folders.organization_folders.folders : folder.display_name => folder.folder_id if !contains(var.excluded_folders, folder.folder_id) # 除外対象フォルダは含めない } # 各ルートフォルダ配下のすべてのサブフォルダ(再帰的に取得した情報を統合) # root_name (例: "production") をキーに、その配下の全フォルダID (root自身含む) のリスト all_subfolders_by_root = { for root_name, root_id in local.root_folders : root_name => concat( [root_id], # ルートフォルダ自身もリストに含める flatten([ # data.google_folders.all_subfolders[root_id].folders は map(object) # その中の各folderオブジェクトからfolder_idを取得しflatten for subfolder in try(data.google_folders.all_subfolders[root_id].folders, []) : [ subfolder.folder_id, ] ]) ) } # 各ルートフォルダ配下のすべてのプロジェクト # root_name (例: "production") をキーに、その配下の全プロジェクトIDのリスト projects_by_root_folder = { for root_name, root_id in local.root_folders : root_name => [ for project in data.google_projects.organization_projects.projects : project.project_id # プロジェクトのancestorsにルートフォルダIDが含まれ、かつ除外対象でないものを抽出 if contains(project.ancestors, root_id) && !contains(var.excluded_projects, project.project_id) ] } # IAM設定ファイルを読み込み、localsに統合 # ここでiam_configs/folders/以下のYAMLファイルを動的に読み込みます。 # 各ルートフォルダ名(例: "production")に対応するYAMLファイルを検索し、 # 存在すればその内容をyamldecodeでパースし、Terraformで扱いやすいマップ構造に変換します。 folder_iam_configs = { for root_name, _ in local.root_folders : root_name => { # フォルダごとのIAMバインディング folder_bindings = fileexists("${path.module}/iam_configs/folders/${lower(root_name)}.yaml") ? { for binding in flatten([ for iam_entry in yamldecode(file("${path.module}/iam_configs/folders/${lower(root_name)}.yaml")).folder_bindings : [ # YAML内の'folder_bindings'キーを想定 for role in iam_entry.roles : { principal = "${iam_entry.principal_type}:${iam_entry.email}" role = role condition = lookup(iam_entry, "condition", null) # Conditionもサポート } ] ]) : "${binding.role}_${binding.principal}" => binding # Keyとしてroleとprincipalを連結しユニーク化 } : {} # プロジェクトごとのIAMバインディング (フォルダ配下のプロジェクトに適用したい場合) project_bindings = fileexists("${path.module}/iam_configs/folders/${lower(root_name)}.yaml") ? { for binding in flatten([ for iam_entry in yamldecode(file("${path.module}/iam_configs/folders/${lower(root_name)}.yaml")).project_bindings : [ # YAML内の'project_bindings'キーを想定 for role in iam_entry.roles : { principal = "${iam_entry.principal_type}:${iam_entry.email}" role = role condition = lookup(iam_entry, "condition", null) } ] ]) : "${binding.role}_${binding.principal}" => binding } : {} folder_ids = local.all_subfolders_by_root[root_name] # そのルートフォルダ配下の全フォルダID project_ids = local.projects_by_root_folder[root_name] # そのルートフォルダ配下の全プロジェクトID } } } この locals ブロックは、動的に取得したGCPの階層情報と、YAMLファイルで定義されたIAM設定を組み合わせ、 folder_iam_configs というマップ構造に変換します。これにより、後続のモジュール呼び出しで、各フォルダセット(例: productionフォルダとその配下のすべてのフォルダ・プロジェクト)に適用すべきIAMポリシーを動的に渡すことが可能になります。 YAML設定ファイルの読み込みと構造 IAM設定は、 iam_configs/ ディレクトリ配下にYAMLファイルとして定義します。これにより、HCL(HashiCorp Configuration Language)に不慣れなチームメンバーでもIAM設定を記述しやすくなり、Terraformコード本体と設定データを分離できます。 YAML設定ファイルの例 ( iam_configs/folders/production.yaml ) : # production.yaml folder_bindings: - principal_type: "user" email: "admin@example.com" roles: - "roles/resourcemanager.folderViewer" - "roles/resourcemanager.folderEditor" - principal_type: "group" email: "production-team@example.com" roles: - "roles/resourcemanager.folderViewer" - principal_type: "serviceAccount" email: "terraform@your-project.iam.gserviceaccount.com" roles: - "roles/resourcemanager.folderAdmin" project_bindings: - principal_type: "group" email: "production-team@example.com" roles: - "roles/viewer" - "roles/container.developer" # 例えばGKE開発者ロール YAMLファイルでは、 folder_bindings と project_bindings をキーとして、それぞれのレベルで付与したいプリンシパル、そのタイプ、メールアドレス、そしてロールのリストを定義します。これにより、特定のフォルダやその配下のプロジェクトに対して、一貫したIAMポリシーを適用できます。 TerraformによるIAM運用ワークフロー IAMをTerraformで管理することは、単にコードを書くだけでなく、そのコードをセキュアに運用するためのワークフローを確立することが重要です。 コードレビューの導入 IAMポリシーの変更は、セキュリティに直接影響を与えるため、厳格なコードレビュープロセスが不可欠です。 プルリクエスト (Pull Request) ベースの開発 : Terraformコードの変更はすべて、Gitリポジトリのプルリクエストとして提出します。 セキュリティチーム、アーキテクト、または経験豊富なチームメンバーがレビュー担当者となり、変更内容の妥当性、最小権限原則への準拠、セキュリティベストプラクティスとの整合性を確認します。 terraform plan の活用 : レビューの際には、必ず terraform plan コマンドの出力を共有します。 terraform plan は、Terraformが実行しようとしている変更の差分を詳細に表示するため、意図しない権限の追加や削除がないかを確認する上で極めて重要です。 CI/CDパイプラインとの連携と実行コマンド TerraformによるIAMのデプロイは、CI/CDパイプラインに組み込むことで自動化と信頼性を向上させます。 自動テストとポリシーチェック : Terraformコードの変更がプルリクエストとして提出された際、自動的に terraform validate を実行し、構文エラーがないかを確認します。 さらに、 terraform fmt でコードのフォーマットを統一します。 OPA (Open Policy Agent) や terraform-compliance などのポリシーチェックツールを導入し、セキュリティポリシーやコンプライアンス要件に違反していないかを自動的に検証します。 自動 terraform plan 実行 : プルリクエストが作成されるたびに、CIパイプラインで自動的に terraform plan を実行し、その出力をプルリクエストコメントとして自動投稿します。これにより、レビュー担当者は変更のプレビューを容易に確認できます。 自動デプロイとロールバック戦略 : レビューと承認が完了したプルリクエストは、自動的に本番環境に terraform apply を実行する設定を検討します。 自動デプロイは強力ですが、万が一の事態に備え、迅速なロールバック戦略を準備しておくことが重要です。Gitリポジトリの過去のコミットに git revert で戻し、再度 terraform apply を実行するなどの手順を確立します。 実行コマンド例 : Terraformの実行は、対象スコープを限定することで、影響範囲を制御しながら段階的に適用することができます。 # 全体実行(組織 + 全フォルダ + 全プロジェクトのIAMを適用) terraform plan terraform apply # 組織レベルのみのIAMを適用(特定のモジュールをターゲット指定) terraform plan -target=module.organization_iam terraform apply -target=module.organization_iam # 特定フォルダ配下全体(フォルダ + サブフォルダ + プロジェクト)のIAMを適用 # local.folder_iam_configsをfor_eachで展開しているモジュール(例: module.iam_for_root_folder)に対してターゲットを指定 terraform plan -target=module.iam_for_root_folder["production"] terraform apply -target=module.iam_for_root_folder["production"] # 複数フォルダのIAMを同時に指定して適用 terraform plan -target=module.iam_for_root_folder["production"] -target=module.iam_for_root_folder["analytics"] terraform apply -target=module.iam_for_root_folder["production"] -target=module.iam_for_root_folder["analytics"] -target オプションは、特定の変更を検証・適用する際に非常に有用です。 まとめ 本記事では、GCP環境におけるIAM管理をTerraformでコード化する具体的な方法と、そのメリット、考慮すべき点について解説しました。 IAMをTerraform化することは、手動管理の限界を乗り越え、GCP環境におけるセキュリティと運用ガバナンスを大きく向上させる強力な手段です。ヒューマンエラーのリスクを低減し、透明性のあるレビュープロセスを導入し、変更履歴を完全に追跡できるようになります。さらに、最小権限の原則をコードとして強制することで、セキュリティリスクを大幅に削減することが可能です。 初期の導入には手間と学習コストがかかるかもしれませんが、その投資は長期的なセキュリティ体制の強化と運用効率の向上として必ず報われます。Infrastructure as CodeによるIAM管理は、現代のクラウド運用において不可欠なアプローチです。 継続的な改善と、セキュリティベストプラクティスの適用を通じて、より堅牢で効率的なクラウドインフラを目指していきましょう。 参考 Google Cloud IAM の概要 – Google Cloud 公式ドキュメント https://cloud.google.com/iam/docs/overview?hl=ja
こんにちは、SCSKの齋藤です。 Google Cloudでは、このシークレット管理の課題を解決するために「 Secret Manager 」というサービスを提供しています。Secret Managerは、機密情報を安全に保存、管理、アクセス制御するためのフルマネージドサービスであり、バージョン管理や監査ログ機能も備えています。 本稿では、Cloud RunアプリケーションでSecret Managerを活用する際に検討すべき3つの連携方法を比較し、特に 「Cloud Runのボリュームとしてシークレットをマウントする」 方法の具体的な設定方法と、そのメリットについて深く掘り下げて解説します。 Cloud RunとSecret Managerの基本 まずはCloud RunとSecret Managerそれぞれの基本的な役割を確認しておきましょう。 Google Cloud Run:サーバーレスコンテナプラットフォーム Cloud Runは、コンテナイメージからWebサービスやバッチジョブを実行するためのフルマネージドなサーバーレスプラットフォームです。トラフィックに応じて自動的にスケーリングし、リクエストがない場合は0にスケールダウンするため、コスト効率に優れています。開発者はコンテナイメージを用意するだけで、インフラのプロビジョニングや管理を意識することなくアプリケーションを展開できます。 Google Cloud Secret Manager:シークレットの一元管理サービス Secret Managerは、各種認証情報やAPIキー、証明書といった機密情報を安全に保存・管理するためのサービスです。主な特徴は以下の通りです。 集中管理: アプリケーションごとに分散しがちなシークレットを一元的に管理できます。 バージョン管理: シークレットの変更履歴を自動的に管理し、必要に応じて特定のバージョンにロールバックできます。 アクセス制御: IAM(Identity and Access Management)と連携し、誰がどのシークレットにアクセスできるかを厳密に制御できます。 監査ログ: シークレットへのアクセスや変更履歴を詳細に記録し、コンプライアンス要件への対応を支援します。 自動ローテーション(一部対応): シークレットの自動的な更新をサポートし、セキュリティ強化に貢献します。 Cloud RunでSecret Managerを使用することは、アプリケーションのセキュリティを確保し、運用の手間を削減するための不可欠なステップとなります。 Cloud RunにおけるSecret Managerの連携方法:3つの選択肢 Cloud RunアプリケーションがSecret Managerからシークレット情報を取得する方法は、主に以下の3種類があります。 Secret Managerを読み込む方法 方法 特徴(メリット/デメリット) 1 Cloud Runのボリュームとしてマウント gcloud run jobs create JOB_NAME --image IMAGE_URL --set-secrets=PATH=SECRET_NAME:VERSION 【メリット】 コンフィグでの依存関係が明確。アプリケーションコードはファイル読み込みのみでポータビリティが高い。環境変数よりもセキュアな提供方法。シークレット変更時の挙動が明確化される。 【デメリット】 インスタンス起動時のシークレットアクセス失敗は実行時エラーとなる。シークレットの自動更新には対応しない場合が多い。 2 Cloud Runの環境変数として読み込み gcloud run jobs update JOB_NAME --set-secrets ENV_VAR_NAME=SECRET_NAME:VERSION 【メリット】 アプリケーションコードからシンプルに環境変数としてアクセスできる。インスタンス開始前にシークレット取得が行われるため、失敗した場合はインスタンスが起動しない(早期発見)。 【デメリット】 環境変数はプロセスダンプやログから漏洩するリスクがある。コンフィグでの依存関係がやや見えにくい。シークレットが変更されても、インスタンスが再起動されない限りアプリケーションに反映されない。 3 プログラムからSecret Manager APIを直接読み込み SecretManagerServiceClient()を使用 【メリット】 Cloud Runというサービスに直接依存しない実装となり、ポータビリティが最も高い。シークレットの動的な取得や、特定のタイミングでの取得が可能。 【デメリット】 アプリケーションコードがSecret Manager APIへの依存性を持つ。権限管理が複雑化する可能性。シークレットへのアクセス回数が増え、運用が複雑になる。どのタイミングでシークレットが参照されるか不透明になる。 本稿では、特に 「Cloud Runのボリュームとしてシークレットをマウントする」 方法に焦点を当て、その具体的な設定とメリットを詳細に解説します。 ボリュームマウントでシークレットをファイルとして利用する方法 Cloud RunでSecret Managerのシークレットをボリュームとしてマウントする方法は、コンテナがファイルシステムからシークレットを読み込めるようにするものです。この方法を設定する具体的なコマンドと、それに伴うメリットを見ていきましょう。 設定方法:–set-secretsオプションの使用 シークレットをボリュームとしてマウントするには、 gcloud run jobs create コマンドまたは gcloud run services update コマンド(Cloud Runサービスの場合)で --set-secrets オプションを使用します。 ジョブの場合の例: gcloud run jobs create MY-BATCH-JOB \ --image gcr.io/my-project/my-batch-app \ --set-secrets=/secrets/db_password=my-database-password:latest \ --region us-central1 このコマンドは、 my-database-password というSecret Managerのシークレットの最新バージョンを、コンテナ内の /secrets/db_password というパスにファイルとしてマウントします。アプリケーションは、このパスのファイルを読み込むことでシークレットにアクセスできます。 ボリュームマウント方式のメリット シークレットをボリュームとしてマウントする方式には、複数のメリットがあります。 コンフィグでの依存関係が明確: Cloud Runのデプロイ設定(コマンドラインオプションやYAMLコンフィグレーション)において、どのSecret Managerのシークレットが、どのパスにマウントされるかが明示的に定義されます。これにより、デプロイ設定をレビューするだけで、アプリケーションがどのシークレットに依存しているか、そしてどのバージョンのシークレットを使用しているかが一目で分かり、CI/CDパイプラインの管理やセキュリティ監査の際に可視性が向上します。 アプリケーションコードのポータビリティが高い: シークレットをボリュームとしてマウントする方式では、アプリケーションコード自体はファイルシステムからデータを読み込むだけであり、Secret Manager APIへの直接的な依存性を持ちません。これにより、コンテナイメージのポータビリティを高く保つことができます。例えば、開発環境、ステージング環境、本番環境で異なるSecret Managerのシークレットを使用したい場合でも、同じコンテナイメージを使い回し、各環境のデプロイ設定で適切なシークレットをマウントするだけで対応が完結します。 よりセキュアな方法でアプリケーションにデータを提供: シークレットをアプリケーションに提供する際、セキュリティは最優先事項です。ボリュームとしてマウントされたシークレットは、コンテナ内のファイルシステムにファイルとして配置されます。これにより、ファイルシステムアクセス権限によって読み取りが制御され、意図しないアクセスを防ぎやすくなります。Kubernetesのセキュリティベストプラクティスにおいても、シークレットを環境変数として直接指定するよりも、ボリュームとしてマウントする方が、プロセスダンプなどからの漏洩リスクが低減されるため、よりセキュアであると推奨されています。 シークレット変更時の影響を明確化できる: ボリュームマウント方式の場合、Cloud Runインスタンスの起動時に一度だけシークレットがボリュームに注入されます。これにより、シークレットが変更された際にアプリケーションに新しい値を反映させるには、Cloud Runサービス(またはジョブ)の再デプロイ(または更新)が必要であることが明確になります。この予測可能な挙動は、シークレット変更時の運用計画を立てやすくし、予期せぬ動作を回避する上で有効です。インスタンスの起動時にシークレットへのアクセスが失敗した場合、ボリュームマウントされたシークレットの読み取りも失敗するため、アプリケーションの起動に影響が出ます。これは、シークレットが正しく提供されていないことを早期に検知できるというメリットでもあります。 ローカル開発環境でのシークレット管理 本番環境でSecret Managerをボリュームとしてマウントする方法を用いる一方で、ローカル開発環境でのシークレット管理も考慮する必要があります。開発中にCloud Run環境を完全に再現し、シークレットをマウントすることは非効率的です。 ローカルでの実行時には、以下の手順でシークレットを管理する方法も検討することをお勧めします。 Secret Managerからのシークレット取得: gcloud secrets versions access latest --secret=SECRET_NAME コマンドを使用して、Secret Managerから対象のシークレットの最新バージョンを一時的に取得します。必要に応じて特定のバージョンを指定することも可能です。 環境変数への設定: 取得したシークレットの値を、ローカル環境の環境変数として設定します。例えば、Bashでは export MY_API_KEY="取得したシークレットの値" のように設定します。 アプリケーションの実行: 設定した環境変数を使用して、アプリケーションをローカルで実行します。 このアプローチにより、本番環境ではファイルシステムからシークレットを読み込むアプリケーションが、ローカルでは環境変数からシークレットを読み込む形となり、開発と本番の間のシークレット取得方法の差異を吸収しつつ、安全な開発環境を維持できます。アプリケーションコードは、単に「 MY_API_KEY という値(ファイルまたは環境変数)を読み込む」という抽象化されたロジックに留めることが可能です。 まとめ クラウドネイティブな環境におけるシークレット管理は、アプリケーションのセキュリティと運用効率の根幹をなす要素です。Google Cloud Secret Managerは、その強力な機能によってこの課題を解決する重要なサービスであり、Cloud Runとの連携はサーバーレスアプリケーションの安全な運用に不可欠です。 本稿で解説したように、Cloud RunでSecret Managerを活用する方法は複数存在します。その中でも、 「Cloud Runのボリュームとしてシークレットをマウントする」 方法は、以下の点で注目すべき特徴とメリットを提供します。 設定の可視性が高く、運用管理が容易である点。 アプリケーションコードのポータビリティを維持し、環境間で同じコンテナイメージを再利用しやすい点。 環境変数に比べてシークレットの露出リスクが低く、Kubernetesのセキュリティベストプラクティスにも合致する、よりセキュアな提供方法である点。 シークレット変更時のアプリケーションの挙動が予測しやすく、運用計画やトラブルシューティングが容易である点。 どの方法を選択するかは、アプリケーションの特性、チームのスキルセット、組織のセキュリティポリシーによって最適な判断が異なります。しかし、上記で述べたボリュームマウント方式のメリットは、Cloud Runでのシークレット管理戦略を検討する上で重要な考慮点となるでしょう。 安全で効率的なクラウドネイティブ開発を目指す上で、Google Cloud RunとSecret Managerを組み合わせたセキュアなシークレット管理は不可欠な要素です。本稿が、貴社のクラウド環境におけるシークレット管理戦略の策定に役立ち、より堅牢なシステム構築の一助となれば幸いです。 参考資料 Cloud Run にシークレットを構成する – Google Cloud 公式ドキュメント https://cloud.google.com/run/docs/configuring/secrets?hl=ja Secret Manager の概要 – Google Cloud 公式ドキュメント https://cloud.google.com/secret-manager/docs/overview?hl=ja