0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

terraform apply実行時のエラー「A duplicate Security Group rule was found on (sg-...」に対するトラブルシューティング

Last updated at Posted at 2024-10-19

用語

SG: セキュリティグループ
SGR: セキュリティグループルール

注意

terraform apply実行時のエラーに対するトラブルシューティングという内容ですが、後述するように、そもそも、terraform state mvコマンドを適切に事前に実行すれば、回避できるエラーです。
私は、tfmigrate を使っているので、terraform state mvコマンドをコードに起こして確認してから実行しています。

目的

  • SGR(セキュリティグループルール) を改名して、 terraform apply を実施したときに起きることがあるエラーのトラブルシューティングの方法を知る。
    ※ 後で説明するが、エラーが起きないときもある。
│ Error: [WARN] A duplicate Security Group rule was found on (sg-XXXXXXXXXXXXXXX). This may be
  • SGR(セキュリティグループルール)の削除と作成のタイミングを知る。
  • 事前に上記エラーを回避する方法を知る。

結論

  • 上記エラーが起きたら、もう一度 terraform applyをやれば成功する。
    • ※ただ、そもそも、terraform applyを実施してこのエラーを起こす前に、terraform state mvコマンドや tfmigrate applyコマンド(tfmigrate のインストール必須)を実施しよう。
  • SGR(セキュリティグループルール)の削除と作成のタイミングは、かなり適当で、上記のterraform applyはエラーになったりならなかったりする。
  • リソースの改名や置き換えの時は、stateコマンドを使ってからterraform applyを実施するべきなので、terraform apply実施前に必ず検討しよう。

説明

エラーを見てみる

モジュール内のSGRを sgr_ingress から sgr_ingress_renamed に改名した。

modules/security_group/aws_security_group_rule.tf
resource "aws_security_group_rule" "sgr_ingress_renamed" {
  type              = "ingress"
  from_port         = var.port
  to_port           = var.port
  protocol          = "tcp"
  cidr_blocks       = var.cidr_blocks_ingress
  security_group_id = aws_security_group.normal.id

  timeouts {
    create = "1m"
  }
}

resource "aws_security_group_rule" "sgr_egress" {
  type              = "egress"
  from_port         = 0
  to_port           = 0
  protocol          = "-1"
  cidr_blocks       = ["0.0.0.0/0"]
  security_group_id = aws_security_group.normal.id

  timeouts {
    create = "1m"
  }
}
modules/security_group/aws_security_group.tf
resource "aws_security_group" "normal" {
  name   = var.name
  vpc_id = var.vpc_id

  timeouts {
    create = "1m"
    delete = "1m"
  }
}
aws_security_group.tf
module "allow_http" {
  source              = "./modules/security_group"
  name                = "AllowHTTP_2"
  vpc_id              = aws_vpc.tf_my_vpc.id
  port                = 80
  cidr_blocks_ingress = ["0.0.0.0/0"]
}

module "allow_https" {
  source              = "./modules/security_group"
  name                = "AllowHTTPS_2"
  vpc_id              = aws_vpc.tf_my_vpc.id
  port                = 443
  cidr_blocks_ingress = ["0.0.0.0/0"]
}

module "allow_ssh" {
  source              = "./modules/security_group"
  name                = "AllowSSH_2"
  vpc_id              = aws_vpc.tf_my_vpc.id
  port                = 22
  cidr_blocks_ingress = ["0.0.0.0/0"]
}

そして、terraform applyを実施すると、下記のエラーが出るときがある。 ※ この記事の趣旨でもあるが、場合によってはエラーは出ない。

Plan: 3 to add, 0 to change, 3 to destroy.
module.allow_https.aws_security_group_rule.sgr_ingress: Destroying... [id=sgrule-XXXXXXXXXX]
module.allow_http.aws_security_group_rule.sgr_ingress: Destroying... [id=sgrule-XXXXXXXXXX]
module.allow_ssh.aws_security_group_rule.sgr_ingress: Destroying... [id=sgrule-XXXXXXXXXX]
module.allow_https.aws_security_group_rule.sgr_ingress_renamed: Creating...
module.allow_http.aws_security_group_rule.sgr_ingress_renamed: Creating...
module.allow_ssh.aws_security_group_rule.sgr_ingress_renamed: Creating...
module.allow_http.aws_security_group_rule.sgr_ingress: Destruction complete after 0s
module.allow_ssh.aws_security_group_rule.sgr_ingress: Destruction complete after 0s
module.allow_https.aws_security_group_rule.sgr_ingress: Destruction complete after 1s
module.allow_http.aws_security_group_rule.sgr_ingress_renamed: Creation complete after 1s [id=sgrule-XXXXXXXXXX]
module.allow_ssh.aws_security_group_rule.sgr_ingress_renamed: Creation complete after 2s [id=sgrule-XXXXXXXXXX]
╷
│ Error: [WARN] A duplicate Security Group rule was found on (sg-XXXXXXXXXXXXXXX). This may be
│ a side effect of a now-fixed Terraform issue causing two security groups with
│ identical attributes but different source_security_group_ids to overwrite each
│ other in the state. See https://github.com/hashicorp/terraform/pull/2376 for more
│ information and instructions for recovery. Error: operation error EC2: AuthorizeSecurityGroupIngress, https response error StatusCode: 400, RequestID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, api error InvalidPermission.Duplicate: the specified rule "peer: 0.0.0.0/0, TCP, from port: 443, to port: 443, ALLOW" already exists
│ 
│   with module.allow_https.aws_security_group_rule.sgr_ingress_renamed,
│   on modules/security_group/aws_security_group_rule.tf line 1, in resource "aws_security_group_rule" "sgr_ingress_renamed":
│    1: resource "aws_security_group_rule" "sgr_ingress_renamed" {
│ 
╵
Error: Process completed with exit code 1.

下記の部分に注目してほしい。
module.allow_http.aws_security_group_rule.sgr_ingressmodule.allow_ssh.aws_security_group_rule.sgr_ingressは、無事に破壊されて、リネームされた上で再作成されている。
一方、module.allow_https.aws_security_group_rule.sgr_ingress はしっかり破壊されているものの、リネームしたSGRの再作成に失敗している。

module.allow_http.aws_security_group_rule.sgr_ingress: Destruction complete after 0s
module.allow_ssh.aws_security_group_rule.sgr_ingress: Destruction complete after 0s
module.allow_https.aws_security_group_rule.sgr_ingress: Destruction complete after 1s
module.allow_http.aws_security_group_rule.sgr_ingress_renamed: Creation complete after 1s [id=sgrule-XXXXXXXXXX]
module.allow_ssh.aws_security_group_rule.sgr_ingress_renamed: Creation complete after 2s [id=sgrule-XXXXXXXXXX]
╷
│ Error: [WARN] A duplicate Security Group rule was found on (sg-XXXXXXXXXXXXXXX). This may b

エラーの原因

エラーの原因は、リネーム前のSGR(module.allow_https.aws_security_group_rule.sgr_ingress)が破壊されるタイミングと、リネーム後のSGR(module.allow_https.aws_security_group_rule.sgr_ingress_renamed)が作成されようとしているタイミングが近すぎて、リネーム後のSGRを作成しようとした時に、リネーム前のSGRがまだ破壊されていないと判断されてしまったことである。
リネーム前のSGRとリネーム後のSGRは、名前が違うだけで内容が全く同じなので、同じSGの中に共存できないのである。なので、リネーム後のSGRの内容を少し変更すれば、このようなエラーは起きないはずである(たぶん)。

エラーが起きるときと起きないときがある

何回か実験してみたら、まったくエラーがでないときもあれば、上記とは違って、module.allow_http.aws_security_group_rule.sgr_ingressを改名したSGRの作成がエラーになるときもあった。

トラブルシューティング

状況としては、リネーム前のSGRの削除に成功して、リネーム後のSGRの作成に失敗しているので、terraform applyを再度実行すれば解決する。

そもそもこのようなエラーを起こさないために

terraform state mvコマンドや tfmigrate applyコマンド(tfmigrate のインストール必須)を実施してから、terraform applyを実施しよう。
ちなみに、tfmigrate を使う場合、下記のようなマイグレーションファイルを用意して、tfmigrate applyを実施することになる。

tfmigrate/20241019212900_rename_sgr_ingress_to_sgr_ingress_renamed.hcl
migration "state" "20241019212900_rename_sgr_ingress_to_sgr_ingress_renamed" {
  actions = [
    "mv module.allow_http.aws_security_group_rule.sgr_ingress module.allow_http.aws_security_group_rule.sgr_ingress_renamed",
    "mv module.allow_https.aws_security_group_rule.sgr_ingress module.allow_https.aws_security_group_rule.sgr_ingress_renamed",
    "mv module.allow_ssh.aws_security_group_rule.sgr_ingress module.allow_ssh.aws_security_group_rule.sgr_ingress_renamed"
  ]
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?