The gcp:apphub/application:Application resource, part of the Pulumi GCP provider, defines an App Hub application that groups services and workloads by business function. This guide focuses on two capabilities: regional and global scope configuration, and metadata and ownership tracking.
Applications require a GCP project with the App Hub API enabled. Services and workloads are attached separately after the application is created. The examples are intentionally small. Combine them with your own service discovery and workload registration.
Create a regional application with minimal configuration
Most deployments start by creating a regional application that groups services within a specific GCP region.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const example = new gcp.apphub.Application("example", {
location: "us-east1",
applicationId: "example-application",
scope: {
type: "REGIONAL",
},
});
import pulumi
import pulumi_gcp as gcp
example = gcp.apphub.Application("example",
location="us-east1",
application_id="example-application",
scope={
"type": "REGIONAL",
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/apphub"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := apphub.NewApplication(ctx, "example", &apphub.ApplicationArgs{
Location: pulumi.String("us-east1"),
ApplicationId: pulumi.String("example-application"),
Scope: &apphub.ApplicationScopeArgs{
Type: pulumi.String("REGIONAL"),
},
})
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 example = new Gcp.Apphub.Application("example", new()
{
Location = "us-east1",
ApplicationId = "example-application",
Scope = new Gcp.Apphub.Inputs.ApplicationScopeArgs
{
Type = "REGIONAL",
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.apphub.Application;
import com.pulumi.gcp.apphub.ApplicationArgs;
import com.pulumi.gcp.apphub.inputs.ApplicationScopeArgs;
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 Application("example", ApplicationArgs.builder()
.location("us-east1")
.applicationId("example-application")
.scope(ApplicationScopeArgs.builder()
.type("REGIONAL")
.build())
.build());
}
}
resources:
example:
type: gcp:apphub:Application
properties:
location: us-east1
applicationId: example-application
scope:
type: REGIONAL
The applicationId provides a unique identifier within the project and location. The scope property with type REGIONAL confines the application to us-east1, making it suitable for region-specific service groupings.
Create a global application spanning multiple regions
Applications that span multiple regions use the GLOBAL scope type to aggregate services across geographic boundaries.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const example = new gcp.apphub.Application("example", {
location: "global",
applicationId: "example-application",
scope: {
type: "GLOBAL",
},
});
import pulumi
import pulumi_gcp as gcp
example = gcp.apphub.Application("example",
location="global",
application_id="example-application",
scope={
"type": "GLOBAL",
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/apphub"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := apphub.NewApplication(ctx, "example", &apphub.ApplicationArgs{
Location: pulumi.String("global"),
ApplicationId: pulumi.String("example-application"),
Scope: &apphub.ApplicationScopeArgs{
Type: pulumi.String("GLOBAL"),
},
})
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 example = new Gcp.Apphub.Application("example", new()
{
Location = "global",
ApplicationId = "example-application",
Scope = new Gcp.Apphub.Inputs.ApplicationScopeArgs
{
Type = "GLOBAL",
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.apphub.Application;
import com.pulumi.gcp.apphub.ApplicationArgs;
import com.pulumi.gcp.apphub.inputs.ApplicationScopeArgs;
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 Application("example", ApplicationArgs.builder()
.location("global")
.applicationId("example-application")
.scope(ApplicationScopeArgs.builder()
.type("GLOBAL")
.build())
.build());
}
}
resources:
example:
type: gcp:apphub:Application
properties:
location: global
applicationId: example-application
scope:
type: GLOBAL
Setting location to “global” and scope.type to GLOBAL allows the application to group services from any region. This configuration suits multi-region architectures where services need unified visibility.
Add metadata and ownership information
Production applications benefit from metadata that identifies environment type, criticality, and ownership contacts.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const example2 = new gcp.apphub.Application("example2", {
location: "us-east1",
applicationId: "example-application",
displayName: "Application Full",
scope: {
type: "REGIONAL",
},
description: "Application for testing",
attributes: {
environment: {
type: "STAGING",
},
criticality: {
type: "MISSION_CRITICAL",
},
businessOwners: [{
displayName: "Alice",
email: "alice@google.com",
}],
developerOwners: [{
displayName: "Bob",
email: "bob@google.com",
}],
operatorOwners: [{
displayName: "Charlie",
email: "charlie@google.com",
}],
},
});
import pulumi
import pulumi_gcp as gcp
example2 = gcp.apphub.Application("example2",
location="us-east1",
application_id="example-application",
display_name="Application Full",
scope={
"type": "REGIONAL",
},
description="Application for testing",
attributes={
"environment": {
"type": "STAGING",
},
"criticality": {
"type": "MISSION_CRITICAL",
},
"business_owners": [{
"display_name": "Alice",
"email": "alice@google.com",
}],
"developer_owners": [{
"display_name": "Bob",
"email": "bob@google.com",
}],
"operator_owners": [{
"display_name": "Charlie",
"email": "charlie@google.com",
}],
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/apphub"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := apphub.NewApplication(ctx, "example2", &apphub.ApplicationArgs{
Location: pulumi.String("us-east1"),
ApplicationId: pulumi.String("example-application"),
DisplayName: pulumi.String("Application Full"),
Scope: &apphub.ApplicationScopeArgs{
Type: pulumi.String("REGIONAL"),
},
Description: pulumi.String("Application for testing"),
Attributes: &apphub.ApplicationAttributesArgs{
Environment: &apphub.ApplicationAttributesEnvironmentArgs{
Type: pulumi.String("STAGING"),
},
Criticality: &apphub.ApplicationAttributesCriticalityArgs{
Type: pulumi.String("MISSION_CRITICAL"),
},
BusinessOwners: apphub.ApplicationAttributesBusinessOwnerArray{
&apphub.ApplicationAttributesBusinessOwnerArgs{
DisplayName: pulumi.String("Alice"),
Email: pulumi.String("alice@google.com"),
},
},
DeveloperOwners: apphub.ApplicationAttributesDeveloperOwnerArray{
&apphub.ApplicationAttributesDeveloperOwnerArgs{
DisplayName: pulumi.String("Bob"),
Email: pulumi.String("bob@google.com"),
},
},
OperatorOwners: apphub.ApplicationAttributesOperatorOwnerArray{
&apphub.ApplicationAttributesOperatorOwnerArgs{
DisplayName: pulumi.String("Charlie"),
Email: pulumi.String("charlie@google.com"),
},
},
},
})
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 example2 = new Gcp.Apphub.Application("example2", new()
{
Location = "us-east1",
ApplicationId = "example-application",
DisplayName = "Application Full",
Scope = new Gcp.Apphub.Inputs.ApplicationScopeArgs
{
Type = "REGIONAL",
},
Description = "Application for testing",
Attributes = new Gcp.Apphub.Inputs.ApplicationAttributesArgs
{
Environment = new Gcp.Apphub.Inputs.ApplicationAttributesEnvironmentArgs
{
Type = "STAGING",
},
Criticality = new Gcp.Apphub.Inputs.ApplicationAttributesCriticalityArgs
{
Type = "MISSION_CRITICAL",
},
BusinessOwners = new[]
{
new Gcp.Apphub.Inputs.ApplicationAttributesBusinessOwnerArgs
{
DisplayName = "Alice",
Email = "alice@google.com",
},
},
DeveloperOwners = new[]
{
new Gcp.Apphub.Inputs.ApplicationAttributesDeveloperOwnerArgs
{
DisplayName = "Bob",
Email = "bob@google.com",
},
},
OperatorOwners = new[]
{
new Gcp.Apphub.Inputs.ApplicationAttributesOperatorOwnerArgs
{
DisplayName = "Charlie",
Email = "charlie@google.com",
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.apphub.Application;
import com.pulumi.gcp.apphub.ApplicationArgs;
import com.pulumi.gcp.apphub.inputs.ApplicationScopeArgs;
import com.pulumi.gcp.apphub.inputs.ApplicationAttributesArgs;
import com.pulumi.gcp.apphub.inputs.ApplicationAttributesEnvironmentArgs;
import com.pulumi.gcp.apphub.inputs.ApplicationAttributesCriticalityArgs;
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 example2 = new Application("example2", ApplicationArgs.builder()
.location("us-east1")
.applicationId("example-application")
.displayName("Application Full")
.scope(ApplicationScopeArgs.builder()
.type("REGIONAL")
.build())
.description("Application for testing")
.attributes(ApplicationAttributesArgs.builder()
.environment(ApplicationAttributesEnvironmentArgs.builder()
.type("STAGING")
.build())
.criticality(ApplicationAttributesCriticalityArgs.builder()
.type("MISSION_CRITICAL")
.build())
.businessOwners(ApplicationAttributesBusinessOwnerArgs.builder()
.displayName("Alice")
.email("alice@google.com")
.build())
.developerOwners(ApplicationAttributesDeveloperOwnerArgs.builder()
.displayName("Bob")
.email("bob@google.com")
.build())
.operatorOwners(ApplicationAttributesOperatorOwnerArgs.builder()
.displayName("Charlie")
.email("charlie@google.com")
.build())
.build())
.build());
}
}
resources:
example2:
type: gcp:apphub:Application
properties:
location: us-east1
applicationId: example-application
displayName: Application Full
scope:
type: REGIONAL
description: Application for testing
attributes:
environment:
type: STAGING
criticality:
type: MISSION_CRITICAL
businessOwners:
- displayName: Alice
email: alice@google.com
developerOwners:
- displayName: Bob
email: bob@google.com
operatorOwners:
- displayName: Charlie
email: charlie@google.com
The attributes property adds operational context. The environment.type field marks this as STAGING, while criticality.type indicates MISSION_CRITICAL priority. The businessOwners, developerOwners, and operatorOwners arrays establish clear ownership with display names and email contacts for incident response and change management.
Beyond these examples
These snippets focus on specific application-level features: regional and global scope configuration, and metadata and ownership tracking. They’re intentionally minimal rather than full service catalogs.
The examples assume pre-existing infrastructure such as a GCP project with App Hub API enabled. They focus on configuring the application rather than attaching services or workloads.
To keep things focused, common application patterns are omitted, including:
- Service and workload attachment (managed separately)
- Custom attribute schemas beyond standard fields
- Application lifecycle management (state transitions)
These omissions are intentional: the goal is to illustrate how each application feature is wired, not provide drop-in service catalog modules. See the App Hub Application resource reference for all available configuration options.
Let's create GCP App Hub Applications
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Configuration & Scope
us-east1 with scope.type set to REGIONAL. GLOBAL applications use location set to global with scope.type set to GLOBAL.attributes property to set environment.type (e.g., STAGING) and criticality.type (e.g., MISSION_CRITICAL).Immutability & Lifecycle
applicationId, location, and project properties are immutable and require resource replacement if changed.Attributes & Metadata
businessOwners, developerOwners, and operatorOwners, each with a displayName and email.Using a different cloud?
Explore integration guides for other cloud providers: