The aws:alb/loadBalancer:LoadBalancer resource, part of the Pulumi AWS provider, provisions an Elastic Load Balancer: its type (Application, Network, or Gateway), network placement, and traffic distribution settings. This guide focuses on three capabilities: Application and Network Load Balancer deployment, subnet placement with standard or custom IP addressing, and access logging and deletion protection.
Load balancers require VPC subnets spanning multiple availability zones, security groups for Application Load Balancers, and optionally S3 buckets for logging or Elastic IPs for static addressing. The examples are intentionally small. Combine them with your own VPC infrastructure, target groups, and listeners.
Deploy an internet-facing Application Load Balancer
Most web applications distribute HTTP/HTTPS traffic across targets in different availability zones using an Application Load Balancer.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const test = new aws.lb.LoadBalancer("test", {
name: "test-lb-tf",
internal: false,
loadBalancerType: "application",
securityGroups: [lbSg.id],
subnets: .map(subnet => (subnet.id)),
enableDeletionProtection: true,
accessLogs: {
bucket: lbLogs.id,
prefix: "test-lb",
enabled: true,
},
tags: {
Environment: "production",
},
});
import pulumi
import pulumi_aws as aws
test = aws.lb.LoadBalancer("test",
name="test-lb-tf",
internal=False,
load_balancer_type="application",
security_groups=[lb_sg["id"]],
subnets=[subnet["id"] for subnet in public],
enable_deletion_protection=True,
access_logs={
"bucket": lb_logs["id"],
"prefix": "test-lb",
"enabled": True,
},
tags={
"Environment": "production",
})
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var test = new Aws.LB.LoadBalancer("test", new()
{
Name = "test-lb-tf",
Internal = false,
LoadBalancerType = "application",
SecurityGroups = new[]
{
lbSg.Id,
},
Subnets = .Select(subnet =>
{
return subnet.Id;
}).ToList(),
EnableDeletionProtection = true,
AccessLogs = new Aws.LB.Inputs.LoadBalancerAccessLogsArgs
{
Bucket = lbLogs.Id,
Prefix = "test-lb",
Enabled = true,
},
Tags =
{
{ "Environment", "production" },
},
});
});
The loadBalancerType property determines routing behavior: application load balancers operate at the HTTP layer and support path-based routing and host-based routing. The internal property controls whether the load balancer receives a public DNS name (false) or only private IPs (true). The accessLogs block sends request logs to S3 for analysis. The enableDeletionProtection property prevents accidental deletion through the AWS API.
Deploy a Network Load Balancer for TCP traffic
Applications requiring ultra-low latency or handling millions of requests per second route TCP/UDP traffic at the connection level using Network Load Balancers.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const test = new aws.lb.LoadBalancer("test", {
name: "test-lb-tf",
internal: false,
loadBalancerType: "network",
subnets: .map(subnet => (subnet.id)),
enableDeletionProtection: true,
tags: {
Environment: "production",
},
});
import pulumi
import pulumi_aws as aws
test = aws.lb.LoadBalancer("test",
name="test-lb-tf",
internal=False,
load_balancer_type="network",
subnets=[subnet["id"] for subnet in public],
enable_deletion_protection=True,
tags={
"Environment": "production",
})
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var test = new Aws.LB.LoadBalancer("test", new()
{
Name = "test-lb-tf",
Internal = false,
LoadBalancerType = "network",
Subnets = .Select(subnet =>
{
return subnet.Id;
}).ToList(),
EnableDeletionProtection = true,
Tags =
{
{ "Environment", "production" },
},
});
});
Network Load Balancers operate at the transport layer, preserving source IP addresses and providing static IP addresses per availability zone. Unlike Application Load Balancers, they don’t require security groups by default (though they can be added). The subnets property places the load balancer in specific availability zones; for network type, subnets can only be added, not removed.
Assign static Elastic IPs to Network Load Balancer nodes
Some applications require stable IP addresses for firewall allowlisting or DNS configuration. Network Load Balancers can use Elastic IPs for predictable endpoints.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.lb.LoadBalancer("example", {
name: "example",
loadBalancerType: "network",
subnetMappings: [
{
subnetId: example1AwsSubnet.id,
allocationId: example1.id,
},
{
subnetId: example2AwsSubnet.id,
allocationId: example2.id,
},
],
});
import pulumi
import pulumi_aws as aws
example = aws.lb.LoadBalancer("example",
name="example",
load_balancer_type="network",
subnet_mappings=[
{
"subnet_id": example1_aws_subnet["id"],
"allocation_id": example1["id"],
},
{
"subnet_id": example2_aws_subnet["id"],
"allocation_id": example2["id"],
},
])
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/lb"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := lb.NewLoadBalancer(ctx, "example", &lb.LoadBalancerArgs{
Name: pulumi.String("example"),
LoadBalancerType: pulumi.String("network"),
SubnetMappings: lb.LoadBalancerSubnetMappingArray{
&lb.LoadBalancerSubnetMappingArgs{
SubnetId: pulumi.Any(example1AwsSubnet.Id),
AllocationId: pulumi.Any(example1.Id),
},
&lb.LoadBalancerSubnetMappingArgs{
SubnetId: pulumi.Any(example2AwsSubnet.Id),
AllocationId: pulumi.Any(example2.Id),
},
},
})
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 example = new Aws.LB.LoadBalancer("example", new()
{
Name = "example",
LoadBalancerType = "network",
SubnetMappings = new[]
{
new Aws.LB.Inputs.LoadBalancerSubnetMappingArgs
{
SubnetId = example1AwsSubnet.Id,
AllocationId = example1.Id,
},
new Aws.LB.Inputs.LoadBalancerSubnetMappingArgs
{
SubnetId = example2AwsSubnet.Id,
AllocationId = example2.Id,
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.lb.LoadBalancer;
import com.pulumi.aws.lb.LoadBalancerArgs;
import com.pulumi.aws.lb.inputs.LoadBalancerSubnetMappingArgs;
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 example = new LoadBalancer("example", LoadBalancerArgs.builder()
.name("example")
.loadBalancerType("network")
.subnetMappings(
LoadBalancerSubnetMappingArgs.builder()
.subnetId(example1AwsSubnet.id())
.allocationId(example1.id())
.build(),
LoadBalancerSubnetMappingArgs.builder()
.subnetId(example2AwsSubnet.id())
.allocationId(example2.id())
.build())
.build());
}
}
resources:
example:
type: aws:lb:LoadBalancer
properties:
name: example
loadBalancerType: network
subnetMappings:
- subnetId: ${example1AwsSubnet.id}
allocationId: ${example1.id}
- subnetId: ${example2AwsSubnet.id}
allocationId: ${example2.id}
The subnetMappings property replaces the subnets property when you need control over IP addresses. Each mapping pairs a subnet with an Elastic IP allocation. The allocationId references a pre-allocated Elastic IP; the load balancer assigns this IP to its node in that subnet. This provides stable addresses that persist across load balancer updates.
Configure private IP addresses for internal load balancing
Internal applications that need predictable private IP addresses for service discovery or network routing can specify exact IPs within their subnet ranges.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.lb.LoadBalancer("example", {
name: "example",
loadBalancerType: "network",
subnetMappings: [
{
subnetId: example1.id,
privateIpv4Address: "10.0.1.15",
},
{
subnetId: example2.id,
privateIpv4Address: "10.0.2.15",
},
],
});
import pulumi
import pulumi_aws as aws
example = aws.lb.LoadBalancer("example",
name="example",
load_balancer_type="network",
subnet_mappings=[
{
"subnet_id": example1["id"],
"private_ipv4_address": "10.0.1.15",
},
{
"subnet_id": example2["id"],
"private_ipv4_address": "10.0.2.15",
},
])
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/lb"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := lb.NewLoadBalancer(ctx, "example", &lb.LoadBalancerArgs{
Name: pulumi.String("example"),
LoadBalancerType: pulumi.String("network"),
SubnetMappings: lb.LoadBalancerSubnetMappingArray{
&lb.LoadBalancerSubnetMappingArgs{
SubnetId: pulumi.Any(example1.Id),
PrivateIpv4Address: pulumi.String("10.0.1.15"),
},
&lb.LoadBalancerSubnetMappingArgs{
SubnetId: pulumi.Any(example2.Id),
PrivateIpv4Address: pulumi.String("10.0.2.15"),
},
},
})
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 example = new Aws.LB.LoadBalancer("example", new()
{
Name = "example",
LoadBalancerType = "network",
SubnetMappings = new[]
{
new Aws.LB.Inputs.LoadBalancerSubnetMappingArgs
{
SubnetId = example1.Id,
PrivateIpv4Address = "10.0.1.15",
},
new Aws.LB.Inputs.LoadBalancerSubnetMappingArgs
{
SubnetId = example2.Id,
PrivateIpv4Address = "10.0.2.15",
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.lb.LoadBalancer;
import com.pulumi.aws.lb.LoadBalancerArgs;
import com.pulumi.aws.lb.inputs.LoadBalancerSubnetMappingArgs;
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 example = new LoadBalancer("example", LoadBalancerArgs.builder()
.name("example")
.loadBalancerType("network")
.subnetMappings(
LoadBalancerSubnetMappingArgs.builder()
.subnetId(example1.id())
.privateIpv4Address("10.0.1.15")
.build(),
LoadBalancerSubnetMappingArgs.builder()
.subnetId(example2.id())
.privateIpv4Address("10.0.2.15")
.build())
.build());
}
}
resources:
example:
type: aws:lb:LoadBalancer
properties:
name: example
loadBalancerType: network
subnetMappings:
- subnetId: ${example1.id}
privateIpv4Address: 10.0.1.15
- subnetId: ${example2.id}
privateIpv4Address: 10.0.2.15
For internal load balancers, subnetMappings can specify privateIpv4Address instead of allocationId. The IP must fall within the subnet’s CIDR range and be available. This gives you control over the exact private IPs used for internal service endpoints, useful for DNS records or network routing rules that reference specific addresses.
Beyond these examples
These snippets focus on specific load balancer features: Application and Network Load Balancer types, subnet placement and IP address control, and access logging and deletion protection. They’re intentionally minimal rather than full traffic distribution solutions.
The examples reference pre-existing infrastructure such as VPC subnets across multiple availability zones, security groups for Application Load Balancers, S3 buckets for access logs, and Elastic IP allocations for static IP configurations. They focus on configuring the load balancer rather than provisioning the surrounding network.
To keep things focused, common load balancer patterns are omitted, including:
- Cross-zone load balancing (enableCrossZoneLoadBalancing)
- Connection and health check logging (connectionLogs, healthCheckLogs)
- HTTP/2 and header processing (enableHttp2, dropInvalidHeaderFields, xffHeaderProcessingMode)
- Idle timeout and client keep-alive tuning (idleTimeout, clientKeepAlive)
- WAF integration and TLS header forwarding (enableWafFailOpen, enableTlsVersionAndCipherSuiteHeaders)
- Zonal shift and DNS routing policies (enableZonalShift, dnsRecordClientRoutingPolicy)
These omissions are intentional: the goal is to illustrate how each load balancer feature is wired, not provide drop-in traffic distribution modules. See the Load Balancer resource reference for all available configuration options.
Let's create AWS Application Load Balancers
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Load Balancer Types & Configuration
application (default), network, or gateway. The type is immutable after creation.subnets or subnetMappings is required. Use subnetMappings when you need to specify Elastic IPs (allocationId) or private IP addresses (privateIpv4Address) for your load balancer.aws.alb.LoadBalancer is an alias for aws.lb.LoadBalancer with the same functionality.Networking & IP Addressing
ipv4 as the ipAddressType. You can only change to dualstack if the selected subnets are IPv6 enabled.subnetMappings with subnetId and allocationId for each subnet, as shown in the Elastic IPs example.subnetMappings with subnetId and privateIpv4Address for each subnet.network type load balancers, subnets can only be added. Deleting a subnet forces recreation of the resource.Security Groups
network type load balancers, security groups cannot be added if none are currently present, and cannot all be removed once added. Either condition forces recreation of the resource.application or network type load balancers, but not for gateway type.Immutability & Lifecycle
internal, name, namePrefix, loadBalancerType, and customerOwnedIpv4Pool.secondaryIpsAutoAssignedPerSubnet forces recreation of the resource. Only increase this value if needed.Advanced Features & Defaults
network and gateway types, it’s disabled by default (false). For application type, it’s always enabled (true) and cannot be disabled.idleTimeout is 60 seconds. This setting only applies to application type load balancers.Using a different cloud?
Explore networking guides for other cloud providers: