The aws:s3/bucketVersioningV2:BucketVersioningV2 resource, part of the Pulumi AWS provider, controls versioning behavior on S3 buckets: enabling, disabling, or suspending version tracking for objects. This guide focuses on two capabilities: enabling and disabling versioning, and coordinating object creation with versioning state.
Versioning resources reference existing S3 buckets and may need to coordinate with object creation timing. The examples are intentionally small. Combine them with your own bucket infrastructure and lifecycle policies.
Enable versioning to preserve object history
Teams protecting against accidental deletions or overwrites enable versioning to preserve every version of every object.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.s3.Bucket("example", {bucket: "example-bucket"});
const exampleBucketAcl = new aws.s3.BucketAcl("example", {
bucket: example.id,
acl: "private",
});
const versioningExample = new aws.s3.BucketVersioning("versioning_example", {
bucket: example.id,
versioningConfiguration: {
status: "Enabled",
},
});
import pulumi
import pulumi_aws as aws
example = aws.s3.Bucket("example", bucket="example-bucket")
example_bucket_acl = aws.s3.BucketAcl("example",
bucket=example.id,
acl="private")
versioning_example = aws.s3.BucketVersioning("versioning_example",
bucket=example.id,
versioning_configuration={
"status": "Enabled",
})
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-bucket"),
})
if err != nil {
return err
}
_, err = s3.NewBucketAcl(ctx, "example", &s3.BucketAclArgs{
Bucket: example.ID(),
Acl: pulumi.String("private"),
})
if err != nil {
return err
}
_, err = s3.NewBucketVersioning(ctx, "versioning_example", &s3.BucketVersioningArgs{
Bucket: example.ID(),
VersioningConfiguration: &s3.BucketVersioningVersioningConfigurationArgs{
Status: pulumi.String("Enabled"),
},
})
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-bucket",
});
var exampleBucketAcl = new Aws.S3.BucketAcl("example", new()
{
Bucket = example.Id,
Acl = "private",
});
var versioningExample = new Aws.S3.BucketVersioning("versioning_example", new()
{
Bucket = example.Id,
VersioningConfiguration = new Aws.S3.Inputs.BucketVersioningVersioningConfigurationArgs
{
Status = "Enabled",
},
});
});
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.BucketAcl;
import com.pulumi.aws.s3.BucketAclArgs;
import com.pulumi.aws.s3.BucketVersioning;
import com.pulumi.aws.s3.BucketVersioningArgs;
import com.pulumi.aws.s3.inputs.BucketVersioningVersioningConfigurationArgs;
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-bucket")
.build());
var exampleBucketAcl = new BucketAcl("exampleBucketAcl", BucketAclArgs.builder()
.bucket(example.id())
.acl("private")
.build());
var versioningExample = new BucketVersioning("versioningExample", BucketVersioningArgs.builder()
.bucket(example.id())
.versioningConfiguration(BucketVersioningVersioningConfigurationArgs.builder()
.status("Enabled")
.build())
.build());
}
}
resources:
example:
type: aws:s3:Bucket
properties:
bucket: example-bucket
exampleBucketAcl:
type: aws:s3:BucketAcl
name: example
properties:
bucket: ${example.id}
acl: private
versioningExample:
type: aws:s3:BucketVersioning
name: versioning_example
properties:
bucket: ${example.id}
versioningConfiguration:
status: Enabled
When versioning is enabled, S3 assigns a unique version ID to each object write. The versioningConfiguration block sets the status property to “Enabled”, which activates version tracking. AWS recommends waiting 15 minutes after enabling versioning before issuing write operations on objects in the bucket.
Disable versioning to stop creating new versions
When versioning is no longer needed, you can disable it to stop creating new versions while preserving existing ones.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.s3.Bucket("example", {bucket: "example-bucket"});
const exampleBucketAcl = new aws.s3.BucketAcl("example", {
bucket: example.id,
acl: "private",
});
const versioningExample = new aws.s3.BucketVersioning("versioning_example", {
bucket: example.id,
versioningConfiguration: {
status: "Disabled",
},
});
import pulumi
import pulumi_aws as aws
example = aws.s3.Bucket("example", bucket="example-bucket")
example_bucket_acl = aws.s3.BucketAcl("example",
bucket=example.id,
acl="private")
versioning_example = aws.s3.BucketVersioning("versioning_example",
bucket=example.id,
versioning_configuration={
"status": "Disabled",
})
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-bucket"),
})
if err != nil {
return err
}
_, err = s3.NewBucketAcl(ctx, "example", &s3.BucketAclArgs{
Bucket: example.ID(),
Acl: pulumi.String("private"),
})
if err != nil {
return err
}
_, err = s3.NewBucketVersioning(ctx, "versioning_example", &s3.BucketVersioningArgs{
Bucket: example.ID(),
VersioningConfiguration: &s3.BucketVersioningVersioningConfigurationArgs{
Status: pulumi.String("Disabled"),
},
})
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-bucket",
});
var exampleBucketAcl = new Aws.S3.BucketAcl("example", new()
{
Bucket = example.Id,
Acl = "private",
});
var versioningExample = new Aws.S3.BucketVersioning("versioning_example", new()
{
Bucket = example.Id,
VersioningConfiguration = new Aws.S3.Inputs.BucketVersioningVersioningConfigurationArgs
{
Status = "Disabled",
},
});
});
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.BucketAcl;
import com.pulumi.aws.s3.BucketAclArgs;
import com.pulumi.aws.s3.BucketVersioning;
import com.pulumi.aws.s3.BucketVersioningArgs;
import com.pulumi.aws.s3.inputs.BucketVersioningVersioningConfigurationArgs;
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-bucket")
.build());
var exampleBucketAcl = new BucketAcl("exampleBucketAcl", BucketAclArgs.builder()
.bucket(example.id())
.acl("private")
.build());
var versioningExample = new BucketVersioning("versioningExample", BucketVersioningArgs.builder()
.bucket(example.id())
.versioningConfiguration(BucketVersioningVersioningConfigurationArgs.builder()
.status("Disabled")
.build())
.build());
}
}
resources:
example:
type: aws:s3:Bucket
properties:
bucket: example-bucket
exampleBucketAcl:
type: aws:s3:BucketAcl
name: example
properties:
bucket: ${example.id}
acl: private
versioningExample:
type: aws:s3:BucketVersioning
name: versioning_example
properties:
bucket: ${example.id}
versioningConfiguration:
status: Disabled
Setting status to “Disabled” suspends versioning: new writes no longer create versions, but existing versions remain accessible. This differs from deleting the versioning resource, which either suspends versioning or removes the resource from state if the bucket was never versioned.
Coordinate object creation with versioning enablement
When creating objects that need version IDs in the same deployment, explicit dependencies ensure versioning is enabled first.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.s3.Bucket("example", {bucket: "yotto"});
const exampleBucketVersioning = new aws.s3.BucketVersioning("example", {
bucket: example.id,
versioningConfiguration: {
status: "Enabled",
},
});
const exampleBucketObjectv2 = new aws.s3.BucketObjectv2("example", {
bucket: exampleBucketVersioning.id,
key: "droeloe",
source: new pulumi.asset.FileAsset("example.txt"),
});
import pulumi
import pulumi_aws as aws
example = aws.s3.Bucket("example", bucket="yotto")
example_bucket_versioning = aws.s3.BucketVersioning("example",
bucket=example.id,
versioning_configuration={
"status": "Enabled",
})
example_bucket_objectv2 = aws.s3.BucketObjectv2("example",
bucket=example_bucket_versioning.id,
key="droeloe",
source=pulumi.FileAsset("example.txt"))
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("yotto"),
})
if err != nil {
return err
}
exampleBucketVersioning, err := s3.NewBucketVersioning(ctx, "example", &s3.BucketVersioningArgs{
Bucket: example.ID(),
VersioningConfiguration: &s3.BucketVersioningVersioningConfigurationArgs{
Status: pulumi.String("Enabled"),
},
})
if err != nil {
return err
}
_, err = s3.NewBucketObjectv2(ctx, "example", &s3.BucketObjectv2Args{
Bucket: exampleBucketVersioning.ID(),
Key: pulumi.String("droeloe"),
Source: pulumi.NewFileAsset("example.txt"),
})
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 = "yotto",
});
var exampleBucketVersioning = new Aws.S3.BucketVersioning("example", new()
{
Bucket = example.Id,
VersioningConfiguration = new Aws.S3.Inputs.BucketVersioningVersioningConfigurationArgs
{
Status = "Enabled",
},
});
var exampleBucketObjectv2 = new Aws.S3.BucketObjectv2("example", new()
{
Bucket = exampleBucketVersioning.Id,
Key = "droeloe",
Source = new FileAsset("example.txt"),
});
});
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.BucketVersioning;
import com.pulumi.aws.s3.BucketVersioningArgs;
import com.pulumi.aws.s3.inputs.BucketVersioningVersioningConfigurationArgs;
import com.pulumi.aws.s3.BucketObjectv2;
import com.pulumi.aws.s3.BucketObjectv2Args;
import com.pulumi.asset.FileAsset;
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("yotto")
.build());
var exampleBucketVersioning = new BucketVersioning("exampleBucketVersioning", BucketVersioningArgs.builder()
.bucket(example.id())
.versioningConfiguration(BucketVersioningVersioningConfigurationArgs.builder()
.status("Enabled")
.build())
.build());
var exampleBucketObjectv2 = new BucketObjectv2("exampleBucketObjectv2", BucketObjectv2Args.builder()
.bucket(exampleBucketVersioning.id())
.key("droeloe")
.source(new FileAsset("example.txt"))
.build());
}
}
resources:
example:
type: aws:s3:Bucket
properties:
bucket: yotto
exampleBucketVersioning:
type: aws:s3:BucketVersioning
name: example
properties:
bucket: ${example.id}
versioningConfiguration:
status: Enabled
exampleBucketObjectv2:
type: aws:s3:BucketObjectv2
name: example
properties:
bucket: ${exampleBucketVersioning.id}
key: droeloe
source:
fn::FileAsset: example.txt
The BucketObjectv2 resource references the versioning resource’s bucket ID, creating an implicit dependency that ensures versioning is active before the object is written. For critical or production objects, AWS recommends creating the bucket and enabling versioning in a separate deployment, waiting 15 minutes, then creating objects in a subsequent deployment.
Beyond these examples
These snippets focus on specific versioning features: versioning state management and object creation coordination. They’re intentionally minimal rather than full bucket configurations.
The examples reference pre-existing infrastructure such as S3 buckets. They focus on versioning configuration rather than provisioning buckets or managing their contents.
To keep things focused, common versioning patterns are omitted, including:
- MFA delete protection (mfa property)
- Cross-account bucket access (expectedBucketOwner)
- Lifecycle policies for version expiration
- Suspending vs permanently disabling versioning
These omissions are intentional: the goal is to illustrate how versioning state is wired, not provide drop-in bucket modules. See the S3 BucketVersioningV2 resource reference for all available configuration options.
Let's configure AWS S3 Bucket Versioning
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Versioning Configuration & Timing
versioningConfiguration.status to Enabled to turn on versioning, or Disabled to turn it off.Enabled turns on versioning for new and existing objects, while Disabled prevents new versions from being created (existing versions remain).Resource Lifecycle & Dependencies
bucket property in your object definition, or use explicit dependsOn to ensure versioning is enabled before object creation.Limitations & Compatibility
bucket and expectedBucketOwner properties are immutable and cannot be changed after creation.Cross-Account & Import
bucket-name,123456789012.