{"id":22347745,"url":"https://github.com/wearetechnative/terraform-aws-s3","last_synced_at":"2026-03-19T22:29:06.924Z","repository":{"id":258505094,"uuid":"706804849","full_name":"wearetechnative/terraform-aws-s3","owner":"wearetechnative","description":"Standard S3 module that enforces KMS encryption. Use principal based policies to access this bucket if possible.","archived":false,"fork":false,"pushed_at":"2025-02-17T14:38:58.000Z","size":189,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-02-17T15:22:29.749Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wearetechnative.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-18T16:43:31.000Z","updated_at":"2025-02-17T14:39:01.000Z","dependencies_parsed_at":"2024-10-19T10:13:02.099Z","dependency_job_id":"1c80aaf5-d886-4c59-88b1-8f97ddd0d703","html_url":"https://github.com/wearetechnative/terraform-aws-s3","commit_stats":null,"previous_names":["wearetechnative/terraform-aws-s3"],"tags_count":0,"template":false,"template_full_name":"TechNative-B-V/terraform-aws-module-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wearetechnative%2Fterraform-aws-s3","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wearetechnative%2Fterraform-aws-s3/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wearetechnative%2Fterraform-aws-s3/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wearetechnative%2Fterraform-aws-s3/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wearetechnative","download_url":"https://codeload.github.com/wearetechnative/terraform-aws-s3/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245641317,"owners_count":20648637,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-04T10:10:43.172Z","updated_at":"2026-01-06T07:34:37.484Z","avatar_url":"https://github.com/wearetechnative.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Terraform AWS [S3] ![](https://img.shields.io/github/workflow/status/wearetechnative/terraform-aws-s3/tflint.yaml?branch=main\u0026style=plastic)\n\nStandard S3 module that enforces KMS encryption. Use principal based policies to access this bucket if possible.\n\nBasically there are two workflows:\n- Bucket is non-public: `var.name` and `var.kms_key_arn` are provided.\n- Bucket is public: `var.name` and `var.kms_key_arn` are provided and `var.use_sse-s3_encryption_instead_of_sse-kms` is `true` along with `var.public_read_access` is also `true`.\n\nUse `var.additional_tags` for any tagging purposes like backups.\n\nYou can externally attach resources such as aws_s3_bucket_cors_configuration \u0026 aws_s3_bucket_lifecycle_configuration as wrapping them only duplicates work and they cannot be generally applied.\n\nSetting any other parameter other than the flows above is generally against best practices. Best practices involve:\n- Always enable versioning.\n- Always enable KMS encryption. We use CMK when possible or SSE-S3 if not.\n- Disable ACLs completely.\n- Enable full bucket protection (public access block).\n\nThis module also creates an SSM parameter called \"/s3/${var.name}/id\" to allow e.g. CICD systems to fetch the bucket name since bucket names are globally unique and we use the Terraform autogenerated prefix to do this. This makes the bucket name non-predictable but the SSM parameter solves this.\n\n## How does it work\n\nBasic flows are explained above. More complex flows are wrapped in our other modules that stem from AWS requirements and limitations. They involve more complex scenarios that are not explained here but are required from other module purposes.\n\nSee [./example] for examples on the replication setups.\n\n\u003c!-- BEGIN_TF_DOCS --\u003e\n## Providers\n\n| Name | Version |\n|------|---------|\n| \u003ca name=\"provider_aws\"\u003e\u003c/a\u003e [aws](#provider\\_aws) | \u003e=4.8.0 |\n\n## Modules\n\n| Name | Source | Version |\n|------|--------|---------|\n| \u003ca name=\"module_replication_source\"\u003e\u003c/a\u003e [replication\\_source](#module\\_replication\\_source) | ./replication_source | n/a |\n| \u003ca name=\"module_replication_target\"\u003e\u003c/a\u003e [replication\\_target](#module\\_replication\\_target) | ./replication_target | n/a |\n\n## Resources\n\n| Name | Type |\n|------|------|\n| [aws_s3_bucket.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |\n| [aws_s3_bucket_lifecycle_configuration.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_lifecycle_configuration) | resource |\n| [aws_s3_bucket_ownership_controls.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_ownership_controls) | resource |\n| [aws_s3_bucket_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource |\n| [aws_s3_bucket_public_access_block.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource |\n| [aws_s3_bucket_server_side_encryption_configuration.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource |\n| [aws_s3_bucket_versioning.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning) | resource |\n| [aws_ssm_parameter.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter) | resource |\n| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |\n| [aws_iam_policy_document.deny_obsolete_tls](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |\n| [aws_iam_policy_document.deny_unencrypted_kms](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |\n| [aws_iam_policy_document.deny_unencrypted_objectaccess](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |\n| [aws_iam_policy_document.deny_unencrypted_sse](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |\n| [aws_iam_policy_document.dummy_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |\n| [aws_iam_policy_document.public_read_access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |\n| [aws_iam_policy_document.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |\n| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |\n\n## Inputs\n\n| Name | Description | Type | Default | Required |\n|------|-------------|------|---------|:--------:|\n| \u003ca name=\"input_additional_tags\"\u003e\u003c/a\u003e [additional\\_tags](#input\\_additional\\_tags) | Additional tags to be added to resources. | `map(string)` | `{}` | no |\n| \u003ca name=\"input_bucket_policy_addition\"\u003e\u003c/a\u003e [bucket\\_policy\\_addition](#input\\_bucket\\_policy\\_addition) | Optional TF Object that converts to policy JSON with jsonencode() to append to current bucket policy which forbids non-encrypted uploads by default. Set an `\u003cbucket\u003e` resource attribute to have it replaced by this module for you. | `any` | `null` | no |\n| \u003ca name=\"input_disable_encryption_enforcement\"\u003e\u003c/a\u003e [disable\\_encryption\\_enforcement](#input\\_disable\\_encryption\\_enforcement) | Internal use only. Buckets get a standard policy that prevents un-encrypted uploads or encryption schemes that are not the default encryption. Some services cannot work (Athena CUR) with this policy enabled. | `bool` | `false` | no |\n| \u003ca name=\"input_enable_acl\"\u003e\u003c/a\u003e [enable\\_acl](#input\\_enable\\_acl) | Internal use only. Enable ACL which is disabled by default. This is required in order to use the bucket for CloudFront S3 logging. | `bool` | `false` | no |\n| \u003ca name=\"input_enable_public_read_access\"\u003e\u003c/a\u003e [enable\\_public\\_read\\_access](#input\\_enable\\_public\\_read\\_access) | Enable public read access. | `bool` | `false` | no |\n| \u003ca name=\"input_kms_key_arn\"\u003e\u003c/a\u003e [kms\\_key\\_arn](#input\\_kms\\_key\\_arn) | KMS key to use for encrypting S3 bucket. | `string` | n/a | yes |\n| \u003ca name=\"input_lifecycle_configuration\"\u003e\u003c/a\u003e [lifecycle\\_configuration](#input\\_lifecycle\\_configuration) | Object Lifecycle rules configuration. | \u003cpre\u003emap(object({\u003cbr\u003e    status = string\u003cbr\u003e    bucket_prefix = string\u003cbr\u003e    transition = object({\u003cbr\u003e      storage_class = string\u003cbr\u003e      transition_days = number\u003cbr\u003e    })\u003cbr\u003e    expiration_days = number\u003cbr\u003e    noncurrent_version_expiration = object({\u003cbr\u003e        newer_noncurrent_versions = number\u003cbr\u003e        noncurrent_days = number\u003cbr\u003e    })\u003cbr\u003e    noncurrent_version_transition = object({\u003cbr\u003e        newer_noncurrent_versions = number\u003cbr\u003e        noncurrent_days = number\u003cbr\u003e        storage_class = string\u003cbr\u003e    })\u003cbr\u003e  }))\u003c/pre\u003e | `{}` | no |\n| \u003ca name=\"input_name\"\u003e\u003c/a\u003e [name](#input\\_name) | Prefix name for S3 bucket. | `string` | n/a | yes |\n| \u003ca name=\"input_source_replication_configuration\"\u003e\u003c/a\u003e [source\\_replication\\_configuration](#input\\_source\\_replication\\_configuration) | Replication configuration using this bucket as source. The key of the map is used for naming. Use output.replication\\_target\\_bucket\\_arguments from any source buckets you want to replicate to in order to fill this argument if available. | \u003cpre\u003emap(object({\u003cbr\u003e    destination_bucket_arn  = string\u003cbr\u003e    destination_aws_account = string\u003cbr\u003e    destination_kms_key_arn = string\u003cbr\u003e  }))\u003c/pre\u003e | `{}` | no |\n| \u003ca name=\"input_target_replication_configuration\"\u003e\u003c/a\u003e [target\\_replication\\_configuration](#input\\_target\\_replication\\_configuration) | Replication configuration using this bucket as target. The key of the map is used for naming. Use output.replication\\_source\\_bucket\\_arguments from any source buckets you want to replicate to in order to fill this argument if available. | \u003cpre\u003emap(object({\u003cbr\u003e    source_role_arn = string\u003cbr\u003e  }))\u003c/pre\u003e | `{}` | no |\n| \u003ca name=\"input_use_fixed_name\"\u003e\u003c/a\u003e [use\\_fixed\\_name](#input\\_use\\_fixed\\_name) | Dont generate suffix after var.name to support already created S3 buckets. Not recommended to use this as this makes the S3 module non-portable. | `bool` | `false` | no |\n| \u003ca name=\"input_use_sse-s3_encryption_instead_of_sse-kms\"\u003e\u003c/a\u003e [use\\_sse-s3\\_encryption\\_instead\\_of\\_sse-kms](#input\\_use\\_sse-s3\\_encryption\\_instead\\_of\\_sse-kms) | Internal use only unless var.enable\\_public\\_read\\_access is true. Enforce SSE-S3 encryption instead of SSE-KMS. This is required if external services only support SSE-S3. This is also a requirement for public buckets. | `bool` | `false` | no |\n\n## Outputs\n\n| Name | Description |\n|------|-------------|\n| \u003ca name=\"output_kms_key_arn\"\u003e\u003c/a\u003e [kms\\_key\\_arn](#output\\_kms\\_key\\_arn) | n/a |\n| \u003ca name=\"output_replication_source_bucket_arguments\"\u003e\u003c/a\u003e [replication\\_source\\_bucket\\_arguments](#output\\_replication\\_source\\_bucket\\_arguments) | n/a |\n| \u003ca name=\"output_replication_target_bucket_arguments\"\u003e\u003c/a\u003e [replication\\_target\\_bucket\\_arguments](#output\\_replication\\_target\\_bucket\\_arguments) | n/a |\n| \u003ca name=\"output_s3_arn\"\u003e\u003c/a\u003e [s3\\_arn](#output\\_s3\\_arn) | n/a |\n| \u003ca name=\"output_s3_bucket_name\"\u003e\u003c/a\u003e [s3\\_bucket\\_name](#output\\_s3\\_bucket\\_name) | n/a |\n| \u003ca name=\"output_s3_name_parameter_arn\"\u003e\u003c/a\u003e [s3\\_name\\_parameter\\_arn](#output\\_s3\\_name\\_parameter\\_arn) | n/a |\n| \u003ca name=\"output_website_regional_domain\"\u003e\u003c/a\u003e [website\\_regional\\_domain](#output\\_website\\_regional\\_domain) | regional is better than global since global has redirects and is being deprecated |\n\u003c!-- END_TF_DOCS --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwearetechnative%2Fterraform-aws-s3","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwearetechnative%2Fterraform-aws-s3","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwearetechnative%2Fterraform-aws-s3/lists"}