繁体   English   中英

terraform 想在我只想向安全组添加规则时替换 ec2 实例

[英]terraform wants to replace ec2 instances when i simply want to add a rule to a security group

我在 terraform 中定义了一个 ec2 实例以及一些安全规则。

这些是安全规则:

resource "aws_security_group" "ec2_web" {
  name        = "${var.project_name}_${var.env}_ec2_web"
  description = "ec2 instances that serve to the load balancer"
  vpc_id      = aws_vpc.main.id
}
resource "aws_security_group_rule" "ec2_web_http" {
  type              = "egress"
  from_port         = 80
  to_port           = 80
  protocol          = "tcp"
  # cidr_blocks       = ["0.0.0.0/0"]
  security_group_id = aws_security_group.ec2_web.id
  source_security_group_id = aws_security_group.elb.id
}
resource "aws_security_group_rule" "ec2_web_ssh" {
  type              = "ingress"
  from_port         = 22
  to_port           = 22
  protocol          = "tcp"
  cidr_blocks       = ["${var.ip_address}/32"]
  security_group_id = aws_security_group.ec2_web.id
}

我试图简单地添加另一个安全规则:

resource "aws_security_group_rule" "ec2_web_ssh_test" {
  type              = "ingress"
  from_port         = 22
  to_port           = 22
  protocol          = "tcp"
  cidr_blocks       = ["${var.ip_address}/32"]
  security_group_id = aws_security_group.ec2_web.id
}

而 terraform 想要完全替换安全组,并且级联到完全替换 ec2 实例。

我正在修改 .tf 文件然后运行:

terraform apply

编辑:

安全组本身似乎完全无关。 当我执行“计划”时,我得到 output:

  # aws_instance.ec2 must be replaced
-/+ resource "aws_instance" "ec2" {
...
      ~ security_groups                      = [ # forces replacement
          + "sg-0befd5d21eee052ad",
        ]

ec2 实例创建时使用:

resource "aws_instance" "ec2" {
  
  ami           = "ami-0b5eea76982371e91"
  instance_type = "t3.small"
  key_name      = "${var.project_name}"

  depends_on = [aws_internet_gateway.main]

  user_data     = <<EOF
#!/bin/bash
sudo amazon-linux-extras install -y php8.1 mariadb10.5
sudo yum install -y httpd mariadb php8.1 php8.1-cli
sudo systemctl start httpd
sudo systemctl enable httpd
echo 'yup' | sudo tee /var/www/html/index.html
echo '<?php echo phpinfo();' | sudo tee /var/www/html/phpinfo.php
  EOF
  tags = {
    Name = "${var.project_name}_${var.env}_ec2"
  }
  root_block_device {
    volume_size = 8 # GB
    volume_type = "gp3"
  }
  security_groups = [aws_security_group.ec2_web.id]
  # vpc_security_group_ids = [aws_security_group.main.id]
  subnet_id = aws_subnet.main1.id
}

如果我注释掉

# security_groups = [aws_security_group.bake.name]

我没有收到任何错误。

发生这种情况是因为security_groups只能用于EC2-Classic(遗留实例)和默认 VPC 对于其他一切,您必须使用vpc_security_group_ids

在您的原因中,您使用的是名为main自定义 VPC ,因此您必须使用vpc_security_group_ids而不是security_groups

在申请之前请运行terraform apply -refresh-only然后你的主要问题是你不能用不同的 terraform id 定义相同的规则

当您为ec2_web_ssh_test应用新更改时,AWS 会抱怨

│Error: [WARN] A duplicate Security Group rule was found on (sg-xxxxxx). 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

然后你将从 AWS api 得到这个错误

Error: InvalidPermission.Duplicate: the specified rule "peer: xxx.xxx.xxx.xxx/32, TCP, from port: 22, to port: 22, ALLOW" already exists

对于 Terraform,它将当前配置的 state 与新的 state 进行比较,后者将包含您要添加的新规则。 这里当前的 state 与您要添加的新规则所需的 state 不同。

因此,在两种不同的状态下,Terraform 试图销毁 EC2 实例并尝试使用新添加的规则 state 构建新实例。

这可以通过使用terraform import命令来避免,该命令会将现有资源导入到您的 terraform state,然后对其进行更改。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM