Configure GCP Network Security Address Groups

The gcp:networksecurity/addressGroup:AddressGroup resource, part of the Pulumi GCP provider, defines collections of IP addresses or CIDR ranges for use in firewall policies and Cloud Armor security rules. This guide focuses on two capabilities: project and organization scoping, and Cloud Armor integration.

Address groups belong to projects or organizations and are referenced by firewall policies or Cloud Armor rules. The examples are intentionally small. Combine them with your own firewall policies and security configurations.

Create a project-scoped address group

Most firewall policies start by defining address groups at the project level, collecting IP addresses that represent trusted sources or restricted destinations.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const _default = new gcp.networksecurity.AddressGroup("default", {
    name: "my-address-groups",
    parent: "projects/my-project-name",
    location: "us-central1",
    type: "IPV4",
    capacity: 100,
    items: ["208.80.154.224/32"],
});
import pulumi
import pulumi_gcp as gcp

default = gcp.networksecurity.AddressGroup("default",
    name="my-address-groups",
    parent="projects/my-project-name",
    location="us-central1",
    type="IPV4",
    capacity=100,
    items=["208.80.154.224/32"])
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/networksecurity"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := networksecurity.NewAddressGroup(ctx, "default", &networksecurity.AddressGroupArgs{
			Name:     pulumi.String("my-address-groups"),
			Parent:   pulumi.String("projects/my-project-name"),
			Location: pulumi.String("us-central1"),
			Type:     pulumi.String("IPV4"),
			Capacity: pulumi.Int(100),
			Items: pulumi.StringArray{
				pulumi.String("208.80.154.224/32"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var @default = new Gcp.NetworkSecurity.AddressGroup("default", new()
    {
        Name = "my-address-groups",
        Parent = "projects/my-project-name",
        Location = "us-central1",
        Type = "IPV4",
        Capacity = 100,
        Items = new[]
        {
            "208.80.154.224/32",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.networksecurity.AddressGroup;
import com.pulumi.gcp.networksecurity.AddressGroupArgs;
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 default_ = new AddressGroup("default", AddressGroupArgs.builder()
            .name("my-address-groups")
            .parent("projects/my-project-name")
            .location("us-central1")
            .type("IPV4")
            .capacity(100)
            .items("208.80.154.224/32")
            .build());

    }
}
resources:
  default:
    type: gcp:networksecurity:AddressGroup
    properties:
      name: my-address-groups
      parent: projects/my-project-name
      location: us-central1
      type: IPV4
      capacity: '100'
      items:
        - 208.80.154.224/32

The parent property sets the scope to a specific project. The type property specifies IPv4 or IPv6 addresses. The capacity property defines the maximum number of items the group can hold (immutable after creation). The items array contains the actual IP addresses or CIDR ranges.

Scope address groups to an organization

Organizations managing multiple projects often define address groups at the organization level to share common IP lists across projects.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const _default = new gcp.networksecurity.AddressGroup("default", {
    name: "my-address-groups",
    parent: "organizations/123456789",
    location: "us-central1",
    type: "IPV4",
    capacity: 100,
    items: ["208.80.154.224/32"],
});
import pulumi
import pulumi_gcp as gcp

default = gcp.networksecurity.AddressGroup("default",
    name="my-address-groups",
    parent="organizations/123456789",
    location="us-central1",
    type="IPV4",
    capacity=100,
    items=["208.80.154.224/32"])
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/networksecurity"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := networksecurity.NewAddressGroup(ctx, "default", &networksecurity.AddressGroupArgs{
			Name:     pulumi.String("my-address-groups"),
			Parent:   pulumi.String("organizations/123456789"),
			Location: pulumi.String("us-central1"),
			Type:     pulumi.String("IPV4"),
			Capacity: pulumi.Int(100),
			Items: pulumi.StringArray{
				pulumi.String("208.80.154.224/32"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var @default = new Gcp.NetworkSecurity.AddressGroup("default", new()
    {
        Name = "my-address-groups",
        Parent = "organizations/123456789",
        Location = "us-central1",
        Type = "IPV4",
        Capacity = 100,
        Items = new[]
        {
            "208.80.154.224/32",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.networksecurity.AddressGroup;
import com.pulumi.gcp.networksecurity.AddressGroupArgs;
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 default_ = new AddressGroup("default", AddressGroupArgs.builder()
            .name("my-address-groups")
            .parent("organizations/123456789")
            .location("us-central1")
            .type("IPV4")
            .capacity(100)
            .items("208.80.154.224/32")
            .build());

    }
}
resources:
  default:
    type: gcp:networksecurity:AddressGroup
    properties:
      name: my-address-groups
      parent: organizations/123456789
      location: us-central1
      type: IPV4
      capacity: '100'
      items:
        - 208.80.154.224/32

When parent uses the organizations/{organization_id} format instead of projects/{project_id}, the address group becomes available across all projects in the organization. This enables centralized management of IP allow lists or deny lists.

Configure address groups for Cloud Armor

Cloud Armor security policies use address groups to define allow or deny lists for DDoS protection and application-layer filtering.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const _default = new gcp.networksecurity.AddressGroup("default", {
    name: "my-address-groups",
    parent: "projects/my-project-name",
    location: "global",
    type: "IPV4",
    capacity: 100,
    purposes: ["CLOUD_ARMOR"],
    items: ["208.80.154.224/32"],
});
import pulumi
import pulumi_gcp as gcp

default = gcp.networksecurity.AddressGroup("default",
    name="my-address-groups",
    parent="projects/my-project-name",
    location="global",
    type="IPV4",
    capacity=100,
    purposes=["CLOUD_ARMOR"],
    items=["208.80.154.224/32"])
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/networksecurity"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := networksecurity.NewAddressGroup(ctx, "default", &networksecurity.AddressGroupArgs{
			Name:     pulumi.String("my-address-groups"),
			Parent:   pulumi.String("projects/my-project-name"),
			Location: pulumi.String("global"),
			Type:     pulumi.String("IPV4"),
			Capacity: pulumi.Int(100),
			Purposes: pulumi.StringArray{
				pulumi.String("CLOUD_ARMOR"),
			},
			Items: pulumi.StringArray{
				pulumi.String("208.80.154.224/32"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var @default = new Gcp.NetworkSecurity.AddressGroup("default", new()
    {
        Name = "my-address-groups",
        Parent = "projects/my-project-name",
        Location = "global",
        Type = "IPV4",
        Capacity = 100,
        Purposes = new[]
        {
            "CLOUD_ARMOR",
        },
        Items = new[]
        {
            "208.80.154.224/32",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.networksecurity.AddressGroup;
import com.pulumi.gcp.networksecurity.AddressGroupArgs;
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 default_ = new AddressGroup("default", AddressGroupArgs.builder()
            .name("my-address-groups")
            .parent("projects/my-project-name")
            .location("global")
            .type("IPV4")
            .capacity(100)
            .purposes("CLOUD_ARMOR")
            .items("208.80.154.224/32")
            .build());

    }
}
resources:
  default:
    type: gcp:networksecurity:AddressGroup
    properties:
      name: my-address-groups
      parent: projects/my-project-name
      location: global
      type: IPV4
      capacity: '100'
      purposes:
        - CLOUD_ARMOR
      items:
        - 208.80.154.224/32

The purposes property specifies how the address group will be used. Setting it to CLOUD_ARMOR makes the group available to Cloud Armor security policies. The location must be “global” for Cloud Armor integration, rather than a regional location.

Beyond these examples

These snippets focus on specific address group features: project and organization scoping, and Cloud Armor integration. They’re intentionally minimal rather than complete security configurations.

The examples reference pre-existing infrastructure such as GCP projects or organizations with appropriate permissions. They focus on defining address groups rather than the firewall policies or Cloud Armor rules that consume them.

To keep things focused, common address group patterns are omitted, including:

  • Description and label metadata
  • IPv6 address groups (type: IPV6)
  • Dynamic capacity management
  • Integration with firewall policy rules

These omissions are intentional: the goal is to illustrate how address groups are configured, not provide drop-in security modules. See the AddressGroup resource reference for all available configuration options.

Let's configure GCP Network Security Address Groups

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 properties can't I change after creating an address group?
The capacity and parent properties are immutable and cannot be changed after creation. Modifying these requires replacing the resource.
What's the difference between labels and effectiveLabels?
The labels field only manages labels defined in your Pulumi configuration. Use effectiveLabels to see all labels on the resource, including those set by other clients and services.
Scoping & Organization
Can I create address groups at the organization level?
Yes, set parent to organizations/{organization_id} format. Address groups can be scoped to either projects or organizations.
What's the default location for address groups?
The default location is global. For Cloud Armor use cases, you must explicitly set location to global.
IP Addresses & Purposes
What IP address types and formats are supported?
Address groups support IPV4 or IPV6 types. Use CIDR notation for items, such as 208.80.154.224/32.
How do I use address groups with Cloud Armor?
Set location to global and purposes to ["CLOUD_ARMOR"]. Cloud Armor requires global address groups.

Using a different cloud?

Explore security guides for other cloud providers: