👨‍💻

Do It with AIでアプリケーションを構成する:DevSecOpsに組み込む(開発編)

2025/02/16に公開

こんにちは。山下です。

前回は生成AIをアプリケーション開発/インフラ構築に活かせる可能性とその課題について触れました。生成AIの得手/不得手とリスクを理解した上で開発と構築を行う事で、オペレーションエクセレンスの向上につなげる事ができます。

実際にAmazon Qを用いた活用をここでは考えてみます。まだ発展中かつプレビューのものも多くあります。正解となるもの、ベストプラクティスとなるものもありませんが、表題の通り、DevSecOpsでの組み込みを行い課題の把握と解消を試みます。

DevSecOpsの概要

DevOpsという単語は一般的なので詳細は割愛しますが、アプリケーションの製造からデリバリーまでを自動化、効率化できるモダンアプリケーションには欠かせない思想であり、技術です。よくCI/CDツールとモニタリング(監視)ツールを組み合わせた内容で語られる事も多いです。

様々なサイトや書籍でも定義されていますが、AWSでは以下のようにDevSecOpsは定義されています。要するにセキュリティとコンプライアンスを担保しながらもDevOpsを実現する取り組みであり、それを実現するツールチェーンのことでもあります。

ソフトウェア開発プロセスのすべての段階のセキュリティテストを統合する手法です。これには、効率的で安全なソフトウェアを構築するために、開発者、セキュリティの専門家、運用チームの間のコラボレーションを促進するツールとプロセスが含まれています。DevSecOps は、ソフトウェアを構築しているすべての人にセキュリティに関する共通の責任を持たせる文化の変革をもたらします。

https://aws.amazon.com/jp/what-is/devsecops/

設計→コーディング→ビルド→テスト→開発リリース→本番デプロイ→運用→監視の”DevOps”にセキュリティを担保する要素を盛り込んでいます。アプリケーションの信頼性/運用性/コスト効率/性能の向上を担保しながら、セキュリティについても担保するのがポイントです。

https://aws.amazon.com/jp/builders-flash/202208/create-devsecops-pipeline/

どのフェーズでAmazon Qを活用できるのか?

さっそく、DevSecOpsの工程表における各工程で当てはめる事を考えてみましょう。前提となるのは私が以前考えた新しい責任共有モデルです。生成AIが持つ課題とその課題に対する責任を負うのは我々クラウド利用者と考えています。一方、今まで通りAWS責任(管理)となるマネージドサービス利用を組み合わせる事で責任や運用負荷を負わずに済みます。

文字通り、コードやファイルを生成するCI/CDの場面では非常に有用な一方で、ハルシネーション是正やビジネスの最終目的を満たしているかのチェックを行うために設計/計画フェーズではあまり利用しない方が良いと考えています。また、リアルタイムでの検出と対応が求められる運用/監視フェーズでもその曖昧さはかえって危険になります。

コンテナ/サーバレスを使えばモダンアプリケーションではないのと同じで、生成AIを使えば運用が完全に自動化したり人件費の大幅削減につながる訳ではありません。むしろ管理工数やリスクが上がる可能性さえあります。
他で代替できるもの、確立したものを扱えるのであれば生成AIに任せずともよいのです。

さらにこの工程を分解してAmazonQを活用することを以下に考えます。極端な話、全てのフェーズに生成AIを組み込むことはできますが、リスクやカバーを考えると得手不得手があるように感じます。

