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 FREEFrequently Asked Questions
Configuration & Immutability
capacity and parent properties are immutable and cannot be changed after creation. Modifying these requires replacing the resource.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
parent to organizations/{organization_id} format. Address groups can be scoped to either projects or organizations.global. For Cloud Armor use cases, you must explicitly set location to global.IP Addresses & Purposes
IPV4 or IPV6 types. Use CIDR notation for items, such as 208.80.154.224/32.location to global and purposes to ["CLOUD_ARMOR"]. Cloud Armor requires global address groups.