Aws_security_group_rule toggles the re

Here is my code and the rules getting toggle always. Meaning when I execute, it adds the ingress rules for the security group, if I do Terraform apply, getting deleted these rules from the security group, when I do Terraform apply, add again. and this is kind of scenario like Toggles

Below is my code and is there any way to fix this issue?

resource “aws_security_group” “emr_master_private” {

vpc_id = “${aws_vpc.vpc-dev.id}”

name = “${var.emr_master_pri_name}”

description = “Allow all ssh conection from internet”

ingress {

from_port = 0

to_port = 65535

protocol = “tcp”

self = true

}

ingress {

from_port = 0

to_port = 65535

protocol = “udp”

self = true

}

ingress {

from_port = -1

to_port = -1

protocol = “icmp”

self = true

}

tags = {

Name = “${var.emr_master_pri_name}”

Source = “${var.infra_source}”

}

}

resource “aws_security_group” “emr_slave_private” {

vpc_id = “${aws_vpc.vpc-dev.id}”

name = “${var.emr_slave_pri_name}”

description = “Allow all ssh conection from internet”

ingress {

from_port = 0

to_port = 65535

protocol = “tcp”

self = true

}

ingress {

from_port = 0

to_port = 65535

protocol = “udp”

self = true

}

ingress {

from_port = -1

to_port = -1

protocol = “icmp”

self = true

}

tags = {

Name = “${var.emr_slave_pri_name}”

Source = “${var.infra_source}”

}

}

resource “aws_security_group_rule” “emr_master_private_tcp” {

type = “ingress”

from_port = 0

to_port = 65535

protocol = “tcp”

security_group_id = “${aws_security_group.emr_master_private.id}”

source_security_group_id = “${aws_security_group.emr_slave_private.id}”

}

resource “aws_security_group_rule” “emr_master_private_udp” {

type = “ingress”

from_port = 0

to_port = 65535

protocol = “udp”

security_group_id = “${aws_security_group.emr_master_private.id}”

source_security_group_id = “${aws_security_group.emr_slave_private.id}”

}

resource “aws_security_group_rule” “emr_master_private_icmp” {

type = “ingress”

from_port = -1

to_port = -1

protocol = “icmp”

security_group_id = “${aws_security_group.emr_master_private.id}”

source_security_group_id = “${aws_security_group.emr_slave_private.id}”

}

resource “aws_security_group_rule” “emr_slave_private_tcp” {

type = “ingress”

from_port = 0

to_port = 65535

protocol = “tcp”

security_group_id = “${aws_security_group.emr_slave_private.id}”

source_security_group_id = “${aws_security_group.emr_master_private.id}”

}

resource “aws_security_group_rule” “emr_slave_private_udp” {

type = “ingress”

from_port = 0

to_port = 65535

protocol = “udp”

security_group_id = “${aws_security_group.emr_slave_private.id}”

source_security_group_id = “${aws_security_group.emr_master_private.id}”

}

resource “aws_security_group_rule” “emr_slave_private_icmp” {

type = “ingress”

from_port = -1

to_port = -1

protocol = “icmp”

security_group_id = “${aws_security_group.emr_slave_private.id}”

source_security_group_id = “${aws_security_group.emr_master_private.id}”

}

Thank you,
Bala

Hi @balarajuaws68

Your examples used both Security Group with in-line rules and some rules that are added to the created Security Groups. It is a non supported configuration.

From the Terraform official docs about aws_security_group_rule I see a note:

NOTE on Security Groups and Security Group Rules: Terraform currently provides both a standalone Security Group Rule resource (a single ingress or egress rule), and a Security Group resource with ingress and egress rules defined in-line. At this time you cannot use a Security Group with in-line rules in conjunction with any Security Group Rule resources. Doing so will cause a conflict of rule settings and will overwrite rules.

You could rewrite your code to either create the Security Group without any rules and add the rules after that or create the Security Groups with inline rules and no additional Security Group Rule resources.

Thank you so much but when I tried with below code,

resource “aws_security_group” “emr_master_private” {

vpc_id = “${var.vpc_id_mod}”

name = “${var.emr_security_group_master_private_name}”

tags = {

Name = "${var.emr_security_group_master_private_name}"

Source = "${var.infra_source}"

}

}

resource “aws_security_group_rule” “emr_master_private_tcp_self” {

type = “ingress”

from_port = 0

to_port = 65535

protocol = “tcp”

security_group_id = aws_security_group.emr_master_private.id

}

giving me the error,
resource “aws_security_group” “emr_master_private” {

vpc_id = “${var.vpc_id_mod}”

name = “${var.emr_security_group_master_private_name}”

tags = {

Name = "${var.emr_security_group_master_private_name}"

Source = "${var.infra_source}"

}

}

resource “aws_security_group_rule” “emr_master_private_tcp_self” {

type = “ingress”

from_port = 0

to_port = 65535

protocol = “tcp”

security_group_id = aws_security_group.emr_master_private.id

}

I tried with Self, but doesn’t work.

Could you please help me to make it work?

Hi @balarajuaws68

I would suggest that you take a look at the following tutorial where I explain how I like to define Resource Security in AWS with Terraform:

It uses modules and many references to other resources.