みずほリサーチ&テクノロジーズが AWS CDK で実装したマルチアカウント管理の仕組み ~ 第 3 回 組織単位ごとのガバナンス戦略 ! AWS Service Catalog 製品のセキュリティ運用と CI/CD パイプライン実践例
2026-02-03 | Author : 松尾 優成 (みずほリサーチ&テクノロジーズ株式会社, ヴァイスプレジデント)
はじめに
builders.flash 読者の皆さん、こんにちは ! みずほリサーチ&テクノロジーズ株式会社の松尾です。
大変ありがたいことに、今年も当社の AWS 活用事例を紹介させていただくことになりました。当社では AWS Cloud Deployment Kit (AWS CDK) を活用して、マルチアカウント環境の管理基盤を構築・運用しています。
これまでの連載では、AWS Service Catalog を使ったセルフサービス型機能の提供と、AWS Step Functions を活用したアカウント発行処理について解説してきました。今回は組織単位 (OU) ごとに異なるデプロイ戦略を採用した、より実践的な運用手法をご紹介します。
- 第1回:AWS Service Catalog を使ったセルフサービス型機能の提供
- 第2回:[Step Functions を使ったアカウント発行自動化
- 第3回:組織単位ごとのガバナンス戦略! AWS Service Catalog 製品のセキュリティ運用と CI/CD パイプライン実践例(今回)
今後、本記事の他に 2 件の連載を予定していますので、そちらもお楽しみに !
builders.flash メールメンバー登録
builders.flash メールメンバー登録で、毎月の最新アップデート情報とともに、AWS を無料でお試しいただけるクレジットコードを受け取ることができます。
本記事で解説する内容
当社のプラットフォームで共通的に提供している AWS Service Catalog 製品では、多数のセキュリティ設定やガードレールを含んでいます (以後、「セキュリティ共通製品」と呼称)。一方で、セキュリティ共通製品を全テナントへ一斉更新することは現場調整の負担が大きいという課題もあります。
本記事では、組織単位(OU)ごとに「フルサービス」と「セルフサービス」を使い分ける CI/CD パイプラインの設計例を紹介します。セルフサービスによるテナントの自主性と、プラットフォーム管理 OU での強制アップデートによるガバナンス維持の両立ノウハウを、実際の運用例とともに解説します。
セキュリティ共通製品における運用課題
セキュリティ共通製品を運用する中で、以下のような課題が発生しました。
迅速に更新させたい統制目線と、負荷の大きい現場調整によるジレンマ
セキュリティ共通製品は社内のプラットフォームチームとセキュリティチームが協働し、頻繁にバージョンアップデートしています。本来ならば、セキュリティリスクを低減させるために、最新バージョンのセキュリティ共通製品を組織全体へ速やかに適用すべきです。しかし、本番環境のシステムが稼働している Workload OU の AWS アカウントに対しては、以下の理由で即座にアップデートを適用することが困難です。
- 影響範囲の事前確認 : 本番稼働中のシステムへの影響を評価する必要がある
- メンテナンス時間の調整 : テナントの業務影響を考慮したデプロイスケジュールの調整が必要
- ロールバック計画の策定 : 問題発生時に復旧手順の準備が必要
そのため、セキュリティ共通製品は AWS Service Catalog の機能を活かしてセルフサービスで提供しています。セルフサービスにより、テナント (Workload OU) の任意タイミングでセキュリティ共通製品を更新できます。テナントにアップデートを委任しているため、プラットフォームチームは製品改善サイクルをより速く回せるようになりました。
特定 AWS アカウントへの迅速なアップデート要求
一方、本番業務に直接影響しない AWS アカウントでは、セキュリティ共通製品のバージョンアップを速やかに適用したいと考えました。具体的な OU / AWS アカウントは以下の通りです。
- 管理アカウント : Security OU などプラットフォームチームが管理する AWS アカウント群 (AWS Control Tower 管理アカウントも含む)
- Sandbox OU : 検証用 AWS アカウント群
1 に属する AWS アカウントは、セキュリティ共通製品を開発するプラットフォームチームが管理しており、調整不要です。また、2 の Sandbox OU アカウントは本番業務に影響しないため、セキュリティ共通製品の最新バージョンを速やかに適用することが可能です。(そもそも、素早く検証したい Sandbox OU で製品の更新運用は負担となるため、プラットフォーム側で一括更新したいというニーズもあります)
まとめると、これらの OU / AWS アカウントに対してはフルサービスでセキュリティ共通製品を提供することが適切だと考えました。
当社の OU 構成 (抜粋) とフルサービス/セルフサービス戦略の適用範囲
「フルサービス」と「セルフサービス」運用の違い
ここで、「フルサービス」と「セルフサービス」におけるバージョンアップ運用の違いを整理します。
|
|
名称
|
概要
|
主な利点
|
適用先
|
|---|---|---|---|---|
|
1
|
フルサービス |
プラットフォームチームがセキュリティ共通製品を更新 |
|
|
|
2
|
セルフサービス |
プラットフォーム利用者がセキュリティ共通製品を任意のバージョンに更新 |
|
Workload OU |
上記の通り、当社では OU / AWS アカウントの特性に応じて以下の2つの運用方式を使い分けています。
セルフサービスではセキュリティアップデートの遅延リスクがありますが、責任分界点を明確にしてテナントの自主性を尊重しています。一方、フルサービスではプラットフォームチームが一元的に管理することで、迅速なセキュリティアップデートと統一されたガバナンスを実現します。
AWS Service Catalog 製品のバージョン更新方法
AWS Service Catalog で構成されているセキュリティ共通製品は、マネジメントコンソールから簡単にバージョン更新できます。セルフサービスの更新はマネジメントコンソールからの実行を想定しています。
一方、AWS Service Catalog API では UpdateProvisionedProduct が提供されています。この API を AWS Service Catalog の CI/CD パイプラインに組み込むことで、フルサービスのバージョン更新を実現できます。
CI/CD パイプライン全体像
AWS Service Catalog の CI/CD パイプラインは、AWS CodePipeline で実装しています。構成概要は以下の通りです [*]。
Workload OU についてはセキュリティ共通製品の共有に留まっていますが、管理アカウント/Sandbox OU については製品のバージョン更新まで自動化しています。
[*]: 第 1 回連載では AWS CodeCommit をソースコードリポジトリとして使用していましたが、現在は GitHub Enterprise を使用しています。
AWS Service Catalog の CI/CD パイプライン構成概要
パイプラインのステージ・処理フロー
パイプラインのステージは大きく分けて 3 つあり、以下の処理を行っています。
- ソースステージ
- GitHub Enterprise からソースコードを取得
- ビルド・デプロイステージ
- npm 依存関係など各種インストール
- CDK synthによるテンプレート生成、単体テスト実行
- Service Catalog 委任アカウントに、AWS CloudFormation スタックをデプロイ
- Audit アカウントに、セキュリティ共通製品と同等の AWS CloudFormation スタックをデプロイ[*] - 製品バージョン更新ステージ
- 管理アカウント (管理タグが付与されたアカウント) の一覧を取得
- Sandbox OU 配下のアカウント一覧を取得
- 管理アカウント/Sandbox OU に対して、セキュリティ共通製品のバージョンを更新
[*]: Audit アカウントは各 AWS アカウントからのイベント通知が集まるため、通常のセキュリティ共通製品と設定値が異なります。したがって、当社では Audit アカウント専用の AWS CloudFormation スタックを別途デプロイしています。
実装方法
ここからは当社のソースコードから一部を抜粋して、CI/CD パイプラインの具体的な実装方法を解説します。
|
|
ライブラリ
|
バージョン
|
|---|---|---|
|
1
|
AWS CDK CLI
|
2.1033.0
|
|
2
|
AWS CDK ライブラリ
|
2.232.1
|
|
3
|
TypeScript
|
5.9.3 |
実際には分岐・繰り返しなどで各処理を定義しているのですが、ここでは読みやすさを重視して静的なコマンドに置き換えています。また、エラーハンドリングなど本番運用で求められるような実装は省略しています。実際のプロダクション環境では、これらの要素を考慮して実装してください。
ソースリポジトリとの接続
GitHub リポジトリとの接続には、AWS CodeConnections を使用しています。ユーザーガイド に沿って、マネジメントコンソールで事前設定します [*]。
マネジメントコンソールでの設定が完了したら、接続の ARN をメモします。次に AWS CDK で GitHub リポジトリとの接続情報を定義します。メモした ARN を connectionArn に指定します。
[*] : AWS CLI や AWS CloudFormation で接続情報を定義したとしても、マネジメントコンソールでの操作が必要になります。詳細は ユーザーガイド を参照してください。
connectionArn
import * as cdk from "aws-cdk-lib";
import * as codepipeline from "aws-cdk-lib/aws-codepipeline";
import * as codebuild from "aws-cdk-lib/aws-codebuild";
import * as action from "aws-cdk-lib/aws-codepipeline-actions";
import { Construct } from "constructs";
// (その他は省略)
export class PipelineStack extends cdk.Stack {
constructor(scope: Construct, id: string, props: PipelineProps) {
super(scope, id, props);
const sourceArtifact = new codepipeline.Artifact("SourceArtifact");
const sourceAction = new action.CodeStarConnectionsSourceAction({
actionName: "GitHubConnection",
/** メモした CodeConnection の ARN を記載 **/
connectionArn: "arn:aws:codeconnections:ap-northeast-1:123456789012:connection/aa-bb-cc-dd-ee",
output: sourceArtifact,
owner: "mizuho",
repo: "sample-repo",
branch: "main",
codeBuildCloneOutput: true,
});
ビルド・デプロイ
ビルド・デプロイステージでは、CodeBuild プロジェクトに以下を定義しています。
- npm 依存関係など各種インストール
- CDK synthによるテンプレート生成、単体テスト実行
- Service Catalog 委任アカウントに、AWS CloudFormation スタックをデプロイ
- Audit アカウントに、セキュリティ共通製品と同等の AWS CloudFormation スタックをデプロイ
コード例
コード例は以下の通りです。
const buildDeploy = new codebuild.PipelineProject(this, "ServiceCatalogBuildProject",
{
role: buildRole,
environment: {
buildImage: codebuild.LinuxBuildImage.AMAZON_LINUX_2_5,
},
buildSpec: codebuild.BuildSpec.fromObject({
version: "0.2",
env: {
"git-credential-helper": "yes",
},
phases: {
install: {
"runtime-versions": {
nodejs: 20,
},
commands: [
/** npm 依存関係のインストール **/
"npm ci",
"npx cdk --version",
],
},
build: {
commands: [
/** AWS CloudFormation テンプレート生成、単体テスト実行 **/
"npx cdk synth",
"npm test -- --environment=prod",
/** Service Catalog 委任アカウントに、Service Catalog 関連の資産をデプロイ **/
"npx cdk deploy TagOptions*Stack --require-approval never",
"npx cdk deploy ServiceCatalogProd*Stack --require-approval never",
/** Audit アカウントに、セキュリティ共通製品と同等の資産をデプロイ **/
"npx cdk deploy AuditDeployProd*Stack --require-approval never",
],
},
},
}),
},
);
cdk deploy では複数リージョンにデプロイしているため、スタック名にワイルドカードを利用しています。(ServiceCatalogProdApNorthEast1Stack や ServiceCatalogProdApNorthEast3Stack が存在するイメージです。)
製品バージョン更新
製品バージョン更新ステージでは、CodeBuild プロジェクトで以下を定義しています。
- 管理アカウント (管理タグが付与されたアカウント) の一覧を取得
- Sandbox OU 配下のアカウント一覧を取得
- 管理アカウント/Sandbox OU に対して、セキュリティ共通製品のバージョンを更新
コード例は以下の通りです。
const updateProduct = new codebuild.PipelineProject(this, "UpdateProductProject", {
role: buildRole,
environment: {
buildImage: codebuild.LinuxBuildImage.AMAZON_LINUX_2_5,
},
buildSpec: codebuild.BuildSpec.fromObject({
version: "0.2",
phases: {
build: {
commands: [
GetLatestVersion, // セキュリティ共通製品の最新バージョンを取得
GetMasterCredential, // AWS ControlTower 管理アカウントのロールを引き受け
GetManagementAccountIds, // タグによる管理アカウント一覧の取得
GetSandboxAccountIds, // Sandbox OU アカウント一覧の取得
UpdateProductVersion, // セキュリティ共通製品のバージョン更新
],
},
},
}),
});
コマンド(commands) が複雑なので別ファイルにスクリプトの内容を定義しています。
[TIP]
これから AWS CDK で実装するのであれば、AWS Step Functions を利用することも検討してください。AWS API のバリデーションや再実行性の担保など、より堅牢な実装が可能です。当社では、元々シェルスクリプトでバージョン更新処理を手動実行していました。AWS Code Build であればシェルスクリプトを簡単に移植できるため、今回採用しています。
以下では、スクリプトの重要な処理をピックアップして紹介します。
- タグによる管理アカウント一覧の取得 (タグによる管理アカウント一覧の取得) : GetManagementAccountIds
- Sandbox OU アカウント一覧の取得 (sandbox-ou-アカウント一覧の取得) : GetSandboxAccountIds
- セキュリティ共通製品のバージョン更新 (セキュリティ共通製品のバージョン更新) : UpdateProductVersion
※前提として、AWS Control Tower 管理アカウントの IAM ロールを引き受ける必要があります。
タグによる管理アカウント一覧の取得
GetManagementAccountIds については、以下の処理を実行しています。
- AWS Organizations API ListAccounts で全 AWS アカウントの一覧を取得
- 各 AWS アカウントのタグを AWS Organizations API ListTagsForResource で取得
- 管理タグが付与されている AWS アカウントを抽出し、AWS アカウント ID の一覧を保存
Sandbox OU アカウント一覧の取得
GetSandboxAccountIds についてはシンプルです。AWS Organizations API ListAccountsForParent で Sandbox OU に属するアカウントの一覧を取得・保存しています。
セキュリティ共通製品のバージョン更新
UpdateProductVersion については、更新対象の AWS アカウントごとに以下の処理を繰り返し実行しています。
- AWSControlTowerExecution ロールを引き受け
AWS Service Catalog API UpdateProvisionedProduct でセキュリティ共通製品のバージョンを更新 (対象リージョン分、繰り返し実行) - AWS Control Tower 管理アカウントの認証情報にリセット [*]
[*]: 各 AWS アカウントに存在する AWSControlTowerExecution ロールは、AWS Control Tower 管理アカウントからのみ引き受けできます。そのため、各アカウントでの処理後に AWS Control Tower 管理アカウントの認証情報に戻す必要があります。
[IMPORTANT]
AWS Service Catalog 製品に AWS CloudFormation パラメータを設定している場合、注意が必要です。AWS Service Catalog API UpdateProvisionedProduct の ProvisioningParameters で UsePreviousValue を true に指定してください。指定しない場合、AWS CloudFormation パラメータがデフォルト値にリセットされてしまいます。パラメータの値をカスタマイズしている Sandbox OU 利用者に影響が出るため、特に注意してください。当社ではこの設定が漏れており、リカバリ対応に苦労しました。
CI/CD パイプラインの定義
最後に CI/CD パイプラインの定義を紹介します。以下の通り、3つのステージを持つシンプルな構成です。
const pipeline = new codepipeline.Pipeline(this, "ServiceCatalogPipeline", {
crossAccountKeys: true,
pipelineType: codepipeline.PipelineType.V2,
stages: [
{
stageName: "Source",
actions: [sourceAction],
},
{
stageName: "BuildDeploy",
actions: [
new action.CodeBuildAction({
actionName: "BuildDeploy",
project: buildDeploy,
input: sourceArtifact,
}),
],
},
{
stageName: "UpdateProduct",
actions: [
new action.CodeBuildAction({
actionName: "UpdateProduct",
project: updateProduct,
input: sourceArtifact,
}),
],
},
],
});
おわりに
本記事では、OUごとに異なるデプロイ戦略を採用した AWS Service Catalog 製品の運用について詳しく解説しました。
フルサービス運用 (管理アカウント/Sandbox OU) では迅速なセキュリティアップデートを実現し、セルフサービス運用 (Workload OU) ではテナントの自律性を尊重しています。この使い分けにより、以下を両立できました。
- セキュリティガバナンスの維持 : 重要なアップデートの迅速な適用
- テナントの自律性 : 業務に合わせた柔軟な更新計画
- 運用効率の向上 : 自動化とセルフサービス化による負荷分散
AWS Service Catalog を活用したマルチアカウント環境の運用において、OUの特性に応じた戦略の使い分けは非常に有効です。皆様の環境でも、ぜひ参考にしていただければと思います。
次回の連載では、当社のセキュリティ共通製品について特徴的な内容を解説する予定です。お楽しみに !
筆者プロフィール
松尾 優成
みずほリサーチ&テクノロジーズ株式会社
先端技術研究部 ヴァイスプレジデント
入社後、国際系金融システムの開発・保守業務を担当。その後、CCoE 活動を経て、社内共通プラットフォーム・AWS 案件を推進。
現在は社内 DX アプリの推進に従事。その他、〈みずほ〉グループ横断コミュニティ「コクリエ」を運営。