Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: adds root module example + more docs #1

Merged
merged 4 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 10 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# terraform-child-module-template
# client-tf-templates

This repository serves as a template for creating Terraform [child modules](https://developer.hashicorp.com/terraform/language/modules#child-modules), providing a standardized structure and essential files for efficient module development. It's designed to ensure consistency and best practices across Terraform projects.
This repository serves as a template for creating Terraform [child](https://opentofu.org/docs/language/modules/#child-modules) and [root](https://opentofu.org/docs/language/modules/#the-root-module) modules, providing a standardized structure and essential files for efficient module development. It's designed to ensure consistency and best practices across Terraform projects.

This README.md serves as the module’s primary documentation and entry point.
Child module example is provided in [terraform-random-pet](./terraform-random-pet/) directory.

Root module example is provided in [root-module](./root-module/) directory.

This README.md serves as the module's primary documentation and entry point.

## Recommenations

Expand All @@ -14,16 +18,17 @@ We recommend to include:
- Prerequisites and Dependencies: Mention any dependencies, required providers, or external resources.
- Example Configurations: If applicable, include or link to example code snippets or a separate examples/ directory.

## Repository Structure
## Module Repository/Directory Structure

Below is the recommended structure for a Terraform child module. You'll fine the best practices for what to include inside each file. This layout helps maintain clarity, and consistency across your infrastructure code:
Below is a recommended structure for both TF child modules and root modules. Inside each file, you’ll find guidance and best practices that help maintain clarity and consistency across your infrastructure code.

```sh
.
├── README.md
├── main.tf
├── data.tf (optional)
├── outputs.tf
├── providers.tf (root module only)
├── variables.tf
└── versions.tf
```
Expand All @@ -32,42 +37,3 @@ Below is the recommended structure for a Terraform child module. You'll fine the

- Testing and Examples: Consider adding an examples/ directory with sample configurations and a test/ directory (if using tools like terratest or native Terraform testing) to ensure the module works as intended
- Continuous Improvement: Update documentation and constraints (versions.tf) as Terraform and providers evolve, and as you refine the module’s functionality.
gberenice marked this conversation as resolved.
Show resolved Hide resolved

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

## Requirements

| Name | Version |
| ------------------------------------------------------------------------ | ------- |
| <a name="requirement_terraform"></a> [terraform](#requirement_terraform) | ~> 1.0 |
| <a name="requirement_random"></a> [random](#requirement_random) | ~> 3.0 |

## Providers

| Name | Version |
| --------------------------------------------------------- | ------- |
| <a name="provider_random"></a> [random](#provider_random) | 3.6.3 |

## Modules

No modules.

## Resources

| Name | Type |
| --------------------------------------------------------------------------------------------------------- | -------- |
| [random_pet.template](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource |

## Inputs

| Name | Description | Type | Default | Required |
| --------------------------------------------------- | ----------------------------- | -------- | ------- | :------: |
| <a name="input_length"></a> [length](#input_length) | The length of the random name | `number` | `2` | no |

## Outputs

| Name | Description |
| -------------------------------------------------------------------------------- | ----------------------------- |
| <a name="output_random_pet_name"></a> [random_pet_name](#output_random_pet_name) | The generated random pet name |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
48 changes: 48 additions & 0 deletions root-module/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# root-module

This is a template root module.
Comment on lines +1 to +3
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance the module description

The current description "This is a template root module" is too generic. Consider providing a more specific description that explains the purpose and functionality of this root module example.

-This is a template root module.
+# Example Root Module
+
+This root module demonstrates how to compose child modules together to create a complete infrastructure. It showcases best practices for:
+- Module composition
+- Variable management
+- Resource organization
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# root-module
This is a template root module.
# root-module
# Example Root Module
This root module demonstrates how to compose child modules together to create a complete infrastructure. It showcases best practices for:
- Module composition
- Variable management
- Resource organization


## Documentation Recommendations (DO NOT INCLUDE THIS INTO THE REAL README)

- Module description: Briefly explain what the root module sets up (e.g., infrastructure for RDS Postgres instances).
- Use [terraform-docs](https://github.com/terraform-docs/terraform-docs) to ensure that variables, outputs, child module, and resource documentation is included.
- Maintain current information: Keep the README updated as the infrastructure evolves.
Comment on lines +7 to +11
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove documentation recommendations from template

The "Documentation Recommendations" section with the note "(DO NOT INCLUDE THIS INTO THE REAL README)" should not be part of the template itself. Consider moving these recommendations to a separate documentation guide or contributing guidelines document.


## Structure

Explore the contents of each file to understand their purpose and discover recommended best practices.

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

## Requirements

| Name | Version |
| ------------------------------------------------------------------------ | ------- |
| <a name="requirement_terraform"></a> [terraform](#requirement_terraform) | ~> 1.0 |
| <a name="requirement_random"></a> [random](#requirement_random) | ~> 3.0 |

## Providers

No providers.

## Modules

| Name | Source | Version |
| ----------------------------------------------------------------- | ------------------------ | ------- |
| <a name="module_random_pet"></a> [random_pet](#module_random_pet) | masterpointio/random/pet | 0.1.0 |

## Resources

No resources.

## Inputs

| Name | Description | Type | Default | Required |
| --------------------------------------------------- | ----------------------------- | -------- | ------- | :------: |
| <a name="input_length"></a> [length](#input_length) | The length of the random name | `number` | `2` | no |

## Outputs

No outputs.

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
2 changes: 2 additions & 0 deletions data.tf → root-module/data.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
# The data.tf file contains Terraform data sources—these do not create resources but query existing infrastructure or configuration for reference.

# Best Practices:
# - Data sources in a root module often fetch information about existing shared infrastructure or external systems.
# Keep these lookups minimal and well-documented, as the root module is usually the topmost layer of your configuration.
# - Data Source Declarations: Place all data blocks here, for example, data "aws_ami" "linux" { ... }.
# - Clear Naming and Purpose: Use descriptive names for data sources to indicate their role (e.g., data "aws_ami" "ubuntu_latest").
# - Commenting and Filtering: Document why each data source is used and ensure filters or queries are well explained.
Expand Down
6 changes: 6 additions & 0 deletions root-module/example.auto.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Purpose:
# The example.auto.tfvars file provides a sample set of input variable values for the root module.
# Terraform automatically loads any .auto.tfvars files, applying these values without requiring additional command-line flags.
# Rename or remove this file to fit your needs.

length = 1
31 changes: 31 additions & 0 deletions root-module/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Purpose:
# The main.tf file in a root module is the entry point for defining and orchestrating your infrastructure.
# It may include resource definitions, calls to child modules, and overall configuration logic.

# Best Practices:
# - Resource declarations: Place core resources that are unique to this layer of your infrastructure.
# - Module calls:
# - Use Terraform Registry Modules with Version Pinning:
# module "vpc" {
# source = "terraform-aws-modules/vpc/aws"
# version = "1.0.0"
# }
# - Use Git Sources with a Specific Tag or Commit:
# module "vpc" {
# source = "git::https://github.com/org/terraform-aws-vpc.git?ref=v1.0.0".
# }
# - Logical grouping: Group related resources and modules logically and use comments to explain complex logic.
# - Minimal hard-coding: Use variables defined in variables.tf instead of hard-coded values for flexibility and reusability.

locals {
# Get the current timestamp and format it as YYYYMMDD
prefix = formatdate("YYYYMMDD", timestamp())
}
gberenice marked this conversation as resolved.
Show resolved Hide resolved

module "random_pet" {
source = "masterpointio/random/pet"
version = "0.1.0"

length = var.length
prefix = local.prefix
}
gberenice marked this conversation as resolved.
Show resolved Hide resolved
7 changes: 7 additions & 0 deletions root-module/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Purpose:
# The outputs.tf file defines values that the module exports for use by the caller.

# Best Practices:
# - Descriptive output names: Use meaningful names (e.g., instance_id, db_connection_string).
# - Descriptions: Include description attributes to clarify the purpose of each output.
# - Minimal outputs: Only output what consumers need. For sensitive outputs, mark as `sensitive = true`.
13 changes: 13 additions & 0 deletions root-module/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Purpose:
# The providers.tf file configures any providers the root module needs, including setting up authentication, default regions, or other provider-specific settings.

# Best Practices:
# - Provider configuration: Define providers (e.g., aws {}, azurerm {}, google {}) and set their region, credentials, or other parameters.
# - Multiple provider configurations: If you need multiple configurations for the same provider (e.g., two AWS regions), define them here with explicit aliases.
# - Avoid hard-coded and static credentials: Instead of embedding static credentials directly in your code, consider:
# - AWS Assume Role: For the AWS provider, configure an assume role to obtain temporary credentials dynamically.
# - Encrypted Configuration Files: For providers requiring API tokens, use a tool like SOPS to encrypt sensitive variables.

provider "random" {
# Configuration options
}
8 changes: 4 additions & 4 deletions variables.tf → root-module/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
# The variables.tf file defines input variables that control the module’s configuration.

# Best Practices:
# - Descriptive Variables: Use meaningful names and description attributes.
# - Default Values: Provide reasonable defaults when possible. For mandatory inputs, omit defaults to enforce explicit user input.
# - Type Constraints and Validation: Use type constraints and validation blocks to catch incorrect inputs early.
# - Group Related Variables: Organize variables logically, adding comments to separate sections if many variables exist.
# - Descriptive variables: Use meaningful names and description attributes.
# - Default values: Provide reasonable defaults when possible. For mandatory inputs, omit defaults to enforce explicit user input.
# - Type vonstraints and validation: Use type constraints and validation blocks to catch incorrect inputs early.
# - Group related variables: Organize variables logically, adding comments to separate sections if many variables exist.

variable "length" {
description = "The length of the random name"
Expand Down
17 changes: 17 additions & 0 deletions root-module/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Purpose:
# The versions.tf file sets explicit Terraform and provider versions, ensuring that users run a known-compatible setup.

# Best Practices:
# - Pessimistic version constraints: Use version constraints (e.g., required_version = "~> 1.3") to allow patch updates but prevent breaking changes.
# - Stability over time: Regularly review and update version constraints as Terraform and providers evolve.

terraform {
required_version = "~> 1.0"
gberenice marked this conversation as resolved.
Show resolved Hide resolved

required_providers {
random = {
source = "hashicorp/random"
version = "~> 3.0"
gberenice marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
102 changes: 102 additions & 0 deletions terraform-random-pet/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# terraform-random-pet
gberenice marked this conversation as resolved.
Show resolved Hide resolved

This is a template child module.
Comment on lines +1 to +3
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance the module description

The current description "This is a template child module" is too generic. Consider providing a more specific description that explains the purpose and functionality of this random pet name generator module.

-This is a template child module.
+# Random Pet Name Generator Module
+
+This Terraform module generates random pet names that can be used as unique identifiers for your infrastructure resources. It supports customizable name length and optional prefixing for organizational purposes.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# terraform-random-pet
This is a template child module.
# terraform-random-pet
# Random Pet Name Generator Module
This Terraform module generates random pet names that can be used as unique identifiers for your infrastructure resources. It supports customizable name length and optional prefixing for organizational purposes.


gberenice marked this conversation as resolved.
Show resolved Hide resolved
## Documentation Recommendations (DO NOT INCLUDE THIS INTO THE REAL README)

### Naming

The repository/directory name should follow this pattern:

```sh
terraform-<PROVIDER>-<NAME>
```

Here’s what this means:

1. The repository should start with `terraform-` if your module should be [published to and discovered on the Registry](https://opentofu.org/docs/language/modules/develop/publish/). Even if you don’t intend to publish the module, following this pattern is a good practice that helps differentiate your Terraform child modules from other code in your projects.
gberenice marked this conversation as resolved.
Show resolved Hide resolved
2. Include the provider name: After the prefix, specify the primary provider your module is for, such as aws, google, datadog, etc.
3. Use descriptive name: Follow the provider name with a clear and concise identifier that describes the module’s purpose.
4. Use hyphens to separate words.

Also:

1. Keep name short and focused: While it should be descriptive, avoid overly long names. The goal is to convey the module’s purpose concisely:
- Good: terraform-aws-internal-lb
- Not so good: terraform-aws-internal-misc-module
- Too long: terraform-aws-internal-application-load-balancer-with-extra-rules
2. Module names should reflect their purpose rather than environment-specific details.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Move documentation recommendations to a separate guide

The "Documentation Recommendations" section with naming guidelines should not be part of the template itself. Consider moving these recommendations to a separate documentation guide or contributing guidelines document.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~24-~24: Possible missing article found.
Context: ...hens to separate words. Also: 1. Keep name short and focused: While it should be d...

(AI_HYDRA_LEO_MISSING_THE)

### Structure

Explore the contents of each file to understand their purpose and discover recommended best practices.

## Use Cases

- Generating unique resource names (e.g., S3 buckets, compute instances).
- Attaching a common prefix to easily identify resources associated with a particular application or environment.
- Simplifying naming conventions and reducing collisions in environments with multiple resources.
gberenice marked this conversation as resolved.
Show resolved Hide resolved

gberenice marked this conversation as resolved.
Show resolved Hide resolved
### Usage

To use this module, reference it from your main configuration and provide the necessary input variables. For example:

```hcl
module "sandbox_pet" {
source = "masterpointio/random/pet"
# We recommend to pin the specific version
# version = "X.X.X"

# Input variables
length = 2
prefix = "sandbox"
}
```

Once applied, the random resource will produce a random name such as `sandbox-lively-parrot` (the exact name will vary). This name can be referenced via:

```hcl
output "pet_name" {
value = module.sandbox_pet.random_pet_name
}
```

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

## Requirements

| Name | Version |
| ------------------------------------------------------------------------ | ------- |
| <a name="requirement_terraform"></a> [terraform](#requirement_terraform) | >= 1.0 |
| <a name="requirement_random"></a> [random](#requirement_random) | >= 3.0 |

## Providers

| Name | Version |
| --------------------------------------------------------- | ------- |
| <a name="provider_random"></a> [random](#provider_random) | >= 3.0 |

## Modules

No modules.

## Resources

| Name | Type |
| --------------------------------------------------------------------------------------------------------- | -------- |
| [random_pet.template](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource |

## Inputs

| Name | Description | Type | Default | Required |
| --------------------------------------------------- | --------------------------------- | -------- | ------- | :------: |
| <a name="input_length"></a> [length](#input_length) | The length of the random name. | `number` | `2` | no |
| <a name="input_prefix"></a> [prefix](#input_prefix) | A string to prefix the name with. | `string` | `null` | no |

## Outputs

| Name | Description |
| -------------------------------------------------------------------------------- | ----------------------------- |
| <a name="output_random_pet_name"></a> [random_pet_name](#output_random_pet_name) | The generated random pet name |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
8 changes: 8 additions & 0 deletions terraform-random-pet/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Purpose:
# The data.tf file contains Terraform data sources—these do not create resources but query existing infrastructure or configuration for reference.

# Best Practices:
# - Data source declarations: Place all data blocks here, for example, data "aws_ami" "linux" { ... }.
# - Clear naming and purpose: Use descriptive names for data sources to indicate their role (e.g., data "aws_ami" "ubuntu_latest").
# - Commenting and filtering: Document why each data source is used and ensure filters or queries are well explained.
# - Minimize external dependencies: Only query the minimum necessary information. Overly complicated data sources can slow down Terraform runs and confuse future maintainers.
9 changes: 5 additions & 4 deletions main.tf → terraform-random-pet/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
# The main.tf file contains the core resource definitions and logic that compose the module’s functionality.

# Best Practices:
# - Resource Definitions: Declare here all the primary resources that this module is responsible for managing.
# - Locals and Expressions: Use locals blocks to simplify expressions and keep the code DRY (Don’t Repeat Yourself).
# - Comments and Structure: Organize resources logically and use comments to explain complex or non-obvious configurations.
# - Minimal Hard-Coding: Use variables extensively to avoid embedding environment-specific values directly in the code.
# - Resource definitions: Declare here all the primary resources that this module is responsible for managing.
# - Locals and expressions: Use locals blocks to simplify expressions and keep the code DRY (Don’t Repeat Yourself).
# - Comments and structure: Organize resources logically and use comments to explain complex or non-obvious configurations.
# - Minimal hard-coding: Use variables extensively to avoid embedding environment-specific values directly in the code.

resource "random_pet" "template" {
length = var.length
prefix = var.prefix
}
4 changes: 2 additions & 2 deletions outputs.tf → terraform-random-pet/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
# The outputs.tf file defines values that the module exports for use by the caller.

# Best Practices:
# - Descriptive Output Names: Use meaningful names (e.g., instance_id, db_connection_string).
# - Descriptive output names: Use meaningful names (e.g., instance_id, db_connection_string).
# - Descriptions: Include description attributes to clarify the purpose of each output.
# - Minimal Outputs: Only output what consumers need. For sensitive outputs, mark as sensitive = true.
# - Minimal outputs: Only output what consumers need. For sensitive outputs, mark as sensitive = true.

output "random_pet_name" {
description = "The generated random pet name"
Expand Down
24 changes: 24 additions & 0 deletions terraform-random-pet/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Purpose:
# The variables.tf file defines input variables that control the module’s configuration.

# Best Practices:
# - Descriptive variables: Use meaningful names and description attributes.
# - Default values: Provide reasonable defaults when possible. For mandatory inputs, omit defaults to enforce explicit user input.
# - Type constraints and validation: Use type constraints and validation blocks to catch incorrect inputs early.
# - Group related variables: Organize variables logically, adding comments to separate sections if many variables exist.

variable "length" {
description = "The length of the random name."
type = number
default = 2
validation {
condition = var.length > 0
error_message = "The length must be a positive number."
}
}

variable "prefix" {
description = "A string to prefix the name with."
type = string
default = null
}
Loading
Loading