🧑‍🚒

AWS WAFをterraformで変更したときの依存性解決問題

2023/02/06に公開

問題

terraformでAWSのWAFリソースを変更した場合、依存性の解決がうまくできずにapplyがスタックする場合がある。

ある aws_wafv2_web_acl に含まれる aws_wafv2_rule_group のnameを変更した場合、nameは破壊を伴う変更(replace)であるため削除後作成になる。

しかし、これをapplyしようとすると:

  1. aws_wafv2_web_aclの内部のルールロジックを変更しようとする
  2. 変更後の aws_wafv2_rule_group のarnが必要になる
  3. aws_wafv2_rule_group の変更は古い aws_wafv2_rule_group の破棄が必要になる
  4. 古いaws_wafv2_rule_group はまだ aws_wafv2_web_acl から参照されており、破棄できない

というデッドロックが発生する。

では、

  lifecycle {
    create_before_destroy = true
  }

を用いて削除前に作成してしまえばいいかというとこれもうまくいかない。というのは、ルールグループのnameはAWSアカウント内で被ってはいけないためだ。このルールにより、削除前の作成は成功しない。

なお、この現象はルールグループ以外でも発生する。

解決策

以下のように名前の末尾にランダム文字列を追加して衝突しないようにする。


resource "random_id" "suffix" {
  keepers = {
    # 以下には破壊的変更を伴う aws_wafv2_rule_group のプロパティを列挙する
    capacity = local.capacity
  }

  byte_length = 2 # hexのoutputはこの長さの2倍になる。4文字長がほしいので、その半分を指定
}

resource "aws_wafv2_rule_group" "this" {
  name  = "my-waf-rule-${random_id.suffix.hex}"

  lifecycle {
    # waf系は基本 create before destroy でないとうまく作り直せない
    create_before_destroy = true
  }
  
  ...

これにより、applyが成功することを2023/02/06までに複数回確認した。

スポンサー

この記事はSpeeeでの業務中に15分で書きました。

Discussion