工程 生成AIを利用すべきか 利用サービス 責任担保の方法
Plan(要件定義) 支援にとどめるべき 生成AI全般 人間がリードして要件がブレていないか他工程で判断するための材料とする
Plan(基本/詳細設計) 支援にとどめるべき Amazon Q for Developer 人間がリードして要件がブレていないか他工程で判断するための材料とする
Code(コーディング) 積極活用すべき Amazon Q for Developer 設計で決めた機能要件と非機能要件と照らし合わせてコード生成内容をセルフチェックし、変数や関数を変更する
Code(デバッグ/レビュー) 支援にとどめるすべき Amazon Q for Developer 品質を担保する関門となるため人間がチェックすべき、ダブルチェックとして使うのもあり
Code(コミット/マージリクエスト) 積極活用すべき Amazon Q for Developer コミットの内容を要約、説明する文章の作成に有用
Code(SAST/SCA) わざわざ利用しなくてもよい CodeGuru Security、その他サードパーティ製品 最新の脆弱性情報が大切なものなので専用のツールやサービス利用が運用面でもよい
Build(ビルド) 積極活用すべき Amazon Q for Developer+CodeBuild等CIツール パッケージ定義やDockerfileなどビルド定義の作成に有用
Build(単体テスト) 積極活用すべき Amazon Q for Developer+CodeBuild等CIツール 積極活用すべきだが、AmazonQではJava/Pythonのみなので今後に期待
Test(結合テスト/総合テスト) 支援にとどめるべき 生成AI全般+Selenium等ツール/サービス テストシナリオを考える補助にはなりえるが、実際のテスト次第で品質が大きく変わる
Test(DAST) わざわざ利用しなくてもよい サードパーティ製品 実際にアプリケーションにアクセスして確認するのが大切なものなので専用のツールやサービス利用が運用面でもよい

各フェーズでの対応

では、具体的に各フェーズでの適用を考えていきます。活かせるところでAmazonQを組み込むと生産性の向上が期待出来ます。一方、あえて活用しない、補助として使うことで価値を発揮できる場面もあります。

Plan(要件定義/設計)

ウォーターフォール型なのかアジャイル型なのかによってその重さや拡充度合いは異なるものの、アプリ/インフラの基盤部分となるのがこのフェーズです。

要件と設計が定まっていれば、コーディングやテスト、AWS設計、その後の運用立て付けで軌道修正が出来ます。ここは要件の要約や観点の洗い出しを手伝うなど補助に限定したいところです。

各フェーズで生成AIがハルシネーションしたり、プロンプトの実行者の指示が不足している場合、独自のビジネス上の要件がある場合によい開発ができません。品質とセキュリティを担保するためにも要件の整理と設計が基準になります。


Code(コーディング/レビュー)

このフェーズでは、Amazon Q Developerを活用することで、コーディング作業の効率化と品質向上を図ることができます。特に、コード生成、バグ検出、リファクタリング支援において強みを発揮します。ただし、生成されたコードは必ず人間による確認とレビューを経る必要があります。

このコーディングフェーズでの具体的な活用方法として、以下の2つのアプローチが考えられます。1つ目は個々の開発者がIDEプラグインやCLIを通じて活用する方法、2つ目はGitLab Duoなどのチーム開発環境に組み込む方法です。どちらの場合も、生成AIの支援を受けながら、人間による適切なレビューと品質管理を組み合わせることが重要です。

実装案

IDEプラグインにAmazonQを組み込んだ場合で実際のフローを考えてみます。開発者がコーディングを行い、Gitにレビュー後マージするケースをここでは考えました。一方、レビュアーが開発者も兼ねて一人でやりきる事も出来なくはないのがAmazonQの驚異的なところです。

特にAmazonQの生成結果の最終品質責任を持つ箇所に生成AI品質ゲートというものを記載してみました。ここを疎かにするとAmazonQに対するユーザー責任の放棄となってしまうため、不可欠な箇所です。

0.生成の前に

Developer Proの購入か利用しているIDE上で必ずオプトアウトしましょう。検証利用といえど、意図せずしてワークスペース上のコードをAmazonQ(Bedrock)に送ってしまう危険性があるためです。直接すぐに実害はないですが、情報漏洩に繋がりかねないため有事に備えて有効にします。また、AWSに保管されるデータはAWS責にはなりますが、コードは著作物かつ時に攻撃の対象にもなりえるため、ユーザ側で取り扱い前に責任を持つべき項目です。

https://docs.aws.amazon.com/ja_jp/amazonq/latest/qdeveloper-ug/opt-out-IDE.html

1. /devでの生成

新規開発か既存改修かで違いはありますが、Planフェーズで定めた要件をプロンプトでできるだけ詳細に伝えていきます。改修の場合は既存コードを材料にできますが、新規開発の場合は要件をどれだけAmazonQに伝え切れるかがポイントになります。Planフェーズでどこまで詰められていたか、プロンプトエンジニアリングでの深掘りがこのフェーズでは重要です。

