Skip to content

Commit

Permalink
Merge pull request #1 from Lachlan-White/feature/content
Browse files Browse the repository at this point in the history
Version 1 Content Release
  • Loading branch information
Lachlan-White authored Mar 27, 2022
2 parents 856de54 + 67539d2 commit 1938277
Show file tree
Hide file tree
Showing 16 changed files with 267 additions and 3 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Changelog

This Changelog should be used to document the differences between releases of your modules versions.

Whilst manually updating this file is possible for every change and release, it is much better to use the commit history and automatically populate this file.

The use of the [semantic-release-bot](https://github.com/semantic-release/semantic-release) is a great way to take the pain out of doing this.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ A module is a container for multiple resources that are used together. Modules c

- The modules' purpose is solely to be consumed by another high-level module

## How to use this template

**Step 1:** Click the `Use this template` button at the top of the page

**Step 2:** Select the Owner / Organisation and Name of your new repository, along with privacy settings of the repository

**Step 3:** Delete the README.md file and rename README.new to README.md

**Step 4:** Start building your module

## File Specific Guidance

Within every file is some guidance on the purpose of these files, and when to use them.
39 changes: 39 additions & 0 deletions README.new
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# <Insert Name of Module Here>

Between the name of the module and the overview subsection should live a description of the module itself. Typically I look to find descriptions written by the platform's documentation so I am not re-inventing the wheel.

As an example a description for any Microsoft Service can be found on their 'Overview' page of each service.

Example: https://docs.microsoft.com/en-us/azure/cosmos-db/introduction

## Overview

### Features

- Creation and Management of an <provider> <resource_type>
- Configuration of feature x
- Configuration of feature y

### Limitations

- Unable to create foo or bar because of limitation on the SDK <link to issue>

### Documentation

- <Link to Terraform Resources Documentation>
- <Link to Platform Resource Documentat>

## Examples

```hcl
module "example1" {
source = "github.com/<oprg_name>/<repo_name>?ref=v0.0.0"

name = "example"
parameter_1 = "yes"
parameter_2 = "no"
parameter_3 = "maybe"
}
```

More detailed examples can be found at [examples](./examples)
20 changes: 20 additions & 0 deletions data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
Data sources allow Terraform to use information defined outside of Terraform, defined by another separate Terraform configuration, or modified by functions.
I personally use data sources within modules sparingly, whilst they are incredibly powerful, I usually side where possible on using the consumer of the module for the inputs to a module. There are exemptions to this rule as an example, a common practice within the Azure Module space is to use the below data source:
`data "azurerm_client_config" "current" {}`
This provides a large amount of information such as:
- client_id
- tenant_id
- subscription_id
- object_id
In some cases these pieces of information are required to deploy a resource, such as an Azure Key Vault, and asking the consumer to provide the tenant_id isn't as simple as calling the aforementioned data source which has no inputs required.
If the data.tf file is unused, it should be deleted from the module.
*/
21 changes: 21 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Examples Folder

## Overview

The purpose of the examples folder is to create a repeatable and sustainable model of enablement for each and every module that you create.

It enables a more complete example that what is typically provided to the consumer in the root README of the module itself.

It can and should also be used in conjunction with a GitHub Action or a Pipeline to validate changes to the module and even can be used as checks and balancer before and automated release.

## Basic Example

The basic example should deploy all the required prerequisite resources / modules in order to deploy the module in the desired way. But should use only the required inputs to the module in order to keep it as simple as an example as possible.

## Complex Example

The complex example should again use all the required prerequisite resources / modules in order to deploy itself. However, this example should use all possible variables available to provide examples and context on how to consume the most advanced version of this module. You may find that your complex example sometimes has more resource / module prerequisites than the basic example.

## End Goal

The end goal of these examples is to ensure that the consumer can find the help they need within your module, and they can easily consume the module, even if thats simply via copy and paste.
16 changes: 16 additions & 0 deletions examples/basic/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
This file should house all the configurations required to stand up a basic version of the module and its required prerequisites in order to validate the deployment of the module.
Example of calling the module at the root directory of this repository
module "basic" {
source = "../..
name = "example"
parameter_1 = "yes"
parameter_2 = "no"
parameter_3 = "maybe"
}
*/
14 changes: 14 additions & 0 deletions examples/basic/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
The purpose of this outputs.tf file is to validate the expected outputs of the module itself.
Similarly to what exists within your outputs.tf at the root directory of the module, however, we now need to ensure that our output is coming from the module itself not the resources within the module.
Example:
output "virtual_machine_public_ip_address" {
value = module.example_module.virtual_machine_public_ip_address
description = "The public IP address of the vm1 windows server resource."
}
*/
19 changes: 19 additions & 0 deletions examples/basic/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
The providers.md file should be used to declare the configuration of any provider information that will be consumed.
The provider blocks declared within this file provide context to the module. This can be anything from the credentials neede to authenticate the provider to the specific region to be used.
Examples:
provider "azurerm" {
features {}
}
provider "aws" {
region = "us-west-2"
access_key = "my-access-key"
secret_key = "my-secret-key"
}
*/
7 changes: 7 additions & 0 deletions examples/complex/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
This file should be deleted if it isn't used or there isn't a complex example for the module.
The complex example should again use all the required prerequisite resources / modules in order to deploy itself. However, this example should use all possible variables available to provide examples and context on how to consume the most advanced version of this module. You may find that your complex example sometimes has more resource / module prerequisites than the basic example.
*/
14 changes: 14 additions & 0 deletions examples/complex/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
The purpose of this outputs.tf file is to validate the expected outputs of the module itself.
Similarly to what exists within your outputs.tf at the root directory of the module, however, we now need to ensure that our output is coming from the module itself not the resources within the module.
Example:
output "virtual_machine_public_ip_address" {
value = module.example_module.virtual_machine_public_ip_address
description = "The public IP address of the vm1 windows server resource."
}
*/
19 changes: 19 additions & 0 deletions examples/complex/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
The providers.md file should be used to declare the configuration of any provider information that will be consumed.
The provider blocks declared within this file provide context to the module. This can be anything from the credentials neede to authenticate the provider to the specific region to be used.
Examples:
provider "azurerm" {
features {}
}
provider "aws" {
region = "us-west-2"
access_key = "my-access-key"
secret_key = "my-secret-key"
}
*/
22 changes: 22 additions & 0 deletions locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
The locals.tf file is used to store all of the declarations of local values.
Local values within Terraform are declared through the use of one or many locals blocks.
Simple Example:
locals {
service_name = "forum"
owner = "Community Team"
}
A local value assigns a name to an expression, so you can use it multiple times within a module without repeating it.
The benefit of separating this into a specific file means that your ability to find and alter these values is made easier than digging through 1000 lines files throughout the rest of the module.
Whilst local values are powerful it should be carefully considered as to the use of these within a module. Traditionally within a module, local values are used as a way to translate variables from the user or to reconfigure outputs of other modules into a more usable format for this modules specific use case.
If the locals.tf file is unused, it should be deleted from the module.
*/
11 changes: 11 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
The main.tf is named because of traditionally the main configuration of resources would live within this file. However, it is also common place that in larger modules or codebases with large amounts of resources and modules that those are split out into their own files, to enable easier navigation.
So for simple modules or deployments keep everything within a single main.tf file.
But as you become more comfortable and take on more complex projects / deployments start to logically separate out the contents of the main.tf into other files, that are named after the resource or module.
A main.tf or any_resource.tf should only contain modules or resources within the file, if local or data blocks are used they should be stored in their respective files.
*/
28 changes: 28 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
Output values make information about your infrastructure available on the command line, and can expose information for other Terraform configurations to use. Output values are similar to return values in programming languages.
The use of the outputs file is incredibly important, as we know, Terraform module are often used in conjunction with one another to create composite modules or holistic platforms hosting applications. The ability to interop between modules and pass information from one source to another is key.
The outputs.tf file contains the declaration of all of the values that will be callable as an output of this module.
Simple Output Example:
output "virtual_machine_public_ip_address" {
value = azurerm_windows_virtual_machine.vm1.public_ip_address
description = "The public IP address of the vm1 windows server resource."
}
It is also important to note that sometimes you may want to hide sensitive information from being displayed as a result of a Terraform Plan or Apply. This can be done buy using the sensitive flag
Sensitive Output Example:
output "db_password" {
value = aws_db_instance.db.password
description = "The password for logging in to the database."
sensitive = true
}
More information on Outputs can be found: <https://www.terraform.io/language/values/outputs>
*/
3 changes: 0 additions & 3 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ variable "source_image_reference" {
}
}
Variable Validation Example:
variable "resource_group_name" {
Expand All @@ -102,5 +101,3 @@ variable "resource_group_name" {
}
*/


20 changes: 20 additions & 0 deletions versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# notes

/*
The versions.tf file is where I declare all of the required versions of providers for this module. Whilst provider configurations are shared between modules, every module must declare it's own provider requirements.
This is done so that Terraform can ensure that there is a single version of the provider that meets the compatibility requirements of all modules within a configuration.
Example:
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=3.0.0"
}
}
}
*/

0 comments on commit 1938277

Please sign in to comment.