Associating an Elastic IP Address (EIP) with a secondary Elastic Network Interface (ENI) gives each application on a single ECS instance its own public IP address — without reconfiguring the instance itself.
This tutorial walks you through creating and associating an EIP with a secondary ENI using Terraform.
Note: The sample code in this tutorial supports one-click execution. Run it now in API Workbench
Prerequisites
Before you begin, ensure that you have:
Terraform installed and configured with Alibaba Cloud credentials
(Optional) An existing VPC ID and zone ID, if associating the ENI with an existing ECS instance
Create a configuration file
Create a file named terraform.tf, add the following content, and save it.
The configuration creates a VPC, vSwitch, security group, secondary ENI, and an EIP, then associates the EIP with the ENI. Use the variables table below to customize the deployment.
provider "alicloud" {
region = var.region
}
# The region where the resources will be created.
variable "region" {
default = "cn-beijing"
description = "The region where the resources will be created."
}
# The ID of an existing VPC (required when associating ENI with existing ECS instance).
variable "vpc_id" {
default = ""
description = "When binding an ENI to an existing ECS instance, this value is required and must be the VPC associated with the ECS instance."
}
# The CIDR block for the VPC. You can leave this parameter empty if you specify vpc_id.
variable "vpc_cidr_block" {
default = "192.168.0.0/16"
description = "Specify the CIDR block of the VPC. If the vpc_id is provided, this value can be left blank."
}
# The zone. This parameter is required when you associate an ENI with an existing ECS instance. The value must be the zone where the ECS instance is located.
variable "zone_id" {
default = ""
description = "When binding an ENI to an existing ECS instance, this value is required and must be the zone where the ECS instance is located."
}
# The CIDR block for the vSwitch. The CIDR block must be within the CIDR block of the VPC.
variable "vswitch_cidr_block" {
default = "192.168.0.0/24"
description = "Specify the CIDR block of the VSwitch. The CIDR block must be within the range of the VPC CIDR block."
}
# The source IP address for accessing the ENI.
variable "source_ip" {
description = "The IP address you used to access the ENI."
type = string
default = "0.0.0.0/0"
}
# The private IP address of the ENI.
variable "private_ip" {
description = "The primary private IP address of the ENI. The specified IP address must be available within the CIDR block of the VSwitch. If this parameter is not specified, an available IP address is assigned from the VSwitch CIDR block at random."
type = string
default = ""
}
locals {
new_zone_id = var.zone_id == ""
create_vpc = var.vpc_id == ""
}
resource "alicloud_eip" "eip" {
address_name = "test_eip"
}
resource "alicloud_vpc" "vpc" {
count = local.create_vpc ? 1 : 0
vpc_name = "test_vpc"
cidr_block = var.vpc_cidr_block
}
data "alicloud_zones" "default" {
count = local.new_zone_id ? 1 : 0
available_resource_creation = "VSwitch"
}
resource "alicloud_vswitch" "vswitch" {
vswitch_name = "test_vswitch"
cidr_block = var.vswitch_cidr_block
zone_id = local.new_zone_id ? data.alicloud_zones.default[0].zones.0.id : var.zone_id
vpc_id = local.create_vpc ? alicloud_vpc.vpc[0].id : var.vpc_id
}
resource "alicloud_security_group" "group" {
security_group_name = "test_sg"
vpc_id = local.create_vpc ? alicloud_vpc.vpc[0].id : var.vpc_id
}
# Add a rule to allow inbound traffic on TCP port 80.
resource "alicloud_security_group_rule" "allow_80_tcp" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "intranet"
policy = "accept"
port_range = "80/80"
priority = 1
security_group_id = alicloud_security_group.group.id
cidr_ip = var.source_ip
}
resource "alicloud_network_interface" "default" {
network_interface_name = "test_eni"
vswitch_id = alicloud_vswitch.vswitch.id
security_group_ids = [alicloud_security_group.group.id]
primary_ip_address = var.private_ip
secondary_private_ip_address_count = 1
}
resource "alicloud_eip_association" "default" {
allocation_id = alicloud_eip.eip.id
instance_type = "NetworkInterface"
instance_id = alicloud_network_interface.default.id
}Variables
| Variable | Default | Required | Description |
|---|---|---|---|
region | cn-beijing | No | Region where all resources are created |
vpc_id | _(blank)_ | Required when associating with an existing ECS instance | ID of the existing VPC; must match the ECS instance's VPC |
vpc_cidr_block | 192.168.0.0/16 | No | CIDR block for the new VPC; leave blank if vpc_id is set |
zone_id | _(blank)_ | Required when associating with an existing ECS instance | Zone where the ECS instance is located |
vswitch_cidr_block | 192.168.0.0/24 | No | CIDR block for the vSwitch; must fall within the VPC CIDR block |
source_ip | 0.0.0.0/0 | No | Source IP address allowed to access the ENI |
private_ip | _(blank)_ | No | Primary private IP of the ENI; if blank, an IP is assigned automatically from the vSwitch CIDR block |
Create resources
Run the following commands from the directory containing terraform.tf.
Initialize Terraform:
terraform initA successful initialization ends with:
Terraform has been successfully initialized!Create the resources:
terraform applyEnter
yesat the confirmation prompt. When the operation completes, you see:Apply complete! Resources: 7 added, 0 changed, 0 destroyed.Note: To associate a new ENI with an existing ECS instance, pass the required variables at apply time. For example:
terraform apply -var source_ip=XX.XX.XX.XX -var vpc_id=vpc-2vc4ctyuxpq6nXXXXXXXXX -var zone_id=cn-beijing-a -var vswitch_cidr_block=XX.XX.XX.XX/XXVerify the created resources:
terraform showThe output lists all provisioned resources, including the VPC, EIP, and ENI. Alternatively, view the resources in the Alibaba Cloud console.
Clean up resources
To release all resources created by this configuration, run:
terraform destroyWhat's next
After creating an ENI, associate it with an ECS instance in the same zone and VPC.
For a full list of Terraform commands, see Common Terraform commands.