NEWSニュース&ブログ

【Terraform】謎事象からの脱却!根本原因の究明アプローチ

投稿日:2024/05/09

こんにちは!ソリューションサービス事業部の西田です。

クラウド&インフラ系の案件に携わる中で、IaCInfrastructure as Code)という
言葉を
近年よく耳にします。

IaC とは、サーバーやネットワーク、ストレージ等の IT インフラストラクチャー
(例:Azure、AWS 環境等)を、コードによって自動で構築・管理するための手法です。

この IaC を実現するツールの1つとして、Terraform があります。

私も Terraform を使ったクラウド環境のリソース構築や管理をすることがありますが、
ちょくちょく意味不明な事象(エラー)に遭遇することがあります。

今回、1つの事例をご紹介するので、同じような罠にハマった経験がある方や、
現在進行形でハマっている1人でも多くの方々に届きますと幸いです。

対象者:

 ・Terraform の基本的な使用方法/コマンドを知っている
 ・Terraform で発生した予期せぬ問題(エラー)を解決したい方
 ・Azure を利用(※AWS 等の他クラウド環境でも応用できるとは思います!)

前提:

● Terraform による作成予定のシステム構成は以下です。

● 上図のように、踏み台サーバ 経由(プライベート接続)でのみアクセスできる、
 セキュリティを考慮した ストレージアカウント(赤枠箇所)を作成しようとしています。

● Terraform による作成対象は以下で、ストレージアカウント以外のリソースは既に作成済みです。

【作成対象リソース】

 リソースの種類 リソース名
 ・リソースグループ TEST-RG-01
 ・仮想ネットワーク VNET-01
 ・サブネット(パブリック用) pubsubnet-01
 ・ネットワークセキュリティーグループ(パブリック用) PUB-NSG
 ・サブネット(プライベート用) prisubnet-01
 ・ネットワークセキュリティーグループ(プライベート用) PRI-NSG
 ・仮想マシン(踏み台サーバ) VM-01
 ・ストレージアカウント st0001

事象内容:

ある日のこと、terraform apply コマンドを実行し、ストレージアカウント(st0001)を
新規で作成しようとしていました。

※terraform init(初期化処理)や terraform plan(作成予定リソースの実行計画作成)
 コマンドが問題なく完了することは事前に確認済みです。

すると、なんということでしょう。

st0001 を作ろうとしているのに、「st0001が見つからないため作成に失敗しました」といった
何とも意味が分からない、矛盾系のエラーが突如現れたのです。

エラーの出力内容は↓だけで、これ以上の情報はありません。

Error: retrieving Storage Account (Subscription: “XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX”
Resource Group Name: “TEST-RG-01”
Storage Account Name: “st0001“): storage.AccountsClient#GetProperties: Fail
ure responding to request: StatusCode=404 — Original Error: autorest/azure: S
ervice returned an error. Status=404 Code=”StorageAccountNotFound
Message=”The storage account st0001 was not found.


これから作るんだし、今時点で見つからないのは当然では!?」ってツッコミたくなります。

そんな気持ちを抑え、
Web サイト上で、”404” や “StorageAccountNotFound” 等のエラーに関する出力内容をもとに
キーワード検索してみましたが、もちろん解決に繋がるような情報は見つかりませんでした。
困ったものです、、

対応内容:

闇雲に Terraform 構成ファイル(tfファイル)の記述をチェックし直したり、トライ&エラーでの
対処を繰り返すとなると、この問題がいつ解決するのか全然目途が立ちません。

やはり、問題(エラー)の詳細を確認できないことには、次のアクションに踏み出すのは難しそうです。

そこで、Terraform 実行時にデバッグ設定を仕掛けてみることにしました。

TF_LOG=DEBUG terraform apply

TF_LOG=DEBUG を terraform コマンドの前に指定することで、実行時限定でデバッグ設定が有効になります。
 
Enter!!

すると、なんということでしょう。
沢山のログメッセージが出るわ出るわ。。(頼むから止まってくれぃ…)

そんなこんなで、コマンドを実行してからエラーに至るまでのログが数百行ほど出力されました。

そのログ内で「error」や「failed」といった失敗関連キーワードを中心に検索をかけたところ、
発生源と思われるエラーメッセージにすぐに辿り着きました。

{“status”:”Failed“,”error“:{“code”:”NetworkAclsValidationFailure“,”message”:”Validation of network acls failure: SubnetsHaveNoServiceEndpointsConfigured:Subnets prisubnet-01 of virtual network /subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX/resourceGroups/TEST-RG-01/providers/Microsoft.Network/virtualNetworks/VNET-01 do not have ServiceEndpoints for Microsoft.Storage resources configured. Add Microsoft.Storage to subnet’s ServiceEndpoints collection before trying to ACL Microsoft.Storage resources to these subnets..”}}: timestamp=”2024-05-02T11:58:01.372+0900″


上記のエラーログを要約してみましょう。
========================================
NetworkAclsValidationFailure というエラーコードが発生。
SubnetsHaveNoServiceEndpointsConfigured で失敗)

・仮想ネットワーク(VNET-01)のサブネット(prisubnet-01)上に、Microsoft.Storage のサービスエンドポイントが
 未設定だから、このサブネットに Microsoft.Storage のサービスエンドポイントを追加してね!
========================================

ありがたいことに、具体的な対応方法まで分かりました。

という訳で、「service_endpoints = ["Microsoft.Storage"]」という記述を
Terraform 構成ファイル内のサブネットリソース箇所に追記してみましょう。
※Terraform の公式ドキュメント(azurerm_subnet)に、構文の説明がサクッと書かれています。

↓ 作成済みの Terraform 構成ファイル内で、以下太字個所を追記 ↓
┌─────────────────────────────────────────────────────────┐
resource "azurerm_subnet" "subnet" {
name = var.subnet_name
resource_group_name = var.rg_name
virtual_network_name = var.vnet_name
address_prefixes = var.subnet_address_prefixes
service_endpoints = ["Microsoft.Storage"]      -- ★追記箇所★
}
└─────────────────────────────────────────────────────────┘

その後、もう一度 Terraform apply を実行してみたところ、
無事にストレージアカウント(st0001)が作れました!!

これで一件落着です!

module.storage_account.azurerm_storage_account.storage_account:
Creation complete after 34s
[id=/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX/resourceGroups
/TEST-RG-01/providers/Microsoft.Storage/storageAccounts/st0001]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

まとめ:

何か問題が発生すると、ついついトライ&エラーで突き進んでしまっていませんか?
(偉そうに言っていますが、実は私もそんなタイプだったりします…笑)

今回ご紹介した事例も、試行錯誤で1つずつ原因を切り分けていけば、いつかは解決できたかもしれませんが、
きっとこんなにサクッとは解決できなかったのではないかと思います。

面倒くさくて疎かになりがちですが、
発生している問題を正確(詳細)に把握することが、解決への第一歩!
という個人的な教訓(?) が、今回の記事を通じて読者の皆様に伝わりますと幸いです。

なお、TF_LOG=DEBUG によるログの出力量の多さには、初見だと心が折れかけるかもしれませんが、
Terraform におけるエラーの詳細を確認する手法としてはうってつけ(王道)ですので、是非ご参考ください。

それではまた次回のブログでお会いしましょう!


西田 幸平(2021年入社)
株式会社システムサポート フューチャーイノベーション事業本部 ソリューションサービス事業部所属
DB(Oracle Database, SQL Server 等)やクラウド(Azure, AWS)を中心とした案件に従事
好きな言葉は『寝る子は育つ』