The aws:ec2/eip:Eip resource, part of the Pulumi AWS provider, allocates Elastic IP addresses and manages their association with EC2 instances or network interfaces. This guide focuses on two capabilities: instance and network interface association, and BYOIP and IPAM pool allocation.
Elastic IPs require an Internet Gateway in the VPC before association, though examples don’t show this dependency explicitly. The examples are intentionally small. Combine them with your own VPC infrastructure and dependency management.
Associate an Elastic IP with an EC2 instance
Most deployments allocate an Elastic IP and attach it to an instance, giving the instance a stable public address that persists across stops and starts.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const lb = new aws.ec2.Eip("lb", {
instance: web.id,
domain: "vpc",
});
import pulumi
import pulumi_aws as aws
lb = aws.ec2.Eip("lb",
instance=web["id"],
domain="vpc")
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ec2"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := ec2.NewEip(ctx, "lb", &ec2.EipArgs{
Instance: pulumi.Any(web.Id),
Domain: pulumi.String("vpc"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var lb = new Aws.Ec2.Eip("lb", new()
{
Instance = web.Id,
Domain = "vpc",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.ec2.Eip;
import com.pulumi.aws.ec2.EipArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var lb = new Eip("lb", EipArgs.builder()
.instance(web.id())
.domain("vpc")
.build());
}
}
resources:
lb:
type: aws:ec2:Eip
properties:
instance: ${web.id}
domain: vpc
The instance property attaches the Elastic IP to an EC2 instance by ID. The domain property must be set to “vpc” for VPC-based Elastic IPs. The IP address remains associated even when the instance stops, allowing you to maintain the same public endpoint.
Attach multiple Elastic IPs to one network interface
Applications that need multiple public IPs on a single instance can attach several Elastic IPs to one network interface, each mapped to a different private IP.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const multi_ip = new aws.ec2.NetworkInterface("multi-ip", {
subnetId: main.id,
privateIps: [
"10.0.0.10",
"10.0.0.11",
],
});
const one = new aws.ec2.Eip("one", {
domain: "vpc",
networkInterface: multi_ip.id,
associateWithPrivateIp: "10.0.0.10",
});
const two = new aws.ec2.Eip("two", {
domain: "vpc",
networkInterface: multi_ip.id,
associateWithPrivateIp: "10.0.0.11",
});
import pulumi
import pulumi_aws as aws
multi_ip = aws.ec2.NetworkInterface("multi-ip",
subnet_id=main["id"],
private_ips=[
"10.0.0.10",
"10.0.0.11",
])
one = aws.ec2.Eip("one",
domain="vpc",
network_interface=multi_ip.id,
associate_with_private_ip="10.0.0.10")
two = aws.ec2.Eip("two",
domain="vpc",
network_interface=multi_ip.id,
associate_with_private_ip="10.0.0.11")
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ec2"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
multi_ip, err := ec2.NewNetworkInterface(ctx, "multi-ip", &ec2.NetworkInterfaceArgs{
SubnetId: pulumi.Any(main.Id),
PrivateIps: pulumi.StringArray{
pulumi.String("10.0.0.10"),
pulumi.String("10.0.0.11"),
},
})
if err != nil {
return err
}
_, err = ec2.NewEip(ctx, "one", &ec2.EipArgs{
Domain: pulumi.String("vpc"),
NetworkInterface: multi_ip.ID(),
AssociateWithPrivateIp: pulumi.String("10.0.0.10"),
})
if err != nil {
return err
}
_, err = ec2.NewEip(ctx, "two", &ec2.EipArgs{
Domain: pulumi.String("vpc"),
NetworkInterface: multi_ip.ID(),
AssociateWithPrivateIp: pulumi.String("10.0.0.11"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var multi_ip = new Aws.Ec2.NetworkInterface("multi-ip", new()
{
SubnetId = main.Id,
PrivateIps = new[]
{
"10.0.0.10",
"10.0.0.11",
},
});
var one = new Aws.Ec2.Eip("one", new()
{
Domain = "vpc",
NetworkInterface = multi_ip.Id,
AssociateWithPrivateIp = "10.0.0.10",
});
var two = new Aws.Ec2.Eip("two", new()
{
Domain = "vpc",
NetworkInterface = multi_ip.Id,
AssociateWithPrivateIp = "10.0.0.11",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.ec2.NetworkInterface;
import com.pulumi.aws.ec2.NetworkInterfaceArgs;
import com.pulumi.aws.ec2.Eip;
import com.pulumi.aws.ec2.EipArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var multi_ip = new NetworkInterface("multi-ip", NetworkInterfaceArgs.builder()
.subnetId(main.id())
.privateIps(
"10.0.0.10",
"10.0.0.11")
.build());
var one = new Eip("one", EipArgs.builder()
.domain("vpc")
.networkInterface(multi_ip.id())
.associateWithPrivateIp("10.0.0.10")
.build());
var two = new Eip("two", EipArgs.builder()
.domain("vpc")
.networkInterface(multi_ip.id())
.associateWithPrivateIp("10.0.0.11")
.build());
}
}
resources:
multi-ip:
type: aws:ec2:NetworkInterface
properties:
subnetId: ${main.id}
privateIps:
- 10.0.0.10
- 10.0.0.11
one:
type: aws:ec2:Eip
properties:
domain: vpc
networkInterface: ${["multi-ip"].id}
associateWithPrivateIp: 10.0.0.10
two:
type: aws:ec2:Eip
properties:
domain: vpc
networkInterface: ${["multi-ip"].id}
associateWithPrivateIp: 10.0.0.11
The networkInterface property targets a specific network interface rather than an instance. The associateWithPrivateIp property maps each Elastic IP to one of the interface’s private IPs. This allows a single instance to serve multiple public endpoints.
Allocate an IP from your own address pool
Organizations that bring their own IP address ranges to AWS can allocate Elastic IPs from those pools rather than using Amazon-provided addresses.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const byoip_ip = new aws.ec2.Eip("byoip-ip", {
domain: "vpc",
publicIpv4Pool: "ipv4pool-ec2-012345",
});
import pulumi
import pulumi_aws as aws
byoip_ip = aws.ec2.Eip("byoip-ip",
domain="vpc",
public_ipv4_pool="ipv4pool-ec2-012345")
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ec2"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := ec2.NewEip(ctx, "byoip-ip", &ec2.EipArgs{
Domain: pulumi.String("vpc"),
PublicIpv4Pool: pulumi.String("ipv4pool-ec2-012345"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var byoip_ip = new Aws.Ec2.Eip("byoip-ip", new()
{
Domain = "vpc",
PublicIpv4Pool = "ipv4pool-ec2-012345",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.ec2.Eip;
import com.pulumi.aws.ec2.EipArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var byoip_ip = new Eip("byoip-ip", EipArgs.builder()
.domain("vpc")
.publicIpv4Pool("ipv4pool-ec2-012345")
.build());
}
}
resources:
byoip-ip:
type: aws:ec2:Eip
properties:
domain: vpc
publicIpv4Pool: ipv4pool-ec2-012345
The publicIpv4Pool property specifies a BYOIP pool ID. AWS allocates the Elastic IP from your organization’s address range. This maintains IP address continuity when migrating workloads to AWS.
Allocate an IP from an IPAM-managed pool
AWS IPAM (IP Address Manager) provides centralized IP address management across accounts and regions. Elastic IPs can be allocated from IPAM pools for consistent address governance.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const ipam_ip = new aws.ec2.Eip("ipam-ip", {
domain: "vpc",
ipamPoolId: "ipam-pool-07ccc86aa41bef7ce",
});
import pulumi
import pulumi_aws as aws
ipam_ip = aws.ec2.Eip("ipam-ip",
domain="vpc",
ipam_pool_id="ipam-pool-07ccc86aa41bef7ce")
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ec2"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := ec2.NewEip(ctx, "ipam-ip", &ec2.EipArgs{
Domain: pulumi.String("vpc"),
IpamPoolId: pulumi.String("ipam-pool-07ccc86aa41bef7ce"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var ipam_ip = new Aws.Ec2.Eip("ipam-ip", new()
{
Domain = "vpc",
IpamPoolId = "ipam-pool-07ccc86aa41bef7ce",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.ec2.Eip;
import com.pulumi.aws.ec2.EipArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var ipam_ip = new Eip("ipam-ip", EipArgs.builder()
.domain("vpc")
.ipamPoolId("ipam-pool-07ccc86aa41bef7ce")
.build());
}
}
resources:
ipam-ip:
type: aws:ec2:Eip
properties:
domain: vpc
ipamPoolId: ipam-pool-07ccc86aa41bef7ce
The ipamPoolId property references an IPAM pool that has public IPv4 CIDR blocks provisioned. IPAM enforces allocation policies and tracks IP usage across your organization.
Beyond these examples
These snippets focus on specific Elastic IP features: instance and network interface association, and BYOIP and IPAM pool allocation. They’re intentionally minimal rather than full networking configurations.
The examples may reference pre-existing infrastructure such as EC2 instances, network interfaces, subnets, Internet Gateways (required but not shown), and BYOIP or IPAM pools for relevant examples. They focus on IP allocation and association rather than provisioning the surrounding infrastructure.
To keep things focused, common Elastic IP patterns are omitted, including:
- Internet Gateway dependency management (dependsOn)
- Private IP targeting (associateWithPrivateIp for single IPs)
- Tags for resource organization
- Network Border Group for Local Zone placement
These omissions are intentional: the goal is to illustrate how each Elastic IP feature is wired, not provide drop-in networking modules. See the Elastic IP resource reference for all available configuration options.
Let's create AWS Elastic IP Addresses
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Common Errors & Pitfalls
networkInterface to associate EIPs with aws.lb.LoadBalancer or aws.ec2.NatGateway. Instead, use the allocationId property available in those resources to let AWS manage the association.instance and networkInterface causes undefined behavior. Choose one or the other.dependsOn to create an explicit dependency on the IGW resource.Association & Attachment
associateWithPrivateIp to specify which primary or secondary private IP address to associate with. If not specified, the EIP associates with the primary private IP.associateWithPrivateIp pointing to each private IP.IP Address Pools & Allocation
address is used. Use publicIpv4Pool to allocate any IP from a pool, or address to request a specific IP.publicIpv4Pool to your BYOIP pool identifier, or use address to specify an exact IP from the pool. Both options require VPC EIPs (domain: "vpc").ipamPoolId to the ID of an IPAM pool that has an Amazon-provided or BYOIP public IPv4 CIDR provisioned to it.VPC & Configuration
tags property to assign tags. Tags in provider defaultTags will be merged with resource-level tags.Using a different cloud?
Explore networking guides for other cloud providers: