おはこんばんちは
ユニファのインフラみてます、すずきです。
8月に入ってから猛暑と湿度で部屋から一歩も出たくない日々が続きますね。 涼しくなれ!
さて、Terraformでステータスが更新されるまで情報が取得できない、変更できないリソースなどは、Create後すぐに別のリソースで呼び出そうとするとエラーになることがあります。 ちょっと違うけど、ACMって検証が終わるまでELBやCloudFrontで呼び出せないので Resource: aws_acm_certificate_validation を利用して待機しますよね。
そういったことが起こりうるリソースで同じことをやってみようというものです。
Terraformで構文は間違ってないのにエラーになる
そういったことが発生しやすいのは、アカウントまたぎするネットワーク系のときが多いかなと思います。
なぜこれが失敗するのかの説明の前に、アカウント跨ぎのリソースが作成される場合簡単に書くと以下のようになります。(例としてPeeringのことを書いてみます)
- AアカウントからBアカウントへ繋がりたい申請を出してリソースを作成
- その際A,Bともに参照可能な共通リソースとなる
- Bアカウントで1.で作ったリソースへ繋がって良いよと許可を出す
- A,BともにそのリソースのステータスがActiveに変化する
- 1のリソースに関連する設定を変更しようとする
- peeringの際はDNSの設定変更や、ルートテーブルに追加するなど
ざっとこんな雰囲気になるんですが、Terraformで矢継ぎ早にその処理を書くと、4. 実行時に以下のようなエラーになります。
Error: error modifying VPC Peering Connection (pcx-aaaaaaaaaaaaaaa) Options: OperationNotPermitted: Peering pcx-aaaaaaaaaaaaaaais not active. Peering options can be added only to active peerings. status code: 400, request id: e49e5624-9567-4210-9706-3ac4c85d140a on peers.tf line 30, in resource "aws_vpc_peering_connection_options" "b": 30: resource aws_vpc_peering_connection_options b {
Terraformでその状況を書くと以下のようになります。
※ モジュールでVPCを2つ作って、その間をPeeringする際の設定です(VPCの設定は省略してます。)
なぜこんなことが起こるかというと、30行目のaws_vpc_peering_connection_optionsを実行する際に、Peering のリソースがまだ Active
になっていなかったようでエラーになります。(例として出したエラーに not Active
って書かれてますよね)
この場合再度動かせば普通にOKになるのですが、一発でOKにしたいですよね。
ステータスが変更されるまで待機する
Terrafomで待機するってどうやるの? Sleep Functionとか無いよと思ったらありました、Time Provider 、特にその中でSleepリソースを利用します。
30行以下を書き直すと以下のようになります。
行ってることは、B側でpeeringの承認後、20秒スリープします。
また、新たに追加したSleepリソースを depends_on
に追加することで、20秒待機後に設定変更の処理が動くようになります。
AWSアカウント跨ぎなどでTerraformがうまく行かないって人はSleepモジュールなどをお試しあれ。
蛇足ですが、Null リソースでSleepコマンドを叩くとかいう魔改造的なものもあるみたいですねw
まとめ
あっさりとしてましたが、Terraformの小ネタをブログにまとめてみました。 あまり複数アカウントをつないで運用してる人はいないかもしれませんが、同じようなことで困っている方などいたら試してみてください。
また、Sleepリソースの例文にもありますが、Transit Gatewayの共有に必要なRAMなどもSleepを使うことで似たような問題を解決できるそうです。
現在ユニファではAWSやTerraformをバリバリ利用したいエンジニアを募集しています!