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

docs: [IAC-3227]: Add module registry structure and submodule usage docs #9541

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
---
title: Module Code Structure
description: Learn about the required code structure for module registry.
sidebar_position: 10
sidebar_label: Module Code Structure
---

OpenTofu or Terraform modules are reusable units of infrastructure configuration that help standardize deployment patterns and improve maintainability. A well-structured module simplifies usage and promotes best practices. This guide outlines the essential components of a Terraform module and how to structure it effectively.

## Requirements
### Root Module
All OpenTofu or Terraform configurations consist of at least one module, known as the root module, which is **the only required element**. The most common name for this file is `main.tf`. This file serves as the entry point for [OpenTofu](https://opentofu.org/) or Terraform execution and contains all the necessary configurations to provision the desired infrastructure.

:::info modules folder
When using submodules, note that they are only recognized if they are placed within the `modules` folder at the root directory.
Go to [submodule usage](/docs/infra-as-code-management/iacm-features/module-registry/root-sub-module-usage) for more information.
:::

---
## Module Layout
A typical OpenTofu or Terraform module consists of a set of configuration files that define resources, variables, outputs, and dependencies. Below is a recommended directory structure:

```
module-name/
├── main.tf # Primary resource configurations
├── variables.tf # Input variable definitions
├── outputs.tf # Output values
├── README.md # Documentation for the module
├── provider.tf # Provider configuration (if needed)
├── versions.tf # Required Terraform and provider versions
├── modules/ # Nested submodules (if applicable)
├── examples/ # Usage examples for reference
└── tests/ # Automated tests for the module
```

## Other key components
### `variables.tf` (Input Variables)
- Declares configurable inputs for the module.
- Variables should include descriptions and, when applicable, default values.

Example:
```hcl
variable "instance_type" {
description = "EC2 instance type"
type = string
default = "t2.micro"
}
```
Also see [variable usage](/docs/infra-as-code-management/project-setup/input-variables) for more information.

---
### `outputs.tf` (Output Values)
- Defines values that the module will return upon execution.
- Helps users access relevant module data.

Example:
```hcl
output "instance_id" {
description = "ID of the created EC2 instance"
value = aws_instance.example.id
}
```

---
### `README.md` (Module Documentation)
- Provides an overview of the module’s purpose and usage.
- Includes example configurations and descriptions of variables and outputs.

---
### `provider.tf` (Provider Configuration)
If a module requires provider settings, define them here. Avoid hardcoding provider settings within a module to allow flexibility.

Example:
```hcl
tofu {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}
```

---
### `versions.tf` (Version Constraints)
- Specifies compatible OpenTofu or Terraform and provider versions.
- Ensures module stability by preventing incompatible updates.

Example:
```hcl
tofu {
required_version = ">= 1.0.0"
}
```

---
### `modules/` (Nested Modules / Submodules)
If a module is composed of multiple submodules, organize them within this directory to improve modularity and reusability.

:::info module folder
Submodules are only recognized if they are placed within the `modules` folder.
:::

---
### `examples/` (Usage Examples)
Provide working examples demonstrating how to use the module in different scenarios. This helps users understand its implementation.

---
### `tests/` (Automated Testing)
Testing ensures the module functions as expected. Use tools like `tofu test` or external frameworks such as `Terratest`.

Example test using `tofu test`:
```hcl
tofu {
test {
assert {
condition = resource.aws_instance.example.instance_type == "t2.micro"
error_message = "Unexpected instance type"
}
}
}
```

---
## Best practices
To ensure your modules are well-structured and maintainable, follow these best practices:

**Root Module:** Always include a `main.tf` file at the root level of your repository. This file serves as the entry point for [OpenTofu](https://opentofu.org/docs/language/modules/) or Terraform execution.
**Modules Folder:** Place all submodules within a `modules/` folder. Submodules are only recognized if they are placed within this folder.
**Consistent Naming:** Use consistent naming conventions for files and directories to improve readability and maintainability.
**Documentation:** Provide comprehensive documentation in the README.md file, including an overview, usage instructions, and examples.
**Version Constraints:** Specify compatible OpenTofu or Terraform and provider versions in the `versions.tf` file to ensure module stability.
**Testing:** Include automated tests in the tests/ directory to verify the functionality of your module.

---
## Conclusion
A well-structured IaC module enhances reusability, maintainability, and collaboration. By following these guidelines, you can create reliable and scalable modules for your infrastructure needs.

For more details, refer to the following documentation:
- [Register a Module](/docs/infra-as-code-management/iacm-features/module-registry/module-registry)
- [Root and Submodule Usage](/docs/infra-as-code-management/iacm-features/module-registry/root-sub-module-usage)
Original file line number Diff line number Diff line change
@@ -1,26 +1,13 @@
---
title: Registered module settings
description: Explore each tab of a registered module to understand its data, settings, and usage in detail.
sidebar_position: 20
sidebar_label: Registered module settings
sidebar_position: 40
sidebar_label: Registered Module Settings
---

<CTABanner
buttonText="Learn More"
title="Pending release"
tagline="The IaCM Module Registry feature is currently pending release and will be available soon!"
link="https://www.harness.io/blog/harness-iacm-module-registry"
closable={true}
target="_self"
/>

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

:::warning pending release
IaCM Module Registry is currently pending release and will be available soon! [Learn more](https://www.harness.io/blog/harness-iacm-module-registry).
:::

## Prerequisites
- A registered *tf* modules, to register a new module, go to [Register a module](https://developer.harness.io/docs/infra-as-code-management/iacm-features/module-registry#register-a-module)

Expand Down Expand Up @@ -126,18 +113,7 @@ Submodules can provide users with the flexibility to override or customize certa
## Top level overview
<Tabs>
<TabItem value="Interactive guide">
<iframe
src="https://app.tango.us/app/embed/338cf3be-ddf5-4272-9178-fe3f84d815d4"
title="Harness IaCM registered module overview"
style={{ minHeight: '640px' }}
width="100%"
height="100%"
referrerpolicy="strict-origin-when-cross-origin"
frameborder="0"
webkitallowfullscreen="true"
mozallowfullscreen="true"
allowfullscreen="true"
></iframe>
<DocVideo src="https://app.tango.us/app/embed/338cf3be-ddf5-4272-9178-fe3f84d815d4" title="Harness IaCM registered module overview" />
</TabItem>
<TabItem value="Step-by-step">

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
title: Module Registry
description: Learn how to register a module in Harness IaCM
sidebar_position: 10
sidebar_label: Register modules
sidebar_position: 20
sidebar_label: Register Modules
---

import Tabs from '@theme/Tabs';
Expand All @@ -21,18 +21,7 @@ Follow the steps in the guide below to register a new module.

<Tabs>
<TabItem value="Interactive guide">
<iframe
src="https://app.tango.us/app/embed/5aa16720-f96c-44f3-9ad7-2e4dce4ad3b3"
title="Register a module in Harness"
style={{ minHeight: '640px' }}
width="100%"
height="100%"
referrerpolicy="strict-origin-when-cross-origin"
frameborder="0"
webkitallowfullscreen="true"
mozallowfullscreen="true"
allowfullscreen="true"
></iframe>
<DocVideo src="ttps://app.tango.us/app/embed/5aa16720-f96c-44f3-9ad7-2e4dce4ad3b3" title="Register a module in Harness" />
</TabItem>
<TabItem value="Step-by-step">
1. Login to [Harness](https://app.harness.io).
Expand All @@ -56,19 +45,8 @@ Follow the steps in the guide below to register a new module.

## Review module settings
Harness pulls various details from your module and makes it easy to review them.
<iframe
src="https://app.tango.us/app/embed/f23cb280-5072-4622-a56b-7882cd01afff"
title="Review your settings for a registered module"
style={{ minHeight: '640px' }}
width="100%"
height="100%"
referrerpolicy="strict-origin-when-cross-origin"
frameborder="0"
webkitallowfullscreen="true"
mozallowfullscreen="true"
allowfullscreen="true"
></iframe>

<DocVideo src="https://app.tango.us/app/embed/f23cb280-5072-4622-a56b-7882cd01afff" title="Review your settings for a registered module" />

:::info syncing module versions
The Sync button checks your registered module in Harness against the latest release in your repository and configured connector branch. If a newer version exists, it will sync it.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
title: Root & Submodule Usage
description: Learn about the requirements and correct usage of root modules and nested submodules.
sidebar_position: 30
sidebar_label: Root & Submodule Usage
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';


This document provides an overview of the requirements and best practices for using root modules and nested submodules in your infrastructure-as-code setup. It explains the structure and configuration needed for single-module repositories and how to properly reference submodules within your code. Understanding these concepts will help ensure consistency and maintainability in your module usage.

<Tabs>
<TabItem value="Single modules">

## Root Level Modules
If you are using only a single module, you must have a `main.tf` file at the root level of your repository. Below is an example of the typical structure for a single-module repository:

```
.
├── README.md
├── main.tf
├── variables.tf
├── outputs.tf
```

Here is an example of defining a single module in `main.tf`:

```hcl
module "native-module" {
source = "app.harness.io/<account_id>/native-module/aws"
version = "1.2.1" # This matches your repository's Git tags.
}
```
</TabItem>
<TabItem value="Submodules">

## Submodule Usage
:::info
While there is no set limit on nested submodule paths, metadata collection is only carried out one level deep.
:::

Submodules are only recognized if they are placed within the `modules` folder.

Here is an example of the repository tree with submodules:

```
.
├── README.md
├── main.tf
├── variables.tf
├── outputs.tf
├── ...
├── modules/
│ ├── submoduleA/
│ │ ├── main.tf
│ │ ├── ...
│ ├── native-module/
│ │ │── README.md
│ │ │── main.tf
│ │ │── variables.tf
│ │ │── outputs.tf
```

They can be referenced in your root module `main.tf` file as shown below. Notice the `//` syntax, which indicates the path to the submodule:

```hcl
module "native-submodule" {
source = "app.harness.io/<account-id>/native-module//modules/native-submodule"
}
```
:::info submodule versions
Note that **submodules cannot have a version included**, as Git tags do not apply to anything beyond the root level.
:::
</TabItem>
</Tabs>