# S3 bucket

Reference for provisioning an S3 bucket with sane defaults using the public [`terraform-aws-modules/s3-bucket`](https://registry.terraform.io/modules/terraform-aws-modules/s3-bucket/aws/latest){:target="_blank"} module.

## Configuration

The recommended location for this is in a `-data` directory (e.g. `my-app-data`), as per Golden Path conventions.

```hcl title="my-app-data/my-s3-bucket.tf"
module "bucket" {
  source  = "terraform-aws-modules/s3-bucket/aws"
  version = "~> 4.0"

  bucket = "my-bucket" # (1)!

  versioning = {
    enabled = true
  }

  server_side_encryption_configuration = {
    rule = {
      apply_server_side_encryption_by_default = {
        sse_algorithm = "AES256"
      }
    }
  }

  control_object_ownership = true

  attach_deny_insecure_transport_policy = true

  lifecycle_rule = [{
    id     = "expire-noncurrent-versions"
    status = "Enabled"
    noncurrent_version_expiration = {
      noncurrent_days = 90
    }
  }]
}
```

1. Include your team or environment in the name to avoid collisions, since S3 bucket names are globally unique across all AWS accounts.

## Settings

| Setting                                         | Value                  | Effect                                                                               |
| ----------------------------------------------- | ---------------------- | ------------------------------------------------------------------------------------ |
| `versioning.enabled`                            | `true`                 | Keeps previous object versions, so overwritten and deleted objects can be recovered. |
| `server_side_encryption_configuration`          | `AES256`               | Encrypts objects at rest with S3-managed keys.                                       |
| `control_object_ownership`                      | `true`                 | The bucket owner owns all objects; ACLs are disabled.                                |
| `attach_deny_insecure_transport_policy`         | `true`                 | Rejects requests that do not use TLS.                                                |
| `lifecycle_rule` (`expire-noncurrent-versions`) | `noncurrent_days = 90` | Expires noncurrent object versions 90 days after they become noncurrent.             |

## Outputs

The module exposes the underlying bucket attributes as outputs, referenced through `module.bucket`. Commonly used outputs:

| Output                                  | Description                                                                            |
| --------------------------------------- | -------------------------------------------------------------------------------------- |
| `s3_bucket_id`                          | The bucket name.                                                                       |
| `s3_bucket_arn`                         | The bucket ARN.                                                                        |
| `s3_bucket_bucket_regional_domain_name` | The bucket's region-specific domain name, e.g. `my-bucket.s3.eu-west-1.amazonaws.com`. |

To re-expose an output from your stack:

```hcl
output "regional_domain_name" {
  value = module.bucket.s3_bucket_bucket_regional_domain_name
}
```
