Writing a Terraform Module: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
 
(19 intermediate revisions by the same user not shown)
Line 13: Line 13:


=Playground=
=Playground=
{{External|https://github.com/ovidiuf/playground/tree/master/hashicorp/terraform/blue-module}}
{{External|https://github.com/ovidiuf/playground/tree/master/hashicorp/terraform/simplest-module}}


=Procedure=
=Procedure=
Line 27: Line 27:
* LICENSE
* LICENSE
* Recommended file (they should exist even if they are empty):
* Recommended file (they should exist even if they are empty):
** <code>main.tf</code>
** <code>main.tf</code> - this must contain all nested module calls, if any. If such calls exist, the should use paths like <code>./modules/my-internal-module/...</code> so that Terraform will consider them to be part of the same repository or package, rather than downloading them again separately.
** <code>variables.tf</code>
** <code>variables.tf</code> - this must contain [[Hashicorp_Configuration_Language#Input_Variable|input variable]] declarations. Input variables should have descriptions.
** <code>outputs.tf</code>
** <code>outputs.tf</code> - this must contain [[Hashicorp_Configuration_Language#Output_Variable|outputs]]. Output variables should have descriptions.
* For a complex module, resource creation may be split into multiple files, but '''any nested module calls should be in the main file'''.
* For a complex module, resource creation may be split into multiple files, but '''any nested module calls should be in the main file'''.
* <code>modules/</code> directory should contain the nested modules. Any nested module with a README.md is considered usable by an external user. If a README doesn't exist, it is considered for internal use only.
* <code>examples/</code> directory should contain examples. Each example may have a README to explain the goal and usage of the example. Examples for submodules should also be placed in the root examples/ directory. Because examples will often be copied into other repositories for customization, any <code>module</code> blocks should have their source set to the address an external caller would use, not to a relative path.
.
|-- main.tf
|-- variables.tf
|-- outputs.tf
|-- README.md
|-- modules
|      |
|      |-- nestedA   
|      |      |
|      |      |-- main.tf
|      |      |-- variables.tf
|      |      |-- outputs.tf
|      |      |-- README.md
|      |      +- ...
|      |
|      |-- nestedB   
|              |
|              |-- main.tf
|              |-- variables.tf
|              |-- outputs.tf
|              |-- README.md
|              +- ...
|
+-- examples
===main.tf===
<syntaxhighlight lang='text'>
</syntaxhighlight>
===variables.tf===
{{Internal|Hashicorp_Configuration_Language#Input_Variable|Input Variables}}
===outputs.tf===
{{Internal|Hashicorp_Configuration_Language#Output_Variable|Output Variables}}
=Module Composition=
{{External|https://www.terraform.io/docs/modules/composition.html}}
=Module Versioning=
Modules intended for public consumption must be versioned. Hashicorp publishes the Consul module, which is supposed to be a reference implementation, using the following versioning scheme:
https&#58;//releases.hashicorp.com/consul/'''''version'''''/consul_'''''version'''''_linux_amd64.zip
where "version" is a semantic version string: "0.8.0"
However, the versioning scheme seems to be entirely "external", in that there is no metdata in the module that says what version the module is.
<font color=darkgray>TO CONTINUE</font>.

Latest revision as of 02:23, 20 February 2020

External

Internal

Reference Example

Playground

https://github.com/ovidiuf/playground/tree/master/hashicorp/terraform/simplest-module

Procedure

To define a module, create a new root directory for it and place one or more .tf files inside it.

Standard Structure

Everything is optional, except for the root module:

  • Root module - this is the only required element for the standard module structure, and it consists in .tf files - which must exist - in the root directory of the module.
  • README or README.md. Should contain a description of the module. Examples can be included in an example directory.
  • LICENSE
  • Recommended file (they should exist even if they are empty):
    • main.tf - this must contain all nested module calls, if any. If such calls exist, the should use paths like ./modules/my-internal-module/... so that Terraform will consider them to be part of the same repository or package, rather than downloading them again separately.
    • variables.tf - this must contain input variable declarations. Input variables should have descriptions.
    • outputs.tf - this must contain outputs. Output variables should have descriptions.
  • For a complex module, resource creation may be split into multiple files, but any nested module calls should be in the main file.
  • modules/ directory should contain the nested modules. Any nested module with a README.md is considered usable by an external user. If a README doesn't exist, it is considered for internal use only.
  • examples/ directory should contain examples. Each example may have a README to explain the goal and usage of the example. Examples for submodules should also be placed in the root examples/ directory. Because examples will often be copied into other repositories for customization, any module blocks should have their source set to the address an external caller would use, not to a relative path.
.
|-- main.tf
|-- variables.tf
|-- outputs.tf
|-- README.md
|-- modules
|      |
|      |-- nestedA     
|      |       |
|      |       |-- main.tf
|      |       |-- variables.tf
|      |       |-- outputs.tf
|      |       |-- README.md
|      |       +- ...
|      |
|      |-- nestedB     
|              |
|              |-- main.tf
|              |-- variables.tf
|              |-- outputs.tf
|              |-- README.md
|              +- ...
|
+-- examples

main.tf

variables.tf

Input Variables

outputs.tf

Output Variables

Module Composition

https://www.terraform.io/docs/modules/composition.html

Module Versioning

Modules intended for public consumption must be versioned. Hashicorp publishes the Consul module, which is supposed to be a reference implementation, using the following versioning scheme:

https://releases.hashicorp.com/consul/version/consul_version_linux_amd64.zip

where "version" is a semantic version string: "0.8.0"

However, the versioning scheme seems to be entirely "external", in that there is no metdata in the module that says what version the module is.

TO CONTINUE.