The aws:s3/accessPoint:AccessPoint resource, part of the Pulumi AWS provider, creates named network endpoints for S3 buckets that simplify permission management and network access control. This guide focuses on two capabilities: creating access points for general purpose buckets and restricting access to VPC traffic.
Access points attach to existing S3 buckets and may reference VPC infrastructure for network restrictions. The examples are intentionally small. Combine them with your own bucket policies and network configuration.
Create an access point for a general purpose bucket
Most deployments start with a standard general purpose bucket in an AWS region. Access points provide named endpoints that simplify permission management for shared buckets.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.s3.Bucket("example", {bucket: "example"});
const exampleAccessPoint = new aws.s3.AccessPoint("example", {
bucket: example.id,
name: "example",
});
import pulumi
import pulumi_aws as aws
example = aws.s3.Bucket("example", bucket="example")
example_access_point = aws.s3.AccessPoint("example",
bucket=example.id,
name="example")
package main
import (
"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 {
example, err := s3.NewBucket(ctx, "example", &s3.BucketArgs{
Bucket: pulumi.String("example"),
})
if err != nil {
return err
}
_, err = s3.NewAccessPoint(ctx, "example", &s3.AccessPointArgs{
Bucket: example.ID(),
Name: pulumi.String("example"),
})
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.S3.Bucket("example", new()
{
BucketName = "example",
});
var exampleAccessPoint = new Aws.S3.AccessPoint("example", new()
{
Bucket = example.Id,
Name = "example",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.s3.Bucket;
import com.pulumi.aws.s3.BucketArgs;
import com.pulumi.aws.s3.AccessPoint;
import com.pulumi.aws.s3.AccessPointArgs;
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 Bucket("example", BucketArgs.builder()
.bucket("example")
.build());
var exampleAccessPoint = new AccessPoint("exampleAccessPoint", AccessPointArgs.builder()
.bucket(example.id())
.name("example")
.build());
}
}
resources:
example:
type: aws:s3:Bucket
properties:
bucket: example
exampleAccessPoint:
type: aws:s3:AccessPoint
name: example
properties:
bucket: ${example.id}
name: example
The bucket property references an existing S3 bucket by ID. The name property assigns a unique identifier to the access point. Without additional configuration, the access point inherits the bucket’s permissions and allows internet access subject to bucket policies.
Restrict access to requests from a VPC
Applications in private subnets often need S3 access without traversing the public internet. VPC-restricted access points keep traffic within your network boundary.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.s3control.Bucket("example", {bucket: "example"});
const exampleVpc = new aws.ec2.Vpc("example", {cidrBlock: "10.0.0.0/16"});
const exampleAccessPoint = new aws.s3.AccessPoint("example", {
bucket: example.arn,
name: "example",
vpcConfiguration: {
vpcId: exampleVpc.id,
},
});
import pulumi
import pulumi_aws as aws
example = aws.s3control.Bucket("example", bucket="example")
example_vpc = aws.ec2.Vpc("example", cidr_block="10.0.0.0/16")
example_access_point = aws.s3.AccessPoint("example",
bucket=example.arn,
name="example",
vpc_configuration={
"vpc_id": example_vpc.id,
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ec2"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/s3"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/s3control"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
example, err := s3control.NewBucket(ctx, "example", &s3control.BucketArgs{
Bucket: pulumi.String("example"),
})
if err != nil {
return err
}
exampleVpc, err := ec2.NewVpc(ctx, "example", &ec2.VpcArgs{
CidrBlock: pulumi.String("10.0.0.0/16"),
})
if err != nil {
return err
}
_, err = s3.NewAccessPoint(ctx, "example", &s3.AccessPointArgs{
Bucket: example.Arn,
Name: pulumi.String("example"),
VpcConfiguration: &s3.AccessPointVpcConfigurationArgs{
VpcId: exampleVpc.ID(),
},
})
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.S3Control.Bucket("example", new()
{
BucketName = "example",
});
var exampleVpc = new Aws.Ec2.Vpc("example", new()
{
CidrBlock = "10.0.0.0/16",
});
var exampleAccessPoint = new Aws.S3.AccessPoint("example", new()
{
Bucket = example.Arn,
Name = "example",
VpcConfiguration = new Aws.S3.Inputs.AccessPointVpcConfigurationArgs
{
VpcId = exampleVpc.Id,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.s3control.Bucket;
import com.pulumi.aws.s3control.BucketArgs;
import com.pulumi.aws.ec2.Vpc;
import com.pulumi.aws.ec2.VpcArgs;
import com.pulumi.aws.s3.AccessPoint;
import com.pulumi.aws.s3.AccessPointArgs;
import com.pulumi.aws.s3.inputs.AccessPointVpcConfigurationArgs;
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 Bucket("example", BucketArgs.builder()
.bucket("example")
.build());
var exampleVpc = new Vpc("exampleVpc", VpcArgs.builder()
.cidrBlock("10.0.0.0/16")
.build());
var exampleAccessPoint = new AccessPoint("exampleAccessPoint", AccessPointArgs.builder()
.bucket(example.arn())
.name("example")
.vpcConfiguration(AccessPointVpcConfigurationArgs.builder()
.vpcId(exampleVpc.id())
.build())
.build());
}
}
resources:
example:
type: aws:s3control:Bucket
properties:
bucket: example
exampleAccessPoint:
type: aws:s3:AccessPoint
name: example
properties:
bucket: ${example.arn}
name: example
vpcConfiguration:
vpcId: ${exampleVpc.id}
exampleVpc:
type: aws:ec2:Vpc
name: example
properties:
cidrBlock: 10.0.0.0/16
The vpcConfiguration property limits access to requests originating from the specified VPC. When configured, the networkOrigin output shows “VPC” instead of “Internet”, and the access point rejects requests from outside the VPC. This configuration is required for S3 on Outposts buckets.
Beyond these examples
These snippets focus on specific access point features: access point creation for general purpose and Outposts buckets, and VPC-restricted network access. They’re intentionally minimal rather than full access control solutions.
The examples reference pre-existing infrastructure such as S3 buckets (general purpose or Outposts) and VPC infrastructure for VPC-restricted access points. They focus on configuring the access point rather than provisioning buckets or network infrastructure.
To keep things focused, common access point patterns are omitted, including:
- Access point policies (policy property or standalone AccessPointPolicy resource)
- Public access block configuration (publicAccessBlockConfiguration)
- Directory bucket access points (shown but not explained in detail)
These omissions are intentional: the goal is to illustrate how each access point feature is wired, not provide drop-in access control modules. See the S3 AccessPoint resource reference for all available configuration options.
Let's configure AWS S3 Access Points
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Policy Management
policy on the access point resource alongside the standalone aws.s3control.AccessPointPolicy resource. Using both causes policy conflicts and overwrites. Choose one approach or the other.policy to null or an empty string won’t delete the policy (it may have been set by aws.s3control.AccessPointPolicy). To remove it, set policy to "{}" (an empty JSON document).Configuration & Immutability
accountId, bucket, bucketAccountId, name, publicAccessBlockConfiguration, and vpcConfiguration. Changing any of these requires recreating the access point.You have three options:
- General Purpose Bucket - Use the bucket name in the
bucketproperty - S3 on Outposts - Use the bucket ARN and include
vpcConfiguration(required) - Directory Bucket - Use special naming format with zoneId (e.g.,
example--zoneId--x-s3)
accountId and region default to the values set in your AWS provider configuration if not explicitly specified.Connectivity & Endpoints
domainName.s3control endpoint provider configuration, not the s3 endpoint. This resource is managed through the S3 Control API.networkOrigin shows whether the access point allows public Internet access (Internet) or only VPC access (VPC). This is determined by your vpcConfiguration settings.Import & Migration
account_id:name format. For S3 on Outposts, use the full ARN. Example: pulumi import aws:s3/accessPoint:AccessPoint example 123456789012:example