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 that can be referenced in firewall policies and Cloud Armor rules. This guide focuses on two capabilities: project and organization scoping, and Cloud Armor integration.

Address groups reference existing GCP projects or organizations and are consumed by firewall policies or Cloud Armor security policies. The examples are intentionally small. Combine them with your own firewall rules and security policies.

Define an address group for firewall policies

Firewall policies often need to reference collections of IP addresses rather than hardcoding individual addresses in each rule.

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 (project or organization). The type property specifies IPv4 or IPv6. The capacity property defines the maximum number of addresses the group can hold; this is immutable after creation. The items array contains the actual IP addresses or CIDR ranges.

Scope an address group to an organization

Organizations managing firewall policies across multiple projects can define address groups at the organization level for centralized IP management.

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

Setting parent to an organization ID (format: organizations/{organization_id}) makes the address group available across all projects in that organization. This enables centralized management of IP collections used in organization-wide firewall policies.

Configure address groups for Cloud Armor policies

Cloud Armor security policies use address groups to define allow/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 indicates this group is for Cloud Armor security policies. The location must be global for Cloud Armor integration, as Cloud Armor operates at the global edge network level.

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 full security policy configurations.

The examples reference pre-existing infrastructure such as GCP projects or organizations (referenced in parent property). They focus on defining address collections 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 VPC firewall 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

Immutability & Limitations
Can I change the capacity after creating an address group?
No, capacity is immutable and cannot be changed after creation. You must recreate the address group to change capacity.
Can I change the parent after creating an address group?
No, parent is immutable. You must specify the correct parent format (organizations/{organization_id} or projects/{project_id}) at creation time.
Labels & Metadata
What's the difference between labels and effectiveLabels?
The labels field only manages labels defined in your Pulumi configuration and is non-authoritative. Use effectiveLabels to see all labels on the resource, including those set by other clients and services.
Configuration & Scope
How do I create an address group for my organization vs project?
Set parent to organizations/{organization_id} for organization-level groups or projects/{project_id} for project-level groups.
What IP address format should I use in the items array?
Use CIDR notation like 208.80.154.224/32 for individual IPs or 192.168.1.0/24 for ranges.
What are the available address group types and purposes?
Types are IPV4 or IPV6. Purposes are DEFAULT or CLOUD_ARMOR (Beta).
Cloud Armor Integration
What location should I use for Cloud Armor address groups?
Use location: "global" when setting purposes: ["CLOUD_ARMOR"].

Using a different cloud?

Explore security guides for other cloud providers: