Skip to content

Commit

Permalink
feat!: Update to support AWS provider v3.75 and newer (including v4.x) (
Browse files Browse the repository at this point in the history
#139)

BREAKING CHANGES:
- Yes, see file `UPGRADE-3.0.md`
- Requires AWS provider v3.75 or newer (including v4.x)
  • Loading branch information
antonbabenko authored Mar 30, 2022
1 parent 5d0ed51 commit e0de434
Show file tree
Hide file tree
Showing 35 changed files with 1,155 additions and 338 deletions.
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,13 @@ inputs = {
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.1 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | ~> 3.69 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.75 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | ~> 3.69 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.75 |

## Modules

Expand All @@ -127,9 +127,21 @@ No modules.
| Name | Type |
|------|------|
| [aws_s3_bucket.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |
| [aws_s3_bucket_accelerate_configuration.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_accelerate_configuration) | resource |
| [aws_s3_bucket_acl.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_acl) | resource |
| [aws_s3_bucket_cors_configuration.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_cors_configuration) | resource |
| [aws_s3_bucket_lifecycle_configuration.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_lifecycle_configuration) | resource |
| [aws_s3_bucket_logging.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_logging) | resource |
| [aws_s3_bucket_object_lock_configuration.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_object_lock_configuration) | resource |
| [aws_s3_bucket_ownership_controls.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_ownership_controls) | resource |
| [aws_s3_bucket_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource |
| [aws_s3_bucket_public_access_block.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource |
| [aws_s3_bucket_replication_configuration.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_replication_configuration) | resource |
| [aws_s3_bucket_request_payment_configuration.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_request_payment_configuration) | resource |
| [aws_s3_bucket_server_side_encryption_configuration.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource |
| [aws_s3_bucket_versioning.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning) | resource |
| [aws_s3_bucket_website_configuration.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_website_configuration) | resource |
| [aws_canonical_user_id.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/canonical_user_id) | data source |
| [aws_elb_service_account.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/elb_service_account) | data source |
| [aws_iam_policy_document.combined](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.deny_insecure_transport](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
Expand All @@ -142,7 +154,7 @@ No modules.
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_acceleration_status"></a> [acceleration\_status](#input\_acceleration\_status) | (Optional) Sets the accelerate configuration of an existing bucket. Can be Enabled or Suspended. | `string` | `null` | no |
| <a name="input_acl"></a> [acl](#input\_acl) | (Optional) The canned ACL to apply. Defaults to 'private'. Conflicts with `grant` | `string` | `"private"` | no |
| <a name="input_acl"></a> [acl](#input\_acl) | (Optional) The canned ACL to apply. Conflicts with `grant` | `string` | `null` | no |
| <a name="input_attach_deny_insecure_transport_policy"></a> [attach\_deny\_insecure\_transport\_policy](#input\_attach\_deny\_insecure\_transport\_policy) | Controls if S3 bucket should have deny non-SSL transport policy attached | `bool` | `false` | no |
| <a name="input_attach_elb_log_delivery_policy"></a> [attach\_elb\_log\_delivery\_policy](#input\_attach\_elb\_log\_delivery\_policy) | Controls if S3 bucket should have ELB log delivery policy attached | `bool` | `false` | no |
| <a name="input_attach_lb_log_delivery_policy"></a> [attach\_lb\_log\_delivery\_policy](#input\_attach\_lb\_log\_delivery\_policy) | Controls if S3 bucket should have ALB/NLB log delivery policy attached | `bool` | `false` | no |
Expand All @@ -156,13 +168,15 @@ No modules.
| <a name="input_control_object_ownership"></a> [control\_object\_ownership](#input\_control\_object\_ownership) | Whether to manage S3 Bucket Ownership Controls on this bucket. | `bool` | `false` | no |
| <a name="input_cors_rule"></a> [cors\_rule](#input\_cors\_rule) | List of maps containing rules for Cross-Origin Resource Sharing. | `any` | `[]` | no |
| <a name="input_create_bucket"></a> [create\_bucket](#input\_create\_bucket) | Controls if S3 bucket should be created | `bool` | `true` | no |
| <a name="input_expected_bucket_owner"></a> [expected\_bucket\_owner](#input\_expected\_bucket\_owner) | The account ID of the expected bucket owner | `string` | `null` | no |
| <a name="input_force_destroy"></a> [force\_destroy](#input\_force\_destroy) | (Optional, Default:false ) A boolean that indicates all objects should be deleted from the bucket so that the bucket can be destroyed without error. These objects are not recoverable. | `bool` | `false` | no |
| <a name="input_grant"></a> [grant](#input\_grant) | An ACL policy grant. Conflicts with `acl` | `any` | `[]` | no |
| <a name="input_ignore_public_acls"></a> [ignore\_public\_acls](#input\_ignore\_public\_acls) | Whether Amazon S3 should ignore public ACLs for this bucket. | `bool` | `false` | no |
| <a name="input_lifecycle_rule"></a> [lifecycle\_rule](#input\_lifecycle\_rule) | List of maps containing configuration of object lifecycle management. | `any` | `[]` | no |
| <a name="input_logging"></a> [logging](#input\_logging) | Map containing access bucket logging configuration. | `map(string)` | `{}` | no |
| <a name="input_object_lock_configuration"></a> [object\_lock\_configuration](#input\_object\_lock\_configuration) | Map containing S3 object locking configuration. | `any` | `{}` | no |
| <a name="input_object_ownership"></a> [object\_ownership](#input\_object\_ownership) | Object ownership. Valid values: BucketOwnerEnforced, BucketOwnerPreferred or ObjectWriter. 'BucketOwnerEnforced': ACLs are disabled, and the bucket owner automatically owns and has full control over every object in the bucket. 'BucketOwnerPreferred': Objects uploaded to the bucket change ownership to the bucket owner if the objects are uploaded with the bucket-owner-full-control canned ACL. 'ObjectWriter': The uploading account will own the object if the object is uploaded with the bucket-owner-full-control canned ACL. | `string` | `"ObjectWriter"` | no |
| <a name="input_owner"></a> [owner](#input\_owner) | Bucket owner's display name and ID. Conflicts with `acl` | `map(string)` | `{}` | no |
| <a name="input_policy"></a> [policy](#input\_policy) | (Optional) A valid bucket policy JSON document. Note that if the policy document is not specific enough (but still valid), Terraform may view the policy as constantly changing in a terraform plan. In this case, please make sure you use the verbose/specific version of the policy. For more information about building AWS IAM policy documents with Terraform, see the AWS IAM Policy Document Guide. | `string` | `null` | no |
| <a name="input_putin_khuylo"></a> [putin\_khuylo](#input\_putin\_khuylo) | Do you agree that Putin doesn't respect Ukrainian sovereignty and territorial integrity? More info: https://en.wikipedia.org/wiki/Putin_khuylo! | `bool` | `true` | no |
| <a name="input_replication_configuration"></a> [replication\_configuration](#input\_replication\_configuration) | Map containing cross-region replication configuration. | `any` | `{}` | no |
Expand All @@ -171,7 +185,7 @@ No modules.
| <a name="input_server_side_encryption_configuration"></a> [server\_side\_encryption\_configuration](#input\_server\_side\_encryption\_configuration) | Map containing server-side encryption configuration. | `any` | `{}` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | (Optional) A mapping of tags to assign to the bucket. | `map(string)` | `{}` | no |
| <a name="input_versioning"></a> [versioning](#input\_versioning) | Map containing versioning configuration. | `map(string)` | `{}` | no |
| <a name="input_website"></a> [website](#input\_website) | Map containing static web-site hosting or redirect configuration. | `map(string)` | `{}` | no |
| <a name="input_website"></a> [website](#input\_website) | Map containing static web-site hosting or redirect configuration. | `any` | `{}` | no |

## Outputs

Expand Down
131 changes: 131 additions & 0 deletions UPGRADE-3.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Upgrade from v2.x to v3.x

If you have any questions regarding this upgrade process, please consult the [`examples/`](https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/tree/master/examples) projects:

If you find a bug, please open an issue with supporting configuration to reproduce.

## List of backwards incompatible changes

- Terraform AWS provider minimum version is now `v3.75.0` in order to have forward compatibility with Terraform AWS provider `v4.x`. Using the latest version of `v4` is highly recommended, if possible.
- Main group of changes is related to refactoring of `aws_s3_bucket` resource into several smaller resources. Read [`S3 bucket refactor` section in the official Terraform AWS Provider Version 4 Upgrade Guide](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/guides/version-4-upgrade#s3-bucket-refactor) and [discussion around these changes](https://github.com/hashicorp/terraform-provider-aws/issues/23106) can help even when using AWS provider version 3.75 or newer.
- `modules/object`: Changed resource type from `aws_bucket_s3_object` to `aws_s3_object`. After upgrade, on the next apply, Terraform will recreate the object. If you prefer to not have Terraform recreate the object, import the object using `aws_s3_object`. [Read more](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_object#import).

## Additional changes

### Added

- None

### Modified

- `acl` variable is set to `null` by default
- In addition to pseudo-boolean values like "Enabled", "Disabled", "Suspended", it is now possible to specify `true` or `false` in all such arguments (e.g. `versioning = { enabled = true }`).

### Variable and output changes

1. Removed variables:

- None

2. Renamed variables:

- None

3. Added variables:

- `owner`
- `expected_bucket_owner`

4. Removed outputs:

- None

5. Renamed outputs:

`modules/object`:

- `s3_bucket_object_id` -> `s3_object_id`
- `s3_bucket_object_etag` -> `s3_object_etag`
- `s3_bucket_object_version_id` -> `s3_object_version_id`

6. Added outputs:

- None

## Upgrade Migrations

The following examples demonstrate some of the changes that users can elect to make to avoid any potential disruptions when upgrading.

### Before 2.x Example

See code in [`examples/complete-legacy`](https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/tree/master/examples/complete-legacy).

```hcl
module "s3_bucket" {
source = "terraform-aws-modules/s3-bucket/aws"
version = "~> 2.0"
bucket = "my-awesome-bucket"
acl = "log-delivery-write"
}
terraform {
required_providers {
aws = "~> 3.69.0" # or anything lower than 3.75.0
}
}
```

### After 3.x Example

See code in [`examples/complete`](https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/tree/master/examples/complete).

```hcl
module "s3_bucket" {
source = "terraform-aws-modules/s3-bucket/aws"
version = "~> 3.0"
bucket = "my-awesome-bucket"
acl = "log-delivery-write"
}
terraform {
required_providers {
aws = ">= 3.75" # or anything higher than 3.75.0
}
}
```

After the code is updated, you need run `terraform init -upgrade` to download newer AWS provider, and then import S3 bucket ACL using such command:

```
terraform import "module.s3_bucket.aws_s3_bucket_acl.this[0]" my-awesome-bucket,log-delivery-write
```

Where `log-delivery-write` is the value of `acl` argument in the module block above.

Read more about [import in the official documentation for `aws_s3_bucket_acl`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_acl#import).

#### Import existing resources (required during the migration from v2.x of this module)

During the migration to v3.x of this module, several S3 resources will be created by this module. In order to guarantee the best experience and prevent data loss, you will need to import them into terraform state using commands like these:

```bash
terraform import "module.s3_bucket.aws_s3_bucket.this[0]" <bucket-name>
terraform import "module.s3_bucket.aws_s3_bucket_acl.this[0]" <bucket-name>,<acl>
terraform import "module.s3_bucket.aws_s3_bucket_logging.this[0]" <bucket-name>
terraform import "module.s3_bucket.aws_s3_bucket_website_configuration.this[0]" <bucket-name>,<account-id>
terraform import "module.s3_bucket.aws_s3_bucket_versioning.this[0]" <bucket-name>,<account-id>
terraform import "module.s3_bucket.aws_s3_bucket_server_side_encryption_configuration.this[0]" <bucket-name>,<account-id>
terraform import "module.s3_bucket.aws_s3_bucket_request_payment_configuration.this[0]" <bucket-name>,<account-id>
terraform import "module.s3_bucket.aws_s3_bucket_accelerate_configuration.this[0]" <bucket-name>,<account-id>
terraform import "module.s3_bucket.aws_s3_bucket_policy.this[0]" <bucket-name>
terraform import "module.s3_bucket.aws_s3_bucket_ownership_controls.this[0]" <bucket-name>
terraform import "module.s3_bucket.aws_s3_bucket_cors_configuration.this[0]" <bucket-name>,<account-id>
terraform import "module.s3_bucket.aws_s3_bucket_object_lock_configuration.this[0]" <bucket-name>,<account-id>
terraform import "module.s3_bucket.aws_s3_bucket_public_access_block.this[0]" <bucket-name>
terraform import "module.s3_bucket.aws_s3_bucket_lifecycle_configuration.this[0]" <bucket-name>,<account-id>
terraform import "module.s3_bucket.aws_s3_bucket_replication_configuration.this[0]" <bucket-name>
```

Where `s3_bucket` is the name of your module definition, `bucket-name` is the name of the bucket, `acl` is the bucket ACL (e.g. `private`, `log-delivery-write`, etc), `<account-id>` is your AWS account number (required only if `expected_bucket_owner` is set in the code).
59 changes: 59 additions & 0 deletions examples/complete-legacy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Legacy - Complete S3 bucket with most of supported features enabled

Configuration in this directory creates S3 bucket using previous (2.x) version of this module to test upgrade process.

This configuration is similar to the code in [examples/complete](https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/tree/master/examples/complete) but not identical.

## Usage

Once this configuration is created, you need to use the newer version of this module (e.g. `~> 3.0`), review/update arguments (see code in [examples/complete](https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/tree/master/examples/complete)) and import existing resources (see [UPGRADE-3.0.md](https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/blob/master/UPGRADE-3.0.md) for more precise commands).

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.1 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | ~> 3.69.0 |
| <a name="requirement_random"></a> [random](#requirement\_random) | >= 2.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | ~> 3.69.0 |
| <a name="provider_random"></a> [random](#provider\_random) | >= 2.0 |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_log_bucket"></a> [log\_bucket](#module\_log\_bucket) | terraform-aws-modules/s3-bucket/aws | ~> 2.0 |
| <a name="module_s3_bucket"></a> [s3\_bucket](#module\_s3\_bucket) | terraform-aws-modules/s3-bucket/aws | ~> 2.0 |

## Resources

| Name | Type |
|------|------|
| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_kms_key.objects](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
| [random_pet.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource |
| [aws_iam_policy_document.bucket_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |

## Inputs

No inputs.

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_s3_bucket_arn"></a> [s3\_bucket\_arn](#output\_s3\_bucket\_arn) | The ARN of the bucket. Will be of format arn:aws:s3:::bucketname. |
| <a name="output_s3_bucket_bucket_domain_name"></a> [s3\_bucket\_bucket\_domain\_name](#output\_s3\_bucket\_bucket\_domain\_name) | The bucket domain name. Will be of format bucketname.s3.amazonaws.com. |
| <a name="output_s3_bucket_bucket_regional_domain_name"></a> [s3\_bucket\_bucket\_regional\_domain\_name](#output\_s3\_bucket\_bucket\_regional\_domain\_name) | The bucket region-specific domain name. The bucket domain name including the region name, please refer here for format. Note: The AWS CloudFront allows specifying S3 region-specific endpoint when creating S3 origin, it will prevent redirect issues from CloudFront to S3 Origin URL. |
| <a name="output_s3_bucket_hosted_zone_id"></a> [s3\_bucket\_hosted\_zone\_id](#output\_s3\_bucket\_hosted\_zone\_id) | The Route 53 Hosted Zone ID for this bucket's region. |
| <a name="output_s3_bucket_id"></a> [s3\_bucket\_id](#output\_s3\_bucket\_id) | The name of the bucket. |
| <a name="output_s3_bucket_region"></a> [s3\_bucket\_region](#output\_s3\_bucket\_region) | The AWS region this bucket resides in. |
| <a name="output_s3_bucket_website_domain"></a> [s3\_bucket\_website\_domain](#output\_s3\_bucket\_website\_domain) | The domain of the website endpoint, if the bucket is configured with a website. If not, this will be an empty string. This is used to create Route 53 alias records. |
| <a name="output_s3_bucket_website_endpoint"></a> [s3\_bucket\_website\_endpoint](#output\_s3\_bucket\_website\_endpoint) | The website endpoint, if the bucket is configured with a website. If not, this will be an empty string. |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
Loading

0 comments on commit e0de434

Please sign in to comment.