Commit bd803f1a authored by Anton Babenko's avatar Anton Babenko Committed by GitHub

feat: Added modules/object (Happy Amazon S3 Pi Day!) (#74)

parent 17d253da
repos: repos:
- repo: git://github.com/antonbabenko/pre-commit-terraform - repo: git://github.com/antonbabenko/pre-commit-terraform
rev: v1.47.0 rev: v1.48.0
hooks: hooks:
- id: terraform_fmt - id: terraform_fmt
- id: terraform_validate - id: terraform_validate
......
...@@ -4,9 +4,10 @@ Terraform module which creates S3 bucket on AWS with all (or almost all) feature ...@@ -4,9 +4,10 @@ Terraform module which creates S3 bucket on AWS with all (or almost all) feature
This type of resources are supported: This type of resources are supported:
* [S3 Bucket](https://www.terraform.io/docs/providers/aws/r/s3_bucket.html) * [S3 Bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket)
* [S3 Bucket Policy](https://www.terraform.io/docs/providers/aws/r/s3_bucket_policy.html) * [S3 Bucket Policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy)
* [S3 Bucket Notification](https://www.terraform.io/docs/providers/aws/r/s3_bucket_notification.html) - use [modules/notification](https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/tree/master/modules/notification) to configure notifications to Lambda functions, SQS queues, and SNS topics. * [S3 Bucket Notification](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_notification) - use [modules/notification](https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/tree/master/modules/notification) to configure notifications to Lambda functions, SQS queues, and SNS topics.
* [S3 Bucket Object](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_object) - use [modules/object](https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/tree/master/modules/object) to upload files to S3 bucket.
These features of S3 bucket configurations are supported: These features of S3 bucket configurations are supported:
...@@ -20,10 +21,6 @@ These features of S3 bucket configurations are supported: ...@@ -20,10 +21,6 @@ These features of S3 bucket configurations are supported:
- Cross-Region Replication (CRR) - Cross-Region Replication (CRR)
- ELB log delivery bucket policy - ELB log delivery bucket policy
## Terraform versions
Terraform 0.12 and above are supported.
## Usage ## Usage
### Private bucket with versioning enabled ### Private bucket with versioning enabled
...@@ -76,7 +73,8 @@ module "s3_bucket" { ...@@ -76,7 +73,8 @@ module "s3_bucket" {
* [Complete](https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/tree/master/examples/complete) - Complete S3 bucket with most of supported features enabled * [Complete](https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/tree/master/examples/complete) - Complete S3 bucket with most of supported features enabled
* [Cross-Region Replication](https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/tree/master/examples/s3-replication) - S3 bucket with Cross-Region Replication (CRR) enabled * [Cross-Region Replication](https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/tree/master/examples/s3-replication) - S3 bucket with Cross-Region Replication (CRR) enabled
- [S3 bucket Notifications](https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/tree/master/examples/notification) - S3 bucket notifications to Lambda functions, SQS queues, and SNS topics. - [S3 Bucket Notifications](https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/tree/master/examples/notification) - S3 bucket notifications to Lambda functions, SQS queues, and SNS topics.
- [S3 Bucket Object](https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/tree/master/examples/object) - Manage S3 bucket objects.
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK --> <!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
......
# S3 bucket object
Configuration in this directory creates S3 bucket objects with different configurations.
## Usage
To run this example you need to execute:
```bash
$ terraform init
$ terraform plan
$ terraform apply
```
Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources.
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
| Name | Version |
|------|---------|
| terraform | >= 0.13 |
| aws | >= 3.0 |
| random | >= 2 |
## Providers
| Name | Version |
|------|---------|
| aws | >= 3.0 |
| random | >= 2 |
## Modules
| Name | Source | Version |
|------|--------|---------|
| object | ../../modules/object | |
| object_complete | ../../modules/object | |
| object_locked | ../../modules/object | |
| s3_bucket | ../../ | |
| s3_bucket_with_object_lock | ../../ | |
## Resources
| Name |
|------|
| [aws_kms_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) |
| [random_pet](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) |
## Inputs
No input.
## Outputs
| Name | Description |
|------|-------------|
| this\_s3\_bucket\_arn | The ARN of the bucket. Will be of format arn:aws:s3:::bucketname. |
| this\_s3\_bucket\_id | The name of the bucket. |
| this\_s3\_bucket\_object\_etag | The ETag generated for the object (an MD5 sum of the object content). |
| this\_s3\_bucket\_object\_id | The key of S3 object |
| this\_s3\_bucket\_object\_version\_id | A unique version ID value for the object, if bucket versioning is enabled. |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
provider "aws" {
region = "eu-west-1"
# Make it faster by skipping something
skip_get_ec2_platforms = true
skip_metadata_api_check = true
skip_region_validation = true
skip_credentials_validation = true
skip_requesting_account_id = true
}
module "object" {
source = "../../modules/object"
bucket = module.s3_bucket.this_s3_bucket_id
key = "${random_pet.this.id}-local"
file_source = "README.md"
# content = file("README.md")
# content_base64 = filebase64("README.md")
tags = {
Sensitive = "not-really"
}
}
module "object_complete" {
source = "../../modules/object"
bucket = module.s3_bucket.this_s3_bucket_id
key = "${random_pet.this.id}-complete"
content = jsonencode({ data : "value" })
acl = "public-read"
storage_class = "ONEZONE_IA"
force_destroy = true
cache_control = "public; max-age=1200"
content_disposition = "attachment; filename=\"invoice.pdf\""
content_encoding = "gzip"
content_language = "en-US"
content_type = "application/json"
website_redirect = "https://www.google.com/"
metadata = {
key = "value1"
another-key = "value2"
}
server_side_encryption = "aws:kms"
kms_key_id = aws_kms_key.this.arn
}
module "object_locked" {
source = "../../modules/object"
bucket = module.s3_bucket_with_object_lock.this_s3_bucket_id
key = "${random_pet.this.id}-locked"
content = "some-content-locked-by-governance"
force_destroy = true
object_lock_legal_hold_status = true # boolean or string ("ON" or "OFF")
object_lock_mode = "GOVERNANCE"
object_lock_retain_until_date = formatdate("YYYY-MM-DD'T'hh:00:00Z", timeadd(timestamp(), "1h")) # some time in the future
}
##################
# Extra resources
##################
resource "random_pet" "this" {
length = 2
}
resource "aws_kms_key" "this" {
description = "KMS key for S3 object"
deletion_window_in_days = 7
}
#############
# S3 buckets
#############
module "s3_bucket" {
source = "../../"
bucket = random_pet.this.id
force_destroy = true
}
module "s3_bucket_with_object_lock" {
source = "../../"
bucket = "${random_pet.this.id}-with-object-lock"
force_destroy = true
object_lock_configuration = {
object_lock_enabled = "Enabled"
}
}
# S3 object
output "this_s3_bucket_object_id" {
description = "The key of S3 object"
value = module.object.this_s3_bucket_object_id
}
output "this_s3_bucket_object_etag" {
description = "The ETag generated for the object (an MD5 sum of the object content)."
value = module.object.this_s3_bucket_object_etag
}
output "this_s3_bucket_object_version_id" {
description = "A unique version ID value for the object, if bucket versioning is enabled."
value = module.object.this_s3_bucket_object_version_id
}
# S3 bucket
output "this_s3_bucket_id" {
description = "The name of the bucket."
value = module.s3_bucket.this_s3_bucket_id
}
output "this_s3_bucket_arn" {
description = "The ARN of the bucket. Will be of format arn:aws:s3:::bucketname."
value = module.s3_bucket.this_s3_bucket_arn
}
terraform {
required_version = ">= 0.13"
required_providers {
aws = ">= 3.0"
random = ">= 2"
}
}
...@@ -9,7 +9,6 @@ Creates S3 bucket notification resource with all supported types of deliveries: ...@@ -9,7 +9,6 @@ Creates S3 bucket notification resource with all supported types of deliveries:
|------|---------| |------|---------|
| terraform | >= 0.12.6 | | terraform | >= 0.12.6 |
| aws | >= 3.0 | | aws | >= 3.0 |
| random | >= 2.0 |
## Providers ## Providers
......
...@@ -2,7 +2,6 @@ terraform { ...@@ -2,7 +2,6 @@ terraform {
required_version = ">= 0.12.6" required_version = ">= 0.12.6"
required_providers { required_providers {
aws = ">= 3.0" aws = ">= 3.0"
random = ">= 2.0"
} }
} }
# S3 bucket object
Creates S3 bucket objects with different configurations.
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
| Name | Version |
|------|---------|
| terraform | >= 0.13 |
| aws | >= 3.0 |
## Providers
| Name | Version |
|------|---------|
| aws | >= 3.0 |
## Modules
No Modules.
## Resources
| Name |
|------|
| [aws_s3_bucket_object](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_object) |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| acl | The canned ACL to apply. Valid values are private, public-read, public-read-write, aws-exec-read, authenticated-read, bucket-owner-read, and bucket-owner-full-control. Defaults to private. | `string` | `null` | no |
| bucket | The name of the bucket to put the file in. Alternatively, an S3 access point ARN can be specified. | `string` | `""` | no |
| cache\_control | Specifies caching behavior along the request/reply chain. | `string` | `null` | no |
| content | Literal string value to use as the object content, which will be uploaded as UTF-8-encoded text. | `string` | `null` | no |
| content\_base64 | Base64-encoded data that will be decoded and uploaded as raw bytes for the object content. This allows safely uploading non-UTF8 binary data, but is recommended only for small content such as the result of the gzipbase64 function with small text strings. For larger objects, use source to stream the content from a disk file. | `string` | `null` | no |
| content\_disposition | Specifies presentational information for the object. | `string` | `null` | no |
| content\_encoding | Specifies what content encodings have been applied to the object and thus what decoding mechanisms must be applied to obtain the media-type referenced by the Content-Type header field. | `string` | `null` | no |
| content\_language | The language the content is in e.g. en-US or en-GB. | `string` | `null` | no |
| content\_type | A standard MIME type describing the format of the object data, e.g. application/octet-stream. All Valid MIME Types are valid for this input. | `string` | `null` | no |
| create | Whether to create this resource or not? | `bool` | `true` | no |
| etag | Used to trigger updates. This attribute is not compatible with KMS encryption, kms\_key\_id or server\_side\_encryption = "aws:kms". | `string` | `null` | no |
| file\_source | The path to a file that will be read and uploaded as raw bytes for the object content. | `string` | `null` | no |
| force\_destroy | Allow the object to be deleted by removing any legal hold on any object version. Default is false. This value should be set to true only if the bucket has S3 object lock enabled. | `bool` | `false` | no |
| key | The name of the object once it is in the bucket. | `string` | `""` | no |
| kms\_key\_id | Amazon Resource Name (ARN) of the KMS Key to use for object encryption. If the S3 Bucket has server-side encryption enabled, that value will automatically be used. If referencing the aws\_kms\_key resource, use the arn attribute. If referencing the aws\_kms\_alias data source or resource, use the target\_key\_arn attribute. Terraform will only perform drift detection if a configuration value is provided. | `string` | `null` | no |
| metadata | A map of keys/values to provision metadata (will be automatically prefixed by x-amz-meta-, note that only lowercase label are currently supported by the AWS Go API). | `map(string)` | `{}` | no |
| object\_lock\_legal\_hold\_status | The legal hold status that you want to apply to the specified object. Valid values are ON and OFF. | `string` | `null` | no |
| object\_lock\_mode | The object lock retention mode that you want to apply to this object. Valid values are GOVERNANCE and COMPLIANCE. | `string` | `null` | no |
| object\_lock\_retain\_until\_date | The date and time, in RFC3339 format, when this object's object lock will expire. | `string` | `null` | no |
| server\_side\_encryption | Specifies server-side encryption of the object in S3. Valid values are "AES256" and "aws:kms". | `string` | `null` | no |
| storage\_class | Specifies the desired Storage Class for the object. Can be either STANDARD, REDUCED\_REDUNDANCY, ONEZONE\_IA, INTELLIGENT\_TIERING, GLACIER, DEEP\_ARCHIVE, or STANDARD\_IA. Defaults to STANDARD. | `string` | `null` | no |
| tags | A map of tags to assign to the object. | `map(string)` | `{}` | no |
| website\_redirect | Specifies a target URL for website redirect. | `string` | `null` | no |
## Outputs
| Name | Description |
|------|-------------|
| this\_s3\_bucket\_object\_etag | The ETag generated for the object (an MD5 sum of the object content). |
| this\_s3\_bucket\_object\_id | The key of S3 object |
| this\_s3\_bucket\_object\_version\_id | A unique version ID value for the object, if bucket versioning is enabled. |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
resource "aws_s3_bucket_object" "this" {
count = var.create ? 1 : 0
bucket = var.bucket
key = var.key
force_destroy = var.force_destroy
acl = var.acl
storage_class = try(upper(var.storage_class), var.storage_class)
source = var.file_source
content = var.content
content_base64 = var.content_base64
etag = var.etag
cache_control = var.cache_control
content_disposition = var.content_disposition
content_encoding = var.content_encoding
content_language = var.content_language
content_type = var.content_type
website_redirect = var.website_redirect
metadata = var.metadata
server_side_encryption = var.server_side_encryption
kms_key_id = var.kms_key_id
object_lock_legal_hold_status = try(tobool(var.object_lock_legal_hold_status) ? "ON" : upper(var.object_lock_legal_hold_status), var.object_lock_legal_hold_status)
object_lock_mode = try(upper(var.object_lock_mode), var.object_lock_mode)
object_lock_retain_until_date = var.object_lock_retain_until_date
tags = var.tags
lifecycle {
ignore_changes = [object_lock_retain_until_date]
}
}
output "this_s3_bucket_object_id" {
description = "The key of S3 object"
value = element(concat(aws_s3_bucket_object.this.*.id, [""]), 0)
}
output "this_s3_bucket_object_etag" {
description = "The ETag generated for the object (an MD5 sum of the object content)."
value = element(concat(aws_s3_bucket_object.this.*.etag, [""]), 0)
}
output "this_s3_bucket_object_version_id" {
description = "A unique version ID value for the object, if bucket versioning is enabled."
value = element(concat(aws_s3_bucket_object.this.*.version_id, [""]), 0)
}
variable "create" {
description = "Whether to create this resource or not?"
type = bool
default = true
}
variable "bucket" {
description = "The name of the bucket to put the file in. Alternatively, an S3 access point ARN can be specified."
type = string
default = ""
}
variable "key" {
description = "The name of the object once it is in the bucket."
type = string
default = ""
}
variable "file_source" {
description = "The path to a file that will be read and uploaded as raw bytes for the object content."
type = string
default = null
}
variable "content" {
description = "Literal string value to use as the object content, which will be uploaded as UTF-8-encoded text."
type = string
default = null
}
variable "content_base64" {
description = "Base64-encoded data that will be decoded and uploaded as raw bytes for the object content. This allows safely uploading non-UTF8 binary data, but is recommended only for small content such as the result of the gzipbase64 function with small text strings. For larger objects, use source to stream the content from a disk file."
type = string
default = null
}
variable "acl" {
description = "The canned ACL to apply. Valid values are private, public-read, public-read-write, aws-exec-read, authenticated-read, bucket-owner-read, and bucket-owner-full-control. Defaults to private."
type = string
default = null
}
variable "cache_control" {
description = "Specifies caching behavior along the request/reply chain."
type = string # map?
default = null
}
variable "content_disposition" {
description = "Specifies presentational information for the object."
type = string # map?
default = null
}
variable "content_encoding" {
description = "Specifies what content encodings have been applied to the object and thus what decoding mechanisms must be applied to obtain the media-type referenced by the Content-Type header field."
type = string
default = null
}
variable "content_language" {
description = "The language the content is in e.g. en-US or en-GB."
type = string
default = null
}
variable "content_type" {
description = "A standard MIME type describing the format of the object data, e.g. application/octet-stream. All Valid MIME Types are valid for this input."
type = string
default = null
}
variable "website_redirect" {
description = "Specifies a target URL for website redirect."
type = string
default = null
}
variable "storage_class" {
description = "Specifies the desired Storage Class for the object. Can be either STANDARD, REDUCED_REDUNDANCY, ONEZONE_IA, INTELLIGENT_TIERING, GLACIER, DEEP_ARCHIVE, or STANDARD_IA. Defaults to STANDARD."
type = string
default = null
}
variable "etag" {
description = "Used to trigger updates. This attribute is not compatible with KMS encryption, kms_key_id or server_side_encryption = \"aws:kms\"."
type = string
default = null
}
variable "server_side_encryption" {
description = "Specifies server-side encryption of the object in S3. Valid values are \"AES256\" and \"aws:kms\"."
type = string
default = null
}
variable "kms_key_id" {
description = "Amazon Resource Name (ARN) of the KMS Key to use for object encryption. If the S3 Bucket has server-side encryption enabled, that value will automatically be used. If referencing the aws_kms_key resource, use the arn attribute. If referencing the aws_kms_alias data source or resource, use the target_key_arn attribute. Terraform will only perform drift detection if a configuration value is provided."
type = string
default = null
}
variable "metadata" {
description = "A map of keys/values to provision metadata (will be automatically prefixed by x-amz-meta-, note that only lowercase label are currently supported by the AWS Go API)."
type = map(string)
default = {}
}
variable "tags" {
description = "A map of tags to assign to the object."
type = map(string)
default = {}
}
variable "force_destroy" {
description = "Allow the object to be deleted by removing any legal hold on any object version. Default is false. This value should be set to true only if the bucket has S3 object lock enabled."
type = bool
default = false
}
variable "object_lock_legal_hold_status" {
description = "The legal hold status that you want to apply to the specified object. Valid values are ON and OFF."
type = string
default = null
}
variable "object_lock_mode" {
description = "The object lock retention mode that you want to apply to this object. Valid values are GOVERNANCE and COMPLIANCE."
type = string
default = null
}
variable "object_lock_retain_until_date" {
description = "The date and time, in RFC3339 format, when this object's object lock will expire."
type = string
default = null
}
terraform {
required_version = ">= 0.13"
required_providers {
aws = ">= 3.0"
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment