Terraform のパイプラインを閉域化(パブリックアクセス無効 + Private Endpoint)した環境で実行する方法を解説

Azure

Azure DevOps の運用負荷を下げる救世主として登場した「Managed DevOps Pool(MDP)」。

近年、セキュリティ要件の厳格化に伴い、医療や金融だけでなく小・中規模アプリケーションでも本番環境の閉域化が主流となっています。

しかし、Terraform の tfstate を保管する Storage Account を閉域化(パブリックアクセス無効 + Private Endpoint)した途端、「タイムアウト」や「403 認可エラー」といったトラブルに直面するケースが後を絶ちません。

ネットワーク経路の確立と、適切な権限(RBAC)の付与。この2つが正しく設定できて初めて、閉域パイプラインは正常に動作します。

そこで本記事では、Managed DevOps Pool を使用して、閉域ネットワーク経由で安全に Terraform を実行するための設定方法を解説します。

なぜ、最近の本番運用では「閉域ネットワーク」が標準なのか?

ひと昔前まで、システム全体を閉域ネットワーク内に閉じ込めるインフラ構成は、一部の極めてセキュリティ要件が厳しい大規模システムに限られた話でした。

しかし現在、その常識は大きく変わりつつあります。

小・中規模アプリでも本番環境の閉域化が主流に

かつては「Webサーバーはパブリックに置き、データベースだけをプライベートサブネットに隠す」という境界防御が一般的でした。

しかし現在では、システムの規模を問わず、本番環境そのものをインターネットから完全に隔離するケースが急増しています。

医療・ヘルスケア分野のシステム環境

電子カルテなどの機微情報を守るため、厳格なガイドラインに準拠し、実行環境からストレージまでの全経路をVNet内に閉じ込めるのが大前提となっています。

金融・決済系のインフラ環境

銀行や証券、フィンテックなどの決済サービスでは、業界内の安全対策基準(FISCなど)や国際的なセキュリティ基準(PCI DSSなど)を満たす必要があります。

パブリックインターネットからの直接の侵入経路を完全に断つために、閉域化は必須要件となります。

近年は小・中規模アプリでも閉域ネットワークが主流に

そして今、こうした特定の業界だけでなく、一般的なWebアプリケーションや社内向けの小・中規模システムであっても、本番環境は閉域ネットワークで構築するケースが標準化しています。

クラウドの利用が当たり前になったからこそ、インフラ全体のセキュリティ水準のボトムアップが求められているのです。

本番環境で閉域ネットワークが選ばれる理由

なぜ、ここまで頑なに「閉域化」が選ばれるのでしょうか。

それには、近年のインフラ運用における現実的なリスクと、クラウド技術の進化が背景にあります。

設定ミスによる情報漏洩を防げる

クラウドにおけるセキュリティ事故の大部分は、ハッカーによる高度なサイバー攻撃ではなく、「ストレージやデータベースのアクセス制御をうっかりパブリック許可のままにしてしまった」という人為的な設定ミスです。

最初からリソースのパブリックエンドポイントを無効化し、閉域網(VNet)の中に閉じ込めておけば、仮に内部のアクセス権限の設定に不備があっても、インターネット側から覗かれるリスクを根本から排除できます。

CI/CDパイプライン自体が狙われる時代に

最近のトレンドとして、本番環境そのものではなく、本番環境へのデプロイ権限を持つ「CI/CDパイプライン(ビルドエージェント)」を標的とした攻撃(サプライチェーン攻撃)が急増しています。

実行環境自体をVNet内に注入できる「Managed DevOps Pool」を採用し、デプロイする側もされる側も両方閉域に引きこもるのが、今の最も安全な運用スタイルです。

Azure標準機能(Private Link)の成熟

ひと昔前は、閉域環境を作ろうとすると「NATゲートウェイのコストが高い」「名前解決(DNS)の設定が複雑で動かない」といった運用ハードルの高さがありました。

しかし現在では、Azureの Private Endpoint(Private Link)Private DNS Zone の仕組みが非常に洗練され、インフラをコード化(IaC)する際もスマートに定義できるようになりました。

【全体像】Managed DevOps Pool を使った閉域アーキテクチャ

この記事のゴールは、「インターネットを経由せず、VNet(仮想ネットワーク)の内部だけで Terraform の実行から state ファイルの更新までを完結させる」ことです。

まずは全体像となるアーキテクチャ図と、それぞれのコンポーネントの役割を確認しましょう。

Azure DevOps Pipeline
        │
        ▼
┌─────────────────┐
│   Managed DevOps Pool            │
│   (VNet 統合 / サブネット委任)   │
└─────────────────┘
        │
        │ ① プライベート IP で通信(名前解決)
        ▼
┌─────────────────┐
│   Private Endpoint               │
│   (privatelink.blob...)          │
└─────────────────┘
        │
        │ ② ネットワークセキュリティ境界内
        ▼
┌─────────────────┐
│   Storage Account                │
│   (tfstate 保存コンテナ)         │
│   Public Access: 無効            │
└─────────────────┘

stateファイルを管理する場所

Terraformの実行状態を記録する tfstate ファイルの保存先にはいくつか選択肢があります。

ローカルPC(個人検証用)

複雑な設定は不要ですが、「チームで共有できない」「CI/CDパイプラインに組み込めない」ため、本番運用には非推奨です。

外部クラウド・SaaS(AWS S3、Terraform Cloud等)

マルチクラウド環境では選択肢に入りますが、Azureの閉域ネットワーク内から安全に接続しようとすると、設定が非常に複雑になります。

Azure Storage Account(推奨)

Azure環境で最も選ばれる理由は以下の3点です。

  1. 自動ロック機能: Blob標準の「リース機能」により、複数人の同時実行によるファイル破損(競合)を自動で防げる。
  2. 強固な閉域化: 外部にネットワークの穴を開けることなく、Private Endpointを使ってVNet内からのみ安全にアクセスさせられる。
  3. スマートな権限管理: Azure DevOpsの認証情報に対し、AzureのRBAC(ロール)を使って最小限のアクセス権限を簡単に付与できる。

したがって、Azureで本番運用を行うなら、セキュリティと運用の両面からストレージアカウントへの格納がデファクトスタンダードとなります。

「4つのステップ」のハンズオン部分の本文です。 実務でそのまま手を動かせるよう、各ステップで行う作業の目的と具体的な設定ポイントを簡潔にまとめました。

【実践】閉域Terraform環境を構築する4つのステップ

それでは、実際にManaged DevOps Poolを使った閉域Terraform環境を構築していきましょう。手順は以下の4つのステップで進めます。

1. VNet とサブネットの作成

Screenshot

まずは、すべてのリソースの土台となる仮想ネットワーク(VNet)とサブネットを準備します。本構成では、セキュリティと運用の観点からサブネットを明確に分けるのが鉄則です。

  • MDP用サブネット: Managed DevOps Pool(ビルドエージェント)を配置する専用のサブネットです。作成時、設定の「サブネットの委任(Delegation)」で Microsoft.DevOps/managedAgentPools を必ず指定してください。これを行わないと、MDPをVNet統合できません。
  • プライベートエンドポイント(PE)用サブネット: 後述するStorage AccountのPrivate Endpointを配置するためのサブネットです。

2. ストレージアカウントの作成と閉域化

Terraformの tfstate を安全に保管するため、Storage Accountを作成し、外部からのアクセスを完全に遮断します。

パブリックアクセスの無効化: ストレージアカウントの「ネットワーク」設定で、パブリックネットワークからのアクセスを「無効(Disable)」にします。これでインターネット経由のアクセスはすべて拒否されます。

プライベートエンドポイントの作成: 「1. VNet とサブネットの作成」で用意したPE用サブネットに向けて、Storage AccountのPrivate Endpoint(対象サブリソース:blob)を作成します。

Screenshot

Private DNS Zoneの紐付け: privatelink.blob.core.windows.net という名前のPrivate DNS Zoneを作成し、VNetにリンクします。これにより、MDPがストレージのURL(FQDN)を叩いた際に、VNet内のプライベートIPアドレスへと正しく名前解決されるようになります。

3. Managed DevOps Pool(MDP)の作成

次に、実際にTerraformコマンドを実行するコンピューティングリソース(MDP)を作成します。

Screenshot
  • Azureポータルでの作成とVNet統合: AzureポータルからManaged DevOps Poolリソースを作成します。設定項目にあるネットワーク設定で、「1. VNet とサブネットの作成」で用意したMDP用サブネットを指定し、VNet統合を有効にします。これにより、エージェントはVNetの内部から通信を開始できるようになります。
  • Azure DevOpsへのプール登録: 作成したプールをパイプラインから呼び出せるようにします。Azure DevOpsの Project SettingsAgent poolsAdd pool から「Azure DevOps pool」を選択し、先ほどAzure側で作成したMDPをプロジェクトに登録します。

4. Azure DevOps の Service Connection設定

最後に、パイプラインがStorage Account内のBlobコンテナに対して、実際に tfstate ファイルを読み書きできるようにするための権限(認可)を設定します。

  • 最小権限(RBAC)の付与: Azure DevOpsのService Connectionが使用しているサービスプリンシパル(アプリケーション登録)に対して、作成したStorage Account(またはコンテナ)のスコープで 「Storage Blob Data Contributor(ストレージ BLOB データ共同作成者)」 ロールを付与します。

⚠️ 注意: 閲覧者(Reader)や通常の共同作成者(Contributor)ロールだけでは、Blobの「データプレーン(ファイルの中身)」に対する読み書き権限が不足し、terraform init 時に403エラー(AuthorizationFailed)になります。必ず Storage Blob Data Contributor を付与してください。

まとめ

Managed DevOps Pool(MDP)と Storage Account を組み合わせた閉域 Terraform 環境は、現代の本番運用におけるセキュリティの最適解です。

インフラの閉域化は一見複雑ですが、「ネットワーク経路の確立」と「正しいRBAC権限の付与」という2つのレイヤーを順にクリアしていけば確実に構築できます。エラーに直面した際も、タイムアウトならネットワーク、403エラーなら権限不足と、原因をシンプルに切り分けられるようになります。

これまで閉域環境の維持に必要だったセルフホストエージェントの運用管理コストは、MDPの登場によって激減しました。本記事の4つのステップを参考に、強固なセキュリティと効率的な運用を両立したインフラデプロイ環境をぜひ実現させてください。

あわせて読みたい

本記事で扱った「Private Endpoint+RBACで閉域化する」考え方は、Terraformのパイプラインに限らずAzureの様々なサービスで共通です。閉域ネットワーク設計をさらに深めたい方は、あわせてどうぞ。

タイトルとURLをコピーしました