Files

4.0 KiB

Assignment

The Nautilus DevOps team has been creating a couple of services on AWS cloud. They have been breaking down the migration into smaller tasks, allowing for better control, risk mitigation, and optimization of resources throughout the migration process. Recently they came up with requirements mentioned below.

There is an instance named xfusion-ec2 and an elastic-ip named xfusion-ec2-eip in us-east-1 region. Attach the xfusion-ec2-eip elastic-ip to the xfusion-ec2 instance using Terraform only. The Terraform working directory is /home/bob/terraform. Update the main.tf file (do not create a separate .tf file) to attach the specified Elastic IP to the instance.

Note: Right-click under the EXPLORER section in VS Code and select Open in Integrated Terminal to launch the terminal.

Solution

Attach Elastic IP — xfusion-ec2-eipxfusion-ec2

Both the instance (aws_instance.ec2) and the Elastic IP (aws_eip.ec2_eip) are already managed in this main.tf. So there's no need for data sources — you reference the existing resources directly and add a single association resource.

main.tf (append this block; leave the existing two resources unchanged)

# Provision EC2 instance
resource "aws_instance" "ec2" {
  ami           = "ami-0c101f26f147fa7fd"
  instance_type = "t2.micro"
  subnet_id     = "subnet-bca4d7696cae064fb"
  vpc_security_group_ids = [
    "sg-62f0812f2b5774df4"
  ]

  tags = {
    Name = "xfusion-ec2"
  }
}

# Provision Elastic IP
resource "aws_eip" "ec2_eip" {
  tags = {
    Name = "xfusion-ec2-eip"
  }
}

# Associate the Elastic IP with the instance
resource "aws_eip_association" "ec2_eip_assoc" {
  allocation_id = aws_eip.ec2_eip.id
  instance_id   = aws_instance.ec2.id
}

How to run

cd /home/bob/terraform
terraform plan     # should show only the new aws_eip_association to add
terraform apply -auto-approve

How it works

Referencing managed resources (not data sources)

Because both the instance and the EIP already live in this configuration, you point the association straight at their resource attributes:

  • allocation_id = aws_eip.ec2_eip.id — a VPC Elastic IP's id is its allocation ID (eipalloc-...), which is what an association binds. (Data sources would only be needed if these resources were created outside this config — here they aren't.)
  • instance_id = aws_instance.ec2.id — the instance's i-... ID.

Referencing the resource attributes (rather than hardcoding IDs) also creates implicit dependencies: Terraform knows the association depends on both the instance and the EIP, so it orders creation correctly and the plan cleanly shows only the new association being added — the two existing resources are untouched.

aws_eip_association

This standalone resource represents the binding between the EIP and the instance. On apply, Terraform calls AssociateAddress, and the instance's public-facing IP becomes the Elastic IP. Keeping the association as its own resource (rather than folding an instance = ... argument into the aws_eip block) is the cleaner, more explicit pattern and keeps the attach/detach lifecycle isolated — destroying just this resource would detach the EIP while leaving the instance and EIP intact.

Note on the alternative: you could instead add instance = aws_instance.ec2.id directly to the aws_eip resource. That also works when Terraform owns the EIP, but a dedicated aws_eip_association is the recommended approach and avoids mixing allocation and association concerns in one resource.

Verify

aws ec2 describe-addresses \
  --filters Name=tag:Name,Values=xfusion-ec2-eip \
  --query 'Addresses[0].{EIP:PublicIp,InstanceId:InstanceId,AssocId:AssociationId}'

Expected — the address shows a populated InstanceId (the xfusion-ec2 instance) and an AssociationId. Cross-check that the instance's PublicIpAddress now equals the EIP:

aws ec2 describe-instances \
  --filters Name=tag:Name,Values=xfusion-ec2 \
  --query 'Reservations[0].Instances[0].PublicIpAddress'