プリザンター® Pleasanter® は株式会社インプリムの登録商標です。 はじめに 今回は、9/19(金)に名古屋でオフライン開催された「 プリザンターハンズオンセミナー 」に参加してまいりましたので、そのレポートをさせていただきます。 本セミナーは、特にプリザンターを使ったことがない方や、使い始めたばかりの初心者の方向けの内容として構成されており、その基本操作を実際に手を動かしながら体験できる貴重な機会でした。 アイキャッチは当日いただいたアンブレラマーカー、クリアファイル、ステッカーです。 プリザンター® Pleasanter® は株式会社インプリムの登録商標です。 イベントの概要 本セミナーは名古屋にてオフライン形式で開催されました。 開催日時:2025年9月19日(金) 16:30〜18:00 会場:愛知県名古屋市中村区太閤1丁目20-13 秀幸ビル 6階 601号 (オフライン開催) 主催:株式会社インプリム 共催:プレシャスト株式会社 費用:無料 定員:15名(先着順) 60日間無料で全機能を試せるデモ環境 を使ってのハンズオンセミナーでした。 Pleasanter(プリザンター)とは Pleasanterはノーコードで業務アプリを作成できるプラットフォームです。Excelのような親しみやすい操作感で、プログラミングの知識がなくても簡単に業務アプリを作成することができます。顧客管理やプロジェクト管理、日報の管理などの散在しがちな情報を一元化して管理ができることが大きな特長です。 システム導入においても柔軟性が高く、クラウドでの利用はもちろん、インターネットに接続できないオンプレミス環境への導入にも対応しています。 Pleasanterの特徴的な機能 Pleasanterは、業務効率化と情報セキュリティを両立させる多様な機能を備えています。 進捗の可視化 標準機能としてガントチャートやカンバン機能なども搭載されており、業務の進捗状況の可視化、チーム内での情報共有を効率化することができます。 豊富なテンプレート 顧客情報、FAQ、資産管理など、幅広い業務に対応した業務アプリが多数用意されています。 通知・リマインド アプリケーション内の更新情報をメール通知したり、タスクの期日前にリマインド通知を送る設定も可能です。 アクセス制御 個人情報などの機密性の高い情報を、特定の担当者のみが閲覧・編集できるようにアクセス制御が可能です。 プリザンターでできること 成果物の紹介 今回のハンズオンでは案件管理で用いるアプリをプリザンターで作成しました。 ハンズオンでの成果物 今回主に作成したのは「フォルダ」と「テーブル」です。 「フォルダ」は皆さんが普段PCで使っているフォルダをイメージしていただけるとわかりやすいと思います。Pleasanterではテーブルや他のフォルダを格納しツリー構造でデータを管理します。 このフォルダの中にテーブルを作成することができます。テーブルは2種類あり、タスク管理などの期限の管理を行う「期限付きテーブル」と、資産管理などの情報の管理に使用する「記録テーブル」の二つがあります。テーブルの中には「レコード」を登録することができ、各タスクや記録の内容はこのレコードを登録することで管理されます。 今回のハンズオンでは「営業部」という名前のフォルダを作成し、その直下に「商談」という期限付きテーブルと「顧客マスタ」という記録テーブルを作成しました。作成した各テーブル内にレコードを作成し、商談情報や顧客情報を管理できるようにしました。 さらに、実践的な機能として、レコードへの画像の添付、テーブルに親子関係を持たせてのデータ連携、集計やフィルタの設定といった、実際の業務で役立つ操作も実施しました。 参加しての感想と所感 使用した感想としては、フォルダやテーブルの作成、テーブルの管理などの操作が直感的に分かりやすく、技術的な知識がない方でも操作しやすいと感じました。 個人的に便利だと感じたのは、テーブルの設計やレコードの内容を変更した際に更新を忘れるとダイアログが出るため、更新忘れがなく便利だと感じました。 セミナー全体を通して、進行のテンポが適正で、戸惑うことなく自分のペースで手を動かしやすかった点も、主催者様のご配慮を感じるポイントでした。 プリザンターのセミナーは、今回の名古屋開催のように各地で随時開催されております。ご興味をお持ちの方は、ぜひ参加されてみてはいかがでしょうか。 セミナー情報など 参考文献 Pleasanter Pleasanterの活用シーン Pleasanter導入事例 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 【セミナーレポート】プリザンターハンズオンセミナー@名古屋に参加してきました! first appeared on SIOS Tech. Lab .
~史上最大級のnpm自己増殖型ワーム攻撃「Shai-Hulud」とその防御策~ 2025年9月15日、npmリポジトリに対する史上最大級のソフトウェアサプライチェーン攻撃「Shai-Hulud」が発見されました。この攻撃は、わずか1週間で20種類以上の悪意あるOSSパッケージを利用し、200万回以上ダウンロードされた大規模なものです。特にフィンテック企業(コイン取引所、銀行、証券など)が攻撃の対象とされることが多いとされています。 Shai-Huludは、従来の攻撃とは異なり、新しい自己増殖型マルウェア(ワーム)として自己拡散を続けます。攻撃は多段階で実行され、まずフィッシングによって開発者のGitHubやnpmトークンなどの認証情報を盗みます。開発者が感染パッケージをインストールし`postinstall`スクリプトが実行されると、悪意のあるコードが注入されます。 このコードは、環境内の機密データ(GitHubのPAT、SSHキー、AWS、GCP、Azureなどのクラウドプロバイダーのキー)を徹底的にスキャン(クレデンシャルハーベスティング)します。盗まれたデータは複数回エンコードされ、「Shai-Hulud」という名前のパブリックGitHubリポジトリなどに流出します。 最も危険な特徴は、ワームの拡散メカニズムです。有効なnpmトークンを発見すると、それを利用してメンテナが管理する他のパッケージの悪意あるバージョンを公開し、感染をエコシステム全体に広げる自己再生的なサイクルを生み出します。これは、npmエコシステムにおける最初の成功した自己増殖型ワームの一つであり、極めて深刻な脅威をもたらしています。 コミュニティベースのOSSは、その公開性や複雑な依存関係、セキュリティテストの不十分さ、コミュニティ内の信頼の悪用などから、サイバー攻撃の格好の標的となっています。 今回の事件では、多くのJFrogユーザー企業がこのリスクを防げたと報告されています。JFrog Platformは、ソフトウェアサプライチェーンのセキュリティガバナンスを全体的に守る統合プラットフォームであり、以下の主要な機能で防御策を提供します。 1. Curation機能: 悪意のあるパッケージがサプライチェーンに入る前にダウンロードを阻止する即時のガバナンスを提供します。 2. JFrog Xray: 現在の開発環境および本番環境のパッケージをリアルタイムスキャンし、「悪意度スコア」を付与して早期に脅威を発見・対策します。 3. Artifactoryのリモートリポジトリ機能: 外部パッケージリポジトリからのキャッシュを管理し、悪意あるアーティファクトの侵入を防ぎます。 もし影響を受けたパッケージをインストールしていた場合、GitHub、NPM、AWS、GCP、Azureなどで使用していたアクセストークンを直ちに回転させることが必須です。JFrogはこの脅威に対する研究を継続しています。 本記事の詳細は こちら からご確認ください ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 注意喚起:史上最大なNpmソフトウエアサプライチェーン攻撃:Shai-Hulud first appeared on SIOS Tech. Lab .
ここでは、連載形式で公開してきた「Git & GitLab入門」シリーズの記事へのリンクとともに、各回の概要を整理します。 Gitの基本とGitLab / GitHubについて バージョン管理の基盤となるGitの基本概念(リポジトリ、コミットなど)を解説し、そのツールであるGitと、プロジェクトをホストするGitLab/GitHubとの関係性を整理した入門連載の第1回です。 Git & GitLab 入門 (1) ~Git マスターへの道~「Git の基本と GitLab/GitHub」 Git操作入門 GitとVS Codeのインストールやユーザー設定といった環境構築から、ローカルリポジトリ上での変更・ステージング・コミットというバージョン管理の初歩的な操作手順を解説しています。 Git & GitLab 入門 (2) ~Git マスターへの道~「Git操作入門」 Git操作チーム利用コマンドや ロールバック チーム開発で必要となる履歴表示(git log)や差分確認(git diff)、タグ付け(git tag)、バージョン管理対象外の設定(.gitignore)といった操作と、状況に応じて使い分ける必要があるコミットを取り消すコマンド(git revert、git reset、git restore)について解説しています。 Git & GitLab 入門 (3) ~Git マスターへの道~「Git操作チーム利用コマンドや ロールバック」 リモートリポジトリとローカルリポジトリ リモートリポジトリの役割を解説し、SSHキーの登録、プロジェクトの作成、クローン、そしてローカルの変更をリモートへ反映させるadd/commit/pushといったリモートリポジトリとローカルリポジトリの連携操作を解説しています。 Git & GitLab 入門 (4) ~Git マスターへの道~「リモートリポジトリとローカルリポジトリ」 Git のブランチについて Gitのブランチの基本概念と、Git FlowやGitHub Flowなどの主要なブランチ戦略を解説し、チーム開発におけるマージリクエスト(プルリクエスト)の作成からコンフリクトの発生と手動による解消手順までを解説しています。 Git & GitLab 入門 (5) ~Git マスターへの道~「Git のブランチについて」 GitLabの画面説明とよく利用される機能説明 GitLabが提供する「プロジェクト」、CI/CD、セキュリティ機能、Issue管理やマージリクエストといったDevSecOpsライフサイクル全体をカバーする統合プラットフォームとしての主要な機能を、外部ツールとの連携を重視するGitHubとの違いを交えながら解説しています。 Git & GitLab 入門 (6) ~Git マスターへの道~「GitLabの画面説明とよく利用される機能説明」 GitLabのプロジェクトについて GitLabにおけるグループとプロジェクトの関係や、リポジトリとの違いを解説しています。また、マージリクエストやCI/CDを含むプロジェクトの統合的な機能を説明し、ユーザー招待や保護ブランチ、Wikiの設定といった開発を始めるための具体的な初期準備手順を解説しています。 Git & GitLab 入門 (7) ~Git マスターへの道~「GitLabのプロジェクトについて」 GitLabのCICD設定 継続的インテグレーション・継続的デリバリー(CI/CD)の概要を解説し、Kubernetes上にGitLab Runnerをセットアップして連携させた上で、.gitlab-ci.ymlを用いてコンテナイメージのビルド、プッシュ、デプロイメントまでを一貫して自動化するパイプラインの構築手順を解説しています。 Git & GitLab 入門 (8) ~Git マスターへの道~「GitLabのCICD設定」 コードレビューの進め方 GitLabのマージリクエスト(MR)をコードレビューの場として活用する方法を解説しており、レビュアーとレビューイ双方の視点から、レビューを円滑に進めるための具体的な手順(MR設定、コメント、承認、提案の適用)を解説しています。 Git & GitLab 入門 (9) ~Git マスターへの道~「コードレビューの進め方」 GitLabでDevSecOps 開発スピードと安全性を両立する「DevSecOps」の概念と、GitLabがCI/CDパイプラインへのセキュリティスキャン統合を通じてこれを実現し、Hilti社やCarfax社などの具体的な企業事例における開発効率化やセキュリティ向上といった導入成果を解説しています。 Git & GitLab 入門 (10) ~Git マスターへの道~「GitLabでDevSecOps」 この連載を通じて、Git/GitLabを利用した個人・チーム開発のプロセスを体系的に理解することができます。Gitの基本操作はもちろん、CI/CDやDevSecOps機能を組み込んだGitLabの基礎を学ぶことができます。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Git & GitLab 入門 ~Git マスターへの道~「まとめ」 first appeared on SIOS Tech. Lab .
はじめに 昨今、生成AIが流行っているのは言うまでもありません。ChatGPTから始まり、そしてRAG(Retrieval Augmented Generation)と呼ばれる技術が注目され、さらにAIエージェントなんていうのも出てきています。そして、今、最も熱いのはMCP(Model Context Protocol)でしょう。 今回は、そんなMCPのテクノロジーとMoodle(オープンソースの学習管理システム)を組み合わせたMCPサーバーを作成しましたので、その紹介をしたいと思います。以下のGitリポジトリにてソースコードを公開しています。 https://github.com/ntakei-sti/moodle-mcp-server このMCPサーバーは、勉学に励む学生を優しく支えるAIツールです。 ざっくりいってしまうと、例えば下図のようにチャット形式のアプリにこのMCPサーバーを組み込むことで、学生がチャット形式で質問した内容に応じて、Moodleの情報を取得して、回答することができます。 例えば、このチャットみたいに、ちょっと弱気な発言をすると、過去の成績を鑑みて、オススメの教材を提案して励ましてくれたり、締切間近の宿題を忘れないように教えてくれたりします。 MCPサーバーとは? MCPとは、Model Context Protocolの略で、今流行りのAIエージェントに簡単に機能を追加するためのプロトコルです。 AIエージェントに関する詳しい説明は以下の記事を参考にしてください。 https://tech-lab.sios.jp/archives/42867 そして、このMCPというプロコトルに準拠して作成されたサーバーがMCPサーバーです。 では、このMCPサーバーの機能を理解するために、「MCPがない世界」と「MCPがある世界」を比較してみましょう。 MCPがない世界 MCPがない世界では、他のAIエージェントAでとても役立つ機能を使っていたとして、それをいざAIエージェントBで使おうとした場合、AIエージェントB向けにその機能を実装し直す必要があります。 というのは、今まではLLMアプリ(DifyやClaudeなど)はそれぞれ独自の実装方式を持っており、またAIエージェントが使うツールもそれぞれ独自の実装方式をもっており、それぞれの実装方式に合わせて、ツールの方を改修する必要がありました。 例えばAIエージェントAではクラウドストレージにアクセスして、ファイルの一覧や中身を取得する機能があったとしても、AIエージェントBではそのクラウドストレージにアクセスする方法が異なっている場合、AIエージェントB向けにクラウドストレージにアクセスする機能を実装し直す必要があります。 MCPがある世界 MCPがある世界では、AIエージェントAで実装した機能をそのままAIエージェントBでも利用することができます。なぜなら、MCPに準拠したインターフェースを通じて、異なるAIエージェント間で機能を共有できるからです。 ここでは、「MCPサーバーがない世界」で「ツール」と言われていたものは「MCPサーバー」と呼ばれるようになりました。当然「サーバー」と呼ばれるくらいなので、それにラクセスするクライアントである「MCPクライアント」も必要になります。 MCPクライントとMCPサーバーを用意し、その間の通信をMCPに準拠したものにして、MCPサーバー側ではインターネットやクラウドストレージなど各種リソースにアクセスして、MCPクライアントに結果を返すようにします。 このようにして、MCPサーバーを用意することで、異なるAIエージェント間で機能を共有できるようになります。 今回の記事では、MCPの話が本筋ではないので、MCPに関する詳しい説明は割愛します。MCPに関する詳しい説明は以下のYouTubeを参考にしてください。 https://www.youtube.com/live/f7x6flxAfak?si=XDNt7xYWWpaZVHkP Moodleとは? Moodle(ムードル)は、学校や企業の学習をオンラインで運営するための「学習管理システム(LMS)」です。オープンソースで無償利用でき、ブラウザさえあれば受講から課題提出、採点、成績管理まで一通り行えます。 主な登場人物は管理者・教師・学習者の3つになります。 管理者はサイトやユーザーを統括したり、Moodleの基本的な設定(権限管理やメールサーバーなどの設定)を行います。 教師はコース(科目)を作って教材やテストを配置し、学生への各種伝達、課題の提出管理や採点を行います。 学習者は学生のことで、教師からの指示に基づいて、課題などの受講・提出・確認を行います。 ざっくりこんな流れ このMCPサーバーの処理の流れをざっくり説明します。 ① 認証 ユーザーがIdPで認証します。このIdPはKeyCloakやOktaなどのOpenID Connectに対応したものの利用を想定しています。 ② 質問 LLMアプリ(DifyやClaudeなど)で質問します。このとき①で取得したIDトークンをHTTPヘッダー Authorization にセットして、LLMアプリに渡します。 ③ ツール取得 MCPのプロトコルに則り、MCPクライアントからMCPサーバーに対して、利用可能なツールの一覧を取得します。 ④ ツール選定 ③で取得したツール一覧をAzure OpenAI ServiceなどのLLMに渡し、質問に対して適切なツールを選定します。 ⑤ ツール返却 LLMから返却されたツールをLLMアプリが受け取ります。 ⑥ ツール呼び出し LLMアプリがMCPクライアントを通じて、MCPサーバーに対してツールを呼び出します。このとき、②で取得したIDトークンをもとに、MCPサーバーに対して、ユーザー情報を渡します。 ⑦ API実行 MCPサーバーはユーザー情報やコース情報などをもとに、MoodleのREST APIを呼び出して、必要な情報を取得します。 MCPサーバーの基本機能 今回作成したMCPサーバーは、MoodleのREST APIを利用して、Moodleの情報を取得する機能を持っております。具体的には以下の機能を提供しています。 ■ 成績が低い課題のコースに関するファイル一覧を取得 ユーザーの履修コースのうち、成績の回答率が 一定値を下回るコースに添付されたファイルを列挙します。 ■ 未提出の課題の取得 ユーザーの未提出と判定される課題を検索して返します。 ■ ユーザーが履修しているコース一覧の取得 ユーザーが履修しているコースの一覧を取得します。 ■ コース検索 全コースからキーワード検索を行います。表示名(displayname)や概要(summary)も出力に含めます。 ■ 締め切り間近の課題取得 ユーザーの未提出と判定される課題のうち、締め切りが近いものを検索して返します。 MCPサーバーの詳細機能 MCPサーバーのより詳細な機能について説明します。 get_resources_under_specific_grade ユーザーの履修コースのうち、成績の回答率が環境変数 COMPLETION_THRESHOLD を下回るコースに添付されたファイルを列挙します。 ユーザー名は REMOTE_USER 環境変数、または X-Remote-User ヘッダー、あるいは ID トークンで指定します。 get_my_unsubmitted_assignments ユーザーの未提出と判定される課題を検索して返します。課題の提出判定には 環境変数 mod_assign_get_submission_status を優先利用し、 ユーザー名は REMOTE_USER 環境変数、または X-Remote-User ヘッダー、あるいは ID トークンで指定します。 get_my_enrolled_courses ユーザーが履修しているコース一覧を返します。 ユーザー名は REMOTE_USER 環境変数、または X-Remote-User ヘッダー、あるいは ID トークンで指定します。 find_my_courses_by_keyword(keyword) core_course_search_courses を利用して全コースからキーワード検索を行います。表示名(displayname)や概要(summary)も出力に含めます。 get_upcoming_deadlines 環境変数 UPCOMING_DEADLINES_DAYS 日以内に締切が来る課題を集約して返します。 mod_assign_get_assignments を優先して使い、 フォールバックで gradereport から締切を探します。 ユーザー名は REMOTE_USER 環境変数、または X-Remote-User ヘッダー、あるいは ID トークンで指定します。 システム構成 このMCPサーバーで構成することの出来るシステム構成の例をいくつか紹介します。 信頼できるネットワーク内にMCPクライントとMCPサーバーがある場合 この場合、MCPクライアントとMCPサーバーは同じ信頼できるネットワーク内にあるため、つまり、このMCPサーバーにアクセスできるのは、LLMアプリのみのため、HTTPヘッダー X-Remote-User を使ってユーザー名を渡すことができます。 後述するIDトークンを使う場合と比べて、LLMアプリの実装が簡単になります。 信頼できるネットワーク外にMCPクライントとMCPサーバーがある場合 この場合、MCPクライアントとMCPサーバーは同じ信頼できるネットワーク内にはないため、つまり、このMCPサーバーにアクセスできるのは、不特定多数のユーザーが利用する可能性があるため、HTTPヘッダー X-Remote-User を使ってユーザー名を渡すことはできません。 この場合、IDトークンを使ってユーザー名を渡す必要があります。MCPサーバーはIDトークンを検証し、ユーザー名を取得します。 MCPクライアントとMCPサーバーが同じアプリケーションサーバー上にある場合 この場合、MCPクライアントとMCPサーバーは同じアプリケーションサーバー上にあるため、通信方式としてSTDIOを用います。環境変数 REMOTE_USER を使ってユーザー名を渡すことができます。 起動方法 このMCPサーバーはPythonで作成されており、 pip コマンドでインストールして利用します。 事前準備 以下のコマンドを実行して、必要なライブラリをインストールしてください。 $ git clone https://hogehoge.git $ cd moodle-mcp-server $ ppip install -r requirements.txt 環境変数の設定 このプロジェクトは環境変数で各種挙動を制御します。 .env ファイルを作成するか、シェルの環境変数として設定してください。通信方式(MCP_TRANSPORT)により必要な環境変数が異なります。 共通 MOODLE_API_URL (必須): Moodle サイトのベース URL(例: < https://moodle.example.com >) MOODLE_WSTOKEN (必須): Moodle の Webservice トークン COMPLETION_THRESHOLD (任意): 成績の「回答率」閾値(デフォルト 80) UPCOMING_DEADLINES_DAYS (任意): get_upcoming_deadlines が参照する日数ウィンドウ(デフォルト 7) MCP_TRANSPORT (任意): 通信方式。 sse (既定)または stdio SSE モード(MCP_TRANSPORT=sse)もしくはStreamable HTTPモード(MCP_TRANSPORT=streamable-http)で主に使用する変数 MCP_SERVER_HOST (任意): サーバのバインドアドレス(デフォルト 0.0.0.0 ) MCP_SERVER_PORT (任意): サーバのポート(デフォルト 8000 ) ACCEPT_REMOTE_USER_HEADERS (任意): true で X-Remote-User ヘッダを優先(デフォルト true ) Bearer トークン検証を使う場合に必要: OIDC_METADATA_URL : OpenID Provider のメタデータ URL(必須) OIDC_AUDIENCE (任意): 期待する audience OIDC_USERNAME_CLAIM (任意): ユーザー識別子に使うクレーム名(デフォルト sub ) STDIO モード(MCP_TRANSPORT=stdio)で使用する変数 REMOTE_USER (必須): 実行中プロセスで扱う Moodle の username 注意: ACCEPT_REMOTE_USER_HEADERS を有効にする場合、 リモートヘッダは信頼できるプロキシからのみ渡す ようにしてください。 例: `.env` ファイルテンプレート(SSEもしくはStreamable HTTP) MOODLE_API_URL=https://moodle.example.com MOODLE_WSTOKEN=your_moodle_ws_token COMPLETION_THRESHOLD=80 OIDC_METADATA_URL=https://idp.example.com/.well-known/openid-configuration OIDC_AUDIENCE=your-client-id OIDC_USERNAME_CLAIM=preferred_username ACCEPT_REMOTE_USER_HEADERS=true UPCOMING_DEADLINES_DAYS=7 MCP_TRANSPORT=sse MCP_SERVER_HOST=0.0.0.0 MCP_SERVER_PORT=8000 例: `.env` ファイルテンプレート(STDIO) MOODLE_API_URL=https://moodle.example.com MOODLE_WSTOKEN=your_moodle_ws_token REMOTE_USER=your-username MCP_TRANSPORT=stdio 起動 以下のコマンドを実行して、MCPサーバーを起動します。 $ python moodle_mcpserver.py 動作確認 MCP Inspectorというツールを使うと簡単に動作確認ができます。MCP InspectorはMCPサーバーに対して、MCPのプロトコルに則った通信を行うことができるツールです。動作するためにはNode.jsの環境が必要です。 以下のコマンドでMCP Inspectorを起動します。 $ npx @modelcontextprotocol/inspector STDIOで動作確認する場合 まず基本的な設定を行います。 ① Transportで `stdio` を選択します。 ② Commandに `python ` を選択します。 ③ Commandにmoodle_mcp_server.pyのパスを入力します。 ④ `MOODLE_API_URL` 、 `MOODLE_WSTOKEN` 、 `REMOTE_USER` の環境変数を設定します。 MCPサーバーに接続します。 `Connect` ボタンを押します。 ツールの一覧を取得して実行します。 `Tools` タブを選択し(①)、 `List Tools` ボタンを押します(②)。ツールの一覧が取得されます(③)。ツールを選んで、 `Run Tool` ボタンを押すと、ツールが実行されます(④)。 ツールの実行に成功すると、以下のように結果が表示されます。 Stremable HTTPもしくはSSEで動作確認する場合 まず基本的な設定を行います。 ① Transport Typeは、 `Streamable HTTP` もしくは `sse` を選択します。 ② Transport Typeが `Streamable HTTP` の場合、 `http://[MCPサーバーのホスト名]/mcp` を入力します。Transport Typeが `sse` の場合、 `http://[MCPサーバーのホスト名]/sse` を入力します。 ③ HTTPヘッダを追加します。 `ACCEPT_REMOTE_USER_HEADERS` を `true` に設定している場合、 `X-Remote-User` ヘッダーを追加します。IDトークンを使う場合、 `Authorization` ヘッダーを追加します。両方とも値はMoodleのユーザー名です。 ⑤ `Connect` ボタンを押します。 後の手順は、STDIOで動作確認する場合と同様です。 より実践的なシステムを構築 簡単な動作確認が出来たところで、このMCPサーバーを動かすための、より実践的なシステムを構築してみましょう。以下の図がそのシステム構成です。 LLM アプリとして Dify を利用します。Dify は MCP に対応しているため、MCP クライアントとして動作します。 Dify 自体には認証機能がないため、別途チャット UI を提供するアプリケーションサーバーを用意します。ここでは Streamlit を利用します。Streamlit は OpenID Connect に対応しているため、KeyCloak でユーザーを認証した後に ID トークンを取得できます。 ユーザーが認証を終えると、取得した ID トークンが Streamlit に渡され、Streamlit 側でトークンの検証を行い、Moodle のユーザー名を取得します。そのうえで Streamlit から Dify に対して API を呼び出します。Dify は公開 API を提供しており、そこに質問を送ることで回答を得ることができます。この際、ID トークンから取得したユーザー名を API のパラメーターとして渡すことで、Dify がユーザー名を認識できるようにします。 Dify は MCP クライアントとして、MCP サーバーに対して Moodle の情報を取得するためのツール一覧の取得やツール実行を行います。ここから先は MCP のプロトコルに従って通信が進みます。 では構築手順を説明していきます。 KeyCloakの設定 クライアントを作成するために、KeyCloakの管理コンソールにログインし、 `Clients` メニューから、 `Create client` ボタンを押します。 `Client ID` に任意の名称を入力し、 `Next` ボタンを押します。 `Client authentication` を `ON` (①)、 `Authorization` を `OFF` (②)にしてクライアントシークレットによる認証を有効にします。認可コードフローに対応するために、 `Standrd flow` にチェックを入れます(③)。最後に `Next` ボタンを押します(④)。 Valid redirect URIsに `http[s]://[Streamlitのホスト名]/oauth2callback` を入力し(①)、 `Save` ボタンを押します(②)。 クライアントシークレットを確認するために、 `Credentials` タブを選択します(①)。 `Secret` の値を控えておきます(②)。後でStreamlitの設定で利用します。 Streamlitの設定 Streamlitでは、KeyCloakなどのOpenID Connectに対応したIdPを利用して、ユーザー認証を行い、DifyのAPIを呼び出す必要があります。このアプリケーションは、以下のGitHubリポジトリで公開していますので、Cloneして利用してください。 https://github.com/ntakei-sti/streamlit4dify Cloneしたら、まず、 `.env` を以下のように設定します。 `DIFY_API_URL` はDifyのAPIエンドポイントを指定します。 `DIFY_API_KEY` はDifyのAPIキーを指定します。 `OIDC_USERNAME_CLAIM` はKeyCloakのユーザー名に対応するクレーム名を指定します。KeyCloakのデフォルトでは `preferred_username` ですが、環境によって異なる場合がありますので、適宜変更してください。 DIFY_API_URL=http[s]://<Difyのホスト名>/v1/chat-messages DIFY_API_KEY=<DifyのAPIキー> OIDC_USERNAME_CLAIM=<KeyCloakのユーザー名に対応するクレーム名> 次に、 `secrets.toml` を以下のように設定します。 `redirect_uri` はKeyCloakのクライアント設定で指定した `Valid redirect URIs` を指定します。 `cookie_secret` は任意の文字列を指定します。 `client_id` はKeyCloakのクライアントIDを指定します。 `client_secret` はKeyCloakのクライアントシークレットを指定します。 `server_metadata_url` はKeyCloakのメタデータURLを指定します。 [auth] redirect_uri = "http[s]://<Streamlitのホスト名>/oauth2callback" cookie_secret = "<任意の文字列>" client_id = "<KeyCloakのクライアントID>" client_secret = "<KeyCloakのクライアントシークレット>" server_metadata_url = "http[s]://<KeyCloakのホスト名>/realms/<レルム名>/.well-known/openid-configuration" Streamlitアプリケーションを起動します。 $ streamlit run app.py Dify設定 まず、DifyのマーケットプレイスからMCPプラグインをインストールします。Difyの管理コンソールにログインし、 `Plugins` メニューから、 `Agent Strategies` のプラグインをインストールします。 そして、ワークフロー内でMCPプラグインを利用するように設定します。 `Agent` というブロックが追加出来るようになっているので、これをワークフローに追加します。 `Agentic Strategy` は `Function Calling (Support MCP Tools)` を選択します(①)。 `MCP SERVERS CONFIG` は、以下のように設定します(②)。 { "server_name1": { "transport": "sse", "headers": { "X-Remote-User": 🏡Start/{x}sys.user_id }, "url": "http[s]://<MCPサーバーのホスト名>/sse" } } `INSTRUCTIONS` は以下のように設定します(③)。このシステムメッセージを定義することにより、ユーザーの弱気な発言を拾って、Moodleの情報を取得して、優しく励ますことができます。 あなたはmoodleからいろんな情報を取得する賢いエージェントです。 ユーザーが、「成績が出なくて困った」などの類の弱気な趣旨の質問をした場合には、ツールget_resources_under_specific_gradeを呼んでください。その回答は、成績が思わしく無いコースの資料ですので、それらの資料を優しく提案してあげてください。 MCPサーバーの設定 MCPサーバーを起動します。起動するための環境変数の説明は説明済みですので割愛します。今回の構成では、通信方式をSSE、MCPサーバーはDifyからのみアクセスされることを前提として、 `ACCEPT_REMOTE_USER_HEADERS` を `true` に設定します。以下は `.env` ファイルの例です。 MOODLE_API_URL=<MoodleのURL> MOODLE_WSTOKEN=<MoodleのWebサービスのトークン> COMPLETION_THRESHOLD=80 MCP_TRANSPORT=sse ACCEPT_REMOTE_USER_HEADERS=true MCPサーバーを起動します。 $ python moodle_mcp_server.py 動作確認 Streamlitのアプリケーションにアクセスします。KeyCloakのログイン画面が表示されるので、ユーザー名とパスワードを入力してログインします。 KeyCloakのログイン画面が表示されるので、ユーザー名とパスワードを入力してログインします。 ログインに成功すると、チャット画面が表示されます。チャット画面で質問を入力して、 `Send` ボタンを押します。 まとめ いかがでしたでしょうか?勉学に励む学生を優しく包むAIって素敵ですね。ときに厳しく、そして特に優しく、学生を支えるMoodle対応のMCPサーバーをぜひご活用ください。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 生成AIの学術利用を加速する!!勉学に励む学生を優しくサポートするMoodle対応のMCPサーバーを作りました!! first appeared on SIOS Tech. Lab .
はじめに 前回の記事では、GitLabとOpenShift、Gatekeeperを組み合わせたDevSecOpsモデルケース環境の構築方法を紹介しました。 本記事では、それらを組み合わせて閉域環境におけるDevSecOpsモデルケースを構築し、デモアプリを使ってCI/CDの流れにセキュリティがどのように組み込まれるのかを確認します。 金融や公共分野など高いセキュリティ要件が求められるシステムでは、インターネット非接続の環境であっても、開発のスピードと安全性を両立することが求められます。 GitLabとGatekeeperを活用することで、この課題をどのように解決できるのかを具体的に示すのが今回の目的です。 DevSecOpsとは、DevOpsの迅速な開発・運用プロセスに「セキュリティ」を組み込み、スピードと安全性を両立させる手法です。従来は「開発が完了した後にセキュリティチェックを行う」ことが一般的でした。しかしこの方法では、最終段階で脆弱性が見つかった際に大きな修正が必要となり、時間やコストの増大、リリースの遅延を招いてしまいます。 DevSecOpsでは、開発ライフサイクルの各段階にセキュリティを統合することで、早い段階からリスクを検知し、小規模な修正で対処できます。その結果、開発のスピードを維持しながら、コスト削減と安全性の向上を同時に実現できます。 DevSecOpsは、下図のように開発(Dev)と運用(Ops)のライフサイクルにセキュリティ(Sec)を組み込む考え方です。 DevSecOpsの詳細については以下の記事で解説していますので、ご参照ください。 DevSecOpsとは?安全性とスピードを両立する開発手法 | SIOS Tech. Lab 本記事のデモは、以下の流れで進めます。 ゴール 本記事のゴールは次のとおりです。 DevSecOpsのライフサイクルを実際のCI/CDパイプラインを通じて理解する GitLabとGatekeeperを組み合わせたセキュリティ統制の仕組みを把握する 前提条件 本記事のデモンストレーションは、以下の環境を前提としています。 GitLab サーバー(ソースコード管理・CI/CD実行) OpenShift クラスター(閉域環境にて構築済み、アプリケーション実行環境) GitLab Runner(OpenShift 内にデプロイ済み) Gatekeeper(OpenShift 内にデプロイ済み、リソース作成許可ポリシーを定義済み) 踏み台サーバー(クラスターへのアクセス用) これらは前回の記事「 構築編 」で構築したモデルケース環境に含まれています。 構築手順の詳細は「構築編」を参照してください。 デモアプリの仕様 ベースイメージ:nginx サービス提供ポート:8080 到達性:内部ネットワークのみアクセス可能(外部公開なし) デプロイ方式:Helm(Chart・valuesでイメージタグを切り替え) デモで使用するタグ:v1.0(初回デプロイ)、v1.1(修正デプロイ) パイプラインの実行フロー 今回利用するCI/CDパイプラインの実行フローは以下の通りです。 ビルド用パイプライン実行フロー 開発者がGitLabのビルド用プロジェクトにブランチをマージ マージをトリガーとして、GitLab CI/CDパイプラインが起動 GitLab CI/CDからOpenShiftクラスター内のGitLab Runnerへビルドジョブ実行リクエストを送信 RunnerがジョブPodを起動 ジョブPodがビルド用プロジェクトからアプリのソースコードをClone ジョブPodがdocker CLIなどを利用してコンテナイメージをビルド ジョブPodがビルドしたイメージをGitLabのビルド用プロジェクト内のレジストリにpush デプロイ用パイプライン実行フロー 開発者がGitLabのデプロイ用プロジェクトにブランチをマージ マージをトリガーとして、GitLab CI/CDパイプラインが起動 GitLab CI/CDからOpenShiftクラスター内のGitLab Runnerへデプロイジョブ実行リクエストを送信 RunnerがジョブPodを起動 ジョブPodがOpenShiftのAPIサーバーに対し、リソースのデプロイリクエストを送信 APIサーバーがGitLabのレジストリからアプリのイメージをpull APIサーバーがOpenShiftクラスター内にアプリをデプロイ DevSecOpsのデモンストレーション ここからは、構築済みのモデルケース環境を使って、実際にDevSecOpsの流れを確認します。 以下のように、アプリのデプロイを2回繰り返し、最後にGatekeeperによる制御を体験します。 アプリの初回アップロード(v1.0 デプロイ) アプリを修正して再度デプロイ(v1.1 デプロイ) Gatekeeperによる不正リソース作成の拒否 アプリケーションの初回デプロイ ここからは、DevSecOpsライフサイクルのCode → Operate(1週目)に対応します。 まず、アプリの初回デプロイを行います。 コードを ビルド用プロジェクト のfeatureブランチにpushし、developブランチへマージします。 developブランチにマージすると、コンテナイメージをビルドするパイプラインが起動します。 この操作によって、開発用のイメージ(dev-v1.0)がビルドされます。 続いて、 デプロイ用プロジェクト のfeatureブランチをdevelop ブランチへマージします。 これにより、先ほどビルドされたv1.0イメージを利用して、開発用Namespaceにアプリがデプロイされます。 $ oc get pod -n devsecops-develop -l app="nginx" NAME READY STATUS RESTARTS AGE nginx-deployment-5d75b659c5-cqbqp 1/1 Running 0 118s 動作確認が完了したら、ビルド用プロジェクトのdevelopブランチからmainブランチへのマージリクエストを作成し、承認後にマージします。 mainブランチにマージすると、パイプラインが起動し、prod-v1.0イメージがレジストリに格納されます。 次にデプロイ用プロジェクトでdevelopブランチをmainブランチにマージすると、パイプラインが起動し、本番環境用のネームスペースにアプリをデプロイします。 その結果、本番環境にアプリがデプロイされ、表示内容を確認できれば、 Code → Operate の1週目(v1.0)が完了 です。 $ oc get pod -n devsecops-production -l app="nginx" NAME READY STATUS RESTARTS AGE nginx-deployment-6c49676b47-m96pf 1/1 Running 0 29s nginx-deployment-6c49676b47-pzv96 1/1 Running 0 29s アプリケーションを修正して再度デプロイ ここからは、DevSecOpsライフサイクルのCode → Operate(2週目)に対応します。 アプリを修正します。ここではindex.htmlの内容を更新し、あわせて.gitlab-ci.ymlで定義しているコンテナイメージのタグをv1.1に変更します。 次に、 ビルド用プロジェクト のfeatureブランチにpushし、developブランチへマージします。 この操作によって、新しい開発用イメージ(v1.1)がビルドされます。 続いて、 デプロイ用プロジェクト のfeatureブランチでConfig/develop-values.yamlと Config/product-values.yamlのtagを修正し、反映します。その後、同様にdevelopブランチ へマージして変更を適用します。 これにより、先ほどビルドされたv1.1イメージを利用して、開発用Namespaceにアプリがデプロイされます。 $ oc describe pod -n devsecops-develop nginx-deployment-54d94596b6-8j8w6 | grep "Image:" Image: registry.gitlab.local.example.com/devsecops-user/devsecops-build-project/nginx:dev-v1.1 動作確認が完了したら、developブランチからmainブランチへのマージリクエストを作成し、承認後にマージします。 その結果、本番環境に修正版アプリがデプロイされ、表示内容が更新されていることを確認できます。 $ oc describe pod -n devsecops-production nginx-deployment-59ddc6dbb6-lhd6b | grep "Image:" Image: registry.gitlab.local.example.com/devsecops-user/devsecops-build-project/nginx:prod-v1.1 この時点で、 Code → Operate の2週目(v1.1)が完了 です。 Gatekeeperによる不正リソースの検知・拒否 ここからは、DevSecOpsライフサイクルのSecに対応します。 最後に、あえて不正な設定を持つリソースをNamespaceにデプロイしてみます。 Gatekeeperのポリシー設定で、 envラベルの値がデプロイ先のnamespace名と一致していないとPodの作成を許可しない 制約 を設定しています。 以下のように、 デプロイ用プロジェクト でdeploymentのlabelsでenvラベルを不正な値に書き換える修正を行い、developブランチにマージします。 このときGatekeeperのポリシーが働き、不正なリソースの作成は拒否されます。 実際のログやイベントを確認すると、Constraint によって違反が検出され、Podのデプロイが失敗していることが分かります。 一番下のReplicaSetはDesired 1に対して、Currentが0であり、Podがデプロイされていないことがわかります。 $ oc get replicasets.apps -n devsecops-develop NAME DESIRED CURRENT READY AGE nginx-deployment-54d94596b6 1 1 1 20m nginx-deployment-5d75b659c5 0 0 0 14h nginx-deployment-6bfd599796 1 0 0 3m48s PodがデプロイされていないReplicaSetのイベントを確認すると、Gatekeeperの 制約テンプレート で設定したエラーメッセージが表示されていることがわかります。 $ oc describe replicasets.apps -n devsecops-develop nginx-deployment-6bfd599796 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedCreate 4m13s replicaset-controller Error creating: admission webhook "validation.gatekeeper.sh" denied the request: [require-env-label-match-namespace] Pod 'nginx-deployment-6bfd599796-z7hgf' の 'env' ラベルの値は、Namespace名 'devsecops-develop' と一致する必要があります。現在の値は 'dummy-env' です。 このように、 開発者が意識しなくてもポリシー違反が自動的にブロックされる ことで、セキュリティを犠牲にせずに CI/CD のスピードを維持できることを体験できます。 まとめ 本記事では、GitLab、OpenShift、Gatekeeperを組み合わせて閉域環境にDevSecOpsモデルケースを構築し、デモアプリを用いて以下の流れを確認しました。 GitLab CI/CDによるアプリケーションデプロイの自動化 コード変更からの継続的デリバリー Gatekeeperポリシーによるセキュリティ担保 このデモを通じて、次のポイントを押さえることができました。 DevOpsだけでは不十分 開発サイクルが迅速化しても、不正なリソースや設定が混入すれば安全性は損なわれる。 ポリシー制御の仕組みが重要 Gatekeeperを用いることで、開発の初期段階から不正なリソースを自動的に排除できる。 GitLabとOpenShiftの統合は実用的 インターネット非接続の閉域環境でも再現可能であり、金融・公共分野を含む実案件にも応用できる。 さらに実環境での利用を考えるなら、コンテナイメージのセキュリティスキャンや、より複雑なポリシー制御を組み合わせることで、より強固なDevSecOpsを実現できます。 まずは小規模なモデルケースから試し、徐々に自社の環境や要件に合わせて拡張していくことをおすすめします。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post DevSecOps実践ガイド:セキュアなCI/CD運用の実践編 first appeared on SIOS Tech. Lab .
はじめに 前回までに、GitLabとOpenShift、Gatekeeperを閉域環境で構築する手順を紹介しました。 本記事では、その環境を基盤としてGitLabのプロジェクト作成や設定を追加し、CI/CDパイプラインとポリシー検証を組み合わせたDevSecOpsの実践例に向けた環境構築を行います。 特に、金融や公共分野のように高いセキュリティ要件が求められるシステムでは、インターネット非接続環境での開発・運用が前提となるケースが多くあります。本記事で取り上げる構成は、そうした制約下でも有効な実践例となります。 なお、本記事では構築の全手順を網羅するのではなく、モデルケースの全体像と主要な構成要素を中心に解説します。詳細な設定値やコードについては、 こちらのリポジトリ をご参照ください。 ゴール GitLabにビルド用・デプロイ用プロジェクトを作成する OpenShiftのNamespaceや権限を設定する Gatekeeperのポリシーを適用し、CI/CDパイプライン実行時にポリシー違反を検知できるようにする 次回のデモ実演に向けた基盤を完成させる DevSecOpsとは? DevSecOpsとは、DevOpsの迅速な開発・運用プロセスにセキュリティを統合することで、スピードと安全性を両立する手法です。 従来の「開発の後にセキュリティチェックを行う」アプローチではなく、開発ライフサイクルの各段階にセキュリティを組み込む点が特徴です。 詳細については以下の記事で解説していますので、ご参照ください。 DevSecOpsとは?安全性とスピードを両立する開発手法 | SIOS Tech. Lab 前提条件 以下の記事の手順に従って、環境構築が完了していること GitLabとコンテナプラットフォームの連携 | SIOS Tech. Lab OPA/Gatekeeperで始める安心OpenShift運用:構築編 デモアプリの仕様 ベースイメージ:nginx サービス提供ポート:8080 到達性:内部ネットワークのみアクセス可能(外部公開なし) デプロイ方式:Helm(Chart・valuesでイメージタグを切り替え) サンプル構成の全体像 プロジェクトの分割方針 devsecops-build-project(ビルド用) ソースコードとDockerfileを管理し、イメージをビルドしてGitLab Container Registryにpushします。 devsecops-deploy-project(デプロイ用) Helmチャートと環境別のvaluesファイルを管理し、Registryのイメージを参照してOpenShiftにデプロイします。 このように ビルドとデプロイを分けることで、開発コードの管理とデプロイ設定の管理を明確に切り分けられるようにしています。 リポジトリ構成(概要) ビルド用リポジトリ Containerfileとsrc/ : Nginxベースのアプリ .gitlab-ci.yml : イメージビルド&レジストリへpush デプロイ用リポジトリ devsecops-nginx-chart/ : Helmチャート develop-values.yamlとproduct-values.yaml : 環境別設定 .gitlab-ci.yml : Helmを使ったOpenShiftへのアプリのデプロイ ※詳細なディレクトリとファイル内容は こちらのリポジトリ をご覧ください。 ブランチ戦略 feature/* : 開発作業用ブランチ develop : 開発環境に対応 main : 本番環境に対応 feature → develop → main の流れでレビューを経たマージを行い、保護ブランチ設定によりdevelopやmainブランチへの直接pushは禁止しています。 パイプラインの流れ ビルドパイプライン(build-project) ソースコード変更を検知 Runnerがイメージをビルドし、レジストリにpush デプロイパイプライン(deploy-project) Helm設定変更を検知 Runnerがレジストリのイメージをpullし、OpenShiftにデプロイ Gatekeeperがポリシーを検証し、違反があればリソース作成を拒否 構築手順(概要) 手順の流れ 今回のサンプルケースでは以下の構成要素を準備します。 GitLabユーザー作成 ソースコード用プロジェクトの作成 デプロイ用プロジェクトの作成 OpenShift側のNamespaceと権限設定 Gatekeeperのポリシー設定 1. GitLabユーザー作成 管理者アカウントでGitLabにログインし、プロジェクト管理用ユーザーを作成します。 今回使用するプロジェクトのネームスペースはここで作成したユーザー名を指定します。 続いて、作成したプロジェクト管理用ユーザー(devsecops-user)にSSHキーを登録し、Gitでのアクセスを確認します。 作成したプロジェクト管理用ユーザーでログインし、サイドメニューからアバターアイコンを選択→[プロファイルを編集]をクリックして、ユーザー設定画面に移動します。 ユーザー設定画面のサイドメニューで[SSHキー]を選択し、このユーザー用に作成した公開鍵を登録します。 例:SSHキー生成とGitLab接続確認 $ ssh-keygen -t rsa -b 4096 -C "devsecops-user@gitlab.local" $ ssh -T git@gitlab-private.example.local 2. ソースコード用プロジェクト 先ほど作成したプロジェクト管理用ユーザーでログインし、GitLabで新規プロジェクトを作成します。 このプロジェクトはイメージのビルドとレジストリへのイメージ保存を担当します。 プロジェクト作成の詳細な手順は弊社ブログ記事 Git & GitLab 入門 (7) ~Git マスターへの道~「GitLabのプロジェクトについて」 | SIOS Tech. Lab をご参照ください。 続いて、作成したビルド用プロジェクト内でmain と develop ブランチを用いし、保護ブランチの設定を行います。 ブランチの保護設定を行うことで、mainブランチ及びdevelopブランチへの直接pushを防止し、パイプラインの誤動作を防止します。 ブランチ保護設定手順の詳細につきましても、弊社ブログ記事 Git & GitLab 入門 (7) ~Git マスターへの道~「GitLabのプロジェクトについて」 | SIOS Tech. Lab に記載しておりますので、ご参考になれば幸いです。 任意の開発者用ユーザーを作成し、プロジェクトにDeveloper権限で追加します。このユーザーはプロジェクト内でコードをコミットしたり、パイプラインを操作するために利用します。 プロジェクトにユーザーを招待する方法や主要なユーザー権限につきましては、 Git & GitLab 入門 (7) ~Git マスターへの道~「GitLabのプロジェクトについて」 | SIOS Tech. Lab に記載しておりますのでご参照ください。 プロジェクトに追加した開発用ユーザーでログインし、サンプルのアプリコードをリポジトリのfeatureブランチにpushし、管理を開始します。 アプリのベースイメージ(nginx:latestなど)をGitLab Container Registryにpushします。 ※この記事では、OpenShiftの環境を使用しているため、コンテナ管理ツールとしてPodmanを利用しています。Dockerを利用している環境ではpodman→dockerに読み替えてください。 $ podman login registry.gitlab.local.example.com $ podman pull nginx:latest $ podman tag nginx:latest registry.gitlab.local.example.com/devsecops-user/devsecops-build-project/nginx:latest $ podman push registry.gitlab.local.example.com/devsecops-user/devsecops-build-project/nginx:latest 参考: Git & GitLab 入門 (7) ~Git マスターへの道~「GitLabのプロジェクトについて」 | SIOS Tech. Lab 3. デプロイ用プロジェクト プロジェクト管理用ユーザーでGitLabにログインし、今度はデプロイ用のGitLabプロジェクトを新規作成します。 このプロジェクトはレジストリのイメージを参照し、Helmを用いてOpenShiftにデプロイする役割を担います。 ビルド用プロジェクトを作成した時と同様に、mainとdevelopブランチに保護設定を行います。 今回はデプロイ手段としてHelmチャートを利用するため、このプロジェクトのレジストリにHelmが利用可能なコンテナイメージを格納します。 ※この記事では、OpenShiftの環境を使用しているため、コンテナ管理ツールとしてPodmanを利用しています。Dockerを利用している環境ではpodman→dockerに読み替えてください。 $ podman login registry.gitlab.local.example.com $ podman pull docker.io/alpine/helm:3 $ podman tag docker.io/alpine/helm:3 \ registry.gitlab.local.example.com/root/test-project/helm:3 $ podman push registry.gitlab.local.example.com/root/test-project/helm:3 デプロイ用プロジェクトのレジストリにHelmイメージを格納しておくと、パイプライン内で実行されるジョブPodのイメージを指定できます。この指定は、パイプライン定義ファイル(.gitlab-ci.yml)のimageプロパティで行います。 .default_deploy: &default_deploy stage: deploy image: registry.gitlab.local.example.com/devsecops-user/devsecops-deploy-project/helm:3 before_script: - set -euo pipefail - helm version - | if [ -n "${K8S_NAMESPACE:-}" ]; then HELM_NS_ARG="-n ${K8S_NAMESPACE}" else echo "K8S_NAMESPACE variable not provided. Helm will use the current context's namespace." HELM_NS_ARG="" fi - helm dependency update "$HELM_CHART_DIR" || true 今回使用するデプロイ用パイプラインは、ブランチに応じてデプロイ先のネームスペースを決定します。 たとえば、developブランチにマージした時はdevsecops-developネームスペースにアプリをデプロイし、mainブランチにマージした時はdevsecops-productionネームスペースにアプリをデプロイするなどの制御を行います。 deploy_develop: <<: *default_deploy tags: - devsecops-runner variables: <<: *common_vars VALUES_ENV: "deploy/Config/develop-values.yaml" K8S_NAMESPACE: "$DEPLOY_PROJECT_NAME_DEVELOP" rules: - if: '$CI_COMMIT_BRANCH == "develop" && $CI_PIPELINE_SOURCE == "push"' environment: { name: develop, deployment_tier: development } script: - | set -euo pipefail : "${HELM_RELEASE:=devsecops-nginx}" : "${HELM_CHART_DIR:=deploy/devsecops-nginx-chart}" : "${VALUES_COMMON:=deploy/devsecops-nginx-chart/values.yaml}" : "${VALUES_ENV:?VALUES_ENV must be set}" test -f "${HELM_CHART_DIR}/Chart.yaml" || { echo "Chart.yaml not found under ${HELM_CHART_DIR}"; exit 1; } echo "[RUN] helm upgrade --install ${HELM_RELEASE} ${HELM_CHART_DIR} ${HELM_NS_ARG} -f ${VALUES_COMMON} -f ${VALUES_ENV}" helm upgrade --install "${HELM_RELEASE}" "${HELM_CHART_DIR}" ${HELM_NS_ARG} -f "${VALUES_COMMON}" -f "${VALUES_ENV}" deploy_production: <<: *default_deploy tags: - devsecops-runner variables: <<: *common_vars VALUES_ENV: "deploy/Config/product-values.yaml" K8S_NAMESPACE: "$DEPLOY_PROJECT_NAME_PRODUCTION" rules: - if: '$CI_COMMIT_BRANCH == "main" && $CI_PIPELINE_SOURCE == "push"' allow_failure: false environment: { name: production, deployment_tier: production } script: - | set -euo pipefail : "${HELM_RELEASE:=devsecops-nginx}" : "${HELM_CHART_DIR:=deploy/devsecops-nginx-chart}" : "${VALUES_COMMON:=deploy/devsecops-nginx-chart/values.yaml}" : "${VALUES_ENV:?VALUES_ENV must be set}" test -f "${HELM_CHART_DIR}/Chart.yaml" || { echo "Chart.yaml not found under ${HELM_CHART_DIR}"; exit 1; } echo "[RUN] helm upgrade --install ${HELM_RELEASE} ${HELM_CHART_DIR} ${HELM_NS_ARG} -f ${VALUES_COMMON} -f ${VALUES_ENV}" helm upgrade --install "${HELM_RELEASE}" "${HELM_CHART_DIR}" ${HELM_NS_ARG} -f "${VALUES_COMMON}" -f "${VALUES_ENV}" デプロイ用パイプラインが読み取れるCI/CD変数を登録します。 プロジェクト画面のサイドメニューから[設定] > [CI/CD]を選択し、[変数]のメニューを展開します。 [変数を追加]をクリックすると、CI/CDパイプラインが利用可能な環境変数を定義することができます。今回の例では、環境別のネームスペース名であるDEPLOY_PROJECT_NAME_DEVELOPとDEPLOY_PROJECT_NAME_PRODUCTIONを定義しています。他にも外部サービスのAPIキーなどを登録するなどの利用が可能です。 上記の作業が完了した後、デプロイ用のHelmチャートやマニフェストをfeatureブランチにpushします。 4. OpenShift設定 開発用 (develop) と本番用 (production) のNamespaceを作成し、ラベルを付与します。 ※tagのenvにはdevやprodなどデプロイ先の環境名を指定しています。 $ oc create namespace <namespace> $ oc label namespace <namespace> tag=<env> GitLab Runner用のServiceAccountを作成し、必要なRBAC権限とSCCを付与します。 開発用 (develop) と本番用 (production) のNamespaceのGitLab Runner用のServiceAccountに必要なRBAC権限を付与 GitLab Container RegistryへのPull SecretをNamespaceに登録します。 自己署名証明書を利用している場合はCA証明書をSecretとして登録します。 開発用 (develop) と本番用 (production) のNamespaceのdefault ServiceAccountにanyuidのSCCを付与します。 GitLab Runner用のNamespaceのServiceAccountにデプロイ先namespaceでのedit権限を付与します。 5. Gatekeeper設定 必要なConstraintTemplateを作成します(例:イメージタグに特定文字列を含める、Namespaceとラベルが一致していることなど)。 今回作成したポリシールールは こちらのリポジトリ をご参照ください。 開発環境、本番環境それぞれを対象としたConstraintsを作成します。 oc get コマンドでConstraintTemplateとConstraintsが正しく反映されていることを確認します。 参考: OPA/Gatekeeperで始める安心OpenShift運用:設定編 まとめ ここまでで、GitLabのビルド・デプロイ用プロジェクト、OpenShiftのNamespace設定、Gatekeeperのポリシー適用といった要素が揃い、セキュリティを組み込んだCI/CD基盤のモデルケースが完成しました。これにより、ソースコードの変更がパイプラインを通じて自動的にビルド・デプロイされるだけでなく、Gatekeeperによるポリシー検証によって不適切なリソースの作成を未然に防ぐことが可能になります。 本記事で紹介した構成は、高いセキュリティ要件が求められるシステムにおいても有効なアプローチです。次回の記事では、この環境を活用して実際のパイプライン実行からポリシー違反検知までの一連の流れをデモンストレーションします。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post DevSecOps実践ガイド:CI/CD環境の構築編 first appeared on SIOS Tech. Lab .
はじめに 前回 までは、GitとGitLabの具体的な機能や操作方法を入門者向けに解説してきました。 今回は、GitLabの根幹となる「DevSecOps」という考え方を中心に解説します。近年のソフトウェア開発では、開発のスピードを上げつつ、セキュリティを確保することが不可欠です。この相反する課題を解決するために必要なアプローチが「DevSecOps」です。 このDevSecOpsをGitLabがどのように実現しているのか、そしてそれがどのようなメリットを生み出すのかを、公式事例を交えて具体的に解説します。 DevOpsとは? まず、DevSecOpsを理解するために、その土台となるDevOpsについて解説します。 DevOpsは、開発チーム(Development)と運用チーム(Operations)が連携し、アプリケーションのビルドからテスト、デプロイ、リリースまでのプロセスを自動化し、高速化する取り組みです。これにより、新しい機能を素早く提供し、顧客のフィードバックに迅速に対応することが可能になります。 DevSecOpsとは? DevSecOpsとは、DevOpsの迅速な開発・運用プロセスにセキュリティを統合することで、スピードと安全性を両立する手法です。 従来の「開発の後にセキュリティチェックを行う」アプローチではなく、開発ライフサイクルの各段階にセキュリティを組み込む点が特徴です。 開発の最終段階で脆弱性が発見されると、その修正には時間とコストがかかり、リリースの遅延につながります。DevSecOpsは、このような手戻りをなくすために、早い段階で問題を検知し、小さな修正で済ませることを目指します。これにより、開発のスピードを保ちつつ、コスト削減と安全性の向上を同時に実現できます。 詳細については以下の記事で解説していますので、ご参照ください。 DevSecOpsとは?安全性とスピードを両立する開発手法 | SIOS Tech. Lab GitLabでのDevSecOpsの扱い GitLabは、DevOpsの統合プラットフォームであるため、DevSecOpsを体現したツールです。 GitLabはCI/CDパイプラインにセキュリティスキャン機能を組み込むことが可能です。開発者は、追加のツールや設定をすることなく、以下の代表的なセキュリティ機能をCI/CDパイプラインに含めることができます。 静的アプリケーションセキュリティテスト(SAST):コードをビルドする前に、ソースコードに存在する脆弱性を自動で検知します。 認証情報検知(Secret Detection):コード内に誤ってコミットされたAPIキーやパスワードなどの機密情報を自動で検出します。 依存関係スキャン(Dependency Scanning):プロジェクトが使用しているライブラリやフレームワークに既知の脆弱性がないかをチェックします。 これらのスキャン結果は、マージリクエスト画面にCI/CDパイプラインの実行結果として直接表示されるため、レビュー時にコード品質とセキュリティの両方を一度に確認できます。 参考: Git & GitLab 入門 (6) ~Git マスターへの道~「GitLabの画面説明とよく利用される機能説明」 GitLab公式で提示しているDevSecOpsの事例について GitLabのDevSecOps機能は、規模を問わず多くの企業で成果を上げています。ここでは、GitLabの公式事例からそのメリットを具体的に見てみましょう。 参考: https://about.gitlab.com/ja-jp/customers/ エンタープライズ事例:Hilti社(デプロイ時間の短縮) 建設業界の大手であるHiltiは、以前、ソフトウェア開発の一部を外部に委託しており、社内でのコード管理やCI/CD体制が十分に整っていませんでした。そのため、バグや脆弱性への対応が後手に回り、セキュリティ上のリスクやコード品質の低下が課題となっていました。 これらの課題を解決し、セキュリティスキャンを最優先にソフトウェア開発を社内化するため、統合のしやすさ、SCM (Source Code Management)、豊富なSAST/DAST等のセキュリティ機能を理由にGitLab Ultimateを採用しました。 GitLab導入の具体的な成果として、デプロイ時間が平均3時間からわずか15分に短縮されました。これは、以下が大きな要因です。 開発・テストチームがコードを管理し、脆弱性を事前に発見できるようになった フィードバックループが6日から3日に短縮されたこと コードチェック頻度が3か月6回から週2回に増加 これにより、Hiltiはセキュリティ、コード品質、開発効率、チームコラボレーションを大幅に向上させることができました。 参考: https://about.gitlab.com/customers/hilti/ ミッドマーケット事例:Carfax社(脆弱性の早期発見) 自動車履歴データベースを提供するCarfaxは、以前、複数のDevOpsツールチェーンの維持管理をするため、多くの時間やコストがかかっていました。さらに、開発ライフサイクル後半の手動による脆弱性スキャンで問題が発覚することが多く、迅速な修正が難しい状況でした。 より早い段階でセキュリティリスクを検知したいという課題から、GitLabのDevSecOpsプラットフォームを採用しました。Carfaxは導入後6ヶ月以内に、コードをGitLabに移し、GitLabのセキュリティスキャンを活用し始めました。 GitLabの自動セキュリティ機能(依存関係スキャン、コンテナスキャン、シークレット検出など)を導入することで、Carfaxは1年間で脆弱性の約3分の1を開発ライフサイクルのかなり早い段階で発見できるようになりました。これにより、開発チーム全体がソフトウェアライフサイクルの最も早い段階からセキュリティを考慮する「シフトレフト」を実現し、問題の修正にかかる時間とコストを大幅に削減し、セキュリティを向上させました。 参考: https://about.gitlab.com/customers/carfax/ 中小企業(SMB)事例:Jasper Solutions社(オールインワンの利点) 政府・民間向けのソフトウェア開発を行うJasper Solutionsは、以前、 複数の個別ツールを組み合わせた開発パイプラインを利用していましたが、個々のツールのバージョンアップが原因でパイプラインが頻繁に機能しなくなり、開発チームは顧客向けのコード開発よりもその修正に多くのリソースを割かなければなりませんでした。 こうした運用負荷を根本から解決するため、GitLabをCI/CD、SCMを統合した「オールインワン」プラットフォームとして採用しました。 GitLabの「オールインワン」プラットフォームにより、パイプラインの破損がほぼなくなり、単一のアップグレードでパイプライン全体が常に最新の状態に保たれるため、開発チームはアプリケーション開発に集中できるようになりました。この統合によって、以下の具体的なメリットが生まれています。 1製品あたり年間平均約350人時の作業時間を削減 個別のツールを維持管理する費用と比較して年間33〜37%のコスト削減 サイクルタイムが30%短縮され、デプロイ頻度が25%向上 Jasper Solutionsは、GitLabの「オールインワン」の利点を最大限に活用することで、複数のツールチェーンの維持管理から解放され、開発への集中と運用コストの削減を同時に実現できました。 参考: https://about.gitlab.com/customers/jasper-solutions/ GitLabのDevSecOpsを導入することによって、Hilti社ではデプロイ時間の短縮、Carfax社では脆弱性の早期発見、Jasper Solutions社では運用コスト削減と安定化が実現されました。 事例 改善効果 Hilti社 デプロイ時間の短縮(平均3時間から15分) Carfax社 脆弱性の早期発見(約3分の1) Jasper Solutions社 運用コスト削減と安定化(年間33〜37%のコスト削減) まとめ 今回は、GitLabがCI/CDパイプラインにセキュリティスキャン機能を統合することで、開発スピードと安全性を両立する「DevSecOps」という手法を実現していることを解説しました。 そして、GitLabが実際の企業事例(Hilti、Carfax、Jasper Solutions)でどのような具体的な成果(デプロイ時間の短縮、脆弱性の早期発見、運用コストの削減など)を生み出しているかを具体的に見てきました。 これまで学んだGitLabの基本操作を踏まえ、次は実際にDevSecOpsを体験できる環境を構築する方法をご紹介します。 参考文献 https://about.gitlab.com/ja-jp/customers/ ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Git & GitLab 入門 (10) ~Git マスターへの道~「GitLabでDevSecOps」 first appeared on SIOS Tech. Lab .
/br今号では、nftables について、その仕組みや設定方法について説明します! nftables とは nltables とはパケットフィルタリング (通過するパケットの IPアドレス、プロトコル、ポート番号などをフィルタリング設定に基づいてチェックし、通信を許可・拒否を判断すること) ツールの名称です。カーネル 3.13 (RHEL だとバージョン 8系) から導入されました。 従来は iptables、ip6tables、arptables、ebtables といった複数のツールを使い分けてフィルタリング設定をする必要がありましたが、これらのツールを 1つの nft コマンド に統合し、より管理しやすくなりました。 nftables は従来のツールと比較して構文がシンプルかつ柔軟に設定ができるようになっています。 なお、nftables について過去に下記の記事でもご紹介しています。2019年の記事ということもあり、前回説明しきれなかった部分も含めてご紹介できればと思います。 ※内容が重複してしまう部分もあります。ご了承ください。 https://tech-lab.sios.jp/archives/16930#teburuno_she_ding フィルタリング設定の全体的な構造 nftables では、フィルタリング設定のことを ルールセット と呼びます。 ルールセットは、inet、ip、ip6 などのアドレスファミリごとに作成できる テーブル 、さらにテーブル内にフィルタリングのルールをひとまとめに管理するための チェーン 、そしてチェーン内で具体的なルール設定を行うための ルール が含まれる構造になっています。 基本の書式 nft コマンド の基本的な使用方法をご説明します。 ルールセットの追加 nftables によるフィルタリング設定は、 ①テーブル、②チェーン、③ルール 、という順序で行なっていきます。 テーブルの追加 テーブルを新しく追加するには nft add table コマンド を使用します。 例1:inet ファミリのテーブルを作成 # nft add table inet table1 例2:ip4 ファミリのテーブルを作成 # nft add table ip table2 チェーンの追加 チェーンを新しく追加するには nft add chain コマンド を使用します。 例1:table1 テーブルに新しいチェーンを作成 # nft add chain inet table1 chain1 { type filter hook input priority 0 \; } ※ “{}” 内で指定する type、hook、priority に指定可能な値については、過去にご紹介した記事でも説明しています。 (ブログより抜粋) —– ・type には、filter、route、nat のいずれかを設定します。 ・hook には、prerouting、input、forward、output、postrouting のいずれかを設定します。 ・priority には、チェインの優先度 (整数値) を設定します。 値が小さいほど、優先度は高くなります。また、負の値を設定することもできます。 —– ルールの追加 ルールを新しく追加するには nft add rule コマンド を使用します。 例1:table1 テーブル内の chain1 に、22 番ポート (SSH) による外部アクセスを許可するルールを作成 # nft add rule inet table1 chain1 tcp dport 22 accept 例2:table1 テーブル内の chain1 に,、80 番ポート (HTTP) による外部アクセスを許可するルールを作成 # nft add rule inet table1 chain1 tcp dport 80 accept ルールセットの表示 ルールセットの内容を表示するには nft list ruleset コマンド を使用します。 # nft list ruleset table inet table1 { chain chain1 { type filter hook input priority filter; policy accept; tcp dport 22 accept tcp dport 80 accept } } テーブルの一覧を表示するには nft list tables コマンド を使用します。 ※テーブルの一覧のみ。内容は表示されません # nft list tables table inet table1 特定のチェーンに設定されているルールの内容を表示するには、 nft list chain コマンド を使用します。 # nft list chain inet table1 chain1 table inet table1 { chain chain1 { type filter hook input priority filter; policy accept; tcp dport 22 accept tcp dport 80 accept } } ルールセットの削除 ルールを削除するには nft delete コマンド を使用します。 なお、ルールの削除には各ルールごとに設定されている ハンドル番号 が必須となります。 ハンドル番号の確認方法は、上で説明した nft list chain コマンドに –handle もしくは -a オプションを指定します。 # nft -a list chain inet table1 chain1 table inet table1 { chain chain1 { # handle 1 type filter hook input priority filter; policy accept; tcp dport 22 accept # handle 2 tcp dport 80 accept # handle 3 } } # nft --handle list chain inet table1 chain1 table inet table1 { chain chain1 { # handle 1 type filter hook input priority filter; policy accept; tcp dport 22 accept # handle 2 tcp dport 80 accept # handle 3 } } tcp dport 22 accept の横に handle 2 、 tcp dport 80 accept の横に handle 3 と記載されており、各ルールのハンドル番号を確認することができました。 例えば、上記のうち 22 番ポート (SSH) のルールを削除するには、下記の様に handle 2 と指定します。 # nft delete rule inet table1 chain1 handle 2 次号について 次号では、 nftables の設定例や、知っておくと便利な tips についてご紹介します! ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 知っておくとちょっと便利!nftables によるパケットフィルタリング1 first appeared on SIOS Tech. Lab .
こんにちは! 今月も「OSSのサポートエンジニアが気になった!OSSの最新ニュース」をお届けします。 9/10、IPA (情報処理推進機構) が、「情報セキュリティ白書2025」PDF 版を公開しました。 プレス発表「情報セキュリティ白書2025」PDF版の公開 https://www.ipa.go.jp/pressrelease/2025/press20250910.html 9/16、LPI-Japanは Linux の学習教材の最新版である「Linuxシステム管理標準教科書 バージョン2.0.0」を公開しました。 PDF版と ePub版は無償で提供されています。 LPI-Japan、無償のLinux学習用教材「Linuxシステム管理標準教科書」最新版を公開 https://japan.zdnet.com/article/35238032/ 総務省のサイトより、9/18 に実施された AI セキュリティ分科会の資料が公開されました。 総務省 – AIセキュリティ分科会(第1回) https://www.soumu.go.jp/main_sosiki/kenkyu/cybersecurity_taskforce/02cyber01_04000001_00321.html ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 【2025年9月】OSSサポートエンジニアが気になった!OSS最新ニュース first appeared on SIOS Tech. Lab .
はじめに これまで本ブログでは、GitLabをDevSecOpsのための開発プラットフォームとして利用する際に必要となる主要機能(コンテナレジストリやCI/CD)について紹介してきました。今回はその基盤をより安定して運用するために欠かせない冗長化構成について紹介します。 概要 GitLabを構成するコンポーネントとして以下のものがあります: GitLab Rails UIの提供やAPIの管理を行うGitLabの中核を成すウェブアプリケーションです Consul GitLabの各コンポーネントのサービスディスカバリーとヘルスチェックを行うコンポーネントです Database(PostgreSQL) GitLabの主要データ(プロジェクト、ユーザーなど)を保存するデータベースです Sidekiq GitLabのバックグラウンドジョブを非同期で処理するためのコンポーネントです Redis GitLabの一時的なデータ(キャッシュ、ジョブキューなど)を保存する高速なインメモリデータストアです Gitaly Cluster Gitリポジトリの読み書きを行うコンポーネントです 今回は以下のようなGitLabの構成例( 例:最大 1000 RPS または 50,000 ユーザー )を参考にして各コンポーネントの冗長化について説明します。 GitLabの構成例(引用: 最大 1000 RPS または 50,000 ユーザー ) 各コンポーネントの冗長化 GitLab Rails GitLab Railsの冗長化 GitLab RailsはGitLabのアプリケーションサーバーです。想定されるアクセスユーザーに合わせてノードを水平スケールする必要があります。(参考: https://docs.gitlab.com/administration/reference_architectures/ ) アプリケーションサーバーは多数のユーザーからのリクエストを処理する必要があります。また、アプリケーションサーバーから内部の各種コンポーネントに多数のリクエストが送られます。そのため、GitLab Railsの冗長化には外部ロードバランサーと内部ロードバランサーが使われます。 外部ロードバランサーはGitLabへアクセスする際の外部からのSSH、HTTPS通信のトラフィックを分散させます。TLS終端をロードバランサーによって行うことが可能です。 内部ロードバランサーはPgBouncerやGitaly Cluster (Praefect)への接続などの内部コンポーネント同士の通信を仲介して、負荷を分散します。 Consul Consulの冗長化 Consulは各コンポーネントの監視を行い、サービスディスカバリーとヘルスチェックを行うコンポーネントです。GitLabの各コンポーネント同士の接続の手伝いをします。 クォーラム(クラスターが正常に機能する最小台数)を維持するために、3ノード以上の奇数ノードにConsulをデプロイする必要があります。 Database(PostgreSQL) Database(PostgreSQL)の冗長化 GitLabでは主要データ(プロジェクト、ユーザーなど)を保存するデータベースとしてPostgreSQLが利用されます。 GitLabのPostgreSQLでは単一障害点を回避するためにプライマリDBとセカンダリDBの2種類が用意されます。プライマリDBは実際に利用されるメインのDBで、セカンダリDBはプライマリの内容をリアルタイムで複製している読み取り専用の予備のDBです。 PgBouncerは各コンポーネントがPostgreSQLのDBに接続を行う際に仲介をして、DB本体への負荷を軽減させるコンポーネントです。PgBouncerがないとGitLabへの接続制限によって、エラーが出たり処理速度が低下します。PgBouncer自身は内部ロードバランサーによって負荷分散されます。 また、PatroniというPostgreSQLのHAクラスタを管理するツールを用いることによってプライマリDBに障害が起きた場合、セカンダリDBをプライマリに昇格する処理が自動的に行われます。 Sidekiq Sidekiqの冗長化 SidekiqはGitLabの様々なバックグラウンドジョブ(メール送信、CIジョブなど)を処理するコンポーネントです。 Sidekiqのキューにジョブが追加されていくと、あるコンポーネントで処理が低下した場合、連鎖的にすべてのジョブの速度が低下する可能性があります。そのような場合の対策として、以下のようなものがあります。 複数インスタンスを立ち上げて処理能力を増やす ジョブを小さな単位に分割する ジョブのキューを最適化する 上記に示す通りSidekiqの冗長化は単純に水平スケールするだけでなく、ジョブキューの設計を適切に行うことが重要になります。 Sidekiqはログを見ることによってジョブの実行時間や実行回数を視覚的に確認することが可能です。その結果をSidekiqのキューの設計に反映させて、継続的にキューの最適化を行う必要があります。 Sidekiqのログ(引用: GitLabの負荷分散 ) Redis Redisの冗長化 RedisはGitLabで高速処理が求められる様々な一時的なデータを保存するために利用されます。PostgreSQLと同じくプライマリとセカンダリに別れていますが、Redisのセカンダリは読み取りができません。 ジョブキューやユーザーセッションの状態の情報など、失われるとGitLabの機能が停止するような情報はRedis Persisetentに保存され、Cacheやログなどの失われてもGitLabが動作できるような情報はRedis Cacheに保存されます。 Redis Sentinelというコンポーネントによって、Redisのプライマリで障害が起きた場合、セカンダリに自動的に切り替えが行われます。 Redisクラスターはクォーラム(クラスターが正常に機能する最小台数)を維持するために、3ノード以上の奇数ノードにデプロイする必要があります。 Gitaly Cluster Gitaly Clusterの冗長化 GitalyはGitリポジトリの読み書きを行うコンポーネントです。 Gitaly ClusterはすべてのGitリポジトリがすべてのGitalyノードに保存され、そのうち一つがプライマリとして動作します。 Gitalyへの接続はすべてPraefectというGitaly Clusterのリクエストをルーティングするコンポーネントを経由します。これによってGitalyノードで障害が起きた場合、自動的にフェイルオーバーします。また、PraefectはTLSの接続をサポートしています。 Praefect自身は内部ロードバランサーによって負荷分散されます。また、クォーラム(クラスターが正常に機能する最小台数)を維持するために、3ノード以上の奇数ノードにデプロイする必要があります。 PraefectにはGitaly Clusterのステータスを保存する独自のDB(Praefect PostgreSQL)が必要になります。GitLabのLinuxパッケージで構築する場合、非HA構成のDBになります。高可用性を保ちたい場合は外部の冗長化されたPostgreSQLが必要になります。 終わりに 今回はGitLabの各コンポーネントの冗長化について解説しました。セキュアで継続的な開発環境を実現するための土台として、冗長化の考え方を理解しておくことはDevSecOpsの観点でも重要です。今回示した例は1000RPSまたは50,000ユーザーを想定した大規模な環境です。各々のユースケースに適したGitLabの構成を設計し、その環境規模に応じてどのコンポーネントを冗長化するべきか判断する必要があります。今回の記事がその判断材料の助力になれば幸いです。 参考 GitLabコンポーネントリスト https://docs.gitlab.com/development/architecture/#component-list GitLabリファレンスアーキテクチャ https://docs.gitlab.com/administration/reference_architectures/ 例:最大 1000 RPS または 50,000 ユーザー https://docs.gitlab.com/administration/reference_architectures/50k_users/ マルチノードGitLab向けロードバランサー https://docs.gitlab.com/administration/load_balancer/ GitLabの負荷分散 https://docs.gitlab.com/development/scalability データベース負荷分散 https://docs.gitlab.com/administration/postgresql/database_load_balancing/ ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post GitLabの冗長化構成を徹底解説:安定運用のための実践ガイド first appeared on SIOS Tech. Lab .
はじめに 前回の記事では、2回にわたりGitLab CI/CDの基本的なパイプライン作成方法 を解説しました。ジョブの定義からステージの構成まで、一通りの流れを実際に試しながら理解できたと思います。 しかし、実際にチーム開発を進めていくと、パイプラインの定義ファイルである.gitlab-ci.ymlがすぐに肥大化しがちです。 同じ処理を複数のジョブに書いてしまう プロジェクトごとに似たような CI 定義をコピペして使い回す こうした状態になると、修正や共通化が難しくなり、運用コストが増えてしまいます。 そこで今回の記事では、GitLab CI/CDが用意している include と extends の仕組みに注目します。これらを活用することで、設定を整理し、再利用しやすい形に整えることができます。 小さな検証を通して、それぞれの機能がどのように役立つかを紹介していきます。 include機能:外部ファイルのインポート includeは、別ファイルに書かれたCI定義を取り込む機能です。別のプロジェクトにあるファイルを読み込めるのが大きな特徴です。今回の検証では、テスト用にGitLab上で 2 つのプロジェクトを用意し、一方のプロジェクトにあるパイプライン定義を、もう一方のプロジェクトからincludeで読み込む形を確認しました。 検証環境 メインプロジェクト:runner-test-project-1 .gitlab-ci.yml(実際にパイプラインを実行する定義ファイル) インポート用プロジェクト:runner-test-project-2 ci/shared.yml(他のプロジェクトから取り込んで使うためのジョブ定義ファイル) 設定例(実行側) # runner-test-project-1/.gitlab-ci.yml variables: FROM_PROJECT: "overridden-in-runner-test-project-1" include: - project: "group/runner-test-project-2" ref: "main" file: "/ci/shared.yml" stages: [test] check-local: stage: test script: - echo "FROM_PROJECT=${FROM_PROJECT}" 設定例(includeされる側) # runner-test-project-2/ci/shared.yml project-job: stage: test variables: FROM_PROJECT: "default-in-provider-project" script: - echo "FROM_PROJECT=${FROM_PROJECT}" 実行結果 check-local(ローカルジョブ)と project-job(外部ジョブ)がどちらもパイプラインに表示される すべてのジョブが成功 FROM_PROJECT=overridden-in-runner-test-project-1 が出力され、実行側の変数が優先されることを確認 ポイント 変数の上書き :同じ名前の変数が複数定義されている場合、最終的にはメインの.gitlab-ci.ymlファイルで定義された値が優先されます。外部ファイル側はデフォルト値を置き、環境依存の値はメイン側で上書きするのがベストです。 権限 :実行するユーザーが参照先リポジトリを読む権限を持っている必要があります。安定運用のためには、参照元・参照先を同じグループ内にまとめておくとよいでしょう。 ref の固定 :main を参照すると、外部ファイルの変更が即座に反映されてしまうため、安定性を重視するなら、タグやリリースブランチを指定するのがおすすめです。 参考: Use CI/CD configuration from other files | GitLab Docs extends機能:共通設定の継承 extendsは、ジョブごとに共通する設定をテンプレートとしてまとめ、そこから継承できる仕組みです。同じ処理や変数を繰り返し記述せずに済むのが大きな特徴です。今回の検証では、共通設定を.default-templateとして定義し、job_aではそのまま継承、job_bでは一部の変数を上書きする形を確認しました。 検証環境 任意のプロジェクトに extends-gitlab-ci.yaml を作成し、次の内容を記述しました。 設定例 stages: [test] # 共通設定(テンプレート) .default-template: stage: test image: registry.gitlab.local.example.com/root/registry-project/alpine:latest tags: - devsecops-runner before_script: - echo "BEFORE(from base) run common setup" variables: BASE_VAR: from-base OVERRIDE_ME: from-base # 継承のみ(上書きなし) job_a: extends: .default-template script: - echo "A BASE_VAR=$BASE_VAR OVERRIDE_ME=$OVERRIDE_ME" - echo "A IMAGE=$(cat /etc/alpine-release 2>/dev/null || echo unknown)" # 一部上書き(variables を上書き) job_b: extends: .default-template variables: OVERRIDE_ME: from-job-b script: - echo "B BASE_VAR=$BASE_VAR OVERRIDE_ME=$OVERRIDE_ME" 実行結果 すべてのジョブが成功 job_a BASE_VAR=from-base OVERRIDE_ME=from-base before_script の “BEFORE(from base) run common setup” が実行され、image も alpine:latest が利用されている job_b → 変数 OVERRIDE_ME はジョブ側の値で上書き、BASE_VAR や before_script はテンプレートの値がそのまま反映されている BASE_VAR=from-base(テンプレートのまま) OVERRIDE_ME=from-job-b(ジョブ側の値で上書き) before_script と image はテンプレートの設定が適用されている ポイント 共通化のメリット :before_script や変数をテンプレートにまとめることで、修正が必要になった際に1箇所を直すだけで全ジョブに反映できます。結果として、ジョブテンプレートの管理や保守がシンプルになり、影響範囲も明確に把握できます。 変数の上書き :テンプレートとジョブの両方に同じキーが定義されている場合、ジョブで定義された値が優先されます。テンプレートは共通の値を設定し、必要に応じてジョブ側で上書きするのが基本的な使い方です。 参考: Optimize GitLab CI/CD configuration files まとめ includeを使うと、外部ファイルを取り込んで 共通ジョブを複数のプロジェクトで再利用できます。 extendsを使うと、共通設定をテンプレート化してジョブごとの差分だけを簡潔に記述できます。 どちらの機能も、複雑化しやすい .gitlab-ci.yml を整理し、変更や保守を効率化するために欠かせない仕組みです。 チームやプロジェクトが大きくなるほど、パイプラインの管理は難しくなります。include とextendsを活用すれば、CI/CD 設定をシンプルかつ再利用性の高い形に整え、大規模な開発環境でも安定して運用できる基盤を作ることができます。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post GitLab CI/CD 実践[応用編]:共通設定と外部ファイルの利用 first appeared on SIOS Tech. Lab .
本書は、2025年8月に公開した マイクロサービス化の課題とその解決策 に関するホワイトペーパーを紹介するものです。 「ビジネスの変化に柔軟かつスピーディーに対応するためのマイクロサービス化だったはずが、なぜか開発は遅くなり、運用は複雑怪奇、分散モノリスのようになってしまった…」 もし、読者の皆様が企業の技術リーダーやアーキテクトとして、少しでも心当たりのあるのであれば、本書をお勧めいたします。さらに、AI時代のマイクロサービス化においては、別の問題も待ち構えていることを意識する必要があります。 AIが生み出すマイクロサービス化の新しい課題 ご存知の通り、生成AIは、驚異的なスピードでコードを生成します。しかし、一方ではビジネスの意図を汲み取ることが苦手です。 その結果、AIが高速で生成したコードが、気づかぬうちにサービスをまたがるデータの整合性を破壊し、ビジネスに致命傷をもたらしかねません。ここは人間による介入が必要な部分なのです。従来のSagaパターンのような複雑な手法のみでは、AIが大量に生み出すコードの整合性を人間が検証し続けるには、もはや限界に近づいています。 課題の全体像と解決へのアプローチ この度公開したホワイトペーパー「マイクロサービス化の課題とその解決策」では、マイクロサービス化に関する旧来からの課題に対しては、単なる技術論のみではなく、技術論から一歩離れた組織論から検討する体系的なアプローチでの解決策を提案します。更に、AI時代のマイクロサービス固有の課題であるデータ整合性担保に対する解決策として、強力な選択肢の一つとなり得る ScalarDB を紹介します。 ホワイトペーパーの構成(11ページ) 第1部:問題提起 – なぜマイクロサービス化は失敗するのか 第2部:SIOS APIエコシステムとScalarDBによる包括的解決策 第3部:実践的トレードオフと典型的な設計パターン 第4部:結論 経験豊富なアーキテクトの皆様へ 第3部では、本書の記載に対して経験豊富なアーキテクトであればこそ抱くであろう妥当な疑問に対して、正面から向き合います。 疎結合と「時間的カップリング」の板挟み 2PCの性能オーバーヘッドとTCO(総所有コスト) アプリケーション層からインフラ層への複雑性の移動は問題解決になるか? ストラングラーフィグパターンへの応用 ▼ホワイトペーパーのダウンロードはこちらから https://api-ecosystem.sios.jp/scalar/download/scalarsiosapi01.html ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post マイクロサービス化の新旧課題の解決策を提案するホワイトペーパーの紹介 first appeared on SIOS Tech. Lab .
はじめに こんにちは!珍しくブログを連投しているなーがです。今回はClaude Code UIをインストールした際につまづいたことについて書こうと思います。 最近、AIを活用した開発ツールが次々と登場していますが、その中でもClaude Code UIは特に注目を集めています。しかし、Windows環境でのインストールには意外な落とし穴があることがわかりました。同じ問題で悩む方のお役に立てればと思い、解決方法をまとめてみました。 時間がない方のために Claude Code UIをWindows環境でインストールする際は、Visual Studio Installerから以下の2つをインストールする必要があります: ワークロード「C++によるデスクトップ開発」 個別のコンポーネント「最新のSpectre 軽減のライブラリ」 これらがないと、 npm install 時にビルドエラーが発生します。 Claude Code UIとは Claude Code UIは、Anthropic社のClaude Code CLIやCursor CLIをWebブラウザ経由で操作できるようにするWebアプリケーションです。これにより、ローカル環境だけでなく、スマートフォンやタブレットなどのモバイルデバイスからもAIを活用したコーディングが可能になります。 主な特徴 ブラウザベースのターミナルインターフェース Claude CodeやCursorの全機能をWeb UIから利用可能 モバイルフレンドリーなレスポンシブデザイン Cloudflare Tunnelなどと組み合わせて、どこからでもアクセス可能 GitHubリポジトリ:https://github.com/siteboon/claudecodeui 関連するいくつかのブログが投稿されています。 スマホでClaude Code!?外出先でClaude Codeを使ってみた!! (こちらは弊社の細川君の記事なのでぜひ読んでください!) 【徹底解説】Claude Code UI と Cloudflare Tunnelでスマホから快適にAIコーディング Claude Code UIレビュー:スマホからでもAIコーディングが可能に!開発効率が劇的向上 インストール手順と遭遇した問題 前提条件の確認 READMEによると、以下の前提条件が必要です: Prerequisites Node.js v20 or higher Claude Code CLI installed and configured, and/or Cursor CLI installed and configured 私のPCにはすでにv20以上のNode.jsとClaude Code CLIがインストール済みだったので、さっそくインストールを開始しました。 インストール開始 まずはリポジトリをCloneします。 git clone https://github.com/siteboon/claudecodeui.git Cloneされたら、ディレクトリを移動します。 cd claudecodeui ライブラリをインストールします。 npm install 最初のエラー:Visual Studio C++ツールセットが見つからない $ npm install npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory... (中略) npm error gyp ERR! find VS - found "Visual Studio C++ core features" npm error gyp ERR! find VS - missing any VC++ toolset npm error gyp ERR! find VS could not find a version of Visual Studio 2017 or newer to use npm error gyp ERR! find VS npm error gyp ERR! find VS ************************************************************** npm error gyp ERR! find VS You need to install the latest version of Visual Studio npm error gyp ERR! find VS including the "Desktop development with C++" workload. npm error gyp ERR! find VS For more information consult the documentation at: npm error gyp ERR! find VS https://github.com/nodejs/node-gyp#on-windows npm error gyp ERR! find VS ************************************************************** すっごく長いエラーが発生して最初は驚きましたが、よく見ると意味は明確でした。 エラーの原因: node-pty というNode.jsのネイティブモジュールのビルドでエラーが発生しています。 node-pty は疑似ターミナル(PTY)を作成するためのモジュールで、Claude Code UIのターミナル機能に必要不可欠です。 Windowsでこのようなネイティブモジュールをビルドするには、C++のコンパイラツールチェーンが必要となります。エラーメッセージは「Visual StudioのC++開発ツールが見つからないので、最新のVisual Studioをインストールして『C++によるデスクトップ開発』ワークロードをインストールしてください」と教えてくれています。 解決策1:Visual Studio C++開発環境のインストール Visual Studio Installerを開きます。Visual Studioをインストールされていない方は、 こちら からダウンロードしてください。 「変更」をクリックします。 「ワークロード」タブで「C++によるデスクトップ開発」を選択してインストールをクリックします。(筆者はインストール済みのため、ボタンが「閉じる」になっています) インストールが終わったら、再度ライブラリをインストールするコマンドを実行します。 npm install 2回目のエラー:Spectre軽減ライブラリが必要 $ npm install npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory... (中略) npm error C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppBuild.targets(511,5): error MSB8040: Spectre 軽減のライブラリは、このプロジェクトに必要です。使用されているツールセットとアーキテクチャについては、Visual Studio インストーラー (個々のコンポーネント タブ) からインストールします。詳細情報: https://aka.ms/Ofhn4c 今度は「Spectre 軽減のライブラリ」が必要というエラーが発生しました。 Spectreとは? 2018年に発見されたCPUの脆弱性で、投機的実行という高速化技術の副作用を悪用して、本来アクセスできないメモリ領域の情報を盗み見ることができる攻撃手法です。MicrosoftはこれらのセキュリティリスクからWindowsアプリケーションを保護するため、Visual Studioに特別な軽減ライブラリを提供しています。 最近のプロジェクトでは、セキュリティ上の理由から、これらの軽減ライブラリを使用することがデフォルトで要求されることが多くなっています。 解決策2:Spectre軽減ライブラリのインストール 診断コードMSB8040の解決策は Microsoft公式リファレンス に記載されている通り、Visual Studio Installerの「個別のコンポーネント」タブから最新のSpectre軽減ライブラリを選択してインストールします。 インストールが終わったら、三度目の正直でライブラリをインストールするコマンドを実行します。 npm install インストール成功! $ npm install npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory... (警告は続きますが、これらは依存関係の警告なので問題ありません) added 613 packages, and audited 614 packages in 2m 141 packages are looking for funding run `npm fund` for details 1 low severity vulnerability To address all issues, run: npm audit fix Run `npm audit` for details. やっとライブラリのインストールが成功しました!警告はいくつか表示されていますが、これらは依存パッケージの非推奨に関するものなので、動作には影響しません。 あとは README.md に書いてある通りに実行するだけです! トラブルシューティング もし同様の問題に遭遇した場合は、以下の点を確認してください: 1. Visual Studioのバージョン Visual Studio 2017以降が必要です Community版で問題ありません 2. 必要なコンポーネント 必須 : C++によるデスクトップ開発(ワークロード) 必須 : 最新のSpectre軽減のライブラリ(個別のコンポーネント) 3. Node.jsのバージョン Node.js v20以上が必要です node --version で確認できます 4. 権限の問題 管理者権限でコマンドプロンプトを実行してみてください node_modules フォルダを削除してから再度 npm install を試してください まとめ 今回はClaude Code UIをWindows環境でインストールする際につまづいたことについて書きました。一見すると単純なnpmパッケージのインストールですが、ネイティブモジュールを含む場合は、Visual StudioのC++ビルドツールが必要になることがあります。 特にWindows環境では、以下の2つが必要です: Visual StudioのC++によるデスクトップ開発ワークロード Spectre軽減のライブラリ これらを事前にインストールしておけば、スムーズにセットアップできるはずです。 昨今のAIツールの発展はめまぐるしいものがありますが、こうしたツールを活用することで、開発効率は飛躍的に向上します。インストールで少し苦労するかもしれませんが、その価値は十分にあると思います。 AIツールの進化に負けずに、楽しく開発していきましょう! 参考リンク Claude Code UI GitHub Repository Node.js Visual Studio Downloads MSB8040エラーの解決方法(Microsoft公式) node-gyp on Windows(GitHub) ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Claude Code UIをインストールする際につまづいたこと first appeared on SIOS Tech. Lab .
はじめに 前回 は、CI/CDの基本から、GitLab Runnerの導入、そしてコンテナイメージのビルド・プッシュ・デプロイまで、一連のワークフローを解説しました。 今回は、マージリクエスト(MR)の重要な役割であるコードレビューに焦点を当てます。コードレビューは、バグの早期発見やコード品質の向上、さらにはチームの知識共有を促す、開発プロセスに欠かせない作業です。 本記事では、GitLabのMR機能を活用し、レビューをスムーズに進めるための具体的な操作方法を、レビュアー(レビューする人)とレビューイ(レビューしてもらう人)の両方の視点から解説します。 コードレビューの概要 コードレビューとは、他の開発者が書いたコードを読み、フィードバックや改善点を議論するプロセスです。これは、単にバグを見つけるだけでなく、チーム全体のコード品質を高め、知識を共有し、開発の一貫性を保つために重要です。 GitLabでは、このコードレビューのプロセスがマージリクエスト(MR)に統合されています。MR上でコードレビューを行う流れは以下のようになります。 レビューイ(レビューしてもらう人):構文チェック後にMRを作成し、パイプラインの自動テストが完了していることを確認する。 レビューイ:レビュアーを指定してレビュー依頼を出す。 レビュアー(レビューする人):レビュー依頼を受けたらMR画面を確認し、MRの概要を把握する。 レビュアー:コードの変更点へのコメントをする レビューイ:MRのレビューを確認し、コードの変更が必要な場合は修正する。 レビュアー:コードの変更点に問題がなければMRを承認する。 レビューイ:MRが承認されたらマージする。 今回はレビューイが承認をもらったら、レビューイ自身でマージする流れで紹介します。 承認に複数名必須な場合もあるので、すべての承認者が承認してからマージするためにレビューイ自身でマージする流れを紹介しましたが、誰がマージするかはチーム文化に依存します。 マージリクエストのレビュー機能紹介 MRの設定 マージリクエスト(MR)を作成する際、タイトルや説明、担当者といった様々な項目を設定できます。 タイトル MRの目的を示します。一目で内容がわかるように「feat: 新機能追加」や「fix: バグ修正」といったルール(コミット規約)を適用するのが一般的です。 説明 以下の点を意識して記載すると、レビュアーは内容を素早く理解できます。 なぜこの変更が必要かといった背景や課題 何を変更したかといった技術的な詳細 何を確認してほしいかといったレビューのポイント 関連するイシュー番号 担当者 このMRの責任者をアサインします。通常は作成者(レビューイ)自身をアサインします。 レビュアー コードレビューを依頼する人を指定します。 マイルストーン プロジェクトの特定のフェーズやリリース目標にMRを関連付けます。次のバージョンのリリースに向けたタスクをまとめること等ができます。 ラベル MRを分類するためのタグ付け機能です。「バグ」「ドキュメント」「緊急修正」などのラベルをつけて分類します。 マージ開始日時 マージを特定の日時にスケジュールするための機能です。特定の時間に自動でマージを実行したい場合に利用します。例えば、深夜に自動デプロイを行う際などに便利です。マージを開始するには、CI/CDのテストが成功している状態などのチェックに合格している必要があります。 マージオプション MRが承認されたときにソースブランチを削除します。 マージ完了後に、不要になった作業用ブランチを自動的に削除します。マージ後にブランチを削除し忘れることがなくなり、リポジトリを整理できます。 MRが承認されたときにコミットをスカッシュします。 マージする際に、複数のコミットを1つの大きなコミットにまとめる機能です。マージ時には1つのコミットとして履歴に記録できます。これにより、mainブランチの履歴を見やすく保てます。 ブランチ保護 以前の記事 で解説したように、mainのような重要なブランチは保護設定をすることが推奨されます。これにより、MRを経由しない直接のプッシュを防ぎ、レビューのプロセスを強制します。 Approve必須化 プロジェクトの承認ルールを設定することで、特定のチームメンバーやコードオーナーからの承認をマージに必須できます。例えば、「2人以上のレビューアの承認が必要」といったルールを設定することで、コード品質のチェック体制を強化します。この設定は、Premium, Ultimateのプランで行えます。Free版では1人の承認必須設定が可能です。 参考: https://docs.gitlab.com/user/project/merge_requests/approvals/rules/ レビュアー(レビューする人)の視点 レビュアーとしてMRをアサインされたら、以下のステップでレビューを進めましょう。 MR画面の確認 まず、MRの概要を把握します。 MRの目的、関連するイシュー、変更の概要を確認します。 失敗したCI/CDパイプラインのエラーが未解決の場合は、そこでレビューを中断し、修正を依頼します。 変更されたコードを詳細に確認します。以下の点を意識して確認するとよいと思います。 コードの品質 境界値や大規模データでの計算量が考慮されているか プロジェクトのコーディング規約に準拠しているか 変更点へのコメント 特定の変更点にコメントを付けることで、レビューイにフィードバックを伝えます。 変更された特定の行にカーソルを合わせると、コメントアイコンが表示されます。クリックすると、コメント入力欄が現れます。 修正案をコメントで提案できます。 「レビューを開始」 複数の箇所にわたるフィードバックを、まとめて一度に投稿したい場合に使うボタンです。このボタンをクリックすると、コメントはすぐに投稿されず、「保留中のコメント」として保存されます。すべてのレビューを終えた後、MRの画面の「Your review」から「レビューを送信」ボタンをクリックすると、保留中のすべてのコメントがまとめて投稿されます。 「今すぐコメントを追加」 特定のコード行に対して、すぐに投稿したい単発のコメントに使うボタンです。 明確な正解はありませんが、基本的には「レビューを開始」でフィードバックをまとめ、「今すぐコメントを追加」で緊急性の高いシンプルなコメントを送るのが良いと思います。例えば、大きめのリファクタリングでは「レビューを開始」、小さな誤字では「今すぐコメントを追加」といった使い分けができます。 「提案」 コメント入力欄にある「候補を挿入する」ボタンをクリックし、修正後のコードを記述します。これにより、ワンクリックで修正を適用できるようになります。 記述したら、その他コメントと同様にコメントを追加します。 承認(Approve) レビューが完了したら、MRを承認します。コードに修正が必要な場合は、レビューイに修正依頼を出し、修正完了の連絡をもらったら再度変更を確認して承認します。 変更が適切であると判断したら、MR画面の「承認」ボタンをクリックします。これは、コードを承認したという意思表示になります。 レビューイ(レビューしてもらう人)の視点 レビューイは、MRを作成してビューを依頼した後、レビュアーからのフィードバックに対応し、変更を完了させます。レビューが完了したらマージを行います。 MRの作成 マージするブランチのコードを確認して、レビュアーに見てもらえる状態にします。以下の点を意識して確認するとよいと思います。 パイプラインのテスト結果が成功しているか 不要なデバッグコードやコメント、一時ファイルが残っていないか レビュアーを指定してMRを作成します。MRの作成手順は 第5回 を参考にしてみてください。 コメントへの返信 質問のコメントに対しては意図を説明する返信を行います。議論が必要な場合は、返信で対話を続けます。 感謝の意を常に忘れないようにしましょう。 変更の適用 レビュアーから「提案」を受け取った場合、GitLabの機能を使って簡単に変更を適用できます。しかし、提案をそのまま適用すると1コミット単位で履歴が増えるため、コミットをまとめたい場合はローカルでの修正が必要です。「提案」機能ではコミットの粒度を制御しにくいため、ローカルでの修正との使い分けが必要です。 MRの「変更」タブで、コメントに付いている「変更を適用」ボタンをクリックします。コミットメッセージを入力して「適用」をクリックします。これで、提案された変更をコミットとして追加できます。 表示するコミットを最新バージョンに変更します。 提案された変更が適用されていることが確認できます。これで、簡単に変更を適用できました。 追加コミットと再プッシュ 複雑な修正が必要な場合や、提案をまとめて適用したい場合は、ローカルで変更を行い、再度コミットしてプッシュします。コメントに対してすべて対応が完了したら、再度レビュアーに連絡して、承認をもらいます。 マージ レビューが完了したら、MRを承認してマージします。 承認ルールが満たされ、すべてのチェックが完了したら、MR画面の「マージ」ボタンをクリックして、ブランチをマージします。 まとめ 今回は、GitLabのマージリクエストを単なるマージの申請ではなく、コードレビューの場として活用する方法を解説しました。 レビュアーは、MR画面を確認し、具体的なコメントや提案を使ってフィードバックを伝えます。一方、レビューイは、コメントに適切に対応し、修正を迅速に反映させることが重要です。MRでレビューを行うことで、レビューの履歴が残り、開発の透明性も向上します。 MRの機能を使いこなすことで、チーム全体のコード品質が向上し、効率的な開発が可能になります。 参考文献 https://docs.gitlab.com/user/project/merge_requests/reviews/ https://docs.gitlab.com/user/project/merge_requests/approvals/rules/ https://qiita.com/C_HERO/items/c5cfbdbb269efb72fb8f https://bake0937.hatenablog.com/entry/2019/10/24/145241 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Git & GitLab 入門 (9) ~Git マスターへの道~「コードレビューの進め方」 first appeared on SIOS Tech. Lab .
はじめに 前回の記事 では、単一のジョブをステップごとに実行するシンプルなパイプラインを題材に、GitLab CI/CDの基本的な仕組みを確認しました。しかし、実際の開発現場では、アプリケーションのビルド、テスト、デプロイなど複数の処理を組み合わせ、段階的に実行することが求められます。今回はその実践編として、複数のジョブをつなぎ合わせてステージごとに実行するマルチステージパイプラインの設計方法を紹介します。さらに、作成したパイプラインを効率的に管理・運用するための実行管理のポイントについても解説します。 前提条件 本記事では、あらかじめ以下の環境が構築されていることを前提とします。環境の詳細な構築手順については、 環境構築編の記事 をご参照ください。 GitLab(Self-Managed版) LinuxサーバーにOmnibusパッケージでインストール済み Community Edition(無償版)を利用 自己署名証明書を利用し、内部DNSによる名前解決が可能 Gitlab Runner OpenShiftクラスター上にデプロイ済み Kubernetes Executorを利用し、CI/CDジョブをPodとして実行可能 レジストリ認証情報をリンクしたServiceAccountを利用可能 ex. oc secrets link gitlab-runner-sa gitlab-registry-secret –for=pull OpenShiftクラスター 閉域環境(インターネット非接続)に構築 踏み台サーバーからocコマンドで操作可能 GitLab Container Registry コンテナイメージのpush / pullに利用 自己署名証明書のため、CA証明書をRunner / ノードに登録済み 踏み台サーバー 内部DNSサーバー、NFSサーバーを兼任 外部インターネットへの接続が可能 ocコマンドでOpenShiftを操作可能 podmanでコンテナイメージの push / pull が可能 これらの環境を利用してGitLab CI/CDパイプラインを実行し、ビルドからデプロイまでの流れを検証できます。 また、本記事では以下のようにテスト用のプロジェクトとブランチを用意して検証します。 テスト用プロジェクトの作成 任意の名称で新規作成(例: test-project)。このプロジェクトでジョブを検証します。 テスト用ブランチの作成 本記事ではmulti-stage-testブランチを作成して使用していますが、mainなど任意のブランチでも検証可能です。 マルチステージパイプラインの作成方法 ここでは、実際にGitLab上でマルチステージパイプラインを作成し、アプリケーションを OpenShiftクラスターにデプロイする一連の流れを確認します。今回のサンプルでは、「イメージのビルド」と「Kubernetes へのデプロイ」をそれぞれ独立したステージとして定義します。 ディレクトリ構成 まず、プロジェクトのディレクトリ構成は以下のとおりです。 ソースコードや設定ファイルに加え、CI/CDの定義ファイル(.gitlab-ci.yml)とKubernetes のマニフェスト(deploy.yaml)を配置しています。 . ├── .gitlab-ci.yml ├── Dockerfile ├── README.md ├── deploy.yaml ├── nginx.conf └── web └── index.html 各ファイルの役割 ファイル名 概要 Dockerfile ベースとなるNginxイメージにアプリの静的ファイルとNginx設定を組み込み、ポート8080で待ち受けるコンテナを作成します。 nginx.conf ヘルスチェック用の/healthzエンドポイントとトップページでindex.htmlを返す設定、使用ポートを定義しています。 web/index.html デプロイ成功を確認するための簡単なHTMLページです。 deploy.yaml OpenShift上にDeploymentを作成するためのマニフェストです。後述のジョブで${IMAGE}:${TAG}の部分を置換し、実際にビルドしたコンテナイメージを指定します。 .gitlab-ci.yml CI/CD パイプラインの定義です。buildステージでイメージのビルドとプッシュを行い、deployステージでKubernetesへ適用します。 Dockerfile このアプリケーションでは、ベースイメージに nginx:1.29-alpine を利用しています。閉域環境のため、本記事では事前にこのイメージをGitLab Container Registryにpushし、そのレジストリを参照する形で FROM を指定しています。 FROM registry.gitlab.local.example.com/root/test-project/nginx:1.29-alpine # アプリ静的ファイル COPY web/ /usr/share/nginx/html/ # Nginx 設定(ポート8080で待受) COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 8080 CMD ["nginx", "-g", "daemon off;"] このDockerfileでは、web/index.htmlを/usr/share/nginx/html/に配置し、Nginxをポート8080で起動することで、ブラウザやcurlからアクセスするとindex.htmlが返されるシンプルな構成になっています。 nginx.conf このnginx.confはポート8080で待ち受け、/healthzに200を返すヘルスチェック用エンドポイントを定義しています。 ドキュメントルート/usr/share/nginx/htmlに配置したindex.htmlをトップページとして返し、存在しないパスもindex.htmlにフォールバックするシンプルな設定です。 server { listen 8080 default_server; server_name _; # ヘルスチェック用(200/ok) location = /healthz { add_header Content-Type text/plain; return 200 "ok\n"; } root /usr/share/nginx/html; index index.html; location / { try_files $uri $uri/ /index.html; } } web/index.html デプロイの動作確認用に用意したシンプルな静的ファイルです。 Nginxのドキュメントルートに配置され、ブラウザやcurlでアクセスするとトップページとして返されます。パイプラインの挙動を検証したい場合は、このファイルを編集してpushすることで、新しいイメージがビルドされ、再デプロイ後に変更内容を確認できます。 <!doctype html> <html lang="ja"> <head><meta charset="utf-8"><title>Demo App</title></head> <body> <h1>Deploy Success v1.0.0.</h1> </body> </html> deploy.yaml アプリケーションをOpenShiftクラスター上にデプロイするためのDeploymentマニフェストです。spec.template.spec.containers[0].imageには ${IMAGE}:${TAG}を指定しており、CI/CDパイプライン実行時にビルドしたイメージ名へ置換されます。 コンテナはポート8080を公開し、/healthzへのHTTP応答をreadinessProbeとして利用することで、Pod が正常に起動しているかを判定します。 apiVersion: apps/v1 kind: Deployment metadata: name: multi-stage-demo-deploy namespace: gitlab-runner-test spec: replicas: 1 selector: matchLabels: app: multi-stage-demo template: metadata: labels: app: multi-stage-demo spec: serviceAccountName: gitlab-runner-sa imagePullSecrets: - name: gitlab-registry-secret containers: - name: multi-stage-demo-app image: ${IMAGE}:${TAG} imagePullPolicy: Always ports: - containerPort: 8080 readinessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 3 periodSeconds: 5 .gitlab-ci.yml この.gitlab-ci.ymlは 2ステージ(build → deploy)構成でdindを使ってイメージをビルド→レジストリへpush →OpenShiftへのデプロイまでを自動化します。まず定義全体を示し、その後に実行フローを解説します。 stages: - build - deploy default: tags: [devsecops-runner] build_image: stage: build image: registry.gitlab.local.example.com/root/registry-project/docker:28.3.3 services: - name: registry.gitlab.local.example.com/root/registry-project/docker:28.3.3-dind alias: docker entrypoint: ["/bin/sh","-lc"] command: - > cp /etc/gitlab-runner/certs/gitlab.local.example.com.crt /usr/local/share/ca-certificates/ca.crt && update-ca-certificates ; exec dockerd-entrypoint.sh --tls=false --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2375 variables: DOCKER_HOST: tcp://docker:2375 DOCKER_TLS_CERTDIR: "" before_script: - cp /etc/gitlab-runner/certs/gitlab.local.example.com.crt /usr/local/share/ca-certificates/ca.crt && update-ca-certificates - docker login "$CI_REGISTRY" -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" # IMAGE_VERSION が定義されていればそれを利用、なければ CI_COMMIT_SHORT_SHA - export IMAGE_TAG="${IMAGE_VERSION:-$CI_COMMIT_SHORT_SHA}" - export IMAGE_FULL="${CI_REGISTRY_IMAGE}/demo:${IMAGE_TAG}" script: - docker build -t "$IMAGE_FULL" . - docker push "$IMAGE_FULL" - printf "IMAGE_FULL=%s\n" "$IMAGE_FULL" > build.env artifacts: reports: dotenv: build.env deploy_manifest: stage: deploy image: registry.gitlab.local.example.com/root/test-project/oc:4.18 needs: - job: build_image artifacts: true variables: K8S_NAMESPACE: gitlab-runner-test before_script: - oc whoami script: - | : "${IMAGE_FULL:?IMAGE_FULL missing from build.env}" # IMAGE と TAG を分離 IMAGE="${IMAGE_FULL%:*}"; TAG="${IMAGE_FULL##*:}" # ${IMAGE}:${TAG} を合成 sed "s|\${IMAGE}:\${TAG}|${IMAGE_FULL}|g" deploy.yaml > deploy.rendered.yaml echo "---- rendered ----" cat deploy.rendered.yaml oc apply -f deploy.rendered.yaml ※IMAGE_VERSIONが未定義の場合はCI_COMMIT_SHORT_SHAがタグに使われます。この場合、短いコミットIDごとに新しいイメージが作成されるため、レジストリの容量管理や不要イメージの削除に注意してください。レジストリの容量管理については GitLab Container Registry: 応用編(可視性設定とガベージコレクション) をご参照ください。 補足: 閉域環境向けの準備 ベースイメージ登録 通常はDocker Hubから直接nginx:1.29-alpineを取得できますが、インターネット接続ができない環境では以下のように 事前にレジストリにpushしておきます。 $ podman login registry.gitlab.local.example.com $ podman pull docker.io/library/nginx:1.29.1-alpine $ podman tag docker.io/library/nginx:1.29.1-alpine \ registry.gitlab.local.example.com/root/test-project/nginx:1.29.1-alpine $ podman push \ registry.gitlab.local.example.com/root/test-project/nginx:1.29.1-alpine ※Docker 利用環境ではpodman → dockerに置き換えてください。 ocコマンド用イメージ登録 通常はregistry.redhat.ioから直接ose-cli-rhel9:v4.18を取得できますが、インターネット接続ができない環境では以下のように 事前にレジストリにpushしておきます。 $ podman login registry.redhat.io $ podman pull registry.redhat.io/openshift4/ose-cli-rhel9:v4.18 $ podman login registry.gitlab.local.example.com $ podman tag registry.redhat.io/openshift4/ose-cli-rhel9:v4.18 \ registry.gitlab.local.example.com/root/test-project/oc:4.18 $ podman push registry.gitlab.local.example.com/root/test-project/oc:4.18 ※Docker利用環境ではpodman → dockerに置き換えてください。 ※デプロイ先のコンテナ基盤がKubernetesである場合はoc → kubectlに置き換えてください。OpenShiftの場合もkubectlコマンドで基本的な操作は可能ですが、ocにはOpenShift特有の拡張機能が含まれています。 パイプラインの仕組み(実行フロー解説) パイプラインは 2ステージ構成 になっています。 1. build ステージ(イメージのビルドとプッシュ) ジョブbuild_imageが実行されます。 Docker-in-Docker(dind)環境を利用してdocker buildを実行し、GitLab Container Registryにイメージをpushします。 pushしたイメージのフルパス(IMAGE_FULL)をbuild.envとしてアーティファクトに保存します。 → この情報が次のステージに引き渡されます。 2. deploy ステージ(マニフェストの適用) ジョブdeploy_manifestが実行されます。 先ほど保存したIMAGE_FULLを利用し、deploy.yaml内の${IMAGE}:${TAG}を実際のイメージ名に置換します。 oc apply -f deploy.rendered.yamlを実行してOpenShiftクラスターにDeploymentを作成します。 Podが立ち上がり、readiness probeによって/healthzが成功すればデプロイ完了です。 パイプラインの実行 作成したパイプラインを実際に動かしてみましょう。 まず、検証用プロジェクトに移動し、管理画面からCI/CD変数を設定します。[変数を追加]をクリックし、キーにIMAGE_VERSION、値にv1.0.0を入力します。なお、mainブランチなどの保護ブランチ以外で試す場合は、保存時に[変数の保護]のチェックを外してください。チェックが付いたままだと、featureブランチなど非保護ブランチでパイプライン実行時に環境変数を参照できなくなります。 次に、ソースコードをリポジトリにpushします。GitLabのプロジェクト画面から検証対象のブランチに切り替え、[編集] → [Web IDE]を選択して内部エディタを開きます。前述のファイル(.gitlab-ci.ymlやdeploy.yamlなど)を作成し、右側の[Source Control]アイコンからコミットメッセージを入力して[Commit and push]をクリックすれば、コードがブランチにpushされます。 ソースコードがpushされると、自動的にパイプラインが起動します。プロジェクトのサイドバーから [ビルド] > [パイプライン] を選択すると、実行中のパイプラインを確認できます。さらに、パイプラインIDをクリックすれば、各ジョブの実行状況やログを確認できます。 プロジェクトのサイドバーから[デプロイ] > [コンテナレジストリ]を選択すると、プロジェクト内レジストリのリポジトリ一覧が表示されます。今回ビルドしたイメージはdemoリポジトリに格納されています。 この例では、build_imageジョブでイメージをビルドしてレジストリにpushし、その結果生成されたIMAGE_FULL変数がbuild.envに保存されます。続くdeploy_manifestジョブでは、その変数を利用してマニフェスト内のプレースホルダーを置換し、oc applyコマンドでOpenShiftにデプロイできていることが確認できます。 デプロイ成功の確認 デプロイジョブの成功を確認した後、アプリのPodがRunning状態で起動していることを確認します。 $ oc get pod -n gitlab-runner-test -l app=multi-stage-demo NAME READY STATUS RESTARTS AGE multi-stage-demo-deploy-6874887f67-w7br8 1/1 Running 0 69s Podが正常に起動すると、Pod内のNginxでweb/index.htmlが配信されます。以下のようにアクセスして動作を確認できます。 # Pod名を取得 $ POD=$(oc -n gitlab-runner-test get pod -l app=multi-stage-demo -o jsonpath='{.items[0].metadata.name}') # ローカル18080 → Pod 8080 へ転送 $ oc -n gitlab-runner-test port-forward pod/$POD 18080:8080 # ブラウザからlocalhost:18080にアクセスし、index.htmlの内容が表示されることを確認 Deploy Success v1.0.0. このメッセージが表示されれば、マルチステージパイプラインを通じて「ビルド→レジストリへのpush→OpenShiftへのデプロイ」が自動化できていることを確認できます。 これで、コードのpushをトリガーにビルドからデプロイまでが一連の流れで実行されることを、実際のパイプライン実行を通して確かめられます。 なお、すべての処理を1つのステージにまとめることも可能ですが、ビルドとデプロイを分けることで以下のメリットがあります。 責務の分離: ビルドとデプロイを明確に分けることで、どの段階で失敗したのかを特定しやすくなります。 効率的なリトライ: ビルドが成功していれば、デプロイだけを再実行できるため、再試行の効率が向上します。 並列・拡張性の確保: 将来的にテストステージを挟んだり、複数環境へのデプロイを分岐させたりといった拡張が容易になります。 このように、ステージを適切に分割することで、パイプラインの信頼性と運用効率を高めることができます。 まとめ 本記事では、複数のステージを組み合わせたパイプラインの設定方法を解説しました。 サンプルアプリケーションを題材に、ビルドとデプロイを別ステージに分けたマルチステージパイプラインを構築し、実際にコードのpushをトリガーにして一連の処理が自動で実行される流れを確認しました。 単一ステージに処理をまとめることも可能ですが、ステージを分割することで「どこで失敗したのかが明確になる」「ビルドが成功していればデプロイのみを再実行できる」といった運用上のメリットが得られることも示しました。これにより、パイプラインの信頼性や管理性が大きく向上します。 次回は、さらに複雑化したパイプライン定義ファイルを include / extends 機能 を活用して整理する方法を解説します。複数のジョブやステージが増えて管理が煩雑になったときに役立つ実践的なテクニックを取り上げ、よりスケーラブルなCI/CD運用に向けた一歩を紹介します。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post GitLab CI/CD 実践[マルチステージ編]:複数ジョブをつなぐパイプライン設計 first appeared on SIOS Tech. Lab .
初めに 前回のブログでは「 Claude Code革命!3フェーズ開発で効率的な開発:計画→実装→検証術 」について紹介しましたが、今回は実際にClaude Codeで仕様書ベース開発運用する際に「これは絶対に押さえておかないとハマる」というポイントについてお話しします。 実際に検証していて失敗したことや、気をつけないと時間を無駄にしてしまうポイントを中心にまとめました。 1. ドメイン知識の明示的なドキュメント化の重要性 この方法で検証していて失敗したこともあります。例えば、 プロジェクトの基礎的な知識(ドメイン知識)は、明示的にドキュメント化しない限りAIは理解してくれません 。 実際あった問題として、ネイティブアプリとWebアプリのバックエンドリンクの構成があります。ローカル環境ではSWCでエミュレートしていて、「/api」に自動でプロキシされる仕組みでしたが、AIはそれを知らずにバックエンドURLを直接埋め込もうとして、 APIパスの参照エラーが多発 しました。 これは「プロジェクトコア」のようなドキュメントを作成して共通知識を提供することで解決しました。 AIは書かれていないことは認識できず、セッション内で与えていない情報は理解しません 。 プロジェクトコアドキュメントの具体例 プロジェクトコアには、実際にデプロイする環境のプロキシの設計やプロジェクトの根幹に関わる部分をちゃんと定義しておくべきです。 今回私が作った環境では、Azure Static Web Appsをバックエンドリンクで構築していて、スラッシュAPIというのが自動でプレフィックスで飛んでいくという仕組みがあります。そのため、プレフィックス「/api」でアクセスするということを明記したり、プロジェクト構成みたいなのを書いておいて、そういった情報をAIに与えています。 当たり前のように思える環境設定や開発ルールも、AIにとっては「初めて聞く話」です。人間の開発者なら暗黙知として共有されている部分も、AIには明示的に教える必要があります。 2. AIがドキュメントを無視する問題への対処 計画フェーズでは「計画.md」などのファイルに指示を書いていますが、 AIは時々ドキュメントを無視することがあります 。人間と同じで、指示や定義を見ないこともあるんです。読んだうえで無視することもあるので、 絶対守ってほしいことはドキュメント化し、プロンプトでも注意するのが重要 です。 これは本当にイライラするポイントで、せっかく時間をかけて詳細な仕様書を作っても「それ、無視しちゃダメでしょ!」ということが頻繁に起こります。 無視されやすいパターンと対策 プロンプトに期待してない情報は割と無視しますね。そのパターン的なミスの傾向みたいなのがあったら、マークダウンファイルに情報反映させるというやり取りをよくやっています。 仕様書を書いてもらうフェーズと開発フェーズで、仕様書を書いている最中にコードの編集をしたりしていたんですよ。そこで、仕様要件フェーズと開発フェーズの三つに分けますという指示をつけて、計画フェーズではファイルの編集は加えないでくださいという指示を追加しています。開発フェーズは、作成した仕様のドキュメントを読んで、それに対してステップバイステップで開発を進めてくださいということを、マークダウンファイルで定義しています。 対策としては: 最重要な制約事項はドキュメントに書く さらにプロンプトでも再度強調する 「この部分だけは絶対に守ってください」という明示的な指示を含める 二重、三重の安全策を講じることが大切です。 3. 仕様書の適切な分量バランス 仕様書の分量については、 長すぎるとAIが無視する確率が上がります 。「無視しました」という返答が返ってくることもあり、それを見たときは正直 ブチ切れました (笑)。 短ければ理想的ですが、短すぎると時間がかかるので、AIが無視する可能性も考慮しながら適切な分量を見極める必要があります。 どの程度の分量が適切かはプロジェクト依存 です。ドメイン知識が多ければ、その分仕様書に書く情報は少なくて済みます。 具体的な分量の目安 私の環境で言うと、 エンドポイント2つと、それに対応する画面1つ という感じだと、体感的に上手くいったという印象です。これは本当にプロジェクトによるというか、プロジェクトコアによる感じの内容というか、元のコンテキスト量が影響してきます。 この辺りは経験則になってしまいますが、AIが「長いから読みたくない」と判断するラインを見極めることが重要です。人間と同じで、あまりにも長い仕様書は最後まで読んでもらえません。 4. 新機能開発とバグレポートの使い分け 私は新機能開発とバグレポートをこの二つの方法で分けて対応しています。 新機能開発 : 必ず3フェーズ(計画→実装→検証)を踏む 小さな変更 : でもドキュメント→実装という段階を踏む 本当に小さな変更 : 人間がやったほうが早い 人間がやったほうが早い変更の見極め プロジェクト構成的な部分の変更ですね。コード規約みたいなところで、ちょっと上の階層にファイルを移し替えたりとか、ファイル構成で、ちょっとこっちに移行させるほうがいいよねみたいな話とか、ファイルの単純な移動は、VS Codeの補完機能が優秀なので、そういった作業とか、あとは関数名が気に入らないので、関数名のリネームするという作業ですよね。 人間が手を動かして作業して、セッションが継続しているのであれば、ちゃんと変更を加えましたよということをAI側に伝えてあげる必要はあります。そうじゃないと、人間が編集したファイルとAIが編集しようとしているファイルでコンフリクト起きてしまうので、再度ファイルを作ろうとするんですよ。なので、そういったところで調整を取っていく必要はあるかなと思います。 この使い分けが重要で、何でもかんでもAIに頼めばいいというものではありません。1行2行の修正をAIに説明するより、自分でやってしまったほうが早いケースも多々あります。 プロセスを踏んでも意図したものができない場合は、やはり人間のドキュメントが不十分だということです。AIは書かれていないことを自由に判断するので、ドキュメントの質を高める必要があります。 5. 中規模開発での威力と現在の限界 現在はプライベートリポジトリで検証しているため、 大規模プロジェクトへの導入経験はまだありません が、中規模程度の開発であれば強力なツールになると思います。特に プロトタイピングでは大きな力を発揮しそう です。 個人的に学びになった点としては、仕様書作成が苦手な私でも、AIが返してきた仕様書を見て「分かりやすい」と感じることがあります。 学習的な側面でも価値がある と思います。 完璧な仕様書があれば理想的ですが、そういうものは実際には存在せず、どこかに不備があるものです。だからこそ、機能ごとに段階的に仕様書を作っていくアプローチが有効だと思います。 6. よくある失敗パターンとその対策 型定義の不整合問題 本当によくあるのが、フロントエンドとバックエンドで型定義が共通化されてなくて、バックエンドにアクセスできない、APIアクセスは成功してるんだけども、画面に表示がされないということがありました。 対策としては、 OpenAPI スペックを作らせて、そのOpenAPIスペックから型定義を作成する 。 そして、フロントエンドはその型定義を絶対に使用するようにする、という感じで回避しています。 デプロイ環境の差異による問題 デプロイ環境の差異みたいなところで問題が起きることもあります。今回Azure のバックエンドリンクで、スラッシュAPIのコンテンツを自動でプロキシしてくれるんですけど、そういったことを伝えてなくて、なんか別のエンドポイントベースURLみたいなのを付けて、そこにアクセスするようにしましょうみたいな提案をされました。 バックエンドが現状、localhost の3001番で動いてるので、ローカル3001番に直接アクセスするように変えちゃいましょう、みたいなことを言われることがあります。これはプロジェクトコアドキュメントでしっかりと環境構成を明記しておくことで回避できます。 まとめ Claude Codeは確実に開発効率を向上させてくれるツールですが、これらのポイントを押さえておかないと、余計な時間を費やしてしまいます。特にドメイン知識の明示化と仕様書の分量バランスは、成功の鍵となる重要な要素です。 まぁ暴走するのは人間と一緒って感じですね。人間よりも暴走しがちですが、言いやすい相手ですよねw 皆さんも、ぜひこれらのポイントを参考にClaude Codeを活用してみてください! ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Claude Code仕様書ベースでハマる6つの落とし穴!失敗回避の備忘録 first appeared on SIOS Tech. Lab .
はじめに ども!AIとの開発をがっつり初めて2か月で毎日Claude Codeとお話している龍ちゃんです。本業とは別で開発を進めているのですが、今まで1週間で頑張って1件の検証開発しかできなかったんですが、2日で検証したいことをサンプル付きで作成できるので最高ですね。これまでの開発経験で技術記事も数多く書いてきましたが、今回は特に効果を実感したAIとの協働について書いていこうと思います。 ちなみに「 Claude Code革命!3フェーズ開発で効率的な開発:計画→実装→検証術 」Claudeに実装させるフェーズを分割して開発をする手法を紹介しています。今回はそこの計画書執筆フェーズのお話です。 皆さんは、仕様書を書くことに対してどんな印象をお持ちですか?正直に言うと、入社して4年ですが、いまだに仕様書を書くという作業に対して苦手意識があります。仕様書を書くのが好きというエンジニアに個人的にあったことがありません。「完璧な仕様書を書くぞ~!」というモチベーションを持ったとしてもアレルギーといいますか、「完璧な仕様書」というものを書くのはハードルが高いですね。 背景・課題説明 仕様書が必要な理由 その一方でAIと共同で開発を進めていくためには「仕様書」があったほうが良いです。コード規約やLinter/Formatterが整備されているプロジェクトであれば、コードが仕様書の機能を持つことがありますが、プロジェクト初期の段階であれば仕様書を読み込ませて開発をするほうが圧倒的に開発効率が良いです。Vibe Codingで単純なプロンプトで100-300文字のプロンプトで作成するのは不可能です。 機能開発中によくあるのが、検討不足や考慮不足によって開発中にSlackでの相談やミーティングを挟んだり、手が止まって考え込んだりすることではないでしょうか。コードの書き方で悩むのは問題ありませんが、事前に決めておくべき情報が未確定なために発生する手戻りは避けたいものです。 仕様書アレルギーの原因分析 仕様書を書くことに対してアレルギーがある原因を個人的に分析をしてみると、仕様書を読み込んだ経験があまりないことがあります。より良い仕様書を書くためには、良い仕様書のお手本が必要です。じゃあそのより良い仕様書ってどこにあるのって話ですよね。完璧超人が執筆した仕様書があれば理想ですね。(レビューなしで完璧な仕様書を書ける人がいるならあってみたい…) そんな可能性はないので、プロジェクトではレビューを重ねてより良い仕様書を目指していくのが、普通の流れになると思います。ということを踏まえて、皆さんの周りに仕様書ってありますか?仕様書を読み込む経験ってあまりないんじゃないでしょうか? 技術選択の理由:なぜAIと協力するのか そこで提案です!小さく仕様書を書いてみませんか?いきなり完璧な仕様書なんて不可能ですし、レビューアーを確保するのも大変ですよね。そこでAIを活用します。 AIを活用した仕様書作成フロー AIに仕様書を書いてもらい、それをレビューする。私たちは意図を伝えて仕様書を作成してもらい、人間がレビュアーとして参加し、AIと協力する形で仕様書を作成していくフローです。 実装詳細 CLAUDE.mdの具体的な記述例 前提としてAIはコードを書きたがります。設計段階では、目的や禁止事項をCLAUDE.mdに定義しています。 実際に私が使っているCLAUDE.mdの中身を見てみましょう: # 設計フェーズのルール ## 目的 AIに人間の意図を適切に伝えて効率的な開発を行う ## 設計フェーズで行うこと - 型定義の設計 - データベース構造の設計 - API 仕様の定義 - アーキテクチャ設計 - 機能要件の明確化 - 非機能要件の定義 ## 設計フェーズで禁止すること - ❌ 実装コードの記述禁止 - ❌ 具体的なロジックの記述禁止 - ❌ ライブラリの選定禁止 - ❌ 具体的な関数実装禁止 ## レビューポイント - 要件の抜け漏れはないか - 設計の整合性は取れているか - スケーラビリティは考慮されているか - セキュリティ要件は満たしているか このように明確にルールを定義することで、AIが設計に集中してくれます。 仕様書作成の具体的な手順 要件の整理 :何を作りたいかを箇条書きで整理 AIとの対話 :CLAUDE.mdのルールに基づいて仕様書を依頼 レビューと修正 :作成された仕様書を人間の視点でレビュー 反復改善 :不足部分や曖昧な部分を繰り返し修正 仕様書のテンプレート例 # 機能仕様書:[機能名] ## 概要 [機能の目的と概要] ## 機能要件 - [要件1] - [要件2] - [要件3] ## 非機能要件 - パフォーマンス要件 - セキュリティ要件 - 可用性要件 ## データ構造 [必要なデータ構造の定義] ## API仕様 [エンドポイントの定義] ## 制約事項 [技術的制約や業務的制約] 動作確認・検証 実際の効果を検証してみた 従来の開発フローと比較してみました: 項目 Before(従来の人間だけでの開発) After(AIと協力した仕様書駆動) 仕様検討 開発中に随時(割り込み多数) 事前に1-2時間 開発時間 1週間 2日 手戻り回数 平均3-4回 平均1回 特に 開発時間の短縮 と手戻り回数が顕著に現れました! まだまだ検証中の段階なので、小規模な検証なことは留意しておいてください。 AIと協力する副次的効果 仕様書を書くことの効果は、開発前に作成したい機能の整理ができることです。 AIと一緒に仕様書を作成する副次的効果として、AIが作った仕様書をレビューする経験が得られます。仕様書の段階で、こちらの意図が適切に伝わっていなければレビューして修正します。これにより開発前に検討不足や考慮不足を抑えることができます。完璧なレビューは不可能ですが、それは経験を重ねることで改善していくものですね。 成功事例:実際のプロジェクトから 最近の検証プロジェクトでは、以下のような成果が得られました: ユーザー認証システム :仕様書作成1時間 → 実装1.5日 データ分析ダッシュボード :仕様書作成2時間 → 実装2日 API統合機能 :仕様書作成1.5時間 → 実装1日 いずれも従来の3-4倍の速度で完成させることができました。 課題と今後の展望 現在の制限事項と改善案 まだ完璧ではありません。AIの理解度に依存する部分があり、複雑な業務ロジックは人間の補完が必要です。また、チーム内での標準化やレビュー観点の統一も課題ですね。 短期的には仕様書テンプレートの標準化とAIプロンプトの最適化を進めています。 いっそのこと 、将来的にはAIが要件定義から運用まで一貫してサポートしてくれるような環境を構築したいですね。 まとめ 今回は、AIと協力した仕様書作成フローについて詳しく見てきました。 「仕様書アレルギー」を克服し、効率的な開発を実現する方法として: 小さく始める仕様書作成 :完璧を目指さず、まずは基本的な要件から AIとの協働レビュープロセス :AIに作成してもらい、人間がレビューする 設計フェーズでの明確なルール設定 :CLAUDE.mdでの禁止事項と目的の明示 段階的な開発プロセス :設計→開発→ブラッシュアップの3段階 これらの知識を活かして、皆さんもAIと一緒に仕様書作成にチャレンジしてみてください!最初は慣れないかもしれませんが、開発効率の向上を実感できると思います。 実際のプロジェクトでどちらを選ぶべきか、迷うところですよね。でも、一度この方法を試してみれば、その効果を実感していただけるはずです。 次回は、実際の開発フェーズでのAI活用術について書く予定です。お楽しみに! ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post AI協働で仕様書アレルギー克服!開発時間を1週間→2日に短縮する実践法 first appeared on SIOS Tech. Lab .
初めに AIと一緒に開発をするようになってから、フロントエンドとバックエンド両方を爆速で開発することができるようになって、検証が爆速で進むようになった龍ちゃんです。 AIが混乱しないようにプロジェクト自体を整備する方法についてお話しします。AIと一緒に開発を進める開発手法に関しては、以下の記事で解説をしています。 Claude Code革命!3フェーズ開発で効率的な開発:計画→実装→検証術 AI協働で仕様書アレルギー克服!開発時間を1週間→2日に短縮する実践法 Claude Code仕様書ベースでハマる6つの落とし穴!失敗回避の備忘録 AIに触らせないファイルを作ることで過剰な生成を禁止したり、自動生成パイプラインを構築して人為的なミスを防ぐなど、プロジェクト構造レベルでの対策が重要です。 実際に発生した問題事例:型定義の齟齬 まず、実際に私が遭遇した問題から紹介します。 環境構成 フロントエンド : Next.js バックエンド : Nest.js 発生した問題 フロントエンドとバックエンドで 型定義の齟齬が発生 していました。バックエンドで定義した型をフロントエンド側で再定義して、変更が反映されておらず 参照エラーが発生 する状況でした。 この問題の根本原因は、AIが各環境で独立して型定義を生成してしまい、バックエンドの型定義変更がフロントエンドに反映されないことでした。人間の開発者なら「バックエンドで型が変わったから、フロントエンドも更新しなきゃ」と気づけますが、AIは各ファイルを独立して見てしまいます。 解決策:自動生成パイプラインの構築 この問題を解決するため、以下の自動生成パイプラインを構築しました: 1. OpenAPI Spec自動生成 Nest.jsからOpenAPI Spec を自動生成する仕組みを導入しました。これにより、バックエンドのAPI仕様が変更されると、自動的にスペックファイルも更新されます。 公式で提供されているので、コードレベルでOpenAPI Specを生成することができます。 2. フロントエンド側の自動生成 Orval を使用して、Next.jsに SWR + Axiosのリクエスト・型定義を自動生成 する仕組み を構築しました。OpenAPI Specから自動的にフロントエンド用のコードが生成されるため、バックエンドとフロントエンドの型定義が必ず一致します。 このシステムでは、SWRとAxiosを使ってAPIリクエストを行っており、データフェッチャーやカスタムフックが自動で提供されるため、非常に便利な仕組みになっています。 3. Claude への通知 最も重要なのは、 Claudeに変更不可と明確に通知 することです。自動生成されるファイルには、コメントやCLAUDE.mdファイルで「このファイルは自動生成されるため変更禁止」と明記し、Claudeが勝手に編集しないように徹底しました。 自動生成するためのコマンドと、どのファイルが変更不可なのかを明確に指定する必要があります。 プロジェクト構成の最適化 AIが迷わないよう、プロジェクト構成も工夫しています: / ├── CLAUDE.md # プロジェクト全体のガイドライン ├── docs/ # 計画・設計フェーズ │ ├── CLAUDE.md # 計画フェーズ専用ルール │ └── api/ # OpenAPI Spec └── application/ # 実装フェーズ ├── backend/ │ └── CLAUDE.md # バックエンド実装ルール └── frontend/ └── CLAUDE.md # フロントエンド実装ルール 各フェーズ用のCLAUDE.mdファイル配置 各ディレクトリに CLAUDE.md ファイルを配置し、そのディレクトリで作業する際の固有ルールを記載しています。例えば: application/frontend/CLAUDE.md : 自動生成ファイルの変更禁止、使用可能なライブラリの制限など application/backend/CLAUDE.md : API仕様変更時の手順、データベーススキーマ変更の注意点など docs/CLAUDE.md : ドキュメント作成時のフォーマット、必須項目など AIに触らせないファイルの明確化 過剰な生成を防ぐファイル管理戦略 として、以下のような対策を実施しています: 自動生成ファイルには必ず「DO NOT EDIT – Auto Generated」のコメントを付与 パッケージファイル(package.json等)の変更制限 設定ファイル類の変更制限 各CLAUDE.mdで変更不可ファイルのリスト明記 ただし、ここまで書いていたとしても、AIは結構無視することがあります。実際に、自動生成して編集禁止にしている設定ファイルを編集しに行って動くようにしたりとか、ダイナミックな手法をやってきたりするので、いくら書いていたとしても無視をする可能性があることは念頭においた方が良いと思います。 大規模プロジェクトでの課題と対策 フロントエンド・バックエンド開発者が異なる場合の同期 大規模プロジェクトでは、フロントエンドの開発者とバックエンドの開発者が違う場合に、いかに同期を取っていくかが重要な課題となります。 開発順序の調整 現在のシステムだと、バックエンドの開発をしてからフロントエンドの開発をするという順番になるため、この順序をどう合わせていくかが必要です。 同時開発のためのアプローチ 同時に開発を進めていくためには、以下のような手法が有効です: モック を使用した並行開発 型定義を先に作成 してOpenAPI仕様書だけを先に渡す Orvalで生成 したフロントエンドコードを使ってバックエンドと協調開発 このアプローチにより、フロントエンドとバックエンドの同時進行での開発が可能になります。 この手法の効果 自動生成パイプラインとプロジェクト整備により: 型定義の齟齬が完全に解消 AIが余計なファイルを触ることによる意図しない変更の防止 人間が後から「なぜこの変更をしたのか分からない」状況の回避 コードレビュー時の確認ポイントの削減 バックエンドを定義したら、そこからフロントエンドを並行して開発できますし、バックエンドとフロントエンドで型定義が異なるという問題がほとんどなくなりました。もちろん、バックエンドの定義自体が間違っていれば動作しませんが、フロントエンド側での型の不一致はかなり抑制できたと感じています。 これまでは自動生成の仕組みを使わずに開発していたため、コードが若干汚くなる傾向があり、フロント側で型定義の再定義が行われて連携が取れていないという問題や、型ファイルが増えていくという課題がありました。この仕組みにより、プロジェクト全体がより整理されたファイル構造になり、可読性が向上したと実感しています。 特に型定義の自動同期により、フロントエンドとバックエンドの開発を並行して進められるようになりました。 まとめ 正直、これは導入してみて一番良かったなと思える点ですね。ルールをあまり追加させずにAIに生成させるコードが圧倒的にきれいになりました。 ルールをガッチガチにしてコードをきれいにするというのも今後の検証として取り込んでいきます。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post AIと爆速開発!Next.js×Nest.js型定義同期の自動生成パイプライン構築術 first appeared on SIOS Tech. Lab .
はじめに ども!毎日毎日Claude Codeとお話して日課となっている龍ちゃんです。直近ではClaude Codeに関するお話を執筆していこうと思います。 最初は「これは革命的だ!」と思って飛び込んだClaude Codeでしたが、実際に使い込んでいくと、思った以上に奥が深くて、適当にプロンプトを投げているだけでは思うような成果が出ないことがわかってきました。 今回は、私が実際にClaude Codeを使い倒してきた中で見つけた、「Vibe Coding」から卒業するための実践的なTipsをまとめてみました。同じような課題を感じている方の参考になれば幸いです。 今回紹介する問題点・課題を解消するために検証した内容をまとめています。こちらも併せて読んでもらえると楽しいかもしれません。 Claude Code革命!3フェーズ開発で効率的な開発:計画→実装→検証術 AI協働で仕様書アレルギー克服!開発時間を1週間→2日に短縮する実践法 Claude Code仕様書ベースでハマる6つの落とし穴!失敗回避の備忘録 AIと爆速開発!Next.js×Nest.js型定義同期の自動生成パイプライン構築術 Vibe Codingの落とし穴 雑なプロンプトでは成果が出ない現実 「とりあえずやってみる」テンション感で始めがちなClaude Codeですが、これが最初の落とし穴でした。数行のプロンプトで開発に十分な意図が伝わっていないんですよね。 例えば、「4輪駆動で走る車を作って」と言っているようなもので、具体的な仕様や制約が伝わっていない状況になってしまいます。これでは、Claude Codeも困ってしまいますよね。 ドキュメント化が成功の鍵 解決策として見えてきたのが、 Claude Codingの前にドキュメント化しておく ことの重要性です。 具体的には、以下のような準備が必要になります: 既存のコードがある場合 /initはとりあえず打つ! 既存コードを読み取らせてドキュメントを作っておく Azureなどの構成などもある場合はドキュメント化しておく コーディングの前にタスク専用の設計書を作成する 設計書→Codingの流れを徹底する まずは設計書を作成して内容が人間の意図しているものと一致しているか確認しておく Claude Codeはコードを書きたがるから、設計書のみに中止させる Vibe Debugがつらすぎる問題 よくあるデバッグ地獄 Vibe Codingしていて、動かないことがそれなりにあります。エラー内容を入力して修正してもらうこともできますが、治らない場合は大胆な戦略をとることがあるんです。 例えば: フロントの改修をしているのに、バックエンドのコードを直そうとする 新規ファイルを作成してバージョンアップしたりする Bicepファイルを編集するときに、いったんリソースグループを削除してしまう 効果的なデバッグ戦略 エラー→Vibe Codingがつらくなる場合は、該当箇所のコードを読み込んで、 人間の観点+エラーメッセージ+調査指示 で取り組むことで精度が上がることがわかりました。 セッション管理の重要性 メモリ制限を理解する ドキュメント化していない知識は伝わっていないと思ったほうが良い です。Claude Codeはセッション型でメモリに記憶を保持していないので、セッションを閉じると記憶が失われると思ったほうが良いですね。 そのため、定期的なドキュメント管理とプロジェクトのコア部分の情報をドキュメント化して読み込ませておくことが重要になります。 適切なタスクサイズ 1セッション1タスク ぐらいの分量で収まるように進めることを意識しています。ドキュメント→タスクを完了させる動きをさせておくのがコツです。 セッションを閉じるとタスクの進捗が確認することができないので、セッションを閉じるときはタスクが完了したタイミングであることを意識しておきます。 巨大なタスクでなく、 2~3hで完了させる程度 でタスクのサイズを分割して進めるのが良いですね。タスクが大きすぎると、Claude Code側がフェーズを分割したりするので、フェーズ進行中はセッションを切らないようにしています。 実践的なTips集 不要ファイル・デバッグコンソールの管理 Vibe Debugの結果、不要なコードや不要なファイルが生成されていることがあります。これは、最終的にコミットやPRに含まないことが大切です。 最後に「参照していないコードを削除しておいてください。不要なファイルは削除してください」と指示することで、きれいな状態を保てます。 ディレクトリ単位で不要になったファイルは削除しておくことも重要です(過去のプロジェクトなどのファイルがある場合は削除しておきましょう)。 フロントとバックの型定義の不整合対策 バックエンドとフロントエンドでAPIの型が不整合が発生していたことがありました。 対応策: フロントのコードを作成する前にバックエンドのソースを読ませる バックエンドのAPIへアクセスする部分は自動生成させてそれを使用するように変更する(検討中) CLAUDE.mdの活用と注意点 特にセッションが長くなった場合は CLAUDE.mdを無視しがち になります。AIは昔のコンテキストほど優先度が下がるというのはよくある話ですね。 対応策: セッションが長くなった場合はいったん切る セッションの開始時には必ずCLAUDE.mdを読み込まれるので、セッション内で編集するファイルの領域を決定する バック→フロントの連続ではなく、バック作成→OpenAPI Spec→フロントという連携をする ただし、 セッション開始時からCLAUDE.mdを無視することもあります 。そういった場合は、追加のプロンプトで指示を与えることが効果的です。 具体的には: いったん処理を止めて、追加のプロンプトで再指示 「無視されているCLAUDE.mdを再度読み込んでください」といった明示的な指示 重要なルールを#コマンドで再度強調する これらの方法で、CLAUDE.mdの内容を確実に反映させることができます。 ファイルスコープの明確化 編集するファイルと触らないファイルを決定する ことが重要です。例えば: ビルド後のファイルを直接変更しようとした フロントの改修中にバックエンドのコードを変更しようとした このような問題を避けるために、事前にスコープを明確にしておきます。 プログラミングファイルによる違い Bicepファイルは難しい Bicepファイルの依存関係周りの設定が難しいことがわかりました。 回避策: 依存関係やリソースが完成した後で連携する処理はShell ScriptでAzure CLI経由で処理を行う Bicepの処理はリソースの作成のみに注力させておく GitHub Actionsも要注意 GitHub Actionsについても課題があります: 提供されているActionsを読み込んで使うことが難しい 割と大胆なActionsを書いてくる(Azure CLIとかGitHub CLIを使うような) 回避策: GitHub Actionsはプログラム言語レベルで多岐にわたらないため、Vibe Codingではなく、人力コーディングで行ったほうが良いという結論になりました。 まとめ 今回は、Claude Code使用時の「Vibe Coding」から脱却するための実践的なTipsをまとめてみました。 重要なポイントをまとめると: 事前のドキュメント化と設計書作成を徹底する セッション管理とタスクサイズの適正化 ファイル種別による特性を理解して使い分ける 型の不整合やスコープの明確化に注意する Claude Codeは非常に強力なツールですが、適切な使い方を身につけることで、その真価を発揮できるようになります。皆さんも、ぜひこれらのTipsを参考に、より効率的な開発フローを構築してみてください! LinterとFormatterの設定など、基本的な開発環境の整備も忘れずに。ここは人間と一緒ですからね。 Claude Codeでの開発、一緒に極めていきましょう! ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 「適当にプロンプト投げるだけ」を卒業!Vibe Coding脱却術:【Claude Code】 first appeared on SIOS Tech. Lab .
はじめに みなさん、こんばんは。最近はClaude CodeでAIにコードを書かせる検証をしている龍ちゃんです。 先月はあまりブログを書けなくて、僕もビックリするぐらい三本しか書いていませんでした。今月は多少時間を取ってでもブログを書いていこうと思っています。 まず Vibe Codingをやってみて感じた課題感 に関してはこちらでまとめています。 AIが悪いのではなく、人間が悪い 色々検証して思ったことですが、 だいたい人間の入力が悪い というか、人間のせいなんですよね。AIの仕組みでそれを解消しようという試みもありますが、業務でAIを使うなら、人間の入力が悪いと考えて、入力の方を改善していく方が、AIの精度向上を待つよりも効果的だと思います。人間の入力をいかに変えていくかということにフォーカスを当てて検証を進めています。つまり、 Claude Codeが悪いんじゃなく、人間が悪い んです。 人間の入力をAIが理解しやすいように作っていくという前提を押さえてもらえればと思います。 従来手法の限界:ペアコーディング 最初の1〜2ヶ月間、Claude Codeを使い始めた頃は、Vibe Coding(ペアコーディング)という手法で開発していました。プロンプトとしては100から300文字ぐらいのシンプルなものを投げていました。 これだと小規模な改善や機能追加には非常に優秀でした。リファクタリングも効果的でした。しかし、大規模な開発(例えば、一つのページ全体を組むような)をしようとすると、意図したとおりのものを作ってくれないことがありました。AIが自由に解釈しすぎて、変なものを作ってくることもありました。 ペアコーディングの具体的な問題点 実際にペアコーディング手法で開発していて気づいた課題があります。雑なプロンプトを投げて作ったものだと、やっぱり意図したものが作られないということが頻繁にありました。また、ペアプログラミング的な使い方だと人間の手が入る分、作業が遅くなるという印象もありますね。 特に既存プロジェクトで、すでにコード規約やディレクトリ構成が決まっている状態なら、それを学習させてからエンドポイントを追加する作業は割と有効だと思います。しかし、 300文字程度で自分が作りたいものを説明するのは文豪でも難しいでしょう 。文章が苦手な人にとっては尚更です。 ここで思い出してほしいのが「人間が悪い」ということです。そういう意味では、「意図したものができない」と言っている人は、当然のことを言っているだけなのです。 このような背景があり、リファクタリングは得意分野だと言えます。既存コードのパフォーマンス問題を改善するといった単純な指示は分かりやすいです。しかし新機能開発となると話が違います。Claude Codeで自分の意図したとおりのものを作る手法についてお話ししようと思います。 ディレクトリ構成とファイル管理 ディレクトリ構成としては、計画・検証用のドキュメント部分と実装コード部分を分けています。 / ├── CLAUDE.md # プロジェクト全体のガイドライン ├── docs/ # 計画・設計フェーズ │ ├── CLAUDE.md # 計画フェーズ専用ルール │ ├── features/ # 新機能計画 │ ├── bugs/ # バグ調査・修正計画 │ └── research/ # 検証結果・知見 └── application/ # 実装フェーズ ├── backend/ │ └── CLAUDE.md # バックエンド実装ルール └── frontend/ └── CLAUDE.md # フロントエンド実装ルール 新手法:3フェーズ開発 最近実践している方法では、開発フェーズを「 計画 」「 実装 」「 検証 」の3つに分けています。 計画フェーズ まず「計画」フェーズでは、やりたいことの仕様書をAIに説明し、文書化してもらいます。 このフェーズではコードを一切書かせません (型定義などの簡単なものは除く)。 AIが返してきたドキュメントを確認し、自分の意図しているものかを確認します。これによってAIが自由に解釈する余地を減らします。 計画フェーズで効果を発揮するCLAUDE.mdや具体的な手法・効果については「 AI協働で仕様書アレルギー克服!開発時間を1週間→2日に短縮する実践法 」で紹介しています。 実装フェーズ 次に「実装」フェーズでは、作成した仕様書を読み込ませ、それに基づいて実装してもらいます。説明は全て計画フェーズで作った仕様書に含まれているので、それを入力として与えるだけです。 人間は監視役に徹し、AIが暴走した場合は適宜小さなプロンプトで修正します。 龍ちゃん 実装時に陥りそうな課題に関しては、「 Claude Code仕様書ベースでハマる6つの落とし穴!失敗回避の備忘録 」でも書いています。 検証フェーズ 最後の「検証」フェーズでは、仕様書の不備がどこにあったか、その結果どのような変更が加えられたかを分析します。これにより実装と仕様を照らし合わせ、根拠のない編集を防止できます。実装後は人間の手で確認作業を行います。 計画と実装を比較することで、レビューした仕様書の中で不足があった分などを特定することができます。 計画ドキュメントと実装の内容を確認して、計画と実装の差異がある点をまとめてください。 ここで不測の指摘があるってことは、仕様書や計画が不足しているということになります。ここで学びができますね。 実際の開発効果:驚異的な時間短縮 この3フェーズ手法を実践してみて、開発期間は圧倒的に短縮されました。具体的な事例をご紹介しますと: 小規模システムの例 バックエンドのエンドポイント2つ フロントエンドの画面1つ 開発時間:約30分で完了 作った画面は結構シンプルなシステムでしたが、エンドポイントの仕様としては単純なものでした。この規模なら、仕様書作成から実装まで含めて30分という短時間で完成します。 中規模システムでの限界 一方で、バックエンドのエンドポイントが4つで、フロントエンドの画面でそれら4つのエンドポイントをいい感じに使うような中規模なものを作ろうとすると、セッションが限界になったりということがありました。この辺はタスクを分割するべきだったなと考えています。 この手法の効果と学び、そして課題 現在はプライベートリポジトリで検証しているため、大規模プロジェクトへの導入経験はまだありませんが、中規模程度の開発であれば強力なツールになると思います。特に プロトタイピングでは大きな力を発揮しそう です。 バグ発生率と仕様漏れの実態 開発時の課題として、バグというよりも 仕様漏れ の方が圧倒的に多いです。仕様書を元に開発するので、仕様から漏れている内容が実装している最中やテストしている最中に気づいたりします。これは大体バグというより仕様漏れかなと思います。 ビルドが失敗するようなケースは結構あるんですが、PrettierやESLintなどのフォーマッターやリンターをちゃんと定義しておいて、その定義の下で処理してもらうようにするとある程度コードとしては綺麗になります。 ただし、ディレクトリ構成やプロジェクトのコード設計思想みたいなところを伝えていないと、fat controllerのように1ファイルに対して過剰にコードを書いてしまうみたいなことは割とありがちですね。 学習効果の発見 個人的に学びになった点としては、仕様書作成が苦手な私でも、AIが返してきた仕様書を見て「分かりやすい」と感じることがあります。学習的な側面でも価値があると思います。 完璧な仕様書があれば理想的ですが、そういうものは実際には存在せず、どこかに不備があるものです。だからこそ、 機能ごとに段階的に仕様書を作っていくアプローチが有効 だと思います。 また、検証フェーズで計画の不備を見つけるプロセスを踏むことでレビュー観点を育てることができます。レビューをする体験そのものが貴重です。 実践での注意点とコツ ここにまとまり切っていない部分に関しては別途「 Claude Code仕様書ベースでハマる6つの落とし穴!失敗回避の備忘録 」でまとめています。 この手法が向いていない作業 実際に検証してみて、 この3フェーズ手法でも上手くいかない作業 があることが分かりました。 プロジェクト構造の大幅変更 プロジェクトのディレクトリ構成を変えるような作業は、Claude Codeだとパスの解決なども自動でやってくれるのですが、使っている・参照しているファイルを再帰的に検索してということになるので、実際時間がかかってしまうという印象があります。 簡単なリネーム作業 関数のリネームのような作業に関しては、人間の手作業の方が圧倒的に早いです。VS Codeのリファクタリング機能のようなサポート機能を使うのがいいんじゃないかなと思っています。 フロントエンドデザインの特殊性 フロントエンドのデザインに関しては、仕様書を書いて作るというのはあまり向いていない かなと思ってます。 理由としては: フロントエンドで最初に想定していた仕様が全てを満たすことって無い UIを文章で説明するのって結構な分量が必要 分量が増えるとAIが混乱する確率も上がる 実際に画面を見て「何か違うな」という瞬間が割とある 自分の書いている仕様と自分の頭の中にあるイメージが合ってることがあまりない コンテキストが膨大に増えていく そのため、フロントエンドに関しては別のアプローチが必要だと考えており、別途検証を進めています。 Claude Codeの”忘れっぽさ”との付き合い方 実際に運用していて気づいたのですが、 CLAUDE.mdにいくら設定を書いても、コンテキストを無視することが結構あります 。特に長時間の作業や複雑なタスクになると、最初に設定した原則を忘れてしまうことがありますね。 そういう時の対処法として、私は以下のようなアプローチを取っています: リアルタイム修正パターン 動作を確認しながら進めて、「あ、意図した挙動をしてないな」と感じた瞬間に処理を止めます。そして、プロンプトに守ってほしい原則を改めて追加して再度実行する、という感じですね。 事後確認パターン 処理が完了した後に、「あれ?原則守ってないですよね?」とClaude Codeに詰める作業も行っています。これによって、なぜその判断をしたのかを確認し、次回の改善につなげています。 この経験から学んだのは、 AIも完璧ではない ということです。「人間が悪い」と言いましたが、同時にAI側の限界も理解して、適切にガードレールを設ける必要がありますね。完璧な仕様書があれば理想的ですが、そういうものは実際には存在しないのと同じように、完璧なAIも存在しません。だからこそ、人間とAIの協働において、お互いの特性を理解することが重要だと感じています。 適用に向いているプロジェクト 逆に、この手法が効果的なのは: バックエンドのAPI開発 :仕様が明確に定義しやすい データ処理ロジック :入力と出力が明確 既存プロジェクトへの機能追加 :コード規約やディレクトリ構成が既に決まっている プロトタイピング :完璧性よりもスピードを重視 まとめ 私は新機能開発とバグレポートをこの二つの方法で分けて対応しています。計画段階で仕様書を挟むことで、意図したものを作れるようになります。 ただし、万能ではありません。プロジェクトの性質や作業内容によって、従来のペアコーディング手法や人間による手作業の方が効率的な場合もあります。 適材適所で使い分けることが重要 ですね。 皆さんも、ぜひこの3フェーズ開発手法を試してみて、自分のプロジェクトに合うかどうか検証してみてください!何か質問や改善点があれば、コメントでお聞かせください。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Claude Code革命!3フェーズ開発で効率的な開発:計画→実装→検証術 first appeared on SIOS Tech. Lab .