terraform-provider-aws: aws_security_group: DependencyViolation: resource sg-XXX has a dependent object
This issue was originally opened by @brikis98 as hashicorp/terraform#11047. It was migrated here as a result of the provider split. The original body of the issue is below.
Terraform Version
Terraform v0.8.2
Affected Resource(s)
- aws_security_group
Terraform Configuration Files
This is part of a larger configuration, but I think the relevant parts are as follows.
Under modules/webserver-cluster/main.tf, I define a module with the following code:
resource "aws_autoscaling_group" "example" {
launch_configuration = "${aws_launch_configuration.example.id}"
availability_zones = ["${data.aws_availability_zones.all.names}"]
load_balancers = ["${aws_elb.example.name}"]
health_check_type = "ELB"
min_size = 2
max_size = 10
}
resource "aws_launch_configuration" "example" {
image_id = "ami-40d28157"
instance_type = "t2.micro"
security_groups = ["${aws_security_group.instance.id}"]
lifecycle {
create_before_destroy = true
}
}
resource "aws_security_group" "instance" {
name = "my-security-group"
lifecycle {
create_before_destroy = true
}
}
resource "aws_security_group_rule" "allow_http_inbound" {
type = "ingress"
security_group_id = "${aws_security_group.instance.id}"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
data "aws_availability_zones" "all" {}
resource "aws_elb" "example" {
name = "my-example-elb"
availability_zones = ["${data.aws_availability_zones.all.names}"]
security_groups = ["${aws_security_group.elb.id}"]
listener {
lb_port = 80
lb_protocol = "http"
instance_port = 80
instance_protocol = "http"
}
health_check {
healthy_threshold = 2
unhealthy_threshold = 2
timeout = 3
interval = 30
target = "HTTP:80/"
}
}
resource "aws_security_group" "elb" {
name = "elb"
}
resource "aws_security_group_rule" "allow_http_inbound" {
type = "ingress"
security_group_id = "${aws_security_group.elb.id}"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_security_group_rule" "allow_all_outbound" {
type = "egress"
security_group_id = "${aws_security_group.elb.id}"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
output "elb_security_group_id" {
value = "${aws_security_group.elb.id}"
}
In a separate folder, I use this module in the usual way, but also add a custom security group rule:
module "webserver_cluster" {
source = "modules/webserver-cluster"
# ... pass various parameters ...
}
resource "aws_security_group_rule" "allow_testing_inbound" {
type = "ingress"
security_group_id = "${module.webserver_cluster.elb_security_group_id}"
from_port = 12345
to_port = 12345
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
Expected Behavior
I expect to be able to run terraform apply and terraform destroy without errors.
Actual Behavior
terraform apply works fine. Occasionally, terraform destroy fails with the following error:
aws_security_group.elb: DependencyViolation: resource sg-344baa48 has a dependent object
Steps to Reproduce
terraform applyterraform destroy
Important Factoids
It’s an intermittent issue, so I can’t be sure, but I don’t think this error happened with Terraform 0.7.x.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 28
- Comments: 34 (7 by maintainers)
Commits related to this issue
- Fix the destroy of 'aws_security_group' for mysql-primary/replica After #1530, we're hitting an error applying the plan: ``` Error: Error applying plan: 2 errors occurred: * aws_security_group.mys... — committed to alphagov/govuk-aws by ChrisBAshton 2 years ago
- Fix the destroy of 'aws_security_group' for mysql-primary/replica After #1530, we're hitting an error applying the plan: ``` Error: Error applying plan: 2 errors occurred: * aws_security_group.mys... — committed to alphagov/govuk-aws by ChrisBAshton 2 years ago
OK, it looks like adding
create_before_destroy = true, and usingname_prefixinstead ofnamefixed this issue. I can’t believe it took me this long to figure it out!I am experiencing the issue where security groups are not deleted, referencing dependent objects, because they are attached to lingering ENIs.
The ENIs seem to be coming from an aws_launch_template/aws_autoscaling_group combo and since I did not experience this behaviour when I was using aws_launch_configuration, I suspect that aws_launch_template is somehow the cause of this.
I have tried to solve the problem via
revoke_rules_on_delete,lifecycleandname_prefixbut they all have no effect since the root cause are the lingering ENIs.Sweet! I tested create_before_destroy = true, and using name_prefix instead of name fixed it for me! Thank you brikis98
Update: we eventually determined that this issue was being caused by a security group that had an inbound rule for another security group. After we manually removed the inbound rule, Terraform was able to proceed with the destruction of the security group that was causing this issue.
We did toggle the
revoke_rules_on_deletesetting totruebut the Terraform deploy of that change was blocked by this issue.Yes - the security group has to use “name_prefix” instead of “name” to use this workaround
I am not running into the issue anymore.
I traced it to not having set
delete_on_termination = truein thenetwork_interfacespart of theaws_launch_templateresource I was using.As of 0.11.7 it was fixed by lifecycle { create_before_destroy = true }
I’m on 0.10.8 and am currently experiencing this issue. One tip for figuring out what the “dependent object” is: type the name of the SG into the ENI instances searchbox (https://serverfault.com/a/866203/223606). It appears that an attached ENI is preventing Terraform from deleting my SG.
Spent several hours on various configurations to attempt to work around this. The DependencyViolation… has a dependent object error occurs after the 5 minute timeout in every scenario. Bottom line is that the network interface does not get assigned to the new security group if a new SG resource must be created (e.g. sg name change). The security group is created (if lifecycle create_before_destroy = true) as desired alongside the existing sg which is assigned to the ENI, but the ENI is never reassigned to the new SG.
While Terraform is waiting, I can go into the AWS console and do “change security groups” on either the Network Interface or the ec2 Instance itself and Terraform will immediately continue its process and remove the old SG before completing.
I also tried several iterations using aws_network_interface_sg_attachment without a security_group block on the aws_instance. This deploys fine, but it relies on the AZs default_vpc to initially launch the ec2 instance into which is a security issue for us and leaves the issue of removing it after deployment. Anyway, the idea was to see if a more specific dependency on the ENI would cause terraform to make the change on AWS (ENI to new SG). It did not work.
Is there no explicit way of causing the “Change Security Group” functionality? Seems this should be done under the Terraform hood whenever it recognizes that the SG will change for an instance or ENI.
@CamelCaseNotation yes, our issue was resolved after setting
revoke_rules_on_deletetotrue.@elektron9 Can you confirm that
revoke_rules_on_deletefixes the issue of being unable to delete a security group that had an inbound rule for another security group?Same issue. For me I’m 99% sure it’s because there an ec-2 instance not being changed that is still using the security group. So right now looks like I have to make this change manually.