Home

Awesome

AWS S3 bucket Terraform module

Terraform module which creates S3 bucket on AWS with all (or almost all) features provided by Terraform AWS provider.

SWUbanner

These features of S3 bucket configurations are supported:

Usage

Private bucket with versioning enabled

module "s3_bucket" {
  source = "terraform-aws-modules/s3-bucket/aws"

  bucket = "my-s3-bucket"
  acl    = "private"

  control_object_ownership = true
  object_ownership         = "ObjectWriter"

  versioning = {
    enabled = true
  }
}

Bucket with ELB access log delivery policy attached

module "s3_bucket_for_logs" {
  source = "terraform-aws-modules/s3-bucket/aws"

  bucket = "my-s3-bucket-for-logs"
  acl    = "log-delivery-write"

  # Allow deletion of non-empty bucket
  force_destroy = true

  control_object_ownership = true
  object_ownership         = "ObjectWriter"

  attach_elb_log_delivery_policy = true
}

Bucket with ALB/NLB access log delivery policy attached

module "s3_bucket_for_logs" {
  source = "terraform-aws-modules/s3-bucket/aws"

  bucket = "my-s3-bucket-for-logs"
  acl    = "log-delivery-write"

  # Allow deletion of non-empty bucket
  force_destroy = true

  control_object_ownership = true
  object_ownership         = "ObjectWriter"

  attach_elb_log_delivery_policy = true  # Required for ALB logs
  attach_lb_log_delivery_policy  = true  # Required for ALB/NLB logs
}

Conditional creation

Sometimes you need to have a way to create S3 resources conditionally but Terraform does not allow to use count inside module block, so the solution is to specify argument create_bucket.

# This S3 bucket will not be created
module "s3_bucket" {
  source = "terraform-aws-modules/s3-bucket/aws"

  create_bucket = false
  # ... omitted
}

Terragrunt and variable "..." { type = any }

There is a bug #1211 in Terragrunt related to the way how the variables of type any are passed to Terraform.

This module solves this issue by supporting jsonencode()-string in addition to the expected type (list or map).

In terragrunt.hcl you can write:

inputs = {
  bucket    = "foobar"            # `bucket` has type `string`, no need to jsonencode()
  cors_rule = jsonencode([...])   # `cors_rule` has type `any`, so `jsonencode()` is required
}

Module wrappers

Users of this Terraform module can create multiple similar resources by using for_each meta-argument within module block which became available in Terraform 0.13.

Users of Terragrunt can achieve similar results by using modules provided in the wrappers directory, if they prefer to reduce amount of configuration files.

Examples:

<!-- BEGIN_TF_DOCS -->

Requirements

NameVersion
<a name="requirement_terraform"></a> terraform>= 1.0
<a name="requirement_aws"></a> aws>= 5.70

Providers

NameVersion
<a name="provider_aws"></a> aws>= 5.70

Modules

No modules.

Resources

NameType
aws_s3_bucket.thisresource
aws_s3_bucket_accelerate_configuration.thisresource
aws_s3_bucket_acl.thisresource
aws_s3_bucket_analytics_configuration.thisresource
aws_s3_bucket_cors_configuration.thisresource
aws_s3_bucket_intelligent_tiering_configuration.thisresource
aws_s3_bucket_inventory.thisresource
aws_s3_bucket_lifecycle_configuration.thisresource
aws_s3_bucket_logging.thisresource
aws_s3_bucket_metric.thisresource
aws_s3_bucket_object_lock_configuration.thisresource
aws_s3_bucket_ownership_controls.thisresource
aws_s3_bucket_policy.thisresource
aws_s3_bucket_public_access_block.thisresource
aws_s3_bucket_replication_configuration.thisresource
aws_s3_bucket_request_payment_configuration.thisresource
aws_s3_bucket_server_side_encryption_configuration.thisresource
aws_s3_bucket_versioning.thisresource
aws_s3_bucket_website_configuration.thisresource
aws_caller_identity.currentdata source
aws_canonical_user_id.thisdata source
aws_iam_policy_document.access_log_deliverydata source
aws_iam_policy_document.combineddata source
aws_iam_policy_document.deny_incorrect_encryption_headersdata source
aws_iam_policy_document.deny_incorrect_kms_key_ssedata source
aws_iam_policy_document.deny_insecure_transportdata source
aws_iam_policy_document.deny_unencrypted_object_uploadsdata source
aws_iam_policy_document.elb_log_deliverydata source
aws_iam_policy_document.inventory_and_analytics_destination_policydata source
aws_iam_policy_document.lb_log_deliverydata source
aws_iam_policy_document.require_latest_tlsdata source
aws_partition.currentdata source
aws_region.currentdata source

Inputs

NameDescriptionTypeDefaultRequired
<a name="input_acceleration_status"></a> acceleration_status(Optional) Sets the accelerate configuration of an existing bucket. Can be Enabled or Suspended.stringnullno
<a name="input_access_log_delivery_policy_source_accounts"></a> access_log_delivery_policy_source_accounts(Optional) List of AWS Account IDs should be allowed to deliver access logs to this bucket.list(string)[]no
<a name="input_access_log_delivery_policy_source_buckets"></a> access_log_delivery_policy_source_buckets(Optional) List of S3 bucket ARNs which should be allowed to deliver access logs to this bucket.list(string)[]no
<a name="input_acl"></a> acl(Optional) The canned ACL to apply. Conflicts with grantstringnullno
<a name="input_allowed_kms_key_arn"></a> allowed_kms_key_arnThe ARN of KMS key which should be allowed in PutObjectstringnullno
<a name="input_analytics_configuration"></a> analytics_configurationMap containing bucket analytics configuration.any{}no
<a name="input_analytics_self_source_destination"></a> analytics_self_source_destinationWhether or not the analytics source bucket is also the destination bucket.boolfalseno
<a name="input_analytics_source_account_id"></a> analytics_source_account_idThe analytics source account id.stringnullno
<a name="input_analytics_source_bucket_arn"></a> analytics_source_bucket_arnThe analytics source bucket ARN.stringnullno
<a name="input_attach_access_log_delivery_policy"></a> attach_access_log_delivery_policyControls if S3 bucket should have S3 access log delivery policy attachedboolfalseno
<a name="input_attach_analytics_destination_policy"></a> attach_analytics_destination_policyControls if S3 bucket should have bucket analytics destination policy attached.boolfalseno
<a name="input_attach_deny_incorrect_encryption_headers"></a> attach_deny_incorrect_encryption_headersControls if S3 bucket should deny incorrect encryption headers policy attached.boolfalseno
<a name="input_attach_deny_incorrect_kms_key_sse"></a> attach_deny_incorrect_kms_key_sseControls if S3 bucket policy should deny usage of incorrect KMS key SSE.boolfalseno
<a name="input_attach_deny_insecure_transport_policy"></a> attach_deny_insecure_transport_policyControls if S3 bucket should have deny non-SSL transport policy attachedboolfalseno
<a name="input_attach_deny_unencrypted_object_uploads"></a> attach_deny_unencrypted_object_uploadsControls if S3 bucket should deny unencrypted object uploads policy attached.boolfalseno
<a name="input_attach_elb_log_delivery_policy"></a> attach_elb_log_delivery_policyControls if S3 bucket should have ELB log delivery policy attachedboolfalseno
<a name="input_attach_inventory_destination_policy"></a> attach_inventory_destination_policyControls if S3 bucket should have bucket inventory destination policy attached.boolfalseno
<a name="input_attach_lb_log_delivery_policy"></a> attach_lb_log_delivery_policyControls if S3 bucket should have ALB/NLB log delivery policy attachedboolfalseno
<a name="input_attach_policy"></a> attach_policyControls if S3 bucket should have bucket policy attached (set to true to use value of policy as bucket policy)boolfalseno
<a name="input_attach_public_policy"></a> attach_public_policyControls if a user defined public bucket policy will be attached (set to false to allow upstream to apply defaults to the bucket)booltrueno
<a name="input_attach_require_latest_tls_policy"></a> attach_require_latest_tls_policyControls if S3 bucket should require the latest version of TLSboolfalseno
<a name="input_block_public_acls"></a> block_public_aclsWhether Amazon S3 should block public ACLs for this bucket.booltrueno
<a name="input_block_public_policy"></a> block_public_policyWhether Amazon S3 should block public bucket policies for this bucket.booltrueno
<a name="input_bucket"></a> bucket(Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name.stringnullno
<a name="input_bucket_prefix"></a> bucket_prefix(Optional, Forces new resource) Creates a unique bucket name beginning with the specified prefix. Conflicts with bucket.stringnullno
<a name="input_control_object_ownership"></a> control_object_ownershipWhether to manage S3 Bucket Ownership Controls on this bucket.boolfalseno
<a name="input_cors_rule"></a> cors_ruleList of maps containing rules for Cross-Origin Resource Sharing.any[]no
<a name="input_create_bucket"></a> create_bucketControls if S3 bucket should be createdbooltrueno
<a name="input_expected_bucket_owner"></a> expected_bucket_ownerThe account ID of the expected bucket ownerstringnullno
<a name="input_force_destroy"></a> force_destroy(Optional, Default:false ) A boolean that indicates all objects should be deleted from the bucket so that the bucket can be destroyed without error. These objects are not recoverable.boolfalseno
<a name="input_grant"></a> grantAn ACL policy grant. Conflicts with aclany[]no
<a name="input_ignore_public_acls"></a> ignore_public_aclsWhether Amazon S3 should ignore public ACLs for this bucket.booltrueno
<a name="input_intelligent_tiering"></a> intelligent_tieringMap containing intelligent tiering configuration.any{}no
<a name="input_inventory_configuration"></a> inventory_configurationMap containing S3 inventory configuration.any{}no
<a name="input_inventory_self_source_destination"></a> inventory_self_source_destinationWhether or not the inventory source bucket is also the destination bucket.boolfalseno
<a name="input_inventory_source_account_id"></a> inventory_source_account_idThe inventory source account id.stringnullno
<a name="input_inventory_source_bucket_arn"></a> inventory_source_bucket_arnThe inventory source bucket ARN.stringnullno
<a name="input_lifecycle_rule"></a> lifecycle_ruleList of maps containing configuration of object lifecycle management.any[]no
<a name="input_logging"></a> loggingMap containing access bucket logging configuration.any{}no
<a name="input_metric_configuration"></a> metric_configurationMap containing bucket metric configuration.any[]no
<a name="input_object_lock_configuration"></a> object_lock_configurationMap containing S3 object locking configuration.any{}no
<a name="input_object_lock_enabled"></a> object_lock_enabledWhether S3 bucket should have an Object Lock configuration enabled.boolfalseno
<a name="input_object_ownership"></a> object_ownershipObject ownership. Valid values: BucketOwnerEnforced, BucketOwnerPreferred or ObjectWriter. 'BucketOwnerEnforced': ACLs are disabled, and the bucket owner automatically owns and has full control over every object in the bucket. 'BucketOwnerPreferred': Objects uploaded to the bucket change ownership to the bucket owner if the objects are uploaded with the bucket-owner-full-control canned ACL. 'ObjectWriter': The uploading account will own the object if the object is uploaded with the bucket-owner-full-control canned ACL.string"BucketOwnerEnforced"no
<a name="input_owner"></a> ownerBucket owner's display name and ID. Conflicts with aclmap(string){}no
<a name="input_policy"></a> policy(Optional) A valid bucket policy JSON document. Note that if the policy document is not specific enough (but still valid), Terraform may view the policy as constantly changing in a terraform plan. In this case, please make sure you use the verbose/specific version of the policy. For more information about building AWS IAM policy documents with Terraform, see the AWS IAM Policy Document Guide.stringnullno
<a name="input_putin_khuylo"></a> putin_khuyloDo you agree that Putin doesn't respect Ukrainian sovereignty and territorial integrity? More info: https://en.wikipedia.org/wiki/Putin_khuylo!booltrueno
<a name="input_replication_configuration"></a> replication_configurationMap containing cross-region replication configuration.any{}no
<a name="input_request_payer"></a> request_payer(Optional) Specifies who should bear the cost of Amazon S3 data transfer. Can be either BucketOwner or Requester. By default, the owner of the S3 bucket would incur the costs of any data transfer. See Requester Pays Buckets developer guide for more information.stringnullno
<a name="input_restrict_public_buckets"></a> restrict_public_bucketsWhether Amazon S3 should restrict public bucket policies for this bucket.booltrueno
<a name="input_server_side_encryption_configuration"></a> server_side_encryption_configurationMap containing server-side encryption configuration.any{}no
<a name="input_tags"></a> tags(Optional) A mapping of tags to assign to the bucket.map(string){}no
<a name="input_transition_default_minimum_object_size"></a> transition_default_minimum_object_sizeThe default minimum object size behavior applied to the lifecycle configuration. Valid values: all_storage_classes_128K (default), varies_by_storage_classstringnullno
<a name="input_versioning"></a> versioningMap containing versioning configuration.map(string){}no
<a name="input_website"></a> websiteMap containing static web-site hosting or redirect configuration.any{}no

Outputs

NameDescription
<a name="output_s3_bucket_arn"></a> s3_bucket_arnThe ARN of the bucket. Will be of format arn:aws:s3:::bucketname.
<a name="output_s3_bucket_bucket_domain_name"></a> s3_bucket_bucket_domain_nameThe bucket domain name. Will be of format bucketname.s3.amazonaws.com.
<a name="output_s3_bucket_bucket_regional_domain_name"></a> s3_bucket_bucket_regional_domain_nameThe bucket region-specific domain name. The bucket domain name including the region name, please refer here for format. Note: The AWS CloudFront allows specifying S3 region-specific endpoint when creating S3 origin, it will prevent redirect issues from CloudFront to S3 Origin URL.
<a name="output_s3_bucket_hosted_zone_id"></a> s3_bucket_hosted_zone_idThe Route 53 Hosted Zone ID for this bucket's region.
<a name="output_s3_bucket_id"></a> s3_bucket_idThe name of the bucket.
<a name="output_s3_bucket_lifecycle_configuration_rules"></a> s3_bucket_lifecycle_configuration_rulesThe lifecycle rules of the bucket, if the bucket is configured with lifecycle rules. If not, this will be an empty string.
<a name="output_s3_bucket_policy"></a> s3_bucket_policyThe policy of the bucket, if the bucket is configured with a policy. If not, this will be an empty string.
<a name="output_s3_bucket_region"></a> s3_bucket_regionThe AWS region this bucket resides in.
<a name="output_s3_bucket_website_domain"></a> s3_bucket_website_domainThe domain of the website endpoint, if the bucket is configured with a website. If not, this will be an empty string. This is used to create Route 53 alias records.
<a name="output_s3_bucket_website_endpoint"></a> s3_bucket_website_endpointThe website endpoint, if the bucket is configured with a website. If not, this will be an empty string.
<!-- END_TF_DOCS -->

Authors

Module is maintained by Anton Babenko with help from these awesome contributors.

License

Apache 2 Licensed. See LICENSE for full details.

Additional information for users from Russia and Belarus