Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/terraform-aws-modules/terraform-aws-s3-bucket/llms.txt

Use this file to discover all available pages before exploring further.

Data in transit to and from S3 should always be encrypted using HTTPS. The module provides two IAM bucket policies that enforce secure transport:
  1. Deny insecure transport — rejects any S3 API call made over plain HTTP
  2. Require latest TLS — rejects connections using TLS versions older than 1.2
Both policies apply to all principals ("*") making requests against the bucket, including IAM users, roles, and AWS services.

Deny insecure transport

Setting attach_deny_insecure_transport_policy = true attaches a bucket policy that denies all s3:* actions when the request is not made over SSL. The policy condition checks aws:SecureTransport = false and denies the request:
data "aws_iam_policy_document" "deny_insecure_transport" {
  statement {
    sid    = "denyInsecureTransport"
    effect = "Deny"

    actions = [
      "s3:*",
    ]

    resources = [
      aws_s3_bucket.this[0].arn,
      "${aws_s3_bucket.this[0].arn}/*",
    ]

    principals {
      type        = "*"
      identifiers = ["*"]
    }

    condition {
      test     = "Bool"
      variable = "aws:SecureTransport"
      values = [
        "false"
      ]
    }
  }
}
This policy covers both the bucket itself and all objects within it.

Require latest TLS

Setting attach_require_latest_tls_policy = true attaches a bucket policy that denies s3:* actions when the TLS version used by the client is less than 1.2. The policy condition checks s3:TlsVersion < 1.2 and denies the request:
data "aws_iam_policy_document" "require_latest_tls" {
  statement {
    sid    = "denyOutdatedTLS"
    effect = "Deny"

    actions = [
      "s3:*",
    ]

    resources = [
      aws_s3_bucket.this[0].arn,
      "${aws_s3_bucket.this[0].arn}/*",
    ]

    principals {
      type        = "*"
      identifiers = ["*"]
    }

    condition {
      test     = "NumericLessThan"
      variable = "s3:TlsVersion"
      values = [
        "1.2"
      ]
    }
  }
}
Use both attach_deny_insecure_transport_policy and attach_require_latest_tls_policy together for complete in-transit security. The insecure transport policy blocks plain HTTP entirely, while the TLS version policy ensures that even HTTPS clients are running a modern protocol version. The module merges both into a single bucket policy document automatically.

Variables

VariableDefaultDescription
attach_deny_insecure_transport_policyfalseWhen true, attaches a bucket policy that denies all s3:* actions when aws:SecureTransport is false.
attach_require_latest_tls_policyfalseWhen true, attaches a bucket policy that denies all s3:* actions when s3:TlsVersion is less than 1.2.

Complete example

The following example creates a private bucket with both TLS enforcement policies enabled:
module "s3_bucket" {
  source = "terraform-aws-modules/s3-bucket/aws"

  bucket = "my-secure-bucket"

  # Enforce HTTPS-only access
  attach_deny_insecure_transport_policy = true

  # Require TLS 1.2 or higher
  attach_require_latest_tls_policy = true
}

How policies are applied

1

Policy documents are generated

When either attach_deny_insecure_transport_policy or attach_require_latest_tls_policy is true, Terraform generates the corresponding aws_iam_policy_document data sources.
2

Policies are merged into a combined document

Both policy documents are included in data.aws_iam_policy_document.combined, which merges all active bucket policies (TLS, log delivery, encryption, custom, etc.) into a single JSON document.
3

Policy is attached after the public access block

The aws_s3_bucket_policy resource depends on aws_s3_bucket_public_access_block to avoid race conditions that can occur when attaching a bucket policy at the same time as updating public access block settings.
These policies are IAM resource-based bucket policies. They apply to all requestors regardless of their identity — including AWS service principals, IAM roles, and cross-account principals — whenever they interact with the bucket via the S3 API.