Configure AWS CodeBuild Webhooks

The aws:codebuild/webhook:Webhook resource, part of the Pulumi AWS provider, creates webhook endpoints that trigger CodeBuild projects from source repository events. This guide focuses on three capabilities: event filtering for push and pull request events, GitHub Enterprise manual webhook setup, and GitHub Actions runner integration.

Webhooks depend on existing CodeBuild projects with configured source repositories. For GitHub and Bitbucket, the AWS account must have OAuth authorization configured before creating webhooks; CodeBuild automatically manages the repository webhook itself. The examples are intentionally small. Combine them with your own CodeBuild projects and repository configurations.

Trigger builds on push events to specific branches

CI/CD pipelines often build only when code is pushed to specific branches, such as main or master, to avoid unnecessary builds on feature branches.

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

const example = new aws.codebuild.Webhook("example", {
    projectName: exampleAwsCodebuildProject.name,
    buildType: "BUILD",
    filterGroups: [{
        filters: [
            {
                type: "EVENT",
                pattern: "PUSH",
            },
            {
                type: "BASE_REF",
                pattern: "master",
            },
        ],
    }],
});
import pulumi
import pulumi_aws as aws

example = aws.codebuild.Webhook("example",
    project_name=example_aws_codebuild_project["name"],
    build_type="BUILD",
    filter_groups=[{
        "filters": [
            {
                "type": "EVENT",
                "pattern": "PUSH",
            },
            {
                "type": "BASE_REF",
                "pattern": "master",
            },
        ],
    }])
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/codebuild"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := codebuild.NewWebhook(ctx, "example", &codebuild.WebhookArgs{
			ProjectName: pulumi.Any(exampleAwsCodebuildProject.Name),
			BuildType:   pulumi.String("BUILD"),
			FilterGroups: codebuild.WebhookFilterGroupArray{
				&codebuild.WebhookFilterGroupArgs{
					Filters: codebuild.WebhookFilterGroupFilterArray{
						&codebuild.WebhookFilterGroupFilterArgs{
							Type:    pulumi.String("EVENT"),
							Pattern: pulumi.String("PUSH"),
						},
						&codebuild.WebhookFilterGroupFilterArgs{
							Type:    pulumi.String("BASE_REF"),
							Pattern: pulumi.String("master"),
						},
					},
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.CodeBuild.Webhook("example", new()
    {
        ProjectName = exampleAwsCodebuildProject.Name,
        BuildType = "BUILD",
        FilterGroups = new[]
        {
            new Aws.CodeBuild.Inputs.WebhookFilterGroupArgs
            {
                Filters = new[]
                {
                    new Aws.CodeBuild.Inputs.WebhookFilterGroupFilterArgs
                    {
                        Type = "EVENT",
                        Pattern = "PUSH",
                    },
                    new Aws.CodeBuild.Inputs.WebhookFilterGroupFilterArgs
                    {
                        Type = "BASE_REF",
                        Pattern = "master",
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.codebuild.Webhook;
import com.pulumi.aws.codebuild.WebhookArgs;
import com.pulumi.aws.codebuild.inputs.WebhookFilterGroupArgs;
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 Webhook("example", WebhookArgs.builder()
            .projectName(exampleAwsCodebuildProject.name())
            .buildType("BUILD")
            .filterGroups(WebhookFilterGroupArgs.builder()
                .filters(                
                    WebhookFilterGroupFilterArgs.builder()
                        .type("EVENT")
                        .pattern("PUSH")
                        .build(),
                    WebhookFilterGroupFilterArgs.builder()
                        .type("BASE_REF")
                        .pattern("master")
                        .build())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:codebuild:Webhook
    properties:
      projectName: ${exampleAwsCodebuildProject.name}
      buildType: BUILD
      filterGroups:
        - filters:
            - type: EVENT
              pattern: PUSH
            - type: BASE_REF
              pattern: master

When a push event occurs, CodeBuild evaluates the filterGroups to determine whether to trigger a build. Each filter group contains an array of filters that must all match for the build to start. The EVENT filter matches the repository event type (PUSH, PULL_REQUEST_CREATED, etc.), while BASE_REF matches the branch name using a regular expression pattern. Here, builds trigger only on pushes to the master branch.

Connect GitHub Enterprise with manual webhook creation

GitHub Enterprise deployments require manual webhook management because CodeBuild cannot automatically create webhooks in self-hosted GitHub instances.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
import * as github from "@pulumi/github";

const example = new aws.codebuild.Webhook("example", {projectName: exampleAwsCodebuildProject.name});
const exampleRepositoryWebhook = new github.RepositoryWebhook("example", {
    active: true,
    events: ["push"],
    name: "example",
    repository: exampleGithubRepository.name,
    configuration: [{
        url: example.payloadUrl,
        secret: example.secret,
        contentType: "json",
        insecureSsl: false,
    }],
});
import pulumi
import pulumi_aws as aws
import pulumi_github as github

example = aws.codebuild.Webhook("example", project_name=example_aws_codebuild_project["name"])
example_repository_webhook = github.RepositoryWebhook("example",
    active=True,
    events=["push"],
    name="example",
    repository=example_github_repository["name"],
    configuration=[{
        "url": example.payload_url,
        "secret": example.secret,
        "contentType": "json",
        "insecureSsl": False,
    }])
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/codebuild"
	"github.com/pulumi/pulumi-github/sdk/v6/go/github"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		example, err := codebuild.NewWebhook(ctx, "example", &codebuild.WebhookArgs{
			ProjectName: pulumi.Any(exampleAwsCodebuildProject.Name),
		})
		if err != nil {
			return err
		}
		_, err = github.NewRepositoryWebhook(ctx, "example", &github.RepositoryWebhookArgs{
			Active: pulumi.Bool(true),
			Events: pulumi.StringArray{
				pulumi.String("push"),
			},
			Name:       "example",
			Repository: pulumi.Any(exampleGithubRepository.Name),
			Configuration: github.RepositoryWebhookConfigurationArgs{
				map[string]interface{}{
					"url":         example.PayloadUrl,
					"secret":      example.Secret,
					"contentType": "json",
					"insecureSsl": false,
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
using Github = Pulumi.Github;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.CodeBuild.Webhook("example", new()
    {
        ProjectName = exampleAwsCodebuildProject.Name,
    });

    var exampleRepositoryWebhook = new Github.RepositoryWebhook("example", new()
    {
        Active = true,
        Events = new[]
        {
            "push",
        },
        Name = "example",
        Repository = exampleGithubRepository.Name,
        Configuration = new[]
        {
            
            {
                { "url", example.PayloadUrl },
                { "secret", example.Secret },
                { "contentType", "json" },
                { "insecureSsl", false },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.codebuild.Webhook;
import com.pulumi.aws.codebuild.WebhookArgs;
import com.pulumi.github.RepositoryWebhook;
import com.pulumi.github.RepositoryWebhookArgs;
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 Webhook("example", WebhookArgs.builder()
            .projectName(exampleAwsCodebuildProject.name())
            .build());

        var exampleRepositoryWebhook = new RepositoryWebhook("exampleRepositoryWebhook", RepositoryWebhookArgs.builder()
            .active(true)
            .events("push")
            .name("example")
            .repository(exampleGithubRepository.name())
            .configuration(RepositoryWebhookConfigurationArgs.builder()
                .url(example.payloadUrl())
                .secret(example.secret())
                .contentType("json")
                .insecureSsl(false)
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:codebuild:Webhook
    properties:
      projectName: ${exampleAwsCodebuildProject.name}
  exampleRepositoryWebhook:
    type: github:RepositoryWebhook
    name: example
    properties:
      active: true
      events:
        - push
      name: example
      repository: ${exampleGithubRepository.name}
      configuration:
        - url: ${example.payloadUrl}
          secret: ${example.secret}
          contentType: json
          insecureSsl: false

For GitHub Enterprise, CodeBuild returns payloadUrl and secret values instead of creating the webhook automatically. You use these values to configure a webhook in your GitHub Enterprise repository, either manually or with the github.RepositoryWebhook resource. The payloadUrl is the CodeBuild endpoint that receives webhook events, and the secret authenticates incoming requests.

Configure CodeBuild as a GitHub Actions runner

Teams can use CodeBuild as a compute backend for GitHub Actions workflows, allowing builds to run on AWS infrastructure with custom configurations.

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

const example = new aws.codebuild.Webhook("example", {
    projectName: exampleAwsCodebuildProject.name,
    buildType: "BUILD",
    filterGroups: [{
        filters: [{
            type: "EVENT",
            pattern: "WORKFLOW_JOB_QUEUED",
        }],
    }],
});
import pulumi
import pulumi_aws as aws

example = aws.codebuild.Webhook("example",
    project_name=example_aws_codebuild_project["name"],
    build_type="BUILD",
    filter_groups=[{
        "filters": [{
            "type": "EVENT",
            "pattern": "WORKFLOW_JOB_QUEUED",
        }],
    }])
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/codebuild"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := codebuild.NewWebhook(ctx, "example", &codebuild.WebhookArgs{
			ProjectName: pulumi.Any(exampleAwsCodebuildProject.Name),
			BuildType:   pulumi.String("BUILD"),
			FilterGroups: codebuild.WebhookFilterGroupArray{
				&codebuild.WebhookFilterGroupArgs{
					Filters: codebuild.WebhookFilterGroupFilterArray{
						&codebuild.WebhookFilterGroupFilterArgs{
							Type:    pulumi.String("EVENT"),
							Pattern: pulumi.String("WORKFLOW_JOB_QUEUED"),
						},
					},
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.CodeBuild.Webhook("example", new()
    {
        ProjectName = exampleAwsCodebuildProject.Name,
        BuildType = "BUILD",
        FilterGroups = new[]
        {
            new Aws.CodeBuild.Inputs.WebhookFilterGroupArgs
            {
                Filters = new[]
                {
                    new Aws.CodeBuild.Inputs.WebhookFilterGroupFilterArgs
                    {
                        Type = "EVENT",
                        Pattern = "WORKFLOW_JOB_QUEUED",
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.codebuild.Webhook;
import com.pulumi.aws.codebuild.WebhookArgs;
import com.pulumi.aws.codebuild.inputs.WebhookFilterGroupArgs;
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 Webhook("example", WebhookArgs.builder()
            .projectName(exampleAwsCodebuildProject.name())
            .buildType("BUILD")
            .filterGroups(WebhookFilterGroupArgs.builder()
                .filters(WebhookFilterGroupFilterArgs.builder()
                    .type("EVENT")
                    .pattern("WORKFLOW_JOB_QUEUED")
                    .build())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:codebuild:Webhook
    properties:
      projectName: ${exampleAwsCodebuildProject.name}
      buildType: BUILD
      filterGroups:
        - filters:
            - type: EVENT
              pattern: WORKFLOW_JOB_QUEUED

CodeBuild Runner Projects listen for WORKFLOW_JOB_QUEUED events from GitHub Actions. When a workflow job is queued, GitHub sends a webhook event to CodeBuild, which starts a build to execute the job. The buildType property must be set to BUILD for runner projects. This configuration allows you to run GitHub Actions workflows on CodeBuild’s compute environment with custom instance types, VPC access, or other AWS-specific features.

Beyond these examples

These snippets focus on specific webhook-level features: event filtering and branch targeting, GitHub Enterprise integration, and GitHub Actions runner configuration. They’re intentionally minimal rather than full CI/CD pipelines.

The examples reference pre-existing infrastructure such as CodeBuild projects with source repositories configured, OAuth authorization for GitHub/Bitbucket (for automatic webhook creation), and GitHub provider configuration (for GitHub Enterprise). They focus on configuring the webhook rather than provisioning the entire build infrastructure.

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

  • Pull request approval policies (pullRequestBuildPolicy)
  • Organization-wide webhook scopes (scopeConfiguration)
  • Branch filtering with branchFilter (deprecated in favor of filterGroups)
  • Batch build triggers (BUILD_BATCH buildType)

These omissions are intentional: the goal is to illustrate how each webhook feature is wired, not provide drop-in CI/CD modules. See the CodeBuild Webhook resource reference for all available configuration options.

Let's configure AWS CodeBuild Webhooks

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

OAuth & Authorization
Why am I getting 'ResourceNotFoundException: Could not find access token for server type github'?
This error occurs when CodeBuild hasn’t been authorized to access your GitHub or Bitbucket OAuth API. You must manually authorize CodeBuild in each applicable region before creating webhooks.
What setup is required before creating a webhook for GitHub or Bitbucket?
You must manually authorize CodeBuild to access the OAuth API for GitHub or Bitbucket in each region where you’ll create webhooks. This is a one-time setup step per region.
Webhook Management
Does CodeBuild automatically create the webhook in my GitHub or Bitbucket repository?
Yes, for GitHub and Bitbucket sources, CodeBuild automatically creates the repository webhook when you create the aws.codebuild.Webhook resource and deletes it when you destroy the resource. This behavior cannot be controlled.
How do I manage webhooks for GitHub Enterprise?
GitHub Enterprise webhooks must be separately managed. Create the aws.codebuild.Webhook resource, then use the payloadUrl and secret outputs to manually create a webhook or use the github_repository_webhook resource.
Why isn't the secret attribute available for my Bitbucket or GitHub webhook?
The CodeBuild API doesn’t return the secret attribute for automatically created Bitbucket/GitHub webhooks. To access the secret, either use manualCreation mode or import the webhook resource after creation.
How do I manually create a webhook instead of letting CodeBuild do it automatically?
Set manualCreation to true. CodeBuild will return payloadUrl and secret values that you can use to manually create the webhook in your repository.
Configuration & Filtering
Should I use branchFilter or filterGroups to control which branches trigger builds?
Use filterGroups instead of branchFilter. The schema explicitly recommends filterGroups over branchFilter for filtering webhook triggers.
How do I create a webhook for a CodeBuild Runner Project?
Set buildType to BUILD and configure filterGroups with a filter of type EVENT and pattern WORKFLOW_JOB_QUEUED.
Immutability & Limitations
What properties can't be changed after creating the webhook?
Both projectName and manualCreation are immutable. Changing either requires recreating the webhook resource.
What are the valid values for buildType?
The buildType parameter accepts two values: BUILD for single builds or BUILD_BATCH for batch builds.

Using a different cloud?

Explore integration guides for other cloud providers: