From 1d4c64736750bd5b1fb452cdbc932c8742c5b08d Mon Sep 17 00:00:00 2001 From: Anton Tayanovskyy Date: Tue, 17 Sep 2024 12:44:11 -0400 Subject: [PATCH 01/20] Document migrating aws.s3.Bucket to aws.s3.BucketV2 --- .../aws/how-to-guides/bucketv2-migration.md | 345 ++++++++++++++++++ 1 file changed, 345 insertions(+) create mode 100644 themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md diff --git a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md new file mode 100644 index 0000000000..7eeb1087b0 --- /dev/null +++ b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md @@ -0,0 +1,345 @@ +--- +title: "BucketV2 Migration Guide" +h1: "Migrating from aws.s3.Bucket to aws.s3.BucketV2" +meta_desc: Practitioner level instructions for migrating from aws.s3.Bucket to aws.s3.BucketV2 resources +layout: package +--- + +## Migrating from aws.s3.Bucket to aws.s3.BucketV2 + +In the upcoming AWS Classic major release (v7), `aws.s3.Bucket` will be discontinued in favor of `BucketV2`. Users of +`aws.s3.Bucket` resource are encouraged to migrate early. The migration is straightforward for simple use cases but +requires some care for advanced configurations. Specifically `BucketV2` inputs such as `policy` and `accelerationStatus` +are deprecated and using the requires migrating to side-by-side resources (see [Removed inputs](#removed-inputs)). This +guide aims to cover all relevant scenarios with precise migration instructions. + +To migrate existing `aws.s3.Bucket` resources to `aws.s3.BucketV2`: + +1. Edit your Pulumi program sources to replace [Removed inputs](#removed-inputs) with equivalent side-by-side resources. + +2. Perform `pulumi up` to replace (delete and re-create) the buckets in AWS. + +If replacement is not acceptable, it is possible to perform a manual migration with `pulumi import`. For a fully worked +example see [Avoiding replacement](#avoiding-replacement). + +## Migrating deprecated inputs + +Inputs such as `policy` and `accelerationStatus` are deprecated on the `aws.s3.BucketV2` resource. Instead of using +these inputs, it is recommended to use side-by-side resources to achieve the same effect. + +### policy input + +To specify a +[bucket policy](https://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html), +instead of: + +``` typescript +new aws.s3.Bucket("my-bucket", { + bucket: "my-bucket-26224916", + policy: JSON.stringify({ + "Version": "2012-10-17", + "Id": "PutObjPolicy", + "Statement": [ + { + "Sid": "DenyObjectsThatAreNotSSEKMS", + "Principal": "*", + "Effect": "Deny", + "Action": "s3:PutObject", + "Resource": "arn:aws:s3:::my-bucket-26224916/*", + "Condition": { + "Null": { + "s3:x-amz-server-side-encryption-aws-kms-key-id": "true" + } + } + } + ] + }), +}); +``` + +Use the `aws.s3.BucketPolicy` resource: + +``` typescript +const myBucket = new aws.s3.BucketV2("my-new-bucket", {}); + +new aws.s3.BucketPolicy("my-bucket-policy", { + bucket: myBucket.bucket, + policy: myBucket.bucket.apply(bucket => JSON.stringify({ + "Version": "2012-10-17", + "Id": "PutObjPolicy", + "Statement": [ + { + "Sid": "DenyObjectsThatAreNotSSEKMS", + "Principal": "*", + "Effect": "Deny", + "Action": "s3:PutObject", + "Resource": `arn:aws:s3:::${bucket}/*`, + "Condition": { + "Null": { + "s3:x-amz-server-side-encryption-aws-kms-key-id": "true" + } + } + } + ] + })), +}); +``` + +As a bonus, the policy can now more easily refer to the concrete name of the bucket. + +### serverSideEncryptionConfiguration input + +To specify [server-side encryption configuration](http://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html), +instead of: + +``` typescript +new aws.s3.Bucket("my-bucket", { + serverSideEncryptionConfiguration: { + rule: { + applyServerSideEncryptionByDefault: { + sseAlgorithm: "aws:kms", + }, + }, + }, +}); +``` + +Use the `aws.s3.BucketServerSideEncryptionConfiguration` resource: + +``` typescript +const myBucket = new aws.s3.BucketV2("my-new-bucket", {}); + +new aws.s3.BucketServerSideEncryptionConfigurationV2("my-new-bucket-sse-config", { + bucket: myBucket.bucket, + rules: [{ + applyServerSideEncryptionByDefault: { + sseAlgorithm: "aws:kms" + }, + }], +}); +``` + +### acceleration input + +To enable acceleration, instead of: + +``` typescript +new aws.s3.Bucket("my-bucket", { + accelerationStatus: "Enabled", +}); +``` + +Use the `aws.s3.BucketAccelerationConfiguration` resource: + +``` typescript +const myBucket = new aws.s3.BucketV2("my-new-bucket", {}); + +new aws.s3.BucketAccelerateConfigurationV2("my-bucket-acceleration", { + bucket: myBucket.bucket, + status: "Enabled", +}); +``` + +### corsRules input + +To configure [Cross-Origin Resource Sharing](https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html), +instead of: + +``` typescript +new aws.s3.Bucket("my-bucket", { + corsRules: [ + { + allowedHeaders: ["*"], + allowedMethods: ["GET"], + allowedOrigins: ["*"], + exposeHeaders: ["ETag"], + maxAgeSeconds: 3000, + }, + ], +}); +``` + +Use the `aws.s3.BucketCorsConfiguration` resource: + +``` typescript +const myBucket = new aws.s3.BucketV2("my-new-bucket", {}); + +new aws.s3.BucketCorsConfigurationV2("my-bucket-cors", { + bucket: myBucket.bucket, + corsRules: [ + { + allowedHeaders: ["*"], + allowedMethods: ["GET"], + allowedOrigins: ["*"], + exposeHeaders: ["ETag"], + maxAgeSeconds: 3000, + }, + ] +}); +``` + +### acl and grants inputs + +The `aws.s3.BucketAcl` resource is now required to configure either +[canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl) +or [ACL policy grant](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#sample-acl), +and it replaces the use of `acl` and `grants` inputs. To illustrate migrating the uses of `grants`, instead of: + +``` typescript +const currentUser = aws.s3.getCanonicalUserIdOutput({}); + +new aws.s3.Bucket("my-bucket", { + grants: [ + { + permissions: ["READ"], + type: "CanonicalUser", + id: currentUser.id, + }, + ], +}); +``` + +Use the `aws.s3.BucketAcl` resource like this: + +``` typescript +const myBucket = new aws.s3.BucketV2("my-new-bucket", {}); + +const myBucketOwnershipControls = new aws.s3.BucketOwnershipControls("my-new-bucket-oc", { + bucket: myBucket.id, + rule: { + objectOwnership: "BucketOwnerPreferred", + }, +}); + +new aws.s3.BucketAclV2("grant", { + bucket: myBucket.bucket, + accessControlPolicy: { + owner: {id: currentUser.id}, + grants: [ + { + permission: "READ", + grantee: { + type: "CanonicalUser", + id: currentUser.id, + }, + }, + ], + }, +}, { + dependsOn: [myBucketOwnershipControls] +}); +``` + +Note that `dependsOn` on `BucketOwnershipControls` is required for Pulumi to correctly order the operations for this +infrastructure. Consult the documentation on `aws.s3.BucketAclV2` for more fully worked examples of configuring ACL. + +### hostedZoneId input + +This will only be available as an output. If your program specified this as an input, simply remove it. The input was +ignored by prior versions of the provider and was exposed in error. + +### other inputs + +All other removed inputs are treated similarly. Consult the documentation for the matching resource replacing the input +for more information: + +| Input | Resource | +|--------------------------|--------------------------------------------| +| lifecycleRules | aws.s3.BucketLifecycleConfigurationV2 | +| loggings | aws.s3.BucketLoggingV2 | +| objectLockConfiguration | aws.s3.BucketObjectLockConfigurationV2 | +| replicationConfiguration | aws.s3.BucketReplicationConfig | +| requestPayer | aws.s3.BucketRequestPaymentConfigurationV2 | +| versionings | aws.s3.BucketVersioningV2 | +| website | aws.s3.BucketWebsiteConfigurationV2 | +| websiteDomain | aws.s3.BucketWebsiteConfigurationV2 | +| websiteEndpoint | aws.s3.BucketWebsiteConfigurationV2 | + + +## Avoiding replacement + +In situations when replacing the bucket in the AWS account is not acceptable, it is possible to perform a manual +migration that changes Pulumi program and state to track buckets using the new resource without executing any changes +against the actual cloud account. While the details will vary depending on your use case, this procedure generally +involves the following steps: + +1. Find URNs for legacy Bucket Pulumi resources using `pulumi stack export` +2. Determine the actual bucket name(s) +3. Determine which side-by-side resources will be needed for each bucket +4. Construct an `pulumi-import.json` file listing the buckets and their side-by-side resources +5. Run `pulumi import --file import-file.json` using the [Bulk Importing](https://www.pulumi.com/tutorials/importing/bulk-importing/) feature +6. Add the suggested code into your Pulumi program source +7. Remove the legacy Bucket code from your Pulumi program source +8. Remove the legacy Bucket resources from state using `pulumi state delete $bucketURN` +9. Run `pulumi preview` to confirm a no-change plan + +Consider a concrete example, suppose you have provisioned a bucket with a `serverSideEncryptionConfiguration` as +follows: + +```typescript +import * as aws from "@pulumi/aws"; + +new aws.s3.Bucket("my-bucket", { + serverSideEncryptionConfiguration: { + rule: { + applyServerSideEncryptionByDefault: { + sseAlgorithm: "aws:kms", + }, + }, + }, +}); +``` + +1. Scanning through the state in `pulumi stack export`, observe and note its URN is + `"urn:pulumi:dev::bucket-playground::aws:s3/bucket:Bucket::my-bucket"` + +2. The state file should also include the actual cloud name for the bucket such as `"bucket": "my-bucket-cd24744"` + +3. This bucket will require a `BucketServerSideEncryptionConfiguration` side-by-side resource + +4. The import file should therefore look like this: + + ```json + { + "resources": [ + { + "type": "aws:s3/bucketV2:BucketV2", + "name": "my-bucket", + "id": "my-bucket-cd24744" + }, + { + "type": "aws:s3/bucketServerSideEncryptionConfigurationV2:BucketServerSideEncryptionConfigurationV2", + "name": "my-bucket-encryption-configuration", + "id": "my-bucket-cd24744" + } + ] + } + ``` + +5. `pulumi import --file import-file.json` will suggest new code to include in your program, for example: + + ```typescript + const my_bucket = new aws.s3.BucketV2("my-bucket", { + bucket: "my-bucket-cd24744", + }, { + protect: true, + }); + + const my_bucket_encryption_configuration = new aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", { + bucket: "my-bucket-cd24744", + rules: [{ + applyServerSideEncryptionByDefault: { + sseAlgorithm: "aws:kms", + }, + }], + }, { + protect: true, + }); + ``` + +6. Run `pulumi state delete "urn:pulumi:dev::bucket-playground::aws:s3/bucket:Bucket::my-bucket"` to remove the old + bucket from the state + +7. Delete the code for the old bucket from the sources. + +8. `pulumi preview` should result in `Resources: N unchanged` to confirm everything went well. From 5ea6ef84417b425ed67891966f91a6f681690a95 Mon Sep 17 00:00:00 2001 From: Anton Tayanovskyy Date: Tue, 17 Sep 2024 13:11:32 -0400 Subject: [PATCH 02/20] Fix --- .../packages/aws/how-to-guides/bucketv2-migration.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md index 7eeb1087b0..d60d7508fb 100644 --- a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md +++ b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md @@ -15,12 +15,12 @@ guide aims to cover all relevant scenarios with precise migration instructions. To migrate existing `aws.s3.Bucket` resources to `aws.s3.BucketV2`: -1. Edit your Pulumi program sources to replace [Removed inputs](#removed-inputs) with equivalent side-by-side resources. +1. Edit your Pulumi program sources to replace removed inputs (see below) with equivalent side-by-side resources. 2. Perform `pulumi up` to replace (delete and re-create) the buckets in AWS. -If replacement is not acceptable, it is possible to perform a manual migration with `pulumi import`. For a fully worked -example see [Avoiding replacement](#avoiding-replacement). +If replacement is not acceptable, it is possible to perform a manual migration with `pulumi import` (see Avoiding +replacement). ## Migrating deprecated inputs From 7f998e01c3762befa9726685c4cece249fe32adc Mon Sep 17 00:00:00 2001 From: Anton Tayanovskyy Date: Tue, 17 Sep 2024 14:12:49 -0400 Subject: [PATCH 03/20] Work around another x-ref build issue --- .../registry/packages/aws/how-to-guides/bucketv2-migration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md index d60d7508fb..ec6116b41f 100644 --- a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md +++ b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md @@ -10,8 +10,8 @@ layout: package In the upcoming AWS Classic major release (v7), `aws.s3.Bucket` will be discontinued in favor of `BucketV2`. Users of `aws.s3.Bucket` resource are encouraged to migrate early. The migration is straightforward for simple use cases but requires some care for advanced configurations. Specifically `BucketV2` inputs such as `policy` and `accelerationStatus` -are deprecated and using the requires migrating to side-by-side resources (see [Removed inputs](#removed-inputs)). This -guide aims to cover all relevant scenarios with precise migration instructions. +are deprecated and using the requires migrating to side-by-side resources (see Removed inputs). This guide aims to cover +all relevant scenarios with precise migration instructions. To migrate existing `aws.s3.Bucket` resources to `aws.s3.BucketV2`: From 3dfe7abf2a9c612e4a7b545d988b10278741cf9a Mon Sep 17 00:00:00 2001 From: Anton Tayanovskyy Date: Tue, 17 Sep 2024 14:45:19 -0400 Subject: [PATCH 04/20] Translate example 1 to yaml --- .../aws/how-to-guides/bucketv2-migration.md | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md index ec6116b41f..82be2436c8 100644 --- a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md +++ b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md @@ -33,29 +33,31 @@ To specify a [bucket policy](https://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html), instead of: -``` typescript -new aws.s3.Bucket("my-bucket", { - bucket: "my-bucket-26224916", - policy: JSON.stringify({ - "Version": "2012-10-17", - "Id": "PutObjPolicy", - "Statement": [ - { - "Sid": "DenyObjectsThatAreNotSSEKMS", - "Principal": "*", - "Effect": "Deny", - "Action": "s3:PutObject", - "Resource": "arn:aws:s3:::my-bucket-26224916/*", - "Condition": { - "Null": { - "s3:x-amz-server-side-encryption-aws-kms-key-id": "true" - } - } - } - ] - }), -}); +{{% choosable %}} + +```yaml +name: example +runtime: yaml +resources: + my-bucket: + type: aws:s3:Bucket + properties: + bucket: "my-bucket-26224916" + policy: + fn::toJSON: + Version: 2012-10-17 + Id: PutObjPolicy + Statement: + Sid: DenyObjectsThatAreNotSSEKMS + Principal: "*" + Effect: Deny + Action: s3:PutObject + Resource: "arn:aws:s3:::my-bucket-26224916/*" + Condition: + "Null": + s3:x-amz-server-side-encryption-aws-kms-key-id: "true" ``` +{{% /choosable %}} Use the `aws.s3.BucketPolicy` resource: From 56233970d8d960bd7b5084233ccada0c3e0c783e Mon Sep 17 00:00:00 2001 From: Anton Tayanovskyy Date: Tue, 17 Sep 2024 15:05:26 -0400 Subject: [PATCH 05/20] Render the first example --- .../aws/how-to-guides/bucketv2-migration.md | 213 +++++++++++++++++- 1 file changed, 212 insertions(+), 1 deletion(-) diff --git a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md index 82be2436c8..60cfae3b0e 100644 --- a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md +++ b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md @@ -33,7 +33,213 @@ To specify a [bucket policy](https://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html), instead of: -{{% choosable %}} +{{< chooser language "typescript,python,go,csharp,java,yaml" >}} + +{{% choosable language typescript %}} + +```typescript +import * as pulumi from "@pulumi/pulumi"; +import * as aws from "@pulumi/aws"; + +const myBucket = new aws.s3.Bucket("my-bucket", { + bucket: "my-bucket-26224916", + policy: JSON.stringify({ + Version: "2012-10-17", + Id: "PutObjPolicy", + Statement: { + Sid: "DenyObjectsThatAreNotSSEKMS", + Principal: "*", + Effect: "Deny", + Action: "s3:PutObject", + Resource: "arn:aws:s3:::my-bucket-26224916/*", + Condition: { + Null: { + "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", + }, + }, + }, + }), +}); + +``` + +{{% /choosable %}} + +{{% choosable language python %}} + +```python +import pulumi +import json +import pulumi_aws as aws + +my_bucket = aws.s3.Bucket("my-bucket", + bucket="my-bucket-26224916", + policy=json.dumps({ + "Version": "2012-10-17", + "Id": "PutObjPolicy", + "Statement": { + "Sid": "DenyObjectsThatAreNotSSEKMS", + "Principal": "*", + "Effect": "Deny", + "Action": "s3:PutObject", + "Resource": "arn:aws:s3:::my-bucket-26224916/*", + "Condition": { + "Null": { + "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", + }, + }, + }, + })) + +``` + +{{% /choosable %}} + +{{% choosable language go %}} + +```go +package main + +import ( + "encoding/json" + + "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + tmpJSON0, err := json.Marshal(map[string]interface{}{ + "Version": "2012-10-17", + "Id": "PutObjPolicy", + "Statement": map[string]interface{}{ + "Sid": "DenyObjectsThatAreNotSSEKMS", + "Principal": "*", + "Effect": "Deny", + "Action": "s3:PutObject", + "Resource": "arn:aws:s3:::my-bucket-26224916/*", + "Condition": map[string]interface{}{ + "Null": map[string]interface{}{ + "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", + }, + }, + }, + }) + if err != nil { + return err + } + json0 := string(tmpJSON0) + _, err = s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{ + Bucket: pulumi.String("my-bucket-26224916"), + Policy: pulumi.String(json0), + }) + if err != nil { + return err + } + return nil + }) +} + +``` + +{{% /choosable %}} + +{{% choosable language csharp %}} + +```csharp +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; +using Pulumi; +using Aws = Pulumi.Aws; + +return await Deployment.RunAsync(() => +{ + var myBucket = new Aws.S3.Bucket("my-bucket", new() + { + BucketName = "my-bucket-26224916", + Policy = JsonSerializer.Serialize(new Dictionary + { + ["Version"] = "2012-10-17", + ["Id"] = "PutObjPolicy", + ["Statement"] = new Dictionary + { + ["Sid"] = "DenyObjectsThatAreNotSSEKMS", + ["Principal"] = "*", + ["Effect"] = "Deny", + ["Action"] = "s3:PutObject", + ["Resource"] = "arn:aws:s3:::my-bucket-26224916/*", + ["Condition"] = new Dictionary + { + ["Null"] = new Dictionary + { + ["s3:x-amz-server-side-encryption-aws-kms-key-id"] = "true", + }, + }, + }, + }), + }); + +}); + + +``` + +{{% /choosable %}} + +{{% choosable language java %}} + +```java +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 static com.pulumi.codegen.internal.Serialization.*; +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 myBucket = new Bucket("myBucket", BucketArgs.builder() + .bucket("my-bucket-26224916") + .policy(serializeJson( + jsonObject( + jsonProperty("Version", "2012-10-17"), + jsonProperty("Id", "PutObjPolicy"), + jsonProperty("Statement", jsonObject( + jsonProperty("Sid", "DenyObjectsThatAreNotSSEKMS"), + jsonProperty("Principal", "*"), + jsonProperty("Effect", "Deny"), + jsonProperty("Action", "s3:PutObject"), + jsonProperty("Resource", "arn:aws:s3:::my-bucket-26224916/*"), + jsonProperty("Condition", jsonObject( + jsonProperty("Null", jsonObject( + jsonProperty("s3:x-amz-server-side-encryption-aws-kms-key-id", "true") + )) + )) + )) + ))) + .build()); + + } +} + +``` + +{{% /choosable %}} + +{{% choosable language yaml %}} ```yaml name: example @@ -57,8 +263,13 @@ resources: "Null": s3:x-amz-server-side-encryption-aws-kms-key-id: "true" ``` + {{% /choosable %}} +{{< /chooser >}} + + + Use the `aws.s3.BucketPolicy` resource: ``` typescript From 839b9f193c09da0cd02b9b2cbc8ab87169b4bad7 Mon Sep 17 00:00:00 2001 From: Anton Tayanovskyy Date: Tue, 17 Sep 2024 15:13:40 -0400 Subject: [PATCH 06/20] Add chooser for example #2 --- .../aws/how-to-guides/bucketv2-migration.md | 350 +++++++++++++++++- 1 file changed, 334 insertions(+), 16 deletions(-) diff --git a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md index 60cfae3b0e..b912884843 100644 --- a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md +++ b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md @@ -270,6 +270,7 @@ resources: + Use the `aws.s3.BucketPolicy` resource: ``` typescript @@ -305,33 +306,350 @@ As a bonus, the policy can now more easily refer to the concrete name of the buc To specify [server-side encryption configuration](http://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html), instead of: -``` typescript -new aws.s3.Bucket("my-bucket", { - serverSideEncryptionConfiguration: { +{{< chooser language "typescript,python,go,csharp,java,yaml" >}} + +{{% choosable language typescript %}} + +```typescript +import * as pulumi from "@pulumi/pulumi"; +import * as aws from "@pulumi/aws"; + +const myBucket = new aws.s3.Bucket("my-bucket", {serverSideEncryptionConfiguration: { rule: { - applyServerSideEncryptionByDefault: { - sseAlgorithm: "aws:kms", - }, + applyServerSideEncryptionByDefault: { + sseAlgorithm: "aws:kms", + }, }, - }, +}}); + +``` + +{{% /choosable %}} + +{{% choosable language python %}} + +```python +import pulumi +import pulumi_aws as aws + +my_bucket = aws.s3.Bucket("my-bucket", server_side_encryption_configuration={ + "rule": { + "apply_server_side_encryption_by_default": { + "sse_algorithm": "aws:kms", + }, + }, +}) + +``` + +{{% /choosable %}} + +{{% choosable language go %}} + +```go +package main + +import ( + "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + _, err := s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{ + ServerSideEncryptionConfiguration: &s3.BucketServerSideEncryptionConfigurationArgs{ + Rule: &s3.BucketServerSideEncryptionConfigurationRuleArgs{ + ApplyServerSideEncryptionByDefault: &s3.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs{ + SseAlgorithm: pulumi.String("aws:kms"), + }, + }, + }, + }) + if err != nil { + return err + } + return nil + }) +} + +``` + +{{% /choosable %}} + +{{% choosable language csharp %}} + +```csharp +using System.Collections.Generic; +using System.Linq; +using Pulumi; +using Aws = Pulumi.Aws; + +return await Deployment.RunAsync(() => +{ + var myBucket = new Aws.S3.Bucket("my-bucket", new() + { + ServerSideEncryptionConfiguration = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationArgs + { + Rule = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationRuleArgs + { + ApplyServerSideEncryptionByDefault = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs + { + SseAlgorithm = "aws:kms", + }, + }, + }, + }); + }); + + +``` + +{{% /choosable %}} + +{{% choosable language java %}} + +```java +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.inputs.BucketServerSideEncryptionConfigurationArgs; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationRuleArgs; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs; +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 myBucket = new Bucket("myBucket", BucketArgs.builder() + .serverSideEncryptionConfiguration(BucketServerSideEncryptionConfigurationArgs.builder() + .rule(BucketServerSideEncryptionConfigurationRuleArgs.builder() + .applyServerSideEncryptionByDefault(BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs.builder() + .sseAlgorithm("aws:kms") + .build()) + .build()) + .build()) + .build()); + + } +} + +``` + +{{% /choosable %}} + +{{% choosable language yaml %}} + +```yaml +name: example +runtime: yaml +resources: + my-bucket: + type: aws:s3:Bucket + properties: + serverSideEncryptionConfiguration: + rule: + applyServerSideEncryptionByDefault: + sseAlgorithm: "aws:kms" ``` +{{% /choosable %}} + +{{< /chooser >}} + + Use the `aws.s3.BucketServerSideEncryptionConfiguration` resource: -``` typescript -const myBucket = new aws.s3.BucketV2("my-new-bucket", {}); +{{< chooser language "typescript,python,go,csharp,java,yaml" >}} + +{{% choosable language typescript %}} + +```typescript +import * as pulumi from "@pulumi/pulumi"; +import * as aws from "@pulumi/aws"; + +const myBucket = new aws.s3.BucketV2("my-bucket", {}); +const myBucketSseConfig = new aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-sse-config", { + bucket: myBucket.bucket, + rules: [{ + applyServerSideEncryptionByDefault: { + sseAlgorithm: "aws:kms", + }, + }], +}); + +``` + +{{% /choosable %}} + +{{% choosable language python %}} + +```python +import pulumi +import pulumi_aws as aws + +my_bucket = aws.s3.BucketV2("my-bucket") +my_bucket_sse_config = aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-sse-config", + bucket=my_bucket.bucket, + rules=[{ + "apply_server_side_encryption_by_default": { + "sse_algorithm": "aws:kms", + }, + }]) + +``` + +{{% /choosable %}} + +{{% choosable language go %}} + +```go +package main + +import ( + "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + myBucket, err := s3.NewBucketV2(ctx, "my-bucket", nil) + if err != nil { + return err + } + _, err = s3.NewBucketServerSideEncryptionConfigurationV2(ctx, "my-bucket-sse-config", &s3.BucketServerSideEncryptionConfigurationV2Args{ + Bucket: myBucket.Bucket, + Rules: s3.BucketServerSideEncryptionConfigurationV2RuleArray{ + &s3.BucketServerSideEncryptionConfigurationV2RuleArgs{ + ApplyServerSideEncryptionByDefault: &s3.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs{ + SseAlgorithm: pulumi.String("aws:kms"), + }, + }, + }, + }) + if err != nil { + return err + } + return nil + }) +} + +``` + +{{% /choosable %}} + +{{% choosable language csharp %}} + +```csharp +using System.Collections.Generic; +using System.Linq; +using Pulumi; +using Aws = Pulumi.Aws; + +return await Deployment.RunAsync(() => +{ + var myBucket = new Aws.S3.BucketV2("my-bucket"); + + var myBucketSseConfig = new Aws.S3.BucketServerSideEncryptionConfigurationV2("my-bucket-sse-config", new() + { + Bucket = myBucket.Bucket, + Rules = new[] + { + new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationV2RuleArgs + { + ApplyServerSideEncryptionByDefault = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs + { + SseAlgorithm = "aws:kms", + }, + }, + }, + }); -new aws.s3.BucketServerSideEncryptionConfigurationV2("my-new-bucket-sse-config", { - bucket: myBucket.bucket, - rules: [{ - applyServerSideEncryptionByDefault: { - sseAlgorithm: "aws:kms" - }, - }], }); + + +``` + +{{% /choosable %}} + +{{% choosable language java %}} + +```java +package generated_program; + +import com.pulumi.Context; +import com.pulumi.Pulumi; +import com.pulumi.core.Output; +import com.pulumi.aws.s3.BucketV2; +import com.pulumi.aws.s3.BucketServerSideEncryptionConfigurationV2; +import com.pulumi.aws.s3.BucketServerSideEncryptionConfigurationV2Args; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationV2RuleArgs; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs; +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 myBucket = new BucketV2("myBucket"); + + var myBucketSseConfig = new BucketServerSideEncryptionConfigurationV2("myBucketSseConfig", BucketServerSideEncryptionConfigurationV2Args.builder() + .bucket(myBucket.bucket()) + .rules(BucketServerSideEncryptionConfigurationV2RuleArgs.builder() + .applyServerSideEncryptionByDefault(BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs.builder() + .sseAlgorithm("aws:kms") + .build()) + .build()) + .build()); + + } +} + ``` +{{% /choosable %}} + +{{% choosable language yaml %}} + +```yaml +name: example +runtime: yaml +resources: + my-bucket: + type: aws:s3:BucketV2 + my-bucket-sse-config: + type: aws:s3:BucketServerSideEncryptionConfigurationV2 + properties: + bucket: ${my-bucket.bucket} + rules: + - applyServerSideEncryptionByDefault: + sseAlgorithm: "aws:kms" +``` + +{{% /choosable %}} + +{{< /chooser >}} + + ### acceleration input To enable acceleration, instead of: From ce8e8d535941f01357000c02eddd4561061f3e8e Mon Sep 17 00:00:00 2001 From: Anton Tayanovskyy Date: Tue, 17 Sep 2024 15:20:28 -0400 Subject: [PATCH 07/20] More choosers --- .../aws/how-to-guides/bucketv2-migration.md | 274 ++++++++++++++++-- 1 file changed, 251 insertions(+), 23 deletions(-) diff --git a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md index b912884843..36a9df9d25 100644 --- a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md +++ b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md @@ -269,36 +269,262 @@ resources: {{< /chooser >}} +Use the `aws.s3.BucketPolicy` resource: +{{< chooser language "typescript,python,go,csharp,java,yaml" >}} -Use the `aws.s3.BucketPolicy` resource: +{{% choosable language typescript %}} -``` typescript -const myBucket = new aws.s3.BucketV2("my-new-bucket", {}); +```typescript +import * as pulumi from "@pulumi/pulumi"; +import * as aws from "@pulumi/aws"; -new aws.s3.BucketPolicy("my-bucket-policy", { - bucket: myBucket.bucket, - policy: myBucket.bucket.apply(bucket => JSON.stringify({ - "Version": "2012-10-17", - "Id": "PutObjPolicy", - "Statement": [ - { - "Sid": "DenyObjectsThatAreNotSSEKMS", - "Principal": "*", - "Effect": "Deny", - "Action": "s3:PutObject", - "Resource": `arn:aws:s3:::${bucket}/*`, - "Condition": { - "Null": { - "s3:x-amz-server-side-encryption-aws-kms-key-id": "true" - } - } - } - ] - })), +const myBucket = new aws.s3.BucketV2("my-bucket", {}); +const myBucketPolicy = new aws.s3.BucketPolicy("my-bucket-policy", { + bucket: "my-bucket-26224916", + policy: pulumi.jsonStringify({ + Version: "2012-10-17", + Id: "PutObjPolicy", + Statement: { + Sid: "DenyObjectsThatAreNotSSEKMS", + Principal: "*", + Effect: "Deny", + Action: "s3:PutObject", + Resource: pulumi.interpolate`arn:aws:s3:::${myBucket.bucket}/*`, + Condition: { + Null: { + "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", + }, + }, + }, + }), }); + +``` + +{{% /choosable %}} + +{{% choosable language python %}} + +```python +import pulumi +import json +import pulumi_aws as aws + +my_bucket = aws.s3.BucketV2("my-bucket") +my_bucket_policy = aws.s3.BucketPolicy("my-bucket-policy", + bucket="my-bucket-26224916", + policy=pulumi.Output.json_dumps({ + "Version": "2012-10-17", + "Id": "PutObjPolicy", + "Statement": { + "Sid": "DenyObjectsThatAreNotSSEKMS", + "Principal": "*", + "Effect": "Deny", + "Action": "s3:PutObject", + "Resource": my_bucket.bucket.apply(lambda bucket: f"arn:aws:s3:::{bucket}/*"), + "Condition": { + "Null": { + "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", + }, + }, + }, + })) + ``` +{{% /choosable %}} + +{{% choosable language go %}} + +```go +package main + +import ( + "encoding/json" + "fmt" + + "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/iam" + "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + myBucket, err := s3.NewBucketV2(ctx, "my-bucket", nil) + if err != nil { + return err + } + _, err = s3.NewBucketPolicy(ctx, "my-bucket-policy", &s3.BucketPolicyArgs{ + Bucket: pulumi.String("my-bucket-26224916"), + Policy: myBucket.Bucket.ApplyT(func(bucket string) (pulumi.String, error) { + var _zero pulumi.String + tmpJSON0, err := json.Marshal(map[string]interface{}{ + "Version": "2012-10-17", + "Id": "PutObjPolicy", + "Statement": map[string]interface{}{ + "Sid": "DenyObjectsThatAreNotSSEKMS", + "Principal": "*", + "Effect": "Deny", + "Action": "s3:PutObject", + "Resource": fmt.Sprintf("arn:aws:s3:::%v/*", bucket), + "Condition": map[string]interface{}{ + "Null": map[string]interface{}{ + "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", + }, + }, + }, + }) + if err != nil { + return _zero, err + } + json0 := string(tmpJSON0) + return pulumi.String(json0), nil + }).(pulumi.StringOutput), + }) + if err != nil { + return err + } + return nil + }) +} + +``` + +{{% /choosable %}} + +{{% choosable language csharp %}} + +```csharp +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; +using Pulumi; +using Aws = Pulumi.Aws; + +return await Deployment.RunAsync(() => +{ + var myBucket = new Aws.S3.BucketV2("my-bucket"); + + var myBucketPolicy = new Aws.S3.BucketPolicy("my-bucket-policy", new() + { + Bucket = "my-bucket-26224916", + Policy = Output.JsonSerialize(Output.Create(new Dictionary + { + ["Version"] = "2012-10-17", + ["Id"] = "PutObjPolicy", + ["Statement"] = new Dictionary + { + ["Sid"] = "DenyObjectsThatAreNotSSEKMS", + ["Principal"] = "*", + ["Effect"] = "Deny", + ["Action"] = "s3:PutObject", + ["Resource"] = myBucket.Bucket.Apply(bucket => $"arn:aws:s3:::{bucket}/*"), + ["Condition"] = new Dictionary + { + ["Null"] = new Dictionary + { + ["s3:x-amz-server-side-encryption-aws-kms-key-id"] = "true", + }, + }, + }, + })), + }); + +}); + + +``` + +{{% /choosable %}} + +{{% choosable language java %}} + +```java +package generated_program; + +import com.pulumi.Context; +import com.pulumi.Pulumi; +import com.pulumi.core.Output; +import com.pulumi.aws.s3.BucketV2; +import com.pulumi.aws.s3.BucketPolicy; +import com.pulumi.aws.s3.BucketPolicyArgs; +import static com.pulumi.codegen.internal.Serialization.*; +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 myBucket = new BucketV2("myBucket"); + + var myBucketPolicy = new BucketPolicy("myBucketPolicy", BucketPolicyArgs.builder() + .bucket("my-bucket-26224916") + .policy(myBucket.bucket().applyValue(bucket -> serializeJson( + jsonObject( + jsonProperty("Version", "2012-10-17"), + jsonProperty("Id", "PutObjPolicy"), + jsonProperty("Statement", jsonObject( + jsonProperty("Sid", "DenyObjectsThatAreNotSSEKMS"), + jsonProperty("Principal", "*"), + jsonProperty("Effect", "Deny"), + jsonProperty("Action", "s3:PutObject"), + jsonProperty("Resource", String.format("arn:aws:s3:::%s/*", bucket)), + jsonProperty("Condition", jsonObject( + jsonProperty("Null", jsonObject( + jsonProperty("s3:x-amz-server-side-encryption-aws-kms-key-id", "true") + )) + )) + )) + )))) + .build()); + + } +} + +``` + +{{% /choosable %}} + +{{% choosable language yaml %}} + +```yaml +name: example +runtime: yaml +resources: + my-bucket: + type: aws:s3:BucketV2 + my-bucket-policy: + type: aws:s3:BucketPolicy + properties: + bucket: "my-bucket-26224916" + policy: + fn::toJSON: + Version: 2012-10-17 + Id: PutObjPolicy + Statement: + Sid: DenyObjectsThatAreNotSSEKMS + Principal: "*" + Effect: Deny + Action: s3:PutObject + Resource: "arn:aws:s3:::${my-bucket.bucket}/*" + Condition: + "Null": + s3:x-amz-server-side-encryption-aws-kms-key-id: "true" +``` + +{{% /choosable %}} + +{{< /chooser >}} + + As a bonus, the policy can now more easily refer to the concrete name of the bucket. ### serverSideEncryptionConfiguration input @@ -470,6 +696,7 @@ resources: {{< /chooser >}} + Use the `aws.s3.BucketServerSideEncryptionConfiguration` resource: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -650,6 +877,7 @@ resources: {{< /chooser >}} + ### acceleration input To enable acceleration, instead of: From 5e01712f8c304271d931c581038e78e70fe1ad56 Mon Sep 17 00:00:00 2001 From: Anton Tayanovskyy Date: Tue, 17 Sep 2024 15:24:35 -0400 Subject: [PATCH 08/20] Choosers for more examples --- .../aws/how-to-guides/bucketv2-migration.md | 260 +++++++++++++++++- 1 file changed, 251 insertions(+), 9 deletions(-) diff --git a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md index 36a9df9d25..0b30cb19a8 100644 --- a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md +++ b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md @@ -269,6 +269,7 @@ resources: {{< /chooser >}} + Use the `aws.s3.BucketPolicy` resource: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -525,6 +526,7 @@ resources: {{< /chooser >}} + As a bonus, the policy can now more easily refer to the concrete name of the bucket. ### serverSideEncryptionConfiguration input @@ -697,6 +699,7 @@ resources: + Use the `aws.s3.BucketServerSideEncryptionConfiguration` resource: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -877,28 +880,267 @@ resources: {{< /chooser >}} - ### acceleration input To enable acceleration, instead of: -``` typescript -new aws.s3.Bucket("my-bucket", { - accelerationStatus: "Enabled", +{{< chooser language "typescript,python,go,csharp,java,yaml" >}} + +{{% choosable language typescript %}} + +```typescript +import * as pulumi from "@pulumi/pulumi"; +import * as aws from "@pulumi/aws"; + +const myBucket = new aws.s3.Bucket("my-bucket", {accelerationStatus: "Enabled"}); + +``` + +{{% /choosable %}} + +{{% choosable language python %}} + +```python +import pulumi +import pulumi_aws as aws + +my_bucket = aws.s3.Bucket("my-bucket", acceleration_status="Enabled") + +``` + +{{% /choosable %}} + +{{% choosable language go %}} + +```go +package main + +import ( + "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + _, err := s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{ + AccelerationStatus: pulumi.String("Enabled"), + }) + if err != nil { + return err + } + return nil + }) +} + +``` + +{{% /choosable %}} + +{{% choosable language csharp %}} + +```csharp +using System.Collections.Generic; +using System.Linq; +using Pulumi; +using Aws = Pulumi.Aws; + +return await Deployment.RunAsync(() => +{ + var myBucket = new Aws.S3.Bucket("my-bucket", new() + { + AccelerationStatus = "Enabled", + }); + }); + + ``` +{{% /choosable %}} + +{{% choosable language java %}} + +```java +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 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 myBucket = new Bucket("myBucket", BucketArgs.builder() + .accelerationStatus("Enabled") + .build()); + + } +} + +``` + +{{% /choosable %}} + +{{% choosable language yaml %}} + +```yaml +name: example +runtime: yaml +resources: + my-bucket: + type: aws:s3:Bucket + properties: + accelerationStatus: Enabled +``` + +{{% /choosable %}} + +{{< /chooser >}} + + Use the `aws.s3.BucketAccelerationConfiguration` resource: -``` typescript -const myBucket = new aws.s3.BucketV2("my-new-bucket", {}); +{{< chooser language "typescript,python,go,csharp,java,yaml" >}} + +{{% choosable language typescript %}} + +```typescript +import * as pulumi from "@pulumi/pulumi"; +import * as aws from "@pulumi/aws"; + +const myBucket = new aws.s3.BucketV2("my-bucket", {accelerationStatus: "Enabled"}); + +``` + +{{% /choosable %}} + +{{% choosable language python %}} + +```python +import pulumi +import pulumi_aws as aws + +my_bucket = aws.s3.BucketV2("my-bucket", acceleration_status="Enabled") + +``` + +{{% /choosable %}} + +{{% choosable language go %}} + +```go +package main + +import ( + "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + _, err := s3.NewBucketV2(ctx, "my-bucket", &s3.BucketV2Args{ + AccelerationStatus: pulumi.String("Enabled"), + }) + if err != nil { + return err + } + return nil + }) +} + +``` + +{{% /choosable %}} + +{{% choosable language csharp %}} + +```csharp +using System.Collections.Generic; +using System.Linq; +using Pulumi; +using Aws = Pulumi.Aws; + +return await Deployment.RunAsync(() => +{ + var myBucket = new Aws.S3.BucketV2("my-bucket", new() + { + AccelerationStatus = "Enabled", + }); -new aws.s3.BucketAccelerateConfigurationV2("my-bucket-acceleration", { - bucket: myBucket.bucket, - status: "Enabled", }); + + ``` +{{% /choosable %}} + +{{% choosable language java %}} + +```java +package generated_program; + +import com.pulumi.Context; +import com.pulumi.Pulumi; +import com.pulumi.core.Output; +import com.pulumi.aws.s3.BucketV2; +import com.pulumi.aws.s3.BucketV2Args; +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 myBucket = new BucketV2("myBucket", BucketV2Args.builder() + .accelerationStatus("Enabled") + .build()); + + } +} + +``` + +{{% /choosable %}} + +{{% choosable language yaml %}} + +```yaml +name: example +runtime: yaml +resources: + my-bucket: + type: aws:s3:BucketV2 + properties: + accelerationStatus: Enabled + my-bucket-acceleration: + type: aws:s3:BucketAccelerationConfigurationV2 + properties: + bucket: ${my-bucket.bucket} + accelerationStatus: Enabled +``` + +{{% /choosable %}} + +{{< /chooser >}} + + ### corsRules input To configure [Cross-Origin Resource Sharing](https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html), From 26f18241066e812a9fac6ceb76ae45a44dfbb8aa Mon Sep 17 00:00:00 2001 From: Anton Tayanovskyy Date: Tue, 17 Sep 2024 15:40:33 -0400 Subject: [PATCH 09/20] The rest of the choosers --- .../aws/how-to-guides/bucketv2-migration.md | 858 ++++++++++++++++-- 1 file changed, 793 insertions(+), 65 deletions(-) diff --git a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md index 0b30cb19a8..b630c51c99 100644 --- a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md +++ b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md @@ -270,6 +270,7 @@ resources: + Use the `aws.s3.BucketPolicy` resource: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -527,6 +528,7 @@ resources: + As a bonus, the policy can now more easily refer to the concrete name of the bucket. ### serverSideEncryptionConfiguration input @@ -700,6 +702,7 @@ resources: + Use the `aws.s3.BucketServerSideEncryptionConfiguration` resource: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -880,6 +883,7 @@ resources: {{< /chooser >}} + ### acceleration input To enable acceleration, instead of: @@ -1009,6 +1013,7 @@ resources: {{< /chooser >}} + Use the `aws.s3.BucketAccelerationConfiguration` resource: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -1141,96 +1146,819 @@ resources: {{< /chooser >}} + ### corsRules input To configure [Cross-Origin Resource Sharing](https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html), instead of: -``` typescript -new aws.s3.Bucket("my-bucket", { - corsRules: [ +{{< chooser language "typescript,python,go,csharp,java,yaml" >}} + +{{% choosable language typescript %}} + +```typescript +import * as pulumi from "@pulumi/pulumi"; +import * as aws from "@pulumi/aws"; + +const myBucket = new aws.s3.Bucket("my-bucket", {corsRules: [{ + allowedHeaders: ["*"], + allowedMethods: ["GET"], + allowedOrigins: ["*"], + exposeHeaders: ["ETag"], + maxAgeSeconds: 3000, +}]}); + +``` + +{{% /choosable %}} + +{{% choosable language python %}} + +```python +import pulumi +import pulumi_aws as aws + +my_bucket = aws.s3.Bucket("my-bucket", cors_rules=[{ + "allowed_headers": ["*"], + "allowed_methods": ["GET"], + "allowed_origins": ["*"], + "expose_headers": ["ETag"], + "max_age_seconds": 3000, +}]) + +``` + +{{% /choosable %}} + +{{% choosable language go %}} + +```go +package main + +import ( + "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + _, err := s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{ + CorsRules: s3.BucketCorsRuleArray{ + &s3.BucketCorsRuleArgs{ + AllowedHeaders: pulumi.StringArray{ + pulumi.String("*"), + }, + AllowedMethods: pulumi.StringArray{ + pulumi.String("GET"), + }, + AllowedOrigins: pulumi.StringArray{ + pulumi.String("*"), + }, + ExposeHeaders: pulumi.StringArray{ + pulumi.String("ETag"), + }, + MaxAgeSeconds: pulumi.Int(3000), + }, + }, + }) + if err != nil { + return err + } + return nil + }) +} + +``` + +{{% /choosable %}} + +{{% choosable language csharp %}} + +```csharp +using System.Collections.Generic; +using System.Linq; +using Pulumi; +using Aws = Pulumi.Aws; + +return await Deployment.RunAsync(() => +{ + var myBucket = new Aws.S3.Bucket("my-bucket", new() { - allowedHeaders: ["*"], - allowedMethods: ["GET"], - allowedOrigins: ["*"], - exposeHeaders: ["ETag"], - maxAgeSeconds: 3000, - }, - ], + CorsRules = new[] + { + new Aws.S3.Inputs.BucketCorsRuleArgs + { + AllowedHeaders = new[] + { + "*", + }, + AllowedMethods = new[] + { + "GET", + }, + AllowedOrigins = new[] + { + "*", + }, + ExposeHeaders = new[] + { + "ETag", + }, + MaxAgeSeconds = 3000, + }, + }, + }); + }); + + +``` + +{{% /choosable %}} + +{{% choosable language java %}} + +```java +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.inputs.BucketCorsRuleArgs; +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 myBucket = new Bucket("myBucket", BucketArgs.builder() + .corsRules(BucketCorsRuleArgs.builder() + .allowedHeaders("*") + .allowedMethods("GET") + .allowedOrigins("*") + .exposeHeaders("ETag") + .maxAgeSeconds(3000) + .build()) + .build()); + + } +} + +``` + +{{% /choosable %}} + +{{% choosable language yaml %}} + +```yaml +name: example +runtime: yaml +resources: + my-bucket: + type: aws:s3:Bucket + properties: + corsRules: + - allowedHeaders: + - "*" + allowedMethods: + - "GET" + allowedOrigins: + - "*" + exposeHeaders: + - "ETag" + maxAgeSeconds: 3000 ``` +{{% /choosable %}} + +{{< /chooser >}} + + Use the `aws.s3.BucketCorsConfiguration` resource: -``` typescript -const myBucket = new aws.s3.BucketV2("my-new-bucket", {}); +{{< chooser language "typescript,python,go,csharp,java,yaml" >}} + +{{% choosable language typescript %}} + +```typescript +import * as pulumi from "@pulumi/pulumi"; +import * as aws from "@pulumi/aws"; + +const myBucket = new aws.s3.BucketV2("my-bucket", {}); -new aws.s3.BucketCorsConfigurationV2("my-bucket-cors", { - bucket: myBucket.bucket, - corsRules: [ - { - allowedHeaders: ["*"], - allowedMethods: ["GET"], - allowedOrigins: ["*"], - exposeHeaders: ["ETag"], - maxAgeSeconds: 3000, - }, - ] -}); ``` -### acl and grants inputs +{{% /choosable %}} -The `aws.s3.BucketAcl` resource is now required to configure either -[canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl) -or [ACL policy grant](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#sample-acl), -and it replaces the use of `acl` and `grants` inputs. To illustrate migrating the uses of `grants`, instead of: +{{% choosable language python %}} -``` typescript -const currentUser = aws.s3.getCanonicalUserIdOutput({}); +```python +import pulumi +import pulumi_aws as aws + +my_bucket = aws.s3.BucketV2("my-bucket") -new aws.s3.Bucket("my-bucket", { - grants: [ - { - permissions: ["READ"], - type: "CanonicalUser", - id: currentUser.id, - }, - ], -}); ``` -Use the `aws.s3.BucketAcl` resource like this: +{{% /choosable %}} -``` typescript -const myBucket = new aws.s3.BucketV2("my-new-bucket", {}); +{{% choosable language go %}} -const myBucketOwnershipControls = new aws.s3.BucketOwnershipControls("my-new-bucket-oc", { - bucket: myBucket.id, - rule: { - objectOwnership: "BucketOwnerPreferred", - }, -}); +```go +package main + +import ( + "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + _, err := s3.NewBucketV2(ctx, "my-bucket", nil) + if err != nil { + return err + } + return nil + }) +} + +``` + +{{% /choosable %}} + +{{% choosable language csharp %}} + +```csharp +using System.Collections.Generic; +using System.Linq; +using Pulumi; +using Aws = Pulumi.Aws; + +return await Deployment.RunAsync(() => +{ + var myBucket = new Aws.S3.BucketV2("my-bucket"); -new aws.s3.BucketAclV2("grant", { - bucket: myBucket.bucket, - accessControlPolicy: { - owner: {id: currentUser.id}, - grants: [ - { - permission: "READ", - grantee: { - type: "CanonicalUser", - id: currentUser.id, - }, - }, - ], - }, -}, { - dependsOn: [myBucketOwnershipControls] }); + + +``` + +{{% /choosable %}} + +{{% choosable language java %}} + +```java +package generated_program; + +import com.pulumi.Context; +import com.pulumi.Pulumi; +import com.pulumi.core.Output; +import com.pulumi.aws.s3.BucketV2; +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 myBucket = new BucketV2("myBucket"); + + } +} + ``` +{{% /choosable %}} + +{{% choosable language yaml %}} + +```yaml +name: example +runtime: yaml +resources: + my-bucket: + type: aws:s3:BucketV2 + my-bucket-cors: + type: aws:s3:BucketCorsConfiguration + properties: + bucket: ${my-bucket.bucket} + corsRules: + - allowedHeaders: + - "*" + allowedMethods: + - "GET" + allowedOrigins: + - "*" + exposeHeaders: + - "ETag" + maxAgeSeconds: 3000 +``` + +{{% /choosable %}} + +{{< /chooser >}} + + +### acl and grants inputs + +The `aws.s3.BucketAcl` resource is now required to configure either +[canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl) +or [ACL policy grant](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#sample-acl), +and it replaces the use of `acl` and `grants` inputs. To illustrate migrating the uses of `grants`, instead of: + +{{< chooser language "typescript,python,go,csharp,java,yaml" >}} + +{{% choosable language typescript %}} + +```typescript +import * as pulumi from "@pulumi/pulumi"; +import * as aws from "@pulumi/aws"; + +const currentUser = aws.s3.getCanonicalUserIdOutput({}); +const myBucket = new aws.s3.Bucket("my-bucket", {grants: [{ + permissions: ["READ"], + type: "CanonicalUser", + id: currentUser.apply(currentUser => currentUser.id), +}]}); + +``` + +{{% /choosable %}} + +{{% choosable language python %}} + +```python +import pulumi +import pulumi_aws as aws + +current_user = aws.s3.get_canonical_user_id_output() +my_bucket = aws.s3.Bucket("my-bucket", grants=[{ + "permissions": ["READ"], + "type": "CanonicalUser", + "id": current_user.id, +}]) + +``` + +{{% /choosable %}} + +{{% choosable language go %}} + +```go +package main + +import ( + "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + currentUser, err := s3.GetCanonicalUserId(ctx, nil, nil) + if err != nil { + return err + } + _, err = s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{ + Grants: s3.BucketGrantArray{ + &s3.BucketGrantArgs{ + Permissions: pulumi.StringArray{ + pulumi.String("READ"), + }, + Type: pulumi.String("CanonicalUser"), + Id: pulumi.String(currentUser.Id), + }, + }, + }) + if err != nil { + return err + } + return nil + }) +} + +``` + +{{% /choosable %}} + +{{% choosable language csharp %}} + +```csharp +using System.Collections.Generic; +using System.Linq; +using Pulumi; +using Aws = Pulumi.Aws; + +return await Deployment.RunAsync(() => +{ + var currentUser = Aws.S3.GetCanonicalUserId.Invoke(); + + var myBucket = new Aws.S3.Bucket("my-bucket", new() + { + Grants = new[] + { + new Aws.S3.Inputs.BucketGrantArgs + { + Permissions = new[] + { + "READ", + }, + Type = "CanonicalUser", + Id = currentUser.Apply(getCanonicalUserIdResult => getCanonicalUserIdResult.Id), + }, + }, + }); + +}); + + +``` + +{{% /choosable %}} + +{{% choosable language java %}} + +```java +package generated_program; + +import com.pulumi.Context; +import com.pulumi.Pulumi; +import com.pulumi.core.Output; +import com.pulumi.aws.s3.S3Functions; +import com.pulumi.aws.s3.Bucket; +import com.pulumi.aws.s3.BucketArgs; +import com.pulumi.aws.s3.inputs.BucketGrantArgs; +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 currentUser = S3Functions.getCanonicalUserId(); + + var myBucket = new Bucket("myBucket", BucketArgs.builder() + .grants(BucketGrantArgs.builder() + .permissions("READ") + .type("CanonicalUser") + .id(currentUser.applyValue(getCanonicalUserIdResult -> getCanonicalUserIdResult.id())) + .build()) + .build()); + + } +} + +``` + +{{% /choosable %}} + +{{% choosable language yaml %}} + +```yaml +name: example +runtime: yaml +variables: + currentUser: + fn::invoke: + function: aws:s3:getCanonicalUserId + arguments: {} +resources: + my-bucket: + type: aws:s3:Bucket + properties: + grants: + - permissions: + - "READ" + type: "CanonicalUser" + id: ${currentUser.id} +``` + +{{% /choosable %}} + +{{< /chooser >}} + + +Use the `aws.s3.BucketAcl` resource like this: + +{{< chooser language "typescript,python,go,csharp,java,yaml" >}} + +{{% choosable language typescript %}} + +```typescript +import * as pulumi from "@pulumi/pulumi"; +import * as aws from "@pulumi/aws"; + +const currentUser = aws.s3.getCanonicalUserIdOutput({}); +const myBucket = new aws.s3.BucketV2("my-bucket", {}); +const myBucketOwnership = new aws.s3.BucketOwnershipControls("my-bucket-ownership", { + bucket: myBucket.id, + rule: { + objectOwnership: "BucketOwnerPreferred", + }, +}); +const myBucketAcl = new aws.s3.BucketAclV2("my-bucket-acl", { + bucket: myBucket.bucket, + accessControlPolicy: { + owner: { + id: currentUser.apply(currentUser => currentUser.id), + }, + grants: [{ + permission: "READ", + grantee: { + type: "CanonicalUser", + id: currentUser.apply(currentUser => currentUser.id), + }, + }], + }, +}, { + dependsOn: [myBucketOwnership], +}); + +``` + +{{% /choosable %}} + +{{% choosable language python %}} + +```python +import pulumi +import pulumi_aws as aws + +current_user = aws.s3.get_canonical_user_id_output() +my_bucket = aws.s3.BucketV2("my-bucket") +my_bucket_ownership = aws.s3.BucketOwnershipControls("my-bucket-ownership", + bucket=my_bucket.id, + rule={ + "object_ownership": "BucketOwnerPreferred", + }) +my_bucket_acl = aws.s3.BucketAclV2("my-bucket-acl", + bucket=my_bucket.bucket, + access_control_policy={ + "owner": { + "id": current_user.id, + }, + "grants": [{ + "permission": "READ", + "grantee": { + "type": "CanonicalUser", + "id": current_user.id, + }, + }], + }, + opts = pulumi.ResourceOptions(depends_on=[my_bucket_ownership])) + +``` + +{{% /choosable %}} + +{{% choosable language go %}} + +```go +package main + +import ( + "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + currentUser, err := s3.GetCanonicalUserId(ctx, nil, nil) + if err != nil { + return err + } + myBucket, err := s3.NewBucketV2(ctx, "my-bucket", nil) + if err != nil { + return err + } + myBucketOwnership, err := s3.NewBucketOwnershipControls(ctx, "my-bucket-ownership", &s3.BucketOwnershipControlsArgs{ + Bucket: myBucket.ID(), + Rule: &s3.BucketOwnershipControlsRuleArgs{ + ObjectOwnership: pulumi.String("BucketOwnerPreferred"), + }, + }) + if err != nil { + return err + } + _, err = s3.NewBucketAclV2(ctx, "my-bucket-acl", &s3.BucketAclV2Args{ + Bucket: myBucket.Bucket, + AccessControlPolicy: &s3.BucketAclV2AccessControlPolicyArgs{ + Owner: &s3.BucketAclV2AccessControlPolicyOwnerArgs{ + Id: pulumi.String(currentUser.Id), + }, + Grants: s3.BucketAclV2AccessControlPolicyGrantArray{ + &s3.BucketAclV2AccessControlPolicyGrantArgs{ + Permission: pulumi.String("READ"), + Grantee: &s3.BucketAclV2AccessControlPolicyGrantGranteeArgs{ + Type: pulumi.String("CanonicalUser"), + Id: pulumi.String(currentUser.Id), + }, + }, + }, + }, + }, pulumi.DependsOn([]pulumi.Resource{ + myBucketOwnership, + })) + if err != nil { + return err + } + return nil + }) +} + +``` + +{{% /choosable %}} + +{{% choosable language csharp %}} + +```csharp +using System.Collections.Generic; +using System.Linq; +using Pulumi; +using Aws = Pulumi.Aws; + +return await Deployment.RunAsync(() => +{ + var currentUser = Aws.S3.GetCanonicalUserId.Invoke(); + + var myBucket = new Aws.S3.BucketV2("my-bucket"); + + var myBucketOwnership = new Aws.S3.BucketOwnershipControls("my-bucket-ownership", new() + { + Bucket = myBucket.Id, + Rule = new Aws.S3.Inputs.BucketOwnershipControlsRuleArgs + { + ObjectOwnership = "BucketOwnerPreferred", + }, + }); + + var myBucketAcl = new Aws.S3.BucketAclV2("my-bucket-acl", new() + { + Bucket = myBucket.Bucket, + AccessControlPolicy = new Aws.S3.Inputs.BucketAclV2AccessControlPolicyArgs + { + Owner = new Aws.S3.Inputs.BucketAclV2AccessControlPolicyOwnerArgs + { + Id = currentUser.Apply(getCanonicalUserIdResult => getCanonicalUserIdResult.Id), + }, + Grants = new[] + { + new Aws.S3.Inputs.BucketAclV2AccessControlPolicyGrantArgs + { + Permission = "READ", + Grantee = new Aws.S3.Inputs.BucketAclV2AccessControlPolicyGrantGranteeArgs + { + Type = "CanonicalUser", + Id = currentUser.Apply(getCanonicalUserIdResult => getCanonicalUserIdResult.Id), + }, + }, + }, + }, + }, new CustomResourceOptions + { + DependsOn = + { + myBucketOwnership, + }, + }); + +}); + + +``` + +{{% /choosable %}} + +{{% choosable language java %}} + +```java +package generated_program; + +import com.pulumi.Context; +import com.pulumi.Pulumi; +import com.pulumi.core.Output; +import com.pulumi.aws.s3.S3Functions; +import com.pulumi.aws.s3.BucketV2; +import com.pulumi.aws.s3.BucketOwnershipControls; +import com.pulumi.aws.s3.BucketOwnershipControlsArgs; +import com.pulumi.aws.s3.inputs.BucketOwnershipControlsRuleArgs; +import com.pulumi.aws.s3.BucketAclV2; +import com.pulumi.aws.s3.BucketAclV2Args; +import com.pulumi.aws.s3.inputs.BucketAclV2AccessControlPolicyArgs; +import com.pulumi.aws.s3.inputs.BucketAclV2AccessControlPolicyOwnerArgs; +import com.pulumi.resources.CustomResourceOptions; +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 currentUser = S3Functions.getCanonicalUserId(); + + var myBucket = new BucketV2("myBucket"); + + var myBucketOwnership = new BucketOwnershipControls("myBucketOwnership", BucketOwnershipControlsArgs.builder() + .bucket(myBucket.id()) + .rule(BucketOwnershipControlsRuleArgs.builder() + .objectOwnership("BucketOwnerPreferred") + .build()) + .build()); + + var myBucketAcl = new BucketAclV2("myBucketAcl", BucketAclV2Args.builder() + .bucket(myBucket.bucket()) + .accessControlPolicy(BucketAclV2AccessControlPolicyArgs.builder() + .owner(BucketAclV2AccessControlPolicyOwnerArgs.builder() + .id(currentUser.applyValue(getCanonicalUserIdResult -> getCanonicalUserIdResult.id())) + .build()) + .grants(BucketAclV2AccessControlPolicyGrantArgs.builder() + .permission("READ") + .grantee(BucketAclV2AccessControlPolicyGrantGranteeArgs.builder() + .type("CanonicalUser") + .id(currentUser.applyValue(getCanonicalUserIdResult -> getCanonicalUserIdResult.id())) + .build()) + .build()) + .build()) + .build(), CustomResourceOptions.builder() + .dependsOn(myBucketOwnership) + .build()); + + } +} + +``` + +{{% /choosable %}} + +{{% choosable language yaml %}} + +```yaml +name: example +runtime: yaml +variables: + currentUser: + fn::invoke: + function: aws:s3:getCanonicalUserId + arguments: {} +resources: + my-bucket: + type: aws:s3:BucketV2 + my-bucket-ownership: + type: aws:s3:BucketOwnershipControls + properties: + bucket: ${my-bucket.id} + rule: + objectOwnership: "BucketOwnerPreferred" + my-bucket-acl: + type: aws:s3:BucketAclV2 + properties: + bucket: ${my-bucket.bucket} + accessControlPolicy: + owner: + id: ${currentUser.id} + grants: + - permission: "READ" + grantee: + type: "CanonicalUser" + id: ${currentUser.id} + options: + dependsOn: + - ${my-bucket-ownership} +``` + +{{% /choosable %}} + +{{< /chooser >}} + + + Note that `dependsOn` on `BucketOwnershipControls` is required for Pulumi to correctly order the operations for this infrastructure. Consult the documentation on `aws.s3.BucketAclV2` for more fully worked examples of configuring ACL. From 3c7388d1738d633e4e6e95f7ef3681151a64445a Mon Sep 17 00:00:00 2001 From: Anton Tayanovskyy Date: Tue, 17 Sep 2024 15:56:07 -0400 Subject: [PATCH 10/20] Final chooser --- .../aws/how-to-guides/bucketv2-migration.md | 390 +++++++++++++++++- 1 file changed, 370 insertions(+), 20 deletions(-) diff --git a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md index b630c51c99..856937b17b 100644 --- a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md +++ b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md @@ -271,6 +271,7 @@ resources: + Use the `aws.s3.BucketPolicy` resource: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -529,6 +530,7 @@ resources: + As a bonus, the policy can now more easily refer to the concrete name of the bucket. ### serverSideEncryptionConfiguration input @@ -703,6 +705,7 @@ resources: + Use the `aws.s3.BucketServerSideEncryptionConfiguration` resource: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -884,6 +887,7 @@ resources: + ### acceleration input To enable acceleration, instead of: @@ -1014,6 +1018,7 @@ resources: + Use the `aws.s3.BucketAccelerationConfiguration` resource: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -1147,6 +1152,7 @@ resources: + ### corsRules input To configure [Cross-Origin Resource Sharing](https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html), @@ -1343,6 +1349,7 @@ resources: {{< /chooser >}} + Use the `aws.s3.BucketCorsConfiguration` resource: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -1474,6 +1481,7 @@ resources: {{< /chooser >}} + ### acl and grants inputs The `aws.s3.BucketAcl` resource is now required to configure either @@ -1658,6 +1666,7 @@ resources: {{< /chooser >}} + Use the `aws.s3.BucketAcl` resource like this: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -1959,6 +1968,7 @@ resources: + Note that `dependsOn` on `BucketOwnershipControls` is required for Pulumi to correctly order the operations for this infrastructure. Consult the documentation on `aws.s3.BucketAclV2` for more fully worked examples of configuring ACL. @@ -2005,20 +2015,170 @@ involves the following steps: Consider a concrete example, suppose you have provisioned a bucket with a `serverSideEncryptionConfiguration` as follows: +{{< chooser language "typescript,python,go,csharp,java,yaml" >}} + +{{% choosable language typescript %}} + ```typescript +import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; -new aws.s3.Bucket("my-bucket", { - serverSideEncryptionConfiguration: { +const myBucket = new aws.s3.Bucket("my-bucket", {serverSideEncryptionConfiguration: { rule: { - applyServerSideEncryptionByDefault: { - sseAlgorithm: "aws:kms", - }, + applyServerSideEncryptionByDefault: { + sseAlgorithm: "aws:kms", + }, }, - }, +}}); + +``` + +{{% /choosable %}} + +{{% choosable language python %}} + +```python +import pulumi +import pulumi_aws as aws + +my_bucket = aws.s3.Bucket("my-bucket", server_side_encryption_configuration={ + "rule": { + "apply_server_side_encryption_by_default": { + "sse_algorithm": "aws:kms", + }, + }, +}) + +``` + +{{% /choosable %}} + +{{% choosable language go %}} + +```go +package main + +import ( + "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + _, err := s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{ + ServerSideEncryptionConfiguration: &s3.BucketServerSideEncryptionConfigurationArgs{ + Rule: &s3.BucketServerSideEncryptionConfigurationRuleArgs{ + ApplyServerSideEncryptionByDefault: &s3.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs{ + SseAlgorithm: pulumi.String("aws:kms"), + }, + }, + }, + }) + if err != nil { + return err + } + return nil + }) +} + +``` + +{{% /choosable %}} + +{{% choosable language csharp %}} + +```csharp +using System.Collections.Generic; +using System.Linq; +using Pulumi; +using Aws = Pulumi.Aws; + +return await Deployment.RunAsync(() => +{ + var myBucket = new Aws.S3.Bucket("my-bucket", new() + { + ServerSideEncryptionConfiguration = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationArgs + { + Rule = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationRuleArgs + { + ApplyServerSideEncryptionByDefault = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs + { + SseAlgorithm = "aws:kms", + }, + }, + }, + }); + }); + + ``` +{{% /choosable %}} + +{{% choosable language java %}} + +```java +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.inputs.BucketServerSideEncryptionConfigurationArgs; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationRuleArgs; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs; +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 myBucket = new Bucket("myBucket", BucketArgs.builder() + .serverSideEncryptionConfiguration(BucketServerSideEncryptionConfigurationArgs.builder() + .rule(BucketServerSideEncryptionConfigurationRuleArgs.builder() + .applyServerSideEncryptionByDefault(BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs.builder() + .sseAlgorithm("aws:kms") + .build()) + .build()) + .build()) + .build()); + + } +} + +``` + +{{% /choosable %}} + +{{% choosable language yaml %}} + +```yaml +name: example +runtime: yaml +resources: + my-bucket: + type: aws:s3:Bucket + properties: + serverSideEncryptionConfiguration: + rule: + applyServerSideEncryptionByDefault: + sseAlgorithm: "aws:kms" +``` + +{{% /choosable %}} + +{{< /chooser >}} + + 1. Scanning through the state in `pulumi stack export`, observe and note its URN is `"urn:pulumi:dev::bucket-playground::aws:s3/bucket:Bucket::my-bucket"` @@ -2047,24 +2207,214 @@ new aws.s3.Bucket("my-bucket", { 5. `pulumi import --file import-file.json` will suggest new code to include in your program, for example: - ```typescript - const my_bucket = new aws.s3.BucketV2("my-bucket", { - bucket: "my-bucket-cd24744", - }, { - protect: true, +{{< chooser language "typescript,python,go,csharp,java,yaml" >}} + +{{% choosable language typescript %}} + +```typescript +import * as pulumi from "@pulumi/pulumi"; +import * as aws from "@pulumi/aws"; + +const myBucket = new aws.s3.BucketV2("my-bucket", {bucket: "my-bucket-cd24744"}, { + protect: true, +}); +const myBucketEncryptionConfiguration = new aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", { + bucket: "my-bucket-cd24744", + rules: [{ + applyServerSideEncryptionByDefault: { + sseAlgorithm: "aws:kms", + }, + }], +}, { + protect: true, +}); + +``` + +{{% /choosable %}} + +{{% choosable language python %}} + +```python +import pulumi +import pulumi_aws as aws + +my_bucket = aws.s3.BucketV2("my-bucket", bucket="my-bucket-cd24744", +opts = pulumi.ResourceOptions(protect=True)) +my_bucket_encryption_configuration = aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", + bucket="my-bucket-cd24744", + rules=[{ + "apply_server_side_encryption_by_default": { + "sse_algorithm": "aws:kms", + }, + }], + opts = pulumi.ResourceOptions(protect=True)) + +``` + +{{% /choosable %}} + +{{% choosable language go %}} + +```go +package main + +import ( + "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + _, err := s3.NewBucketV2(ctx, "my-bucket", &s3.BucketV2Args{ + Bucket: pulumi.String("my-bucket-cd24744"), + }, pulumi.Protect(true)) + if err != nil { + return err + } + _, err = s3.NewBucketServerSideEncryptionConfigurationV2(ctx, "my-bucket-encryption-configuration", &s3.BucketServerSideEncryptionConfigurationV2Args{ + Bucket: pulumi.String("my-bucket-cd24744"), + Rules: s3.BucketServerSideEncryptionConfigurationV2RuleArray{ + &s3.BucketServerSideEncryptionConfigurationV2RuleArgs{ + ApplyServerSideEncryptionByDefault: &s3.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs{ + SseAlgorithm: pulumi.String("aws:kms"), + }, + }, + }, + }, pulumi.Protect(true)) + if err != nil { + return err + } + return nil + }) +} + +``` + +{{% /choosable %}} + +{{% choosable language csharp %}} + +```csharp +using System.Collections.Generic; +using System.Linq; +using Pulumi; +using Aws = Pulumi.Aws; + +return await Deployment.RunAsync(() => +{ + var myBucket = new Aws.S3.BucketV2("my-bucket", new() + { + Bucket = "my-bucket-cd24744", + }, new CustomResourceOptions + { + Protect = true, }); - const my_bucket_encryption_configuration = new aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", { - bucket: "my-bucket-cd24744", - rules: [{ - applyServerSideEncryptionByDefault: { - sseAlgorithm: "aws:kms", + var myBucketEncryptionConfiguration = new Aws.S3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", new() + { + Bucket = "my-bucket-cd24744", + Rules = new[] + { + new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationV2RuleArgs + { + ApplyServerSideEncryptionByDefault = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs + { + SseAlgorithm = "aws:kms", + }, }, - }], - }, { - protect: true, + }, + }, new CustomResourceOptions + { + Protect = true, }); - ``` + +}); + + +``` + +{{% /choosable %}} + +{{% choosable language java %}} + +```java +package generated_program; + +import com.pulumi.Context; +import com.pulumi.Pulumi; +import com.pulumi.core.Output; +import com.pulumi.aws.s3.BucketV2; +import com.pulumi.aws.s3.BucketV2Args; +import com.pulumi.aws.s3.BucketServerSideEncryptionConfigurationV2; +import com.pulumi.aws.s3.BucketServerSideEncryptionConfigurationV2Args; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationV2RuleArgs; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs; +import com.pulumi.resources.CustomResourceOptions; +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 myBucket = new BucketV2("myBucket", BucketV2Args.builder() + .bucket("my-bucket-cd24744") + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + var myBucketEncryptionConfiguration = new BucketServerSideEncryptionConfigurationV2("myBucketEncryptionConfiguration", BucketServerSideEncryptionConfigurationV2Args.builder() + .bucket("my-bucket-cd24744") + .rules(BucketServerSideEncryptionConfigurationV2RuleArgs.builder() + .applyServerSideEncryptionByDefault(BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs.builder() + .sseAlgorithm("aws:kms") + .build()) + .build()) + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + } +} + +``` + +{{% /choosable %}} + +{{% choosable language yaml %}} + +```yaml +name: example +runtime: yaml +resources: + my-bucket: + type: aws:s3:BucketV2 + properties: + bucket: "my-bucket-cd24744" + options: + protect: true + my-bucket-encryption-configuration: + type: aws:s3:BucketServerSideEncryptionConfigurationV2 + properties: + bucket: "my-bucket-cd24744" + rules: + - applyServerSideEncryptionByDefault: + sseAlgorithm: "aws:kms" + options: + protect: true +``` + +{{% /choosable %}} + +{{< /chooser >}} + 6. Run `pulumi state delete "urn:pulumi:dev::bucket-playground::aws:s3/bucket:Bucket::my-bucket"` to remove the old bucket from the state From 701fead6c2511878b3f2ecee96fbb2ef1f4fa008 Mon Sep 17 00:00:00 2001 From: Anton Tayanovskyy Date: Tue, 17 Sep 2024 16:03:25 -0400 Subject: [PATCH 11/20] Remove redundant heading --- .../aws/how-to-guides/bucketv2-migration.md | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md index 856937b17b..4800e9bcb4 100644 --- a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md +++ b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md @@ -5,8 +5,6 @@ meta_desc: Practitioner level instructions for migrating from aws.s3.Bucket to a layout: package --- -## Migrating from aws.s3.Bucket to aws.s3.BucketV2 - In the upcoming AWS Classic major release (v7), `aws.s3.Bucket` will be discontinued in favor of `BucketV2`. Users of `aws.s3.Bucket` resource are encouraged to migrate early. The migration is straightforward for simple use cases but requires some care for advanced configurations. Specifically `BucketV2` inputs such as `policy` and `accelerationStatus` @@ -153,7 +151,7 @@ using System.Text.Json; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { @@ -405,7 +403,7 @@ using System.Text.Json; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.BucketV2("my-bucket"); @@ -616,7 +614,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { @@ -794,7 +792,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.BucketV2("my-bucket"); @@ -952,7 +950,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { @@ -1081,7 +1079,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.BucketV2("my-bucket", new() { @@ -1246,7 +1244,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { @@ -1410,7 +1408,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.BucketV2("my-bucket"); @@ -1571,7 +1569,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var currentUser = Aws.S3.GetCanonicalUserId.Invoke(); @@ -1807,7 +1805,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var currentUser = Aws.S3.GetCanonicalUserId.Invoke(); @@ -2093,7 +2091,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { @@ -2301,7 +2299,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.BucketV2("my-bucket", new() { From eaddc322ef953925eb5bd083b8f681a5c8aca35b Mon Sep 17 00:00:00 2001 From: Anton Tayanovskyy Date: Tue, 17 Sep 2024 22:22:09 -0400 Subject: [PATCH 12/20] Use un-numbered lists --- .../aws/how-to-guides/bucketv2-migration.md | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md index 4800e9bcb4..efb057082c 100644 --- a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md +++ b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md @@ -2000,15 +2000,15 @@ migration that changes Pulumi program and state to track buckets using the new r against the actual cloud account. While the details will vary depending on your use case, this procedure generally involves the following steps: -1. Find URNs for legacy Bucket Pulumi resources using `pulumi stack export` -2. Determine the actual bucket name(s) -3. Determine which side-by-side resources will be needed for each bucket -4. Construct an `pulumi-import.json` file listing the buckets and their side-by-side resources -5. Run `pulumi import --file import-file.json` using the [Bulk Importing](https://www.pulumi.com/tutorials/importing/bulk-importing/) feature -6. Add the suggested code into your Pulumi program source -7. Remove the legacy Bucket code from your Pulumi program source -8. Remove the legacy Bucket resources from state using `pulumi state delete $bucketURN` -9. Run `pulumi preview` to confirm a no-change plan +- Find URNs for legacy Bucket Pulumi resources using `pulumi stack export` +- Determine the actual bucket name(s) +- Determine which side-by-side resources will be needed for each bucket +- Construct an `pulumi-import.json` file listing the buckets and their side-by-side resources +- Run `pulumi import --file import-file.json` using the [Bulk Importing](https://www.pulumi.com/tutorials/importing/bulk-importing/) feature +- Add the suggested code into your Pulumi program source +- Remove the legacy Bucket code from your Pulumi program source +- Remove the legacy Bucket resources from state using `pulumi state delete $bucketURN` +- Run `pulumi preview` to confirm a no-change plan Consider a concrete example, suppose you have provisioned a bucket with a `serverSideEncryptionConfiguration` as follows: @@ -2176,15 +2176,16 @@ resources: {{< /chooser >}} +Migrate as follows: -1. Scanning through the state in `pulumi stack export`, observe and note its URN is - `"urn:pulumi:dev::bucket-playground::aws:s3/bucket:Bucket::my-bucket"` +- Scanning through the state in `pulumi stack export`, observe and note its URN is + `"urn:pulumi:dev::bucket-playground::aws:s3/bucket:Bucket::my-bucket"` -2. The state file should also include the actual cloud name for the bucket such as `"bucket": "my-bucket-cd24744"` +- The state file should also include the actual cloud name for the bucket such as `"bucket": "my-bucket-cd24744"` -3. This bucket will require a `BucketServerSideEncryptionConfiguration` side-by-side resource +- This bucket will require a `BucketServerSideEncryptionConfiguration` side-by-side resource -4. The import file should therefore look like this: +- The import file should therefore look like this: ```json { @@ -2203,7 +2204,7 @@ resources: } ``` -5. `pulumi import --file import-file.json` will suggest new code to include in your program, for example: +- `pulumi import --file import-file.json` will suggest new code to include in your program, for example: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -2414,9 +2415,9 @@ resources: {{< /chooser >}} -6. Run `pulumi state delete "urn:pulumi:dev::bucket-playground::aws:s3/bucket:Bucket::my-bucket"` to remove the old - bucket from the state +- Run `pulumi state delete "urn:pulumi:dev::bucket-playground::aws:s3/bucket:Bucket::my-bucket"` to remove the old + bucket from the state -7. Delete the code for the old bucket from the sources. +- Delete the code for the old bucket from the sources. -8. `pulumi preview` should result in `Resources: N unchanged` to confirm everything went well. +- `pulumi preview` should result in `Resources: N unchanged` to confirm everything went well. From 7eda261b1f3244a9376b9e5439697ad4605a7d9f Mon Sep 17 00:00:00 2001 From: Anton Tayanovskyy Date: Wed, 18 Sep 2024 13:55:30 -0400 Subject: [PATCH 13/20] PR feedback; add a context session --- .../aws/how-to-guides/bucketv2-migration.md | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md index efb057082c..97faae5cba 100644 --- a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md +++ b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md @@ -6,25 +6,22 @@ layout: package --- In the upcoming AWS Classic major release (v7), `aws.s3.Bucket` will be discontinued in favor of `BucketV2`. Users of -`aws.s3.Bucket` resource are encouraged to migrate early. The migration is straightforward for simple use cases but -requires some care for advanced configurations. Specifically `BucketV2` inputs such as `policy` and `accelerationStatus` -are deprecated and using the requires migrating to side-by-side resources (see Removed inputs). This guide aims to cover -all relevant scenarios with precise migration instructions. +`aws.s3.Bucket` resource are encouraged to migrate early. The migration requires a significant refactor to the source +code and additional steps for avoiding data loss. This guide aims to cover all relevant scenarios with precise migration +instructions. To migrate existing `aws.s3.Bucket` resources to `aws.s3.BucketV2`: -1. Edit your Pulumi program sources to replace removed inputs (see below) with equivalent side-by-side resources. +1. Edit your Pulumi program sources to replace removed inputs with equivalent side-by-side resources. Specifically + `BucketV2` inputs such as `policy` and `accelerationStatus` are to be replaced with migrating to side-by-side + resources `aws.s3.BucketPolicy` and `aws.s3.BucketAccelerateConfigurationV2`. -2. Perform `pulumi up` to replace (delete and re-create) the buckets in AWS. - -If replacement is not acceptable, it is possible to perform a manual migration with `pulumi import` (see Avoiding -replacement). +2. Perform `pulumi up` to replace the buckets in AWS. **WARNING**: replacing the buckets will delete and re-create them, + losing any data stored in these buckets. If this is not acceptable, consider using `pulumi import` to migrate + manually instead as outlined in the "Avoiding replacement" section. ## Migrating deprecated inputs -Inputs such as `policy` and `accelerationStatus` are deprecated on the `aws.s3.BucketV2` resource. Instead of using -these inputs, it is recommended to use side-by-side resources to achieve the same effect. - ### policy input To specify a @@ -1149,8 +1146,6 @@ resources: {{< /chooser >}} - - ### corsRules input To configure [Cross-Origin Resource Sharing](https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html), @@ -2421,3 +2416,15 @@ resources: - Delete the code for the old bucket from the sources. - `pulumi preview` should result in `Resources: N unchanged` to confirm everything went well. + + +## Historical context + +The distinction between Bucket and BucketV2 originates from breaking changes introduced in the V4 release of the +Terraform AWS Provider. In the Pulumi AWS provider projection BucketV2 represents the latest version of the upstream +resource, while Bucket is maintained by Pulumi to enable backwards compatibility. + +See also: + +- [Announcing v5.0.0 of the Pulumi AWS Provider](https://www.pulumi.com/blog/announcing-v5.0.0-of-the-pulumi-aws-provider/) +- [Terraform AWS Provider Version 4 Upgrade Guide](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/guides/version-4-upgrade#s3-bucket-refactor) From a455da669a0caf378ed8170fe3370bb5b0bd2e20 Mon Sep 17 00:00:00 2001 From: Anton Tayanovskyy Date: Wed, 18 Sep 2024 13:57:01 -0400 Subject: [PATCH 14/20] Simplify the grammar --- .../registry/packages/aws/how-to-guides/bucketv2-migration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md index 97faae5cba..7d5a8be1ab 100644 --- a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md +++ b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md @@ -13,8 +13,8 @@ instructions. To migrate existing `aws.s3.Bucket` resources to `aws.s3.BucketV2`: 1. Edit your Pulumi program sources to replace removed inputs with equivalent side-by-side resources. Specifically - `BucketV2` inputs such as `policy` and `accelerationStatus` are to be replaced with migrating to side-by-side - resources `aws.s3.BucketPolicy` and `aws.s3.BucketAccelerateConfigurationV2`. + `BucketV2` inputs such as `policy` and `accelerationStatus` are to be replaced by side-by-side resources + `aws.s3.BucketPolicy` and `aws.s3.BucketAccelerateConfigurationV2`. 2. Perform `pulumi up` to replace the buckets in AWS. **WARNING**: replacing the buckets will delete and re-create them, losing any data stored in these buckets. If this is not acceptable, consider using `pulumi import` to migrate From 6ea5ab7b66ac15d97163e27d56356b2223d0d70f Mon Sep 17 00:00:00 2001 From: Anton Tayanovskyy Date: Wed, 18 Sep 2024 14:10:36 -0400 Subject: [PATCH 15/20] Exampe corrections --- .../aws/how-to-guides/bucketv2-migration.md | 175 ++++++++++++++---- 1 file changed, 136 insertions(+), 39 deletions(-) diff --git a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md index 7d5a8be1ab..5f05056da8 100644 --- a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md +++ b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md @@ -148,7 +148,7 @@ using System.Text.Json; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { @@ -279,7 +279,7 @@ import * as aws from "@pulumi/aws"; const myBucket = new aws.s3.BucketV2("my-bucket", {}); const myBucketPolicy = new aws.s3.BucketPolicy("my-bucket-policy", { - bucket: "my-bucket-26224916", + bucket: myBucket.bucket, policy: pulumi.jsonStringify({ Version: "2012-10-17", Id: "PutObjPolicy", @@ -311,7 +311,7 @@ import pulumi_aws as aws my_bucket = aws.s3.BucketV2("my-bucket") my_bucket_policy = aws.s3.BucketPolicy("my-bucket-policy", - bucket="my-bucket-26224916", + bucket=my_bucket.bucket, policy=pulumi.Output.json_dumps({ "Version": "2012-10-17", "Id": "PutObjPolicy", @@ -354,7 +354,7 @@ func main() { return err } _, err = s3.NewBucketPolicy(ctx, "my-bucket-policy", &s3.BucketPolicyArgs{ - Bucket: pulumi.String("my-bucket-26224916"), + Bucket: myBucket.Bucket, Policy: myBucket.Bucket.ApplyT(func(bucket string) (pulumi.String, error) { var _zero pulumi.String tmpJSON0, err := json.Marshal(map[string]interface{}{ @@ -400,13 +400,13 @@ using System.Text.Json; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.BucketV2("my-bucket"); var myBucketPolicy = new Aws.S3.BucketPolicy("my-bucket-policy", new() { - Bucket = "my-bucket-26224916", + Bucket = myBucket.Bucket, Policy = Output.JsonSerialize(Output.Create(new Dictionary { ["Version"] = "2012-10-17", @@ -464,7 +464,7 @@ public class App { var myBucket = new BucketV2("myBucket"); var myBucketPolicy = new BucketPolicy("myBucketPolicy", BucketPolicyArgs.builder() - .bucket("my-bucket-26224916") + .bucket(myBucket.bucket()) .policy(myBucket.bucket().applyValue(bucket -> serializeJson( jsonObject( jsonProperty("Version", "2012-10-17"), @@ -502,7 +502,7 @@ resources: my-bucket-policy: type: aws:s3:BucketPolicy properties: - bucket: "my-bucket-26224916" + bucket: ${my-bucket.bucket} policy: fn::toJSON: Version: 2012-10-17 @@ -522,10 +522,6 @@ resources: {{< /chooser >}} - - - - As a bonus, the policy can now more easily refer to the concrete name of the bucket. ### serverSideEncryptionConfiguration input @@ -611,7 +607,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { @@ -789,7 +785,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.BucketV2("my-bucket"); @@ -947,7 +943,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { @@ -1014,7 +1010,7 @@ resources: -Use the `aws.s3.BucketAccelerationConfiguration` resource: +Use the `aws.s3.BucketAccelerateConfigurationV2` resource: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -1024,7 +1020,11 @@ Use the `aws.s3.BucketAccelerationConfiguration` resource: import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; -const myBucket = new aws.s3.BucketV2("my-bucket", {accelerationStatus: "Enabled"}); +const myBucket = new aws.s3.BucketV2("my-bucket", {}); +const myBucketAcceleration = new aws.s3.BucketAccelerateConfigurationV2("my-bucket-acceleration", { + bucket: myBucket.bucket, + status: "Enabled", +}); ``` @@ -1036,7 +1036,10 @@ const myBucket = new aws.s3.BucketV2("my-bucket", {accelerationStatus: "Enabled" import pulumi import pulumi_aws as aws -my_bucket = aws.s3.BucketV2("my-bucket", acceleration_status="Enabled") +my_bucket = aws.s3.BucketV2("my-bucket") +my_bucket_acceleration = aws.s3.BucketAccelerateConfigurationV2("my-bucket-acceleration", + bucket=my_bucket.bucket, + status="Enabled") ``` @@ -1054,8 +1057,13 @@ import ( func main() { pulumi.Run(func(ctx *pulumi.Context) error { - _, err := s3.NewBucketV2(ctx, "my-bucket", &s3.BucketV2Args{ - AccelerationStatus: pulumi.String("Enabled"), + myBucket, err := s3.NewBucketV2(ctx, "my-bucket", nil) + if err != nil { + return err + } + _, err = s3.NewBucketAccelerateConfigurationV2(ctx, "my-bucket-acceleration", &s3.BucketAccelerateConfigurationV2Args{ + Bucket: myBucket.Bucket, + Status: pulumi.String("Enabled"), }) if err != nil { return err @@ -1076,11 +1084,14 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { - var myBucket = new Aws.S3.BucketV2("my-bucket", new() + var myBucket = new Aws.S3.BucketV2("my-bucket"); + + var myBucketAcceleration = new Aws.S3.BucketAccelerateConfigurationV2("my-bucket-acceleration", new() { - AccelerationStatus = "Enabled", + Bucket = myBucket.Bucket, + Status = "Enabled", }); }); @@ -1099,7 +1110,8 @@ import com.pulumi.Context; import com.pulumi.Pulumi; import com.pulumi.core.Output; import com.pulumi.aws.s3.BucketV2; -import com.pulumi.aws.s3.BucketV2Args; +import com.pulumi.aws.s3.BucketAccelerateConfigurationV2; +import com.pulumi.aws.s3.BucketAccelerateConfigurationV2Args; import java.util.List; import java.util.ArrayList; import java.util.Map; @@ -1113,8 +1125,11 @@ public class App { } public static void stack(Context ctx) { - var myBucket = new BucketV2("myBucket", BucketV2Args.builder() - .accelerationStatus("Enabled") + var myBucket = new BucketV2("myBucket"); + + var myBucketAcceleration = new BucketAccelerateConfigurationV2("myBucketAcceleration", BucketAccelerateConfigurationV2Args.builder() + .bucket(myBucket.bucket()) + .status("Enabled") .build()); } @@ -1132,13 +1147,11 @@ runtime: yaml resources: my-bucket: type: aws:s3:BucketV2 - properties: - accelerationStatus: Enabled my-bucket-acceleration: - type: aws:s3:BucketAccelerationConfigurationV2 + type: aws:s3:BucketAccelerateConfigurationV2 properties: bucket: ${my-bucket.bucket} - accelerationStatus: Enabled + status: Enabled ``` {{% /choosable %}} @@ -1239,7 +1252,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { @@ -1343,7 +1356,7 @@ resources: -Use the `aws.s3.BucketCorsConfiguration` resource: +Use the `aws.s3.BucketCorsConfigurationV2` resource: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -1354,6 +1367,16 @@ import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; const myBucket = new aws.s3.BucketV2("my-bucket", {}); +const myBucketCors = new aws.s3.BucketCorsConfigurationV2("my-bucket-cors", { + bucket: myBucket.bucket, + corsRules: [{ + allowedHeaders: ["*"], + allowedMethods: ["GET"], + allowedOrigins: ["*"], + exposeHeaders: ["ETag"], + maxAgeSeconds: 3000, + }], +}); ``` @@ -1366,6 +1389,15 @@ import pulumi import pulumi_aws as aws my_bucket = aws.s3.BucketV2("my-bucket") +my_bucket_cors = aws.s3.BucketCorsConfigurationV2("my-bucket-cors", + bucket=my_bucket.bucket, + cors_rules=[{ + "allowed_headers": ["*"], + "allowed_methods": ["GET"], + "allowed_origins": ["*"], + "expose_headers": ["ETag"], + "max_age_seconds": 3000, + }]) ``` @@ -1383,7 +1415,30 @@ import ( func main() { pulumi.Run(func(ctx *pulumi.Context) error { - _, err := s3.NewBucketV2(ctx, "my-bucket", nil) + myBucket, err := s3.NewBucketV2(ctx, "my-bucket", nil) + if err != nil { + return err + } + _, err = s3.NewBucketCorsConfigurationV2(ctx, "my-bucket-cors", &s3.BucketCorsConfigurationV2Args{ + Bucket: myBucket.Bucket, + CorsRules: s3.BucketCorsConfigurationV2CorsRuleArray{ + &s3.BucketCorsConfigurationV2CorsRuleArgs{ + AllowedHeaders: pulumi.StringArray{ + pulumi.String("*"), + }, + AllowedMethods: pulumi.StringArray{ + pulumi.String("GET"), + }, + AllowedOrigins: pulumi.StringArray{ + pulumi.String("*"), + }, + ExposeHeaders: pulumi.StringArray{ + pulumi.String("ETag"), + }, + MaxAgeSeconds: pulumi.Int(3000), + }, + }, + }) if err != nil { return err } @@ -1403,10 +1458,38 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.BucketV2("my-bucket"); + var myBucketCors = new Aws.S3.BucketCorsConfigurationV2("my-bucket-cors", new() + { + Bucket = myBucket.Bucket, + CorsRules = new[] + { + new Aws.S3.Inputs.BucketCorsConfigurationV2CorsRuleArgs + { + AllowedHeaders = new[] + { + "*", + }, + AllowedMethods = new[] + { + "GET", + }, + AllowedOrigins = new[] + { + "*", + }, + ExposeHeaders = new[] + { + "ETag", + }, + MaxAgeSeconds = 3000, + }, + }, + }); + }); @@ -1423,6 +1506,9 @@ import com.pulumi.Context; import com.pulumi.Pulumi; import com.pulumi.core.Output; import com.pulumi.aws.s3.BucketV2; +import com.pulumi.aws.s3.BucketCorsConfigurationV2; +import com.pulumi.aws.s3.BucketCorsConfigurationV2Args; +import com.pulumi.aws.s3.inputs.BucketCorsConfigurationV2CorsRuleArgs; import java.util.List; import java.util.ArrayList; import java.util.Map; @@ -1438,6 +1524,17 @@ public class App { public static void stack(Context ctx) { var myBucket = new BucketV2("myBucket"); + var myBucketCors = new BucketCorsConfigurationV2("myBucketCors", BucketCorsConfigurationV2Args.builder() + .bucket(myBucket.bucket()) + .corsRules(BucketCorsConfigurationV2CorsRuleArgs.builder() + .allowedHeaders("*") + .allowedMethods("GET") + .allowedOrigins("*") + .exposeHeaders("ETag") + .maxAgeSeconds(3000) + .build()) + .build()); + } } @@ -1454,7 +1551,7 @@ resources: my-bucket: type: aws:s3:BucketV2 my-bucket-cors: - type: aws:s3:BucketCorsConfiguration + type: aws:s3:BucketCorsConfigurationV2 properties: bucket: ${my-bucket.bucket} corsRules: @@ -1564,7 +1661,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var currentUser = Aws.S3.GetCanonicalUserId.Invoke(); @@ -1800,7 +1897,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var currentUser = Aws.S3.GetCanonicalUserId.Invoke(); @@ -2086,7 +2183,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { @@ -2295,7 +2392,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.BucketV2("my-bucket", new() { From 82e215bb4f006816927f1933454a781001e337dd Mon Sep 17 00:00:00 2001 From: Anton Tayanovskyy Date: Wed, 18 Sep 2024 16:02:30 -0400 Subject: [PATCH 16/20] Update migration notes on latest --- .../aws/how-to-guides/bucketv2-migration.md | 246 +++++++++++++++--- 1 file changed, 214 insertions(+), 32 deletions(-) diff --git a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md index 5f05056da8..a34eda21bd 100644 --- a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md +++ b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md @@ -148,7 +148,7 @@ using System.Text.Json; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { @@ -400,7 +400,7 @@ using System.Text.Json; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.BucketV2("my-bucket"); @@ -607,7 +607,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { @@ -785,7 +785,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.BucketV2("my-bucket"); @@ -943,7 +943,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { @@ -1084,7 +1084,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.BucketV2("my-bucket"); @@ -1252,7 +1252,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { @@ -1458,7 +1458,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.BucketV2("my-bucket"); @@ -1661,7 +1661,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var currentUser = Aws.S3.GetCanonicalUserId.Invoke(); @@ -1897,7 +1897,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var currentUser = Aws.S3.GetCanonicalUserId.Invoke(); @@ -2094,16 +2094,17 @@ involves the following steps: - Find URNs for legacy Bucket Pulumi resources using `pulumi stack export` - Determine the actual bucket name(s) +- Remove the legacy Bucket code from your Pulumi program source +- Remove the legacy Bucket resources from state using `pulumi state delete $bucketURN` - Determine which side-by-side resources will be needed for each bucket - Construct an `pulumi-import.json` file listing the buckets and their side-by-side resources - Run `pulumi import --file import-file.json` using the [Bulk Importing](https://www.pulumi.com/tutorials/importing/bulk-importing/) feature - Add the suggested code into your Pulumi program source -- Remove the legacy Bucket code from your Pulumi program source -- Remove the legacy Bucket resources from state using `pulumi state delete $bucketURN` - Run `pulumi preview` to confirm a no-change plan +- If warnings are generated, edit the program to remove deprecated inputs from BucketV2 +- Run `pulumi preview` one more time to confirm a no-change plan on the final program -Consider a concrete example, suppose you have provisioned a bucket with a `serverSideEncryptionConfiguration` as -follows: +Consider a concrete example, suppose you have provisioned a bucket as follows: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -2183,7 +2184,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { @@ -2252,16 +2253,40 @@ public class App { {{% choosable language yaml %}} ```yaml -name: example +name: y2 runtime: yaml resources: my-bucket: type: aws:s3:Bucket properties: + bucket: "my-bucket-26224917" serverSideEncryptionConfiguration: rule: applyServerSideEncryptionByDefault: - sseAlgorithm: "aws:kms" + sseAlgorithm: "AES256" + lifecycleRules: + - enabled: true + expiration: + days: 30 + policy: + fn::toJSON: + Version: "2012-10-17" + Id: "PutObjPolicy" + Statement: + - Sid: "DenyObjectsThatAreNotSSEKMS" + Principal: "*" + Effect: "Deny" + Action: "s3:PutObject" + Resource: "arn:aws:s3:::my-bucket-26224917/*" + Condition: + "Null": + "s3:x-amz-server-side-encryption-aws-kms-key-id": "true" + tags: + Environment: "Dev" + objectLockConfiguration: + objectLockEnabled: "Enabled" + versioning: + enabled: true ``` {{% /choosable %}} @@ -2271,11 +2296,22 @@ resources: Migrate as follows: - Scanning through the state in `pulumi stack export`, observe and note its URN is - `"urn:pulumi:dev::bucket-playground::aws:s3/bucket:Bucket::my-bucket"` + `"urn:pulumi:bucket1::y2::aws:s3/bucket:Bucket::my-bucket"` + +- The state file should also include the actual cloud name for the bucket such as `"bucket": "my-bucket-36224917"` -- The state file should also include the actual cloud name for the bucket such as `"bucket": "my-bucket-cd24744"` +- Run `pulumi state delete "urn:pulumi:bucket1::y2::aws:s3/bucket:Bucket::my-bucket"` to remove the old bucket from the + state -- This bucket will require a `BucketServerSideEncryptionConfiguration` side-by-side resource +- Delete the code for the old bucket from the sources. + +- This bucket will require the following side-by-side resources: + + aws:s3:BucketServerSideEncryptionConfigurationV2 + aws:s3:BucketLifecycleConfigurationV2 + aws:s3:BucketPolicy + aws:s3:BucketObjectLockConfigurationV2 + aws:s3:BucketVersioningV2 - The import file should therefore look like this: @@ -2284,13 +2320,33 @@ Migrate as follows: "resources": [ { "type": "aws:s3/bucketV2:BucketV2", - "name": "my-bucket", - "id": "my-bucket-cd24744" + "name": "my-bucket2", + "id": "my-bucket-36224917" }, { "type": "aws:s3/bucketServerSideEncryptionConfigurationV2:BucketServerSideEncryptionConfigurationV2", "name": "my-bucket-encryption-configuration", - "id": "my-bucket-cd24744" + "id": "my-bucket-36224917" + }, + { + "type": "aws:s3/bucketPolicy:BucketPolicy", + "name": "my-bucket-policy", + "id": "my-bucket-36224917" + }, + { + "type": "aws:s3/bucketLifecycleConfigurationV2:BucketLifecycleConfigurationV2", + "name": "my-bucket-policy", + "id": "my-bucket-36224917" + }, + { + "type": "aws:s3/bucketObjectLockConfigurationV2:BucketObjectLockConfigurationV2", + "name": "my-bucket-object-lock-configuration", + "id": "my-bucket-36224917" + }, + { + "type": "aws:s3/bucketVersioningV2:BucketVersioningV2", + "name": "my-bucket-versioning", + "id": "my-bucket-36224917" } ] } @@ -2392,7 +2448,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.BucketV2("my-bucket", new() { @@ -2482,22 +2538,78 @@ public class App { {{% choosable language yaml %}} ```yaml -name: example +name: y2 runtime: yaml resources: my-bucket: type: aws:s3:BucketV2 properties: - bucket: "my-bucket-cd24744" + bucket: my-bucket-36224917 + grants: + - id: e07865a5679c7977370948f1f1e51c21b12d8cfdd396a7e3172275d9164e01b8 + permissions: + - FULL_CONTROL + type: CanonicalUser + lifecycleRules: + - enabled: true + expirations: + - days: 30 + id: pu-s3-lifecycle-20240918194815251100000001 + objectLockConfiguration: + objectLockEnabled: Enabled + policy: '{"Id":"PutObjPolicy","Statement":[{"Action":"s3:PutObject","Condition":{"Null":{"s3:x-amz-server-side-encryption-aws-kms-key-id":"true"}},"Effect":"Deny","Principal":"*","Resource":"arn:aws:s3:::my-bucket-36224917/*","Sid":"DenyObjectsThatAreNotSSEKMS"}],"Version":"2012-10-17"}' + requestPayer: BucketOwner + serverSideEncryptionConfigurations: + - rules: + - applyServerSideEncryptionByDefaults: + - sseAlgorithm: AES256 + tags: + Environment: Dev + versionings: + - enabled: true options: protect: true my-bucket-encryption-configuration: type: aws:s3:BucketServerSideEncryptionConfigurationV2 properties: - bucket: "my-bucket-cd24744" + bucket: my-bucket-36224917 rules: - applyServerSideEncryptionByDefault: - sseAlgorithm: "aws:kms" + sseAlgorithm: AES256 + options: + protect: true + my-bucket-policy: + type: aws:s3:BucketPolicy + properties: + bucket: my-bucket-36224917 + policy: '{"Id":"PutObjPolicy","Statement":[{"Action":"s3:PutObject","Condition":{"Null":{"s3:x-amz-server-side-encryption-aws-kms-key-id":"true"}},"Effect":"Deny","Principal":"*","Resource":"arn:aws:s3:::my-bucket-36224917/*","Sid":"DenyObjectsThatAreNotSSEKMS"}],"Version":"2012-10-17"}' + options: + protect: true + my-bucket-lifecycle: + type: aws:s3:BucketLifecycleConfigurationV2 + properties: + bucket: my-bucket-36224917 + rules: + - expiration: + days: 30 + id: pu-s3-lifecycle-20240918194815251100000001 + status: Enabled + options: + protect: true + my-bucket-object-lock-configuration: + type: aws:s3:BucketObjectLockConfigurationV2 + properties: + bucket: my-bucket-36224917 + objectLockEnabled: Enabled + options: + protect: true + my-bucket-versioning: + type: aws:s3:BucketVersioningV2 + properties: + bucket: my-bucket-36224917 + versioningConfiguration: + mfaDelete: Disabled + status: Enabled options: protect: true ``` @@ -2506,14 +2618,84 @@ resources: {{< /chooser >}} +- `pulumi preview` should result in `Resources: N unchanged` to confirm everything went well. -- Run `pulumi state delete "urn:pulumi:dev::bucket-playground::aws:s3/bucket:Bucket::my-bucket"` to remove the old - bucket from the state +- At this point you may see warnings from deprecated inputs like this: -- Delete the code for the old bucket from the sources. +```shell +warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the top-level parameter object_lock_enabled instead +warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the top-level parameter object_lock_enabled and the aws_s3_bucket_object_lock_configuration resource instead +warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the aws_s3_bucket_lifecycle_configuration resource instead +warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the aws_s3_bucket_versioning resource instead +warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the aws_s3_bucket_acl resource instead +warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the aws_s3_bucket_request_payment_configuration resource instead +warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the aws_s3_bucket_policy resource instead +warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the aws_s3_bucket_server_side_encryption_configuration resource instead +``` -- `pulumi preview` should result in `Resources: N unchanged` to confirm everything went well. +- To mitigate, edit the program to remove the deprecated inputs, leaving the final simplify program that should still + result in an empty `pulumi preview`: + +{{< chooser >}} + +```yaml +name: y2 +runtime: yaml +resources: + my-bucket: + type: aws:s3:BucketV2 + properties: + bucket: my-bucket-36224917 + tags: + Environment: Dev + options: + protect: true + my-bucket-encryption-configuration: + type: aws:s3:BucketServerSideEncryptionConfigurationV2 + properties: + bucket: my-bucket-36224917 + rules: + - applyServerSideEncryptionByDefault: + sseAlgorithm: AES256 + options: + protect: true + my-bucket-policy: + type: aws:s3:BucketPolicy + properties: + bucket: my-bucket-36224917 + policy: '{"Id":"PutObjPolicy","Statement":[{"Action":"s3:PutObject","Condition":{"Null":{"s3:x-amz-server-side-encryption-aws-kms-key-id":"true"}},"Effect":"Deny","Principal":"*","Resource":"arn:aws:s3:::my-bucket-36224917/*","Sid":"DenyObjectsThatAreNotSSEKMS"}],"Version":"2012-10-17"}' + options: + protect: true + my-bucket-lifecycle: + type: aws:s3:BucketLifecycleConfigurationV2 + properties: + bucket: my-bucket-36224917 + rules: + - expiration: + days: 30 + id: pu-s3-lifecycle-20240918194815251100000001 + status: Enabled + options: + protect: true + my-bucket-object-lock-configuration: + type: aws:s3:BucketObjectLockConfigurationV2 + properties: + bucket: my-bucket-36224917 + objectLockEnabled: Enabled + options: + protect: true + my-bucket-versioning: + type: aws:s3:BucketVersioningV2 + properties: + bucket: my-bucket-36224917 + versioningConfiguration: + mfaDelete: Disabled + status: Enabled + options: + protect: true +``` +{{< /chooser >}} ## Historical context From b000b8e963cd0ba5f28b6a29f20a5bd645a323f0 Mon Sep 17 00:00:00 2001 From: Anton Tayanovskyy Date: Wed, 18 Sep 2024 16:05:08 -0400 Subject: [PATCH 17/20] Regenerate choosers --- .../aws/how-to-guides/bucketv2-migration.md | 1092 ++++++++++++++++- 1 file changed, 1042 insertions(+), 50 deletions(-) diff --git a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md index a34eda21bd..67f434d13d 100644 --- a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md +++ b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md @@ -148,7 +148,7 @@ using System.Text.Json; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { @@ -400,7 +400,7 @@ using System.Text.Json; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.BucketV2("my-bucket"); @@ -607,7 +607,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { @@ -785,7 +785,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.BucketV2("my-bucket"); @@ -943,7 +943,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { @@ -1084,7 +1084,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.BucketV2("my-bucket"); @@ -1252,7 +1252,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { @@ -1458,7 +1458,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.BucketV2("my-bucket"); @@ -1661,7 +1661,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var currentUser = Aws.S3.GetCanonicalUserId.Invoke(); @@ -1897,7 +1897,7 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var currentUser = Aws.S3.GetCanonicalUserId.Invoke(); @@ -2114,13 +2114,47 @@ Consider a concrete example, suppose you have provisioned a bucket as follows: import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; -const myBucket = new aws.s3.Bucket("my-bucket", {serverSideEncryptionConfiguration: { - rule: { - applyServerSideEncryptionByDefault: { - sseAlgorithm: "aws:kms", +const myBucket = new aws.s3.Bucket("my-bucket", { + bucket: "my-bucket-26224917", + serverSideEncryptionConfiguration: { + rule: { + applyServerSideEncryptionByDefault: { + sseAlgorithm: "AES256", + }, }, }, -}}); + lifecycleRules: [{ + enabled: true, + expiration: { + days: 30, + }, + }], + policy: JSON.stringify({ + Version: "2012-10-17", + Id: "PutObjPolicy", + Statement: [{ + Sid: "DenyObjectsThatAreNotSSEKMS", + Principal: "*", + Effect: "Deny", + Action: "s3:PutObject", + Resource: "arn:aws:s3:::my-bucket-26224917/*", + Condition: { + Null: { + "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", + }, + }, + }], + }), + tags: { + Environment: "Dev", + }, + objectLockConfiguration: { + objectLockEnabled: "Enabled", + }, + versioning: { + enabled: true, + }, +}); ``` @@ -2130,15 +2164,49 @@ const myBucket = new aws.s3.Bucket("my-bucket", {serverSideEncryptionConfigurati ```python import pulumi +import json import pulumi_aws as aws -my_bucket = aws.s3.Bucket("my-bucket", server_side_encryption_configuration={ - "rule": { - "apply_server_side_encryption_by_default": { - "sse_algorithm": "aws:kms", +my_bucket = aws.s3.Bucket("my-bucket", + bucket="my-bucket-26224917", + server_side_encryption_configuration={ + "rule": { + "apply_server_side_encryption_by_default": { + "sse_algorithm": "AES256", + }, }, }, -}) + lifecycle_rules=[{ + "enabled": True, + "expiration": { + "days": 30, + }, + }], + policy=json.dumps({ + "Version": "2012-10-17", + "Id": "PutObjPolicy", + "Statement": [{ + "Sid": "DenyObjectsThatAreNotSSEKMS", + "Principal": "*", + "Effect": "Deny", + "Action": "s3:PutObject", + "Resource": "arn:aws:s3:::my-bucket-26224917/*", + "Condition": { + "Null": { + "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", + }, + }, + }], + }), + tags={ + "Environment": "Dev", + }, + object_lock_configuration={ + "object_lock_enabled": "Enabled", + }, + versioning={ + "enabled": True, + }) ``` @@ -2150,20 +2218,63 @@ my_bucket = aws.s3.Bucket("my-bucket", server_side_encryption_configuration={ package main import ( + "encoding/json" + "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" ) func main() { pulumi.Run(func(ctx *pulumi.Context) error { - _, err := s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{ + tmpJSON0, err := json.Marshal(map[string]interface{}{ + "Version": "2012-10-17", + "Id": "PutObjPolicy", + "Statement": []map[string]interface{}{ + map[string]interface{}{ + "Sid": "DenyObjectsThatAreNotSSEKMS", + "Principal": "*", + "Effect": "Deny", + "Action": "s3:PutObject", + "Resource": "arn:aws:s3:::my-bucket-26224917/*", + "Condition": map[string]interface{}{ + "Null": map[string]interface{}{ + "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", + }, + }, + }, + }, + }) + if err != nil { + return err + } + json0 := string(tmpJSON0) + _, err = s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{ + Bucket: pulumi.String("my-bucket-26224917"), ServerSideEncryptionConfiguration: &s3.BucketServerSideEncryptionConfigurationArgs{ Rule: &s3.BucketServerSideEncryptionConfigurationRuleArgs{ ApplyServerSideEncryptionByDefault: &s3.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs{ - SseAlgorithm: pulumi.String("aws:kms"), + SseAlgorithm: pulumi.String("AES256"), + }, + }, + }, + LifecycleRules: s3.BucketLifecycleRuleArray{ + &s3.BucketLifecycleRuleArgs{ + Enabled: pulumi.Bool(true), + Expiration: &s3.BucketLifecycleRuleExpirationArgs{ + Days: pulumi.Int(30), }, }, }, + Policy: pulumi.String(json0), + Tags: pulumi.StringMap{ + "Environment": pulumi.String("Dev"), + }, + ObjectLockConfiguration: &s3.BucketObjectLockConfigurationArgs{ + ObjectLockEnabled: pulumi.String("Enabled"), + }, + Versioning: &s3.BucketVersioningArgs{ + Enabled: pulumi.Bool(true), + }, }) if err != nil { return err @@ -2181,22 +2292,70 @@ func main() { ```csharp using System.Collections.Generic; using System.Linq; +using System.Text.Json; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { + BucketName = "my-bucket-26224917", ServerSideEncryptionConfiguration = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationArgs { Rule = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationRuleArgs { ApplyServerSideEncryptionByDefault = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs { - SseAlgorithm = "aws:kms", + SseAlgorithm = "AES256", + }, + }, + }, + LifecycleRules = new[] + { + new Aws.S3.Inputs.BucketLifecycleRuleArgs + { + Enabled = true, + Expiration = new Aws.S3.Inputs.BucketLifecycleRuleExpirationArgs + { + Days = 30, + }, + }, + }, + Policy = JsonSerializer.Serialize(new Dictionary + { + ["Version"] = "2012-10-17", + ["Id"] = "PutObjPolicy", + ["Statement"] = new[] + { + new Dictionary + { + ["Sid"] = "DenyObjectsThatAreNotSSEKMS", + ["Principal"] = "*", + ["Effect"] = "Deny", + ["Action"] = "s3:PutObject", + ["Resource"] = "arn:aws:s3:::my-bucket-26224917/*", + ["Condition"] = new Dictionary + { + ["Null"] = new Dictionary + { + ["s3:x-amz-server-side-encryption-aws-kms-key-id"] = "true", + }, + }, }, }, + }), + Tags = + { + { "Environment", "Dev" }, + }, + ObjectLockConfiguration = new Aws.S3.Inputs.BucketObjectLockConfigurationArgs + { + ObjectLockEnabled = "Enabled", + }, + Versioning = new Aws.S3.Inputs.BucketVersioningArgs + { + Enabled = true, }, }); @@ -2220,6 +2379,11 @@ import com.pulumi.aws.s3.BucketArgs; import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationArgs; import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationRuleArgs; import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs; +import com.pulumi.aws.s3.inputs.BucketLifecycleRuleArgs; +import com.pulumi.aws.s3.inputs.BucketLifecycleRuleExpirationArgs; +import com.pulumi.aws.s3.inputs.BucketObjectLockConfigurationArgs; +import com.pulumi.aws.s3.inputs.BucketVersioningArgs; +import static com.pulumi.codegen.internal.Serialization.*; import java.util.List; import java.util.ArrayList; import java.util.Map; @@ -2234,13 +2398,44 @@ public class App { public static void stack(Context ctx) { var myBucket = new Bucket("myBucket", BucketArgs.builder() + .bucket("my-bucket-26224917") .serverSideEncryptionConfiguration(BucketServerSideEncryptionConfigurationArgs.builder() .rule(BucketServerSideEncryptionConfigurationRuleArgs.builder() .applyServerSideEncryptionByDefault(BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs.builder() - .sseAlgorithm("aws:kms") + .sseAlgorithm("AES256") .build()) .build()) .build()) + .lifecycleRules(BucketLifecycleRuleArgs.builder() + .enabled(true) + .expiration(BucketLifecycleRuleExpirationArgs.builder() + .days(30) + .build()) + .build()) + .policy(serializeJson( + jsonObject( + jsonProperty("Version", "2012-10-17"), + jsonProperty("Id", "PutObjPolicy"), + jsonProperty("Statement", jsonArray(jsonObject( + jsonProperty("Sid", "DenyObjectsThatAreNotSSEKMS"), + jsonProperty("Principal", "*"), + jsonProperty("Effect", "Deny"), + jsonProperty("Action", "s3:PutObject"), + jsonProperty("Resource", "arn:aws:s3:::my-bucket-26224917/*"), + jsonProperty("Condition", jsonObject( + jsonProperty("Null", jsonObject( + jsonProperty("s3:x-amz-server-side-encryption-aws-kms-key-id", "true") + )) + )) + ))) + ))) + .tags(Map.of("Environment", "Dev")) + .objectLockConfiguration(BucketObjectLockConfigurationArgs.builder() + .objectLockEnabled("Enabled") + .build()) + .versioning(BucketVersioningArgs.builder() + .enabled(true) + .build()) .build()); } @@ -2362,19 +2557,84 @@ Migrate as follows: import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; -const myBucket = new aws.s3.BucketV2("my-bucket", {bucket: "my-bucket-cd24744"}, { +const myBucket = new aws.s3.BucketV2("my-bucket", { + bucket: "my-bucket-36224917", + grants: [{ + id: "e07865a5679c7977370948f1f1e51c21b12d8cfdd396a7e3172275d9164e01b8", + permissions: ["FULL_CONTROL"], + type: "CanonicalUser", + }], + lifecycleRules: [{ + enabled: true, + expirations: [{ + days: 30, + }], + id: "pu-s3-lifecycle-20240918194815251100000001", + }], + objectLockConfiguration: { + objectLockEnabled: "Enabled", + }, + policy: "{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", + requestPayer: "BucketOwner", + serverSideEncryptionConfigurations: [{ + rules: [{ + applyServerSideEncryptionByDefaults: [{ + sseAlgorithm: "AES256", + }], + }], + }], + tags: { + Environment: "Dev", + }, + versionings: [{ + enabled: true, + }], +}, { protect: true, }); const myBucketEncryptionConfiguration = new aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", { - bucket: "my-bucket-cd24744", + bucket: "my-bucket-36224917", rules: [{ applyServerSideEncryptionByDefault: { - sseAlgorithm: "aws:kms", + sseAlgorithm: "AES256", + }, + }], +}, { + protect: true, +}); +const myBucketPolicy = new aws.s3.BucketPolicy("my-bucket-policy", { + bucket: "my-bucket-36224917", + policy: "{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", +}, { + protect: true, +}); +const myBucketLifecycle = new aws.s3.BucketLifecycleConfigurationV2("my-bucket-lifecycle", { + bucket: "my-bucket-36224917", + rules: [{ + expiration: { + days: 30, }, + id: "pu-s3-lifecycle-20240918194815251100000001", + status: "Enabled", }], }, { protect: true, }); +const myBucketObjectLockConfiguration = new aws.s3.BucketObjectLockConfigurationV2("my-bucket-object-lock-configuration", { + bucket: "my-bucket-36224917", + objectLockEnabled: "Enabled", +}, { + protect: true, +}); +const myBucketVersioning = new aws.s3.BucketVersioningV2("my-bucket-versioning", { + bucket: "my-bucket-36224917", + versioningConfiguration: { + mfaDelete: "Disabled", + status: "Enabled", + }, +}, { + protect: true, +}); ``` @@ -2386,16 +2646,72 @@ const myBucketEncryptionConfiguration = new aws.s3.BucketServerSideEncryptionCon import pulumi import pulumi_aws as aws -my_bucket = aws.s3.BucketV2("my-bucket", bucket="my-bucket-cd24744", -opts = pulumi.ResourceOptions(protect=True)) +my_bucket = aws.s3.BucketV2("my-bucket", + bucket="my-bucket-36224917", + grants=[{ + "id": "e07865a5679c7977370948f1f1e51c21b12d8cfdd396a7e3172275d9164e01b8", + "permissions": ["FULL_CONTROL"], + "type": "CanonicalUser", + }], + lifecycle_rules=[{ + "enabled": True, + "expirations": [{ + "days": 30, + }], + "id": "pu-s3-lifecycle-20240918194815251100000001", + }], + object_lock_configuration={ + "object_lock_enabled": "Enabled", + }, + policy="{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", + request_payer="BucketOwner", + server_side_encryption_configurations=[{ + "rules": [{ + "apply_server_side_encryption_by_defaults": [{ + "sse_algorithm": "AES256", + }], + }], + }], + tags={ + "Environment": "Dev", + }, + versionings=[{ + "enabled": True, + }], + opts = pulumi.ResourceOptions(protect=True)) my_bucket_encryption_configuration = aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", - bucket="my-bucket-cd24744", + bucket="my-bucket-36224917", rules=[{ "apply_server_side_encryption_by_default": { - "sse_algorithm": "aws:kms", + "sse_algorithm": "AES256", }, }], opts = pulumi.ResourceOptions(protect=True)) +my_bucket_policy = aws.s3.BucketPolicy("my-bucket-policy", + bucket="my-bucket-36224917", + policy="{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", + opts = pulumi.ResourceOptions(protect=True)) +my_bucket_lifecycle = aws.s3.BucketLifecycleConfigurationV2("my-bucket-lifecycle", + bucket="my-bucket-36224917", + rules=[{ + "expiration": { + "days": 30, + }, + "id": "pu-s3-lifecycle-20240918194815251100000001", + "status": "Enabled", + }], + opts = pulumi.ResourceOptions(protect=True)) +my_bucket_object_lock_configuration = aws.s3.BucketObjectLockConfigurationV2("my-bucket-object-lock-configuration", + bucket="my-bucket-36224917", + object_lock_enabled="Enabled", + opts = pulumi.ResourceOptions(protect=True)) +my_bucket_versioning = aws.s3.BucketVersioningV2("my-bucket-versioning", + bucket="my-bucket-36224917", + versioning_configuration={ + "mfa_delete": "Disabled", + "status": "Enabled", + }, + opts = pulumi.ResourceOptions(protect=True)) ``` @@ -2414,24 +2730,109 @@ import ( func main() { pulumi.Run(func(ctx *pulumi.Context) error { _, err := s3.NewBucketV2(ctx, "my-bucket", &s3.BucketV2Args{ - Bucket: pulumi.String("my-bucket-cd24744"), + Bucket: pulumi.String("my-bucket-36224917"), + Grants: s3.BucketV2GrantArray{ + &s3.BucketV2GrantArgs{ + Id: pulumi.String("e07865a5679c7977370948f1f1e51c21b12d8cfdd396a7e3172275d9164e01b8"), + Permissions: pulumi.StringArray{ + pulumi.String("FULL_CONTROL"), + }, + Type: pulumi.String("CanonicalUser"), + }, + }, + LifecycleRules: s3.BucketV2LifecycleRuleArray{ + &s3.BucketV2LifecycleRuleArgs{ + Enabled: pulumi.Bool(true), + Expirations: s3.BucketV2LifecycleRuleExpirationArray{ + &s3.BucketV2LifecycleRuleExpirationArgs{ + Days: pulumi.Int(30), + }, + }, + Id: pulumi.String("pu-s3-lifecycle-20240918194815251100000001"), + }, + }, + ObjectLockConfiguration: &s3.BucketV2ObjectLockConfigurationArgs{ + ObjectLockEnabled: pulumi.String("Enabled"), + }, + Policy: pulumi.String("{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}"), + RequestPayer: pulumi.String("BucketOwner"), + ServerSideEncryptionConfigurations: s3.BucketV2ServerSideEncryptionConfigurationArray{ + &s3.BucketV2ServerSideEncryptionConfigurationArgs{ + Rules: s3.BucketV2ServerSideEncryptionConfigurationRuleArray{ + &s3.BucketV2ServerSideEncryptionConfigurationRuleArgs{ + ApplyServerSideEncryptionByDefaults: s3.BucketV2ServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArray{ + &s3.BucketV2ServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs{ + SseAlgorithm: pulumi.String("AES256"), + }, + }, + }, + }, + }, + }, + Tags: pulumi.StringMap{ + "Environment": pulumi.String("Dev"), + }, + Versionings: s3.BucketV2VersioningArray{ + &s3.BucketV2VersioningArgs{ + Enabled: pulumi.Bool(true), + }, + }, }, pulumi.Protect(true)) if err != nil { return err } _, err = s3.NewBucketServerSideEncryptionConfigurationV2(ctx, "my-bucket-encryption-configuration", &s3.BucketServerSideEncryptionConfigurationV2Args{ - Bucket: pulumi.String("my-bucket-cd24744"), + Bucket: pulumi.String("my-bucket-36224917"), Rules: s3.BucketServerSideEncryptionConfigurationV2RuleArray{ &s3.BucketServerSideEncryptionConfigurationV2RuleArgs{ ApplyServerSideEncryptionByDefault: &s3.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs{ - SseAlgorithm: pulumi.String("aws:kms"), + SseAlgorithm: pulumi.String("AES256"), + }, + }, + }, + }, pulumi.Protect(true)) + if err != nil { + return err + } + _, err = s3.NewBucketPolicy(ctx, "my-bucket-policy", &s3.BucketPolicyArgs{ + Bucket: pulumi.String("my-bucket-36224917"), + Policy: pulumi.Any("{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}"), + }, pulumi.Protect(true)) + if err != nil { + return err + } + _, err = s3.NewBucketLifecycleConfigurationV2(ctx, "my-bucket-lifecycle", &s3.BucketLifecycleConfigurationV2Args{ + Bucket: pulumi.String("my-bucket-36224917"), + Rules: s3.BucketLifecycleConfigurationV2RuleArray{ + &s3.BucketLifecycleConfigurationV2RuleArgs{ + Expiration: &s3.BucketLifecycleConfigurationV2RuleExpirationArgs{ + Days: pulumi.Int(30), }, + Id: pulumi.String("pu-s3-lifecycle-20240918194815251100000001"), + Status: pulumi.String("Enabled"), }, }, }, pulumi.Protect(true)) if err != nil { return err } + _, err = s3.NewBucketObjectLockConfigurationV2(ctx, "my-bucket-object-lock-configuration", &s3.BucketObjectLockConfigurationV2Args{ + Bucket: pulumi.String("my-bucket-36224917"), + ObjectLockEnabled: pulumi.String("Enabled"), + }, pulumi.Protect(true)) + if err != nil { + return err + } + _, err = s3.NewBucketVersioningV2(ctx, "my-bucket-versioning", &s3.BucketVersioningV2Args{ + Bucket: pulumi.String("my-bucket-36224917"), + VersioningConfiguration: &s3.BucketVersioningV2VersioningConfigurationArgs{ + MfaDelete: pulumi.String("Disabled"), + Status: pulumi.String("Enabled"), + }, + }, pulumi.Protect(true)) + if err != nil { + return err + } return nil }) } @@ -2448,11 +2849,74 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.BucketV2("my-bucket", new() { - Bucket = "my-bucket-cd24744", + Bucket = "my-bucket-36224917", + Grants = new[] + { + new Aws.S3.Inputs.BucketV2GrantArgs + { + Id = "e07865a5679c7977370948f1f1e51c21b12d8cfdd396a7e3172275d9164e01b8", + Permissions = new[] + { + "FULL_CONTROL", + }, + Type = "CanonicalUser", + }, + }, + LifecycleRules = new[] + { + new Aws.S3.Inputs.BucketV2LifecycleRuleArgs + { + Enabled = true, + Expirations = new[] + { + new Aws.S3.Inputs.BucketV2LifecycleRuleExpirationArgs + { + Days = 30, + }, + }, + Id = "pu-s3-lifecycle-20240918194815251100000001", + }, + }, + ObjectLockConfiguration = new Aws.S3.Inputs.BucketV2ObjectLockConfigurationArgs + { + ObjectLockEnabled = "Enabled", + }, + Policy = "{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", + RequestPayer = "BucketOwner", + ServerSideEncryptionConfigurations = new[] + { + new Aws.S3.Inputs.BucketV2ServerSideEncryptionConfigurationArgs + { + Rules = new[] + { + new Aws.S3.Inputs.BucketV2ServerSideEncryptionConfigurationRuleArgs + { + ApplyServerSideEncryptionByDefaults = new[] + { + new Aws.S3.Inputs.BucketV2ServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs + { + SseAlgorithm = "AES256", + }, + }, + }, + }, + }, + }, + Tags = + { + { "Environment", "Dev" }, + }, + Versionings = new[] + { + new Aws.S3.Inputs.BucketV2VersioningArgs + { + Enabled = true, + }, + }, }, new CustomResourceOptions { Protect = true, @@ -2460,14 +2924,14 @@ return await Deployment.RunAsync(() => var myBucketEncryptionConfiguration = new Aws.S3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", new() { - Bucket = "my-bucket-cd24744", + Bucket = "my-bucket-36224917", Rules = new[] { new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationV2RuleArgs { ApplyServerSideEncryptionByDefault = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs { - SseAlgorithm = "aws:kms", + SseAlgorithm = "AES256", }, }, }, @@ -2476,14 +2940,65 @@ return await Deployment.RunAsync(() => Protect = true, }); -}); - - -``` - -{{% /choosable %}} + var myBucketPolicy = new Aws.S3.BucketPolicy("my-bucket-policy", new() + { + Bucket = "my-bucket-36224917", + Policy = "{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", + }, new CustomResourceOptions + { + Protect = true, + }); -{{% choosable language java %}} + var myBucketLifecycle = new Aws.S3.BucketLifecycleConfigurationV2("my-bucket-lifecycle", new() + { + Bucket = "my-bucket-36224917", + Rules = new[] + { + new Aws.S3.Inputs.BucketLifecycleConfigurationV2RuleArgs + { + Expiration = new Aws.S3.Inputs.BucketLifecycleConfigurationV2RuleExpirationArgs + { + Days = 30, + }, + Id = "pu-s3-lifecycle-20240918194815251100000001", + Status = "Enabled", + }, + }, + }, new CustomResourceOptions + { + Protect = true, + }); + + var myBucketObjectLockConfiguration = new Aws.S3.BucketObjectLockConfigurationV2("my-bucket-object-lock-configuration", new() + { + Bucket = "my-bucket-36224917", + ObjectLockEnabled = "Enabled", + }, new CustomResourceOptions + { + Protect = true, + }); + + var myBucketVersioning = new Aws.S3.BucketVersioningV2("my-bucket-versioning", new() + { + Bucket = "my-bucket-36224917", + VersioningConfiguration = new Aws.S3.Inputs.BucketVersioningV2VersioningConfigurationArgs + { + MfaDelete = "Disabled", + Status = "Enabled", + }, + }, new CustomResourceOptions + { + Protect = true, + }); + +}); + + +``` + +{{% /choosable %}} + +{{% choosable language java %}} ```java package generated_program; @@ -2493,10 +3008,26 @@ import com.pulumi.Pulumi; import com.pulumi.core.Output; import com.pulumi.aws.s3.BucketV2; import com.pulumi.aws.s3.BucketV2Args; +import com.pulumi.aws.s3.inputs.BucketV2GrantArgs; +import com.pulumi.aws.s3.inputs.BucketV2LifecycleRuleArgs; +import com.pulumi.aws.s3.inputs.BucketV2ObjectLockConfigurationArgs; +import com.pulumi.aws.s3.inputs.BucketV2ServerSideEncryptionConfigurationArgs; +import com.pulumi.aws.s3.inputs.BucketV2VersioningArgs; import com.pulumi.aws.s3.BucketServerSideEncryptionConfigurationV2; import com.pulumi.aws.s3.BucketServerSideEncryptionConfigurationV2Args; import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationV2RuleArgs; import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs; +import com.pulumi.aws.s3.BucketPolicy; +import com.pulumi.aws.s3.BucketPolicyArgs; +import com.pulumi.aws.s3.BucketLifecycleConfigurationV2; +import com.pulumi.aws.s3.BucketLifecycleConfigurationV2Args; +import com.pulumi.aws.s3.inputs.BucketLifecycleConfigurationV2RuleArgs; +import com.pulumi.aws.s3.inputs.BucketLifecycleConfigurationV2RuleExpirationArgs; +import com.pulumi.aws.s3.BucketObjectLockConfigurationV2; +import com.pulumi.aws.s3.BucketObjectLockConfigurationV2Args; +import com.pulumi.aws.s3.BucketVersioningV2; +import com.pulumi.aws.s3.BucketVersioningV2Args; +import com.pulumi.aws.s3.inputs.BucketVersioningV2VersioningConfigurationArgs; import com.pulumi.resources.CustomResourceOptions; import java.util.List; import java.util.ArrayList; @@ -2512,17 +3043,82 @@ public class App { public static void stack(Context ctx) { var myBucket = new BucketV2("myBucket", BucketV2Args.builder() - .bucket("my-bucket-cd24744") + .bucket("my-bucket-36224917") + .grants(BucketV2GrantArgs.builder() + .id("e07865a5679c7977370948f1f1e51c21b12d8cfdd396a7e3172275d9164e01b8") + .permissions("FULL_CONTROL") + .type("CanonicalUser") + .build()) + .lifecycleRules(BucketV2LifecycleRuleArgs.builder() + .enabled(true) + .expirations(BucketV2LifecycleRuleExpirationArgs.builder() + .days(30) + .build()) + .id("pu-s3-lifecycle-20240918194815251100000001") + .build()) + .objectLockConfiguration(BucketV2ObjectLockConfigurationArgs.builder() + .objectLockEnabled("Enabled") + .build()) + .policy("{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}") + .requestPayer("BucketOwner") + .serverSideEncryptionConfigurations(BucketV2ServerSideEncryptionConfigurationArgs.builder() + .rules(BucketV2ServerSideEncryptionConfigurationRuleArgs.builder() + .applyServerSideEncryptionByDefaults(BucketV2ServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs.builder() + .sseAlgorithm("AES256") + .build()) + .build()) + .build()) + .tags(Map.of("Environment", "Dev")) + .versionings(BucketV2VersioningArgs.builder() + .enabled(true) + .build()) .build(), CustomResourceOptions.builder() .protect(true) .build()); var myBucketEncryptionConfiguration = new BucketServerSideEncryptionConfigurationV2("myBucketEncryptionConfiguration", BucketServerSideEncryptionConfigurationV2Args.builder() - .bucket("my-bucket-cd24744") + .bucket("my-bucket-36224917") .rules(BucketServerSideEncryptionConfigurationV2RuleArgs.builder() .applyServerSideEncryptionByDefault(BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs.builder() - .sseAlgorithm("aws:kms") + .sseAlgorithm("AES256") + .build()) + .build()) + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + var myBucketPolicy = new BucketPolicy("myBucketPolicy", BucketPolicyArgs.builder() + .bucket("my-bucket-36224917") + .policy("{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}") + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + var myBucketLifecycle = new BucketLifecycleConfigurationV2("myBucketLifecycle", BucketLifecycleConfigurationV2Args.builder() + .bucket("my-bucket-36224917") + .rules(BucketLifecycleConfigurationV2RuleArgs.builder() + .expiration(BucketLifecycleConfigurationV2RuleExpirationArgs.builder() + .days(30) .build()) + .id("pu-s3-lifecycle-20240918194815251100000001") + .status("Enabled") + .build()) + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + var myBucketObjectLockConfiguration = new BucketObjectLockConfigurationV2("myBucketObjectLockConfiguration", BucketObjectLockConfigurationV2Args.builder() + .bucket("my-bucket-36224917") + .objectLockEnabled("Enabled") + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + var myBucketVersioning = new BucketVersioningV2("myBucketVersioning", BucketVersioningV2Args.builder() + .bucket("my-bucket-36224917") + .versioningConfiguration(BucketVersioningV2VersioningConfigurationArgs.builder() + .mfaDelete("Disabled") + .status("Enabled") .build()) .build(), CustomResourceOptions.builder() .protect(true) @@ -2636,7 +3232,401 @@ warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verificatio - To mitigate, edit the program to remove the deprecated inputs, leaving the final simplify program that should still result in an empty `pulumi preview`: -{{< chooser >}} +{{< chooser language "typescript,python,go,csharp,java,yaml" >}} + +{{% choosable language typescript %}} + +```typescript +import * as pulumi from "@pulumi/pulumi"; +import * as aws from "@pulumi/aws"; + +const myBucket = new aws.s3.BucketV2("my-bucket", { + bucket: "my-bucket-36224917", + tags: { + Environment: "Dev", + }, +}, { + protect: true, +}); +const myBucketEncryptionConfiguration = new aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", { + bucket: "my-bucket-36224917", + rules: [{ + applyServerSideEncryptionByDefault: { + sseAlgorithm: "AES256", + }, + }], +}, { + protect: true, +}); +const myBucketPolicy = new aws.s3.BucketPolicy("my-bucket-policy", { + bucket: "my-bucket-36224917", + policy: "{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", +}, { + protect: true, +}); +const myBucketLifecycle = new aws.s3.BucketLifecycleConfigurationV2("my-bucket-lifecycle", { + bucket: "my-bucket-36224917", + rules: [{ + expiration: { + days: 30, + }, + id: "pu-s3-lifecycle-20240918194815251100000001", + status: "Enabled", + }], +}, { + protect: true, +}); +const myBucketObjectLockConfiguration = new aws.s3.BucketObjectLockConfigurationV2("my-bucket-object-lock-configuration", { + bucket: "my-bucket-36224917", + objectLockEnabled: "Enabled", +}, { + protect: true, +}); +const myBucketVersioning = new aws.s3.BucketVersioningV2("my-bucket-versioning", { + bucket: "my-bucket-36224917", + versioningConfiguration: { + mfaDelete: "Disabled", + status: "Enabled", + }, +}, { + protect: true, +}); + +``` + +{{% /choosable %}} + +{{% choosable language python %}} + +```python +import pulumi +import pulumi_aws as aws + +my_bucket = aws.s3.BucketV2("my-bucket", + bucket="my-bucket-36224917", + tags={ + "Environment": "Dev", + }, + opts = pulumi.ResourceOptions(protect=True)) +my_bucket_encryption_configuration = aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", + bucket="my-bucket-36224917", + rules=[{ + "apply_server_side_encryption_by_default": { + "sse_algorithm": "AES256", + }, + }], + opts = pulumi.ResourceOptions(protect=True)) +my_bucket_policy = aws.s3.BucketPolicy("my-bucket-policy", + bucket="my-bucket-36224917", + policy="{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", + opts = pulumi.ResourceOptions(protect=True)) +my_bucket_lifecycle = aws.s3.BucketLifecycleConfigurationV2("my-bucket-lifecycle", + bucket="my-bucket-36224917", + rules=[{ + "expiration": { + "days": 30, + }, + "id": "pu-s3-lifecycle-20240918194815251100000001", + "status": "Enabled", + }], + opts = pulumi.ResourceOptions(protect=True)) +my_bucket_object_lock_configuration = aws.s3.BucketObjectLockConfigurationV2("my-bucket-object-lock-configuration", + bucket="my-bucket-36224917", + object_lock_enabled="Enabled", + opts = pulumi.ResourceOptions(protect=True)) +my_bucket_versioning = aws.s3.BucketVersioningV2("my-bucket-versioning", + bucket="my-bucket-36224917", + versioning_configuration={ + "mfa_delete": "Disabled", + "status": "Enabled", + }, + opts = pulumi.ResourceOptions(protect=True)) + +``` + +{{% /choosable %}} + +{{% choosable language go %}} + +```go +package main + +import ( + "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + _, err := s3.NewBucketV2(ctx, "my-bucket", &s3.BucketV2Args{ + Bucket: pulumi.String("my-bucket-36224917"), + Tags: pulumi.StringMap{ + "Environment": pulumi.String("Dev"), + }, + }, pulumi.Protect(true)) + if err != nil { + return err + } + _, err = s3.NewBucketServerSideEncryptionConfigurationV2(ctx, "my-bucket-encryption-configuration", &s3.BucketServerSideEncryptionConfigurationV2Args{ + Bucket: pulumi.String("my-bucket-36224917"), + Rules: s3.BucketServerSideEncryptionConfigurationV2RuleArray{ + &s3.BucketServerSideEncryptionConfigurationV2RuleArgs{ + ApplyServerSideEncryptionByDefault: &s3.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs{ + SseAlgorithm: pulumi.String("AES256"), + }, + }, + }, + }, pulumi.Protect(true)) + if err != nil { + return err + } + _, err = s3.NewBucketPolicy(ctx, "my-bucket-policy", &s3.BucketPolicyArgs{ + Bucket: pulumi.String("my-bucket-36224917"), + Policy: pulumi.Any("{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}"), + }, pulumi.Protect(true)) + if err != nil { + return err + } + _, err = s3.NewBucketLifecycleConfigurationV2(ctx, "my-bucket-lifecycle", &s3.BucketLifecycleConfigurationV2Args{ + Bucket: pulumi.String("my-bucket-36224917"), + Rules: s3.BucketLifecycleConfigurationV2RuleArray{ + &s3.BucketLifecycleConfigurationV2RuleArgs{ + Expiration: &s3.BucketLifecycleConfigurationV2RuleExpirationArgs{ + Days: pulumi.Int(30), + }, + Id: pulumi.String("pu-s3-lifecycle-20240918194815251100000001"), + Status: pulumi.String("Enabled"), + }, + }, + }, pulumi.Protect(true)) + if err != nil { + return err + } + _, err = s3.NewBucketObjectLockConfigurationV2(ctx, "my-bucket-object-lock-configuration", &s3.BucketObjectLockConfigurationV2Args{ + Bucket: pulumi.String("my-bucket-36224917"), + ObjectLockEnabled: pulumi.String("Enabled"), + }, pulumi.Protect(true)) + if err != nil { + return err + } + _, err = s3.NewBucketVersioningV2(ctx, "my-bucket-versioning", &s3.BucketVersioningV2Args{ + Bucket: pulumi.String("my-bucket-36224917"), + VersioningConfiguration: &s3.BucketVersioningV2VersioningConfigurationArgs{ + MfaDelete: pulumi.String("Disabled"), + Status: pulumi.String("Enabled"), + }, + }, pulumi.Protect(true)) + if err != nil { + return err + } + return nil + }) +} + +``` + +{{% /choosable %}} + +{{% choosable language csharp %}} + +```csharp +using System.Collections.Generic; +using System.Linq; +using Pulumi; +using Aws = Pulumi.Aws; + +return await Deployment.RunAsync(() => +{ + var myBucket = new Aws.S3.BucketV2("my-bucket", new() + { + Bucket = "my-bucket-36224917", + Tags = + { + { "Environment", "Dev" }, + }, + }, new CustomResourceOptions + { + Protect = true, + }); + + var myBucketEncryptionConfiguration = new Aws.S3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", new() + { + Bucket = "my-bucket-36224917", + Rules = new[] + { + new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationV2RuleArgs + { + ApplyServerSideEncryptionByDefault = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs + { + SseAlgorithm = "AES256", + }, + }, + }, + }, new CustomResourceOptions + { + Protect = true, + }); + + var myBucketPolicy = new Aws.S3.BucketPolicy("my-bucket-policy", new() + { + Bucket = "my-bucket-36224917", + Policy = "{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", + }, new CustomResourceOptions + { + Protect = true, + }); + + var myBucketLifecycle = new Aws.S3.BucketLifecycleConfigurationV2("my-bucket-lifecycle", new() + { + Bucket = "my-bucket-36224917", + Rules = new[] + { + new Aws.S3.Inputs.BucketLifecycleConfigurationV2RuleArgs + { + Expiration = new Aws.S3.Inputs.BucketLifecycleConfigurationV2RuleExpirationArgs + { + Days = 30, + }, + Id = "pu-s3-lifecycle-20240918194815251100000001", + Status = "Enabled", + }, + }, + }, new CustomResourceOptions + { + Protect = true, + }); + + var myBucketObjectLockConfiguration = new Aws.S3.BucketObjectLockConfigurationV2("my-bucket-object-lock-configuration", new() + { + Bucket = "my-bucket-36224917", + ObjectLockEnabled = "Enabled", + }, new CustomResourceOptions + { + Protect = true, + }); + + var myBucketVersioning = new Aws.S3.BucketVersioningV2("my-bucket-versioning", new() + { + Bucket = "my-bucket-36224917", + VersioningConfiguration = new Aws.S3.Inputs.BucketVersioningV2VersioningConfigurationArgs + { + MfaDelete = "Disabled", + Status = "Enabled", + }, + }, new CustomResourceOptions + { + Protect = true, + }); + +}); + + +``` + +{{% /choosable %}} + +{{% choosable language java %}} + +```java +package generated_program; + +import com.pulumi.Context; +import com.pulumi.Pulumi; +import com.pulumi.core.Output; +import com.pulumi.aws.s3.BucketV2; +import com.pulumi.aws.s3.BucketV2Args; +import com.pulumi.aws.s3.BucketServerSideEncryptionConfigurationV2; +import com.pulumi.aws.s3.BucketServerSideEncryptionConfigurationV2Args; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationV2RuleArgs; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs; +import com.pulumi.aws.s3.BucketPolicy; +import com.pulumi.aws.s3.BucketPolicyArgs; +import com.pulumi.aws.s3.BucketLifecycleConfigurationV2; +import com.pulumi.aws.s3.BucketLifecycleConfigurationV2Args; +import com.pulumi.aws.s3.inputs.BucketLifecycleConfigurationV2RuleArgs; +import com.pulumi.aws.s3.inputs.BucketLifecycleConfigurationV2RuleExpirationArgs; +import com.pulumi.aws.s3.BucketObjectLockConfigurationV2; +import com.pulumi.aws.s3.BucketObjectLockConfigurationV2Args; +import com.pulumi.aws.s3.BucketVersioningV2; +import com.pulumi.aws.s3.BucketVersioningV2Args; +import com.pulumi.aws.s3.inputs.BucketVersioningV2VersioningConfigurationArgs; +import com.pulumi.resources.CustomResourceOptions; +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 myBucket = new BucketV2("myBucket", BucketV2Args.builder() + .bucket("my-bucket-36224917") + .tags(Map.of("Environment", "Dev")) + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + var myBucketEncryptionConfiguration = new BucketServerSideEncryptionConfigurationV2("myBucketEncryptionConfiguration", BucketServerSideEncryptionConfigurationV2Args.builder() + .bucket("my-bucket-36224917") + .rules(BucketServerSideEncryptionConfigurationV2RuleArgs.builder() + .applyServerSideEncryptionByDefault(BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs.builder() + .sseAlgorithm("AES256") + .build()) + .build()) + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + var myBucketPolicy = new BucketPolicy("myBucketPolicy", BucketPolicyArgs.builder() + .bucket("my-bucket-36224917") + .policy("{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}") + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + var myBucketLifecycle = new BucketLifecycleConfigurationV2("myBucketLifecycle", BucketLifecycleConfigurationV2Args.builder() + .bucket("my-bucket-36224917") + .rules(BucketLifecycleConfigurationV2RuleArgs.builder() + .expiration(BucketLifecycleConfigurationV2RuleExpirationArgs.builder() + .days(30) + .build()) + .id("pu-s3-lifecycle-20240918194815251100000001") + .status("Enabled") + .build()) + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + var myBucketObjectLockConfiguration = new BucketObjectLockConfigurationV2("myBucketObjectLockConfiguration", BucketObjectLockConfigurationV2Args.builder() + .bucket("my-bucket-36224917") + .objectLockEnabled("Enabled") + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + var myBucketVersioning = new BucketVersioningV2("myBucketVersioning", BucketVersioningV2Args.builder() + .bucket("my-bucket-36224917") + .versioningConfiguration(BucketVersioningV2VersioningConfigurationArgs.builder() + .mfaDelete("Disabled") + .status("Enabled") + .build()) + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + } +} + +``` + +{{% /choosable %}} + +{{% choosable language yaml %}} ```yaml name: y2 @@ -2695,6 +3685,8 @@ resources: protect: true ``` +{{% /choosable %}} + {{< /chooser >}} ## Historical context From 952e353321091175e8735a0795c626431f0853a7 Mon Sep 17 00:00:00 2001 From: Anton Tayanovskyy Date: Fri, 20 Sep 2024 11:43:52 -0400 Subject: [PATCH 18/20] Flip the sections to recommend the data-loss-free option by default --- .../aws/how-to-guides/bucketv2-migration.md | 4011 +++++++++-------- 1 file changed, 2008 insertions(+), 2003 deletions(-) diff --git a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md index 67f434d13d..026f49c306 100644 --- a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md +++ b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md @@ -16,17 +16,28 @@ To migrate existing `aws.s3.Bucket` resources to `aws.s3.BucketV2`: `BucketV2` inputs such as `policy` and `accelerationStatus` are to be replaced by side-by-side resources `aws.s3.BucketPolicy` and `aws.s3.BucketAccelerateConfigurationV2`. -2. Perform `pulumi up` to replace the buckets in AWS. **WARNING**: replacing the buckets will delete and re-create them, - losing any data stored in these buckets. If this is not acceptable, consider using `pulumi import` to migrate +2. Perorm this is not acceptable, consider using `pulumi import` to migrate manually instead as outlined in the "Avoiding replacement" section. -## Migrating deprecated inputs +## Migrating with `pulumi import` -### policy input +This migration path is recommended in situations when replacing the bucket in the AWS account is not acceptable. After +performing the steps your Pulumi program and state will be updated to track buckets using the new resource without +executing any changes against the actual cloud account. The steps involve: -To specify a -[bucket policy](https://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html), -instead of: +- Find URNs for legacy Bucket Pulumi resources using `pulumi stack export` +- Determine the actual bucket name(s) +- Remove the legacy Bucket code from your Pulumi program source +- Remove the legacy Bucket resources from state using `pulumi state delete $bucketURN` +- Determine which side-by-side resources will be needed for each bucket +- Construct an `pulumi-import.json` file listing the buckets and their side-by-side resources +- Run `pulumi import --file import-file.json` using the [Bulk Importing](https://www.pulumi.com/tutorials/importing/bulk-importing/) feature +- Add the suggested code into your Pulumi program source +- Run `pulumi preview` to confirm a no-change plan +- If warnings are generated, edit the program to remove deprecated inputs from BucketV2 +- Run `pulumi preview` one more time to confirm a no-change plan on the final program + +Consider a concrete example, suppose you have provisioned a bucket as follows: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -37,23 +48,45 @@ import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; const myBucket = new aws.s3.Bucket("my-bucket", { - bucket: "my-bucket-26224916", + bucket: "my-bucket-26224917", + serverSideEncryptionConfiguration: { + rule: { + applyServerSideEncryptionByDefault: { + sseAlgorithm: "AES256", + }, + }, + }, + lifecycleRules: [{ + enabled: true, + expiration: { + days: 30, + }, + }], policy: JSON.stringify({ Version: "2012-10-17", Id: "PutObjPolicy", - Statement: { + Statement: [{ Sid: "DenyObjectsThatAreNotSSEKMS", Principal: "*", Effect: "Deny", Action: "s3:PutObject", - Resource: "arn:aws:s3:::my-bucket-26224916/*", + Resource: "arn:aws:s3:::my-bucket-26224917/*", Condition: { Null: { "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", }, }, - }, + }], }), + tags: { + Environment: "Dev", + }, + objectLockConfiguration: { + objectLockEnabled: "Enabled", + }, + versioning: { + enabled: true, + }, }); ``` @@ -68,23 +101,45 @@ import json import pulumi_aws as aws my_bucket = aws.s3.Bucket("my-bucket", - bucket="my-bucket-26224916", + bucket="my-bucket-26224917", + server_side_encryption_configuration={ + "rule": { + "apply_server_side_encryption_by_default": { + "sse_algorithm": "AES256", + }, + }, + }, + lifecycle_rules=[{ + "enabled": True, + "expiration": { + "days": 30, + }, + }], policy=json.dumps({ "Version": "2012-10-17", "Id": "PutObjPolicy", - "Statement": { + "Statement": [{ "Sid": "DenyObjectsThatAreNotSSEKMS", "Principal": "*", "Effect": "Deny", "Action": "s3:PutObject", - "Resource": "arn:aws:s3:::my-bucket-26224916/*", + "Resource": "arn:aws:s3:::my-bucket-26224917/*", "Condition": { "Null": { "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", }, }, - }, - })) + }], + }), + tags={ + "Environment": "Dev", + }, + object_lock_configuration={ + "object_lock_enabled": "Enabled", + }, + versioning={ + "enabled": True, + }) ``` @@ -107,15 +162,17 @@ func main() { tmpJSON0, err := json.Marshal(map[string]interface{}{ "Version": "2012-10-17", "Id": "PutObjPolicy", - "Statement": map[string]interface{}{ - "Sid": "DenyObjectsThatAreNotSSEKMS", - "Principal": "*", - "Effect": "Deny", - "Action": "s3:PutObject", - "Resource": "arn:aws:s3:::my-bucket-26224916/*", - "Condition": map[string]interface{}{ - "Null": map[string]interface{}{ - "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", + "Statement": []map[string]interface{}{ + map[string]interface{}{ + "Sid": "DenyObjectsThatAreNotSSEKMS", + "Principal": "*", + "Effect": "Deny", + "Action": "s3:PutObject", + "Resource": "arn:aws:s3:::my-bucket-26224917/*", + "Condition": map[string]interface{}{ + "Null": map[string]interface{}{ + "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", + }, }, }, }, @@ -125,8 +182,32 @@ func main() { } json0 := string(tmpJSON0) _, err = s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{ - Bucket: pulumi.String("my-bucket-26224916"), + Bucket: pulumi.String("my-bucket-26224917"), + ServerSideEncryptionConfiguration: &s3.BucketServerSideEncryptionConfigurationArgs{ + Rule: &s3.BucketServerSideEncryptionConfigurationRuleArgs{ + ApplyServerSideEncryptionByDefault: &s3.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs{ + SseAlgorithm: pulumi.String("AES256"), + }, + }, + }, + LifecycleRules: s3.BucketLifecycleRuleArray{ + &s3.BucketLifecycleRuleArgs{ + Enabled: pulumi.Bool(true), + Expiration: &s3.BucketLifecycleRuleExpirationArgs{ + Days: pulumi.Int(30), + }, + }, + }, Policy: pulumi.String(json0), + Tags: pulumi.StringMap{ + "Environment": pulumi.String("Dev"), + }, + ObjectLockConfiguration: &s3.BucketObjectLockConfigurationArgs{ + ObjectLockEnabled: pulumi.String("Enabled"), + }, + Versioning: &s3.BucketVersioningArgs{ + Enabled: pulumi.Bool(true), + }, }) if err != nil { return err @@ -148,31 +229,67 @@ using System.Text.Json; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { var myBucket = new Aws.S3.Bucket("my-bucket", new() { - BucketName = "my-bucket-26224916", + BucketName = "my-bucket-26224917", + ServerSideEncryptionConfiguration = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationArgs + { + Rule = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationRuleArgs + { + ApplyServerSideEncryptionByDefault = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs + { + SseAlgorithm = "AES256", + }, + }, + }, + LifecycleRules = new[] + { + new Aws.S3.Inputs.BucketLifecycleRuleArgs + { + Enabled = true, + Expiration = new Aws.S3.Inputs.BucketLifecycleRuleExpirationArgs + { + Days = 30, + }, + }, + }, Policy = JsonSerializer.Serialize(new Dictionary { ["Version"] = "2012-10-17", ["Id"] = "PutObjPolicy", - ["Statement"] = new Dictionary + ["Statement"] = new[] { - ["Sid"] = "DenyObjectsThatAreNotSSEKMS", - ["Principal"] = "*", - ["Effect"] = "Deny", - ["Action"] = "s3:PutObject", - ["Resource"] = "arn:aws:s3:::my-bucket-26224916/*", - ["Condition"] = new Dictionary + new Dictionary { - ["Null"] = new Dictionary + ["Sid"] = "DenyObjectsThatAreNotSSEKMS", + ["Principal"] = "*", + ["Effect"] = "Deny", + ["Action"] = "s3:PutObject", + ["Resource"] = "arn:aws:s3:::my-bucket-26224917/*", + ["Condition"] = new Dictionary { - ["s3:x-amz-server-side-encryption-aws-kms-key-id"] = "true", + ["Null"] = new Dictionary + { + ["s3:x-amz-server-side-encryption-aws-kms-key-id"] = "true", + }, }, }, }, }), + Tags = + { + { "Environment", "Dev" }, + }, + ObjectLockConfiguration = new Aws.S3.Inputs.BucketObjectLockConfigurationArgs + { + ObjectLockEnabled = "Enabled", + }, + Versioning = new Aws.S3.Inputs.BucketVersioningArgs + { + Enabled = true, + }, }); }); @@ -192,6 +309,13 @@ 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.inputs.BucketServerSideEncryptionConfigurationArgs; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationRuleArgs; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs; +import com.pulumi.aws.s3.inputs.BucketLifecycleRuleArgs; +import com.pulumi.aws.s3.inputs.BucketLifecycleRuleExpirationArgs; +import com.pulumi.aws.s3.inputs.BucketObjectLockConfigurationArgs; +import com.pulumi.aws.s3.inputs.BucketVersioningArgs; import static com.pulumi.codegen.internal.Serialization.*; import java.util.List; import java.util.ArrayList; @@ -207,24 +331,44 @@ public class App { public static void stack(Context ctx) { var myBucket = new Bucket("myBucket", BucketArgs.builder() - .bucket("my-bucket-26224916") + .bucket("my-bucket-26224917") + .serverSideEncryptionConfiguration(BucketServerSideEncryptionConfigurationArgs.builder() + .rule(BucketServerSideEncryptionConfigurationRuleArgs.builder() + .applyServerSideEncryptionByDefault(BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs.builder() + .sseAlgorithm("AES256") + .build()) + .build()) + .build()) + .lifecycleRules(BucketLifecycleRuleArgs.builder() + .enabled(true) + .expiration(BucketLifecycleRuleExpirationArgs.builder() + .days(30) + .build()) + .build()) .policy(serializeJson( jsonObject( jsonProperty("Version", "2012-10-17"), jsonProperty("Id", "PutObjPolicy"), - jsonProperty("Statement", jsonObject( + jsonProperty("Statement", jsonArray(jsonObject( jsonProperty("Sid", "DenyObjectsThatAreNotSSEKMS"), jsonProperty("Principal", "*"), jsonProperty("Effect", "Deny"), jsonProperty("Action", "s3:PutObject"), - jsonProperty("Resource", "arn:aws:s3:::my-bucket-26224916/*"), + jsonProperty("Resource", "arn:aws:s3:::my-bucket-26224917/*"), jsonProperty("Condition", jsonObject( jsonProperty("Null", jsonObject( jsonProperty("s3:x-amz-server-side-encryption-aws-kms-key-id", "true") )) )) - )) + ))) ))) + .tags(Map.of("Environment", "Dev")) + .objectLockConfiguration(BucketObjectLockConfigurationArgs.builder() + .objectLockEnabled("Enabled") + .build()) + .versioning(BucketVersioningArgs.builder() + .enabled(true) + .build()) .build()); } @@ -237,37 +381,106 @@ public class App { {{% choosable language yaml %}} ```yaml -name: example +name: y2 runtime: yaml resources: my-bucket: type: aws:s3:Bucket properties: - bucket: "my-bucket-26224916" + bucket: "my-bucket-26224917" + serverSideEncryptionConfiguration: + rule: + applyServerSideEncryptionByDefault: + sseAlgorithm: "AES256" + lifecycleRules: + - enabled: true + expiration: + days: 30 policy: fn::toJSON: - Version: 2012-10-17 - Id: PutObjPolicy + Version: "2012-10-17" + Id: "PutObjPolicy" Statement: - Sid: DenyObjectsThatAreNotSSEKMS - Principal: "*" - Effect: Deny - Action: s3:PutObject - Resource: "arn:aws:s3:::my-bucket-26224916/*" - Condition: - "Null": - s3:x-amz-server-side-encryption-aws-kms-key-id: "true" + - Sid: "DenyObjectsThatAreNotSSEKMS" + Principal: "*" + Effect: "Deny" + Action: "s3:PutObject" + Resource: "arn:aws:s3:::my-bucket-26224917/*" + Condition: + "Null": + "s3:x-amz-server-side-encryption-aws-kms-key-id": "true" + tags: + Environment: "Dev" + objectLockConfiguration: + objectLockEnabled: "Enabled" + versioning: + enabled: true ``` {{% /choosable %}} {{< /chooser >}} +Migrate as follows: +- Scanning through the state in `pulumi stack export`, observe and note its URN is + `"urn:pulumi:bucket1::y2::aws:s3/bucket:Bucket::my-bucket"` +- The state file should also include the actual cloud name for the bucket such as `"bucket": "my-bucket-36224917"` +- Run `pulumi state delete "urn:pulumi:bucket1::y2::aws:s3/bucket:Bucket::my-bucket"` to remove the old bucket from the + state -Use the `aws.s3.BucketPolicy` resource: +- Delete the code for the old bucket from the sources. + +- This bucket will require the following side-by-side resources: + + aws:s3:BucketServerSideEncryptionConfigurationV2 + aws:s3:BucketLifecycleConfigurationV2 + aws:s3:BucketPolicy + aws:s3:BucketObjectLockConfigurationV2 + aws:s3:BucketVersioningV2 + +- The import file should therefore look like this: + + ```json + { + "resources": [ + { + "type": "aws:s3/bucketV2:BucketV2", + "name": "my-bucket2", + "id": "my-bucket-36224917" + }, + { + "type": "aws:s3/bucketServerSideEncryptionConfigurationV2:BucketServerSideEncryptionConfigurationV2", + "name": "my-bucket-encryption-configuration", + "id": "my-bucket-36224917" + }, + { + "type": "aws:s3/bucketPolicy:BucketPolicy", + "name": "my-bucket-policy", + "id": "my-bucket-36224917" + }, + { + "type": "aws:s3/bucketLifecycleConfigurationV2:BucketLifecycleConfigurationV2", + "name": "my-bucket-policy", + "id": "my-bucket-36224917" + }, + { + "type": "aws:s3/bucketObjectLockConfigurationV2:BucketObjectLockConfigurationV2", + "name": "my-bucket-object-lock-configuration", + "id": "my-bucket-36224917" + }, + { + "type": "aws:s3/bucketVersioningV2:BucketVersioningV2", + "name": "my-bucket-versioning", + "id": "my-bucket-36224917" + } + ] + } + ``` + +- `pulumi import --file import-file.json` will suggest new code to include in your program, for example: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -277,25 +490,83 @@ Use the `aws.s3.BucketPolicy` resource: import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; -const myBucket = new aws.s3.BucketV2("my-bucket", {}); +const myBucket = new aws.s3.BucketV2("my-bucket", { + bucket: "my-bucket-36224917", + grants: [{ + id: "e07865a5679c7977370948f1f1e51c21b12d8cfdd396a7e3172275d9164e01b8", + permissions: ["FULL_CONTROL"], + type: "CanonicalUser", + }], + lifecycleRules: [{ + enabled: true, + expirations: [{ + days: 30, + }], + id: "pu-s3-lifecycle-20240918194815251100000001", + }], + objectLockConfiguration: { + objectLockEnabled: "Enabled", + }, + policy: "{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", + requestPayer: "BucketOwner", + serverSideEncryptionConfigurations: [{ + rules: [{ + applyServerSideEncryptionByDefaults: [{ + sseAlgorithm: "AES256", + }], + }], + }], + tags: { + Environment: "Dev", + }, + versionings: [{ + enabled: true, + }], +}, { + protect: true, +}); +const myBucketEncryptionConfiguration = new aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", { + bucket: "my-bucket-36224917", + rules: [{ + applyServerSideEncryptionByDefault: { + sseAlgorithm: "AES256", + }, + }], +}, { + protect: true, +}); const myBucketPolicy = new aws.s3.BucketPolicy("my-bucket-policy", { - bucket: myBucket.bucket, - policy: pulumi.jsonStringify({ - Version: "2012-10-17", - Id: "PutObjPolicy", - Statement: { - Sid: "DenyObjectsThatAreNotSSEKMS", - Principal: "*", - Effect: "Deny", - Action: "s3:PutObject", - Resource: pulumi.interpolate`arn:aws:s3:::${myBucket.bucket}/*`, - Condition: { - Null: { - "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", - }, - }, + bucket: "my-bucket-36224917", + policy: "{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", +}, { + protect: true, +}); +const myBucketLifecycle = new aws.s3.BucketLifecycleConfigurationV2("my-bucket-lifecycle", { + bucket: "my-bucket-36224917", + rules: [{ + expiration: { + days: 30, }, - }), + id: "pu-s3-lifecycle-20240918194815251100000001", + status: "Enabled", + }], +}, { + protect: true, +}); +const myBucketObjectLockConfiguration = new aws.s3.BucketObjectLockConfigurationV2("my-bucket-object-lock-configuration", { + bucket: "my-bucket-36224917", + objectLockEnabled: "Enabled", +}, { + protect: true, +}); +const myBucketVersioning = new aws.s3.BucketVersioningV2("my-bucket-versioning", { + bucket: "my-bucket-36224917", + versioningConfiguration: { + mfaDelete: "Disabled", + status: "Enabled", + }, +}, { + protect: true, }); ``` @@ -306,28 +577,74 @@ const myBucketPolicy = new aws.s3.BucketPolicy("my-bucket-policy", { ```python import pulumi -import json import pulumi_aws as aws -my_bucket = aws.s3.BucketV2("my-bucket") +my_bucket = aws.s3.BucketV2("my-bucket", + bucket="my-bucket-36224917", + grants=[{ + "id": "e07865a5679c7977370948f1f1e51c21b12d8cfdd396a7e3172275d9164e01b8", + "permissions": ["FULL_CONTROL"], + "type": "CanonicalUser", + }], + lifecycle_rules=[{ + "enabled": True, + "expirations": [{ + "days": 30, + }], + "id": "pu-s3-lifecycle-20240918194815251100000001", + }], + object_lock_configuration={ + "object_lock_enabled": "Enabled", + }, + policy="{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", + request_payer="BucketOwner", + server_side_encryption_configurations=[{ + "rules": [{ + "apply_server_side_encryption_by_defaults": [{ + "sse_algorithm": "AES256", + }], + }], + }], + tags={ + "Environment": "Dev", + }, + versionings=[{ + "enabled": True, + }], + opts = pulumi.ResourceOptions(protect=True)) +my_bucket_encryption_configuration = aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", + bucket="my-bucket-36224917", + rules=[{ + "apply_server_side_encryption_by_default": { + "sse_algorithm": "AES256", + }, + }], + opts = pulumi.ResourceOptions(protect=True)) my_bucket_policy = aws.s3.BucketPolicy("my-bucket-policy", - bucket=my_bucket.bucket, - policy=pulumi.Output.json_dumps({ - "Version": "2012-10-17", - "Id": "PutObjPolicy", - "Statement": { - "Sid": "DenyObjectsThatAreNotSSEKMS", - "Principal": "*", - "Effect": "Deny", - "Action": "s3:PutObject", - "Resource": my_bucket.bucket.apply(lambda bucket: f"arn:aws:s3:::{bucket}/*"), - "Condition": { - "Null": { - "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", - }, - }, + bucket="my-bucket-36224917", + policy="{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", + opts = pulumi.ResourceOptions(protect=True)) +my_bucket_lifecycle = aws.s3.BucketLifecycleConfigurationV2("my-bucket-lifecycle", + bucket="my-bucket-36224917", + rules=[{ + "expiration": { + "days": 30, }, - })) + "id": "pu-s3-lifecycle-20240918194815251100000001", + "status": "Enabled", + }], + opts = pulumi.ResourceOptions(protect=True)) +my_bucket_object_lock_configuration = aws.s3.BucketObjectLockConfigurationV2("my-bucket-object-lock-configuration", + bucket="my-bucket-36224917", + object_lock_enabled="Enabled", + opts = pulumi.ResourceOptions(protect=True)) +my_bucket_versioning = aws.s3.BucketVersioningV2("my-bucket-versioning", + bucket="my-bucket-36224917", + versioning_configuration={ + "mfa_delete": "Disabled", + "status": "Enabled", + }, + opts = pulumi.ResourceOptions(protect=True)) ``` @@ -339,47 +656,113 @@ my_bucket_policy = aws.s3.BucketPolicy("my-bucket-policy", package main import ( - "encoding/json" - "fmt" - - "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/iam" "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" ) func main() { pulumi.Run(func(ctx *pulumi.Context) error { - myBucket, err := s3.NewBucketV2(ctx, "my-bucket", nil) - if err != nil { - return err - } - _, err = s3.NewBucketPolicy(ctx, "my-bucket-policy", &s3.BucketPolicyArgs{ - Bucket: myBucket.Bucket, - Policy: myBucket.Bucket.ApplyT(func(bucket string) (pulumi.String, error) { - var _zero pulumi.String - tmpJSON0, err := json.Marshal(map[string]interface{}{ - "Version": "2012-10-17", - "Id": "PutObjPolicy", - "Statement": map[string]interface{}{ - "Sid": "DenyObjectsThatAreNotSSEKMS", - "Principal": "*", - "Effect": "Deny", - "Action": "s3:PutObject", - "Resource": fmt.Sprintf("arn:aws:s3:::%v/*", bucket), - "Condition": map[string]interface{}{ - "Null": map[string]interface{}{ - "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", - }, - }, - }, - }) - if err != nil { - return _zero, err - } - json0 := string(tmpJSON0) - return pulumi.String(json0), nil - }).(pulumi.StringOutput), - }) + _, err := s3.NewBucketV2(ctx, "my-bucket", &s3.BucketV2Args{ + Bucket: pulumi.String("my-bucket-36224917"), + Grants: s3.BucketV2GrantArray{ + &s3.BucketV2GrantArgs{ + Id: pulumi.String("e07865a5679c7977370948f1f1e51c21b12d8cfdd396a7e3172275d9164e01b8"), + Permissions: pulumi.StringArray{ + pulumi.String("FULL_CONTROL"), + }, + Type: pulumi.String("CanonicalUser"), + }, + }, + LifecycleRules: s3.BucketV2LifecycleRuleArray{ + &s3.BucketV2LifecycleRuleArgs{ + Enabled: pulumi.Bool(true), + Expirations: s3.BucketV2LifecycleRuleExpirationArray{ + &s3.BucketV2LifecycleRuleExpirationArgs{ + Days: pulumi.Int(30), + }, + }, + Id: pulumi.String("pu-s3-lifecycle-20240918194815251100000001"), + }, + }, + ObjectLockConfiguration: &s3.BucketV2ObjectLockConfigurationArgs{ + ObjectLockEnabled: pulumi.String("Enabled"), + }, + Policy: pulumi.String("{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}"), + RequestPayer: pulumi.String("BucketOwner"), + ServerSideEncryptionConfigurations: s3.BucketV2ServerSideEncryptionConfigurationArray{ + &s3.BucketV2ServerSideEncryptionConfigurationArgs{ + Rules: s3.BucketV2ServerSideEncryptionConfigurationRuleArray{ + &s3.BucketV2ServerSideEncryptionConfigurationRuleArgs{ + ApplyServerSideEncryptionByDefaults: s3.BucketV2ServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArray{ + &s3.BucketV2ServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs{ + SseAlgorithm: pulumi.String("AES256"), + }, + }, + }, + }, + }, + }, + Tags: pulumi.StringMap{ + "Environment": pulumi.String("Dev"), + }, + Versionings: s3.BucketV2VersioningArray{ + &s3.BucketV2VersioningArgs{ + Enabled: pulumi.Bool(true), + }, + }, + }, pulumi.Protect(true)) + if err != nil { + return err + } + _, err = s3.NewBucketServerSideEncryptionConfigurationV2(ctx, "my-bucket-encryption-configuration", &s3.BucketServerSideEncryptionConfigurationV2Args{ + Bucket: pulumi.String("my-bucket-36224917"), + Rules: s3.BucketServerSideEncryptionConfigurationV2RuleArray{ + &s3.BucketServerSideEncryptionConfigurationV2RuleArgs{ + ApplyServerSideEncryptionByDefault: &s3.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs{ + SseAlgorithm: pulumi.String("AES256"), + }, + }, + }, + }, pulumi.Protect(true)) + if err != nil { + return err + } + _, err = s3.NewBucketPolicy(ctx, "my-bucket-policy", &s3.BucketPolicyArgs{ + Bucket: pulumi.String("my-bucket-36224917"), + Policy: pulumi.Any("{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}"), + }, pulumi.Protect(true)) + if err != nil { + return err + } + _, err = s3.NewBucketLifecycleConfigurationV2(ctx, "my-bucket-lifecycle", &s3.BucketLifecycleConfigurationV2Args{ + Bucket: pulumi.String("my-bucket-36224917"), + Rules: s3.BucketLifecycleConfigurationV2RuleArray{ + &s3.BucketLifecycleConfigurationV2RuleArgs{ + Expiration: &s3.BucketLifecycleConfigurationV2RuleExpirationArgs{ + Days: pulumi.Int(30), + }, + Id: pulumi.String("pu-s3-lifecycle-20240918194815251100000001"), + Status: pulumi.String("Enabled"), + }, + }, + }, pulumi.Protect(true)) + if err != nil { + return err + } + _, err = s3.NewBucketObjectLockConfigurationV2(ctx, "my-bucket-object-lock-configuration", &s3.BucketObjectLockConfigurationV2Args{ + Bucket: pulumi.String("my-bucket-36224917"), + ObjectLockEnabled: pulumi.String("Enabled"), + }, pulumi.Protect(true)) + if err != nil { + return err + } + _, err = s3.NewBucketVersioningV2(ctx, "my-bucket-versioning", &s3.BucketVersioningV2Args{ + Bucket: pulumi.String("my-bucket-36224917"), + VersioningConfiguration: &s3.BucketVersioningV2VersioningConfigurationArgs{ + MfaDelete: pulumi.String("Disabled"), + Status: pulumi.String("Enabled"), + }, + }, pulumi.Protect(true)) if err != nil { return err } @@ -396,37 +779,149 @@ func main() { ```csharp using System.Collections.Generic; using System.Linq; -using System.Text.Json; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { - var myBucket = new Aws.S3.BucketV2("my-bucket"); - - var myBucketPolicy = new Aws.S3.BucketPolicy("my-bucket-policy", new() + var myBucket = new Aws.S3.BucketV2("my-bucket", new() { - Bucket = myBucket.Bucket, - Policy = Output.JsonSerialize(Output.Create(new Dictionary + Bucket = "my-bucket-36224917", + Grants = new[] { - ["Version"] = "2012-10-17", - ["Id"] = "PutObjPolicy", - ["Statement"] = new Dictionary + new Aws.S3.Inputs.BucketV2GrantArgs { - ["Sid"] = "DenyObjectsThatAreNotSSEKMS", - ["Principal"] = "*", - ["Effect"] = "Deny", - ["Action"] = "s3:PutObject", - ["Resource"] = myBucket.Bucket.Apply(bucket => $"arn:aws:s3:::{bucket}/*"), - ["Condition"] = new Dictionary + Id = "e07865a5679c7977370948f1f1e51c21b12d8cfdd396a7e3172275d9164e01b8", + Permissions = new[] { - ["Null"] = new Dictionary + "FULL_CONTROL", + }, + Type = "CanonicalUser", + }, + }, + LifecycleRules = new[] + { + new Aws.S3.Inputs.BucketV2LifecycleRuleArgs + { + Enabled = true, + Expirations = new[] + { + new Aws.S3.Inputs.BucketV2LifecycleRuleExpirationArgs { - ["s3:x-amz-server-side-encryption-aws-kms-key-id"] = "true", + Days = 30, }, }, + Id = "pu-s3-lifecycle-20240918194815251100000001", }, - })), + }, + ObjectLockConfiguration = new Aws.S3.Inputs.BucketV2ObjectLockConfigurationArgs + { + ObjectLockEnabled = "Enabled", + }, + Policy = "{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", + RequestPayer = "BucketOwner", + ServerSideEncryptionConfigurations = new[] + { + new Aws.S3.Inputs.BucketV2ServerSideEncryptionConfigurationArgs + { + Rules = new[] + { + new Aws.S3.Inputs.BucketV2ServerSideEncryptionConfigurationRuleArgs + { + ApplyServerSideEncryptionByDefaults = new[] + { + new Aws.S3.Inputs.BucketV2ServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs + { + SseAlgorithm = "AES256", + }, + }, + }, + }, + }, + }, + Tags = + { + { "Environment", "Dev" }, + }, + Versionings = new[] + { + new Aws.S3.Inputs.BucketV2VersioningArgs + { + Enabled = true, + }, + }, + }, new CustomResourceOptions + { + Protect = true, + }); + + var myBucketEncryptionConfiguration = new Aws.S3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", new() + { + Bucket = "my-bucket-36224917", + Rules = new[] + { + new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationV2RuleArgs + { + ApplyServerSideEncryptionByDefault = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs + { + SseAlgorithm = "AES256", + }, + }, + }, + }, new CustomResourceOptions + { + Protect = true, + }); + + var myBucketPolicy = new Aws.S3.BucketPolicy("my-bucket-policy", new() + { + Bucket = "my-bucket-36224917", + Policy = "{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", + }, new CustomResourceOptions + { + Protect = true, + }); + + var myBucketLifecycle = new Aws.S3.BucketLifecycleConfigurationV2("my-bucket-lifecycle", new() + { + Bucket = "my-bucket-36224917", + Rules = new[] + { + new Aws.S3.Inputs.BucketLifecycleConfigurationV2RuleArgs + { + Expiration = new Aws.S3.Inputs.BucketLifecycleConfigurationV2RuleExpirationArgs + { + Days = 30, + }, + Id = "pu-s3-lifecycle-20240918194815251100000001", + Status = "Enabled", + }, + }, + }, new CustomResourceOptions + { + Protect = true, + }); + + var myBucketObjectLockConfiguration = new Aws.S3.BucketObjectLockConfigurationV2("my-bucket-object-lock-configuration", new() + { + Bucket = "my-bucket-36224917", + ObjectLockEnabled = "Enabled", + }, new CustomResourceOptions + { + Protect = true, + }); + + var myBucketVersioning = new Aws.S3.BucketVersioningV2("my-bucket-versioning", new() + { + Bucket = "my-bucket-36224917", + VersioningConfiguration = new Aws.S3.Inputs.BucketVersioningV2VersioningConfigurationArgs + { + MfaDelete = "Disabled", + Status = "Enabled", + }, + }, new CustomResourceOptions + { + Protect = true, }); }); @@ -445,9 +940,28 @@ import com.pulumi.Context; import com.pulumi.Pulumi; import com.pulumi.core.Output; import com.pulumi.aws.s3.BucketV2; -import com.pulumi.aws.s3.BucketPolicy; +import com.pulumi.aws.s3.BucketV2Args; +import com.pulumi.aws.s3.inputs.BucketV2GrantArgs; +import com.pulumi.aws.s3.inputs.BucketV2LifecycleRuleArgs; +import com.pulumi.aws.s3.inputs.BucketV2ObjectLockConfigurationArgs; +import com.pulumi.aws.s3.inputs.BucketV2ServerSideEncryptionConfigurationArgs; +import com.pulumi.aws.s3.inputs.BucketV2VersioningArgs; +import com.pulumi.aws.s3.BucketServerSideEncryptionConfigurationV2; +import com.pulumi.aws.s3.BucketServerSideEncryptionConfigurationV2Args; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationV2RuleArgs; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs; +import com.pulumi.aws.s3.BucketPolicy; import com.pulumi.aws.s3.BucketPolicyArgs; -import static com.pulumi.codegen.internal.Serialization.*; +import com.pulumi.aws.s3.BucketLifecycleConfigurationV2; +import com.pulumi.aws.s3.BucketLifecycleConfigurationV2Args; +import com.pulumi.aws.s3.inputs.BucketLifecycleConfigurationV2RuleArgs; +import com.pulumi.aws.s3.inputs.BucketLifecycleConfigurationV2RuleExpirationArgs; +import com.pulumi.aws.s3.BucketObjectLockConfigurationV2; +import com.pulumi.aws.s3.BucketObjectLockConfigurationV2Args; +import com.pulumi.aws.s3.BucketVersioningV2; +import com.pulumi.aws.s3.BucketVersioningV2Args; +import com.pulumi.aws.s3.inputs.BucketVersioningV2VersioningConfigurationArgs; +import com.pulumi.resources.CustomResourceOptions; import java.util.List; import java.util.ArrayList; import java.util.Map; @@ -461,28 +975,87 @@ public class App { } public static void stack(Context ctx) { - var myBucket = new BucketV2("myBucket"); + var myBucket = new BucketV2("myBucket", BucketV2Args.builder() + .bucket("my-bucket-36224917") + .grants(BucketV2GrantArgs.builder() + .id("e07865a5679c7977370948f1f1e51c21b12d8cfdd396a7e3172275d9164e01b8") + .permissions("FULL_CONTROL") + .type("CanonicalUser") + .build()) + .lifecycleRules(BucketV2LifecycleRuleArgs.builder() + .enabled(true) + .expirations(BucketV2LifecycleRuleExpirationArgs.builder() + .days(30) + .build()) + .id("pu-s3-lifecycle-20240918194815251100000001") + .build()) + .objectLockConfiguration(BucketV2ObjectLockConfigurationArgs.builder() + .objectLockEnabled("Enabled") + .build()) + .policy("{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}") + .requestPayer("BucketOwner") + .serverSideEncryptionConfigurations(BucketV2ServerSideEncryptionConfigurationArgs.builder() + .rules(BucketV2ServerSideEncryptionConfigurationRuleArgs.builder() + .applyServerSideEncryptionByDefaults(BucketV2ServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs.builder() + .sseAlgorithm("AES256") + .build()) + .build()) + .build()) + .tags(Map.of("Environment", "Dev")) + .versionings(BucketV2VersioningArgs.builder() + .enabled(true) + .build()) + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + var myBucketEncryptionConfiguration = new BucketServerSideEncryptionConfigurationV2("myBucketEncryptionConfiguration", BucketServerSideEncryptionConfigurationV2Args.builder() + .bucket("my-bucket-36224917") + .rules(BucketServerSideEncryptionConfigurationV2RuleArgs.builder() + .applyServerSideEncryptionByDefault(BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs.builder() + .sseAlgorithm("AES256") + .build()) + .build()) + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); var myBucketPolicy = new BucketPolicy("myBucketPolicy", BucketPolicyArgs.builder() - .bucket(myBucket.bucket()) - .policy(myBucket.bucket().applyValue(bucket -> serializeJson( - jsonObject( - jsonProperty("Version", "2012-10-17"), - jsonProperty("Id", "PutObjPolicy"), - jsonProperty("Statement", jsonObject( - jsonProperty("Sid", "DenyObjectsThatAreNotSSEKMS"), - jsonProperty("Principal", "*"), - jsonProperty("Effect", "Deny"), - jsonProperty("Action", "s3:PutObject"), - jsonProperty("Resource", String.format("arn:aws:s3:::%s/*", bucket)), - jsonProperty("Condition", jsonObject( - jsonProperty("Null", jsonObject( - jsonProperty("s3:x-amz-server-side-encryption-aws-kms-key-id", "true") - )) - )) - )) - )))) - .build()); + .bucket("my-bucket-36224917") + .policy("{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}") + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + var myBucketLifecycle = new BucketLifecycleConfigurationV2("myBucketLifecycle", BucketLifecycleConfigurationV2Args.builder() + .bucket("my-bucket-36224917") + .rules(BucketLifecycleConfigurationV2RuleArgs.builder() + .expiration(BucketLifecycleConfigurationV2RuleExpirationArgs.builder() + .days(30) + .build()) + .id("pu-s3-lifecycle-20240918194815251100000001") + .status("Enabled") + .build()) + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + var myBucketObjectLockConfiguration = new BucketObjectLockConfigurationV2("myBucketObjectLockConfiguration", BucketObjectLockConfigurationV2Args.builder() + .bucket("my-bucket-36224917") + .objectLockEnabled("Enabled") + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + var myBucketVersioning = new BucketVersioningV2("myBucketVersioning", BucketVersioningV2Args.builder() + .bucket("my-bucket-36224917") + .versioningConfiguration(BucketVersioningV2VersioningConfigurationArgs.builder() + .mfaDelete("Disabled") + .status("Enabled") + .build()) + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); } } @@ -494,40 +1067,103 @@ public class App { {{% choosable language yaml %}} ```yaml -name: example +name: y2 runtime: yaml resources: my-bucket: type: aws:s3:BucketV2 + properties: + bucket: my-bucket-36224917 + grants: + - id: e07865a5679c7977370948f1f1e51c21b12d8cfdd396a7e3172275d9164e01b8 + permissions: + - FULL_CONTROL + type: CanonicalUser + lifecycleRules: + - enabled: true + expirations: + - days: 30 + id: pu-s3-lifecycle-20240918194815251100000001 + objectLockConfiguration: + objectLockEnabled: Enabled + policy: '{"Id":"PutObjPolicy","Statement":[{"Action":"s3:PutObject","Condition":{"Null":{"s3:x-amz-server-side-encryption-aws-kms-key-id":"true"}},"Effect":"Deny","Principal":"*","Resource":"arn:aws:s3:::my-bucket-36224917/*","Sid":"DenyObjectsThatAreNotSSEKMS"}],"Version":"2012-10-17"}' + requestPayer: BucketOwner + serverSideEncryptionConfigurations: + - rules: + - applyServerSideEncryptionByDefaults: + - sseAlgorithm: AES256 + tags: + Environment: Dev + versionings: + - enabled: true + options: + protect: true + my-bucket-encryption-configuration: + type: aws:s3:BucketServerSideEncryptionConfigurationV2 + properties: + bucket: my-bucket-36224917 + rules: + - applyServerSideEncryptionByDefault: + sseAlgorithm: AES256 + options: + protect: true my-bucket-policy: type: aws:s3:BucketPolicy properties: - bucket: ${my-bucket.bucket} - policy: - fn::toJSON: - Version: 2012-10-17 - Id: PutObjPolicy - Statement: - Sid: DenyObjectsThatAreNotSSEKMS - Principal: "*" - Effect: Deny - Action: s3:PutObject - Resource: "arn:aws:s3:::${my-bucket.bucket}/*" - Condition: - "Null": - s3:x-amz-server-side-encryption-aws-kms-key-id: "true" + bucket: my-bucket-36224917 + policy: '{"Id":"PutObjPolicy","Statement":[{"Action":"s3:PutObject","Condition":{"Null":{"s3:x-amz-server-side-encryption-aws-kms-key-id":"true"}},"Effect":"Deny","Principal":"*","Resource":"arn:aws:s3:::my-bucket-36224917/*","Sid":"DenyObjectsThatAreNotSSEKMS"}],"Version":"2012-10-17"}' + options: + protect: true + my-bucket-lifecycle: + type: aws:s3:BucketLifecycleConfigurationV2 + properties: + bucket: my-bucket-36224917 + rules: + - expiration: + days: 30 + id: pu-s3-lifecycle-20240918194815251100000001 + status: Enabled + options: + protect: true + my-bucket-object-lock-configuration: + type: aws:s3:BucketObjectLockConfigurationV2 + properties: + bucket: my-bucket-36224917 + objectLockEnabled: Enabled + options: + protect: true + my-bucket-versioning: + type: aws:s3:BucketVersioningV2 + properties: + bucket: my-bucket-36224917 + versioningConfiguration: + mfaDelete: Disabled + status: Enabled + options: + protect: true ``` {{% /choosable %}} {{< /chooser >}} -As a bonus, the policy can now more easily refer to the concrete name of the bucket. +- `pulumi preview` should result in `Resources: N unchanged` to confirm everything went well. -### serverSideEncryptionConfiguration input +- At this point you may see warnings from deprecated inputs like this: -To specify [server-side encryption configuration](http://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html), -instead of: +```shell +warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the top-level parameter object_lock_enabled instead +warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the top-level parameter object_lock_enabled and the aws_s3_bucket_object_lock_configuration resource instead +warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the aws_s3_bucket_lifecycle_configuration resource instead +warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the aws_s3_bucket_versioning resource instead +warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the aws_s3_bucket_acl resource instead +warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the aws_s3_bucket_request_payment_configuration resource instead +warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the aws_s3_bucket_policy resource instead +warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the aws_s3_bucket_server_side_encryption_configuration resource instead +``` + +- To mitigate, edit the program to remove the deprecated inputs, leaving the final simplify program that should still + result in an empty `pulumi preview`: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -537,31 +1173,107 @@ instead of: import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; -const myBucket = new aws.s3.Bucket("my-bucket", {serverSideEncryptionConfiguration: { - rule: { - applyServerSideEncryptionByDefault: { - sseAlgorithm: "aws:kms", - }, +const myBucket = new aws.s3.BucketV2("my-bucket", { + bucket: "my-bucket-36224917", + tags: { + Environment: "Dev", }, -}}); - -``` - -{{% /choosable %}} - -{{% choosable language python %}} - -```python -import pulumi -import pulumi_aws as aws - -my_bucket = aws.s3.Bucket("my-bucket", server_side_encryption_configuration={ - "rule": { - "apply_server_side_encryption_by_default": { - "sse_algorithm": "aws:kms", +}, { + protect: true, +}); +const myBucketEncryptionConfiguration = new aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", { + bucket: "my-bucket-36224917", + rules: [{ + applyServerSideEncryptionByDefault: { + sseAlgorithm: "AES256", }, - }, -}) + }], +}, { + protect: true, +}); +const myBucketPolicy = new aws.s3.BucketPolicy("my-bucket-policy", { + bucket: "my-bucket-36224917", + policy: "{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", +}, { + protect: true, +}); +const myBucketLifecycle = new aws.s3.BucketLifecycleConfigurationV2("my-bucket-lifecycle", { + bucket: "my-bucket-36224917", + rules: [{ + expiration: { + days: 30, + }, + id: "pu-s3-lifecycle-20240918194815251100000001", + status: "Enabled", + }], +}, { + protect: true, +}); +const myBucketObjectLockConfiguration = new aws.s3.BucketObjectLockConfigurationV2("my-bucket-object-lock-configuration", { + bucket: "my-bucket-36224917", + objectLockEnabled: "Enabled", +}, { + protect: true, +}); +const myBucketVersioning = new aws.s3.BucketVersioningV2("my-bucket-versioning", { + bucket: "my-bucket-36224917", + versioningConfiguration: { + mfaDelete: "Disabled", + status: "Enabled", + }, +}, { + protect: true, +}); + +``` + +{{% /choosable %}} + +{{% choosable language python %}} + +```python +import pulumi +import pulumi_aws as aws + +my_bucket = aws.s3.BucketV2("my-bucket", + bucket="my-bucket-36224917", + tags={ + "Environment": "Dev", + }, + opts = pulumi.ResourceOptions(protect=True)) +my_bucket_encryption_configuration = aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", + bucket="my-bucket-36224917", + rules=[{ + "apply_server_side_encryption_by_default": { + "sse_algorithm": "AES256", + }, + }], + opts = pulumi.ResourceOptions(protect=True)) +my_bucket_policy = aws.s3.BucketPolicy("my-bucket-policy", + bucket="my-bucket-36224917", + policy="{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", + opts = pulumi.ResourceOptions(protect=True)) +my_bucket_lifecycle = aws.s3.BucketLifecycleConfigurationV2("my-bucket-lifecycle", + bucket="my-bucket-36224917", + rules=[{ + "expiration": { + "days": 30, + }, + "id": "pu-s3-lifecycle-20240918194815251100000001", + "status": "Enabled", + }], + opts = pulumi.ResourceOptions(protect=True)) +my_bucket_object_lock_configuration = aws.s3.BucketObjectLockConfigurationV2("my-bucket-object-lock-configuration", + bucket="my-bucket-36224917", + object_lock_enabled="Enabled", + opts = pulumi.ResourceOptions(protect=True)) +my_bucket_versioning = aws.s3.BucketVersioningV2("my-bucket-versioning", + bucket="my-bucket-36224917", + versioning_configuration={ + "mfa_delete": "Disabled", + "status": "Enabled", + }, + opts = pulumi.ResourceOptions(protect=True)) ``` @@ -579,15 +1291,64 @@ import ( func main() { pulumi.Run(func(ctx *pulumi.Context) error { - _, err := s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{ - ServerSideEncryptionConfiguration: &s3.BucketServerSideEncryptionConfigurationArgs{ - Rule: &s3.BucketServerSideEncryptionConfigurationRuleArgs{ - ApplyServerSideEncryptionByDefault: &s3.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs{ - SseAlgorithm: pulumi.String("aws:kms"), + _, err := s3.NewBucketV2(ctx, "my-bucket", &s3.BucketV2Args{ + Bucket: pulumi.String("my-bucket-36224917"), + Tags: pulumi.StringMap{ + "Environment": pulumi.String("Dev"), + }, + }, pulumi.Protect(true)) + if err != nil { + return err + } + _, err = s3.NewBucketServerSideEncryptionConfigurationV2(ctx, "my-bucket-encryption-configuration", &s3.BucketServerSideEncryptionConfigurationV2Args{ + Bucket: pulumi.String("my-bucket-36224917"), + Rules: s3.BucketServerSideEncryptionConfigurationV2RuleArray{ + &s3.BucketServerSideEncryptionConfigurationV2RuleArgs{ + ApplyServerSideEncryptionByDefault: &s3.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs{ + SseAlgorithm: pulumi.String("AES256"), }, }, }, - }) + }, pulumi.Protect(true)) + if err != nil { + return err + } + _, err = s3.NewBucketPolicy(ctx, "my-bucket-policy", &s3.BucketPolicyArgs{ + Bucket: pulumi.String("my-bucket-36224917"), + Policy: pulumi.Any("{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}"), + }, pulumi.Protect(true)) + if err != nil { + return err + } + _, err = s3.NewBucketLifecycleConfigurationV2(ctx, "my-bucket-lifecycle", &s3.BucketLifecycleConfigurationV2Args{ + Bucket: pulumi.String("my-bucket-36224917"), + Rules: s3.BucketLifecycleConfigurationV2RuleArray{ + &s3.BucketLifecycleConfigurationV2RuleArgs{ + Expiration: &s3.BucketLifecycleConfigurationV2RuleExpirationArgs{ + Days: pulumi.Int(30), + }, + Id: pulumi.String("pu-s3-lifecycle-20240918194815251100000001"), + Status: pulumi.String("Enabled"), + }, + }, + }, pulumi.Protect(true)) + if err != nil { + return err + } + _, err = s3.NewBucketObjectLockConfigurationV2(ctx, "my-bucket-object-lock-configuration", &s3.BucketObjectLockConfigurationV2Args{ + Bucket: pulumi.String("my-bucket-36224917"), + ObjectLockEnabled: pulumi.String("Enabled"), + }, pulumi.Protect(true)) + if err != nil { + return err + } + _, err = s3.NewBucketVersioningV2(ctx, "my-bucket-versioning", &s3.BucketVersioningV2Args{ + Bucket: pulumi.String("my-bucket-36224917"), + VersioningConfiguration: &s3.BucketVersioningV2VersioningConfigurationArgs{ + MfaDelete: pulumi.String("Disabled"), + Status: pulumi.String("Enabled"), + }, + }, pulumi.Protect(true)) if err != nil { return err } @@ -607,20 +1368,87 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { - var myBucket = new Aws.S3.Bucket("my-bucket", new() + var myBucket = new Aws.S3.BucketV2("my-bucket", new() { - ServerSideEncryptionConfiguration = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationArgs + Bucket = "my-bucket-36224917", + Tags = { - Rule = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationRuleArgs + { "Environment", "Dev" }, + }, + }, new CustomResourceOptions + { + Protect = true, + }); + + var myBucketEncryptionConfiguration = new Aws.S3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", new() + { + Bucket = "my-bucket-36224917", + Rules = new[] + { + new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationV2RuleArgs { - ApplyServerSideEncryptionByDefault = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs + ApplyServerSideEncryptionByDefault = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs { - SseAlgorithm = "aws:kms", + SseAlgorithm = "AES256", + }, + }, + }, + }, new CustomResourceOptions + { + Protect = true, + }); + + var myBucketPolicy = new Aws.S3.BucketPolicy("my-bucket-policy", new() + { + Bucket = "my-bucket-36224917", + Policy = "{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", + }, new CustomResourceOptions + { + Protect = true, + }); + + var myBucketLifecycle = new Aws.S3.BucketLifecycleConfigurationV2("my-bucket-lifecycle", new() + { + Bucket = "my-bucket-36224917", + Rules = new[] + { + new Aws.S3.Inputs.BucketLifecycleConfigurationV2RuleArgs + { + Expiration = new Aws.S3.Inputs.BucketLifecycleConfigurationV2RuleExpirationArgs + { + Days = 30, }, + Id = "pu-s3-lifecycle-20240918194815251100000001", + Status = "Enabled", }, }, + }, new CustomResourceOptions + { + Protect = true, + }); + + var myBucketObjectLockConfiguration = new Aws.S3.BucketObjectLockConfigurationV2("my-bucket-object-lock-configuration", new() + { + Bucket = "my-bucket-36224917", + ObjectLockEnabled = "Enabled", + }, new CustomResourceOptions + { + Protect = true, + }); + + var myBucketVersioning = new Aws.S3.BucketVersioningV2("my-bucket-versioning", new() + { + Bucket = "my-bucket-36224917", + VersioningConfiguration = new Aws.S3.Inputs.BucketVersioningV2VersioningConfigurationArgs + { + MfaDelete = "Disabled", + Status = "Enabled", + }, + }, new CustomResourceOptions + { + Protect = true, }); }); @@ -638,11 +1466,24 @@ 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.inputs.BucketServerSideEncryptionConfigurationArgs; -import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationRuleArgs; -import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs; +import com.pulumi.aws.s3.BucketV2; +import com.pulumi.aws.s3.BucketV2Args; +import com.pulumi.aws.s3.BucketServerSideEncryptionConfigurationV2; +import com.pulumi.aws.s3.BucketServerSideEncryptionConfigurationV2Args; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationV2RuleArgs; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs; +import com.pulumi.aws.s3.BucketPolicy; +import com.pulumi.aws.s3.BucketPolicyArgs; +import com.pulumi.aws.s3.BucketLifecycleConfigurationV2; +import com.pulumi.aws.s3.BucketLifecycleConfigurationV2Args; +import com.pulumi.aws.s3.inputs.BucketLifecycleConfigurationV2RuleArgs; +import com.pulumi.aws.s3.inputs.BucketLifecycleConfigurationV2RuleExpirationArgs; +import com.pulumi.aws.s3.BucketObjectLockConfigurationV2; +import com.pulumi.aws.s3.BucketObjectLockConfigurationV2Args; +import com.pulumi.aws.s3.BucketVersioningV2; +import com.pulumi.aws.s3.BucketVersioningV2Args; +import com.pulumi.aws.s3.inputs.BucketVersioningV2VersioningConfigurationArgs; +import com.pulumi.resources.CustomResourceOptions; import java.util.List; import java.util.ArrayList; import java.util.Map; @@ -656,15 +1497,60 @@ public class App { } public static void stack(Context ctx) { - var myBucket = new Bucket("myBucket", BucketArgs.builder() - .serverSideEncryptionConfiguration(BucketServerSideEncryptionConfigurationArgs.builder() - .rule(BucketServerSideEncryptionConfigurationRuleArgs.builder() - .applyServerSideEncryptionByDefault(BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs.builder() - .sseAlgorithm("aws:kms") - .build()) - .build()) - .build()) - .build()); + var myBucket = new BucketV2("myBucket", BucketV2Args.builder() + .bucket("my-bucket-36224917") + .tags(Map.of("Environment", "Dev")) + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + var myBucketEncryptionConfiguration = new BucketServerSideEncryptionConfigurationV2("myBucketEncryptionConfiguration", BucketServerSideEncryptionConfigurationV2Args.builder() + .bucket("my-bucket-36224917") + .rules(BucketServerSideEncryptionConfigurationV2RuleArgs.builder() + .applyServerSideEncryptionByDefault(BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs.builder() + .sseAlgorithm("AES256") + .build()) + .build()) + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + var myBucketPolicy = new BucketPolicy("myBucketPolicy", BucketPolicyArgs.builder() + .bucket("my-bucket-36224917") + .policy("{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}") + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + var myBucketLifecycle = new BucketLifecycleConfigurationV2("myBucketLifecycle", BucketLifecycleConfigurationV2Args.builder() + .bucket("my-bucket-36224917") + .rules(BucketLifecycleConfigurationV2RuleArgs.builder() + .expiration(BucketLifecycleConfigurationV2RuleExpirationArgs.builder() + .days(30) + .build()) + .id("pu-s3-lifecycle-20240918194815251100000001") + .status("Enabled") + .build()) + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + var myBucketObjectLockConfiguration = new BucketObjectLockConfigurationV2("myBucketObjectLockConfiguration", BucketObjectLockConfigurationV2Args.builder() + .bucket("my-bucket-36224917") + .objectLockEnabled("Enabled") + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); + + var myBucketVersioning = new BucketVersioningV2("myBucketVersioning", BucketVersioningV2Args.builder() + .bucket("my-bucket-36224917") + .versioningConfiguration(BucketVersioningV2VersioningConfigurationArgs.builder() + .mfaDelete("Disabled") + .status("Enabled") + .build()) + .build(), CustomResourceOptions.builder() + .protect(true) + .build()); } } @@ -676,16 +1562,60 @@ public class App { {{% choosable language yaml %}} ```yaml -name: example +name: y2 runtime: yaml resources: my-bucket: - type: aws:s3:Bucket + type: aws:s3:BucketV2 properties: - serverSideEncryptionConfiguration: - rule: - applyServerSideEncryptionByDefault: - sseAlgorithm: "aws:kms" + bucket: my-bucket-36224917 + tags: + Environment: Dev + options: + protect: true + my-bucket-encryption-configuration: + type: aws:s3:BucketServerSideEncryptionConfigurationV2 + properties: + bucket: my-bucket-36224917 + rules: + - applyServerSideEncryptionByDefault: + sseAlgorithm: AES256 + options: + protect: true + my-bucket-policy: + type: aws:s3:BucketPolicy + properties: + bucket: my-bucket-36224917 + policy: '{"Id":"PutObjPolicy","Statement":[{"Action":"s3:PutObject","Condition":{"Null":{"s3:x-amz-server-side-encryption-aws-kms-key-id":"true"}},"Effect":"Deny","Principal":"*","Resource":"arn:aws:s3:::my-bucket-36224917/*","Sid":"DenyObjectsThatAreNotSSEKMS"}],"Version":"2012-10-17"}' + options: + protect: true + my-bucket-lifecycle: + type: aws:s3:BucketLifecycleConfigurationV2 + properties: + bucket: my-bucket-36224917 + rules: + - expiration: + days: 30 + id: pu-s3-lifecycle-20240918194815251100000001 + status: Enabled + options: + protect: true + my-bucket-object-lock-configuration: + type: aws:s3:BucketObjectLockConfigurationV2 + properties: + bucket: my-bucket-36224917 + objectLockEnabled: Enabled + options: + protect: true + my-bucket-versioning: + type: aws:s3:BucketVersioningV2 + properties: + bucket: my-bucket-36224917 + versioningConfiguration: + mfaDelete: Disabled + status: Enabled + options: + protect: true ``` {{% /choosable %}} @@ -695,9 +1625,16 @@ resources: +## Migrating with `pulumi up` +If you have reliable backups or test account scenarios where deleting and re-creating buckets is acceptable, a simpler +form of migration path is to rewrite the deprecated inputs to the new form and perform a `pulumi up`. -Use the `aws.s3.BucketServerSideEncryptionConfiguration` resource: +### policy input + +To specify a +[bucket policy](https://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html), +instead of: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -707,14 +1644,24 @@ Use the `aws.s3.BucketServerSideEncryptionConfiguration` resource: import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; -const myBucket = new aws.s3.BucketV2("my-bucket", {}); -const myBucketSseConfig = new aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-sse-config", { - bucket: myBucket.bucket, - rules: [{ - applyServerSideEncryptionByDefault: { - sseAlgorithm: "aws:kms", +const myBucket = new aws.s3.Bucket("my-bucket", { + bucket: "my-bucket-26224916", + policy: JSON.stringify({ + Version: "2012-10-17", + Id: "PutObjPolicy", + Statement: { + Sid: "DenyObjectsThatAreNotSSEKMS", + Principal: "*", + Effect: "Deny", + Action: "s3:PutObject", + Resource: "arn:aws:s3:::my-bucket-26224916/*", + Condition: { + Null: { + "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", + }, + }, }, - }], + }), }); ``` @@ -725,16 +1672,27 @@ const myBucketSseConfig = new aws.s3.BucketServerSideEncryptionConfigurationV2(" ```python import pulumi +import json import pulumi_aws as aws -my_bucket = aws.s3.BucketV2("my-bucket") -my_bucket_sse_config = aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-sse-config", - bucket=my_bucket.bucket, - rules=[{ - "apply_server_side_encryption_by_default": { - "sse_algorithm": "aws:kms", +my_bucket = aws.s3.Bucket("my-bucket", + bucket="my-bucket-26224916", + policy=json.dumps({ + "Version": "2012-10-17", + "Id": "PutObjPolicy", + "Statement": { + "Sid": "DenyObjectsThatAreNotSSEKMS", + "Principal": "*", + "Effect": "Deny", + "Action": "s3:PutObject", + "Resource": "arn:aws:s3:::my-bucket-26224916/*", + "Condition": { + "Null": { + "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", + }, + }, }, - }]) + })) ``` @@ -746,22 +1704,26 @@ my_bucket_sse_config = aws.s3.BucketServerSideEncryptionConfigurationV2("my-buck package main import ( + "encoding/json" + "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" ) func main() { pulumi.Run(func(ctx *pulumi.Context) error { - myBucket, err := s3.NewBucketV2(ctx, "my-bucket", nil) - if err != nil { - return err - } - _, err = s3.NewBucketServerSideEncryptionConfigurationV2(ctx, "my-bucket-sse-config", &s3.BucketServerSideEncryptionConfigurationV2Args{ - Bucket: myBucket.Bucket, - Rules: s3.BucketServerSideEncryptionConfigurationV2RuleArray{ - &s3.BucketServerSideEncryptionConfigurationV2RuleArgs{ - ApplyServerSideEncryptionByDefault: &s3.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs{ - SseAlgorithm: pulumi.String("aws:kms"), + tmpJSON0, err := json.Marshal(map[string]interface{}{ + "Version": "2012-10-17", + "Id": "PutObjPolicy", + "Statement": map[string]interface{}{ + "Sid": "DenyObjectsThatAreNotSSEKMS", + "Principal": "*", + "Effect": "Deny", + "Action": "s3:PutObject", + "Resource": "arn:aws:s3:::my-bucket-26224916/*", + "Condition": map[string]interface{}{ + "Null": map[string]interface{}{ + "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", }, }, }, @@ -769,6 +1731,14 @@ func main() { if err != nil { return err } + json0 := string(tmpJSON0) + _, err = s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{ + Bucket: pulumi.String("my-bucket-26224916"), + Policy: pulumi.String(json0), + }) + if err != nil { + return err + } return nil }) } @@ -782,26 +1752,35 @@ func main() { ```csharp using System.Collections.Generic; using System.Linq; +using System.Text.Json; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { - var myBucket = new Aws.S3.BucketV2("my-bucket"); - - var myBucketSseConfig = new Aws.S3.BucketServerSideEncryptionConfigurationV2("my-bucket-sse-config", new() + var myBucket = new Aws.S3.Bucket("my-bucket", new() { - Bucket = myBucket.Bucket, - Rules = new[] + BucketName = "my-bucket-26224916", + Policy = JsonSerializer.Serialize(new Dictionary { - new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationV2RuleArgs + ["Version"] = "2012-10-17", + ["Id"] = "PutObjPolicy", + ["Statement"] = new Dictionary { - ApplyServerSideEncryptionByDefault = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs + ["Sid"] = "DenyObjectsThatAreNotSSEKMS", + ["Principal"] = "*", + ["Effect"] = "Deny", + ["Action"] = "s3:PutObject", + ["Resource"] = "arn:aws:s3:::my-bucket-26224916/*", + ["Condition"] = new Dictionary { - SseAlgorithm = "aws:kms", + ["Null"] = new Dictionary + { + ["s3:x-amz-server-side-encryption-aws-kms-key-id"] = "true", + }, }, }, - }, + }), }); }); @@ -819,11 +1798,9 @@ package generated_program; import com.pulumi.Context; import com.pulumi.Pulumi; import com.pulumi.core.Output; -import com.pulumi.aws.s3.BucketV2; -import com.pulumi.aws.s3.BucketServerSideEncryptionConfigurationV2; -import com.pulumi.aws.s3.BucketServerSideEncryptionConfigurationV2Args; -import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationV2RuleArgs; -import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs; +import com.pulumi.aws.s3.Bucket; +import com.pulumi.aws.s3.BucketArgs; +import static com.pulumi.codegen.internal.Serialization.*; import java.util.List; import java.util.ArrayList; import java.util.Map; @@ -837,16 +1814,26 @@ public class App { } public static void stack(Context ctx) { - var myBucket = new BucketV2("myBucket"); - - var myBucketSseConfig = new BucketServerSideEncryptionConfigurationV2("myBucketSseConfig", BucketServerSideEncryptionConfigurationV2Args.builder() - .bucket(myBucket.bucket()) - .rules(BucketServerSideEncryptionConfigurationV2RuleArgs.builder() - .applyServerSideEncryptionByDefault(BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs.builder() - .sseAlgorithm("aws:kms") - .build()) - .build()) - .build()); + var myBucket = new Bucket("myBucket", BucketArgs.builder() + .bucket("my-bucket-26224916") + .policy(serializeJson( + jsonObject( + jsonProperty("Version", "2012-10-17"), + jsonProperty("Id", "PutObjPolicy"), + jsonProperty("Statement", jsonObject( + jsonProperty("Sid", "DenyObjectsThatAreNotSSEKMS"), + jsonProperty("Principal", "*"), + jsonProperty("Effect", "Deny"), + jsonProperty("Action", "s3:PutObject"), + jsonProperty("Resource", "arn:aws:s3:::my-bucket-26224916/*"), + jsonProperty("Condition", jsonObject( + jsonProperty("Null", jsonObject( + jsonProperty("s3:x-amz-server-side-encryption-aws-kms-key-id", "true") + )) + )) + )) + ))) + .build()); } } @@ -862,14 +1849,22 @@ name: example runtime: yaml resources: my-bucket: - type: aws:s3:BucketV2 - my-bucket-sse-config: - type: aws:s3:BucketServerSideEncryptionConfigurationV2 + type: aws:s3:Bucket properties: - bucket: ${my-bucket.bucket} - rules: - - applyServerSideEncryptionByDefault: - sseAlgorithm: "aws:kms" + bucket: "my-bucket-26224916" + policy: + fn::toJSON: + Version: 2012-10-17 + Id: PutObjPolicy + Statement: + Sid: DenyObjectsThatAreNotSSEKMS + Principal: "*" + Effect: Deny + Action: s3:PutObject + Resource: "arn:aws:s3:::my-bucket-26224916/*" + Condition: + "Null": + s3:x-amz-server-side-encryption-aws-kms-key-id: "true" ``` {{% /choosable %}} @@ -879,9 +1874,8 @@ resources: -### acceleration input -To enable acceleration, instead of: +Use the `aws.s3.BucketPolicy` resource: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -891,7 +1885,26 @@ To enable acceleration, instead of: import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; -const myBucket = new aws.s3.Bucket("my-bucket", {accelerationStatus: "Enabled"}); +const myBucket = new aws.s3.BucketV2("my-bucket", {}); +const myBucketPolicy = new aws.s3.BucketPolicy("my-bucket-policy", { + bucket: myBucket.bucket, + policy: pulumi.jsonStringify({ + Version: "2012-10-17", + Id: "PutObjPolicy", + Statement: { + Sid: "DenyObjectsThatAreNotSSEKMS", + Principal: "*", + Effect: "Deny", + Action: "s3:PutObject", + Resource: pulumi.interpolate`arn:aws:s3:::${myBucket.bucket}/*`, + Condition: { + Null: { + "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", + }, + }, + }, + }), +}); ``` @@ -901,9 +1914,28 @@ const myBucket = new aws.s3.Bucket("my-bucket", {accelerationStatus: "Enabled"}) ```python import pulumi +import json import pulumi_aws as aws -my_bucket = aws.s3.Bucket("my-bucket", acceleration_status="Enabled") +my_bucket = aws.s3.BucketV2("my-bucket") +my_bucket_policy = aws.s3.BucketPolicy("my-bucket-policy", + bucket=my_bucket.bucket, + policy=pulumi.Output.json_dumps({ + "Version": "2012-10-17", + "Id": "PutObjPolicy", + "Statement": { + "Sid": "DenyObjectsThatAreNotSSEKMS", + "Principal": "*", + "Effect": "Deny", + "Action": "s3:PutObject", + "Resource": my_bucket.bucket.apply(lambda bucket: f"arn:aws:s3:::{bucket}/*"), + "Condition": { + "Null": { + "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", + }, + }, + }, + })) ``` @@ -915,14 +1947,46 @@ my_bucket = aws.s3.Bucket("my-bucket", acceleration_status="Enabled") package main import ( + "encoding/json" + "fmt" + + "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/iam" "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" ) func main() { pulumi.Run(func(ctx *pulumi.Context) error { - _, err := s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{ - AccelerationStatus: pulumi.String("Enabled"), + myBucket, err := s3.NewBucketV2(ctx, "my-bucket", nil) + if err != nil { + return err + } + _, err = s3.NewBucketPolicy(ctx, "my-bucket-policy", &s3.BucketPolicyArgs{ + Bucket: myBucket.Bucket, + Policy: myBucket.Bucket.ApplyT(func(bucket string) (pulumi.String, error) { + var _zero pulumi.String + tmpJSON0, err := json.Marshal(map[string]interface{}{ + "Version": "2012-10-17", + "Id": "PutObjPolicy", + "Statement": map[string]interface{}{ + "Sid": "DenyObjectsThatAreNotSSEKMS", + "Principal": "*", + "Effect": "Deny", + "Action": "s3:PutObject", + "Resource": fmt.Sprintf("arn:aws:s3:::%v/*", bucket), + "Condition": map[string]interface{}{ + "Null": map[string]interface{}{ + "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", + }, + }, + }, + }) + if err != nil { + return _zero, err + } + json0 := string(tmpJSON0) + return pulumi.String(json0), nil + }).(pulumi.StringOutput), }) if err != nil { return err @@ -940,14 +2004,37 @@ func main() { ```csharp using System.Collections.Generic; using System.Linq; +using System.Text.Json; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { - var myBucket = new Aws.S3.Bucket("my-bucket", new() + var myBucket = new Aws.S3.BucketV2("my-bucket"); + + var myBucketPolicy = new Aws.S3.BucketPolicy("my-bucket-policy", new() { - AccelerationStatus = "Enabled", + Bucket = myBucket.Bucket, + Policy = Output.JsonSerialize(Output.Create(new Dictionary + { + ["Version"] = "2012-10-17", + ["Id"] = "PutObjPolicy", + ["Statement"] = new Dictionary + { + ["Sid"] = "DenyObjectsThatAreNotSSEKMS", + ["Principal"] = "*", + ["Effect"] = "Deny", + ["Action"] = "s3:PutObject", + ["Resource"] = myBucket.Bucket.Apply(bucket => $"arn:aws:s3:::{bucket}/*"), + ["Condition"] = new Dictionary + { + ["Null"] = new Dictionary + { + ["s3:x-amz-server-side-encryption-aws-kms-key-id"] = "true", + }, + }, + }, + })), }); }); @@ -965,8 +2052,10 @@ 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.BucketV2; +import com.pulumi.aws.s3.BucketPolicy; +import com.pulumi.aws.s3.BucketPolicyArgs; +import static com.pulumi.codegen.internal.Serialization.*; import java.util.List; import java.util.ArrayList; import java.util.Map; @@ -980,8 +2069,27 @@ public class App { } public static void stack(Context ctx) { - var myBucket = new Bucket("myBucket", BucketArgs.builder() - .accelerationStatus("Enabled") + var myBucket = new BucketV2("myBucket"); + + var myBucketPolicy = new BucketPolicy("myBucketPolicy", BucketPolicyArgs.builder() + .bucket(myBucket.bucket()) + .policy(myBucket.bucket().applyValue(bucket -> serializeJson( + jsonObject( + jsonProperty("Version", "2012-10-17"), + jsonProperty("Id", "PutObjPolicy"), + jsonProperty("Statement", jsonObject( + jsonProperty("Sid", "DenyObjectsThatAreNotSSEKMS"), + jsonProperty("Principal", "*"), + jsonProperty("Effect", "Deny"), + jsonProperty("Action", "s3:PutObject"), + jsonProperty("Resource", String.format("arn:aws:s3:::%s/*", bucket)), + jsonProperty("Condition", jsonObject( + jsonProperty("Null", jsonObject( + jsonProperty("s3:x-amz-server-side-encryption-aws-kms-key-id", "true") + )) + )) + )) + )))) .build()); } @@ -998,19 +2106,36 @@ name: example runtime: yaml resources: my-bucket: - type: aws:s3:Bucket + type: aws:s3:BucketV2 + my-bucket-policy: + type: aws:s3:BucketPolicy properties: - accelerationStatus: Enabled + bucket: ${my-bucket.bucket} + policy: + fn::toJSON: + Version: 2012-10-17 + Id: PutObjPolicy + Statement: + Sid: DenyObjectsThatAreNotSSEKMS + Principal: "*" + Effect: Deny + Action: s3:PutObject + Resource: "arn:aws:s3:::${my-bucket.bucket}/*" + Condition: + "Null": + s3:x-amz-server-side-encryption-aws-kms-key-id: "true" ``` {{% /choosable %}} {{< /chooser >}} +As a bonus, the policy can now more easily refer to the concrete name of the bucket. +### serverSideEncryptionConfiguration input - -Use the `aws.s3.BucketAccelerateConfigurationV2` resource: +To specify [server-side encryption configuration](http://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html), +instead of: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -1020,11 +2145,13 @@ Use the `aws.s3.BucketAccelerateConfigurationV2` resource: import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; -const myBucket = new aws.s3.BucketV2("my-bucket", {}); -const myBucketAcceleration = new aws.s3.BucketAccelerateConfigurationV2("my-bucket-acceleration", { - bucket: myBucket.bucket, - status: "Enabled", -}); +const myBucket = new aws.s3.Bucket("my-bucket", {serverSideEncryptionConfiguration: { + rule: { + applyServerSideEncryptionByDefault: { + sseAlgorithm: "aws:kms", + }, + }, +}}); ``` @@ -1036,10 +2163,13 @@ const myBucketAcceleration = new aws.s3.BucketAccelerateConfigurationV2("my-buck import pulumi import pulumi_aws as aws -my_bucket = aws.s3.BucketV2("my-bucket") -my_bucket_acceleration = aws.s3.BucketAccelerateConfigurationV2("my-bucket-acceleration", - bucket=my_bucket.bucket, - status="Enabled") +my_bucket = aws.s3.Bucket("my-bucket", server_side_encryption_configuration={ + "rule": { + "apply_server_side_encryption_by_default": { + "sse_algorithm": "aws:kms", + }, + }, +}) ``` @@ -1057,13 +2187,14 @@ import ( func main() { pulumi.Run(func(ctx *pulumi.Context) error { - myBucket, err := s3.NewBucketV2(ctx, "my-bucket", nil) - if err != nil { - return err - } - _, err = s3.NewBucketAccelerateConfigurationV2(ctx, "my-bucket-acceleration", &s3.BucketAccelerateConfigurationV2Args{ - Bucket: myBucket.Bucket, - Status: pulumi.String("Enabled"), + _, err := s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{ + ServerSideEncryptionConfiguration: &s3.BucketServerSideEncryptionConfigurationArgs{ + Rule: &s3.BucketServerSideEncryptionConfigurationRuleArgs{ + ApplyServerSideEncryptionByDefault: &s3.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs{ + SseAlgorithm: pulumi.String("aws:kms"), + }, + }, + }, }) if err != nil { return err @@ -1084,14 +2215,20 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { - var myBucket = new Aws.S3.BucketV2("my-bucket"); - - var myBucketAcceleration = new Aws.S3.BucketAccelerateConfigurationV2("my-bucket-acceleration", new() + var myBucket = new Aws.S3.Bucket("my-bucket", new() { - Bucket = myBucket.Bucket, - Status = "Enabled", + ServerSideEncryptionConfiguration = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationArgs + { + Rule = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationRuleArgs + { + ApplyServerSideEncryptionByDefault = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs + { + SseAlgorithm = "aws:kms", + }, + }, + }, }); }); @@ -1109,9 +2246,11 @@ package generated_program; import com.pulumi.Context; import com.pulumi.Pulumi; import com.pulumi.core.Output; -import com.pulumi.aws.s3.BucketV2; -import com.pulumi.aws.s3.BucketAccelerateConfigurationV2; -import com.pulumi.aws.s3.BucketAccelerateConfigurationV2Args; +import com.pulumi.aws.s3.Bucket; +import com.pulumi.aws.s3.BucketArgs; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationArgs; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationRuleArgs; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs; import java.util.List; import java.util.ArrayList; import java.util.Map; @@ -1125,11 +2264,14 @@ public class App { } public static void stack(Context ctx) { - var myBucket = new BucketV2("myBucket"); - - var myBucketAcceleration = new BucketAccelerateConfigurationV2("myBucketAcceleration", BucketAccelerateConfigurationV2Args.builder() - .bucket(myBucket.bucket()) - .status("Enabled") + var myBucket = new Bucket("myBucket", BucketArgs.builder() + .serverSideEncryptionConfiguration(BucketServerSideEncryptionConfigurationArgs.builder() + .rule(BucketServerSideEncryptionConfigurationRuleArgs.builder() + .applyServerSideEncryptionByDefault(BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs.builder() + .sseAlgorithm("aws:kms") + .build()) + .build()) + .build()) .build()); } @@ -1146,12 +2288,12 @@ name: example runtime: yaml resources: my-bucket: - type: aws:s3:BucketV2 - my-bucket-acceleration: - type: aws:s3:BucketAccelerateConfigurationV2 + type: aws:s3:Bucket properties: - bucket: ${my-bucket.bucket} - status: Enabled + serverSideEncryptionConfiguration: + rule: + applyServerSideEncryptionByDefault: + sseAlgorithm: "aws:kms" ``` {{% /choosable %}} @@ -1159,10 +2301,11 @@ resources: {{< /chooser >}} -### corsRules input -To configure [Cross-Origin Resource Sharing](https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html), -instead of: + + + +Use the `aws.s3.BucketServerSideEncryptionConfiguration` resource: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -1172,13 +2315,15 @@ instead of: import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; -const myBucket = new aws.s3.Bucket("my-bucket", {corsRules: [{ - allowedHeaders: ["*"], - allowedMethods: ["GET"], - allowedOrigins: ["*"], - exposeHeaders: ["ETag"], - maxAgeSeconds: 3000, -}]}); +const myBucket = new aws.s3.BucketV2("my-bucket", {}); +const myBucketSseConfig = new aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-sse-config", { + bucket: myBucket.bucket, + rules: [{ + applyServerSideEncryptionByDefault: { + sseAlgorithm: "aws:kms", + }, + }], +}); ``` @@ -1190,13 +2335,14 @@ const myBucket = new aws.s3.Bucket("my-bucket", {corsRules: [{ import pulumi import pulumi_aws as aws -my_bucket = aws.s3.Bucket("my-bucket", cors_rules=[{ - "allowed_headers": ["*"], - "allowed_methods": ["GET"], - "allowed_origins": ["*"], - "expose_headers": ["ETag"], - "max_age_seconds": 3000, -}]) +my_bucket = aws.s3.BucketV2("my-bucket") +my_bucket_sse_config = aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-sse-config", + bucket=my_bucket.bucket, + rules=[{ + "apply_server_side_encryption_by_default": { + "sse_algorithm": "aws:kms", + }, + }]) ``` @@ -1214,22 +2360,17 @@ import ( func main() { pulumi.Run(func(ctx *pulumi.Context) error { - _, err := s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{ - CorsRules: s3.BucketCorsRuleArray{ - &s3.BucketCorsRuleArgs{ - AllowedHeaders: pulumi.StringArray{ - pulumi.String("*"), - }, - AllowedMethods: pulumi.StringArray{ - pulumi.String("GET"), - }, - AllowedOrigins: pulumi.StringArray{ - pulumi.String("*"), - }, - ExposeHeaders: pulumi.StringArray{ - pulumi.String("ETag"), + myBucket, err := s3.NewBucketV2(ctx, "my-bucket", nil) + if err != nil { + return err + } + _, err = s3.NewBucketServerSideEncryptionConfigurationV2(ctx, "my-bucket-sse-config", &s3.BucketServerSideEncryptionConfigurationV2Args{ + Bucket: myBucket.Bucket, + Rules: s3.BucketServerSideEncryptionConfigurationV2RuleArray{ + &s3.BucketServerSideEncryptionConfigurationV2RuleArgs{ + ApplyServerSideEncryptionByDefault: &s3.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs{ + SseAlgorithm: pulumi.String("aws:kms"), }, - MaxAgeSeconds: pulumi.Int(3000), }, }, }) @@ -1252,31 +2393,21 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { - var myBucket = new Aws.S3.Bucket("my-bucket", new() + var myBucket = new Aws.S3.BucketV2("my-bucket"); + + var myBucketSseConfig = new Aws.S3.BucketServerSideEncryptionConfigurationV2("my-bucket-sse-config", new() { - CorsRules = new[] + Bucket = myBucket.Bucket, + Rules = new[] { - new Aws.S3.Inputs.BucketCorsRuleArgs + new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationV2RuleArgs { - AllowedHeaders = new[] - { - "*", - }, - AllowedMethods = new[] - { - "GET", - }, - AllowedOrigins = new[] - { - "*", - }, - ExposeHeaders = new[] + ApplyServerSideEncryptionByDefault = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs { - "ETag", + SseAlgorithm = "aws:kms", }, - MaxAgeSeconds = 3000, }, }, }); @@ -1296,9 +2427,11 @@ 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.inputs.BucketCorsRuleArgs; +import com.pulumi.aws.s3.BucketV2; +import com.pulumi.aws.s3.BucketServerSideEncryptionConfigurationV2; +import com.pulumi.aws.s3.BucketServerSideEncryptionConfigurationV2Args; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationV2RuleArgs; +import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs; import java.util.List; import java.util.ArrayList; import java.util.Map; @@ -1312,13 +2445,14 @@ public class App { } public static void stack(Context ctx) { - var myBucket = new Bucket("myBucket", BucketArgs.builder() - .corsRules(BucketCorsRuleArgs.builder() - .allowedHeaders("*") - .allowedMethods("GET") - .allowedOrigins("*") - .exposeHeaders("ETag") - .maxAgeSeconds(3000) + var myBucket = new BucketV2("myBucket"); + + var myBucketSseConfig = new BucketServerSideEncryptionConfigurationV2("myBucketSseConfig", BucketServerSideEncryptionConfigurationV2Args.builder() + .bucket(myBucket.bucket()) + .rules(BucketServerSideEncryptionConfigurationV2RuleArgs.builder() + .applyServerSideEncryptionByDefault(BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs.builder() + .sseAlgorithm("aws:kms") + .build()) .build()) .build()); @@ -1336,18 +2470,14 @@ name: example runtime: yaml resources: my-bucket: - type: aws:s3:Bucket + type: aws:s3:BucketV2 + my-bucket-sse-config: + type: aws:s3:BucketServerSideEncryptionConfigurationV2 properties: - corsRules: - - allowedHeaders: - - "*" - allowedMethods: - - "GET" - allowedOrigins: - - "*" - exposeHeaders: - - "ETag" - maxAgeSeconds: 3000 + bucket: ${my-bucket.bucket} + rules: + - applyServerSideEncryptionByDefault: + sseAlgorithm: "aws:kms" ``` {{% /choosable %}} @@ -1356,7 +2486,10 @@ resources: -Use the `aws.s3.BucketCorsConfigurationV2` resource: + +### acceleration input + +To enable acceleration, instead of: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -1366,17 +2499,7 @@ Use the `aws.s3.BucketCorsConfigurationV2` resource: import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; -const myBucket = new aws.s3.BucketV2("my-bucket", {}); -const myBucketCors = new aws.s3.BucketCorsConfigurationV2("my-bucket-cors", { - bucket: myBucket.bucket, - corsRules: [{ - allowedHeaders: ["*"], - allowedMethods: ["GET"], - allowedOrigins: ["*"], - exposeHeaders: ["ETag"], - maxAgeSeconds: 3000, - }], -}); +const myBucket = new aws.s3.Bucket("my-bucket", {accelerationStatus: "Enabled"}); ``` @@ -1388,16 +2511,7 @@ const myBucketCors = new aws.s3.BucketCorsConfigurationV2("my-bucket-cors", { import pulumi import pulumi_aws as aws -my_bucket = aws.s3.BucketV2("my-bucket") -my_bucket_cors = aws.s3.BucketCorsConfigurationV2("my-bucket-cors", - bucket=my_bucket.bucket, - cors_rules=[{ - "allowed_headers": ["*"], - "allowed_methods": ["GET"], - "allowed_origins": ["*"], - "expose_headers": ["ETag"], - "max_age_seconds": 3000, - }]) +my_bucket = aws.s3.Bucket("my-bucket", acceleration_status="Enabled") ``` @@ -1415,29 +2529,8 @@ import ( func main() { pulumi.Run(func(ctx *pulumi.Context) error { - myBucket, err := s3.NewBucketV2(ctx, "my-bucket", nil) - if err != nil { - return err - } - _, err = s3.NewBucketCorsConfigurationV2(ctx, "my-bucket-cors", &s3.BucketCorsConfigurationV2Args{ - Bucket: myBucket.Bucket, - CorsRules: s3.BucketCorsConfigurationV2CorsRuleArray{ - &s3.BucketCorsConfigurationV2CorsRuleArgs{ - AllowedHeaders: pulumi.StringArray{ - pulumi.String("*"), - }, - AllowedMethods: pulumi.StringArray{ - pulumi.String("GET"), - }, - AllowedOrigins: pulumi.StringArray{ - pulumi.String("*"), - }, - ExposeHeaders: pulumi.StringArray{ - pulumi.String("ETag"), - }, - MaxAgeSeconds: pulumi.Int(3000), - }, - }, + _, err := s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{ + AccelerationStatus: pulumi.String("Enabled"), }) if err != nil { return err @@ -1458,36 +2551,11 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { - var myBucket = new Aws.S3.BucketV2("my-bucket"); - - var myBucketCors = new Aws.S3.BucketCorsConfigurationV2("my-bucket-cors", new() + var myBucket = new Aws.S3.Bucket("my-bucket", new() { - Bucket = myBucket.Bucket, - CorsRules = new[] - { - new Aws.S3.Inputs.BucketCorsConfigurationV2CorsRuleArgs - { - AllowedHeaders = new[] - { - "*", - }, - AllowedMethods = new[] - { - "GET", - }, - AllowedOrigins = new[] - { - "*", - }, - ExposeHeaders = new[] - { - "ETag", - }, - MaxAgeSeconds = 3000, - }, - }, + AccelerationStatus = "Enabled", }); }); @@ -1505,10 +2573,8 @@ package generated_program; import com.pulumi.Context; import com.pulumi.Pulumi; import com.pulumi.core.Output; -import com.pulumi.aws.s3.BucketV2; -import com.pulumi.aws.s3.BucketCorsConfigurationV2; -import com.pulumi.aws.s3.BucketCorsConfigurationV2Args; -import com.pulumi.aws.s3.inputs.BucketCorsConfigurationV2CorsRuleArgs; +import com.pulumi.aws.s3.Bucket; +import com.pulumi.aws.s3.BucketArgs; import java.util.List; import java.util.ArrayList; import java.util.Map; @@ -1522,17 +2588,8 @@ public class App { } public static void stack(Context ctx) { - var myBucket = new BucketV2("myBucket"); - - var myBucketCors = new BucketCorsConfigurationV2("myBucketCors", BucketCorsConfigurationV2Args.builder() - .bucket(myBucket.bucket()) - .corsRules(BucketCorsConfigurationV2CorsRuleArgs.builder() - .allowedHeaders("*") - .allowedMethods("GET") - .allowedOrigins("*") - .exposeHeaders("ETag") - .maxAgeSeconds(3000) - .build()) + var myBucket = new Bucket("myBucket", BucketArgs.builder() + .accelerationStatus("Enabled") .build()); } @@ -1549,21 +2606,9 @@ name: example runtime: yaml resources: my-bucket: - type: aws:s3:BucketV2 - my-bucket-cors: - type: aws:s3:BucketCorsConfigurationV2 + type: aws:s3:Bucket properties: - bucket: ${my-bucket.bucket} - corsRules: - - allowedHeaders: - - "*" - allowedMethods: - - "GET" - allowedOrigins: - - "*" - exposeHeaders: - - "ETag" - maxAgeSeconds: 3000 + accelerationStatus: Enabled ``` {{% /choosable %}} @@ -1572,12 +2617,8 @@ resources: -### acl and grants inputs -The `aws.s3.BucketAcl` resource is now required to configure either -[canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl) -or [ACL policy grant](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#sample-acl), -and it replaces the use of `acl` and `grants` inputs. To illustrate migrating the uses of `grants`, instead of: +Use the `aws.s3.BucketAccelerateConfigurationV2` resource: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -1587,12 +2628,11 @@ and it replaces the use of `acl` and `grants` inputs. To illustrate migrating th import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; -const currentUser = aws.s3.getCanonicalUserIdOutput({}); -const myBucket = new aws.s3.Bucket("my-bucket", {grants: [{ - permissions: ["READ"], - type: "CanonicalUser", - id: currentUser.apply(currentUser => currentUser.id), -}]}); +const myBucket = new aws.s3.BucketV2("my-bucket", {}); +const myBucketAcceleration = new aws.s3.BucketAccelerateConfigurationV2("my-bucket-acceleration", { + bucket: myBucket.bucket, + status: "Enabled", +}); ``` @@ -1604,12 +2644,10 @@ const myBucket = new aws.s3.Bucket("my-bucket", {grants: [{ import pulumi import pulumi_aws as aws -current_user = aws.s3.get_canonical_user_id_output() -my_bucket = aws.s3.Bucket("my-bucket", grants=[{ - "permissions": ["READ"], - "type": "CanonicalUser", - "id": current_user.id, -}]) +my_bucket = aws.s3.BucketV2("my-bucket") +my_bucket_acceleration = aws.s3.BucketAccelerateConfigurationV2("my-bucket-acceleration", + bucket=my_bucket.bucket, + status="Enabled") ``` @@ -1627,20 +2665,13 @@ import ( func main() { pulumi.Run(func(ctx *pulumi.Context) error { - currentUser, err := s3.GetCanonicalUserId(ctx, nil, nil) + myBucket, err := s3.NewBucketV2(ctx, "my-bucket", nil) if err != nil { return err } - _, err = s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{ - Grants: s3.BucketGrantArray{ - &s3.BucketGrantArgs{ - Permissions: pulumi.StringArray{ - pulumi.String("READ"), - }, - Type: pulumi.String("CanonicalUser"), - Id: pulumi.String(currentUser.Id), - }, - }, + _, err = s3.NewBucketAccelerateConfigurationV2(ctx, "my-bucket-acceleration", &s3.BucketAccelerateConfigurationV2Args{ + Bucket: myBucket.Bucket, + Status: pulumi.String("Enabled"), }) if err != nil { return err @@ -1661,24 +2692,14 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { - var currentUser = Aws.S3.GetCanonicalUserId.Invoke(); + var myBucket = new Aws.S3.BucketV2("my-bucket"); - var myBucket = new Aws.S3.Bucket("my-bucket", new() + var myBucketAcceleration = new Aws.S3.BucketAccelerateConfigurationV2("my-bucket-acceleration", new() { - Grants = new[] - { - new Aws.S3.Inputs.BucketGrantArgs - { - Permissions = new[] - { - "READ", - }, - Type = "CanonicalUser", - Id = currentUser.Apply(getCanonicalUserIdResult => getCanonicalUserIdResult.Id), - }, - }, + Bucket = myBucket.Bucket, + Status = "Enabled", }); }); @@ -1696,10 +2717,9 @@ package generated_program; import com.pulumi.Context; import com.pulumi.Pulumi; import com.pulumi.core.Output; -import com.pulumi.aws.s3.S3Functions; -import com.pulumi.aws.s3.Bucket; -import com.pulumi.aws.s3.BucketArgs; -import com.pulumi.aws.s3.inputs.BucketGrantArgs; +import com.pulumi.aws.s3.BucketV2; +import com.pulumi.aws.s3.BucketAccelerateConfigurationV2; +import com.pulumi.aws.s3.BucketAccelerateConfigurationV2Args; import java.util.List; import java.util.ArrayList; import java.util.Map; @@ -1713,14 +2733,11 @@ public class App { } public static void stack(Context ctx) { - final var currentUser = S3Functions.getCanonicalUserId(); + var myBucket = new BucketV2("myBucket"); - var myBucket = new Bucket("myBucket", BucketArgs.builder() - .grants(BucketGrantArgs.builder() - .permissions("READ") - .type("CanonicalUser") - .id(currentUser.applyValue(getCanonicalUserIdResult -> getCanonicalUserIdResult.id())) - .build()) + var myBucketAcceleration = new BucketAccelerateConfigurationV2("myBucketAcceleration", BucketAccelerateConfigurationV2Args.builder() + .bucket(myBucket.bucket()) + .status("Enabled") .build()); } @@ -1735,20 +2752,14 @@ public class App { ```yaml name: example runtime: yaml -variables: - currentUser: - fn::invoke: - function: aws:s3:getCanonicalUserId - arguments: {} resources: my-bucket: - type: aws:s3:Bucket + type: aws:s3:BucketV2 + my-bucket-acceleration: + type: aws:s3:BucketAccelerateConfigurationV2 properties: - grants: - - permissions: - - "READ" - type: "CanonicalUser" - id: ${currentUser.id} + bucket: ${my-bucket.bucket} + status: Enabled ``` {{% /choosable %}} @@ -1756,8 +2767,10 @@ resources: {{< /chooser >}} +### corsRules input -Use the `aws.s3.BucketAcl` resource like this: +To configure [Cross-Origin Resource Sharing](https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html), +instead of: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -1767,31 +2780,13 @@ Use the `aws.s3.BucketAcl` resource like this: import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; -const currentUser = aws.s3.getCanonicalUserIdOutput({}); -const myBucket = new aws.s3.BucketV2("my-bucket", {}); -const myBucketOwnership = new aws.s3.BucketOwnershipControls("my-bucket-ownership", { - bucket: myBucket.id, - rule: { - objectOwnership: "BucketOwnerPreferred", - }, -}); -const myBucketAcl = new aws.s3.BucketAclV2("my-bucket-acl", { - bucket: myBucket.bucket, - accessControlPolicy: { - owner: { - id: currentUser.apply(currentUser => currentUser.id), - }, - grants: [{ - permission: "READ", - grantee: { - type: "CanonicalUser", - id: currentUser.apply(currentUser => currentUser.id), - }, - }], - }, -}, { - dependsOn: [myBucketOwnership], -}); +const myBucket = new aws.s3.Bucket("my-bucket", {corsRules: [{ + allowedHeaders: ["*"], + allowedMethods: ["GET"], + allowedOrigins: ["*"], + exposeHeaders: ["ETag"], + maxAgeSeconds: 3000, +}]}); ``` @@ -1803,28 +2798,13 @@ const myBucketAcl = new aws.s3.BucketAclV2("my-bucket-acl", { import pulumi import pulumi_aws as aws -current_user = aws.s3.get_canonical_user_id_output() -my_bucket = aws.s3.BucketV2("my-bucket") -my_bucket_ownership = aws.s3.BucketOwnershipControls("my-bucket-ownership", - bucket=my_bucket.id, - rule={ - "object_ownership": "BucketOwnerPreferred", - }) -my_bucket_acl = aws.s3.BucketAclV2("my-bucket-acl", - bucket=my_bucket.bucket, - access_control_policy={ - "owner": { - "id": current_user.id, - }, - "grants": [{ - "permission": "READ", - "grantee": { - "type": "CanonicalUser", - "id": current_user.id, - }, - }], - }, - opts = pulumi.ResourceOptions(depends_on=[my_bucket_ownership])) +my_bucket = aws.s3.Bucket("my-bucket", cors_rules=[{ + "allowed_headers": ["*"], + "allowed_methods": ["GET"], + "allowed_origins": ["*"], + "expose_headers": ["ETag"], + "max_age_seconds": 3000, +}]) ``` @@ -1842,42 +2822,25 @@ import ( func main() { pulumi.Run(func(ctx *pulumi.Context) error { - currentUser, err := s3.GetCanonicalUserId(ctx, nil, nil) - if err != nil { - return err - } - myBucket, err := s3.NewBucketV2(ctx, "my-bucket", nil) - if err != nil { - return err - } - myBucketOwnership, err := s3.NewBucketOwnershipControls(ctx, "my-bucket-ownership", &s3.BucketOwnershipControlsArgs{ - Bucket: myBucket.ID(), - Rule: &s3.BucketOwnershipControlsRuleArgs{ - ObjectOwnership: pulumi.String("BucketOwnerPreferred"), - }, - }) - if err != nil { - return err - } - _, err = s3.NewBucketAclV2(ctx, "my-bucket-acl", &s3.BucketAclV2Args{ - Bucket: myBucket.Bucket, - AccessControlPolicy: &s3.BucketAclV2AccessControlPolicyArgs{ - Owner: &s3.BucketAclV2AccessControlPolicyOwnerArgs{ - Id: pulumi.String(currentUser.Id), - }, - Grants: s3.BucketAclV2AccessControlPolicyGrantArray{ - &s3.BucketAclV2AccessControlPolicyGrantArgs{ - Permission: pulumi.String("READ"), - Grantee: &s3.BucketAclV2AccessControlPolicyGrantGranteeArgs{ - Type: pulumi.String("CanonicalUser"), - Id: pulumi.String(currentUser.Id), - }, + _, err := s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{ + CorsRules: s3.BucketCorsRuleArray{ + &s3.BucketCorsRuleArgs{ + AllowedHeaders: pulumi.StringArray{ + pulumi.String("*"), + }, + AllowedMethods: pulumi.StringArray{ + pulumi.String("GET"), }, + AllowedOrigins: pulumi.StringArray{ + pulumi.String("*"), + }, + ExposeHeaders: pulumi.StringArray{ + pulumi.String("ETag"), + }, + MaxAgeSeconds: pulumi.Int(3000), }, }, - }, pulumi.DependsOn([]pulumi.Resource{ - myBucketOwnership, - })) + }) if err != nil { return err } @@ -1897,48 +2860,32 @@ using System.Linq; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { - var currentUser = Aws.S3.GetCanonicalUserId.Invoke(); - - var myBucket = new Aws.S3.BucketV2("my-bucket"); - - var myBucketOwnership = new Aws.S3.BucketOwnershipControls("my-bucket-ownership", new() - { - Bucket = myBucket.Id, - Rule = new Aws.S3.Inputs.BucketOwnershipControlsRuleArgs - { - ObjectOwnership = "BucketOwnerPreferred", - }, - }); - - var myBucketAcl = new Aws.S3.BucketAclV2("my-bucket-acl", new() + var myBucket = new Aws.S3.Bucket("my-bucket", new() { - Bucket = myBucket.Bucket, - AccessControlPolicy = new Aws.S3.Inputs.BucketAclV2AccessControlPolicyArgs + CorsRules = new[] { - Owner = new Aws.S3.Inputs.BucketAclV2AccessControlPolicyOwnerArgs - { - Id = currentUser.Apply(getCanonicalUserIdResult => getCanonicalUserIdResult.Id), - }, - Grants = new[] + new Aws.S3.Inputs.BucketCorsRuleArgs { - new Aws.S3.Inputs.BucketAclV2AccessControlPolicyGrantArgs + AllowedHeaders = new[] { - Permission = "READ", - Grantee = new Aws.S3.Inputs.BucketAclV2AccessControlPolicyGrantGranteeArgs - { - Type = "CanonicalUser", - Id = currentUser.Apply(getCanonicalUserIdResult => getCanonicalUserIdResult.Id), - }, + "*", }, - }, - }, - }, new CustomResourceOptions - { - DependsOn = - { - myBucketOwnership, + AllowedMethods = new[] + { + "GET", + }, + AllowedOrigins = new[] + { + "*", + }, + ExposeHeaders = new[] + { + "ETag", + }, + MaxAgeSeconds = 3000, + }, }, }); @@ -1957,16 +2904,9 @@ package generated_program; import com.pulumi.Context; import com.pulumi.Pulumi; import com.pulumi.core.Output; -import com.pulumi.aws.s3.S3Functions; -import com.pulumi.aws.s3.BucketV2; -import com.pulumi.aws.s3.BucketOwnershipControls; -import com.pulumi.aws.s3.BucketOwnershipControlsArgs; -import com.pulumi.aws.s3.inputs.BucketOwnershipControlsRuleArgs; -import com.pulumi.aws.s3.BucketAclV2; -import com.pulumi.aws.s3.BucketAclV2Args; -import com.pulumi.aws.s3.inputs.BucketAclV2AccessControlPolicyArgs; -import com.pulumi.aws.s3.inputs.BucketAclV2AccessControlPolicyOwnerArgs; -import com.pulumi.resources.CustomResourceOptions; +import com.pulumi.aws.s3.Bucket; +import com.pulumi.aws.s3.BucketArgs; +import com.pulumi.aws.s3.inputs.BucketCorsRuleArgs; import java.util.List; import java.util.ArrayList; import java.util.Map; @@ -1980,35 +2920,16 @@ public class App { } public static void stack(Context ctx) { - final var currentUser = S3Functions.getCanonicalUserId(); - - var myBucket = new BucketV2("myBucket"); - - var myBucketOwnership = new BucketOwnershipControls("myBucketOwnership", BucketOwnershipControlsArgs.builder() - .bucket(myBucket.id()) - .rule(BucketOwnershipControlsRuleArgs.builder() - .objectOwnership("BucketOwnerPreferred") + var myBucket = new Bucket("myBucket", BucketArgs.builder() + .corsRules(BucketCorsRuleArgs.builder() + .allowedHeaders("*") + .allowedMethods("GET") + .allowedOrigins("*") + .exposeHeaders("ETag") + .maxAgeSeconds(3000) .build()) .build()); - var myBucketAcl = new BucketAclV2("myBucketAcl", BucketAclV2Args.builder() - .bucket(myBucket.bucket()) - .accessControlPolicy(BucketAclV2AccessControlPolicyArgs.builder() - .owner(BucketAclV2AccessControlPolicyOwnerArgs.builder() - .id(currentUser.applyValue(getCanonicalUserIdResult -> getCanonicalUserIdResult.id())) - .build()) - .grants(BucketAclV2AccessControlPolicyGrantArgs.builder() - .permission("READ") - .grantee(BucketAclV2AccessControlPolicyGrantGranteeArgs.builder() - .type("CanonicalUser") - .id(currentUser.applyValue(getCanonicalUserIdResult -> getCanonicalUserIdResult.id())) - .build()) - .build()) - .build()) - .build(), CustomResourceOptions.builder() - .dependsOn(myBucketOwnership) - .build()); - } } @@ -2021,35 +2942,20 @@ public class App { ```yaml name: example runtime: yaml -variables: - currentUser: - fn::invoke: - function: aws:s3:getCanonicalUserId - arguments: {} resources: my-bucket: - type: aws:s3:BucketV2 - my-bucket-ownership: - type: aws:s3:BucketOwnershipControls - properties: - bucket: ${my-bucket.id} - rule: - objectOwnership: "BucketOwnerPreferred" - my-bucket-acl: - type: aws:s3:BucketAclV2 + type: aws:s3:Bucket properties: - bucket: ${my-bucket.bucket} - accessControlPolicy: - owner: - id: ${currentUser.id} - grants: - - permission: "READ" - grantee: - type: "CanonicalUser" - id: ${currentUser.id} - options: - dependsOn: - - ${my-bucket-ownership} + corsRules: + - allowedHeaders: + - "*" + allowedMethods: + - "GET" + allowedOrigins: + - "*" + exposeHeaders: + - "ETag" + maxAgeSeconds: 3000 ``` {{% /choosable %}} @@ -2058,53 +2964,7 @@ resources: - -Note that `dependsOn` on `BucketOwnershipControls` is required for Pulumi to correctly order the operations for this -infrastructure. Consult the documentation on `aws.s3.BucketAclV2` for more fully worked examples of configuring ACL. - -### hostedZoneId input - -This will only be available as an output. If your program specified this as an input, simply remove it. The input was -ignored by prior versions of the provider and was exposed in error. - -### other inputs - -All other removed inputs are treated similarly. Consult the documentation for the matching resource replacing the input -for more information: - -| Input | Resource | -|--------------------------|--------------------------------------------| -| lifecycleRules | aws.s3.BucketLifecycleConfigurationV2 | -| loggings | aws.s3.BucketLoggingV2 | -| objectLockConfiguration | aws.s3.BucketObjectLockConfigurationV2 | -| replicationConfiguration | aws.s3.BucketReplicationConfig | -| requestPayer | aws.s3.BucketRequestPaymentConfigurationV2 | -| versionings | aws.s3.BucketVersioningV2 | -| website | aws.s3.BucketWebsiteConfigurationV2 | -| websiteDomain | aws.s3.BucketWebsiteConfigurationV2 | -| websiteEndpoint | aws.s3.BucketWebsiteConfigurationV2 | - - -## Avoiding replacement - -In situations when replacing the bucket in the AWS account is not acceptable, it is possible to perform a manual -migration that changes Pulumi program and state to track buckets using the new resource without executing any changes -against the actual cloud account. While the details will vary depending on your use case, this procedure generally -involves the following steps: - -- Find URNs for legacy Bucket Pulumi resources using `pulumi stack export` -- Determine the actual bucket name(s) -- Remove the legacy Bucket code from your Pulumi program source -- Remove the legacy Bucket resources from state using `pulumi state delete $bucketURN` -- Determine which side-by-side resources will be needed for each bucket -- Construct an `pulumi-import.json` file listing the buckets and their side-by-side resources -- Run `pulumi import --file import-file.json` using the [Bulk Importing](https://www.pulumi.com/tutorials/importing/bulk-importing/) feature -- Add the suggested code into your Pulumi program source -- Run `pulumi preview` to confirm a no-change plan -- If warnings are generated, edit the program to remove deprecated inputs from BucketV2 -- Run `pulumi preview` one more time to confirm a no-change plan on the final program - -Consider a concrete example, suppose you have provisioned a bucket as follows: +Use the `aws.s3.BucketCorsConfigurationV2` resource: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -2114,46 +2974,16 @@ Consider a concrete example, suppose you have provisioned a bucket as follows: import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; -const myBucket = new aws.s3.Bucket("my-bucket", { - bucket: "my-bucket-26224917", - serverSideEncryptionConfiguration: { - rule: { - applyServerSideEncryptionByDefault: { - sseAlgorithm: "AES256", - }, - }, - }, - lifecycleRules: [{ - enabled: true, - expiration: { - days: 30, - }, +const myBucket = new aws.s3.BucketV2("my-bucket", {}); +const myBucketCors = new aws.s3.BucketCorsConfigurationV2("my-bucket-cors", { + bucket: myBucket.bucket, + corsRules: [{ + allowedHeaders: ["*"], + allowedMethods: ["GET"], + allowedOrigins: ["*"], + exposeHeaders: ["ETag"], + maxAgeSeconds: 3000, }], - policy: JSON.stringify({ - Version: "2012-10-17", - Id: "PutObjPolicy", - Statement: [{ - Sid: "DenyObjectsThatAreNotSSEKMS", - Principal: "*", - Effect: "Deny", - Action: "s3:PutObject", - Resource: "arn:aws:s3:::my-bucket-26224917/*", - Condition: { - Null: { - "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", - }, - }, - }], - }), - tags: { - Environment: "Dev", - }, - objectLockConfiguration: { - objectLockEnabled: "Enabled", - }, - versioning: { - enabled: true, - }, }); ``` @@ -2164,49 +2994,18 @@ const myBucket = new aws.s3.Bucket("my-bucket", { ```python import pulumi -import json import pulumi_aws as aws -my_bucket = aws.s3.Bucket("my-bucket", - bucket="my-bucket-26224917", - server_side_encryption_configuration={ - "rule": { - "apply_server_side_encryption_by_default": { - "sse_algorithm": "AES256", - }, - }, - }, - lifecycle_rules=[{ - "enabled": True, - "expiration": { - "days": 30, - }, - }], - policy=json.dumps({ - "Version": "2012-10-17", - "Id": "PutObjPolicy", - "Statement": [{ - "Sid": "DenyObjectsThatAreNotSSEKMS", - "Principal": "*", - "Effect": "Deny", - "Action": "s3:PutObject", - "Resource": "arn:aws:s3:::my-bucket-26224917/*", - "Condition": { - "Null": { - "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", - }, - }, - }], - }), - tags={ - "Environment": "Dev", - }, - object_lock_configuration={ - "object_lock_enabled": "Enabled", - }, - versioning={ - "enabled": True, - }) +my_bucket = aws.s3.BucketV2("my-bucket") +my_bucket_cors = aws.s3.BucketCorsConfigurationV2("my-bucket-cors", + bucket=my_bucket.bucket, + cors_rules=[{ + "allowed_headers": ["*"], + "allowed_methods": ["GET"], + "allowed_origins": ["*"], + "expose_headers": ["ETag"], + "max_age_seconds": 3000, + }]) ``` @@ -2218,63 +3017,35 @@ my_bucket = aws.s3.Bucket("my-bucket", package main import ( - "encoding/json" - "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" ) func main() { pulumi.Run(func(ctx *pulumi.Context) error { - tmpJSON0, err := json.Marshal(map[string]interface{}{ - "Version": "2012-10-17", - "Id": "PutObjPolicy", - "Statement": []map[string]interface{}{ - map[string]interface{}{ - "Sid": "DenyObjectsThatAreNotSSEKMS", - "Principal": "*", - "Effect": "Deny", - "Action": "s3:PutObject", - "Resource": "arn:aws:s3:::my-bucket-26224917/*", - "Condition": map[string]interface{}{ - "Null": map[string]interface{}{ - "s3:x-amz-server-side-encryption-aws-kms-key-id": "true", - }, - }, - }, - }, - }) + myBucket, err := s3.NewBucketV2(ctx, "my-bucket", nil) if err != nil { return err } - json0 := string(tmpJSON0) - _, err = s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{ - Bucket: pulumi.String("my-bucket-26224917"), - ServerSideEncryptionConfiguration: &s3.BucketServerSideEncryptionConfigurationArgs{ - Rule: &s3.BucketServerSideEncryptionConfigurationRuleArgs{ - ApplyServerSideEncryptionByDefault: &s3.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs{ - SseAlgorithm: pulumi.String("AES256"), + _, err = s3.NewBucketCorsConfigurationV2(ctx, "my-bucket-cors", &s3.BucketCorsConfigurationV2Args{ + Bucket: myBucket.Bucket, + CorsRules: s3.BucketCorsConfigurationV2CorsRuleArray{ + &s3.BucketCorsConfigurationV2CorsRuleArgs{ + AllowedHeaders: pulumi.StringArray{ + pulumi.String("*"), }, - }, - }, - LifecycleRules: s3.BucketLifecycleRuleArray{ - &s3.BucketLifecycleRuleArgs{ - Enabled: pulumi.Bool(true), - Expiration: &s3.BucketLifecycleRuleExpirationArgs{ - Days: pulumi.Int(30), + AllowedMethods: pulumi.StringArray{ + pulumi.String("GET"), + }, + AllowedOrigins: pulumi.StringArray{ + pulumi.String("*"), }, + ExposeHeaders: pulumi.StringArray{ + pulumi.String("ETag"), + }, + MaxAgeSeconds: pulumi.Int(3000), }, }, - Policy: pulumi.String(json0), - Tags: pulumi.StringMap{ - "Environment": pulumi.String("Dev"), - }, - ObjectLockConfiguration: &s3.BucketObjectLockConfigurationArgs{ - ObjectLockEnabled: pulumi.String("Enabled"), - }, - Versioning: &s3.BucketVersioningArgs{ - Enabled: pulumi.Bool(true), - }, }) if err != nil { return err @@ -2292,70 +3063,38 @@ func main() { ```csharp using System.Collections.Generic; using System.Linq; -using System.Text.Json; using Pulumi; using Aws = Pulumi.Aws; -return await Deployment.RunAsync(() => +return await Deployment.RunAsync(() => { - var myBucket = new Aws.S3.Bucket("my-bucket", new() + var myBucket = new Aws.S3.BucketV2("my-bucket"); + + var myBucketCors = new Aws.S3.BucketCorsConfigurationV2("my-bucket-cors", new() { - BucketName = "my-bucket-26224917", - ServerSideEncryptionConfiguration = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationArgs + Bucket = myBucket.Bucket, + CorsRules = new[] { - Rule = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationRuleArgs + new Aws.S3.Inputs.BucketCorsConfigurationV2CorsRuleArgs { - ApplyServerSideEncryptionByDefault = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs + AllowedHeaders = new[] { - SseAlgorithm = "AES256", + "*", }, - }, - }, - LifecycleRules = new[] - { - new Aws.S3.Inputs.BucketLifecycleRuleArgs - { - Enabled = true, - Expiration = new Aws.S3.Inputs.BucketLifecycleRuleExpirationArgs + AllowedMethods = new[] { - Days = 30, + "GET", }, - }, - }, - Policy = JsonSerializer.Serialize(new Dictionary - { - ["Version"] = "2012-10-17", - ["Id"] = "PutObjPolicy", - ["Statement"] = new[] - { - new Dictionary + AllowedOrigins = new[] { - ["Sid"] = "DenyObjectsThatAreNotSSEKMS", - ["Principal"] = "*", - ["Effect"] = "Deny", - ["Action"] = "s3:PutObject", - ["Resource"] = "arn:aws:s3:::my-bucket-26224917/*", - ["Condition"] = new Dictionary - { - ["Null"] = new Dictionary - { - ["s3:x-amz-server-side-encryption-aws-kms-key-id"] = "true", - }, - }, + "*", + }, + ExposeHeaders = new[] + { + "ETag", }, + MaxAgeSeconds = 3000, }, - }), - Tags = - { - { "Environment", "Dev" }, - }, - ObjectLockConfiguration = new Aws.S3.Inputs.BucketObjectLockConfigurationArgs - { - ObjectLockEnabled = "Enabled", - }, - Versioning = new Aws.S3.Inputs.BucketVersioningArgs - { - Enabled = true, }, }); @@ -2374,16 +3113,10 @@ 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.inputs.BucketServerSideEncryptionConfigurationArgs; -import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationRuleArgs; -import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs; -import com.pulumi.aws.s3.inputs.BucketLifecycleRuleArgs; -import com.pulumi.aws.s3.inputs.BucketLifecycleRuleExpirationArgs; -import com.pulumi.aws.s3.inputs.BucketObjectLockConfigurationArgs; -import com.pulumi.aws.s3.inputs.BucketVersioningArgs; -import static com.pulumi.codegen.internal.Serialization.*; +import com.pulumi.aws.s3.BucketV2; +import com.pulumi.aws.s3.BucketCorsConfigurationV2; +import com.pulumi.aws.s3.BucketCorsConfigurationV2Args; +import com.pulumi.aws.s3.inputs.BucketCorsConfigurationV2CorsRuleArgs; import java.util.List; import java.util.ArrayList; import java.util.Map; @@ -2397,44 +3130,16 @@ public class App { } public static void stack(Context ctx) { - var myBucket = new Bucket("myBucket", BucketArgs.builder() - .bucket("my-bucket-26224917") - .serverSideEncryptionConfiguration(BucketServerSideEncryptionConfigurationArgs.builder() - .rule(BucketServerSideEncryptionConfigurationRuleArgs.builder() - .applyServerSideEncryptionByDefault(BucketServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs.builder() - .sseAlgorithm("AES256") - .build()) - .build()) - .build()) - .lifecycleRules(BucketLifecycleRuleArgs.builder() - .enabled(true) - .expiration(BucketLifecycleRuleExpirationArgs.builder() - .days(30) - .build()) - .build()) - .policy(serializeJson( - jsonObject( - jsonProperty("Version", "2012-10-17"), - jsonProperty("Id", "PutObjPolicy"), - jsonProperty("Statement", jsonArray(jsonObject( - jsonProperty("Sid", "DenyObjectsThatAreNotSSEKMS"), - jsonProperty("Principal", "*"), - jsonProperty("Effect", "Deny"), - jsonProperty("Action", "s3:PutObject"), - jsonProperty("Resource", "arn:aws:s3:::my-bucket-26224917/*"), - jsonProperty("Condition", jsonObject( - jsonProperty("Null", jsonObject( - jsonProperty("s3:x-amz-server-side-encryption-aws-kms-key-id", "true") - )) - )) - ))) - ))) - .tags(Map.of("Environment", "Dev")) - .objectLockConfiguration(BucketObjectLockConfigurationArgs.builder() - .objectLockEnabled("Enabled") - .build()) - .versioning(BucketVersioningArgs.builder() - .enabled(true) + var myBucket = new BucketV2("myBucket"); + + var myBucketCors = new BucketCorsConfigurationV2("myBucketCors", BucketCorsConfigurationV2Args.builder() + .bucket(myBucket.bucket()) + .corsRules(BucketCorsConfigurationV2CorsRuleArgs.builder() + .allowedHeaders("*") + .allowedMethods("GET") + .allowedOrigins("*") + .exposeHeaders("ETag") + .maxAgeSeconds(3000) .build()) .build()); @@ -2448,193 +3153,54 @@ public class App { {{% choosable language yaml %}} ```yaml -name: y2 +name: example runtime: yaml resources: my-bucket: - type: aws:s3:Bucket + type: aws:s3:BucketV2 + my-bucket-cors: + type: aws:s3:BucketCorsConfigurationV2 properties: - bucket: "my-bucket-26224917" - serverSideEncryptionConfiguration: - rule: - applyServerSideEncryptionByDefault: - sseAlgorithm: "AES256" - lifecycleRules: - - enabled: true - expiration: - days: 30 - policy: - fn::toJSON: - Version: "2012-10-17" - Id: "PutObjPolicy" - Statement: - - Sid: "DenyObjectsThatAreNotSSEKMS" - Principal: "*" - Effect: "Deny" - Action: "s3:PutObject" - Resource: "arn:aws:s3:::my-bucket-26224917/*" - Condition: - "Null": - "s3:x-amz-server-side-encryption-aws-kms-key-id": "true" - tags: - Environment: "Dev" - objectLockConfiguration: - objectLockEnabled: "Enabled" - versioning: - enabled: true + bucket: ${my-bucket.bucket} + corsRules: + - allowedHeaders: + - "*" + allowedMethods: + - "GET" + allowedOrigins: + - "*" + exposeHeaders: + - "ETag" + maxAgeSeconds: 3000 ``` {{% /choosable %}} {{< /chooser >}} -Migrate as follows: -- Scanning through the state in `pulumi stack export`, observe and note its URN is - `"urn:pulumi:bucket1::y2::aws:s3/bucket:Bucket::my-bucket"` -- The state file should also include the actual cloud name for the bucket such as `"bucket": "my-bucket-36224917"` +### acl and grants inputs -- Run `pulumi state delete "urn:pulumi:bucket1::y2::aws:s3/bucket:Bucket::my-bucket"` to remove the old bucket from the - state +The `aws.s3.BucketAcl` resource is now required to configure either +[canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl) +or [ACL policy grant](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#sample-acl), +and it replaces the use of `acl` and `grants` inputs. To illustrate migrating the uses of `grants`, instead of: -- Delete the code for the old bucket from the sources. +{{< chooser language "typescript,python,go,csharp,java,yaml" >}} -- This bucket will require the following side-by-side resources: +{{% choosable language typescript %}} - aws:s3:BucketServerSideEncryptionConfigurationV2 - aws:s3:BucketLifecycleConfigurationV2 - aws:s3:BucketPolicy - aws:s3:BucketObjectLockConfigurationV2 - aws:s3:BucketVersioningV2 +```typescript +import * as pulumi from "@pulumi/pulumi"; +import * as aws from "@pulumi/aws"; -- The import file should therefore look like this: - - ```json - { - "resources": [ - { - "type": "aws:s3/bucketV2:BucketV2", - "name": "my-bucket2", - "id": "my-bucket-36224917" - }, - { - "type": "aws:s3/bucketServerSideEncryptionConfigurationV2:BucketServerSideEncryptionConfigurationV2", - "name": "my-bucket-encryption-configuration", - "id": "my-bucket-36224917" - }, - { - "type": "aws:s3/bucketPolicy:BucketPolicy", - "name": "my-bucket-policy", - "id": "my-bucket-36224917" - }, - { - "type": "aws:s3/bucketLifecycleConfigurationV2:BucketLifecycleConfigurationV2", - "name": "my-bucket-policy", - "id": "my-bucket-36224917" - }, - { - "type": "aws:s3/bucketObjectLockConfigurationV2:BucketObjectLockConfigurationV2", - "name": "my-bucket-object-lock-configuration", - "id": "my-bucket-36224917" - }, - { - "type": "aws:s3/bucketVersioningV2:BucketVersioningV2", - "name": "my-bucket-versioning", - "id": "my-bucket-36224917" - } - ] - } - ``` - -- `pulumi import --file import-file.json` will suggest new code to include in your program, for example: - -{{< chooser language "typescript,python,go,csharp,java,yaml" >}} - -{{% choosable language typescript %}} - -```typescript -import * as pulumi from "@pulumi/pulumi"; -import * as aws from "@pulumi/aws"; - -const myBucket = new aws.s3.BucketV2("my-bucket", { - bucket: "my-bucket-36224917", - grants: [{ - id: "e07865a5679c7977370948f1f1e51c21b12d8cfdd396a7e3172275d9164e01b8", - permissions: ["FULL_CONTROL"], - type: "CanonicalUser", - }], - lifecycleRules: [{ - enabled: true, - expirations: [{ - days: 30, - }], - id: "pu-s3-lifecycle-20240918194815251100000001", - }], - objectLockConfiguration: { - objectLockEnabled: "Enabled", - }, - policy: "{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", - requestPayer: "BucketOwner", - serverSideEncryptionConfigurations: [{ - rules: [{ - applyServerSideEncryptionByDefaults: [{ - sseAlgorithm: "AES256", - }], - }], - }], - tags: { - Environment: "Dev", - }, - versionings: [{ - enabled: true, - }], -}, { - protect: true, -}); -const myBucketEncryptionConfiguration = new aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", { - bucket: "my-bucket-36224917", - rules: [{ - applyServerSideEncryptionByDefault: { - sseAlgorithm: "AES256", - }, - }], -}, { - protect: true, -}); -const myBucketPolicy = new aws.s3.BucketPolicy("my-bucket-policy", { - bucket: "my-bucket-36224917", - policy: "{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", -}, { - protect: true, -}); -const myBucketLifecycle = new aws.s3.BucketLifecycleConfigurationV2("my-bucket-lifecycle", { - bucket: "my-bucket-36224917", - rules: [{ - expiration: { - days: 30, - }, - id: "pu-s3-lifecycle-20240918194815251100000001", - status: "Enabled", - }], -}, { - protect: true, -}); -const myBucketObjectLockConfiguration = new aws.s3.BucketObjectLockConfigurationV2("my-bucket-object-lock-configuration", { - bucket: "my-bucket-36224917", - objectLockEnabled: "Enabled", -}, { - protect: true, -}); -const myBucketVersioning = new aws.s3.BucketVersioningV2("my-bucket-versioning", { - bucket: "my-bucket-36224917", - versioningConfiguration: { - mfaDelete: "Disabled", - status: "Enabled", - }, -}, { - protect: true, -}); +const currentUser = aws.s3.getCanonicalUserIdOutput({}); +const myBucket = new aws.s3.Bucket("my-bucket", {grants: [{ + permissions: ["READ"], + type: "CanonicalUser", + id: currentUser.apply(currentUser => currentUser.id), +}]}); ``` @@ -2646,72 +3212,12 @@ const myBucketVersioning = new aws.s3.BucketVersioningV2("my-bucket-versioning", import pulumi import pulumi_aws as aws -my_bucket = aws.s3.BucketV2("my-bucket", - bucket="my-bucket-36224917", - grants=[{ - "id": "e07865a5679c7977370948f1f1e51c21b12d8cfdd396a7e3172275d9164e01b8", - "permissions": ["FULL_CONTROL"], - "type": "CanonicalUser", - }], - lifecycle_rules=[{ - "enabled": True, - "expirations": [{ - "days": 30, - }], - "id": "pu-s3-lifecycle-20240918194815251100000001", - }], - object_lock_configuration={ - "object_lock_enabled": "Enabled", - }, - policy="{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", - request_payer="BucketOwner", - server_side_encryption_configurations=[{ - "rules": [{ - "apply_server_side_encryption_by_defaults": [{ - "sse_algorithm": "AES256", - }], - }], - }], - tags={ - "Environment": "Dev", - }, - versionings=[{ - "enabled": True, - }], - opts = pulumi.ResourceOptions(protect=True)) -my_bucket_encryption_configuration = aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", - bucket="my-bucket-36224917", - rules=[{ - "apply_server_side_encryption_by_default": { - "sse_algorithm": "AES256", - }, - }], - opts = pulumi.ResourceOptions(protect=True)) -my_bucket_policy = aws.s3.BucketPolicy("my-bucket-policy", - bucket="my-bucket-36224917", - policy="{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", - opts = pulumi.ResourceOptions(protect=True)) -my_bucket_lifecycle = aws.s3.BucketLifecycleConfigurationV2("my-bucket-lifecycle", - bucket="my-bucket-36224917", - rules=[{ - "expiration": { - "days": 30, - }, - "id": "pu-s3-lifecycle-20240918194815251100000001", - "status": "Enabled", - }], - opts = pulumi.ResourceOptions(protect=True)) -my_bucket_object_lock_configuration = aws.s3.BucketObjectLockConfigurationV2("my-bucket-object-lock-configuration", - bucket="my-bucket-36224917", - object_lock_enabled="Enabled", - opts = pulumi.ResourceOptions(protect=True)) -my_bucket_versioning = aws.s3.BucketVersioningV2("my-bucket-versioning", - bucket="my-bucket-36224917", - versioning_configuration={ - "mfa_delete": "Disabled", - "status": "Enabled", - }, - opts = pulumi.ResourceOptions(protect=True)) +current_user = aws.s3.get_canonical_user_id_output() +my_bucket = aws.s3.Bucket("my-bucket", grants=[{ + "permissions": ["READ"], + "type": "CanonicalUser", + "id": current_user.id, +}]) ``` @@ -2729,107 +3235,21 @@ import ( func main() { pulumi.Run(func(ctx *pulumi.Context) error { - _, err := s3.NewBucketV2(ctx, "my-bucket", &s3.BucketV2Args{ - Bucket: pulumi.String("my-bucket-36224917"), - Grants: s3.BucketV2GrantArray{ - &s3.BucketV2GrantArgs{ - Id: pulumi.String("e07865a5679c7977370948f1f1e51c21b12d8cfdd396a7e3172275d9164e01b8"), - Permissions: pulumi.StringArray{ - pulumi.String("FULL_CONTROL"), - }, - Type: pulumi.String("CanonicalUser"), - }, - }, - LifecycleRules: s3.BucketV2LifecycleRuleArray{ - &s3.BucketV2LifecycleRuleArgs{ - Enabled: pulumi.Bool(true), - Expirations: s3.BucketV2LifecycleRuleExpirationArray{ - &s3.BucketV2LifecycleRuleExpirationArgs{ - Days: pulumi.Int(30), - }, - }, - Id: pulumi.String("pu-s3-lifecycle-20240918194815251100000001"), - }, - }, - ObjectLockConfiguration: &s3.BucketV2ObjectLockConfigurationArgs{ - ObjectLockEnabled: pulumi.String("Enabled"), - }, - Policy: pulumi.String("{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}"), - RequestPayer: pulumi.String("BucketOwner"), - ServerSideEncryptionConfigurations: s3.BucketV2ServerSideEncryptionConfigurationArray{ - &s3.BucketV2ServerSideEncryptionConfigurationArgs{ - Rules: s3.BucketV2ServerSideEncryptionConfigurationRuleArray{ - &s3.BucketV2ServerSideEncryptionConfigurationRuleArgs{ - ApplyServerSideEncryptionByDefaults: s3.BucketV2ServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArray{ - &s3.BucketV2ServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs{ - SseAlgorithm: pulumi.String("AES256"), - }, - }, - }, - }, - }, - }, - Tags: pulumi.StringMap{ - "Environment": pulumi.String("Dev"), - }, - Versionings: s3.BucketV2VersioningArray{ - &s3.BucketV2VersioningArgs{ - Enabled: pulumi.Bool(true), - }, - }, - }, pulumi.Protect(true)) - if err != nil { - return err - } - _, err = s3.NewBucketServerSideEncryptionConfigurationV2(ctx, "my-bucket-encryption-configuration", &s3.BucketServerSideEncryptionConfigurationV2Args{ - Bucket: pulumi.String("my-bucket-36224917"), - Rules: s3.BucketServerSideEncryptionConfigurationV2RuleArray{ - &s3.BucketServerSideEncryptionConfigurationV2RuleArgs{ - ApplyServerSideEncryptionByDefault: &s3.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs{ - SseAlgorithm: pulumi.String("AES256"), - }, - }, - }, - }, pulumi.Protect(true)) - if err != nil { - return err - } - _, err = s3.NewBucketPolicy(ctx, "my-bucket-policy", &s3.BucketPolicyArgs{ - Bucket: pulumi.String("my-bucket-36224917"), - Policy: pulumi.Any("{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}"), - }, pulumi.Protect(true)) + currentUser, err := s3.GetCanonicalUserId(ctx, nil, nil) if err != nil { return err } - _, err = s3.NewBucketLifecycleConfigurationV2(ctx, "my-bucket-lifecycle", &s3.BucketLifecycleConfigurationV2Args{ - Bucket: pulumi.String("my-bucket-36224917"), - Rules: s3.BucketLifecycleConfigurationV2RuleArray{ - &s3.BucketLifecycleConfigurationV2RuleArgs{ - Expiration: &s3.BucketLifecycleConfigurationV2RuleExpirationArgs{ - Days: pulumi.Int(30), + _, err = s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{ + Grants: s3.BucketGrantArray{ + &s3.BucketGrantArgs{ + Permissions: pulumi.StringArray{ + pulumi.String("READ"), }, - Id: pulumi.String("pu-s3-lifecycle-20240918194815251100000001"), - Status: pulumi.String("Enabled"), + Type: pulumi.String("CanonicalUser"), + Id: pulumi.String(currentUser.Id), }, }, - }, pulumi.Protect(true)) - if err != nil { - return err - } - _, err = s3.NewBucketObjectLockConfigurationV2(ctx, "my-bucket-object-lock-configuration", &s3.BucketObjectLockConfigurationV2Args{ - Bucket: pulumi.String("my-bucket-36224917"), - ObjectLockEnabled: pulumi.String("Enabled"), - }, pulumi.Protect(true)) - if err != nil { - return err - } - _, err = s3.NewBucketVersioningV2(ctx, "my-bucket-versioning", &s3.BucketVersioningV2Args{ - Bucket: pulumi.String("my-bucket-36224917"), - VersioningConfiguration: &s3.BucketVersioningV2VersioningConfigurationArgs{ - MfaDelete: pulumi.String("Disabled"), - Status: pulumi.String("Enabled"), - }, - }, pulumi.Protect(true)) + }) if err != nil { return err } @@ -2839,156 +3259,34 @@ func main() { ``` -{{% /choosable %}} - -{{% choosable language csharp %}} - -```csharp -using System.Collections.Generic; -using System.Linq; -using Pulumi; -using Aws = Pulumi.Aws; - -return await Deployment.RunAsync(() => -{ - var myBucket = new Aws.S3.BucketV2("my-bucket", new() - { - Bucket = "my-bucket-36224917", - Grants = new[] - { - new Aws.S3.Inputs.BucketV2GrantArgs - { - Id = "e07865a5679c7977370948f1f1e51c21b12d8cfdd396a7e3172275d9164e01b8", - Permissions = new[] - { - "FULL_CONTROL", - }, - Type = "CanonicalUser", - }, - }, - LifecycleRules = new[] - { - new Aws.S3.Inputs.BucketV2LifecycleRuleArgs - { - Enabled = true, - Expirations = new[] - { - new Aws.S3.Inputs.BucketV2LifecycleRuleExpirationArgs - { - Days = 30, - }, - }, - Id = "pu-s3-lifecycle-20240918194815251100000001", - }, - }, - ObjectLockConfiguration = new Aws.S3.Inputs.BucketV2ObjectLockConfigurationArgs - { - ObjectLockEnabled = "Enabled", - }, - Policy = "{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", - RequestPayer = "BucketOwner", - ServerSideEncryptionConfigurations = new[] - { - new Aws.S3.Inputs.BucketV2ServerSideEncryptionConfigurationArgs - { - Rules = new[] - { - new Aws.S3.Inputs.BucketV2ServerSideEncryptionConfigurationRuleArgs - { - ApplyServerSideEncryptionByDefaults = new[] - { - new Aws.S3.Inputs.BucketV2ServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs - { - SseAlgorithm = "AES256", - }, - }, - }, - }, - }, - }, - Tags = - { - { "Environment", "Dev" }, - }, - Versionings = new[] - { - new Aws.S3.Inputs.BucketV2VersioningArgs - { - Enabled = true, - }, - }, - }, new CustomResourceOptions - { - Protect = true, - }); +{{% /choosable %}} - var myBucketEncryptionConfiguration = new Aws.S3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", new() - { - Bucket = "my-bucket-36224917", - Rules = new[] - { - new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationV2RuleArgs - { - ApplyServerSideEncryptionByDefault = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs - { - SseAlgorithm = "AES256", - }, - }, - }, - }, new CustomResourceOptions - { - Protect = true, - }); +{{% choosable language csharp %}} - var myBucketPolicy = new Aws.S3.BucketPolicy("my-bucket-policy", new() - { - Bucket = "my-bucket-36224917", - Policy = "{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", - }, new CustomResourceOptions - { - Protect = true, - }); +```csharp +using System.Collections.Generic; +using System.Linq; +using Pulumi; +using Aws = Pulumi.Aws; - var myBucketLifecycle = new Aws.S3.BucketLifecycleConfigurationV2("my-bucket-lifecycle", new() +return await Deployment.RunAsync(() => +{ + var currentUser = Aws.S3.GetCanonicalUserId.Invoke(); + + var myBucket = new Aws.S3.Bucket("my-bucket", new() { - Bucket = "my-bucket-36224917", - Rules = new[] + Grants = new[] { - new Aws.S3.Inputs.BucketLifecycleConfigurationV2RuleArgs + new Aws.S3.Inputs.BucketGrantArgs { - Expiration = new Aws.S3.Inputs.BucketLifecycleConfigurationV2RuleExpirationArgs + Permissions = new[] { - Days = 30, + "READ", }, - Id = "pu-s3-lifecycle-20240918194815251100000001", - Status = "Enabled", + Type = "CanonicalUser", + Id = currentUser.Apply(getCanonicalUserIdResult => getCanonicalUserIdResult.Id), }, }, - }, new CustomResourceOptions - { - Protect = true, - }); - - var myBucketObjectLockConfiguration = new Aws.S3.BucketObjectLockConfigurationV2("my-bucket-object-lock-configuration", new() - { - Bucket = "my-bucket-36224917", - ObjectLockEnabled = "Enabled", - }, new CustomResourceOptions - { - Protect = true, - }); - - var myBucketVersioning = new Aws.S3.BucketVersioningV2("my-bucket-versioning", new() - { - Bucket = "my-bucket-36224917", - VersioningConfiguration = new Aws.S3.Inputs.BucketVersioningV2VersioningConfigurationArgs - { - MfaDelete = "Disabled", - Status = "Enabled", - }, - }, new CustomResourceOptions - { - Protect = true, }); }); @@ -3006,29 +3304,10 @@ package generated_program; import com.pulumi.Context; import com.pulumi.Pulumi; import com.pulumi.core.Output; -import com.pulumi.aws.s3.BucketV2; -import com.pulumi.aws.s3.BucketV2Args; -import com.pulumi.aws.s3.inputs.BucketV2GrantArgs; -import com.pulumi.aws.s3.inputs.BucketV2LifecycleRuleArgs; -import com.pulumi.aws.s3.inputs.BucketV2ObjectLockConfigurationArgs; -import com.pulumi.aws.s3.inputs.BucketV2ServerSideEncryptionConfigurationArgs; -import com.pulumi.aws.s3.inputs.BucketV2VersioningArgs; -import com.pulumi.aws.s3.BucketServerSideEncryptionConfigurationV2; -import com.pulumi.aws.s3.BucketServerSideEncryptionConfigurationV2Args; -import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationV2RuleArgs; -import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs; -import com.pulumi.aws.s3.BucketPolicy; -import com.pulumi.aws.s3.BucketPolicyArgs; -import com.pulumi.aws.s3.BucketLifecycleConfigurationV2; -import com.pulumi.aws.s3.BucketLifecycleConfigurationV2Args; -import com.pulumi.aws.s3.inputs.BucketLifecycleConfigurationV2RuleArgs; -import com.pulumi.aws.s3.inputs.BucketLifecycleConfigurationV2RuleExpirationArgs; -import com.pulumi.aws.s3.BucketObjectLockConfigurationV2; -import com.pulumi.aws.s3.BucketObjectLockConfigurationV2Args; -import com.pulumi.aws.s3.BucketVersioningV2; -import com.pulumi.aws.s3.BucketVersioningV2Args; -import com.pulumi.aws.s3.inputs.BucketVersioningV2VersioningConfigurationArgs; -import com.pulumi.resources.CustomResourceOptions; +import com.pulumi.aws.s3.S3Functions; +import com.pulumi.aws.s3.Bucket; +import com.pulumi.aws.s3.BucketArgs; +import com.pulumi.aws.s3.inputs.BucketGrantArgs; import java.util.List; import java.util.ArrayList; import java.util.Map; @@ -3042,87 +3321,15 @@ public class App { } public static void stack(Context ctx) { - var myBucket = new BucketV2("myBucket", BucketV2Args.builder() - .bucket("my-bucket-36224917") - .grants(BucketV2GrantArgs.builder() - .id("e07865a5679c7977370948f1f1e51c21b12d8cfdd396a7e3172275d9164e01b8") - .permissions("FULL_CONTROL") - .type("CanonicalUser") - .build()) - .lifecycleRules(BucketV2LifecycleRuleArgs.builder() - .enabled(true) - .expirations(BucketV2LifecycleRuleExpirationArgs.builder() - .days(30) - .build()) - .id("pu-s3-lifecycle-20240918194815251100000001") - .build()) - .objectLockConfiguration(BucketV2ObjectLockConfigurationArgs.builder() - .objectLockEnabled("Enabled") - .build()) - .policy("{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}") - .requestPayer("BucketOwner") - .serverSideEncryptionConfigurations(BucketV2ServerSideEncryptionConfigurationArgs.builder() - .rules(BucketV2ServerSideEncryptionConfigurationRuleArgs.builder() - .applyServerSideEncryptionByDefaults(BucketV2ServerSideEncryptionConfigurationRuleApplyServerSideEncryptionByDefaultArgs.builder() - .sseAlgorithm("AES256") - .build()) - .build()) - .build()) - .tags(Map.of("Environment", "Dev")) - .versionings(BucketV2VersioningArgs.builder() - .enabled(true) - .build()) - .build(), CustomResourceOptions.builder() - .protect(true) - .build()); - - var myBucketEncryptionConfiguration = new BucketServerSideEncryptionConfigurationV2("myBucketEncryptionConfiguration", BucketServerSideEncryptionConfigurationV2Args.builder() - .bucket("my-bucket-36224917") - .rules(BucketServerSideEncryptionConfigurationV2RuleArgs.builder() - .applyServerSideEncryptionByDefault(BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs.builder() - .sseAlgorithm("AES256") - .build()) - .build()) - .build(), CustomResourceOptions.builder() - .protect(true) - .build()); - - var myBucketPolicy = new BucketPolicy("myBucketPolicy", BucketPolicyArgs.builder() - .bucket("my-bucket-36224917") - .policy("{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}") - .build(), CustomResourceOptions.builder() - .protect(true) - .build()); - - var myBucketLifecycle = new BucketLifecycleConfigurationV2("myBucketLifecycle", BucketLifecycleConfigurationV2Args.builder() - .bucket("my-bucket-36224917") - .rules(BucketLifecycleConfigurationV2RuleArgs.builder() - .expiration(BucketLifecycleConfigurationV2RuleExpirationArgs.builder() - .days(30) - .build()) - .id("pu-s3-lifecycle-20240918194815251100000001") - .status("Enabled") - .build()) - .build(), CustomResourceOptions.builder() - .protect(true) - .build()); - - var myBucketObjectLockConfiguration = new BucketObjectLockConfigurationV2("myBucketObjectLockConfiguration", BucketObjectLockConfigurationV2Args.builder() - .bucket("my-bucket-36224917") - .objectLockEnabled("Enabled") - .build(), CustomResourceOptions.builder() - .protect(true) - .build()); + final var currentUser = S3Functions.getCanonicalUserId(); - var myBucketVersioning = new BucketVersioningV2("myBucketVersioning", BucketVersioningV2Args.builder() - .bucket("my-bucket-36224917") - .versioningConfiguration(BucketVersioningV2VersioningConfigurationArgs.builder() - .mfaDelete("Disabled") - .status("Enabled") + var myBucket = new Bucket("myBucket", BucketArgs.builder() + .grants(BucketGrantArgs.builder() + .permissions("READ") + .type("CanonicalUser") + .id(currentUser.applyValue(getCanonicalUserIdResult -> getCanonicalUserIdResult.id())) .build()) - .build(), CustomResourceOptions.builder() - .protect(true) - .build()); + .build()); } } @@ -3134,103 +3341,31 @@ public class App { {{% choosable language yaml %}} ```yaml -name: y2 +name: example runtime: yaml -resources: - my-bucket: - type: aws:s3:BucketV2 - properties: - bucket: my-bucket-36224917 - grants: - - id: e07865a5679c7977370948f1f1e51c21b12d8cfdd396a7e3172275d9164e01b8 - permissions: - - FULL_CONTROL - type: CanonicalUser - lifecycleRules: - - enabled: true - expirations: - - days: 30 - id: pu-s3-lifecycle-20240918194815251100000001 - objectLockConfiguration: - objectLockEnabled: Enabled - policy: '{"Id":"PutObjPolicy","Statement":[{"Action":"s3:PutObject","Condition":{"Null":{"s3:x-amz-server-side-encryption-aws-kms-key-id":"true"}},"Effect":"Deny","Principal":"*","Resource":"arn:aws:s3:::my-bucket-36224917/*","Sid":"DenyObjectsThatAreNotSSEKMS"}],"Version":"2012-10-17"}' - requestPayer: BucketOwner - serverSideEncryptionConfigurations: - - rules: - - applyServerSideEncryptionByDefaults: - - sseAlgorithm: AES256 - tags: - Environment: Dev - versionings: - - enabled: true - options: - protect: true - my-bucket-encryption-configuration: - type: aws:s3:BucketServerSideEncryptionConfigurationV2 - properties: - bucket: my-bucket-36224917 - rules: - - applyServerSideEncryptionByDefault: - sseAlgorithm: AES256 - options: - protect: true - my-bucket-policy: - type: aws:s3:BucketPolicy - properties: - bucket: my-bucket-36224917 - policy: '{"Id":"PutObjPolicy","Statement":[{"Action":"s3:PutObject","Condition":{"Null":{"s3:x-amz-server-side-encryption-aws-kms-key-id":"true"}},"Effect":"Deny","Principal":"*","Resource":"arn:aws:s3:::my-bucket-36224917/*","Sid":"DenyObjectsThatAreNotSSEKMS"}],"Version":"2012-10-17"}' - options: - protect: true - my-bucket-lifecycle: - type: aws:s3:BucketLifecycleConfigurationV2 - properties: - bucket: my-bucket-36224917 - rules: - - expiration: - days: 30 - id: pu-s3-lifecycle-20240918194815251100000001 - status: Enabled - options: - protect: true - my-bucket-object-lock-configuration: - type: aws:s3:BucketObjectLockConfigurationV2 - properties: - bucket: my-bucket-36224917 - objectLockEnabled: Enabled - options: - protect: true - my-bucket-versioning: - type: aws:s3:BucketVersioningV2 +variables: + currentUser: + fn::invoke: + function: aws:s3:getCanonicalUserId + arguments: {} +resources: + my-bucket: + type: aws:s3:Bucket properties: - bucket: my-bucket-36224917 - versioningConfiguration: - mfaDelete: Disabled - status: Enabled - options: - protect: true + grants: + - permissions: + - "READ" + type: "CanonicalUser" + id: ${currentUser.id} ``` {{% /choosable %}} {{< /chooser >}} -- `pulumi preview` should result in `Resources: N unchanged` to confirm everything went well. - -- At this point you may see warnings from deprecated inputs like this: -```shell -warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the top-level parameter object_lock_enabled instead -warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the top-level parameter object_lock_enabled and the aws_s3_bucket_object_lock_configuration resource instead -warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the aws_s3_bucket_lifecycle_configuration resource instead -warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the aws_s3_bucket_versioning resource instead -warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the aws_s3_bucket_acl resource instead -warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the aws_s3_bucket_request_payment_configuration resource instead -warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the aws_s3_bucket_policy resource instead -warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verification warning: Use the aws_s3_bucket_server_side_encryption_configuration resource instead -``` -- To mitigate, edit the program to remove the deprecated inputs, leaving the final simplify program that should still - result in an empty `pulumi preview`: +Use the `aws.s3.BucketAcl` resource like this: {{< chooser language "typescript,python,go,csharp,java,yaml" >}} @@ -3240,56 +3375,30 @@ warning: urn:pulumi:bucket1::y2::aws:s3/bucketV2:BucketV2::my-bucket verificatio import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; -const myBucket = new aws.s3.BucketV2("my-bucket", { - bucket: "my-bucket-36224917", - tags: { - Environment: "Dev", +const currentUser = aws.s3.getCanonicalUserIdOutput({}); +const myBucket = new aws.s3.BucketV2("my-bucket", {}); +const myBucketOwnership = new aws.s3.BucketOwnershipControls("my-bucket-ownership", { + bucket: myBucket.id, + rule: { + objectOwnership: "BucketOwnerPreferred", }, -}, { - protect: true, -}); -const myBucketEncryptionConfiguration = new aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", { - bucket: "my-bucket-36224917", - rules: [{ - applyServerSideEncryptionByDefault: { - sseAlgorithm: "AES256", - }, - }], -}, { - protect: true, }); -const myBucketPolicy = new aws.s3.BucketPolicy("my-bucket-policy", { - bucket: "my-bucket-36224917", - policy: "{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", -}, { - protect: true, -}); -const myBucketLifecycle = new aws.s3.BucketLifecycleConfigurationV2("my-bucket-lifecycle", { - bucket: "my-bucket-36224917", - rules: [{ - expiration: { - days: 30, +const myBucketAcl = new aws.s3.BucketAclV2("my-bucket-acl", { + bucket: myBucket.bucket, + accessControlPolicy: { + owner: { + id: currentUser.apply(currentUser => currentUser.id), }, - id: "pu-s3-lifecycle-20240918194815251100000001", - status: "Enabled", - }], -}, { - protect: true, -}); -const myBucketObjectLockConfiguration = new aws.s3.BucketObjectLockConfigurationV2("my-bucket-object-lock-configuration", { - bucket: "my-bucket-36224917", - objectLockEnabled: "Enabled", -}, { - protect: true, -}); -const myBucketVersioning = new aws.s3.BucketVersioningV2("my-bucket-versioning", { - bucket: "my-bucket-36224917", - versioningConfiguration: { - mfaDelete: "Disabled", - status: "Enabled", + grants: [{ + permission: "READ", + grantee: { + type: "CanonicalUser", + id: currentUser.apply(currentUser => currentUser.id), + }, + }], }, }, { - protect: true, + dependsOn: [myBucketOwnership], }); ``` @@ -3302,45 +3411,28 @@ const myBucketVersioning = new aws.s3.BucketVersioningV2("my-bucket-versioning", import pulumi import pulumi_aws as aws -my_bucket = aws.s3.BucketV2("my-bucket", - bucket="my-bucket-36224917", - tags={ - "Environment": "Dev", - }, - opts = pulumi.ResourceOptions(protect=True)) -my_bucket_encryption_configuration = aws.s3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", - bucket="my-bucket-36224917", - rules=[{ - "apply_server_side_encryption_by_default": { - "sse_algorithm": "AES256", - }, - }], - opts = pulumi.ResourceOptions(protect=True)) -my_bucket_policy = aws.s3.BucketPolicy("my-bucket-policy", - bucket="my-bucket-36224917", - policy="{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", - opts = pulumi.ResourceOptions(protect=True)) -my_bucket_lifecycle = aws.s3.BucketLifecycleConfigurationV2("my-bucket-lifecycle", - bucket="my-bucket-36224917", - rules=[{ - "expiration": { - "days": 30, +current_user = aws.s3.get_canonical_user_id_output() +my_bucket = aws.s3.BucketV2("my-bucket") +my_bucket_ownership = aws.s3.BucketOwnershipControls("my-bucket-ownership", + bucket=my_bucket.id, + rule={ + "object_ownership": "BucketOwnerPreferred", + }) +my_bucket_acl = aws.s3.BucketAclV2("my-bucket-acl", + bucket=my_bucket.bucket, + access_control_policy={ + "owner": { + "id": current_user.id, }, - "id": "pu-s3-lifecycle-20240918194815251100000001", - "status": "Enabled", - }], - opts = pulumi.ResourceOptions(protect=True)) -my_bucket_object_lock_configuration = aws.s3.BucketObjectLockConfigurationV2("my-bucket-object-lock-configuration", - bucket="my-bucket-36224917", - object_lock_enabled="Enabled", - opts = pulumi.ResourceOptions(protect=True)) -my_bucket_versioning = aws.s3.BucketVersioningV2("my-bucket-versioning", - bucket="my-bucket-36224917", - versioning_configuration={ - "mfa_delete": "Disabled", - "status": "Enabled", + "grants": [{ + "permission": "READ", + "grantee": { + "type": "CanonicalUser", + "id": current_user.id, + }, + }], }, - opts = pulumi.ResourceOptions(protect=True)) + opts = pulumi.ResourceOptions(depends_on=[my_bucket_ownership])) ``` @@ -3358,64 +3450,42 @@ import ( func main() { pulumi.Run(func(ctx *pulumi.Context) error { - _, err := s3.NewBucketV2(ctx, "my-bucket", &s3.BucketV2Args{ - Bucket: pulumi.String("my-bucket-36224917"), - Tags: pulumi.StringMap{ - "Environment": pulumi.String("Dev"), - }, - }, pulumi.Protect(true)) + currentUser, err := s3.GetCanonicalUserId(ctx, nil, nil) if err != nil { return err } - _, err = s3.NewBucketServerSideEncryptionConfigurationV2(ctx, "my-bucket-encryption-configuration", &s3.BucketServerSideEncryptionConfigurationV2Args{ - Bucket: pulumi.String("my-bucket-36224917"), - Rules: s3.BucketServerSideEncryptionConfigurationV2RuleArray{ - &s3.BucketServerSideEncryptionConfigurationV2RuleArgs{ - ApplyServerSideEncryptionByDefault: &s3.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs{ - SseAlgorithm: pulumi.String("AES256"), - }, - }, - }, - }, pulumi.Protect(true)) + myBucket, err := s3.NewBucketV2(ctx, "my-bucket", nil) if err != nil { return err } - _, err = s3.NewBucketPolicy(ctx, "my-bucket-policy", &s3.BucketPolicyArgs{ - Bucket: pulumi.String("my-bucket-36224917"), - Policy: pulumi.Any("{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}"), - }, pulumi.Protect(true)) + myBucketOwnership, err := s3.NewBucketOwnershipControls(ctx, "my-bucket-ownership", &s3.BucketOwnershipControlsArgs{ + Bucket: myBucket.ID(), + Rule: &s3.BucketOwnershipControlsRuleArgs{ + ObjectOwnership: pulumi.String("BucketOwnerPreferred"), + }, + }) if err != nil { return err } - _, err = s3.NewBucketLifecycleConfigurationV2(ctx, "my-bucket-lifecycle", &s3.BucketLifecycleConfigurationV2Args{ - Bucket: pulumi.String("my-bucket-36224917"), - Rules: s3.BucketLifecycleConfigurationV2RuleArray{ - &s3.BucketLifecycleConfigurationV2RuleArgs{ - Expiration: &s3.BucketLifecycleConfigurationV2RuleExpirationArgs{ - Days: pulumi.Int(30), + _, err = s3.NewBucketAclV2(ctx, "my-bucket-acl", &s3.BucketAclV2Args{ + Bucket: myBucket.Bucket, + AccessControlPolicy: &s3.BucketAclV2AccessControlPolicyArgs{ + Owner: &s3.BucketAclV2AccessControlPolicyOwnerArgs{ + Id: pulumi.String(currentUser.Id), + }, + Grants: s3.BucketAclV2AccessControlPolicyGrantArray{ + &s3.BucketAclV2AccessControlPolicyGrantArgs{ + Permission: pulumi.String("READ"), + Grantee: &s3.BucketAclV2AccessControlPolicyGrantGranteeArgs{ + Type: pulumi.String("CanonicalUser"), + Id: pulumi.String(currentUser.Id), + }, }, - Id: pulumi.String("pu-s3-lifecycle-20240918194815251100000001"), - Status: pulumi.String("Enabled"), }, }, - }, pulumi.Protect(true)) - if err != nil { - return err - } - _, err = s3.NewBucketObjectLockConfigurationV2(ctx, "my-bucket-object-lock-configuration", &s3.BucketObjectLockConfigurationV2Args{ - Bucket: pulumi.String("my-bucket-36224917"), - ObjectLockEnabled: pulumi.String("Enabled"), - }, pulumi.Protect(true)) - if err != nil { - return err - } - _, err = s3.NewBucketVersioningV2(ctx, "my-bucket-versioning", &s3.BucketVersioningV2Args{ - Bucket: pulumi.String("my-bucket-36224917"), - VersioningConfiguration: &s3.BucketVersioningV2VersioningConfigurationArgs{ - MfaDelete: pulumi.String("Disabled"), - Status: pulumi.String("Enabled"), - }, - }, pulumi.Protect(true)) + }, pulumi.DependsOn([]pulumi.Resource{ + myBucketOwnership, + })) if err != nil { return err } @@ -3433,89 +3503,51 @@ func main() { using System.Collections.Generic; using System.Linq; using Pulumi; -using Aws = Pulumi.Aws; - -return await Deployment.RunAsync(() => -{ - var myBucket = new Aws.S3.BucketV2("my-bucket", new() - { - Bucket = "my-bucket-36224917", - Tags = - { - { "Environment", "Dev" }, - }, - }, new CustomResourceOptions - { - Protect = true, - }); - - var myBucketEncryptionConfiguration = new Aws.S3.BucketServerSideEncryptionConfigurationV2("my-bucket-encryption-configuration", new() - { - Bucket = "my-bucket-36224917", - Rules = new[] - { - new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationV2RuleArgs - { - ApplyServerSideEncryptionByDefault = new Aws.S3.Inputs.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs - { - SseAlgorithm = "AES256", - }, - }, - }, - }, new CustomResourceOptions - { - Protect = true, - }); +using Aws = Pulumi.Aws; - var myBucketPolicy = new Aws.S3.BucketPolicy("my-bucket-policy", new() - { - Bucket = "my-bucket-36224917", - Policy = "{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}", - }, new CustomResourceOptions +return await Deployment.RunAsync(() => +{ + var currentUser = Aws.S3.GetCanonicalUserId.Invoke(); + + var myBucket = new Aws.S3.BucketV2("my-bucket"); + + var myBucketOwnership = new Aws.S3.BucketOwnershipControls("my-bucket-ownership", new() { - Protect = true, + Bucket = myBucket.Id, + Rule = new Aws.S3.Inputs.BucketOwnershipControlsRuleArgs + { + ObjectOwnership = "BucketOwnerPreferred", + }, }); - var myBucketLifecycle = new Aws.S3.BucketLifecycleConfigurationV2("my-bucket-lifecycle", new() + var myBucketAcl = new Aws.S3.BucketAclV2("my-bucket-acl", new() { - Bucket = "my-bucket-36224917", - Rules = new[] + Bucket = myBucket.Bucket, + AccessControlPolicy = new Aws.S3.Inputs.BucketAclV2AccessControlPolicyArgs { - new Aws.S3.Inputs.BucketLifecycleConfigurationV2RuleArgs + Owner = new Aws.S3.Inputs.BucketAclV2AccessControlPolicyOwnerArgs { - Expiration = new Aws.S3.Inputs.BucketLifecycleConfigurationV2RuleExpirationArgs + Id = currentUser.Apply(getCanonicalUserIdResult => getCanonicalUserIdResult.Id), + }, + Grants = new[] + { + new Aws.S3.Inputs.BucketAclV2AccessControlPolicyGrantArgs { - Days = 30, + Permission = "READ", + Grantee = new Aws.S3.Inputs.BucketAclV2AccessControlPolicyGrantGranteeArgs + { + Type = "CanonicalUser", + Id = currentUser.Apply(getCanonicalUserIdResult => getCanonicalUserIdResult.Id), + }, }, - Id = "pu-s3-lifecycle-20240918194815251100000001", - Status = "Enabled", }, }, }, new CustomResourceOptions { - Protect = true, - }); - - var myBucketObjectLockConfiguration = new Aws.S3.BucketObjectLockConfigurationV2("my-bucket-object-lock-configuration", new() - { - Bucket = "my-bucket-36224917", - ObjectLockEnabled = "Enabled", - }, new CustomResourceOptions - { - Protect = true, - }); - - var myBucketVersioning = new Aws.S3.BucketVersioningV2("my-bucket-versioning", new() - { - Bucket = "my-bucket-36224917", - VersioningConfiguration = new Aws.S3.Inputs.BucketVersioningV2VersioningConfigurationArgs + DependsOn = { - MfaDelete = "Disabled", - Status = "Enabled", + myBucketOwnership, }, - }, new CustomResourceOptions - { - Protect = true, }); }); @@ -3533,23 +3565,15 @@ package generated_program; import com.pulumi.Context; import com.pulumi.Pulumi; import com.pulumi.core.Output; +import com.pulumi.aws.s3.S3Functions; import com.pulumi.aws.s3.BucketV2; -import com.pulumi.aws.s3.BucketV2Args; -import com.pulumi.aws.s3.BucketServerSideEncryptionConfigurationV2; -import com.pulumi.aws.s3.BucketServerSideEncryptionConfigurationV2Args; -import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationV2RuleArgs; -import com.pulumi.aws.s3.inputs.BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs; -import com.pulumi.aws.s3.BucketPolicy; -import com.pulumi.aws.s3.BucketPolicyArgs; -import com.pulumi.aws.s3.BucketLifecycleConfigurationV2; -import com.pulumi.aws.s3.BucketLifecycleConfigurationV2Args; -import com.pulumi.aws.s3.inputs.BucketLifecycleConfigurationV2RuleArgs; -import com.pulumi.aws.s3.inputs.BucketLifecycleConfigurationV2RuleExpirationArgs; -import com.pulumi.aws.s3.BucketObjectLockConfigurationV2; -import com.pulumi.aws.s3.BucketObjectLockConfigurationV2Args; -import com.pulumi.aws.s3.BucketVersioningV2; -import com.pulumi.aws.s3.BucketVersioningV2Args; -import com.pulumi.aws.s3.inputs.BucketVersioningV2VersioningConfigurationArgs; +import com.pulumi.aws.s3.BucketOwnershipControls; +import com.pulumi.aws.s3.BucketOwnershipControlsArgs; +import com.pulumi.aws.s3.inputs.BucketOwnershipControlsRuleArgs; +import com.pulumi.aws.s3.BucketAclV2; +import com.pulumi.aws.s3.BucketAclV2Args; +import com.pulumi.aws.s3.inputs.BucketAclV2AccessControlPolicyArgs; +import com.pulumi.aws.s3.inputs.BucketAclV2AccessControlPolicyOwnerArgs; import com.pulumi.resources.CustomResourceOptions; import java.util.List; import java.util.ArrayList; @@ -3564,59 +3588,33 @@ public class App { } public static void stack(Context ctx) { - var myBucket = new BucketV2("myBucket", BucketV2Args.builder() - .bucket("my-bucket-36224917") - .tags(Map.of("Environment", "Dev")) - .build(), CustomResourceOptions.builder() - .protect(true) - .build()); - - var myBucketEncryptionConfiguration = new BucketServerSideEncryptionConfigurationV2("myBucketEncryptionConfiguration", BucketServerSideEncryptionConfigurationV2Args.builder() - .bucket("my-bucket-36224917") - .rules(BucketServerSideEncryptionConfigurationV2RuleArgs.builder() - .applyServerSideEncryptionByDefault(BucketServerSideEncryptionConfigurationV2RuleApplyServerSideEncryptionByDefaultArgs.builder() - .sseAlgorithm("AES256") - .build()) - .build()) - .build(), CustomResourceOptions.builder() - .protect(true) - .build()); + final var currentUser = S3Functions.getCanonicalUserId(); - var myBucketPolicy = new BucketPolicy("myBucketPolicy", BucketPolicyArgs.builder() - .bucket("my-bucket-36224917") - .policy("{\"Id\":\"PutObjPolicy\",\"Statement\":[{\"Action\":\"s3:PutObject\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::my-bucket-36224917/*\",\"Sid\":\"DenyObjectsThatAreNotSSEKMS\"}],\"Version\":\"2012-10-17\"}") - .build(), CustomResourceOptions.builder() - .protect(true) - .build()); + var myBucket = new BucketV2("myBucket"); - var myBucketLifecycle = new BucketLifecycleConfigurationV2("myBucketLifecycle", BucketLifecycleConfigurationV2Args.builder() - .bucket("my-bucket-36224917") - .rules(BucketLifecycleConfigurationV2RuleArgs.builder() - .expiration(BucketLifecycleConfigurationV2RuleExpirationArgs.builder() - .days(30) - .build()) - .id("pu-s3-lifecycle-20240918194815251100000001") - .status("Enabled") + var myBucketOwnership = new BucketOwnershipControls("myBucketOwnership", BucketOwnershipControlsArgs.builder() + .bucket(myBucket.id()) + .rule(BucketOwnershipControlsRuleArgs.builder() + .objectOwnership("BucketOwnerPreferred") .build()) - .build(), CustomResourceOptions.builder() - .protect(true) - .build()); - - var myBucketObjectLockConfiguration = new BucketObjectLockConfigurationV2("myBucketObjectLockConfiguration", BucketObjectLockConfigurationV2Args.builder() - .bucket("my-bucket-36224917") - .objectLockEnabled("Enabled") - .build(), CustomResourceOptions.builder() - .protect(true) - .build()); + .build()); - var myBucketVersioning = new BucketVersioningV2("myBucketVersioning", BucketVersioningV2Args.builder() - .bucket("my-bucket-36224917") - .versioningConfiguration(BucketVersioningV2VersioningConfigurationArgs.builder() - .mfaDelete("Disabled") - .status("Enabled") + var myBucketAcl = new BucketAclV2("myBucketAcl", BucketAclV2Args.builder() + .bucket(myBucket.bucket()) + .accessControlPolicy(BucketAclV2AccessControlPolicyArgs.builder() + .owner(BucketAclV2AccessControlPolicyOwnerArgs.builder() + .id(currentUser.applyValue(getCanonicalUserIdResult -> getCanonicalUserIdResult.id())) + .build()) + .grants(BucketAclV2AccessControlPolicyGrantArgs.builder() + .permission("READ") + .grantee(BucketAclV2AccessControlPolicyGrantGranteeArgs.builder() + .type("CanonicalUser") + .id(currentUser.applyValue(getCanonicalUserIdResult -> getCanonicalUserIdResult.id())) + .build()) + .build()) .build()) .build(), CustomResourceOptions.builder() - .protect(true) + .dependsOn(myBucketOwnership) .build()); } @@ -3629,71 +3627,78 @@ public class App { {{% choosable language yaml %}} ```yaml -name: y2 +name: example runtime: yaml +variables: + currentUser: + fn::invoke: + function: aws:s3:getCanonicalUserId + arguments: {} resources: my-bucket: type: aws:s3:BucketV2 + my-bucket-ownership: + type: aws:s3:BucketOwnershipControls properties: - bucket: my-bucket-36224917 - tags: - Environment: Dev - options: - protect: true - my-bucket-encryption-configuration: - type: aws:s3:BucketServerSideEncryptionConfigurationV2 - properties: - bucket: my-bucket-36224917 - rules: - - applyServerSideEncryptionByDefault: - sseAlgorithm: AES256 - options: - protect: true - my-bucket-policy: - type: aws:s3:BucketPolicy - properties: - bucket: my-bucket-36224917 - policy: '{"Id":"PutObjPolicy","Statement":[{"Action":"s3:PutObject","Condition":{"Null":{"s3:x-amz-server-side-encryption-aws-kms-key-id":"true"}},"Effect":"Deny","Principal":"*","Resource":"arn:aws:s3:::my-bucket-36224917/*","Sid":"DenyObjectsThatAreNotSSEKMS"}],"Version":"2012-10-17"}' - options: - protect: true - my-bucket-lifecycle: - type: aws:s3:BucketLifecycleConfigurationV2 - properties: - bucket: my-bucket-36224917 - rules: - - expiration: - days: 30 - id: pu-s3-lifecycle-20240918194815251100000001 - status: Enabled - options: - protect: true - my-bucket-object-lock-configuration: - type: aws:s3:BucketObjectLockConfigurationV2 - properties: - bucket: my-bucket-36224917 - objectLockEnabled: Enabled - options: - protect: true - my-bucket-versioning: - type: aws:s3:BucketVersioningV2 + bucket: ${my-bucket.id} + rule: + objectOwnership: "BucketOwnerPreferred" + my-bucket-acl: + type: aws:s3:BucketAclV2 properties: - bucket: my-bucket-36224917 - versioningConfiguration: - mfaDelete: Disabled - status: Enabled + bucket: ${my-bucket.bucket} + accessControlPolicy: + owner: + id: ${currentUser.id} + grants: + - permission: "READ" + grantee: + type: "CanonicalUser" + id: ${currentUser.id} options: - protect: true + dependsOn: + - ${my-bucket-ownership} ``` {{% /choosable %}} {{< /chooser >}} -## Historical context + + + +Note that `dependsOn` on `BucketOwnershipControls` is required for Pulumi to correctly order the operations for this +infrastructure. Consult the documentation on `aws.s3.BucketAclV2` for more fully worked examples of configuring ACL. + +### hostedZoneId input + +This will only be available as an output. If your program specified this as an input, simply remove it. The input was +ignored by prior versions of the provider and was exposed in error. + +### other inputs + +All other removed inputs are treated similarly. Consult the documentation for the matching resource replacing the input +for more information: + +| Input | Resource | +|--------------------------|--------------------------------------------| +| lifecycleRules | aws.s3.BucketLifecycleConfigurationV2 | +| loggings | aws.s3.BucketLoggingV2 | +| objectLockConfiguration | aws.s3.BucketObjectLockConfigurationV2 | +| replicationConfiguration | aws.s3.BucketReplicationConfig | +| requestPayer | aws.s3.BucketRequestPaymentConfigurationV2 | +| versionings | aws.s3.BucketVersioningV2 | +| website | aws.s3.BucketWebsiteConfigurationV2 | +| websiteDomain | aws.s3.BucketWebsiteConfigurationV2 | +| websiteEndpoint | aws.s3.BucketWebsiteConfigurationV2 | + + +## Why should I adopt BucketV2 The distinction between Bucket and BucketV2 originates from breaking changes introduced in the V4 release of the Terraform AWS Provider. In the Pulumi AWS provider projection BucketV2 represents the latest version of the upstream -resource, while Bucket is maintained by Pulumi to enable backwards compatibility. +resource, while Bucket is maintained by Pulumi to enable backwards compatibility. We recommend using BucketV2 for new +code and migrating old code to BucketV2 as it will remain the preferred long-term supported resource. See also: From cdb191661691f61169489666538003b5670af0ee Mon Sep 17 00:00:00 2001 From: Anton Tayanovskyy Date: Tue, 24 Sep 2024 11:10:34 -0400 Subject: [PATCH 19/20] Grammar and spelling in the intro paragraph --- .../packages/aws/how-to-guides/bucketv2-migration.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md index 026f49c306..8f84e27dd6 100644 --- a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md +++ b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md @@ -16,8 +16,10 @@ To migrate existing `aws.s3.Bucket` resources to `aws.s3.BucketV2`: `BucketV2` inputs such as `policy` and `accelerationStatus` are to be replaced by side-by-side resources `aws.s3.BucketPolicy` and `aws.s3.BucketAccelerateConfigurationV2`. -2. Perorm this is not acceptable, consider using `pulumi import` to migrate - manually instead as outlined in the "Avoiding replacement" section. +2. To avoid replacing the buckets and risking data loss, we recommend manually migrating the Bucket resources via + `pulumi import` + +3. If replacing buckets is not a concern for your use case, consider a simpler migration procedure with `pulumi up` ## Migrating with `pulumi import` From 27c92fc3cd40c604e473a8be9d510d554d17e7e8 Mon Sep 17 00:00:00 2001 From: Anton Tayanovskyy Date: Mon, 30 Sep 2024 17:04:16 -0400 Subject: [PATCH 20/20] Edited away recommendation to migrate --- .../aws/how-to-guides/bucketv2-migration.md | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md index 8f84e27dd6..d318b833b7 100644 --- a/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md +++ b/themes/default/content/registry/packages/aws/how-to-guides/bucketv2-migration.md @@ -5,10 +5,9 @@ meta_desc: Practitioner level instructions for migrating from aws.s3.Bucket to a layout: package --- -In the upcoming AWS Classic major release (v7), `aws.s3.Bucket` will be discontinued in favor of `BucketV2`. Users of -`aws.s3.Bucket` resource are encouraged to migrate early. The migration requires a significant refactor to the source -code and additional steps for avoiding data loss. This guide aims to cover all relevant scenarios with precise migration -instructions. +In the upcoming AWS Classic major release (v7), `aws.s3.Bucket` will be discontinued in favor of `BucketV2`. The +migration requires a significant refactor to the source code and additional steps for avoiding data loss. This guide is +for users opting to migrate early. To migrate existing `aws.s3.Bucket` resources to `aws.s3.BucketV2`: @@ -16,16 +15,15 @@ To migrate existing `aws.s3.Bucket` resources to `aws.s3.BucketV2`: `BucketV2` inputs such as `policy` and `accelerationStatus` are to be replaced by side-by-side resources `aws.s3.BucketPolicy` and `aws.s3.BucketAccelerateConfigurationV2`. -2. To avoid replacing the buckets and risking data loss, we recommend manually migrating the Bucket resources via - `pulumi import` +2. To avoid replacing the buckets and risking data loss, migrate via `pulumi import` -3. If replacing buckets is not a concern for your use case, consider a simpler migration procedure with `pulumi up` +3. If replacing buckets is not a concern for your use case, use a simpler migration procedure via `pulumi up` ## Migrating with `pulumi import` -This migration path is recommended in situations when replacing the bucket in the AWS account is not acceptable. After -performing the steps your Pulumi program and state will be updated to track buckets using the new resource without -executing any changes against the actual cloud account. The steps involve: +This migration path is best for when replacing the bucket in the AWS account is not acceptable. After performing the +steps your Pulumi program and state will be updated to track buckets using the new resource without executing any +changes against the actual cloud account. The steps involve: - Find URNs for legacy Bucket Pulumi resources using `pulumi stack export` - Determine the actual bucket name(s) @@ -3700,7 +3698,8 @@ for more information: The distinction between Bucket and BucketV2 originates from breaking changes introduced in the V4 release of the Terraform AWS Provider. In the Pulumi AWS provider projection BucketV2 represents the latest version of the upstream resource, while Bucket is maintained by Pulumi to enable backwards compatibility. We recommend using BucketV2 for new -code and migrating old code to BucketV2 as it will remain the preferred long-term supported resource. +code. Migrating existing old code to BucketV2 is not required in the V6 version of the provider, but has the benefits of +aligning the code with the preferred long-term supported resource. See also: