How to assign an AWS Elastic IP to a newly created EC2 instance with Terraform without it getting reassigned when another instance is created?
Asked Answered
A

1

8

I currently have the following Terraform plan:

provider "aws" {
  region = var.region
}

resource "aws_instance" "ec2" {
  ami             = var.ami
  instance_type   = var.instanceType
  subnet_id       = var.subnet 
  security_groups = var.securityGroups 

  timeouts {
    create = "2h"
    delete = "2h"
  }

  tags = {
    Name = "${var.ec2ResourceName}"
    CoreInfra = "false"
  }

  lifecycle {
    prevent_destroy = true
  }

  key_name = "My_Key_Name"

  connection {
    type        = "ssh"
    user        = "ec2-user"
    password    = ""
    private_key = file(var.keyPath)
    host        = self.public_ip
  }

  provisioner "file" {
    source      = "/home/ec2-user/code/backend/ec2/setup_script.sh"
    destination = "/tmp/setup_script.sh"
  }

  provisioner "remote-exec" {
    inline = [
      "chmod +x /tmp/setup_script.sh",
      "bash /tmp/setup_script.sh ${var.ec2ResourceName}"
    ]
  }
}

resource "aws_eip" "eip_manager" {
  name = "eip-${var.ec2ResourceName}"
  instance = aws_instance.ec2.id
  vpc = true
  
  tags = {
    Name = "eip-${var.ec2ResourceName}"
  }

  lifecycle {
    prevent_destroy = true
  }
}

This plan can be run multiple times, creating a single EC2 instance each time without removing the previous one. However, there is a single Elastic IP that ends up being reassigned to the most recently-created EC2 instance. How can I add an Elastic IP to each new instance that does not get reassigned?

Allard answered 6/8, 2020 at 14:21 Comment(4)
What do you mean by This plan can be run multiple times, creating a single EC2 instance each time without removing the previous one? If you are using the same state file then Terraform won't create extra resources if nothing has changed. This should also apply to your elastic IP address. If you are using a different state file for each run then you should end up with a new EC2 instance and a new EIP as well. Can you share the output of a plan that shows something different happening?Heady
I'm running the Terraform plan with the following npm script: terraform apply -auto-approve -var=\"ec2ResourceName=$EC2_INSTANCE_NAME\"; terraform state rm 'aws_instance.ec2'. I can't recall the details exactly because it's been a while, but I think I configured AWS to not allow deletes from Terraform, so Terraform thinks the resource is gone when it isn't. It was a difficult problem to solve but has been working great. Actually, in the course of writing this comment, I found the solution, which is super simple given the above. I'll approve your answer if you'd like to give it.Allard
If you're not trying to keep state around so that Terraform can manage the lifecycle of the resources it's creating then it's probably not worth using Terraform imo and instead just use the AWS CLI or something else. Terraform really shines with managing the lifecycle of complicated, dependent resources so just automatically removing part of it from state each time makes it overkill. But yes the obvious fix here is to also remove the EIP from state when you remove the instance from state.Heady
@Heady if you make the above an answer I will accept it.Allard
G
11

maybe with aws_eip_association, here is the snippet:

resource "aws_eip_association" "eip_assoc" {
  instance_id   = aws_instance.ec2.id
  allocation_id = aws_eip.eip_manager.id
}

More info here: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eip_association

Galloping answered 7/8, 2020 at 7:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.