Configure GCP Developer Connect Account Connectors

The gcp:developerconnect/accountConnector:AccountConnector resource, part of the Pulumi GCP provider, establishes OAuth-based connections between Google Cloud and external Git providers (GitHub, GitLab). This guide focuses on two capabilities: GitHub OAuth configuration and GitLab OAuth configuration.

Account connectors require a GCP project with the Developer Connect API enabled and a GitHub or GitLab account for OAuth authorization. The examples are intentionally small. Combine them with your own service integrations and repository access patterns.

Connect to GitHub repositories with OAuth

Teams building CI/CD pipelines or developer workflows often need to connect Google Cloud services to GitHub repositories. Developer Connect uses OAuth to establish authenticated connections.

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

const my_account_connector = new gcp.developerconnect.AccountConnector("my-account-connector", {
    location: "us-central1",
    accountConnectorId: "tf-test-ac",
    providerOauthConfig: {
        systemProviderId: "GITHUB",
        scopes: ["repo"],
    },
});
import pulumi
import pulumi_gcp as gcp

my_account_connector = gcp.developerconnect.AccountConnector("my-account-connector",
    location="us-central1",
    account_connector_id="tf-test-ac",
    provider_oauth_config={
        "system_provider_id": "GITHUB",
        "scopes": ["repo"],
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := developerconnect.NewAccountConnector(ctx, "my-account-connector", &developerconnect.AccountConnectorArgs{
			Location:           pulumi.String("us-central1"),
			AccountConnectorId: pulumi.String("tf-test-ac"),
			ProviderOauthConfig: &developerconnect.AccountConnectorProviderOauthConfigArgs{
				SystemProviderId: pulumi.String("GITHUB"),
				Scopes: pulumi.StringArray{
					pulumi.String("repo"),
				},
			},
		})
		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 my_account_connector = new Gcp.DeveloperConnect.AccountConnector("my-account-connector", new()
    {
        Location = "us-central1",
        AccountConnectorId = "tf-test-ac",
        ProviderOauthConfig = new Gcp.DeveloperConnect.Inputs.AccountConnectorProviderOauthConfigArgs
        {
            SystemProviderId = "GITHUB",
            Scopes = new[]
            {
                "repo",
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.developerconnect.AccountConnector;
import com.pulumi.gcp.developerconnect.AccountConnectorArgs;
import com.pulumi.gcp.developerconnect.inputs.AccountConnectorProviderOauthConfigArgs;
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 my_account_connector = new AccountConnector("my-account-connector", AccountConnectorArgs.builder()
            .location("us-central1")
            .accountConnectorId("tf-test-ac")
            .providerOauthConfig(AccountConnectorProviderOauthConfigArgs.builder()
                .systemProviderId("GITHUB")
                .scopes("repo")
                .build())
            .build());

    }
}
resources:
  my-account-connector:
    type: gcp:developerconnect:AccountConnector
    properties:
      location: us-central1
      accountConnectorId: tf-test-ac
      providerOauthConfig:
        systemProviderId: GITHUB
        scopes:
          - repo

After creating the connector, you complete the OAuth flow by visiting the URL in the oauthStartUri output property. The providerOauthConfig block specifies GitHub as the systemProviderId and requests the “repo” scope for repository access. The location and accountConnectorId properties define where the connector lives and its unique identifier within that region.

Connect to GitLab repositories with OAuth

GitLab users need similar OAuth-based connections to integrate their repositories with Google Cloud services. The configuration mirrors GitHub but uses GitLab’s OAuth provider and scope model.

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

const my_account_connector = new gcp.developerconnect.AccountConnector("my-account-connector", {
    location: "us-central1",
    accountConnectorId: "tf-test-ac",
    providerOauthConfig: {
        systemProviderId: "GITLAB",
        scopes: ["api"],
    },
});
import pulumi
import pulumi_gcp as gcp

my_account_connector = gcp.developerconnect.AccountConnector("my-account-connector",
    location="us-central1",
    account_connector_id="tf-test-ac",
    provider_oauth_config={
        "system_provider_id": "GITLAB",
        "scopes": ["api"],
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := developerconnect.NewAccountConnector(ctx, "my-account-connector", &developerconnect.AccountConnectorArgs{
			Location:           pulumi.String("us-central1"),
			AccountConnectorId: pulumi.String("tf-test-ac"),
			ProviderOauthConfig: &developerconnect.AccountConnectorProviderOauthConfigArgs{
				SystemProviderId: pulumi.String("GITLAB"),
				Scopes: pulumi.StringArray{
					pulumi.String("api"),
				},
			},
		})
		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 my_account_connector = new Gcp.DeveloperConnect.AccountConnector("my-account-connector", new()
    {
        Location = "us-central1",
        AccountConnectorId = "tf-test-ac",
        ProviderOauthConfig = new Gcp.DeveloperConnect.Inputs.AccountConnectorProviderOauthConfigArgs
        {
            SystemProviderId = "GITLAB",
            Scopes = new[]
            {
                "api",
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.developerconnect.AccountConnector;
import com.pulumi.gcp.developerconnect.AccountConnectorArgs;
import com.pulumi.gcp.developerconnect.inputs.AccountConnectorProviderOauthConfigArgs;
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 my_account_connector = new AccountConnector("my-account-connector", AccountConnectorArgs.builder()
            .location("us-central1")
            .accountConnectorId("tf-test-ac")
            .providerOauthConfig(AccountConnectorProviderOauthConfigArgs.builder()
                .systemProviderId("GITLAB")
                .scopes("api")
                .build())
            .build());

    }
}
resources:
  my-account-connector:
    type: gcp:developerconnect:AccountConnector
    properties:
      location: us-central1
      accountConnectorId: tf-test-ac
      providerOauthConfig:
        systemProviderId: GITLAB
        scopes:
          - api

This configuration uses “GITLAB” as the systemProviderId and requests the “api” scope, which provides broader API access than GitHub’s “repo” scope. The OAuth flow completion process is identical: visit the oauthStartUri after creation to authorize the connection.

Beyond these examples

These snippets focus on specific account connector features: OAuth provider configuration and GitHub and GitLab integration. They’re intentionally minimal rather than full developer workflow solutions.

The examples assume pre-existing infrastructure such as a GCP project with Developer Connect API enabled and a GitHub or GitLab account with repository access. They focus on configuring the OAuth connection rather than provisioning the surrounding services.

To keep things focused, common connector patterns are omitted, including:

  • Annotations and labels for metadata
  • Multi-region deployment strategies
  • OAuth token refresh and lifecycle management
  • Integration with specific Google Cloud services (Cloud Build, etc.)

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

Let's configure GCP Developer Connect Account Connectors

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Configuration & Setup
What properties can't I change after creating an AccountConnector?
The accountConnectorId, location, and project properties are immutable and cannot be changed after creation. Modifying these requires recreating the resource.
What are the naming requirements for accountConnectorId?
The accountConnectorId must be unique per-project per-location and follow the format specified in https://google.aip.dev/122#resource-id-segments.
How do I configure OAuth for GitHub vs GitLab?
In providerOauthConfig, set systemProviderId to GITHUB with scopes: ["repo"] for GitHub, or GITLAB with scopes: ["api"] for GitLab.
OAuth & Authentication
How do I start the OAuth flow for my AccountConnector?
Use the oauthStartUri output property, which provides the URL to initiate OAuth authentication with your provider.
Labels & Annotations
Why aren't all my annotations and labels showing up in my configuration?
The annotations and labels fields are non-authoritative and only manage values in your configuration. Annotations or labels added outside Pulumi won’t appear in these fields.
What's the difference between labels/annotations and their effective* counterparts?
Use effectiveLabels and effectiveAnnotations to see all labels and annotations on the resource, including those configured through Pulumi, other clients, and GCP services. The non-effective fields only show what’s in your configuration.

Using a different cloud?

Explore integration guides for other cloud providers: