Create Azure Public IP Addresses

The azure-native:network:PublicIPAddress resource, part of the Pulumi Azure Native provider, provisions a public IP address: its allocation method, DNS settings, and SKU tier. This guide focuses on three capabilities: default IP provisioning, DNS label configuration, and static allocation with global tier.

Public IPs require an existing resource group and are typically attached to load balancers, VMs, or NAT gateways. The examples are intentionally small. Combine them with your own network infrastructure and attachment targets.

Create a public IP with default settings

Most deployments start with a minimal configuration, letting Azure select defaults for allocation method and SKU.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const publicIPAddress = new azure_native.network.PublicIPAddress("publicIPAddress", {
    location: "eastus",
    publicIpAddressName: "test-ip",
    resourceGroupName: "rg1",
});
import pulumi
import pulumi_azure_native as azure_native

public_ip_address = azure_native.network.PublicIPAddress("publicIPAddress",
    location="eastus",
    public_ip_address_name="test-ip",
    resource_group_name="rg1")
package main

import (
	network "github.com/pulumi/pulumi-azure-native-sdk/network/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := network.NewPublicIPAddress(ctx, "publicIPAddress", &network.PublicIPAddressArgs{
			Location:            pulumi.String("eastus"),
			PublicIpAddressName: pulumi.String("test-ip"),
			ResourceGroupName:   pulumi.String("rg1"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var publicIPAddress = new AzureNative.Network.PublicIPAddress("publicIPAddress", new()
    {
        Location = "eastus",
        PublicIpAddressName = "test-ip",
        ResourceGroupName = "rg1",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.network.PublicIPAddress;
import com.pulumi.azurenative.network.PublicIPAddressArgs;
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 publicIPAddress = new PublicIPAddress("publicIPAddress", PublicIPAddressArgs.builder()
            .location("eastus")
            .publicIpAddressName("test-ip")
            .resourceGroupName("rg1")
            .build());

    }
}
resources:
  publicIPAddress:
    type: azure-native:network:PublicIPAddress
    properties:
      location: eastus
      publicIpAddressName: test-ip
      resourceGroupName: rg1

Azure assigns a dynamic IP from the Basic SKU by default. The location property places the IP in a specific region. The publicIpAddressName provides a resource identifier within the resource group.

Assign a DNS label for name resolution

Applications that need stable DNS names register a domain label under Azure’s public DNS zones.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const publicIPAddress = new azure_native.network.PublicIPAddress("publicIPAddress", {
    dnsSettings: {
        domainNameLabel: "dnslbl",
    },
    location: "eastus",
    publicIpAddressName: "test-ip",
    resourceGroupName: "rg1",
});
import pulumi
import pulumi_azure_native as azure_native

public_ip_address = azure_native.network.PublicIPAddress("publicIPAddress",
    dns_settings={
        "domain_name_label": "dnslbl",
    },
    location="eastus",
    public_ip_address_name="test-ip",
    resource_group_name="rg1")
package main

import (
	network "github.com/pulumi/pulumi-azure-native-sdk/network/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := network.NewPublicIPAddress(ctx, "publicIPAddress", &network.PublicIPAddressArgs{
			DnsSettings: &network.PublicIPAddressDnsSettingsArgs{
				DomainNameLabel: pulumi.String("dnslbl"),
			},
			Location:            pulumi.String("eastus"),
			PublicIpAddressName: pulumi.String("test-ip"),
			ResourceGroupName:   pulumi.String("rg1"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var publicIPAddress = new AzureNative.Network.PublicIPAddress("publicIPAddress", new()
    {
        DnsSettings = new AzureNative.Network.Inputs.PublicIPAddressDnsSettingsArgs
        {
            DomainNameLabel = "dnslbl",
        },
        Location = "eastus",
        PublicIpAddressName = "test-ip",
        ResourceGroupName = "rg1",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.network.PublicIPAddress;
import com.pulumi.azurenative.network.PublicIPAddressArgs;
import com.pulumi.azurenative.network.inputs.PublicIPAddressDnsSettingsArgs;
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 publicIPAddress = new PublicIPAddress("publicIPAddress", PublicIPAddressArgs.builder()
            .dnsSettings(PublicIPAddressDnsSettingsArgs.builder()
                .domainNameLabel("dnslbl")
                .build())
            .location("eastus")
            .publicIpAddressName("test-ip")
            .resourceGroupName("rg1")
            .build());

    }
}
resources:
  publicIPAddress:
    type: azure-native:network:PublicIPAddress
    properties:
      dnsSettings:
        domainNameLabel: dnslbl
      location: eastus
      publicIpAddressName: test-ip
      resourceGroupName: rg1

The dnsSettings property creates a DNS record in the format {domainNameLabel}.{region}.cloudapp.azure.com. This provides a human-readable name that resolves to the public IP, even if the IP address changes with dynamic allocation.

Configure static allocation and global tier

Production workloads requiring predictable addresses or cross-region load balancing use static allocation with the Standard SKU.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const publicIPAddress = new azure_native.network.PublicIPAddress("publicIPAddress", {
    idleTimeoutInMinutes: 10,
    location: "eastus",
    publicIPAddressVersion: azure_native.network.IPVersion.IPv4,
    publicIPAllocationMethod: azure_native.network.IPAllocationMethod.Static,
    publicIpAddressName: "test-ip",
    resourceGroupName: "rg1",
    sku: {
        name: azure_native.network.PublicIPAddressSkuName.Standard,
        tier: azure_native.network.PublicIPAddressSkuTier.Global,
    },
});
import pulumi
import pulumi_azure_native as azure_native

public_ip_address = azure_native.network.PublicIPAddress("publicIPAddress",
    idle_timeout_in_minutes=10,
    location="eastus",
    public_ip_address_version=azure_native.network.IPVersion.I_PV4,
    public_ip_allocation_method=azure_native.network.IPAllocationMethod.STATIC,
    public_ip_address_name="test-ip",
    resource_group_name="rg1",
    sku={
        "name": azure_native.network.PublicIPAddressSkuName.STANDARD,
        "tier": azure_native.network.PublicIPAddressSkuTier.GLOBAL_,
    })
package main

import (
	network "github.com/pulumi/pulumi-azure-native-sdk/network/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := network.NewPublicIPAddress(ctx, "publicIPAddress", &network.PublicIPAddressArgs{
			IdleTimeoutInMinutes:     pulumi.Int(10),
			Location:                 pulumi.String("eastus"),
			PublicIPAddressVersion:   pulumi.String(network.IPVersionIPv4),
			PublicIPAllocationMethod: pulumi.String(network.IPAllocationMethodStatic),
			PublicIpAddressName:      pulumi.String("test-ip"),
			ResourceGroupName:        pulumi.String("rg1"),
			Sku: &network.PublicIPAddressSkuArgs{
				Name: pulumi.String(network.PublicIPAddressSkuNameStandard),
				Tier: pulumi.String(network.PublicIPAddressSkuTierGlobal),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var publicIPAddress = new AzureNative.Network.PublicIPAddress("publicIPAddress", new()
    {
        IdleTimeoutInMinutes = 10,
        Location = "eastus",
        PublicIPAddressVersion = AzureNative.Network.IPVersion.IPv4,
        PublicIPAllocationMethod = AzureNative.Network.IPAllocationMethod.Static,
        PublicIpAddressName = "test-ip",
        ResourceGroupName = "rg1",
        Sku = new AzureNative.Network.Inputs.PublicIPAddressSkuArgs
        {
            Name = AzureNative.Network.PublicIPAddressSkuName.Standard,
            Tier = AzureNative.Network.PublicIPAddressSkuTier.Global,
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.network.PublicIPAddress;
import com.pulumi.azurenative.network.PublicIPAddressArgs;
import com.pulumi.azurenative.network.inputs.PublicIPAddressSkuArgs;
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 publicIPAddress = new PublicIPAddress("publicIPAddress", PublicIPAddressArgs.builder()
            .idleTimeoutInMinutes(10)
            .location("eastus")
            .publicIPAddressVersion("IPv4")
            .publicIPAllocationMethod("Static")
            .publicIpAddressName("test-ip")
            .resourceGroupName("rg1")
            .sku(PublicIPAddressSkuArgs.builder()
                .name("Standard")
                .tier("Global")
                .build())
            .build());

    }
}
resources:
  publicIPAddress:
    type: azure-native:network:PublicIPAddress
    properties:
      idleTimeoutInMinutes: 10
      location: eastus
      publicIPAddressVersion: IPv4
      publicIPAllocationMethod: Static
      publicIpAddressName: test-ip
      resourceGroupName: rg1
      sku:
        name: Standard
        tier: Global

The publicIPAllocationMethod set to Static reserves a fixed IP address that persists across resource lifecycle changes. The sku property with Standard tier and Global tier enables cross-region load balancing scenarios. The idleTimeoutInMinutes controls how long idle TCP connections remain open before timing out.

Beyond these examples

These snippets focus on specific public IP features: DNS label assignment, allocation methods and SKU tiers, and IP version selection. They’re intentionally minimal rather than full network deployments.

The examples reference pre-existing infrastructure such as Azure resource groups. They focus on configuring the public IP rather than provisioning the surrounding network topology.

To keep things focused, common public IP patterns are omitted, including:

  • DDoS protection policies (ddosSettings)
  • IP tags for categorization (ipTags)
  • Availability zones (zones)
  • NAT gateway association (natGateway)
  • Public IP prefix allocation (publicIPPrefix)

These omissions are intentional: the goal is to illustrate how each public IP feature is wired, not provide drop-in networking modules. See the PublicIPAddress resource reference for all available configuration options.

Let's create Azure Public IP Addresses

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Configuration & Immutability
What's the minimum configuration needed to create a public IP address?
You need three properties: location, publicIpAddressName, and resourceGroupName.
What properties can't I change after creation?
The following properties are immutable: location, publicIpAddressName, resourceGroupName, publicIPAddressVersion, publicIPPrefix, and sku. Changing any of these requires recreating the resource.
What happens to my public IP when I delete the associated VM?
Use the deleteOption property to specify the behavior when the VM using the public IP is deleted.
DNS & Naming
How do I configure DNS for my public IP address?
Set dnsSettings with a domainNameLabel to create a DNS record that resolves to your public IP.
What is domainNameLabelScope and when should I use it?
domainNameLabelScope controls DNS label reuse scope. Set it to TenantReuse to allow the same domain label to be reused across your tenant.
Allocation & SKU
How do I create a static public IP address?
Set publicIPAllocationMethod to Static and use a Standard SKU. Static IPs are required for Standard SKU resources.
What SKU tiers are available for public IP addresses?
The sku property supports different tiers. For example, you can use Standard SKU with Global tier for cross-region scenarios.
Advanced Features
What does idleTimeoutInMinutes control?
idleTimeoutInMinutes sets the idle timeout for the public IP address. The example shows a value of 10 minutes.
API Versions
How do I use a different Azure API version for this resource?
Generate a local SDK package using the CLI command pulumi package add azure-native network [ApiVersion]. The current default is 2024-05-01.

Using a different cloud?

Explore networking guides for other cloud providers: