Skip to content

Commit

Permalink
Optional Object lock configuration added (#84)
Browse files Browse the repository at this point in the history
* Optional Object lock configutarion added

* Auto Format

* low bound of provider version upgraded

* Auto Format

* variables fixed

* Auto Format

* variable values fix

* Auto Format

* variable acl fix

* bridgecrew skip added for versioning check

* bridgecrew skip removed for versioning check

* wording/formatting updates due to PR review

* Auto Format

Co-authored-by: cloudpossebot <[email protected]>
  • Loading branch information
maximmi and cloudpossebot authored Apr 8, 2021
1 parent 999fe3e commit 35484d3
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 5 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,13 @@ Available targets:
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 2.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 2.33 |

## Providers

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

## Modules

Expand Down Expand Up @@ -250,6 +250,7 @@ Available targets:
| <a name="input_noncurrent_version_deeparchive_transition_days"></a> [noncurrent\_version\_deeparchive\_transition\_days](#input\_noncurrent\_version\_deeparchive\_transition\_days) | Number of days to persist in the standard storage tier before moving to the glacier deeparchive access tier | `number` | `60` | no |
| <a name="input_noncurrent_version_expiration_days"></a> [noncurrent\_version\_expiration\_days](#input\_noncurrent\_version\_expiration\_days) | Specifies when noncurrent object versions expire | `number` | `90` | no |
| <a name="input_noncurrent_version_glacier_transition_days"></a> [noncurrent\_version\_glacier\_transition\_days](#input\_noncurrent\_version\_glacier\_transition\_days) | Number of days to persist in the standard storage tier before moving to the glacier infrequent access tier | `number` | `30` | no |
| <a name="input_object_lock_configuration"></a> [object\_lock\_configuration](#input\_object\_lock\_configuration) | A configuration for S3 object locking. With S3 Object Lock, you can store objects using a `write once, read many` (WORM) model. Object Lock can help prevent objects from being deleted or overwritten for a fixed amount of time or indefinitely. | <pre>object({<br> mode = string # Valid values are GOVERNANCE and COMPLIANCE.<br> days = number<br> years = number<br> })</pre> | `null` | no |
| <a name="input_policy"></a> [policy](#input\_policy) | 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 | `string` | `""` | no |
| <a name="input_prefix"></a> [prefix](#input\_prefix) | Prefix identifying one or more objects to which the rule applies | `string` | `""` | no |
| <a name="input_regex_replace_chars"></a> [regex\_replace\_chars](#input\_regex\_replace\_chars) | Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
Expand Down
5 changes: 3 additions & 2 deletions docs/terraform.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 2.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 2.33 |

## Providers

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

## Modules

Expand Down Expand Up @@ -77,6 +77,7 @@
| <a name="input_noncurrent_version_deeparchive_transition_days"></a> [noncurrent\_version\_deeparchive\_transition\_days](#input\_noncurrent\_version\_deeparchive\_transition\_days) | Number of days to persist in the standard storage tier before moving to the glacier deeparchive access tier | `number` | `60` | no |
| <a name="input_noncurrent_version_expiration_days"></a> [noncurrent\_version\_expiration\_days](#input\_noncurrent\_version\_expiration\_days) | Specifies when noncurrent object versions expire | `number` | `90` | no |
| <a name="input_noncurrent_version_glacier_transition_days"></a> [noncurrent\_version\_glacier\_transition\_days](#input\_noncurrent\_version\_glacier\_transition\_days) | Number of days to persist in the standard storage tier before moving to the glacier infrequent access tier | `number` | `30` | no |
| <a name="input_object_lock_configuration"></a> [object\_lock\_configuration](#input\_object\_lock\_configuration) | A configuration for S3 object locking. With S3 Object Lock, you can store objects using a `write once, read many` (WORM) model. Object Lock can help prevent objects from being deleted or overwritten for a fixed amount of time or indefinitely. | <pre>object({<br> mode = string # Valid values are GOVERNANCE and COMPLIANCE.<br> days = number<br> years = number<br> })</pre> | `null` | no |
| <a name="input_policy"></a> [policy](#input\_policy) | 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 | `string` | `""` | no |
| <a name="input_prefix"></a> [prefix](#input\_prefix) | Prefix identifying one or more objects to which the rule applies | `string` | `""` | no |
| <a name="input_regex_replace_chars"></a> [regex\_replace\_chars](#input\_regex\_replace\_chars) | Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
Expand Down
1 change: 1 addition & 0 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module "s3_bucket" {
allow_encrypted_uploads_only = var.allow_encrypted_uploads_only
allowed_bucket_actions = var.allowed_bucket_actions
bucket_name = var.bucket_name
object_lock_configuration = var.object_lock_configuration

context = module.this.context
}
30 changes: 30 additions & 0 deletions examples/complete/object-lock.us-west-1.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
region = "us-west-1"

namespace = "eg"

stage = "test"

name = "s3-object-lock-test"

acl = "private"

force_destroy = false

versioning_enabled = true

allowed_bucket_actions = [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:GetObject",
"s3:DeleteObject",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:GetBucketLocation",
"s3:AbortMultipartUpload"
]

object_lock_configuration = {
mode = "GOVERNANCE"
days = 366
years = null
}
10 changes: 10 additions & 0 deletions examples/complete/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,13 @@ variable "bucket_name" {
default = null
description = "Bucket name. If provided, the bucket will be created with this name instead of generating the name from the context"
}

variable "object_lock_configuration" {
type = object({
mode = string # Valid values are GOVERNANCE and COMPLIANCE.
days = number
years = number
})
default = null
description = "A configuration for S3 object locking. With S3 Object Lock, you can store objects using a `write once, read many` (WORM) model. Object Lock can help prevent objects from being deleted or overwritten for a fixed amount of time or indefinitely."
}
14 changes: 14 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,20 @@ resource "aws_s3_bucket" "default" {
}
}
}

dynamic "object_lock_configuration" {
for_each = var.object_lock_configuration != null ? [1] : []
content {
object_lock_enabled = "Enabled"
rule {
default_retention {
mode = var.object_lock_configuration.mode
days = var.object_lock_configuration.days
years = var.object_lock_configuration.years
}
}
}
}
}

module "s3_user" {
Expand Down
43 changes: 43 additions & 0 deletions test/src/examples_complete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,46 @@ func TestExamplesCompleteWithGrants(t *testing.T) {
// Verify we're getting back the outputs we expect
assert.Equal(t, expectedS3BucketId, s3BucketId)
}

// Test the Terraform module in examples/complete using Terratest for grants.
func TestExamplesCompleteWithObjectLock(t *testing.T) {
rand.Seed(time.Now().UnixNano())

attributes := []string{strconv.Itoa(rand.Intn(100000))}
rootFolder := "../../"
terraformFolderRelativeToRoot := "examples/complete"
varFiles := []string{"object-lock.us-west-1.tfvars"}

tempTestFolder := test_structure.CopyTerraformFolderToTemp(t, rootFolder, terraformFolderRelativeToRoot)

terraformOptions := &terraform.Options{
// The path to where our Terraform code is located
TerraformDir: tempTestFolder,
Upgrade: true,
// Variables to pass to our Terraform code using -var-file options
VarFiles: varFiles,
Vars: map[string]interface{}{
"attributes": attributes,
},
}

// At the end of the test, run `terraform destroy` to clean up any resources that were created
defer terraform.Destroy(t, terraformOptions)

// This will run `terraform init` and `terraform apply` and fail the test if there are any errors
terraform.InitAndApply(t, terraformOptions)

// Run `terraform output` to get the value of an output variable
userName := terraform.Output(t, terraformOptions, "user_name")

expectedUserName := "eg-test-s3-object-lock-test-" + attributes[0]
// Verify we're getting back the outputs we expect
assert.Equal(t, expectedUserName, userName)

// Run `terraform output` to get the value of an output variable
s3BucketId := terraform.Output(t, terraformOptions, "bucket_id")

expectedS3BucketId := "eg-test-s3-object-lock-test-" + attributes[0]
// Verify we're getting back the outputs we expect
assert.Equal(t, expectedS3BucketId, s3BucketId)
}
10 changes: 10 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,13 @@ variable "bucket_name" {
default = null
description = "Bucket name. If provided, the bucket will be created with this name instead of generating the name from the context"
}

variable "object_lock_configuration" {
type = object({
mode = string # Valid values are GOVERNANCE and COMPLIANCE.
days = number
years = number
})
default = null
description = "A configuration for S3 object locking. With S3 Object Lock, you can store objects using a `write once, read many` (WORM) model. Object Lock can help prevent objects from being deleted or overwritten for a fixed amount of time or indefinitely."
}
2 changes: 1 addition & 1 deletion versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 2.0"
version = ">= 2.33"
}
}
}

0 comments on commit 35484d3

Please sign in to comment.