https://www.promptingguide.ai/jp

2. 生成結果への対応

理想通りのコードが初めから生成される可能性は高くありません。少なからずズレていたり、全くの見当違いの場合もあります。それぞれの対応方法を考えてみたいと思います。

プロンプトエンジニアリングによる依頼主側のリクエストを伝える方法を工夫するのが一番簡単で有効です。また、AmazonQ DeveloperではAgent機能で同一ワークスペース内のコードを元にした生成を行う事ができます。プロンプトによる対話だけで理想のコードに辿り着けない場合は自分で手動修正するか、サンプルコードを自分で書いてみる事が挙げられます。

想定されるケース 手法 具体的なアクション
依頼内容が漠然としていたり、伝えた事が反映されていない プロンプトエンジニアリング ベストプラクティスに沿い、プロンプトの詳細化、複数回に分けての依頼、ファイル単位での生成を実施
仕様はある程度伝わっているものの、規則や書き方について伝わってない RAG/Agent サンプルコードと観点を提示し同じようなコードを作成するよう依頼する
上記での改善が見込めない場合、後は微修正で済む場合 手動での修正 生成されたコードをそのまま書き換える、自力で全部作成する

+プロンプトWiki/ライブラリを作成する

チーム開発や複数案件におよぶ場合、Gitにコードと同時にプロンプトを添える事が有用になると考えています。どの粒度で、どの単位で、どのような手法でプロンプトを定義したのかを実例としてGitのWikiに加えます。これをメンバーに共有する事でAmazonQを扱う初心者やチームメンバーによるコード生成の質向上が期待出来ます。実際の生成コードがあるためプロンプトの実例としてGitに上げる事をここでは考えています。

また、レビュー前にプロンプト提出を求めて雑なプロンプトや要件を満たす書き方だったかをコードを見る前段にレビュアーが確認することも出来ます。さらにメンバーによるプロンプトインジェクションやシークレットデータの聞き出しが行われていないかの内部監査としても機能します。

3. /reviewでのダブルチェック

/devで作成したものをいきなり/reviewに通すのはあまり意味がありません。プロンプトを出した人が何も理解/確認せずに丸投げしているだけになるためです。生成結果をレビュー/フィードバックして内容を構成し、そのダブルチェックを行うために使います。

レビュー観点としては、一般的なコードの可読性、保守性、セキュリティ上の懸念、ベストプラクティスへの準拠などを変わらず確認します。特に意図しない脆弱性や非効率な実装が含まれている可能性があるため慎重に確認します。

それでもコード量が多かったり、レビュアーの知識/経験が少ない事による見落としや抜け漏れがどうしても生じます。今度は人間をフォローするためにAmazonQの力を借りる逆のアプローチをとります。このダブルチェックによって更なる品質の担保が見込めます。

一方、/reviewでは修正方法もレクチャーされますが、下記のようにパスワードを環境変数ではなくSecretsManagerに格納する、WAF/Shieldなどコードの枠を超えた箇所での担保も考えられます。補助として優秀ですが、解決策はコード以外の観点でも考えたいところです。

+Java/Pythonなら単体テストコードを/testで生成

現在Java/Pythonに限定されていますが、単体テストコードを/testで生成できます。のちのビルド工程で利用できます。各関数に対する入出力を確認できます。

4. /docで内容をまとめレビュアーにマージリクエストを行う

初回コミット時や追加でクラスを作成する際には全体を説明できる/docで内容をまとめられます。マージリクエストでのレビューや全体俯瞰をするためにMarkdown出力を行うので有用です。ただし英語のため、必要に応じて翻訳は必要になります。

修正や追加を行った特定のコードに対して解説するよう依頼する事も出来ます(コードを選択してExplain selected codeと打つだけ)。より修正した箇所について触れたい場合はこの中から抜粋またはプロンプトで細かく内容を確認します。

+Git付属の生成AIでマージリクエストを説明する

GitLabでは有償ライセンスでAmazonQが利用でき、マージリクエストのサマリを実際のマージリクエストに合わせて作成する事が出来ます。レビュアーが/reviewでコードを追加で確認する事も出来ます。いずれのCodeの工程でも日本語訳を行う必要が現状ではありますが、相当な工数削減が期待でき、人間では見落としてしまう要素をダブルチェックする事も出来ます。

