From f57e0b06c5f3472d4f08a68034d2656860da63c0 Mon Sep 17 00:00:00 2001 From: NitishKumar06 Date: Wed, 31 Jan 2024 15:09:44 +0530 Subject: [PATCH] add kyverno-json policies Signed-off-by: NitishKumar06 --- .../aws/s3/disable-s3-acl/README.md | 35 + .../aws/s3/disable-s3-acl/disable-s3-acl.yaml | 27 + .../s3/disable-s3-acl/test/bad-payload.json | 222 ++ .../s3/disable-s3-acl/test/bad-terraform.tf | 26 + .../s3/disable-s3-acl/test/good-payload.json | 222 ++ .../s3/disable-s3-acl/test/good-terraform.tf | 25 + .../README.md | 29 + .../s3-cross-region-replication.yaml | 31 + .../test/bad-payload.json | 1340 ++++++++++ .../test/bad-terraform.tf | 125 + .../test/good-payload.json | 2246 +++++++++++++++++ .../test/good-terraform.tf | 125 + .../aws/s3/public-access-block/README.md | 79 + .../public-access-block/test/bad-payload.json | 214 ++ .../public-access-block/test/bad-terraform.tf | 27 + .../test/good-payload.json | 214 ++ .../test/good-terraform.tf | 27 + .../validate-public-access-block.yaml | 39 + 18 files changed, 5053 insertions(+) create mode 100644 terraform-best-practices/aws/s3/disable-s3-acl/README.md create mode 100644 terraform-best-practices/aws/s3/disable-s3-acl/disable-s3-acl.yaml create mode 100644 terraform-best-practices/aws/s3/disable-s3-acl/test/bad-payload.json create mode 100644 terraform-best-practices/aws/s3/disable-s3-acl/test/bad-terraform.tf create mode 100644 terraform-best-practices/aws/s3/disable-s3-acl/test/good-payload.json create mode 100644 terraform-best-practices/aws/s3/disable-s3-acl/test/good-terraform.tf create mode 100644 terraform-best-practices/aws/s3/enable-s3-cross-region-replication/README.md create mode 100644 terraform-best-practices/aws/s3/enable-s3-cross-region-replication/s3-cross-region-replication.yaml create mode 100644 terraform-best-practices/aws/s3/enable-s3-cross-region-replication/test/bad-payload.json create mode 100644 terraform-best-practices/aws/s3/enable-s3-cross-region-replication/test/bad-terraform.tf create mode 100644 terraform-best-practices/aws/s3/enable-s3-cross-region-replication/test/good-payload.json create mode 100644 terraform-best-practices/aws/s3/enable-s3-cross-region-replication/test/good-terraform.tf create mode 100644 terraform-best-practices/aws/s3/public-access-block/README.md create mode 100644 terraform-best-practices/aws/s3/public-access-block/test/bad-payload.json create mode 100644 terraform-best-practices/aws/s3/public-access-block/test/bad-terraform.tf create mode 100644 terraform-best-practices/aws/s3/public-access-block/test/good-payload.json create mode 100644 terraform-best-practices/aws/s3/public-access-block/test/good-terraform.tf create mode 100644 terraform-best-practices/aws/s3/public-access-block/validate-public-access-block.yaml diff --git a/terraform-best-practices/aws/s3/disable-s3-acl/README.md b/terraform-best-practices/aws/s3/disable-s3-acl/README.md new file mode 100644 index 00000000..5734b1d3 --- /dev/null +++ b/terraform-best-practices/aws/s3/disable-s3-acl/README.md @@ -0,0 +1,35 @@ +The Access Control List (ACL) by default is disabled for an S3 Bucket. However, if you'd like to disable the ACL while creating an S3 Bucket from a Terraform file, there are three options that you can provide to the `object_ownership` field in your Terraform file. + +**ACLs disabled**: +- *Bucket owner enforced (default)* – ACLs are disabled, and the bucket owner automatically owns and has full control over every object in the bucket. ACLs no longer affect permissions to data in the S3 bucket. The bucket uses policies to define access control. + +**ACLs enabled**: +- *Bucket owner preferred* – The bucket owner owns and has full control over new objects that other accounts write to the bucket with the bucket-owner-full-control canned ACL. + +- *Object writer* – The AWS account that uploads an object owns the object, has full control over it, and can grant other users access to it through ACLs. + +You can read more information about [Controlling ownership of objects and disabling ACLs for your bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html?icmpid=docs_amazons3_console). + +In order to test this policy, use the following commands: + +1. Initialise Terraform in your working directory + ``` + terraform init + ``` + +2. Create a binary of your terraform plan + ``` + terraform plan -out tfplan.binary + ``` + +3. Convert the executable binary into JSON Payload + ``` + terraform show -json tfplan.binary | jq > payload.json + ``` +4. Test the policy using `kyverno-json` command + ``` + kyverno-json scan --payload payload.json --policy policy.yaml + ``` + Since you've set the `object_ownership` field to `BucketOwnerEnforced` in *s3-disable.tf* file, the policy will give you Passing checks. If you try to change the value of `object_ownership` to either `BucketOwnerPreferred` or `ObjectWriter` the policy will give you failing checks. + + In case you'd like to test this policy for a failing scneario, try to set the payload to `./aws/disable-s3-acl/policy-test/bad-payload.json` and run the `kyverno-json scan` command again. \ No newline at end of file diff --git a/terraform-best-practices/aws/s3/disable-s3-acl/disable-s3-acl.yaml b/terraform-best-practices/aws/s3/disable-s3-acl/disable-s3-acl.yaml new file mode 100644 index 00000000..f46edcfa --- /dev/null +++ b/terraform-best-practices/aws/s3/disable-s3-acl/disable-s3-acl.yaml @@ -0,0 +1,27 @@ +apiVersion: json.kyverno.io/v1alpha1 +kind: ValidatingPolicy +metadata: + name: disable-s3-access-control-list + annotations: + policies.kyverno.io/title: Disable S3 Access Control List + policies.kyverno.io/category: AWS S3 Security Best Practices + policies.kyverno.io/severity: medium + policies.kyverno.io/description: >- + S3 Object Ownership is an Amazon S3 bucket-level setting that + you can use to control ownership of objects uploaded to your bucket + and to disable or enable ACLs. By default, Object Ownership is set to + the Bucket owner enforced setting and all ACLs are disabled. + When ACLs are disabled, the bucket owner owns all the objects in the bucket + and manages access to data exclusively using access management policies. +spec: + rules: + - name: disable-s3-access-control-list + match: + any: + - (planned_values.root_module.resources[?type=='aws_s3_bucket_ownership_controls' || type=='aws_s3_bucket'] | length(@) > `0`): true + assert: + all: + - message: Access Control List(ACL) should be disabled for an S3 Bucket + check: + ~.(planned_values.root_module.resources[?type=='aws_s3_bucket_ownership_controls'].values.rule[]): + object_ownership: BucketOwnerEnforced \ No newline at end of file diff --git a/terraform-best-practices/aws/s3/disable-s3-acl/test/bad-payload.json b/terraform-best-practices/aws/s3/disable-s3-acl/test/bad-payload.json new file mode 100644 index 00000000..35209cc2 --- /dev/null +++ b/terraform-best-practices/aws/s3/disable-s3-acl/test/bad-payload.json @@ -0,0 +1,222 @@ +{ + "format_version": "1.2", + "terraform_version": "1.6.6", + "planned_values": { + "root_module": { + "resources": [ + { + "address": "aws_s3_bucket.example", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "bucket": "test-bucket-demo-19012003", + "force_destroy": false, + "tags": null, + "timeouts": null + }, + "sensitive_values": { + "cors_rule": [], + "grant": [], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [], + "tags_all": {}, + "versioning": [], + "website": [] + } + }, + { + "address": "aws_s3_bucket_ownership_controls.example", + "mode": "managed", + "type": "aws_s3_bucket_ownership_controls", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "rule": [ + { + "object_ownership": "ObjectWriter" + } + ] + }, + "sensitive_values": { + "rule": [ + {} + ] + } + } + ] + } + }, + "resource_changes": [ + { + "address": "aws_s3_bucket.example", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "bucket": "test-bucket-demo-19012003", + "force_destroy": false, + "tags": null, + "timeouts": null + }, + "after_unknown": { + "acceleration_status": true, + "acl": true, + "arn": true, + "bucket_domain_name": true, + "bucket_prefix": true, + "bucket_regional_domain_name": true, + "cors_rule": true, + "grant": true, + "hosted_zone_id": true, + "id": true, + "lifecycle_rule": true, + "logging": true, + "object_lock_configuration": true, + "object_lock_enabled": true, + "policy": true, + "region": true, + "replication_configuration": true, + "request_payer": true, + "server_side_encryption_configuration": true, + "tags_all": true, + "versioning": true, + "website": true, + "website_domain": true, + "website_endpoint": true + }, + "before_sensitive": false, + "after_sensitive": { + "cors_rule": [], + "grant": [], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [], + "tags_all": {}, + "versioning": [], + "website": [] + } + } + }, + { + "address": "aws_s3_bucket_ownership_controls.example", + "mode": "managed", + "type": "aws_s3_bucket_ownership_controls", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "rule": [ + { + "object_ownership": "ObjectWriter" + } + ] + }, + "after_unknown": { + "bucket": true, + "id": true, + "rule": [ + {} + ] + }, + "before_sensitive": false, + "after_sensitive": { + "rule": [ + {} + ] + } + } + } + ], + "configuration": { + "provider_config": { + "aws": { + "name": "aws", + "full_name": "registry.terraform.io/hashicorp/aws", + "version_constraint": "~> 4.16", + "expressions": { + "access_key": { + "constant_value": "ASIA4JFRUINQKAVMFJ7T" + }, + "region": { + "constant_value": "us-west-2" + }, + "secret_key": { + "constant_value": "uxBT1k1aAgnKzy7NImgwdi7qV6dXDSwAYnJWF/aX" + }, + "token": { + "constant_value": "IQoJb3JpZ2luX2VjEEUaCXVzLWVhc3QtMiJHMEUCIAICuzfK4ZNXCHP0EBkv8ALykBK4hyEx2NYKvS042jaEAiEA4FyWjJhlfKhG0TE/Pq4ncnbyXNvnLxjjKvDdWF/pdiUqlwMI7v//////////ARADGgw4NDQzMzM1OTc1MzYiDIKBtCpjoZwAp7xp8CrrAoYMvkPMq0StJ88kQUWSscOSDrbeNulBAMp06U3GtCJkG0S/FNtWWB12QnL0Xq68oqU58bmWn7IRHVQba4L+NzVjSaacpAXld7rrdl0NqfUAyTxQFDMMvg6vQATaK4luZDcMJnkYMoKcFXsMVORy2/l030uimnAJK3fPvGzhx7Imhd81sc5f4CXNrIKZBckthb/8UiSZqeW4uBqgGHR4oi5PCiARl8t8tHVw7+wnOemTO5+wyGnz/ymtAfDfEzObS1sZhasenH80eJ5pQn6y42RPtied6QkRgWaMID/WcWDRsxmTPRxecMqazpwXv9QvoVR1uUqxR1JUi/UW+aAmiFKKOUTQ0F/18XOm0Qg9aQ58rdj50qyZAtcAuTIw+jhkaZmZUk7ilr3NiUKmzihbkPtc6uIHAcptwAdwecy3ToaSBNA9jGbGSzHUgP8MUDqWzH60C6CqFeI+6BxL/5BtGZ/Iw2eYP6Jz2H+WITC37qmtBjqmAeYz9W8WtP0+Qwupx9tAQx0/JTeSN9Kx2HvjNMZRAo8U2ir3aOqHL1EdwNpNJjI70j/a+TvJIh3ePc+zCJQGX5j8eWhW6ZTo97/xCmOnQ+lffAANa9+kcpXBrceWuKmiUWMHwYpoLaw0S8RkrTRt6H1W+HFR857h1TRLzKOj4PrD7x3mkBeeyPQzbW+xpc4Oq8Yy6r0Py7BnU+pO+CrT26pgTUQP6mc=" + } + } + } + }, + "root_module": { + "resources": [ + { + "address": "aws_s3_bucket.example", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "example", + "provider_config_key": "aws", + "expressions": { + "bucket": { + "constant_value": "test-bucket-demo-19012003" + } + }, + "schema_version": 0 + }, + { + "address": "aws_s3_bucket_ownership_controls.example", + "mode": "managed", + "type": "aws_s3_bucket_ownership_controls", + "name": "example", + "provider_config_key": "aws", + "expressions": { + "bucket": { + "references": [ + "aws_s3_bucket.example.id", + "aws_s3_bucket.example" + ] + }, + "rule": [ + { + "object_ownership": { + "constant_value": "ObjectWriter" + } + } + ] + }, + "schema_version": 0 + } + ] + } + }, + "relevant_attributes": [ + { + "resource": "aws_s3_bucket.example", + "attribute": [ + "id" + ] + } + ], + "timestamp": "2024-01-19T13:21:17Z", + "errored": false +} diff --git a/terraform-best-practices/aws/s3/disable-s3-acl/test/bad-terraform.tf b/terraform-best-practices/aws/s3/disable-s3-acl/test/bad-terraform.tf new file mode 100644 index 00000000..49c49d3d --- /dev/null +++ b/terraform-best-practices/aws/s3/disable-s3-acl/test/bad-terraform.tf @@ -0,0 +1,26 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 4.16" + } + } + + required_version = ">= 1.2.0" +} + +provider "aws" { + region = "us-west-2" +} + +resource "aws_s3_bucket" "example" { + bucket = "test-bucket-demo-19012003" +} + +resource "aws_s3_bucket_ownership_controls" "example" { + bucket = aws_s3_bucket.example.id + rule { + object_ownership = "ObjectWriter" + } +} + diff --git a/terraform-best-practices/aws/s3/disable-s3-acl/test/good-payload.json b/terraform-best-practices/aws/s3/disable-s3-acl/test/good-payload.json new file mode 100644 index 00000000..4fdaf041 --- /dev/null +++ b/terraform-best-practices/aws/s3/disable-s3-acl/test/good-payload.json @@ -0,0 +1,222 @@ +{ + "format_version": "1.2", + "terraform_version": "1.6.6", + "planned_values": { + "root_module": { + "resources": [ + { + "address": "aws_s3_bucket.example", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "bucket": "test-bucket-demo-18012003", + "force_destroy": false, + "tags": null, + "timeouts": null + }, + "sensitive_values": { + "cors_rule": [], + "grant": [], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [], + "tags_all": {}, + "versioning": [], + "website": [] + } + }, + { + "address": "aws_s3_bucket_ownership_controls.example", + "mode": "managed", + "type": "aws_s3_bucket_ownership_controls", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "rule": [ + { + "object_ownership": "BucketOwnerEnforced" + } + ] + }, + "sensitive_values": { + "rule": [ + {} + ] + } + } + ] + } + }, + "resource_changes": [ + { + "address": "aws_s3_bucket.example", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "bucket": "test-bucket-demo-18012003", + "force_destroy": false, + "tags": null, + "timeouts": null + }, + "after_unknown": { + "acceleration_status": true, + "acl": true, + "arn": true, + "bucket_domain_name": true, + "bucket_prefix": true, + "bucket_regional_domain_name": true, + "cors_rule": true, + "grant": true, + "hosted_zone_id": true, + "id": true, + "lifecycle_rule": true, + "logging": true, + "object_lock_configuration": true, + "object_lock_enabled": true, + "policy": true, + "region": true, + "replication_configuration": true, + "request_payer": true, + "server_side_encryption_configuration": true, + "tags_all": true, + "versioning": true, + "website": true, + "website_domain": true, + "website_endpoint": true + }, + "before_sensitive": false, + "after_sensitive": { + "cors_rule": [], + "grant": [], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [], + "tags_all": {}, + "versioning": [], + "website": [] + } + } + }, + { + "address": "aws_s3_bucket_ownership_controls.example", + "mode": "managed", + "type": "aws_s3_bucket_ownership_controls", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "rule": [ + { + "object_ownership": "BucketOwnerEnforced" + } + ] + }, + "after_unknown": { + "bucket": true, + "id": true, + "rule": [ + {} + ] + }, + "before_sensitive": false, + "after_sensitive": { + "rule": [ + {} + ] + } + } + } + ], + "configuration": { + "provider_config": { + "aws": { + "name": "aws", + "full_name": "registry.terraform.io/hashicorp/aws", + "version_constraint": "~> 4.16", + "expressions": { + "access_key": { + "constant_value": "ASIA4JFRUINQNABYZTNP" + }, + "region": { + "constant_value": "us-west-2" + }, + "secret_key": { + "constant_value": "HXiB5ijszDzqfHCNT4hzF6WsHjFtkvSSZylIFaSO" + }, + "token": { + "constant_value": "IQoJb3JpZ2luX2VjEEQaCXVzLWVhc3QtMiJHMEUCIQDtBv00RXWgfzVtShLXu/ICvgI5I4+OWLgmsxRvN494dQIgavNEPFqrQmk5KAFOeWx8MrJ434tye9Wfss5CEPFvVV8qlwMI7f//////////ARADGgw4NDQzMzM1OTc1MzYiDKB0z2OJRMRQbRZDNirrArUdNiTk6i47T80oO4iBhprjoLvUGlMIPlnvT2c8PRIRsRjPKOVll4USqsyyY7S7n9QdFGjKGXpSFSdmO8O30hHy4PJdqgwrLyQyE6Gl1Fu0A/EAuQWVR8qzg0YcNyj4LVmrJJhKYc7t2kJN+5NuibSpTDuzTs9F+bqco9XntV394ltXEB4dqOzSAXFRVFr90fMhvdS8stNVEsJ3OnXXYbXIrn9N4VLeUlxKSwlji03h+TeqfLk40A+lp8RgIbNsP8qdQFkGi+Fk/i+kqba2K0qGHqo0SKcCNadqsnfmkIhQkq/UKFRGgQdMMQWEFK2IMfn+szsi+AHB6dJDrdvAy/yLDhqkjilA5AqBXm8e4IT0Y5cQwodMU8NCzvTqdeI9ruK1mZfy0gxOpNpj0WBiidJCjMoufYO+iFcDfCaJh7dpQnFSipTdtWPgydk0DL8WXn5mKNFGMDlKaRWQdmVR2oNfLNDghL0JPSnj9TDIyamtBjqmAYa8arm0m3yJJcmR3jDqtEKybLnSGjXvV+B72Tl8i3Y4z5ZengwXNF5JKP/fHUYDfn6zZm/TnUTAaeL0oxAs7bJik/hwqtrde7Bv0gobL3fxqLPEbSxd1iIfO6uUnZDCvynbvD3oMiVwOCmX5tkWqRHEmpfme0irSDcqqem2bB4MOUCDpJQmXi6be+QR0MPC42UyW39ABeqa3K39tZVOLPYz+xLz5WU=" + } + } + } + }, + "root_module": { + "resources": [ + { + "address": "aws_s3_bucket.example", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "example", + "provider_config_key": "aws", + "expressions": { + "bucket": { + "constant_value": "test-bucket-demo-18012003" + } + }, + "schema_version": 0 + }, + { + "address": "aws_s3_bucket_ownership_controls.example", + "mode": "managed", + "type": "aws_s3_bucket_ownership_controls", + "name": "example", + "provider_config_key": "aws", + "expressions": { + "bucket": { + "references": [ + "aws_s3_bucket.example.id", + "aws_s3_bucket.example" + ] + }, + "rule": [ + { + "object_ownership": { + "constant_value": "BucketOwnerEnforced" + } + } + ] + }, + "schema_version": 0 + } + ] + } + }, + "relevant_attributes": [ + { + "resource": "aws_s3_bucket.example", + "attribute": [ + "id" + ] + } + ], + "timestamp": "2024-01-19T12:05:57Z", + "errored": false +} diff --git a/terraform-best-practices/aws/s3/disable-s3-acl/test/good-terraform.tf b/terraform-best-practices/aws/s3/disable-s3-acl/test/good-terraform.tf new file mode 100644 index 00000000..5f3a7cbc --- /dev/null +++ b/terraform-best-practices/aws/s3/disable-s3-acl/test/good-terraform.tf @@ -0,0 +1,25 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 4.16" + } + } + + required_version = ">= 1.2.0" +} + +provider "aws" { + region = "us-west-2" +} + +resource "aws_s3_bucket" "example" { + bucket = "test-bucket-demo-18012003" +} + +resource "aws_s3_bucket_ownership_controls" "example" { + bucket = aws_s3_bucket.example.id + rule { + object_ownership = "BucketOwnerEnforced" + } +} diff --git a/terraform-best-practices/aws/s3/enable-s3-cross-region-replication/README.md b/terraform-best-practices/aws/s3/enable-s3-cross-region-replication/README.md new file mode 100644 index 00000000..b5d03f96 --- /dev/null +++ b/terraform-best-practices/aws/s3/enable-s3-cross-region-replication/README.md @@ -0,0 +1,29 @@ +Replication enables automatic, asynchronous copying of objects across Amazon S3 buckets. Buckets that are configured for object replication can be owned by the same AWS account or by different accounts. You can replicate objects to a single destination bucket or to multiple destination buckets. The destination buckets can be in different AWS Regions or within the same Region as the source bucket. + +To automatically replicate new objects as they are written to the bucket, use live replication, such as Cross-Region Replication (CRR). To replicate existing objects to a different bucket on demand, use S3 Batch Replication. + +In order to *Enable* the cross-region replication for an S3 Bucket, you need to use the *aws_s3_bucket_replication_configuration* resource block in your Terraform file. The *status* field which is a mandatory field will determine whether you'd like to enable the Cross Region Replication or not. The required values for *Status* are *Enabled* or *Disabled* which means you can neither set any other value (say foo) for status field nor exclude the status field from your resource block. You can read more about this in [Terraform documentation](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_replication_configuration#status). + +In order to test this policy, use the following commands: + +1. Initialise Terraform in your working directory + ``` + terraform init + ``` + +2. Create a binary of your terraform plan + ``` + terraform plan -out tfplan.binary + ``` + +3. Convert the executable binary into JSON Payload + ``` + terraform show -json tfplan.binary | jq > payload.json + ``` +4. Test the policy using `kyverno-json` command + ``` + kyverno-json scan --payload good-payload.json --policy s3-cross-region-replication.yaml + ``` + Since you've set the `status` field to `Enabled` in *good-terraform.tf* file, the policy will give you Passing checks. If you try to change the value of `status` to `Disabled` the policy will give you failing checks on a the new payload. + +In case you'd like to test this policy for a failing scneario, try to set the payload to `./aws/enable-s3-cross-region-replication/test/bad-payload.json` and run the `kyverno-json scan` command again. \ No newline at end of file diff --git a/terraform-best-practices/aws/s3/enable-s3-cross-region-replication/s3-cross-region-replication.yaml b/terraform-best-practices/aws/s3/enable-s3-cross-region-replication/s3-cross-region-replication.yaml new file mode 100644 index 00000000..ed2694e3 --- /dev/null +++ b/terraform-best-practices/aws/s3/enable-s3-cross-region-replication/s3-cross-region-replication.yaml @@ -0,0 +1,31 @@ +apiVersion: json.kyverno.io/v1alpha1 +kind: ValidatingPolicy +metadata: + name: enable-s3-cross-region-replication + annotations: + policies.kyverno.io/title: enable-s3-cross-region-replication + policies.kyverno.io/category: AWS S3 Security Best Practices + policies.kyverno.io/severity: medium + policies.kyverno.io/description: >- + Replication enables automatic, asynchronous copying of objects + across Amazon S3 buckets. Buckets that are configured for object + replication can be owned by the same AWS account or by different + accounts. You can replicate objects to a single destination bucket + or to multiple destination buckets. The destination buckets can be + in different AWS Regions or within the same Region as the source bucket. +spec: + rules: + - name: check-s3-cross-region-replication + match: + all: + - (planned_values.root_module.resources[?type=='aws_s3_bucket'] | length(@) > `0`): true + assert: + all: + - message: Use the `aws_s3_bucket_replication_configuration` resource to set the status to Enabled + check: + (planned_values.root_module.resources[?type=='aws_s3_bucket_replication_configuration'] | length(@) > `0`): true + - message: Set S3 Bucket Cross Region Replication status to 'Enabled' + check: + ~.(planned_values.root_module.resources[?type=='aws_s3_bucket_replication_configuration']): + (values.rule[?status=='Enabled'] | length(@) > `0`): true + \ No newline at end of file diff --git a/terraform-best-practices/aws/s3/enable-s3-cross-region-replication/test/bad-payload.json b/terraform-best-practices/aws/s3/enable-s3-cross-region-replication/test/bad-payload.json new file mode 100644 index 00000000..edf45aae --- /dev/null +++ b/terraform-best-practices/aws/s3/enable-s3-cross-region-replication/test/bad-payload.json @@ -0,0 +1,1340 @@ +{ + "format_version": "1.2", + "terraform_version": "1.6.6", + "planned_values": { + "root_module": { + "resources": [ + { + "address": "aws_iam_policy.replication", + "mode": "managed", + "type": "aws_iam_policy", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "description": null, + "name": "tf-iam-role-policy-replication-12345", + "path": "/", + "tags": null + }, + "sensitive_values": { + "tags_all": {} + } + }, + { + "address": "aws_iam_role.replication", + "mode": "managed", + "type": "aws_iam_role", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "assume_role_policy": "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"s3.amazonaws.com\"}}],\"Version\":\"2012-10-17\"}", + "description": null, + "force_detach_policies": false, + "max_session_duration": 3600, + "name": "tf-iam-role-replication-12345", + "path": "/", + "permissions_boundary": null, + "tags": null + }, + "sensitive_values": { + "inline_policy": [], + "managed_policy_arns": [], + "tags_all": {} + } + }, + { + "address": "aws_iam_role_policy_attachment.replication", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "role": "tf-iam-role-replication-12345" + }, + "sensitive_values": {} + }, + { + "address": "aws_s3_bucket.destination", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "destination", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "bucket": "tf-test-bucket-destination-nitish-12345", + "force_destroy": false, + "tags": null, + "timeouts": null + }, + "sensitive_values": { + "cors_rule": [], + "grant": [], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [], + "tags_all": {}, + "versioning": [], + "website": [] + } + }, + { + "address": "aws_s3_bucket.source", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "source", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "bucket": "tf-test-bucket-source-nitish-12345", + "force_destroy": false, + "tags": null, + "timeouts": null + }, + "sensitive_values": { + "cors_rule": [], + "grant": [], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [], + "tags_all": {}, + "versioning": [], + "website": [] + } + }, + { + "address": "aws_s3_bucket_replication_configuration.replication", + "mode": "managed", + "type": "aws_s3_bucket_replication_configuration", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "rule": [ + { + "delete_marker_replication": [ + { + "status": "Enabled" + } + ], + "destination": [ + { + "access_control_translation": [], + "account": null, + "encryption_configuration": [], + "metrics": [], + "replication_time": [], + "storage_class": "STANDARD" + } + ], + "existing_object_replication": [], + "filter": [ + { + "and": [], + "prefix": "foo", + "tag": [] + } + ], + "id": "foobar", + "prefix": null, + "priority": null, + "source_selection_criteria": [], + "status": "Disabled" + } + ], + "token": null + }, + "sensitive_values": { + "rule": [ + { + "delete_marker_replication": [ + {} + ], + "destination": [ + { + "access_control_translation": [], + "encryption_configuration": [], + "metrics": [], + "replication_time": [] + } + ], + "existing_object_replication": [], + "filter": [ + { + "and": [], + "tag": [] + } + ], + "source_selection_criteria": [] + } + ] + } + }, + { + "address": "aws_s3_bucket_versioning.destination", + "mode": "managed", + "type": "aws_s3_bucket_versioning", + "name": "destination", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "expected_bucket_owner": null, + "mfa": null, + "versioning_configuration": [ + { + "status": "Enabled" + } + ] + }, + "sensitive_values": { + "versioning_configuration": [ + {} + ] + } + }, + { + "address": "aws_s3_bucket_versioning.source", + "mode": "managed", + "type": "aws_s3_bucket_versioning", + "name": "source", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "expected_bucket_owner": null, + "mfa": null, + "versioning_configuration": [ + { + "status": "Enabled" + } + ] + }, + "sensitive_values": { + "versioning_configuration": [ + {} + ] + } + }, + { + "address": "data.aws_iam_policy_document.replication", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "override_policy_documents": null, + "policy_id": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "s3:GetReplicationConfiguration", + "s3:ListBucket" + ], + "condition": [], + "effect": "Allow", + "not_actions": null, + "not_principals": [], + "not_resources": null, + "principals": [], + "resources": [ + null + ], + "sid": null + }, + { + "actions": [ + "s3:GetObjectVersionAcl", + "s3:GetObjectVersionForReplication", + "s3:GetObjectVersionTagging" + ], + "condition": [], + "effect": "Allow", + "not_actions": null, + "not_principals": [], + "not_resources": null, + "principals": [], + "resources": [ + null + ], + "sid": null + }, + { + "actions": [ + "s3:ReplicateObject", + "s3:ReplicateTags" + ], + "condition": [], + "effect": "Allow", + "not_actions": null, + "not_principals": [], + "not_resources": null, + "principals": [], + "resources": [ + null + ], + "sid": null + } + ], + "version": null + }, + "sensitive_values": { + "statement": [ + { + "actions": [ + false, + false + ], + "condition": [], + "not_principals": [], + "principals": [], + "resources": [ + false + ] + }, + { + "actions": [ + false, + false, + false + ], + "condition": [], + "not_principals": [], + "principals": [], + "resources": [ + false + ] + }, + { + "actions": [ + false, + false + ], + "condition": [], + "not_principals": [], + "principals": [], + "resources": [ + false + ] + } + ] + } + } + ] + } + }, + "resource_changes": [ + { + "address": "data.aws_iam_policy_document.replication", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "read" + ], + "before": null, + "after": { + "override_policy_documents": null, + "policy_id": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "s3:GetReplicationConfiguration", + "s3:ListBucket" + ], + "condition": [], + "effect": "Allow", + "not_actions": null, + "not_principals": [], + "not_resources": null, + "principals": [], + "resources": [ + null + ], + "sid": null + }, + { + "actions": [ + "s3:GetObjectVersionAcl", + "s3:GetObjectVersionForReplication", + "s3:GetObjectVersionTagging" + ], + "condition": [], + "effect": "Allow", + "not_actions": null, + "not_principals": [], + "not_resources": null, + "principals": [], + "resources": [ + null + ], + "sid": null + }, + { + "actions": [ + "s3:ReplicateObject", + "s3:ReplicateTags" + ], + "condition": [], + "effect": "Allow", + "not_actions": null, + "not_principals": [], + "not_resources": null, + "principals": [], + "resources": [ + null + ], + "sid": null + } + ], + "version": null + }, + "after_unknown": { + "id": true, + "json": true, + "statement": [ + { + "actions": [ + false, + false + ], + "condition": [], + "not_principals": [], + "principals": [], + "resources": [ + true + ] + }, + { + "actions": [ + false, + false, + false + ], + "condition": [], + "not_principals": [], + "principals": [], + "resources": [ + true + ] + }, + { + "actions": [ + false, + false + ], + "condition": [], + "not_principals": [], + "principals": [], + "resources": [ + true + ] + } + ] + }, + "before_sensitive": false, + "after_sensitive": { + "statement": [ + { + "actions": [ + false, + false + ], + "condition": [], + "not_principals": [], + "principals": [], + "resources": [ + false + ] + }, + { + "actions": [ + false, + false, + false + ], + "condition": [], + "not_principals": [], + "principals": [], + "resources": [ + false + ] + }, + { + "actions": [ + false, + false + ], + "condition": [], + "not_principals": [], + "principals": [], + "resources": [ + false + ] + } + ] + } + }, + "action_reason": "read_because_config_unknown" + }, + { + "address": "aws_iam_policy.replication", + "mode": "managed", + "type": "aws_iam_policy", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "description": null, + "name": "tf-iam-role-policy-replication-12345", + "path": "/", + "tags": null + }, + "after_unknown": { + "arn": true, + "id": true, + "name_prefix": true, + "policy": true, + "policy_id": true, + "tags_all": true + }, + "before_sensitive": false, + "after_sensitive": { + "tags_all": {} + } + } + }, + { + "address": "aws_iam_role.replication", + "mode": "managed", + "type": "aws_iam_role", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "assume_role_policy": "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"s3.amazonaws.com\"}}],\"Version\":\"2012-10-17\"}", + "description": null, + "force_detach_policies": false, + "max_session_duration": 3600, + "name": "tf-iam-role-replication-12345", + "path": "/", + "permissions_boundary": null, + "tags": null + }, + "after_unknown": { + "arn": true, + "create_date": true, + "id": true, + "inline_policy": true, + "managed_policy_arns": true, + "name_prefix": true, + "tags_all": true, + "unique_id": true + }, + "before_sensitive": false, + "after_sensitive": { + "inline_policy": [], + "managed_policy_arns": [], + "tags_all": {} + } + } + }, + { + "address": "aws_iam_role_policy_attachment.replication", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "role": "tf-iam-role-replication-12345" + }, + "after_unknown": { + "id": true, + "policy_arn": true + }, + "before_sensitive": false, + "after_sensitive": {} + } + }, + { + "address": "aws_s3_bucket.destination", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "destination", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "bucket": "tf-test-bucket-destination-nitish-12345", + "force_destroy": false, + "tags": null, + "timeouts": null + }, + "after_unknown": { + "acceleration_status": true, + "acl": true, + "arn": true, + "bucket_domain_name": true, + "bucket_prefix": true, + "bucket_regional_domain_name": true, + "cors_rule": true, + "grant": true, + "hosted_zone_id": true, + "id": true, + "lifecycle_rule": true, + "logging": true, + "object_lock_configuration": true, + "object_lock_enabled": true, + "policy": true, + "region": true, + "replication_configuration": true, + "request_payer": true, + "server_side_encryption_configuration": true, + "tags_all": true, + "versioning": true, + "website": true, + "website_domain": true, + "website_endpoint": true + }, + "before_sensitive": false, + "after_sensitive": { + "cors_rule": [], + "grant": [], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [], + "tags_all": {}, + "versioning": [], + "website": [] + } + } + }, + { + "address": "aws_s3_bucket.source", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "source", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "bucket": "tf-test-bucket-source-nitish-12345", + "force_destroy": false, + "tags": null, + "timeouts": null + }, + "after_unknown": { + "acceleration_status": true, + "acl": true, + "arn": true, + "bucket_domain_name": true, + "bucket_prefix": true, + "bucket_regional_domain_name": true, + "cors_rule": true, + "grant": true, + "hosted_zone_id": true, + "id": true, + "lifecycle_rule": true, + "logging": true, + "object_lock_configuration": true, + "object_lock_enabled": true, + "policy": true, + "region": true, + "replication_configuration": true, + "request_payer": true, + "server_side_encryption_configuration": true, + "tags_all": true, + "versioning": true, + "website": true, + "website_domain": true, + "website_endpoint": true + }, + "before_sensitive": false, + "after_sensitive": { + "cors_rule": [], + "grant": [], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [], + "tags_all": {}, + "versioning": [], + "website": [] + } + } + }, + { + "address": "aws_s3_bucket_replication_configuration.replication", + "mode": "managed", + "type": "aws_s3_bucket_replication_configuration", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "rule": [ + { + "delete_marker_replication": [ + { + "status": "Enabled" + } + ], + "destination": [ + { + "access_control_translation": [], + "account": null, + "encryption_configuration": [], + "metrics": [], + "replication_time": [], + "storage_class": "STANDARD" + } + ], + "existing_object_replication": [], + "filter": [ + { + "and": [], + "prefix": "foo", + "tag": [] + } + ], + "id": "foobar", + "prefix": null, + "priority": null, + "source_selection_criteria": [], + "status": "Disabled" + } + ], + "token": null + }, + "after_unknown": { + "bucket": true, + "id": true, + "role": true, + "rule": [ + { + "delete_marker_replication": [ + {} + ], + "destination": [ + { + "access_control_translation": [], + "bucket": true, + "encryption_configuration": [], + "metrics": [], + "replication_time": [] + } + ], + "existing_object_replication": [], + "filter": [ + { + "and": [], + "tag": [] + } + ], + "source_selection_criteria": [] + } + ] + }, + "before_sensitive": false, + "after_sensitive": { + "rule": [ + { + "delete_marker_replication": [ + {} + ], + "destination": [ + { + "access_control_translation": [], + "encryption_configuration": [], + "metrics": [], + "replication_time": [] + } + ], + "existing_object_replication": [], + "filter": [ + { + "and": [], + "tag": [] + } + ], + "source_selection_criteria": [] + } + ], + "token": true + } + } + }, + { + "address": "aws_s3_bucket_versioning.destination", + "mode": "managed", + "type": "aws_s3_bucket_versioning", + "name": "destination", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "expected_bucket_owner": null, + "mfa": null, + "versioning_configuration": [ + { + "status": "Enabled" + } + ] + }, + "after_unknown": { + "bucket": true, + "id": true, + "versioning_configuration": [ + { + "mfa_delete": true + } + ] + }, + "before_sensitive": false, + "after_sensitive": { + "versioning_configuration": [ + {} + ] + } + } + }, + { + "address": "aws_s3_bucket_versioning.source", + "mode": "managed", + "type": "aws_s3_bucket_versioning", + "name": "source", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "expected_bucket_owner": null, + "mfa": null, + "versioning_configuration": [ + { + "status": "Enabled" + } + ] + }, + "after_unknown": { + "bucket": true, + "id": true, + "versioning_configuration": [ + { + "mfa_delete": true + } + ] + }, + "before_sensitive": false, + "after_sensitive": { + "versioning_configuration": [ + {} + ] + } + } + } + ], + "prior_state": { + "format_version": "1.0", + "terraform_version": "1.6.6", + "values": { + "root_module": { + "resources": [ + { + "address": "data.aws_iam_policy_document.assume_role", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "assume_role", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "id": "1765856792", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"sts:AssumeRole\",\n \"Principal\": {\n \"Service\": \"s3.amazonaws.com\"\n }\n }\n ]\n}", + "override_policy_documents": null, + "policy_id": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "sts:AssumeRole" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [ + { + "identifiers": [ + "s3.amazonaws.com" + ], + "type": "Service" + } + ], + "resources": [], + "sid": "" + } + ], + "version": "2012-10-17" + }, + "sensitive_values": { + "statement": [ + { + "actions": [ + false + ], + "condition": [], + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [ + { + "identifiers": [ + false + ] + } + ], + "resources": [] + } + ] + } + } + ] + } + } + }, + "configuration": { + "provider_config": { + "aws": { + "name": "aws", + "full_name": "registry.terraform.io/hashicorp/aws", + "expressions": { + "access_key": { + "constant_value": "ASIA4JFRUINQJ3PM62E4" + }, + "region": { + "constant_value": "eu-west-1" + }, + "secret_key": { + "constant_value": "cAt33vVIa4drH47QG+ayoX1QUyPHEVYb6rVM8fMO" + }, + "token": { + "constant_value": "IQoJb3JpZ2luX2VjELv//////////wEaCXVzLWVhc3QtMiJIMEYCIQDa7mH3BbBgWAN8uIqvByWjIkqE2NgeRlp0wv5lyUqdGAIhALq8kuxs9gem1qyy31iAVNWE/TmqbqoGELcjGRSjzal/Ko4DCHQQAxoMODQ0MzMzNTk3NTM2IgwGJcG4RNOyfF5NjGYq6wIUKagZTTHC1L26O6UYmvtDiMgOZbBUmlwyGu/hx1Ek+tkuFuWCpl6h6ny4t1gMhxhAlkej0+YPLREPr4kkgN32+2ft/dBfPo5zqr0N9QbsijPUL5dvsOUwogjyDsPkrDMsifuWpQy7Xou7FtHlUllSUoofQkBGJZp9d1s1PXGIyhPGr7uOlvAZT0Vp1XgCqdDNKfdi1K6bqqoRJA5vKXnnzlUJbGOhV84d+1jpniT66jyjFsSODuHMK0Cw5jW8Mo2uY2AggTmpObT+NWlQsM7p6hPrx8ue5gM97TDux0AXgjHCeiXyRk2ISzhbWT0cbJuX8FCdxDj7LyUcmFocMYz1HmRjsbq2PicfolqxbtadXo66Pf3+kJLrv4y68qp29zlNsNAJ+MiQBh/W1uUCH+r1gXDaNuntNeG0WPUxBPuHoMmAoT/9W6nzhuedG7enQu6g14pGknpQMpc6Bv5ChGPJHQhCZFv9ZllVLVMw0tbDrQY6pQExYg4kz2d3VqBXU2RUulqe7zx56vbA7cIGp26i9KQs0Pt+6XQdOqK7VIJh5P0JA0/QZar6XqbNtaWs9AAmknUwOfuYeej8gJS8Xszf6QOgVSYtO0IuxOtO9AHGauibsdesN+uRAib0uLMbL7DcPC2AV8OOX5HxvD1RDu2qC+trtZOb3KhZ2nkcdf2HaAdK9lqy/KiJFXyvhUBpnLTQ0i6v6rLCBNs=" + } + } + }, + "aws.central": { + "name": "aws", + "full_name": "registry.terraform.io/hashicorp/aws", + "alias": "central", + "expressions": { + "access_key": { + "constant_value": "ASIA4JFRUINQJ3PM62E4" + }, + "region": { + "constant_value": "eu-central-1" + }, + "secret_key": { + "constant_value": "cAt33vVIa4drH47QG+ayoX1QUyPHEVYb6rVM8fMO" + }, + "token": { + "constant_value": "IQoJb3JpZ2luX2VjELv//////////wEaCXVzLWVhc3QtMiJIMEYCIQDa7mH3BbBgWAN8uIqvByWjIkqE2NgeRlp0wv5lyUqdGAIhALq8kuxs9gem1qyy31iAVNWE/TmqbqoGELcjGRSjzal/Ko4DCHQQAxoMODQ0MzMzNTk3NTM2IgwGJcG4RNOyfF5NjGYq6wIUKagZTTHC1L26O6UYmvtDiMgOZbBUmlwyGu/hx1Ek+tkuFuWCpl6h6ny4t1gMhxhAlkej0+YPLREPr4kkgN32+2ft/dBfPo5zqr0N9QbsijPUL5dvsOUwogjyDsPkrDMsifuWpQy7Xou7FtHlUllSUoofQkBGJZp9d1s1PXGIyhPGr7uOlvAZT0Vp1XgCqdDNKfdi1K6bqqoRJA5vKXnnzlUJbGOhV84d+1jpniT66jyjFsSODuHMK0Cw5jW8Mo2uY2AggTmpObT+NWlQsM7p6hPrx8ue5gM97TDux0AXgjHCeiXyRk2ISzhbWT0cbJuX8FCdxDj7LyUcmFocMYz1HmRjsbq2PicfolqxbtadXo66Pf3+kJLrv4y68qp29zlNsNAJ+MiQBh/W1uUCH+r1gXDaNuntNeG0WPUxBPuHoMmAoT/9W6nzhuedG7enQu6g14pGknpQMpc6Bv5ChGPJHQhCZFv9ZllVLVMw0tbDrQY6pQExYg4kz2d3VqBXU2RUulqe7zx56vbA7cIGp26i9KQs0Pt+6XQdOqK7VIJh5P0JA0/QZar6XqbNtaWs9AAmknUwOfuYeej8gJS8Xszf6QOgVSYtO0IuxOtO9AHGauibsdesN+uRAib0uLMbL7DcPC2AV8OOX5HxvD1RDu2qC+trtZOb3KhZ2nkcdf2HaAdK9lqy/KiJFXyvhUBpnLTQ0i6v6rLCBNs=" + } + } + } + }, + "root_module": { + "resources": [ + { + "address": "aws_iam_policy.replication", + "mode": "managed", + "type": "aws_iam_policy", + "name": "replication", + "provider_config_key": "aws", + "expressions": { + "name": { + "constant_value": "tf-iam-role-policy-replication-12345" + }, + "policy": { + "references": [ + "data.aws_iam_policy_document.replication.json", + "data.aws_iam_policy_document.replication" + ] + } + }, + "schema_version": 0 + }, + { + "address": "aws_iam_role.replication", + "mode": "managed", + "type": "aws_iam_role", + "name": "replication", + "provider_config_key": "aws", + "expressions": { + "assume_role_policy": { + "references": [ + "data.aws_iam_policy_document.assume_role.json", + "data.aws_iam_policy_document.assume_role" + ] + }, + "name": { + "constant_value": "tf-iam-role-replication-12345" + } + }, + "schema_version": 0 + }, + { + "address": "aws_iam_role_policy_attachment.replication", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "replication", + "provider_config_key": "aws", + "expressions": { + "policy_arn": { + "references": [ + "aws_iam_policy.replication.arn", + "aws_iam_policy.replication" + ] + }, + "role": { + "references": [ + "aws_iam_role.replication.name", + "aws_iam_role.replication" + ] + } + }, + "schema_version": 0 + }, + { + "address": "aws_s3_bucket.destination", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "destination", + "provider_config_key": "aws", + "expressions": { + "bucket": { + "constant_value": "tf-test-bucket-destination-nitish-12345" + } + }, + "schema_version": 0 + }, + { + "address": "aws_s3_bucket.source", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "source", + "provider_config_key": "aws.central", + "expressions": { + "bucket": { + "constant_value": "tf-test-bucket-source-nitish-12345" + } + }, + "schema_version": 0 + }, + { + "address": "aws_s3_bucket_replication_configuration.replication", + "mode": "managed", + "type": "aws_s3_bucket_replication_configuration", + "name": "replication", + "provider_config_key": "aws.central", + "expressions": { + "bucket": { + "references": [ + "aws_s3_bucket.source.id", + "aws_s3_bucket.source" + ] + }, + "role": { + "references": [ + "aws_iam_role.replication.arn", + "aws_iam_role.replication" + ] + }, + "rule": [ + { + "delete_marker_replication": [ + { + "status": { + "constant_value": "Enabled" + } + } + ], + "destination": [ + { + "bucket": { + "references": [ + "aws_s3_bucket.destination.arn", + "aws_s3_bucket.destination" + ] + }, + "storage_class": { + "constant_value": "STANDARD" + } + } + ], + "filter": [ + { + "prefix": { + "constant_value": "foo" + } + } + ], + "id": { + "constant_value": "foobar" + }, + "status": { + "constant_value": "Disabled" + } + } + ] + }, + "schema_version": 0, + "depends_on": [ + "aws_s3_bucket_versioning.source" + ] + }, + { + "address": "aws_s3_bucket_versioning.destination", + "mode": "managed", + "type": "aws_s3_bucket_versioning", + "name": "destination", + "provider_config_key": "aws", + "expressions": { + "bucket": { + "references": [ + "aws_s3_bucket.destination.id", + "aws_s3_bucket.destination" + ] + }, + "versioning_configuration": [ + { + "status": { + "constant_value": "Enabled" + } + } + ] + }, + "schema_version": 0 + }, + { + "address": "aws_s3_bucket_versioning.source", + "mode": "managed", + "type": "aws_s3_bucket_versioning", + "name": "source", + "provider_config_key": "aws.central", + "expressions": { + "bucket": { + "references": [ + "aws_s3_bucket.source.id", + "aws_s3_bucket.source" + ] + }, + "versioning_configuration": [ + { + "status": { + "constant_value": "Enabled" + } + } + ] + }, + "schema_version": 0 + }, + { + "address": "data.aws_iam_policy_document.assume_role", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "assume_role", + "provider_config_key": "aws", + "expressions": { + "statement": [ + { + "actions": { + "constant_value": [ + "sts:AssumeRole" + ] + }, + "effect": { + "constant_value": "Allow" + }, + "principals": [ + { + "identifiers": { + "constant_value": [ + "s3.amazonaws.com" + ] + }, + "type": { + "constant_value": "Service" + } + } + ] + } + ] + }, + "schema_version": 0 + }, + { + "address": "data.aws_iam_policy_document.replication", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "replication", + "provider_config_key": "aws", + "expressions": { + "statement": [ + { + "actions": { + "constant_value": [ + "s3:GetReplicationConfiguration", + "s3:ListBucket" + ] + }, + "effect": { + "constant_value": "Allow" + }, + "resources": { + "references": [ + "aws_s3_bucket.source.arn", + "aws_s3_bucket.source" + ] + } + }, + { + "actions": { + "constant_value": [ + "s3:GetObjectVersionForReplication", + "s3:GetObjectVersionAcl", + "s3:GetObjectVersionTagging" + ] + }, + "effect": { + "constant_value": "Allow" + }, + "resources": { + "references": [ + "aws_s3_bucket.source.arn", + "aws_s3_bucket.source" + ] + } + }, + { + "actions": { + "constant_value": [ + "s3:ReplicateObject", + "s3:ReplicateTags" + ] + }, + "effect": { + "constant_value": "Allow" + }, + "resources": { + "references": [ + "aws_s3_bucket.destination.arn", + "aws_s3_bucket.destination" + ] + } + } + ] + }, + "schema_version": 0 + } + ] + } + }, + "relevant_attributes": [ + { + "resource": "aws_s3_bucket.source", + "attribute": [ + "id" + ] + }, + { + "resource": "data.aws_iam_policy_document.replication", + "attribute": [ + "json" + ] + }, + { + "resource": "aws_iam_role.replication", + "attribute": [ + "arn" + ] + }, + { + "resource": "aws_iam_role.replication", + "attribute": [ + "name" + ] + }, + { + "resource": "data.aws_iam_policy_document.assume_role", + "attribute": [ + "json" + ] + }, + { + "resource": "aws_s3_bucket.destination", + "attribute": [ + "id" + ] + }, + { + "resource": "aws_s3_bucket.source", + "attribute": [ + "arn" + ] + }, + { + "resource": "aws_s3_bucket.destination", + "attribute": [ + "arn" + ] + }, + { + "resource": "aws_iam_policy.replication", + "attribute": [ + "arn" + ] + } + ], + "timestamp": "2024-01-24T11:12:11Z", + "errored": false +} diff --git a/terraform-best-practices/aws/s3/enable-s3-cross-region-replication/test/bad-terraform.tf b/terraform-best-practices/aws/s3/enable-s3-cross-region-replication/test/bad-terraform.tf new file mode 100644 index 00000000..49cb3c5b --- /dev/null +++ b/terraform-best-practices/aws/s3/enable-s3-cross-region-replication/test/bad-terraform.tf @@ -0,0 +1,125 @@ +provider "aws" { + region = "eu-west-1" +} + +provider "aws" { + alias = "central" + region = "eu-central-1" +} + +data "aws_iam_policy_document" "assume_role" { + statement { + effect = "Allow" + + principals { + type = "Service" + identifiers = ["s3.amazonaws.com"] + } + + actions = ["sts:AssumeRole"] + } +} + +resource "aws_iam_role" "replication" { + name = "tf-iam-role-replication-12345" + assume_role_policy = data.aws_iam_policy_document.assume_role.json +} + +data "aws_iam_policy_document" "replication" { + statement { + effect = "Allow" + + actions = [ + "s3:GetReplicationConfiguration", + "s3:ListBucket", + ] + + resources = [aws_s3_bucket.source.arn] + } + + statement { + effect = "Allow" + + actions = [ + "s3:GetObjectVersionForReplication", + "s3:GetObjectVersionAcl", + "s3:GetObjectVersionTagging", + ] + + resources = ["${aws_s3_bucket.source.arn}/*"] + } + + statement { + effect = "Allow" + + actions = [ + "s3:ReplicateObject", + "s3:ReplicateTags", + ] + + resources = ["${aws_s3_bucket.destination.arn}/*"] + } +} + +resource "aws_iam_policy" "replication" { + name = "tf-iam-role-policy-replication-12345" + policy = data.aws_iam_policy_document.replication.json +} + +resource "aws_iam_role_policy_attachment" "replication" { + role = aws_iam_role.replication.name + policy_arn = aws_iam_policy.replication.arn +} + +resource "aws_s3_bucket" "destination" { + bucket = "tf-test-bucket-destination-nitish-12345" +} + +resource "aws_s3_bucket_versioning" "destination" { + bucket = aws_s3_bucket.destination.id + versioning_configuration { + status = "Enabled" + } +} + +resource "aws_s3_bucket" "source" { + provider = aws.central + bucket = "tf-test-bucket-source-nitish-12345" +} + +resource "aws_s3_bucket_versioning" "source" { + provider = aws.central + + bucket = aws_s3_bucket.source.id + versioning_configuration { + status = "Enabled" + } +} + +resource "aws_s3_bucket_replication_configuration" "replication" { + provider = aws.central + # Must have bucket versioning enabled first + depends_on = [aws_s3_bucket_versioning.source] + + role = aws_iam_role.replication.arn + bucket = aws_s3_bucket.source.id + + rule { + id = "foobar" + + filter { + prefix = "foo" + } + + status = "Disabled" + + destination { + bucket = aws_s3_bucket.destination.arn + storage_class = "STANDARD" + } + + delete_marker_replication { + status = "Enabled" + } + } +} \ No newline at end of file diff --git a/terraform-best-practices/aws/s3/enable-s3-cross-region-replication/test/good-payload.json b/terraform-best-practices/aws/s3/enable-s3-cross-region-replication/test/good-payload.json new file mode 100644 index 00000000..eec0bf4b --- /dev/null +++ b/terraform-best-practices/aws/s3/enable-s3-cross-region-replication/test/good-payload.json @@ -0,0 +1,2246 @@ +{ + "format_version": "1.2", + "terraform_version": "1.6.6", + "planned_values": { + "root_module": { + "resources": [ + { + "address": "aws_iam_policy.replication", + "mode": "managed", + "type": "aws_iam_policy", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "arn": "arn:aws:iam::844333597536:policy/tf-iam-role-policy-replication-12345", + "description": "", + "id": "arn:aws:iam::844333597536:policy/tf-iam-role-policy-replication-12345", + "name": "tf-iam-role-policy-replication-12345", + "name_prefix": "", + "path": "/", + "policy": "{\"Statement\":[{\"Action\":[\"s3:ListBucket\",\"s3:GetReplicationConfiguration\"],\"Effect\":\"Allow\",\"Resource\":\"arn:aws:s3:::tf-test-bucket-source-nitish-12345\"},{\"Action\":[\"s3:GetObjectVersionTagging\",\"s3:GetObjectVersionForReplication\",\"s3:GetObjectVersionAcl\"],\"Effect\":\"Allow\",\"Resource\":\"arn:aws:s3:::tf-test-bucket-source-nitish-12345/*\"},{\"Action\":[\"s3:ReplicateTags\",\"s3:ReplicateObject\"],\"Effect\":\"Allow\",\"Resource\":\"arn:aws:s3:::tf-test-bucket-destination-nitish-12345/*\"}],\"Version\":\"2012-10-17\"}", + "policy_id": "ANPA4JFRUINQLTD64575W", + "tags": {}, + "tags_all": {} + }, + "sensitive_values": { + "tags": {}, + "tags_all": {} + } + }, + { + "address": "aws_iam_role.replication", + "mode": "managed", + "type": "aws_iam_role", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "arn": "arn:aws:iam::844333597536:role/tf-iam-role-replication-12345", + "assume_role_policy": "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"s3.amazonaws.com\"}}],\"Version\":\"2012-10-17\"}", + "create_date": "2024-01-24T10:55:42Z", + "description": "", + "force_detach_policies": false, + "id": "tf-iam-role-replication-12345", + "inline_policy": [], + "managed_policy_arns": [ + "arn:aws:iam::844333597536:policy/tf-iam-role-policy-replication-12345" + ], + "max_session_duration": 3600, + "name": "tf-iam-role-replication-12345", + "name_prefix": "", + "path": "/", + "permissions_boundary": "", + "tags": {}, + "tags_all": {}, + "unique_id": "AROA4JFRUINQIGIEP43IO" + }, + "sensitive_values": { + "inline_policy": [], + "managed_policy_arns": [ + false + ], + "tags": {}, + "tags_all": {} + } + }, + { + "address": "aws_iam_role_policy_attachment.replication", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "id": "tf-iam-role-replication-12345-20240124105702515800000001", + "policy_arn": "arn:aws:iam::844333597536:policy/tf-iam-role-policy-replication-12345", + "role": "tf-iam-role-replication-12345" + }, + "sensitive_values": {} + }, + { + "address": "aws_s3_bucket.destination", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "destination", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "acceleration_status": "", + "acl": null, + "arn": "arn:aws:s3:::tf-test-bucket-destination-nitish-12345", + "bucket": "tf-test-bucket-destination-nitish-12345", + "bucket_domain_name": "tf-test-bucket-destination-nitish-12345.s3.amazonaws.com", + "bucket_prefix": "", + "bucket_regional_domain_name": "tf-test-bucket-destination-nitish-12345.s3.eu-west-1.amazonaws.com", + "cors_rule": [], + "force_destroy": false, + "grant": [ + { + "id": "62ea66bd2e8f7e76e4fb466e942a41389d6057fcc90d732feaac373bb0d0a7a5", + "permissions": [ + "FULL_CONTROL" + ], + "type": "CanonicalUser", + "uri": "" + } + ], + "hosted_zone_id": "Z1BKCTXD74EZPE", + "id": "tf-test-bucket-destination-nitish-12345", + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "object_lock_enabled": false, + "policy": "", + "region": "eu-west-1", + "replication_configuration": [], + "request_payer": "BucketOwner", + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + { + "kms_master_key_id": "", + "sse_algorithm": "AES256" + } + ], + "bucket_key_enabled": false + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "timeouts": null, + "versioning": [ + { + "enabled": true, + "mfa_delete": false + } + ], + "website": [], + "website_domain": null, + "website_endpoint": null + }, + "sensitive_values": { + "cors_rule": [], + "grant": [ + { + "permissions": [ + false + ] + } + ], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + {} + ] + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "versioning": [ + {} + ], + "website": [] + } + }, + { + "address": "aws_s3_bucket.source", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "source", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "acceleration_status": "", + "acl": null, + "arn": "arn:aws:s3:::tf-test-bucket-source-nitish-12345", + "bucket": "tf-test-bucket-source-nitish-12345", + "bucket_domain_name": "tf-test-bucket-source-nitish-12345.s3.amazonaws.com", + "bucket_prefix": "", + "bucket_regional_domain_name": "tf-test-bucket-source-nitish-12345.s3.eu-central-1.amazonaws.com", + "cors_rule": [], + "force_destroy": false, + "grant": [ + { + "id": "62ea66bd2e8f7e76e4fb466e942a41389d6057fcc90d732feaac373bb0d0a7a5", + "permissions": [ + "FULL_CONTROL" + ], + "type": "CanonicalUser", + "uri": "" + } + ], + "hosted_zone_id": "Z21DNDUVLTQW6Q", + "id": "tf-test-bucket-source-nitish-12345", + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "object_lock_enabled": false, + "policy": "", + "region": "eu-central-1", + "replication_configuration": [], + "request_payer": "BucketOwner", + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + { + "kms_master_key_id": "", + "sse_algorithm": "AES256" + } + ], + "bucket_key_enabled": false + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "timeouts": null, + "versioning": [ + { + "enabled": true, + "mfa_delete": false + } + ], + "website": [], + "website_domain": null, + "website_endpoint": null + }, + "sensitive_values": { + "cors_rule": [], + "grant": [ + { + "permissions": [ + false + ] + } + ], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + {} + ] + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "versioning": [ + {} + ], + "website": [] + } + }, + { + "address": "aws_s3_bucket_replication_configuration.replication", + "mode": "managed", + "type": "aws_s3_bucket_replication_configuration", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "bucket": "tf-test-bucket-source-nitish-12345", + "role": "arn:aws:iam::844333597536:role/tf-iam-role-replication-12345", + "rule": [ + { + "delete_marker_replication": [ + { + "status": "Enabled" + } + ], + "destination": [ + { + "access_control_translation": [], + "account": null, + "bucket": "arn:aws:s3:::tf-test-bucket-destination-nitish-12345", + "encryption_configuration": [], + "metrics": [], + "replication_time": [], + "storage_class": "STANDARD" + } + ], + "existing_object_replication": [], + "filter": [ + { + "and": [], + "prefix": "foo", + "tag": [] + } + ], + "id": "foobar", + "prefix": null, + "priority": null, + "source_selection_criteria": [], + "status": "Enabled" + } + ], + "token": null + }, + "sensitive_values": { + "rule": [ + { + "delete_marker_replication": [ + {} + ], + "destination": [ + { + "access_control_translation": [], + "encryption_configuration": [], + "metrics": [], + "replication_time": [] + } + ], + "existing_object_replication": [], + "filter": [ + { + "and": [], + "tag": [] + } + ], + "source_selection_criteria": [] + } + ] + } + }, + { + "address": "aws_s3_bucket_versioning.destination", + "mode": "managed", + "type": "aws_s3_bucket_versioning", + "name": "destination", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "bucket": "tf-test-bucket-destination-nitish-12345", + "expected_bucket_owner": "", + "id": "tf-test-bucket-destination-nitish-12345", + "mfa": null, + "versioning_configuration": [ + { + "mfa_delete": "", + "status": "Enabled" + } + ] + }, + "sensitive_values": { + "versioning_configuration": [ + {} + ] + } + }, + { + "address": "aws_s3_bucket_versioning.source", + "mode": "managed", + "type": "aws_s3_bucket_versioning", + "name": "source", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "bucket": "tf-test-bucket-source-nitish-12345", + "expected_bucket_owner": "", + "id": "tf-test-bucket-source-nitish-12345", + "mfa": null, + "versioning_configuration": [ + { + "mfa_delete": "", + "status": "Enabled" + } + ] + }, + "sensitive_values": { + "versioning_configuration": [ + {} + ] + } + } + ] + } + }, + "resource_drift": [ + { + "address": "aws_s3_bucket.source", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "source", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "update" + ], + "before": { + "acceleration_status": "", + "acl": null, + "arn": "arn:aws:s3:::tf-test-bucket-source-nitish-12345", + "bucket": "tf-test-bucket-source-nitish-12345", + "bucket_domain_name": "tf-test-bucket-source-nitish-12345.s3.amazonaws.com", + "bucket_prefix": "", + "bucket_regional_domain_name": "tf-test-bucket-source-nitish-12345.s3.eu-central-1.amazonaws.com", + "cors_rule": [], + "force_destroy": false, + "grant": [ + { + "id": "62ea66bd2e8f7e76e4fb466e942a41389d6057fcc90d732feaac373bb0d0a7a5", + "permissions": [ + "FULL_CONTROL" + ], + "type": "CanonicalUser", + "uri": "" + } + ], + "hosted_zone_id": "Z21DNDUVLTQW6Q", + "id": "tf-test-bucket-source-nitish-12345", + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "object_lock_enabled": false, + "policy": "", + "region": "eu-central-1", + "replication_configuration": [ + { + "role": "arn:aws:iam::844333597536:role/tf-iam-role-replication-12345", + "rules": [ + { + "delete_marker_replication_status": "Enabled", + "destination": [ + { + "access_control_translation": [], + "account_id": "", + "bucket": "arn:aws:s3:::tf-test-bucket-destination-nitish-12345", + "metrics": [], + "replica_kms_key_id": "", + "replication_time": [], + "storage_class": "STANDARD" + } + ], + "filter": [ + { + "prefix": "foo", + "tags": {} + } + ], + "id": "foobar", + "prefix": "", + "priority": 0, + "source_selection_criteria": [], + "status": "Disabled" + } + ] + } + ], + "request_payer": "BucketOwner", + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + { + "kms_master_key_id": "", + "sse_algorithm": "AES256" + } + ], + "bucket_key_enabled": false + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "timeouts": null, + "versioning": [ + { + "enabled": true, + "mfa_delete": false + } + ], + "website": [], + "website_domain": null, + "website_endpoint": null + }, + "after": { + "acceleration_status": "", + "acl": null, + "arn": "arn:aws:s3:::tf-test-bucket-source-nitish-12345", + "bucket": "tf-test-bucket-source-nitish-12345", + "bucket_domain_name": "tf-test-bucket-source-nitish-12345.s3.amazonaws.com", + "bucket_prefix": "", + "bucket_regional_domain_name": "tf-test-bucket-source-nitish-12345.s3.eu-central-1.amazonaws.com", + "cors_rule": [], + "force_destroy": false, + "grant": [ + { + "id": "62ea66bd2e8f7e76e4fb466e942a41389d6057fcc90d732feaac373bb0d0a7a5", + "permissions": [ + "FULL_CONTROL" + ], + "type": "CanonicalUser", + "uri": "" + } + ], + "hosted_zone_id": "Z21DNDUVLTQW6Q", + "id": "tf-test-bucket-source-nitish-12345", + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "object_lock_enabled": false, + "policy": "", + "region": "eu-central-1", + "replication_configuration": [], + "request_payer": "BucketOwner", + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + { + "kms_master_key_id": "", + "sse_algorithm": "AES256" + } + ], + "bucket_key_enabled": false + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "timeouts": null, + "versioning": [ + { + "enabled": true, + "mfa_delete": false + } + ], + "website": [], + "website_domain": null, + "website_endpoint": null + }, + "after_unknown": {}, + "before_sensitive": { + "cors_rule": [], + "grant": [ + { + "permissions": [ + false + ] + } + ], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [ + { + "rules": [ + { + "destination": [ + { + "access_control_translation": [], + "metrics": [], + "replication_time": [] + } + ], + "filter": [ + { + "tags": {} + } + ], + "source_selection_criteria": [] + } + ] + } + ], + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + {} + ] + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "versioning": [ + {} + ], + "website": [] + }, + "after_sensitive": { + "cors_rule": [], + "grant": [ + { + "permissions": [ + false + ] + } + ], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + {} + ] + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "versioning": [ + {} + ], + "website": [] + } + } + } + ], + "resource_changes": [ + { + "address": "aws_iam_policy.replication", + "mode": "managed", + "type": "aws_iam_policy", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "no-op" + ], + "before": { + "arn": "arn:aws:iam::844333597536:policy/tf-iam-role-policy-replication-12345", + "description": "", + "id": "arn:aws:iam::844333597536:policy/tf-iam-role-policy-replication-12345", + "name": "tf-iam-role-policy-replication-12345", + "name_prefix": "", + "path": "/", + "policy": "{\"Statement\":[{\"Action\":[\"s3:ListBucket\",\"s3:GetReplicationConfiguration\"],\"Effect\":\"Allow\",\"Resource\":\"arn:aws:s3:::tf-test-bucket-source-nitish-12345\"},{\"Action\":[\"s3:GetObjectVersionTagging\",\"s3:GetObjectVersionForReplication\",\"s3:GetObjectVersionAcl\"],\"Effect\":\"Allow\",\"Resource\":\"arn:aws:s3:::tf-test-bucket-source-nitish-12345/*\"},{\"Action\":[\"s3:ReplicateTags\",\"s3:ReplicateObject\"],\"Effect\":\"Allow\",\"Resource\":\"arn:aws:s3:::tf-test-bucket-destination-nitish-12345/*\"}],\"Version\":\"2012-10-17\"}", + "policy_id": "ANPA4JFRUINQLTD64575W", + "tags": {}, + "tags_all": {} + }, + "after": { + "arn": "arn:aws:iam::844333597536:policy/tf-iam-role-policy-replication-12345", + "description": "", + "id": "arn:aws:iam::844333597536:policy/tf-iam-role-policy-replication-12345", + "name": "tf-iam-role-policy-replication-12345", + "name_prefix": "", + "path": "/", + "policy": "{\"Statement\":[{\"Action\":[\"s3:ListBucket\",\"s3:GetReplicationConfiguration\"],\"Effect\":\"Allow\",\"Resource\":\"arn:aws:s3:::tf-test-bucket-source-nitish-12345\"},{\"Action\":[\"s3:GetObjectVersionTagging\",\"s3:GetObjectVersionForReplication\",\"s3:GetObjectVersionAcl\"],\"Effect\":\"Allow\",\"Resource\":\"arn:aws:s3:::tf-test-bucket-source-nitish-12345/*\"},{\"Action\":[\"s3:ReplicateTags\",\"s3:ReplicateObject\"],\"Effect\":\"Allow\",\"Resource\":\"arn:aws:s3:::tf-test-bucket-destination-nitish-12345/*\"}],\"Version\":\"2012-10-17\"}", + "policy_id": "ANPA4JFRUINQLTD64575W", + "tags": {}, + "tags_all": {} + }, + "after_unknown": {}, + "before_sensitive": { + "tags": {}, + "tags_all": {} + }, + "after_sensitive": { + "tags": {}, + "tags_all": {} + } + } + }, + { + "address": "aws_iam_role.replication", + "mode": "managed", + "type": "aws_iam_role", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "no-op" + ], + "before": { + "arn": "arn:aws:iam::844333597536:role/tf-iam-role-replication-12345", + "assume_role_policy": "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"s3.amazonaws.com\"}}],\"Version\":\"2012-10-17\"}", + "create_date": "2024-01-24T10:55:42Z", + "description": "", + "force_detach_policies": false, + "id": "tf-iam-role-replication-12345", + "inline_policy": [], + "managed_policy_arns": [ + "arn:aws:iam::844333597536:policy/tf-iam-role-policy-replication-12345" + ], + "max_session_duration": 3600, + "name": "tf-iam-role-replication-12345", + "name_prefix": "", + "path": "/", + "permissions_boundary": "", + "tags": {}, + "tags_all": {}, + "unique_id": "AROA4JFRUINQIGIEP43IO" + }, + "after": { + "arn": "arn:aws:iam::844333597536:role/tf-iam-role-replication-12345", + "assume_role_policy": "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"s3.amazonaws.com\"}}],\"Version\":\"2012-10-17\"}", + "create_date": "2024-01-24T10:55:42Z", + "description": "", + "force_detach_policies": false, + "id": "tf-iam-role-replication-12345", + "inline_policy": [], + "managed_policy_arns": [ + "arn:aws:iam::844333597536:policy/tf-iam-role-policy-replication-12345" + ], + "max_session_duration": 3600, + "name": "tf-iam-role-replication-12345", + "name_prefix": "", + "path": "/", + "permissions_boundary": "", + "tags": {}, + "tags_all": {}, + "unique_id": "AROA4JFRUINQIGIEP43IO" + }, + "after_unknown": {}, + "before_sensitive": { + "inline_policy": [], + "managed_policy_arns": [ + false + ], + "tags": {}, + "tags_all": {} + }, + "after_sensitive": { + "inline_policy": [], + "managed_policy_arns": [ + false + ], + "tags": {}, + "tags_all": {} + } + } + }, + { + "address": "aws_iam_role_policy_attachment.replication", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "no-op" + ], + "before": { + "id": "tf-iam-role-replication-12345-20240124105702515800000001", + "policy_arn": "arn:aws:iam::844333597536:policy/tf-iam-role-policy-replication-12345", + "role": "tf-iam-role-replication-12345" + }, + "after": { + "id": "tf-iam-role-replication-12345-20240124105702515800000001", + "policy_arn": "arn:aws:iam::844333597536:policy/tf-iam-role-policy-replication-12345", + "role": "tf-iam-role-replication-12345" + }, + "after_unknown": {}, + "before_sensitive": {}, + "after_sensitive": {} + } + }, + { + "address": "aws_s3_bucket.destination", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "destination", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "no-op" + ], + "before": { + "acceleration_status": "", + "acl": null, + "arn": "arn:aws:s3:::tf-test-bucket-destination-nitish-12345", + "bucket": "tf-test-bucket-destination-nitish-12345", + "bucket_domain_name": "tf-test-bucket-destination-nitish-12345.s3.amazonaws.com", + "bucket_prefix": "", + "bucket_regional_domain_name": "tf-test-bucket-destination-nitish-12345.s3.eu-west-1.amazonaws.com", + "cors_rule": [], + "force_destroy": false, + "grant": [ + { + "id": "62ea66bd2e8f7e76e4fb466e942a41389d6057fcc90d732feaac373bb0d0a7a5", + "permissions": [ + "FULL_CONTROL" + ], + "type": "CanonicalUser", + "uri": "" + } + ], + "hosted_zone_id": "Z1BKCTXD74EZPE", + "id": "tf-test-bucket-destination-nitish-12345", + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "object_lock_enabled": false, + "policy": "", + "region": "eu-west-1", + "replication_configuration": [], + "request_payer": "BucketOwner", + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + { + "kms_master_key_id": "", + "sse_algorithm": "AES256" + } + ], + "bucket_key_enabled": false + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "timeouts": null, + "versioning": [ + { + "enabled": true, + "mfa_delete": false + } + ], + "website": [], + "website_domain": null, + "website_endpoint": null + }, + "after": { + "acceleration_status": "", + "acl": null, + "arn": "arn:aws:s3:::tf-test-bucket-destination-nitish-12345", + "bucket": "tf-test-bucket-destination-nitish-12345", + "bucket_domain_name": "tf-test-bucket-destination-nitish-12345.s3.amazonaws.com", + "bucket_prefix": "", + "bucket_regional_domain_name": "tf-test-bucket-destination-nitish-12345.s3.eu-west-1.amazonaws.com", + "cors_rule": [], + "force_destroy": false, + "grant": [ + { + "id": "62ea66bd2e8f7e76e4fb466e942a41389d6057fcc90d732feaac373bb0d0a7a5", + "permissions": [ + "FULL_CONTROL" + ], + "type": "CanonicalUser", + "uri": "" + } + ], + "hosted_zone_id": "Z1BKCTXD74EZPE", + "id": "tf-test-bucket-destination-nitish-12345", + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "object_lock_enabled": false, + "policy": "", + "region": "eu-west-1", + "replication_configuration": [], + "request_payer": "BucketOwner", + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + { + "kms_master_key_id": "", + "sse_algorithm": "AES256" + } + ], + "bucket_key_enabled": false + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "timeouts": null, + "versioning": [ + { + "enabled": true, + "mfa_delete": false + } + ], + "website": [], + "website_domain": null, + "website_endpoint": null + }, + "after_unknown": {}, + "before_sensitive": { + "cors_rule": [], + "grant": [ + { + "permissions": [ + false + ] + } + ], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + {} + ] + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "versioning": [ + {} + ], + "website": [] + }, + "after_sensitive": { + "cors_rule": [], + "grant": [ + { + "permissions": [ + false + ] + } + ], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + {} + ] + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "versioning": [ + {} + ], + "website": [] + } + } + }, + { + "address": "aws_s3_bucket.source", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "source", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "no-op" + ], + "before": { + "acceleration_status": "", + "acl": null, + "arn": "arn:aws:s3:::tf-test-bucket-source-nitish-12345", + "bucket": "tf-test-bucket-source-nitish-12345", + "bucket_domain_name": "tf-test-bucket-source-nitish-12345.s3.amazonaws.com", + "bucket_prefix": "", + "bucket_regional_domain_name": "tf-test-bucket-source-nitish-12345.s3.eu-central-1.amazonaws.com", + "cors_rule": [], + "force_destroy": false, + "grant": [ + { + "id": "62ea66bd2e8f7e76e4fb466e942a41389d6057fcc90d732feaac373bb0d0a7a5", + "permissions": [ + "FULL_CONTROL" + ], + "type": "CanonicalUser", + "uri": "" + } + ], + "hosted_zone_id": "Z21DNDUVLTQW6Q", + "id": "tf-test-bucket-source-nitish-12345", + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "object_lock_enabled": false, + "policy": "", + "region": "eu-central-1", + "replication_configuration": [], + "request_payer": "BucketOwner", + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + { + "kms_master_key_id": "", + "sse_algorithm": "AES256" + } + ], + "bucket_key_enabled": false + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "timeouts": null, + "versioning": [ + { + "enabled": true, + "mfa_delete": false + } + ], + "website": [], + "website_domain": null, + "website_endpoint": null + }, + "after": { + "acceleration_status": "", + "acl": null, + "arn": "arn:aws:s3:::tf-test-bucket-source-nitish-12345", + "bucket": "tf-test-bucket-source-nitish-12345", + "bucket_domain_name": "tf-test-bucket-source-nitish-12345.s3.amazonaws.com", + "bucket_prefix": "", + "bucket_regional_domain_name": "tf-test-bucket-source-nitish-12345.s3.eu-central-1.amazonaws.com", + "cors_rule": [], + "force_destroy": false, + "grant": [ + { + "id": "62ea66bd2e8f7e76e4fb466e942a41389d6057fcc90d732feaac373bb0d0a7a5", + "permissions": [ + "FULL_CONTROL" + ], + "type": "CanonicalUser", + "uri": "" + } + ], + "hosted_zone_id": "Z21DNDUVLTQW6Q", + "id": "tf-test-bucket-source-nitish-12345", + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "object_lock_enabled": false, + "policy": "", + "region": "eu-central-1", + "replication_configuration": [], + "request_payer": "BucketOwner", + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + { + "kms_master_key_id": "", + "sse_algorithm": "AES256" + } + ], + "bucket_key_enabled": false + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "timeouts": null, + "versioning": [ + { + "enabled": true, + "mfa_delete": false + } + ], + "website": [], + "website_domain": null, + "website_endpoint": null + }, + "after_unknown": {}, + "before_sensitive": { + "cors_rule": [], + "grant": [ + { + "permissions": [ + false + ] + } + ], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + {} + ] + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "versioning": [ + {} + ], + "website": [] + }, + "after_sensitive": { + "cors_rule": [], + "grant": [ + { + "permissions": [ + false + ] + } + ], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + {} + ] + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "versioning": [ + {} + ], + "website": [] + } + } + }, + { + "address": "aws_s3_bucket_replication_configuration.replication", + "mode": "managed", + "type": "aws_s3_bucket_replication_configuration", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "bucket": "tf-test-bucket-source-nitish-12345", + "role": "arn:aws:iam::844333597536:role/tf-iam-role-replication-12345", + "rule": [ + { + "delete_marker_replication": [ + { + "status": "Enabled" + } + ], + "destination": [ + { + "access_control_translation": [], + "account": null, + "bucket": "arn:aws:s3:::tf-test-bucket-destination-nitish-12345", + "encryption_configuration": [], + "metrics": [], + "replication_time": [], + "storage_class": "STANDARD" + } + ], + "existing_object_replication": [], + "filter": [ + { + "and": [], + "prefix": "foo", + "tag": [] + } + ], + "id": "foobar", + "prefix": null, + "priority": null, + "source_selection_criteria": [], + "status": "Enabled" + } + ], + "token": null + }, + "after_unknown": { + "id": true, + "rule": [ + { + "delete_marker_replication": [ + {} + ], + "destination": [ + { + "access_control_translation": [], + "encryption_configuration": [], + "metrics": [], + "replication_time": [] + } + ], + "existing_object_replication": [], + "filter": [ + { + "and": [], + "tag": [] + } + ], + "source_selection_criteria": [] + } + ] + }, + "before_sensitive": false, + "after_sensitive": { + "rule": [ + { + "delete_marker_replication": [ + {} + ], + "destination": [ + { + "access_control_translation": [], + "encryption_configuration": [], + "metrics": [], + "replication_time": [] + } + ], + "existing_object_replication": [], + "filter": [ + { + "and": [], + "tag": [] + } + ], + "source_selection_criteria": [] + } + ], + "token": true + } + } + }, + { + "address": "aws_s3_bucket_versioning.destination", + "mode": "managed", + "type": "aws_s3_bucket_versioning", + "name": "destination", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "no-op" + ], + "before": { + "bucket": "tf-test-bucket-destination-nitish-12345", + "expected_bucket_owner": "", + "id": "tf-test-bucket-destination-nitish-12345", + "mfa": null, + "versioning_configuration": [ + { + "mfa_delete": "", + "status": "Enabled" + } + ] + }, + "after": { + "bucket": "tf-test-bucket-destination-nitish-12345", + "expected_bucket_owner": "", + "id": "tf-test-bucket-destination-nitish-12345", + "mfa": null, + "versioning_configuration": [ + { + "mfa_delete": "", + "status": "Enabled" + } + ] + }, + "after_unknown": {}, + "before_sensitive": { + "versioning_configuration": [ + {} + ] + }, + "after_sensitive": { + "versioning_configuration": [ + {} + ] + } + } + }, + { + "address": "aws_s3_bucket_versioning.source", + "mode": "managed", + "type": "aws_s3_bucket_versioning", + "name": "source", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "no-op" + ], + "before": { + "bucket": "tf-test-bucket-source-nitish-12345", + "expected_bucket_owner": "", + "id": "tf-test-bucket-source-nitish-12345", + "mfa": null, + "versioning_configuration": [ + { + "mfa_delete": "", + "status": "Enabled" + } + ] + }, + "after": { + "bucket": "tf-test-bucket-source-nitish-12345", + "expected_bucket_owner": "", + "id": "tf-test-bucket-source-nitish-12345", + "mfa": null, + "versioning_configuration": [ + { + "mfa_delete": "", + "status": "Enabled" + } + ] + }, + "after_unknown": {}, + "before_sensitive": { + "versioning_configuration": [ + {} + ] + }, + "after_sensitive": { + "versioning_configuration": [ + {} + ] + } + } + } + ], + "prior_state": { + "format_version": "1.0", + "terraform_version": "1.6.6", + "values": { + "root_module": { + "resources": [ + { + "address": "data.aws_iam_policy_document.assume_role", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "assume_role", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "id": "1765856792", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"sts:AssumeRole\",\n \"Principal\": {\n \"Service\": \"s3.amazonaws.com\"\n }\n }\n ]\n}", + "override_policy_documents": null, + "policy_id": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "sts:AssumeRole" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [ + { + "identifiers": [ + "s3.amazonaws.com" + ], + "type": "Service" + } + ], + "resources": [], + "sid": "" + } + ], + "version": "2012-10-17" + }, + "sensitive_values": { + "statement": [ + { + "actions": [ + false + ], + "condition": [], + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [ + { + "identifiers": [ + false + ] + } + ], + "resources": [] + } + ] + } + }, + { + "address": "data.aws_iam_policy_document.replication", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "id": "912466413", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"s3:ListBucket\",\n \"s3:GetReplicationConfiguration\"\n ],\n \"Resource\": \"arn:aws:s3:::tf-test-bucket-source-nitish-12345\"\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"s3:GetObjectVersionTagging\",\n \"s3:GetObjectVersionForReplication\",\n \"s3:GetObjectVersionAcl\"\n ],\n \"Resource\": \"arn:aws:s3:::tf-test-bucket-source-nitish-12345/*\"\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"s3:ReplicateTags\",\n \"s3:ReplicateObject\"\n ],\n \"Resource\": \"arn:aws:s3:::tf-test-bucket-destination-nitish-12345/*\"\n }\n ]\n}", + "override_policy_documents": null, + "policy_id": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "s3:GetReplicationConfiguration", + "s3:ListBucket" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:s3:::tf-test-bucket-source-nitish-12345" + ], + "sid": "" + }, + { + "actions": [ + "s3:GetObjectVersionAcl", + "s3:GetObjectVersionForReplication", + "s3:GetObjectVersionTagging" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:s3:::tf-test-bucket-source-nitish-12345/*" + ], + "sid": "" + }, + { + "actions": [ + "s3:ReplicateObject", + "s3:ReplicateTags" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:s3:::tf-test-bucket-destination-nitish-12345/*" + ], + "sid": "" + } + ], + "version": "2012-10-17" + }, + "sensitive_values": { + "statement": [ + { + "actions": [ + false, + false + ], + "condition": [], + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + false + ] + }, + { + "actions": [ + false, + false, + false + ], + "condition": [], + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + false + ] + }, + { + "actions": [ + false, + false + ], + "condition": [], + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + false + ] + } + ] + } + }, + { + "address": "aws_iam_policy.replication", + "mode": "managed", + "type": "aws_iam_policy", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "arn": "arn:aws:iam::844333597536:policy/tf-iam-role-policy-replication-12345", + "description": "", + "id": "arn:aws:iam::844333597536:policy/tf-iam-role-policy-replication-12345", + "name": "tf-iam-role-policy-replication-12345", + "name_prefix": "", + "path": "/", + "policy": "{\"Statement\":[{\"Action\":[\"s3:ListBucket\",\"s3:GetReplicationConfiguration\"],\"Effect\":\"Allow\",\"Resource\":\"arn:aws:s3:::tf-test-bucket-source-nitish-12345\"},{\"Action\":[\"s3:GetObjectVersionTagging\",\"s3:GetObjectVersionForReplication\",\"s3:GetObjectVersionAcl\"],\"Effect\":\"Allow\",\"Resource\":\"arn:aws:s3:::tf-test-bucket-source-nitish-12345/*\"},{\"Action\":[\"s3:ReplicateTags\",\"s3:ReplicateObject\"],\"Effect\":\"Allow\",\"Resource\":\"arn:aws:s3:::tf-test-bucket-destination-nitish-12345/*\"}],\"Version\":\"2012-10-17\"}", + "policy_id": "ANPA4JFRUINQLTD64575W", + "tags": {}, + "tags_all": {} + }, + "sensitive_values": { + "tags": {}, + "tags_all": {} + }, + "depends_on": [ + "aws_s3_bucket.destination", + "aws_s3_bucket.source", + "data.aws_iam_policy_document.replication" + ] + }, + { + "address": "aws_iam_role.replication", + "mode": "managed", + "type": "aws_iam_role", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "arn": "arn:aws:iam::844333597536:role/tf-iam-role-replication-12345", + "assume_role_policy": "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"s3.amazonaws.com\"}}],\"Version\":\"2012-10-17\"}", + "create_date": "2024-01-24T10:55:42Z", + "description": "", + "force_detach_policies": false, + "id": "tf-iam-role-replication-12345", + "inline_policy": [], + "managed_policy_arns": [ + "arn:aws:iam::844333597536:policy/tf-iam-role-policy-replication-12345" + ], + "max_session_duration": 3600, + "name": "tf-iam-role-replication-12345", + "name_prefix": "", + "path": "/", + "permissions_boundary": "", + "tags": {}, + "tags_all": {}, + "unique_id": "AROA4JFRUINQIGIEP43IO" + }, + "sensitive_values": { + "inline_policy": [], + "managed_policy_arns": [ + false + ], + "tags": {}, + "tags_all": {} + }, + "depends_on": [ + "data.aws_iam_policy_document.assume_role" + ] + }, + { + "address": "aws_iam_role_policy_attachment.replication", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "replication", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "id": "tf-iam-role-replication-12345-20240124105702515800000001", + "policy_arn": "arn:aws:iam::844333597536:policy/tf-iam-role-policy-replication-12345", + "role": "tf-iam-role-replication-12345" + }, + "sensitive_values": {}, + "depends_on": [ + "aws_iam_policy.replication", + "aws_iam_role.replication", + "aws_s3_bucket.destination", + "aws_s3_bucket.source", + "data.aws_iam_policy_document.assume_role", + "data.aws_iam_policy_document.replication" + ] + }, + { + "address": "aws_s3_bucket.destination", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "destination", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "acceleration_status": "", + "acl": null, + "arn": "arn:aws:s3:::tf-test-bucket-destination-nitish-12345", + "bucket": "tf-test-bucket-destination-nitish-12345", + "bucket_domain_name": "tf-test-bucket-destination-nitish-12345.s3.amazonaws.com", + "bucket_prefix": "", + "bucket_regional_domain_name": "tf-test-bucket-destination-nitish-12345.s3.eu-west-1.amazonaws.com", + "cors_rule": [], + "force_destroy": false, + "grant": [ + { + "id": "62ea66bd2e8f7e76e4fb466e942a41389d6057fcc90d732feaac373bb0d0a7a5", + "permissions": [ + "FULL_CONTROL" + ], + "type": "CanonicalUser", + "uri": "" + } + ], + "hosted_zone_id": "Z1BKCTXD74EZPE", + "id": "tf-test-bucket-destination-nitish-12345", + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "object_lock_enabled": false, + "policy": "", + "region": "eu-west-1", + "replication_configuration": [], + "request_payer": "BucketOwner", + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + { + "kms_master_key_id": "", + "sse_algorithm": "AES256" + } + ], + "bucket_key_enabled": false + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "timeouts": null, + "versioning": [ + { + "enabled": true, + "mfa_delete": false + } + ], + "website": [], + "website_domain": null, + "website_endpoint": null + }, + "sensitive_values": { + "cors_rule": [], + "grant": [ + { + "permissions": [ + false + ] + } + ], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + {} + ] + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "versioning": [ + {} + ], + "website": [] + } + }, + { + "address": "aws_s3_bucket.source", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "source", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "acceleration_status": "", + "acl": null, + "arn": "arn:aws:s3:::tf-test-bucket-source-nitish-12345", + "bucket": "tf-test-bucket-source-nitish-12345", + "bucket_domain_name": "tf-test-bucket-source-nitish-12345.s3.amazonaws.com", + "bucket_prefix": "", + "bucket_regional_domain_name": "tf-test-bucket-source-nitish-12345.s3.eu-central-1.amazonaws.com", + "cors_rule": [], + "force_destroy": false, + "grant": [ + { + "id": "62ea66bd2e8f7e76e4fb466e942a41389d6057fcc90d732feaac373bb0d0a7a5", + "permissions": [ + "FULL_CONTROL" + ], + "type": "CanonicalUser", + "uri": "" + } + ], + "hosted_zone_id": "Z21DNDUVLTQW6Q", + "id": "tf-test-bucket-source-nitish-12345", + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "object_lock_enabled": false, + "policy": "", + "region": "eu-central-1", + "replication_configuration": [], + "request_payer": "BucketOwner", + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + { + "kms_master_key_id": "", + "sse_algorithm": "AES256" + } + ], + "bucket_key_enabled": false + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "timeouts": null, + "versioning": [ + { + "enabled": true, + "mfa_delete": false + } + ], + "website": [], + "website_domain": null, + "website_endpoint": null + }, + "sensitive_values": { + "cors_rule": [], + "grant": [ + { + "permissions": [ + false + ] + } + ], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + {} + ] + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "versioning": [ + {} + ], + "website": [] + } + }, + { + "address": "aws_s3_bucket_versioning.destination", + "mode": "managed", + "type": "aws_s3_bucket_versioning", + "name": "destination", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "bucket": "tf-test-bucket-destination-nitish-12345", + "expected_bucket_owner": "", + "id": "tf-test-bucket-destination-nitish-12345", + "mfa": null, + "versioning_configuration": [ + { + "mfa_delete": "", + "status": "Enabled" + } + ] + }, + "sensitive_values": { + "versioning_configuration": [ + {} + ] + }, + "depends_on": [ + "aws_s3_bucket.destination" + ] + }, + { + "address": "aws_s3_bucket_versioning.source", + "mode": "managed", + "type": "aws_s3_bucket_versioning", + "name": "source", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "bucket": "tf-test-bucket-source-nitish-12345", + "expected_bucket_owner": "", + "id": "tf-test-bucket-source-nitish-12345", + "mfa": null, + "versioning_configuration": [ + { + "mfa_delete": "", + "status": "Enabled" + } + ] + }, + "sensitive_values": { + "versioning_configuration": [ + {} + ] + }, + "depends_on": [ + "aws_s3_bucket.source" + ] + } + ] + } + } + }, + "configuration": { + "provider_config": { + "aws": { + "name": "aws", + "full_name": "registry.terraform.io/hashicorp/aws", + "expressions": { + "access_key": { + "constant_value": "ASIA4JFRUINQJ3PM62E4" + }, + "region": { + "constant_value": "eu-west-1" + }, + "secret_key": { + "constant_value": "cAt33vVIa4drH47QG+ayoX1QUyPHEVYb6rVM8fMO" + }, + "token": { + "constant_value": "IQoJb3JpZ2luX2VjELv//////////wEaCXVzLWVhc3QtMiJIMEYCIQDa7mH3BbBgWAN8uIqvByWjIkqE2NgeRlp0wv5lyUqdGAIhALq8kuxs9gem1qyy31iAVNWE/TmqbqoGELcjGRSjzal/Ko4DCHQQAxoMODQ0MzMzNTk3NTM2IgwGJcG4RNOyfF5NjGYq6wIUKagZTTHC1L26O6UYmvtDiMgOZbBUmlwyGu/hx1Ek+tkuFuWCpl6h6ny4t1gMhxhAlkej0+YPLREPr4kkgN32+2ft/dBfPo5zqr0N9QbsijPUL5dvsOUwogjyDsPkrDMsifuWpQy7Xou7FtHlUllSUoofQkBGJZp9d1s1PXGIyhPGr7uOlvAZT0Vp1XgCqdDNKfdi1K6bqqoRJA5vKXnnzlUJbGOhV84d+1jpniT66jyjFsSODuHMK0Cw5jW8Mo2uY2AggTmpObT+NWlQsM7p6hPrx8ue5gM97TDux0AXgjHCeiXyRk2ISzhbWT0cbJuX8FCdxDj7LyUcmFocMYz1HmRjsbq2PicfolqxbtadXo66Pf3+kJLrv4y68qp29zlNsNAJ+MiQBh/W1uUCH+r1gXDaNuntNeG0WPUxBPuHoMmAoT/9W6nzhuedG7enQu6g14pGknpQMpc6Bv5ChGPJHQhCZFv9ZllVLVMw0tbDrQY6pQExYg4kz2d3VqBXU2RUulqe7zx56vbA7cIGp26i9KQs0Pt+6XQdOqK7VIJh5P0JA0/QZar6XqbNtaWs9AAmknUwOfuYeej8gJS8Xszf6QOgVSYtO0IuxOtO9AHGauibsdesN+uRAib0uLMbL7DcPC2AV8OOX5HxvD1RDu2qC+trtZOb3KhZ2nkcdf2HaAdK9lqy/KiJFXyvhUBpnLTQ0i6v6rLCBNs=" + } + } + }, + "aws.central": { + "name": "aws", + "full_name": "registry.terraform.io/hashicorp/aws", + "alias": "central", + "expressions": { + "access_key": { + "constant_value": "ASIA4JFRUINQJ3PM62E4" + }, + "region": { + "constant_value": "eu-central-1" + }, + "secret_key": { + "constant_value": "cAt33vVIa4drH47QG+ayoX1QUyPHEVYb6rVM8fMO" + }, + "token": { + "constant_value": "IQoJb3JpZ2luX2VjELv//////////wEaCXVzLWVhc3QtMiJIMEYCIQDa7mH3BbBgWAN8uIqvByWjIkqE2NgeRlp0wv5lyUqdGAIhALq8kuxs9gem1qyy31iAVNWE/TmqbqoGELcjGRSjzal/Ko4DCHQQAxoMODQ0MzMzNTk3NTM2IgwGJcG4RNOyfF5NjGYq6wIUKagZTTHC1L26O6UYmvtDiMgOZbBUmlwyGu/hx1Ek+tkuFuWCpl6h6ny4t1gMhxhAlkej0+YPLREPr4kkgN32+2ft/dBfPo5zqr0N9QbsijPUL5dvsOUwogjyDsPkrDMsifuWpQy7Xou7FtHlUllSUoofQkBGJZp9d1s1PXGIyhPGr7uOlvAZT0Vp1XgCqdDNKfdi1K6bqqoRJA5vKXnnzlUJbGOhV84d+1jpniT66jyjFsSODuHMK0Cw5jW8Mo2uY2AggTmpObT+NWlQsM7p6hPrx8ue5gM97TDux0AXgjHCeiXyRk2ISzhbWT0cbJuX8FCdxDj7LyUcmFocMYz1HmRjsbq2PicfolqxbtadXo66Pf3+kJLrv4y68qp29zlNsNAJ+MiQBh/W1uUCH+r1gXDaNuntNeG0WPUxBPuHoMmAoT/9W6nzhuedG7enQu6g14pGknpQMpc6Bv5ChGPJHQhCZFv9ZllVLVMw0tbDrQY6pQExYg4kz2d3VqBXU2RUulqe7zx56vbA7cIGp26i9KQs0Pt+6XQdOqK7VIJh5P0JA0/QZar6XqbNtaWs9AAmknUwOfuYeej8gJS8Xszf6QOgVSYtO0IuxOtO9AHGauibsdesN+uRAib0uLMbL7DcPC2AV8OOX5HxvD1RDu2qC+trtZOb3KhZ2nkcdf2HaAdK9lqy/KiJFXyvhUBpnLTQ0i6v6rLCBNs=" + } + } + } + }, + "root_module": { + "resources": [ + { + "address": "aws_iam_policy.replication", + "mode": "managed", + "type": "aws_iam_policy", + "name": "replication", + "provider_config_key": "aws", + "expressions": { + "name": { + "constant_value": "tf-iam-role-policy-replication-12345" + }, + "policy": { + "references": [ + "data.aws_iam_policy_document.replication.json", + "data.aws_iam_policy_document.replication" + ] + } + }, + "schema_version": 0 + }, + { + "address": "aws_iam_role.replication", + "mode": "managed", + "type": "aws_iam_role", + "name": "replication", + "provider_config_key": "aws", + "expressions": { + "assume_role_policy": { + "references": [ + "data.aws_iam_policy_document.assume_role.json", + "data.aws_iam_policy_document.assume_role" + ] + }, + "name": { + "constant_value": "tf-iam-role-replication-12345" + } + }, + "schema_version": 0 + }, + { + "address": "aws_iam_role_policy_attachment.replication", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "replication", + "provider_config_key": "aws", + "expressions": { + "policy_arn": { + "references": [ + "aws_iam_policy.replication.arn", + "aws_iam_policy.replication" + ] + }, + "role": { + "references": [ + "aws_iam_role.replication.name", + "aws_iam_role.replication" + ] + } + }, + "schema_version": 0 + }, + { + "address": "aws_s3_bucket.destination", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "destination", + "provider_config_key": "aws", + "expressions": { + "bucket": { + "constant_value": "tf-test-bucket-destination-nitish-12345" + } + }, + "schema_version": 0 + }, + { + "address": "aws_s3_bucket.source", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "source", + "provider_config_key": "aws.central", + "expressions": { + "bucket": { + "constant_value": "tf-test-bucket-source-nitish-12345" + } + }, + "schema_version": 0 + }, + { + "address": "aws_s3_bucket_replication_configuration.replication", + "mode": "managed", + "type": "aws_s3_bucket_replication_configuration", + "name": "replication", + "provider_config_key": "aws.central", + "expressions": { + "bucket": { + "references": [ + "aws_s3_bucket.source.id", + "aws_s3_bucket.source" + ] + }, + "role": { + "references": [ + "aws_iam_role.replication.arn", + "aws_iam_role.replication" + ] + }, + "rule": [ + { + "delete_marker_replication": [ + { + "status": { + "constant_value": "Enabled" + } + } + ], + "destination": [ + { + "bucket": { + "references": [ + "aws_s3_bucket.destination.arn", + "aws_s3_bucket.destination" + ] + }, + "storage_class": { + "constant_value": "STANDARD" + } + } + ], + "filter": [ + { + "prefix": { + "constant_value": "foo" + } + } + ], + "id": { + "constant_value": "foobar" + }, + "status": { + "constant_value": "Enabled" + } + } + ] + }, + "schema_version": 0, + "depends_on": [ + "aws_s3_bucket_versioning.source" + ] + }, + { + "address": "aws_s3_bucket_versioning.destination", + "mode": "managed", + "type": "aws_s3_bucket_versioning", + "name": "destination", + "provider_config_key": "aws", + "expressions": { + "bucket": { + "references": [ + "aws_s3_bucket.destination.id", + "aws_s3_bucket.destination" + ] + }, + "versioning_configuration": [ + { + "status": { + "constant_value": "Enabled" + } + } + ] + }, + "schema_version": 0 + }, + { + "address": "aws_s3_bucket_versioning.source", + "mode": "managed", + "type": "aws_s3_bucket_versioning", + "name": "source", + "provider_config_key": "aws.central", + "expressions": { + "bucket": { + "references": [ + "aws_s3_bucket.source.id", + "aws_s3_bucket.source" + ] + }, + "versioning_configuration": [ + { + "status": { + "constant_value": "Enabled" + } + } + ] + }, + "schema_version": 0 + }, + { + "address": "data.aws_iam_policy_document.assume_role", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "assume_role", + "provider_config_key": "aws", + "expressions": { + "statement": [ + { + "actions": { + "constant_value": [ + "sts:AssumeRole" + ] + }, + "effect": { + "constant_value": "Allow" + }, + "principals": [ + { + "identifiers": { + "constant_value": [ + "s3.amazonaws.com" + ] + }, + "type": { + "constant_value": "Service" + } + } + ] + } + ] + }, + "schema_version": 0 + }, + { + "address": "data.aws_iam_policy_document.replication", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "replication", + "provider_config_key": "aws", + "expressions": { + "statement": [ + { + "actions": { + "constant_value": [ + "s3:GetReplicationConfiguration", + "s3:ListBucket" + ] + }, + "effect": { + "constant_value": "Allow" + }, + "resources": { + "references": [ + "aws_s3_bucket.source.arn", + "aws_s3_bucket.source" + ] + } + }, + { + "actions": { + "constant_value": [ + "s3:GetObjectVersionForReplication", + "s3:GetObjectVersionAcl", + "s3:GetObjectVersionTagging" + ] + }, + "effect": { + "constant_value": "Allow" + }, + "resources": { + "references": [ + "aws_s3_bucket.source.arn", + "aws_s3_bucket.source" + ] + } + }, + { + "actions": { + "constant_value": [ + "s3:ReplicateObject", + "s3:ReplicateTags" + ] + }, + "effect": { + "constant_value": "Allow" + }, + "resources": { + "references": [ + "aws_s3_bucket.destination.arn", + "aws_s3_bucket.destination" + ] + } + } + ] + }, + "schema_version": 0 + } + ] + } + }, + "relevant_attributes": [ + { + "resource": "aws_iam_role.replication", + "attribute": [ + "arn" + ] + }, + { + "resource": "aws_s3_bucket.source", + "attribute": [ + "id" + ] + }, + { + "resource": "aws_s3_bucket.destination", + "attribute": [ + "arn" + ] + } + ], + "timestamp": "2024-01-24T11:08:21Z", + "errored": false +} diff --git a/terraform-best-practices/aws/s3/enable-s3-cross-region-replication/test/good-terraform.tf b/terraform-best-practices/aws/s3/enable-s3-cross-region-replication/test/good-terraform.tf new file mode 100644 index 00000000..90bfbdf0 --- /dev/null +++ b/terraform-best-practices/aws/s3/enable-s3-cross-region-replication/test/good-terraform.tf @@ -0,0 +1,125 @@ +provider "aws" { + region = "eu-west-1" +} + +provider "aws" { + alias = "central" + region = "eu-central-1" +} + +data "aws_iam_policy_document" "assume_role" { + statement { + effect = "Allow" + + principals { + type = "Service" + identifiers = ["s3.amazonaws.com"] + } + + actions = ["sts:AssumeRole"] + } +} + +resource "aws_iam_role" "replication" { + name = "tf-iam-role-replication-12345" + assume_role_policy = data.aws_iam_policy_document.assume_role.json +} + +data "aws_iam_policy_document" "replication" { + statement { + effect = "Allow" + + actions = [ + "s3:GetReplicationConfiguration", + "s3:ListBucket", + ] + + resources = [aws_s3_bucket.source.arn] + } + + statement { + effect = "Allow" + + actions = [ + "s3:GetObjectVersionForReplication", + "s3:GetObjectVersionAcl", + "s3:GetObjectVersionTagging", + ] + + resources = ["${aws_s3_bucket.source.arn}/*"] + } + + statement { + effect = "Allow" + + actions = [ + "s3:ReplicateObject", + "s3:ReplicateTags", + ] + + resources = ["${aws_s3_bucket.destination.arn}/*"] + } +} + +resource "aws_iam_policy" "replication" { + name = "tf-iam-role-policy-replication-12345" + policy = data.aws_iam_policy_document.replication.json +} + +resource "aws_iam_role_policy_attachment" "replication" { + role = aws_iam_role.replication.name + policy_arn = aws_iam_policy.replication.arn +} + +resource "aws_s3_bucket" "destination" { + bucket = "tf-test-bucket-destination-nitish-12345" +} + +resource "aws_s3_bucket_versioning" "destination" { + bucket = aws_s3_bucket.destination.id + versioning_configuration { + status = "Enabled" + } +} + +resource "aws_s3_bucket" "source" { + provider = aws.central + bucket = "tf-test-bucket-source-nitish-12345" +} + +resource "aws_s3_bucket_versioning" "source" { + provider = aws.central + + bucket = aws_s3_bucket.source.id + versioning_configuration { + status = "Enabled" + } +} + +resource "aws_s3_bucket_replication_configuration" "replication" { + provider = aws.central + # Must have bucket versioning enabled first + depends_on = [aws_s3_bucket_versioning.source] + + role = aws_iam_role.replication.arn + bucket = aws_s3_bucket.source.id + + rule { + id = "foobar" + + filter { + prefix = "foo" + } + + status = "Enabled" + + destination { + bucket = aws_s3_bucket.destination.arn + storage_class = "STANDARD" + } + + delete_marker_replication { + status = "Enabled" + } + } +} \ No newline at end of file diff --git a/terraform-best-practices/aws/s3/public-access-block/README.md b/terraform-best-practices/aws/s3/public-access-block/README.md new file mode 100644 index 00000000..a87fc739 --- /dev/null +++ b/terraform-best-practices/aws/s3/public-access-block/README.md @@ -0,0 +1,79 @@ +Amazon S3 Block Public Access provides settings for access points, buckets, and accounts to help you manage public access to Amazon S3 resources. By default, new buckets, access points, and objects do not allow public access. + +In order to configure public block access settings for your S3 buckets, read [here](https://docs.aws.amazon.com/AmazonS3/latest/userguide/configuring-block-public-access-bucket.html) + +S3 Block Public Access provides four settings. You can apply these settings in any combination to individual access points, buckets, or entire AWS accounts. If you apply a setting to an account, it applies to all buckets and access points that are owned by that account. Similarly, if you apply a setting to a bucket, it applies to all access points associated with that bucket. + +The four settings mentioned above are: + +1. *BlockPublicAcls*: When this is turned on, it prevents anyone from making data in a bucket public by using Access Control Lists (ACLs). ACLs are like a list of who can and cannot access stuff in the bucket. + +2. *IgnorePublicAcls*: If this is enabled, it means the system ignores any public access settings set by Access Control Lists (ACLs). In simpler terms, it doesn't pay attention to certain rules that might make data public. + +3. *BlockPublicPolicy*: This setting stops people from making data public by using bucket policies. Bucket policies are like rules you set for who can access your bucket and how. When you enable this, it prevents public access through these policies. + +4. *RestrictPublicBuckets*: Turning this on limits public access to buckets. It means you're putting restrictions on making your buckets and the data inside them public. This helps in adding an extra layer of control to prevent accidental exposure of your data to the public. + +A brief details about these options have been mentioned in the [AWS Documentation](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html). + +Now, if you'd like to disable the public access block for your S3 bucket, you need to make sure that all the above four settings are enabled. Terraform provides you the `aws_s3_bucket_public_access_block` resource to configure these settings + +``` +resource "aws_s3_bucket_public_access_block" "example" { + bucket = aws_s3_bucket.example.id + + block_public_acls = true + block_public_policy = true + ignore_public_acls = true + restrict_public_buckets = true +} +``` + +**It is important to note that all the argument should be set to *true* in order to disable the public access control. If any one of the argument is set to false, there will be public access configured based on the above settings defined.** + +If you'd like to learn more about this, head over to the [Argument Reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block#argument-reference) for public access block in Terraform. + +In order to test this policy, use the following commands: + +1. Initialise Terraform in your working directory + ``` + terraform init + ``` + +2. Create a binary of your terraform plan + ``` + terraform plan -out tfplan.binary + ``` + +3. Convert the executable binary into JSON Payload + ``` + terraform show -json tfplan.binary | jq > payload.json + ``` + +4. Test the policy using `kyverno-json` command + ``` + kyverno-json scan --payload payload.json --policy policy.yaml + ``` + + Since you've set all the fields for S3 public access block in your Terraform file to *true*, the policy will give you *Passing checks*. + +**Failing Scenario:** If you set any of the argument in your Terraform S3 public access block to false, the policy will be failed. Why? Because you are trying to enable the public access block. A Terraform S3 public access block that could give failing scenario is given below: + +``` +resource "aws_s3_bucket_public_access_block" "example" { + bucket = aws_s3_bucket.example.id + + block_public_acls = false + block_public_policy = true + ignore_public_acls = true + restrict_public_buckets = false +} +``` + +Ideally, you can test your policy for the *bad-payload.json* that is present at `./aws/s3/public-access-block/policy-test` using the following command from root: + +``` +kyverno-json scan --payload ./aws/s3/public-access-block/policy-test/bad-payload.json --policy policy.yaml +``` + +There is also `bad-s3.tf` file provided under `policy-test` directory that you can use to build your payload and use in the above command as an argument to `--policy` flag. \ No newline at end of file diff --git a/terraform-best-practices/aws/s3/public-access-block/test/bad-payload.json b/terraform-best-practices/aws/s3/public-access-block/test/bad-payload.json new file mode 100644 index 00000000..44289288 --- /dev/null +++ b/terraform-best-practices/aws/s3/public-access-block/test/bad-payload.json @@ -0,0 +1,214 @@ +{ + "format_version": "1.2", + "terraform_version": "1.6.6", + "planned_values": { + "root_module": { + "resources": [ + { + "address": "aws_s3_bucket.example", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "bucket": "tf-bucket-demo", + "force_destroy": false, + "tags": null, + "timeouts": null + }, + "sensitive_values": { + "cors_rule": [], + "grant": [], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [], + "tags_all": {}, + "versioning": [], + "website": [] + } + }, + { + "address": "aws_s3_bucket_public_access_block.example", + "mode": "managed", + "type": "aws_s3_bucket_public_access_block", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "block_public_acls": true, + "block_public_policy": true, + "ignore_public_acls": true, + "restrict_public_buckets": true + }, + "sensitive_values": {} + } + ] + } + }, + "resource_changes": [ + { + "address": "aws_s3_bucket.example", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "bucket": "tf-bucket-demo", + "force_destroy": false, + "tags": null, + "timeouts": null + }, + "after_unknown": { + "acceleration_status": true, + "acl": true, + "arn": true, + "bucket_domain_name": true, + "bucket_prefix": true, + "bucket_regional_domain_name": true, + "cors_rule": true, + "grant": true, + "hosted_zone_id": true, + "id": true, + "lifecycle_rule": true, + "logging": true, + "object_lock_configuration": true, + "object_lock_enabled": true, + "policy": true, + "region": true, + "replication_configuration": true, + "request_payer": true, + "server_side_encryption_configuration": true, + "tags_all": true, + "versioning": true, + "website": true, + "website_domain": true, + "website_endpoint": true + }, + "before_sensitive": false, + "after_sensitive": { + "cors_rule": [], + "grant": [], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [], + "tags_all": {}, + "versioning": [], + "website": [] + } + } + }, + { + "address": "aws_s3_bucket_public_access_block.example", + "mode": "managed", + "type": "aws_s3_bucket_public_access_block", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "block_public_acls": true, + "block_public_policy": true, + "ignore_public_acls": true, + "restrict_public_buckets": true + }, + "after_unknown": { + "bucket": true, + "id": true + }, + "before_sensitive": false, + "after_sensitive": {} + } + } + ], + "configuration": { + "provider_config": { + "aws": { + "name": "aws", + "full_name": "registry.terraform.io/hashicorp/aws", + "version_constraint": "~> 4.16", + "expressions": { + "access_key": { + "constant_value": "ASIA4JFRUINQDCTDYKWH" + }, + "region": { + "constant_value": "us-west-2" + }, + "secret_key": { + "constant_value": "4H6vXDA0pQvXRbtzIoeoAnZXxjyzGgk0ihQy7iys" + }, + "token": { + "constant_value": "IQoJb3JpZ2luX2VjEJ///////////wEaCXVzLWVhc3QtMiJHMEUCIQDpkKk+aJuZ4dbZXvPjAPJvuTgXCMCn9fNomdk6G+bwiwIgUtsqh4Mv6zOaCSaok/o9ab0uzMMi0FNEiXMr55klH54qjgMISBADGgw4NDQzMzM1OTc1MzYiDGcVpGVO8xUbqLq1AyrrAreOpj/eNXSL0Qo6PoulEWnDsepBpRu5k8XB8bIG7uAFIZY02aub+wjBYc+3t1vdbAAA18Pljb3DlP0fiqa1RPmWPkQBUnYDStmvhYm+oL4MU7TFS2F0QAHXoeuPSlr7RBnvcCv8q9t4hloloT5QgWquh5fNgMF5mjifYCQXOQOjINxk/DC01SfvHRZeNQkGQoHMnbFH+FzT93KmAyDOj+Kor1DGou7Fzg5OxMMZwF9NGj6Ihjt3Rn80KmG7PIAdWmpzHMi0y9LV42AeSM2hHrB535gAjlLvtdj94WDyDbfEVv+JC3cBlHYkiPptFG75j+9wdK/EVlWHbvygGrzVuOvB8HbRZ//ik7yIjpNky5GJ49cnyoIJ+b07lS8EFFSePXizTSYfs7MSvMiqlT9eT1DtzeHCIblDyAGAudZmZJyXvZcPowjncIgemPMJ5XW5NgJR8+YSehskWS9T0Ib6KrDY8cMvlI60xH+nvzDRp4WtBjqmAcCvVAUOS3mdT36GOZmLa/9lJvl0d12FtN72gQ8wPUDGFJD9J/PFHjQE8YjpPJY///lQC66N8s0fAxXvWrNjztu1FxMKez9G8SWJfncCVrc0lL5bnQmSPtUHb1vzL0RKht6ceSGSzqpNemEJWx4csm196wiFTr4JK/4abyUJ8DGo8lSID8qtEYSTf9t1i5QwlV27UvyBVWJHz7aWEHSfqlnrd3xHNXo=" + } + } + } + }, + "root_module": { + "resources": [ + { + "address": "aws_s3_bucket.example", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "example", + "provider_config_key": "aws", + "expressions": { + "bucket": { + "constant_value": "tf-bucket-demo" + } + }, + "schema_version": 0 + }, + { + "address": "aws_s3_bucket_public_access_block.example", + "mode": "managed", + "type": "aws_s3_bucket_public_access_block", + "name": "example", + "provider_config_key": "aws", + "expressions": { + "block_public_acls": { + "constant_value": true + }, + "block_public_policy": { + "constant_value": true + }, + "bucket": { + "references": [ + "aws_s3_bucket.example.id", + "aws_s3_bucket.example" + ] + }, + "ignore_public_acls": { + "constant_value": true + }, + "restrict_public_buckets": { + "constant_value": true + } + }, + "schema_version": 0 + } + ] + } + }, + "relevant_attributes": [ + { + "resource": "aws_s3_bucket.example", + "attribute": [ + "id" + ] + } + ], + "timestamp": "2024-01-12T15:00:06Z", + "errored": false +} diff --git a/terraform-best-practices/aws/s3/public-access-block/test/bad-terraform.tf b/terraform-best-practices/aws/s3/public-access-block/test/bad-terraform.tf new file mode 100644 index 00000000..a7f17290 --- /dev/null +++ b/terraform-best-practices/aws/s3/public-access-block/test/bad-terraform.tf @@ -0,0 +1,27 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 4.16" + } + } + + required_version = ">= 1.2.0" +} + +provider "aws" { + region = "us-west-2" +} + +resource "aws_s3_bucket" "test-bucket" { + bucket = "tf-bucket-demo" +} + +resource "aws_s3_bucket_public_access_block" "test-bucket" { + bucket = aws_s3_bucket.example.id + + block_public_acls = false + block_public_policy = true + ignore_public_acls = false + restrict_public_buckets = true +} diff --git a/terraform-best-practices/aws/s3/public-access-block/test/good-payload.json b/terraform-best-practices/aws/s3/public-access-block/test/good-payload.json new file mode 100644 index 00000000..dfc32078 --- /dev/null +++ b/terraform-best-practices/aws/s3/public-access-block/test/good-payload.json @@ -0,0 +1,214 @@ +{ + "format_version": "1.2", + "terraform_version": "1.6.6", + "planned_values": { + "root_module": { + "resources": [ + { + "address": "aws_s3_bucket.example", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "bucket": "test-bucket", + "force_destroy": false, + "tags": null, + "timeouts": null + }, + "sensitive_values": { + "cors_rule": [], + "grant": [], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [], + "tags_all": {}, + "versioning": [], + "website": [] + } + }, + { + "address": "aws_s3_bucket_public_access_block.example", + "mode": "managed", + "type": "aws_s3_bucket_public_access_block", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "block_public_acls": true, + "block_public_policy": true, + "ignore_public_acls": true, + "restrict_public_buckets": true + }, + "sensitive_values": {} + } + ] + } + }, + "resource_changes": [ + { + "address": "aws_s3_bucket.example", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "bucket": "test-bucket", + "force_destroy": false, + "tags": null, + "timeouts": null + }, + "after_unknown": { + "acceleration_status": true, + "acl": true, + "arn": true, + "bucket_domain_name": true, + "bucket_prefix": true, + "bucket_regional_domain_name": true, + "cors_rule": true, + "grant": true, + "hosted_zone_id": true, + "id": true, + "lifecycle_rule": true, + "logging": true, + "object_lock_configuration": true, + "object_lock_enabled": true, + "policy": true, + "region": true, + "replication_configuration": true, + "request_payer": true, + "server_side_encryption_configuration": true, + "tags_all": true, + "versioning": true, + "website": true, + "website_domain": true, + "website_endpoint": true + }, + "before_sensitive": false, + "after_sensitive": { + "cors_rule": [], + "grant": [], + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "replication_configuration": [], + "server_side_encryption_configuration": [], + "tags_all": {}, + "versioning": [], + "website": [] + } + } + }, + { + "address": "aws_s3_bucket_public_access_block.example", + "mode": "managed", + "type": "aws_s3_bucket_public_access_block", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "block_public_acls": true, + "block_public_policy": true, + "ignore_public_acls": true, + "restrict_public_buckets": true + }, + "after_unknown": { + "bucket": true, + "id": true + }, + "before_sensitive": false, + "after_sensitive": {} + } + } + ], + "configuration": { + "provider_config": { + "aws": { + "name": "aws", + "full_name": "registry.terraform.io/hashicorp/aws", + "version_constraint": "~> 4.16", + "expressions": { + "access_key": { + "constant_value": "ASIA4JFRUINQMYX7MG4U" + }, + "region": { + "constant_value": "us-west-2" + }, + "secret_key": { + "constant_value": "fZv4C1zNWvgnLK+Cy+5RjXIX2fylhK9zc7z/3WZX" + }, + "token": { + "constant_value": "IQoJb3JpZ2luX2VjEHEaCXVzLWVhc3QtMiJHMEUCIAie72DeRpkvRfn3tFxiIS3Kcg4+44V/ZTD2s+N+q6MeAiEAvAud8vTFBtMz6Q2ZBpmK8FHXRZkV/sUWT1jRu2But/kqjgMIGxADGgw4NDQzMzM1OTc1MzYiDK7+0h14dNYSD4RfkSrrAn2FCPZyAJl3WyZiCiOuGDlT8xa+5v1gdLUwoN7lcerInp2Lhlr2l6wPFnh9DWeCeJBOBbXl6MXvrtsMtWJtlMqFpwG3tZ6xfEIQHCMv2mkska/WcBKtZklOpbNjuP2SMz9UgDCXuC68Mg+47g/F9kyl4aGWE18gGiC6EV6aLgKSzvTQJwGvUeghx93PYNmNeGjGlJkuLW/NtwjU1zbZ7Vpk1wE8uCz71f+kQQcuBD4jpzqJ59BjdnjUzctoo3d/9ZuzW8rNdVohpysBIn4IDJ+1xNvTG/NlAvLtaWkClKkhZC55tmPOCutQN67vQXv53kEfWEdMZ2xqUKs0za/LIf49DG7gItVQLLSP+8XHcnLhNywMdI13LOCcz/74UO9R2fzsD+wn0ZPCgp1oOyM0e3REiF1YskWa3hMDkS69y3TUiJYu5TrZIqfOouMJXe5SMn0NNZACKwOhzPw7HeTbpOxNOcav7ls0ZPTGnzDipvusBjqmASs6RGpF1oK2zXRbsU26JsZV9EYx/Ij0J+fpRnYNzA2AGW4GbXnD1vnNDU8RI2LOujMb26NZmrCgbO3jm9JfmUfuU7Rt9cXNL0CwMAt54gU7sMz2pfd9GxkQvvTawNISq5Mry69i6x2w3tlDmzTQbUVOOCxjXyIMJ2G5C655JfKLAQlIbSmeFKJDAXrjPbXhAUAGnGCTMHvqpcPumgaOZLDSA6neRD4=" + } + } + } + }, + "root_module": { + "resources": [ + { + "address": "aws_s3_bucket.example", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "example", + "provider_config_key": "aws", + "expressions": { + "bucket": { + "constant_value": "test-bucket" + } + }, + "schema_version": 0 + }, + { + "address": "aws_s3_bucket_public_access_block.example", + "mode": "managed", + "type": "aws_s3_bucket_public_access_block", + "name": "example", + "provider_config_key": "aws", + "expressions": { + "block_public_acls": { + "constant_value": true + }, + "block_public_policy": { + "constant_value": true + }, + "bucket": { + "references": [ + "aws_s3_bucket.example.id", + "aws_s3_bucket.example" + ] + }, + "ignore_public_acls": { + "constant_value": true + }, + "restrict_public_buckets": { + "constant_value": true + } + }, + "schema_version": 0 + } + ] + } + }, + "relevant_attributes": [ + { + "resource": "aws_s3_bucket.example", + "attribute": [ + "id" + ] + } + ], + "timestamp": "2024-01-10T17:51:08Z", + "errored": false +} diff --git a/terraform-best-practices/aws/s3/public-access-block/test/good-terraform.tf b/terraform-best-practices/aws/s3/public-access-block/test/good-terraform.tf new file mode 100644 index 00000000..fdc0bcd8 --- /dev/null +++ b/terraform-best-practices/aws/s3/public-access-block/test/good-terraform.tf @@ -0,0 +1,27 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 4.16" + } + } + + required_version = ">= 1.2.0" +} + +provider "aws" { + region = "us-west-2" +} + +resource "aws_s3_bucket" "example" { + bucket = "test-bucket" +} + +resource "aws_s3_bucket_public_access_block" "example" { + bucket = aws_s3_bucket.example.id + + block_public_acls = true + block_public_policy = true + ignore_public_acls = true + restrict_public_buckets = true +} diff --git a/terraform-best-practices/aws/s3/public-access-block/validate-public-access-block.yaml b/terraform-best-practices/aws/s3/public-access-block/validate-public-access-block.yaml new file mode 100644 index 00000000..03958cbc --- /dev/null +++ b/terraform-best-practices/aws/s3/public-access-block/validate-public-access-block.yaml @@ -0,0 +1,39 @@ +apiVersion: json.kyverno.io/v1alpha1 +kind: ValidatingPolicy +metadata: + name: block-s3-public-access-setting + annotations: + policies.kyverno.io/title: block-s3-public-access-setting + policies.kyverno.io/category: AWS S3 Security Best Practices + policies.kyverno.io/severity: medium + policies.kyverno.io/description: >- + The Amazon S3 Block Public Access feature provides settings for access points, + buckets, and accounts to help you manage public access to Amazon S3 resources. + By default, new buckets, access points, and objects don't allow public access. + However, users can modify bucket policies, access point policies, or object + permissions to allow public access. S3 Block Public Access settings override + these policies and permissions so that you can limit public access to these resources. +spec: + rules: + - name: validate-block-s3-public-access-setting + match: + any: + - (planned_values.root_module.resources[?type=='aws_s3_bucket_public_access_block' || type=='aws_s3_bucket'] | length(@) > `0`): true + assert: + all: + - message: Block Public ACLs should be set to true + check: + ~.(planned_values.root_module.resources[?type=='aws_s3_bucket_public_access_block'].values): + block_public_acls: true + - message: Block Public Policy should be set to true + check: + ~.(planned_values.root_module.resources[?type=='aws_s3_bucket_public_access_block'].values): + block_public_policy: true + - message: Ignore Public ACLs should be set to true + check: + ~.(planned_values.root_module.resources[?type=='aws_s3_bucket_public_access_block'].values): + ignore_public_acls: true + - message: Restrict Public Buckets should be set to true + check: + ~.(planned_values.root_module.resources[?type=='aws_s3_bucket_public_access_block'].values): + restrict_public_buckets: true