From eb5cd1e6df3a67bd67a3e2a93b51e65de5b1af67 Mon Sep 17 00:00:00 2001 From: ulises-jeremias Date: Sun, 8 Sep 2024 12:40:27 -0300 Subject: [PATCH] chore: Update README.md and Terraform module template Update the README.md file to include information about creating a new module and reference the Terraform Registry. Also, add a new Terraform module template with its associated files and documentation. --- README.md | 4 ++ modules/__template__/README.md | 38 ++++++++++++++++ modules/__template__/docs/MODULE.md | 55 +++++++++++++++++++++++ modules/__template__/main.tf | 69 +++++++++++++++++++++++++++++ modules/__template__/outputs.tf | 14 ++++++ modules/__template__/variables.tf | 69 +++++++++++++++++++++++++++++ modules/__template__/versions.tf | 10 +++++ 7 files changed, 259 insertions(+) create mode 100644 modules/__template__/README.md create mode 100644 modules/__template__/docs/MODULE.md create mode 100644 modules/__template__/main.tf create mode 100644 modules/__template__/outputs.tf create mode 100644 modules/__template__/variables.tf create mode 100644 modules/__template__/versions.tf diff --git a/README.md b/README.md index e88c1a9..98563cc 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,10 @@ Our custom Terraform modules are located in the `modules` directory. These modul | [VPC](./modules/vpc/README.md) | Bootstrap a VPC for shared infrastructure. | | [VPC Endpoint](./modules/vpc-endpoint/README.md) | Bootstrap VPC endpoints for S3, DynamoDB, and other services. | +In case you need to create a new module, you can use the [Terraform Module Template](./modules/__template__/README.md) as a starting point. + +For reference, you can also check the [Terraform Registry](https://registry.terraform.io/) for additional modules. + ## Apps and Services In addition to infrastructure provisioning, we have included a few apps and services to help you get started. These are located in the `apps` directory and provide useful examples of how to use the infrastructure we have provisioned. diff --git a/modules/__template__/README.md b/modules/__template__/README.md new file mode 100644 index 0000000..301e2de --- /dev/null +++ b/modules/__template__/README.md @@ -0,0 +1,38 @@ +# Terraform Module Template + +This is a template for creating Terraform modules. It includes a basic structure for organizing your module code and documentation. + +In this example, we show how to create an S3 bucket with versioning, encryption, logging, and lifecycle management. This module uses a customizable name prefix for all resources and allows extra tags to be assigned. + +## Key Highlights + +1. **`name` Variable**: Used as a prefix for all resources, providing an easy way to distinguish resources created by the module. +2. **`tags` Variable**: Allows additional tags to be passed to the module, merged with the default tag structure. +3. **Documentation**: The README clearly documents the purpose and examples of using the module. +4. **Module Documentation**: The module documentation is generated using [terraform-docs](https://github.com/terraform-docs/terraform-docs) and provides detailed information about the module's inputs and outputs. + +## Usage + +```hcl +module "s3_bucket" { + source = "path_to_your_module" + + name = "data-lake" + bucket_name = "raw-data" + force_destroy = true + enable_versioning = true + kms_key_id = "alias/my-kms-key" + logging_bucket = "my-logging-bucket" + + tags = { + Owner = "Anton" + Environment = "prod" + } +} +``` + +## Module Documentation + +The module documentation is generated with [terraform-docs](https://github.com/terraform-docs/terraform-docs) by running `terraform-docs md . > ./docs/MODULE.md` from the module directory. + +You can also view the latest version of the module documentation [here](./docs/MODULE.md). diff --git a/modules/__template__/docs/MODULE.md b/modules/__template__/docs/MODULE.md new file mode 100644 index 0000000..952781a --- /dev/null +++ b/modules/__template__/docs/MODULE.md @@ -0,0 +1,55 @@ + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.0.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 5.0.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_s3_bucket.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource | +| [aws_s3_bucket_lifecycle_configuration.lifecycle](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_lifecycle_configuration) | resource | +| [aws_s3_bucket_logging.bucket_logging](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_logging) | resource | +| [aws_s3_bucket_ownership_controls.ownership](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_ownership_controls) | resource | +| [aws_s3_bucket_public_access_block.public_access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource | +| [aws_s3_bucket_server_side_encryption_configuration.sse](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource | +| [aws_s3_bucket_versioning.versioning](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [acl](#input\_acl) | Canned ACL to apply to the bucket | `string` | `"private"` | no | +| [bucket\_name](#input\_bucket\_name) | The name of the S3 bucket | `string` | n/a | yes | +| [enable\_lifecycle\_rule](#input\_enable\_lifecycle\_rule) | Enable lifecycle rule | `bool` | `true` | no | +| [enable\_versioning](#input\_enable\_versioning) | Enable versioning on the S3 bucket | `bool` | `false` | no | +| [force\_destroy](#input\_force\_destroy) | Force bucket deletion | `bool` | `false` | no | +| [kms\_key\_id](#input\_kms\_key\_id) | KMS key for bucket encryption | `string` | `"alias/aws/s3"` | no | +| [lifecycle\_expiration\_days](#input\_lifecycle\_expiration\_days) | Number of days after which to expire objects | `number` | `90` | no | +| [lifecycle\_storage\_class](#input\_lifecycle\_storage\_class) | Storage class for lifecycle transition | `string` | `"GLACIER"` | no | +| [lifecycle\_transition\_days](#input\_lifecycle\_transition\_days) | Number of days after which to transition objects | `number` | `30` | no | +| [logging\_bucket](#input\_logging\_bucket) | Bucket for storing logs | `string` | n/a | yes | +| [name](#input\_name) | Name to be used on all the resources as identifier | `string` | `""` | no | +| [tags](#input\_tags) | Any extra tags to assign to objects | `map(any)` | `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [bucket\_arn](#output\_bucket\_arn) | The ARN of the S3 bucket | +| [bucket\_id](#output\_bucket\_id) | The ID of the S3 bucket | +| [logging\_bucket](#output\_logging\_bucket) | The logging bucket for the S3 bucket | + \ No newline at end of file diff --git a/modules/__template__/main.tf b/modules/__template__/main.tf new file mode 100644 index 0000000..0a67294 --- /dev/null +++ b/modules/__template__/main.tf @@ -0,0 +1,69 @@ +resource "aws_s3_bucket" "bucket" { + bucket = "${var.name}-${var.bucket_name}" + + force_destroy = var.force_destroy + + tags = merge({ + Name = "${var.name}-s3-bucket" + }, var.tags) +} + +resource "aws_s3_bucket_ownership_controls" "ownership" { + bucket = aws_s3_bucket.bucket.id + + rule { + object_ownership = "BucketOwnerEnforced" + } +} + +resource "aws_s3_bucket_public_access_block" "public_access" { + bucket = aws_s3_bucket.bucket.id + + block_public_acls = true + block_public_policy = true + restrict_public_buckets = true + ignore_public_acls = true +} + +resource "aws_s3_bucket_versioning" "versioning" { + bucket = aws_s3_bucket.bucket.id + + versioning_configuration { + status = var.enable_versioning ? "Enabled" : "Suspended" + } +} + +resource "aws_s3_bucket_server_side_encryption_configuration" "sse" { + bucket = aws_s3_bucket.bucket.id + + rule { + apply_server_side_encryption_by_default { + sse_algorithm = "aws:kms" + kms_master_key_id = var.kms_key_id + } + } +} + +resource "aws_s3_bucket_lifecycle_configuration" "lifecycle" { + bucket = aws_s3_bucket.bucket.id + + rule { + id = "default" + status = var.enable_lifecycle_rule ? "Enabled" : "Disabled" + + transition { + days = var.lifecycle_transition_days + storage_class = var.lifecycle_storage_class + } + + expiration { + days = var.lifecycle_expiration_days + } + } +} + +resource "aws_s3_bucket_logging" "bucket_logging" { + bucket = aws_s3_bucket.bucket.id + target_bucket = var.logging_bucket + target_prefix = "${var.name}-${var.bucket_name}/logs/" +} diff --git a/modules/__template__/outputs.tf b/modules/__template__/outputs.tf new file mode 100644 index 0000000..080506b --- /dev/null +++ b/modules/__template__/outputs.tf @@ -0,0 +1,14 @@ +output "bucket_id" { + description = "The ID of the S3 bucket" + value = aws_s3_bucket.bucket.id +} + +output "bucket_arn" { + description = "The ARN of the S3 bucket" + value = aws_s3_bucket.bucket.arn +} + +output "logging_bucket" { + description = "The logging bucket for the S3 bucket" + value = aws_s3_bucket_logging.bucket_logging.target_bucket +} diff --git a/modules/__template__/variables.tf b/modules/__template__/variables.tf new file mode 100644 index 0000000..aa1fe62 --- /dev/null +++ b/modules/__template__/variables.tf @@ -0,0 +1,69 @@ +variable "name" { + description = "Name to be used on all the resources as identifier" + type = string + default = "" +} + +variable "tags" { + description = "Any extra tags to assign to objects" + type = map(any) + default = {} +} + +variable "bucket_name" { + description = "The name of the S3 bucket" + type = string +} + +variable "force_destroy" { + description = "Force bucket deletion" + type = bool + default = false +} + +variable "acl" { + description = "Canned ACL to apply to the bucket" + type = string + default = "private" +} + +variable "enable_versioning" { + description = "Enable versioning on the S3 bucket" + type = bool + default = false +} + +variable "kms_key_id" { + description = "KMS key for bucket encryption" + type = string + default = "alias/aws/s3" +} + +variable "enable_lifecycle_rule" { + description = "Enable lifecycle rule" + type = bool + default = true +} + +variable "lifecycle_transition_days" { + description = "Number of days after which to transition objects" + type = number + default = 30 +} + +variable "lifecycle_storage_class" { + description = "Storage class for lifecycle transition" + type = string + default = "GLACIER" +} + +variable "lifecycle_expiration_days" { + description = "Number of days after which to expire objects" + type = number + default = 90 +} + +variable "logging_bucket" { + description = "Bucket for storing logs" + type = string +} diff --git a/modules/__template__/versions.tf b/modules/__template__/versions.tf new file mode 100644 index 0000000..729454b --- /dev/null +++ b/modules/__template__/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.0.0" + } + } +}