Support the building of Terraform/OpenTofu modules
The purpose is to be able to write modules in a richer environment, but then publish it to the more restrictive style (in our opinion) that Hashicorp requires.
By a richer environment, we would like to achieve:
- Develop one or more Terraform/OpenTofu modules within a Gradle project structure, including multi-project configurations.
- Write documentation in Asciidoc or Markdown.
- Publish to Terraform/OpenTofu public registries
- Publish to any Git repository with version tagging.
Core functionality
-
Publishable modules will be located in the src/tf-modules
by default -
Extensions terraform
&opentofu
be will extended with amodules
section, which will define modules by name i.e.terraform.modules.xyz
will be located atsrc/tf-modules/xyz
by default. -
Core functionality will be in the base plugin, but the publishers will be in a plugin will be called org.ysb33r.(terraform|opentofu).module-publisher
-
The version is derived from the subproject. -
The name of the module in Gradle will be lower-cased and become the publishable module name. The module may not be called terraform
ortofu
oropentofu
. -
The main provider must be configured, which will then form part of the module name in the form terraform-PROVIDER-NAME
. -
Needs to be testable - see #94 (closed). -
Optionally include 'tests' dir when publishing.
Validation:
-
Needs README.md. As an alternative, will look for README.adoc if theorg.ysb33r.(terraform|opentofu).module-publisher.adoc
is applied.-
Needs outputs.tf
,variables.tf
,main.tf
. -
Configurable to fail if child directories, except modules
&examples
, exist. Defaultfalse
, but see below. -
Allow additional directories to be added to the above list. -
Configurable to fail if LICENSE
is not present. Defaultfalse
, but seebelow
.
terraform {
modules {
myModule1 {
failOnExtraDirectories()
allowExtraDirectories 'foo', 'bar'
failOnMissingLicense()
includeTestsWhenPublishing()
provider = 'aws'
}
myModule2 {
}
}
moduleRepositories {
myGenericGit(org.ysb33r.gradle.terraform.publisher.Git) {
// Repo-specific configration
someConfig = true
module('myModule') {
// configure module-repo link
}
}
myGitlab(org.ysb33r.gradle.terraform.publisher.Gitlab) {
}
myGithub(org.ysb33r.gradle.terraform.publisher.Github) {
}
publicTerraform(org.ysb33r.gradle.terraform.publisher.Registry) {
}
}
}
Tasks
A module will register a number of tasks.
Assum,ing the module is called xyz
then,
-
Need to determine whether validate is a valid use-case for a module. It is probably better to use tests to validate.tfModuleXyzValidate
(ortofuModuleXyzValidate
): Runs thevalidate
command. -
tfModuleXyzTest
: Runs thetest
command. -
tfModuleXyzPublishAll
: Publishes to all targets -
tfModuleXyzCheckAll
: Checks all publications for valid conditions. -
tfModuleFormat
: Formats the source code of the module.
Additional tasks will be created for each publication target.
If the module has publishTo 'myGitlab', 'publicTerraform'
, then the following tasks will be created.
tfModuleXyzPublishMyGitlab
tfModuleXyzPublishPublicTerraform
tfModuleXyzCheckMyGitlab
tfModuleXyzCheckPublicTerraform
Publish to Git repo.
-
Will utilise the Git Publish plugin from YSF. -
tfModulePublishAll
task. -
No module is allowed to be called publish
.
Publishing to the Terraform/OpenTofu Registry
-
Enforce LICENSE
. -
Enforce no child directories, except modules
&examples
. -
Collapse all source files intoSee #116 instead.main.tf
, so that only the three core files are published. -
Configure preferred tagging format meaning prefixed with v
or not. Default is withv
. -
Will only publish if semantic versioned without any postfixes. -
Push to Github only. It will be the responsibility of the module author to configure one Github repo per module. (It might be possible to check for duplication within one subproject, but this is limited, so it will not be implemented). The linked repo will be checked and if the URL is not github.com
, it will fail.
NOTE: Gradle will not check whether the Github repo is private or public.
See Publish Terraform Modules & Publish OpenTofu Modules for more information.
Documentation generation
Better to handle this as a separate issue: See #115 (closed).
Breaking change
-
It will no longer be possible to name a Terraform/OpenTofu source set module
.