https://aws.amazon.com/jp/blogs/news/introducing-gitlab-duo-with-amazon-q/

+SASTでGit上のコードを定期健診する

CodeGuruやサードパーティー製品のSASTをGitに対して定期的にスキャンを実行する事でより、最新のCVE,CWE情報を基にコードが抱える脆弱性や問題を検出できます。これはAmazonQを用いる用いないに関わらず実施したい項目です。

ここで注意すべきなのはAmazonQで/reviewを行ったからセキュリティを担保できたと思わない事です。何故なら、/reviewが行われるのはコミット前やマージ直前であり、Git上のしばらく変更が加えられていないコードへのチェックを行えないためです。AmazonQでもカバーできない範囲なのでSASTで担保したいところです。


Build(ビルド)

出来上がったソースコードに対してパッケージ化やコンテナイメージ化を行います。

GitへのコミットをトリガーとしてCIツールでビルド、テストを実施してそこで合格して初めてマージリクエストとする場合とマージリクエスト後にビルド、テストを行うケースがあります。

ここではマージ後にビルドトリガーが起動するという内容でAmazonQをBuildに組み込むケースを考えてみます。

実装案

CodeBuildで成果物を作成する場合を考えてみます。他のCIツールでもよいですが、Gitをセットにする事をここではマストとしたいと考えています。なぜならGitOpsの特性と組み合わせる事でCodeで行って来たのと同じようにレビューしたBuild/CIツール定義だけをGitにマージする運用が組めるためです。そしてGitOpsのGitですべてのファイルを管理するという思想がAmazonQの生成物との相性が良いと考えているためです。

https://aws.amazon.com/jp/blogs/news/automating-amazon-eks-with-gitops/

Gitへのコミット,PR,MRがいつ、誰が行ったのか証跡として残るのに加えて、動いていた時期へのロールバックも簡単になります。さらにGitに限定する事でCodeBuildの定義が外部から持ち込まれる事を制限する事も出来ます。

品質担保と効率化のためにbuildspec.yamlやDockerfile、Makefile、xmlファイルなどビルドに必要な資材の生成をAmazonQに支援してもらう一方でCodeフェーズで行ったことをこのフェーズでも実施する事でAmazonQに任せっきりでないビルドが行えます。

1. /devでのビルド定義生成

/devではコードだけでなく、yamlやxml、MakefileやDockerFileなどビルド定義ファイルの生成も行えます。以下はサンプルのため簡単ではありますが、ビルド定義が多段になる場合に有用です。この程度であれば手動作成でも十分かと思いますが、記法のレビューや例えばDockerFileのコマンドの書き方が分からない場合にサンプルを得る事も可能です。

生成結果への対応や/reviewでのダブルチェックはコーディングの時と変わりません。ユーザーの責任を果たすためのハルシネーションチェック、品質チェックは同じように実施します。

2. /devでのbuildspec生成

/devではさらにCodeBuildのビルド定義を生成できます。こちらもビルド定義と同様に参照先やジョブが多段であったり、条件が複雑な場合に非常に有用です。CIのパイプライン自体は頻繁に変更されるものではないため、コードと違い確立した後は使いまわしが基本になります。

こちらもビルド定義と考えは変わりません。同じくユーザーが責任を持つ範囲と担保の仕方は変わりません。

3. ビルドジョブの手動実行

CIパイプラインは実際にジョブを手動実行してGitから成果物格納先までの一連のジョブが完了できるかで動作確認をします。CI自体がコーディング以降の作業自動化/効率化のための仕組みなので、CIを試験するコードを試験する…など無限自動化/試験になるのでここまで十分かと思います。

buildspec,CodeBuildの動作確認が取れたらそれをGitに上げ、編集権限を持つユーザーを一部に絞り追加編集を許容しないようにします。

ビルドの過程で外部やCodeArtifactを経由してパッケージなどが最終成果物に混入されます。Codeフェーズにてソースコードレベルでのセキュリティ担保をしても、ここで他の脆弱性を含むパッケージが含まれてしまえば台無しになってしまいます。

また、AmazonQを以てしてもビルド定義から外部から調達されるパッケージがどの脆弱性を持っているかを判定する事は難しいです。

