The aws:ec2/eip:Eip resource, part of the Pulumi AWS provider, allocates Elastic IP addresses and optionally associates them 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, Internet Gateways, 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 a specific EC2 instance. The domain property must be set to “vpc” for VPC-based Elastic IPs. The IP remains associated even if you stop and restart the instance, unlike the ephemeral public IPs AWS assigns by default.
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 resource defines multiple private IPs on a single interface. Each Elastic IP uses networkInterface to target that interface and associateWithPrivateIp to specify which private IP receives the public address. This allows one 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 references a BYOIP pool ID that you’ve previously advertised to AWS. This lets you maintain consistent public IPs when migrating workloads to AWS or meet compliance requirements for specific address ranges.
Allocate an IP from an IPAM-managed pool
Teams using AWS IPAM to centrally manage IP address allocation can provision Elastic IPs from IPAM pools that track usage across accounts and regions.
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 tracks which addresses are in use, preventing conflicts and providing visibility into IP allocation 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 allocating and associating Elastic IPs 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 cost tracking and 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.ec2.NatGateway or aws.lb.LoadBalancer. 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 to avoid timing issues.address will be used. The API won’t error, but publicIpv4Pool is ignored when both are specified.Association & Attachment
networkInterface ID, using associateWithPrivateIp to specify different private IPs (e.g., 10.0.0.10, 10.0.0.11) for each EIP.associateWithPrivateIp property to specify the primary or secondary private IP. If not specified, the EIP associates with the primary private IP by default.instance for direct EC2 instance attachment, or networkInterface for attaching to a specific network interface. They’re mutually exclusive, so choose based on your use case.IP Address Pools & Allocation
publicIpv4Pool to your BYOIP pool identifier (e.g., ipv4pool-ec2-012345) and domain to vpc.ipamPoolId to your IPAM pool ID (e.g., ipam-pool-07ccc86aa41bef7ce) and domain to vpc.address specifies an exact IP from the pool, while publicIpv4Pool lets AWS choose. If both are specified, address takes precedence.Using a different cloud?
Explore networking guides for other cloud providers: