こんにちは! ビデオリサーチのキクチです。
皆さんは、Terraformでインフラリソースを管理していて、「terraform planでは確かに差分が表示されるのに、何度applyしてもなぜか反映されない…」という現象に遭遇したことはありませんか?
先日、まさにそんな不可解な事象に直面し、原因を追い求めた結果、意外な落とし穴にたどり着きました。
今回は、そのトラブルシューティングの一部始終とそこから得られた教訓を共有したいと思います。
発端
Auroraでクエリエディタを有効にしたい
開発中のあるプロジェクトで、QAチームのテスト効率化のため、AWSのRDS Aurora (MySQL/Provisioned) でData APIを有効にしようと考えました。
Data APIを使えば、コンソールから直接クエリを実行できるクエリエディタが利用可能になります。
早速、aws_rds_clusterリソースに以下の1行を追加しました。単純な作業のはずでした。
database.tf
resource "aws_rds_cluster" "example" { # ... 他の設定 ... # Data APIを使用できるよう有効化 enable_http_endpoint = true }
terraform planを実行すると、思惑通りに差分が表示されました。
~ resource "aws_rds_cluster" "example" {
~ enable_http_endpoint = false -> true
# (その他の属性は変更なし)
}
そのまま、何も考えずにCDを流しterraform applyを実行。
エラーなく正常に完了!…のはずが、AWSコンソールで確認すると、Data APIは「無効」のまま・・😇
何度かapplyし直しても状況は変わりませんでした。何故だ、ナゼダ・・・コレガワカラナイ
仮説と検証
考えられる仮説
ひとまず考えられる原因を一つずつ潰していくことにしました。
- 【仮説1】設定ミス?
- 検証
apply_immediately = falseが原因で、メンテナンスウィンドウまで適用が保留されている?
- 結果
- CLIで
PendingModifiedValuesを確認するもnull。保留はされていないようでした。
- CLIで
- 検証
- 【仮説2】AWSの仕様?
- 【仮説3】他の設定とのコンフリクト?
- 検証
- 使用中のインスタンスタイプ(
r7g.large)や、Global Databaseの利用など、他の制約事項に抵触している?
- 使用中のインスタンスタイプ(
- 結果
- いずれも該当せず。
- 検証
途方に暮れ、藁にもすがる思いでCloudTrailのログを調査することにしました。
CloudTrailのログ
terraform apply実行時のModifyDBClusterイベントを調べてみると・・
CloudTrailログの抜粋
{ "requestParameters": { "enableHttpEndpoint": true // (1) リクエストは確かに送られている }, "responseElements": { "httpEndpointEnabled": false, // (2) なのに、レスポンスでは無効のまま "engineMode": "provisioned" }, "errorCode": null // (3) エラーは起きていない }
ムムム・・・🤨
ログを見る限り、
ように見えます。
真の原因
AWS側の問題である可能性が濃厚になり、AWSのTAMにも相談し原因を調査していたところ、GitHubに気になるIssueが・・・
- [Enhancement]: Not able to enable the RDS Data API using "enable_http_endpoint" #37125
え・・・
え・・・・・・🤯
正に今回の事象の根本原因が書かれていました
【根本原因(要約)】
「
ModifyDBClusterAPIでEnableHttpEndpointを指定する方法はServerless v1専用の古い仕様。ProvisionedやServerless v2の場合は、EnableHttpEndpointという専用の別のAPIを呼び出す必要がある」
つまり、、
AWSのAPI仕様が裏で変更されていたが、我々が使っていた古いTerraform AWS Providerでは、その変更に追随出来ていなかった、ということです。
そして、このバグはProviderバージョンv5.64.0で修正済みのようです。
得られた教訓
今回のトラブルシューティングから得られた最大の教訓は、これに尽きます。
「バージョンはこまめに上げよう!!」
今回のトラブルはTerraform Providerのバージョンが直接の原因でしたが、これはTerraformに限った話ではありません。
人間、一度動いているものは、ついバージョンなど固定したまま運用しがちです。
しかし、バージョンアップをサボると今回のような「サイレントエラー」を引き起こす可能性があります。
このような事態を避けるためにも、
- 定期的なバージョンアップをチーム・組織の文化として根付かせることが何よりも重要
だと感じました。
最後までお読みいただきありがとうございました。