Configure AWS Bedrock Agent Browser

The aws:bedrock/agentcoreBrowser:AgentcoreBrowser resource, part of the Pulumi AWS provider, provisions a Bedrock AgentCore Browser that gives AI agents web browsing capabilities in controlled environments. This guide focuses on three capabilities: public and VPC network modes, session recording to S3, and IAM execution role configuration.

Browsers may reference VPC infrastructure, S3 buckets for recordings, and IAM roles for execution permissions. The examples are intentionally small. Combine them with your own network configuration and storage infrastructure.

Create a browser with public network access

Most browser deployments start with public network access, allowing agents to reach any internet-accessible website.

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

const example = new aws.bedrock.AgentcoreBrowser("example", {
    name: "example-browser",
    description: "Browser for web data extraction",
    networkConfiguration: {
        networkMode: "PUBLIC",
    },
});
import pulumi
import pulumi_aws as aws

example = aws.bedrock.AgentcoreBrowser("example",
    name="example-browser",
    description="Browser for web data extraction",
    network_configuration={
        "network_mode": "PUBLIC",
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := bedrock.NewAgentcoreBrowser(ctx, "example", &bedrock.AgentcoreBrowserArgs{
			Name:        pulumi.String("example-browser"),
			Description: pulumi.String("Browser for web data extraction"),
			NetworkConfiguration: &bedrock.AgentcoreBrowserNetworkConfigurationArgs{
				NetworkMode: pulumi.String("PUBLIC"),
			},
		})
		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.Bedrock.AgentcoreBrowser("example", new()
    {
        Name = "example-browser",
        Description = "Browser for web data extraction",
        NetworkConfiguration = new Aws.Bedrock.Inputs.AgentcoreBrowserNetworkConfigurationArgs
        {
            NetworkMode = "PUBLIC",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.bedrock.AgentcoreBrowser;
import com.pulumi.aws.bedrock.AgentcoreBrowserArgs;
import com.pulumi.aws.bedrock.inputs.AgentcoreBrowserNetworkConfigurationArgs;
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 AgentcoreBrowser("example", AgentcoreBrowserArgs.builder()
            .name("example-browser")
            .description("Browser for web data extraction")
            .networkConfiguration(AgentcoreBrowserNetworkConfigurationArgs.builder()
                .networkMode("PUBLIC")
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:bedrock:AgentcoreBrowser
    properties:
      name: example-browser
      description: Browser for web data extraction
      networkConfiguration:
        networkMode: PUBLIC

The networkConfiguration property controls how the browser accesses the internet. Setting networkMode to “PUBLIC” allows unrestricted access to public websites without VPC routing. The name property provides a human-readable identifier for the browser instance.

Connect to private resources through VPC

Agents that need to access internal web applications or databases behind a firewall require VPC configuration.

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

const vpcExample = new aws.bedrock.AgentcoreBrowser("vpc_example", {
    name: "vpc-browser",
    description: "Browser with VPC configuration",
    networkConfiguration: {
        networkMode: "VPC",
        vpcConfig: {
            securityGroups: ["sg-12345678"],
            subnets: [
                "subnet-12345678",
                "subnet-87654321",
            ],
        },
    },
});
import pulumi
import pulumi_aws as aws

vpc_example = aws.bedrock.AgentcoreBrowser("vpc_example",
    name="vpc-browser",
    description="Browser with VPC configuration",
    network_configuration={
        "network_mode": "VPC",
        "vpc_config": {
            "security_groups": ["sg-12345678"],
            "subnets": [
                "subnet-12345678",
                "subnet-87654321",
            ],
        },
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := bedrock.NewAgentcoreBrowser(ctx, "vpc_example", &bedrock.AgentcoreBrowserArgs{
			Name:        pulumi.String("vpc-browser"),
			Description: pulumi.String("Browser with VPC configuration"),
			NetworkConfiguration: &bedrock.AgentcoreBrowserNetworkConfigurationArgs{
				NetworkMode: pulumi.String("VPC"),
				VpcConfig: &bedrock.AgentcoreBrowserNetworkConfigurationVpcConfigArgs{
					SecurityGroups: pulumi.StringArray{
						pulumi.String("sg-12345678"),
					},
					Subnets: pulumi.StringArray{
						pulumi.String("subnet-12345678"),
						pulumi.String("subnet-87654321"),
					},
				},
			},
		})
		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 vpcExample = new Aws.Bedrock.AgentcoreBrowser("vpc_example", new()
    {
        Name = "vpc-browser",
        Description = "Browser with VPC configuration",
        NetworkConfiguration = new Aws.Bedrock.Inputs.AgentcoreBrowserNetworkConfigurationArgs
        {
            NetworkMode = "VPC",
            VpcConfig = new Aws.Bedrock.Inputs.AgentcoreBrowserNetworkConfigurationVpcConfigArgs
            {
                SecurityGroups = new[]
                {
                    "sg-12345678",
                },
                Subnets = new[]
                {
                    "subnet-12345678",
                    "subnet-87654321",
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.bedrock.AgentcoreBrowser;
import com.pulumi.aws.bedrock.AgentcoreBrowserArgs;
import com.pulumi.aws.bedrock.inputs.AgentcoreBrowserNetworkConfigurationArgs;
import com.pulumi.aws.bedrock.inputs.AgentcoreBrowserNetworkConfigurationVpcConfigArgs;
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 vpcExample = new AgentcoreBrowser("vpcExample", AgentcoreBrowserArgs.builder()
            .name("vpc-browser")
            .description("Browser with VPC configuration")
            .networkConfiguration(AgentcoreBrowserNetworkConfigurationArgs.builder()
                .networkMode("VPC")
                .vpcConfig(AgentcoreBrowserNetworkConfigurationVpcConfigArgs.builder()
                    .securityGroups("sg-12345678")
                    .subnets(                    
                        "subnet-12345678",
                        "subnet-87654321")
                    .build())
                .build())
            .build());

    }
}
resources:
  vpcExample:
    type: aws:bedrock:AgentcoreBrowser
    name: vpc_example
    properties:
      name: vpc-browser
      description: Browser with VPC configuration
      networkConfiguration:
        networkMode: VPC
        vpcConfig:
          securityGroups:
            - sg-12345678
          subnets:
            - subnet-12345678
            - subnet-87654321

When networkMode is set to “VPC”, the vpcConfig property specifies which subnets and security groups the browser uses. The browser routes traffic through your private network, enabling access to internal applications and private endpoints. Security groups control which resources the browser can reach.

Record browser sessions to S3 for audit

Compliance and debugging workflows often require capturing browser activity for later review.

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

const assumeRole = aws.iam.getPolicyDocument({
    statements: [{
        effect: "Allow",
        actions: ["sts:AssumeRole"],
        principals: [{
            type: "Service",
            identifiers: ["bedrock-agentcore.amazonaws.com"],
        }],
    }],
});
const example = new aws.iam.Role("example", {
    name: "bedrock-agentcore-browser-role",
    assumeRolePolicy: assumeRole.then(assumeRole => assumeRole.json),
});
const recording = new aws.s3.Bucket("recording", {bucket: "browser-recording-bucket"});
const exampleAgentcoreBrowser = new aws.bedrock.AgentcoreBrowser("example", {
    name: "example-browser",
    description: "Browser with recording enabled",
    executionRoleArn: example.arn,
    networkConfiguration: {
        networkMode: "PUBLIC",
    },
    recording: {
        enabled: true,
        s3Location: {
            bucket: recording.bucket,
            prefix: "browser-sessions/",
        },
    },
});
import pulumi
import pulumi_aws as aws

assume_role = aws.iam.get_policy_document(statements=[{
    "effect": "Allow",
    "actions": ["sts:AssumeRole"],
    "principals": [{
        "type": "Service",
        "identifiers": ["bedrock-agentcore.amazonaws.com"],
    }],
}])
example = aws.iam.Role("example",
    name="bedrock-agentcore-browser-role",
    assume_role_policy=assume_role.json)
recording = aws.s3.Bucket("recording", bucket="browser-recording-bucket")
example_agentcore_browser = aws.bedrock.AgentcoreBrowser("example",
    name="example-browser",
    description="Browser with recording enabled",
    execution_role_arn=example.arn,
    network_configuration={
        "network_mode": "PUBLIC",
    },
    recording={
        "enabled": True,
        "s3_location": {
            "bucket": recording.bucket,
            "prefix": "browser-sessions/",
        },
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/bedrock"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/iam"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/s3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		assumeRole, err := iam.GetPolicyDocument(ctx, &iam.GetPolicyDocumentArgs{
			Statements: []iam.GetPolicyDocumentStatement{
				{
					Effect: pulumi.StringRef("Allow"),
					Actions: []string{
						"sts:AssumeRole",
					},
					Principals: []iam.GetPolicyDocumentStatementPrincipal{
						{
							Type: "Service",
							Identifiers: []string{
								"bedrock-agentcore.amazonaws.com",
							},
						},
					},
				},
			},
		}, nil)
		if err != nil {
			return err
		}
		example, err := iam.NewRole(ctx, "example", &iam.RoleArgs{
			Name:             pulumi.String("bedrock-agentcore-browser-role"),
			AssumeRolePolicy: pulumi.String(assumeRole.Json),
		})
		if err != nil {
			return err
		}
		recording, err := s3.NewBucket(ctx, "recording", &s3.BucketArgs{
			Bucket: pulumi.String("browser-recording-bucket"),
		})
		if err != nil {
			return err
		}
		_, err = bedrock.NewAgentcoreBrowser(ctx, "example", &bedrock.AgentcoreBrowserArgs{
			Name:             pulumi.String("example-browser"),
			Description:      pulumi.String("Browser with recording enabled"),
			ExecutionRoleArn: example.Arn,
			NetworkConfiguration: &bedrock.AgentcoreBrowserNetworkConfigurationArgs{
				NetworkMode: pulumi.String("PUBLIC"),
			},
			Recording: &bedrock.AgentcoreBrowserRecordingArgs{
				Enabled: pulumi.Bool(true),
				S3Location: &bedrock.AgentcoreBrowserRecordingS3LocationArgs{
					Bucket: recording.Bucket,
					Prefix: pulumi.String("browser-sessions/"),
				},
			},
		})
		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 assumeRole = Aws.Iam.GetPolicyDocument.Invoke(new()
    {
        Statements = new[]
        {
            new Aws.Iam.Inputs.GetPolicyDocumentStatementInputArgs
            {
                Effect = "Allow",
                Actions = new[]
                {
                    "sts:AssumeRole",
                },
                Principals = new[]
                {
                    new Aws.Iam.Inputs.GetPolicyDocumentStatementPrincipalInputArgs
                    {
                        Type = "Service",
                        Identifiers = new[]
                        {
                            "bedrock-agentcore.amazonaws.com",
                        },
                    },
                },
            },
        },
    });

    var example = new Aws.Iam.Role("example", new()
    {
        Name = "bedrock-agentcore-browser-role",
        AssumeRolePolicy = assumeRole.Apply(getPolicyDocumentResult => getPolicyDocumentResult.Json),
    });

    var recording = new Aws.S3.Bucket("recording", new()
    {
        BucketName = "browser-recording-bucket",
    });

    var exampleAgentcoreBrowser = new Aws.Bedrock.AgentcoreBrowser("example", new()
    {
        Name = "example-browser",
        Description = "Browser with recording enabled",
        ExecutionRoleArn = example.Arn,
        NetworkConfiguration = new Aws.Bedrock.Inputs.AgentcoreBrowserNetworkConfigurationArgs
        {
            NetworkMode = "PUBLIC",
        },
        Recording = new Aws.Bedrock.Inputs.AgentcoreBrowserRecordingArgs
        {
            Enabled = true,
            S3Location = new Aws.Bedrock.Inputs.AgentcoreBrowserRecordingS3LocationArgs
            {
                Bucket = recording.BucketName,
                Prefix = "browser-sessions/",
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.iam.IamFunctions;
import com.pulumi.aws.iam.inputs.GetPolicyDocumentArgs;
import com.pulumi.aws.iam.Role;
import com.pulumi.aws.iam.RoleArgs;
import com.pulumi.aws.s3.Bucket;
import com.pulumi.aws.s3.BucketArgs;
import com.pulumi.aws.bedrock.AgentcoreBrowser;
import com.pulumi.aws.bedrock.AgentcoreBrowserArgs;
import com.pulumi.aws.bedrock.inputs.AgentcoreBrowserNetworkConfigurationArgs;
import com.pulumi.aws.bedrock.inputs.AgentcoreBrowserRecordingArgs;
import com.pulumi.aws.bedrock.inputs.AgentcoreBrowserRecordingS3LocationArgs;
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) {
        final var assumeRole = IamFunctions.getPolicyDocument(GetPolicyDocumentArgs.builder()
            .statements(GetPolicyDocumentStatementArgs.builder()
                .effect("Allow")
                .actions("sts:AssumeRole")
                .principals(GetPolicyDocumentStatementPrincipalArgs.builder()
                    .type("Service")
                    .identifiers("bedrock-agentcore.amazonaws.com")
                    .build())
                .build())
            .build());

        var example = new Role("example", RoleArgs.builder()
            .name("bedrock-agentcore-browser-role")
            .assumeRolePolicy(assumeRole.json())
            .build());

        var recording = new Bucket("recording", BucketArgs.builder()
            .bucket("browser-recording-bucket")
            .build());

        var exampleAgentcoreBrowser = new AgentcoreBrowser("exampleAgentcoreBrowser", AgentcoreBrowserArgs.builder()
            .name("example-browser")
            .description("Browser with recording enabled")
            .executionRoleArn(example.arn())
            .networkConfiguration(AgentcoreBrowserNetworkConfigurationArgs.builder()
                .networkMode("PUBLIC")
                .build())
            .recording(AgentcoreBrowserRecordingArgs.builder()
                .enabled(true)
                .s3Location(AgentcoreBrowserRecordingS3LocationArgs.builder()
                    .bucket(recording.bucket())
                    .prefix("browser-sessions/")
                    .build())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:iam:Role
    properties:
      name: bedrock-agentcore-browser-role
      assumeRolePolicy: ${assumeRole.json}
  recording:
    type: aws:s3:Bucket
    properties:
      bucket: browser-recording-bucket
  exampleAgentcoreBrowser:
    type: aws:bedrock:AgentcoreBrowser
    name: example
    properties:
      name: example-browser
      description: Browser with recording enabled
      executionRoleArn: ${example.arn}
      networkConfiguration:
        networkMode: PUBLIC
      recording:
        enabled: true
        s3Location:
          bucket: ${recording.bucket}
          prefix: browser-sessions/
variables:
  assumeRole:
    fn::invoke:
      function: aws:iam:getPolicyDocument
      arguments:
        statements:
          - effect: Allow
            actions:
              - sts:AssumeRole
            principals:
              - type: Service
                identifiers:
                  - bedrock-agentcore.amazonaws.com

The recording property enables session capture. When enabled is true, the browser writes session data to the specified S3 location. The executionRoleArn grants the browser permissions to write to S3. The prefix organizes recordings within the bucket, making it easier to manage multiple browser instances or time periods.

Beyond these examples

These snippets focus on specific browser-level features: network modes (public and VPC), session recording to S3, and IAM execution roles. They’re intentionally minimal rather than full agent deployments.

The examples may reference pre-existing infrastructure such as VPC subnets and security groups (for VPC mode), S3 buckets (for recording), and IAM roles with appropriate trust policies. They focus on configuring the browser rather than provisioning everything around it.

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

  • Tags for organization and cost tracking
  • Region-specific deployment (region property)
  • Timeout configuration for long-running operations

These omissions are intentional: the goal is to illustrate how each browser feature is wired, not provide drop-in agent modules. See the Bedrock AgentCore Browser resource reference for all available configuration options.

Let's configure AWS Bedrock Agent Browser

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Network Configuration
What's the difference between PUBLIC and VPC network modes?
PUBLIC mode allows the browser to access the internet directly, while VPC mode restricts access to resources within your VPC. When using VPC mode, you must configure vpcConfig with both securityGroups and subnets.
Can I use my existing VPC with the browser?
Yes, set networkMode to VPC and provide your VPC’s security group IDs and subnet IDs in the vpcConfig block.
Session Recording
How do I enable browser session recording?
Set recording.enabled to true and configure s3Location with your S3 bucket name and an optional prefix for organizing recordings.
Where are browser sessions stored when recording is enabled?
Sessions are stored in the S3 bucket specified in recording.s3Location.bucket, with files organized under the optional prefix path.
Do I need to create the S3 bucket before enabling recording?
Yes, the S3 bucket must exist before you configure recording. Create the bucket resource first, then reference it in the browser’s recording configuration.
IAM & Permissions
What IAM permissions does the browser's execution role need?
The execution role must have a trust policy allowing sts:AssumeRole for the bedrock-agentcore.amazonaws.com service principal. Additional permissions depend on what resources the browser needs to access.
Is an execution role required for the browser?
No, executionRoleArn is optional. However, you’ll need it if the browser requires specific AWS permissions beyond basic browsing capabilities.
General Configuration
Which AWS region will my browser be created in?
The browser is created in the region specified by the region property, which defaults to your provider’s configured region if not explicitly set.
How do I import an existing browser into Pulumi?
Use pulumi import aws:bedrock/agentcoreBrowser:AgentcoreBrowser <resource-name> <browser-id>, where browser-id is the unique identifier of your existing browser.

Using a different cloud?

Explore analytics guides for other cloud providers: