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, with automatic webhook management for GitHub and Bitbucket. This guide focuses on three capabilities: event and branch filtering, GitHub Enterprise manual setup, and GitHub Actions runner configuration.

CodeBuild webhooks depend on existing projects with configured source repositories and OAuth authorization between AWS and GitHub or Bitbucket. For GitHub and Bitbucket, CodeBuild automatically creates and deletes repository webhooks; for GitHub Enterprise, you must create webhooks manually. The examples are intentionally small. Combine them with your own CodeBuild projects and repository configuration.

Trigger builds on push events to specific branches

CI/CD pipelines often build only when code is pushed to specific branches, avoiding unnecessary builds on every feature branch.

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

The filterGroups property defines conditions that must all be met for the webhook to trigger a build. Each filter specifies a type (EVENT, BASE_REF, etc.) and a pattern to match. Here, builds trigger only on PUSH events to the master branch. The buildType property controls whether the webhook triggers individual builds or batch builds.

Connect GitHub Enterprise with manual webhook creation

GitHub Enterprise deployments require manual webhook configuration because CodeBuild cannot automatically create webhooks in self-hosted 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

When manualCreation is true (implicit for GitHub Enterprise sources), CodeBuild returns payloadUrl and secret values instead of creating the webhook automatically. You pass these values to the GitHub provider’s RepositoryWebhook resource to complete the connection. This two-step process gives you control over webhook configuration in self-hosted GitHub instances.

Configure CodeBuild as a GitHub Actions runner

Teams can use CodeBuild as a compute backend for GitHub Actions workflows, triggering builds when jobs are queued.

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

The WORKFLOW_JOB_QUEUED event type enables CodeBuild Runner Projects, which execute GitHub Actions workflows. When GitHub Actions queues a job, it sends a webhook event to CodeBuild, which starts a build to process the workflow. This pattern offloads compute from GitHub-hosted runners to your AWS account.

Beyond these examples

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

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

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

Authentication & Authorization
Why am I getting 'ResourceNotFoundException: Could not find access token for server type github'?
You must manually authorize CodeBuild to access Bitbucket or GitHub’s OAuth API in each region before creating webhooks. This is a one-time setup step per region that must be completed before using this resource.
Webhook Management
How does CodeBuild manage webhooks for Bitbucket and GitHub?
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 by Pulumi.
How do I set up a webhook for GitHub Enterprise?
GitHub Enterprise webhooks must be managed separately. Create the aws.codebuild.Webhook resource first, then use its payloadUrl and secret outputs to manually create the webhook or use the github_repository_webhook resource.
When should I use manualCreation?
Set manualCreation to true when you need to manually create the webhook in GitHub instead of having CodeBuild create it automatically. This returns payloadUrl and secret values you can use for manual webhook setup.
Why can't I access the secret for my Bitbucket or GitHub webhook?
The CodeBuild API doesn’t provide the secret attribute for automatically created Bitbucket/GitHub webhooks. To access the secret, either use manualCreation=true or import the webhook resource after creation.
Configuration & Filtering
Should I use branchFilter or filterGroups?
Use filterGroups instead of branchFilter. The schema explicitly recommends filter_group over branch_filter for webhook filtering.
What build types can webhooks trigger?
Webhooks can trigger two build types: BUILD for standard builds and BUILD_BATCH for batch builds.
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.
What properties can't I change after creation?
Both projectName and manualCreation are immutable and cannot be changed after the webhook is created.

Using a different cloud?

Explore integration guides for other cloud providers: