2

I am spinning up multiple Amazon EC2 instances and need to attach a Security Group. I am able to achieve it for one EC2 instance but looking for solution for multiple EC2s. I am using TerraForm 0.12. Please let me know how can I use data resource :- data "aws_instances" (s).

Here is the code for single EC2 which i am trying to convert for multiple EC2s:

    resource "aws_instance" "ec2_instance" {
      count                = "${var.ec2_instance_count}"
      ami                  = "${data.aws_ami.app_qrm_ami.id}"
    ...
    }
    data "aws_instances" "ec2_instances" {
  count      = "${var.ec2_instance_count}"
  filter {
    name = "instance-id"
    values = ["${aws_instance.ec2_instance.*.id[count.index]}"]
  }
    }
    resource "aws_network_interface_sg_attachment" "sg_attachment" {
      security_group_id    = "${data.aws_security_group.security_group.id}"
      network_interface_id = "${data.aws_instance.ec2_instance[count.index].network_interface_id}" //facing issues here.
    }

I want to achieve this using data "aws_instances" #notice the (s). Thanks in advance.

Kamlendra Sharma
  • 687
  • 2
  • 10
  • 37

2 Answers2

3

For removing the Hard coding of ec2 AMI, you can use the following data provider:-

  data "aws_ami" "amazon_linux" {
  count       = "${var.ec2_instance_count}"
  most_recent = true
  owners      = ["amazon"]

  filter {
    name = "name"
    values = [
      "amzn-ami-hvm-*-x86_64-gp2",
    ]
  }

  filter {
    name = "owner-alias"
    values = [
      "amazon",
    ]
  }
}

For rendering the ami id:-

resource "aws_instance" "ec2_instance" {
  count             = "${var.ec2_instance_count}"
  ami               = "${data.aws_ami.amazon_linux[count.index].id}"
  network_interface = 

For getting network_interface_id:-

resource "aws_network_interface" "ec2_nic" {
  count           = "${var.ec2_instance_count}"
  subnet_id       = "${aws_subnet.public_a.id}"
  private_ips     = ["10.0.0.50"]
  security_groups = ["${aws_security_group.web.id}"]

  attachment {
    instance     = "${aws_instance.ec2_instance[count.index].id}"
  }
}

resource "aws_network_interface_sg_attachment" "sg_attachment" {
  security_group_id    = "${data.aws_security_group.security_group.id}"
  network_interface_id = "${aws_network_interface.ec2_ami[count.index].id}"
}
karan sharma
  • 477
  • 3
  • 10
  • Thanks Karan. However the hardcoding is not there with ami in my code, ami is fine. It is with instance_id in the 'data' section of the "aws_instance" and i need help regarding having multiple Ec2_instance looping for attachment of Security group. – Kamlendra Sharma May 10 '20 at 07:10
  • @kamlendra try using instance_id = aws_instance.ec2_instance[count.imdex].id in your data resource – karan sharma May 10 '20 at 07:22
  • I tried that but no luck. actually everything was working fine but after Terraform upgrade to 0.12 I started facing errors. it's sad that terraform is not backward compatible. i have update the old code here. https://stackoverflow.com/questions/61727500/issues-after-upgrade-to-terraform-0-12 – Kamlendra Sharma May 11 '20 at 10:28
1

Thanks Karan, your answer solved the issue for me. Later the infra got fairly complex and I found a different and a smarter way to solve it. I would like to share with other people which might help TF community in future.

multiple internal SG {internal 0-7}and one external to all for creating different groups of swarm which allowed to communicate internal and selectively externally. Majorly used in Microsoft HPC grid.

resource "aws_instance" "ec2_instance" {
  count                   = tonumber(var.mycount)
 vpc_security_group_ids  = [data.aws_security_group.external_security_group.id, element(data.aws_security_group.internal_security_group.*.id, count.index)]
...
}
resource "aws_security_group" "internal_security_group" {
  count       = tonumber(var.mycount)
  name        = "${var.internalSGname}${count.index}"
}
resource "aws_security_group" "external_security_group" {
  name        = ${var.external_sg_name}"

}

Kamlendra Sharma
  • 687
  • 2
  • 10
  • 37