マネージドサービスや3rdパーティー製品を利用する事をここでは強く推奨します。


Test(結合試験/システム試験)

ここでのテストは結合/総合試験を想定します。AmazonQでは残念ながら結合/総合試験シナリオや関連するコードを生成するといった事は現在行えません。ビルドされた成果物を実際にデプロイ出来る環境にデプロイして動作確認を行う必要があります。

自動化向きのテストとそうでないテスト

テストを自動化出来れば、人手も手間も削減が期待出来るため魅力的ですが、自動化する方がかえってそのための準備や保守に時間を要してコストがかかる場合があります。

繰り返し実施するような画面試験やライブラリやパッケージのバージョンアップに伴うリグレッションテストに向きます。これは生成AIに限らないトピックです。

一方で、UIの使い勝手やUX に関する定性的なテスト、あるいは新機能のアイデア出しや改善提案を必要とするテスト、アドホックで都度確認するような場合は人間の判断が必要となるため自動化には向いていません。

実装案

Seleniumをpythonで実行する場合などコードに落とし込む場合は引き続きAmazonQの恩恵を受けられます。一方、テストシナリオやカバレッジを担保するまでではありません。ここはまだ人間が責任を持ちつつ、シナリオを策定する事で今までの工程の担保とする事が出来ます。

試験コードをCode/Buildフェーズと同様に、ハルシネーション確認と意図した内容にするようプロンプトエンジニアリングやサンプルコード提供によるRAG/Agent対応で内容を詰めることが出来ます。/testでカバー出来ない範囲も考え方や当てはめる場所を考えれば出来ないこともありません。

1. 開発/ステージング環境でのデプロイ

DeployフェーズでのDeployは本番環境のことを想定しています。なのでややこしいですが、開発/ステージングでのデプロイはまだテストフェーズの範疇です。

本番環境を模したプラットフォーム(Kubernetes/ECS/仮想マシンなど)へ作成したアプリケーションを稼働させ、動作確認やそれぞれのコンポーネント間が連携できるかを確認できます。CodeDeployやGit付属のツール、GitOps用のArgoCDやFluxCDなどのCDツールを使ってデプロイの自動化もできます。

CodeDeployのappspecもBuildの時と同様にAmazonQで定義することも可能です。

2. /devでのテストコード生成

/devでSeleniumやCurlなどのコマンド実行を行うスクリプトを生成できます。考えられるブラウザ操作やAPIへのHTTPSアクセスなどWebに対する操作を想定した内容であれば要件を伝えて作成が出来ます。自動化できる(≒ルーティン)な内容の試験項目をコードに置き換えられます。

3. 手動または自動でのテスト実行

CDツールのデプロイ後作業として作成したテストコードを実行してその結果をファイルやテキストとしてエクスポートしたり、コンテナとして開発環境に常駐させてチェックを行い変化があれば検出するなど様々な実装/実行方法が考えられます。

+DASTツールで動的にアプリケーションをチェック

AWSでは標準のDASTツールがなく、サードパーティー製品やテストコードにセキュリティ項目を追加して行うかの2択になります。WAF/ShieldでブロックされるようなXSSやSQLインジェクション、認証の脆弱性などをコードからではなく実際のアプリケーションに対してスキャンしてチェックが行えます。そのため、できるだけ本番環境に模した環境を用意すればサービス影響なく原因を特定できます。


まとめ

今回は開発(Dev)でのAmazonQの活用ポイントとそれに対する品質とセキュリティ担保を確認しました。生成AIが作成する成果物に曖昧さや危険性がある以上ユーザ責任で、時には地道なレビューを通じて確認が必要なのが分かったと思います。とはいえ、経験の浅い駆け出しエンジニアや少ないメンバーと工期で頑張るエンジニアには頼もしい仲間にもなり得ます。

リードする責任と実力が必要にはなりますが、時間削減と効率化、チームメンバーの成長に繋げる事ができます。

Proライセンスの導入やAWS Organizationによるオプトアウト強制化やGit閲覧権限を絞って、情報漏洩を避ける、事前にコードの納入先とAmazonQ使用の合意を行って開発業務をセキュアに効率化してみましょう。

Discussion