Commit e7c245d0 authored by Pierre Smeyers's avatar Pierre Smeyers
Browse files

feat(tf-publish): add terraform module publish support

parent 13741fa5
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -548,6 +548,34 @@ In order to generate your documentation with the right format and options, you s
As long as you don't, this job will simply generate the [pretty](https://terraform-docs.io/reference/pretty/)
doc format in the output console.

### `tf-publish-module` job

Publish your Terraform project as a module to GitLab's [Terraform Module Registry](https://docs.gitlab.com/ee/user/packages/terraform_module_registry/).

When enabled, this job triggers on a Git tag with semantic version pattern (`v?[0-9]+\.[0-9]+\.[0-9]+`, _configurable_) and publishes the module with the same version.

| Name                 | description                                                          | default value        |
| -------------------- | -------------------------------------------------------------------- | -------------------- |
| `TF_PUBLISH_ENABLED` | Set to `true` to enable Terraform Module Publish                     | _none_ (disabled) |
| `TF_PUBLISH_IMAGE`   | Container image used to publish module.                              | `registry.hub.docker.com/curlimages/curl:latest` |
| `TF_MODULE_NAME`     | The module name. May not contain any spaces or underscores.          | `$CI_PROJECT_NAME` |
| `TF_MODULE_SYSTEM`   | The module system or provider (example: `local`, `aws`, `google`).   | `local` |
| `TF_MODULE_VERSION`  | The module version. It must be valid according to the [semantic versioning](https://semver.org/) specification. | `$CI_COMMIT_TAG` _(leave default unless you have good reasons to override)_ |
| `TF_MODULE_FILES`    | Glob patterns matching files to include into the Terraform module (:warning: does not support double star). | `*.tf *.tpl *.md`|

#### Example: publish module with sub-modules

By default the template has the right configuration to publish a single module Terraform project (with `tf`, `tpl` and `md` files).

If you're willing to publish a more complex module, possibly with submodules, then you'll have to override the default `TF_MODULE_FILES` variable, with
something like the following:

```yaml
variables:
  # grab submodules from modules/*, templates from templates/ and examples from examples/
  TF_MODULE_FILES: "*.tf *.md templates/* modules/*/*.tf modules/*/*.md examples/*.tf examples/*.md"
```

## Variants

The Terraform template can be used in conjunction with template variants to cover specific cases.
+36 −0
Original line number Diff line number Diff line
@@ -203,6 +203,42 @@
        }
      ]
    },
    {
      "id": "tfpublish",
      "name": "publish module",
      "description": "Publish a Terraform module to GitLab's [Terraform Module Registry](https://docs.gitlab.com/ee/user/packages/terraform_module_registry/)",
      "enable_with": "TF_PUBLISH_ENABLED",
      "variables": [
        {
          "name": "TF_PUBLISH_IMAGE",
          "description": "container image used to publish module",
          "default": "registry.hub.docker.com/curlimages/curl:latest",
          "advanced": true
        },
        {
          "name": "TF_MODULE_NAME",
          "description": "The module name. May not contain any spaces or underscores.",
          "default": "$CI_PROJECT_NAME",
          "advanced": true
        },
        {
          "name": "TF_MODULE_SYSTEM",
          "description": "The module system or provider (example: `local`, `aws`, `google`)",
          "default": "local"
        },
        {
          "name": "TF_MODULE_VERSION",
          "description": "The module version. It must be valid according to the [semantic versioning](https://semver.org/) specification.",
          "default": "$CI_COMMIT_TAG",
          "advanced": true
        },
        {
          "name": "TF_MODULE_FILES",
          "description": "Glob patterns matching files to include into the Terraform module (:warning: does not support double star)",
          "default": "*.tf *.tpl *.md"
        }
      ]
    },
    {
      "id": "review",
      "name": "Review",
+37 −0
Original line number Diff line number Diff line
@@ -74,6 +74,12 @@ variables:
  TF_DOCS_IMAGE: "quay.io/terraform-docs/terraform-docs:edge"
  TF_DOCS_CONFIG: ".terraform-docs.yml"
  TF_DOCS_OUTPUT_DIR: "docs"
  # tf-module-publish job config
  TF_PUBLISH_IMAGE: "registry.hub.docker.com/curlimages/curl:latest"
  TF_MODULE_NAME: ${CI_PROJECT_NAME}
  TF_MODULE_SYSTEM: local
  TF_MODULE_VERSION: "${CI_COMMIT_TAG}"
  TF_MODULE_FILES: "*.tf *.tpl *.md"

  # root module directory
  TF_PROJECT_DIR: "."
@@ -87,12 +93,15 @@ variables:
  PROD_REF: '/^(master|main)$/'
  # default integration ref name (pattern)
  INTEG_REF: '/^develop$/'
  # default release tag name (pattern)
  RELEASE_REF: '/^v?[0-9]+\.[0-9]+\.[0-9]+$/'

# allowed stages depend on your template type (see: https://to-be-continuous.gitlab.io/doc/understand/#generic-pipeline-stages)
stages:
  - build
  - test
  - infra
  - publish
  - infra-prod

.tf-scripts: &tf-scripts |
@@ -867,6 +876,34 @@ tf-docs:
    # only if $TF_DOCS_ENABLED set
    - if: '$TF_DOCS_ENABLED == "true"'

tf-publish-module:
  stage: publish
  image: $TF_PUBLISH_IMAGE
  before_script:
    - *tf-scripts
    - install_ca_certs "${CUSTOM_CA_CERTS:-$DEFAULT_CA_CERTS}"
    - cd "$TF_PROJECT_DIR"
  script:
    - tf_module_archive="/tmp/${TF_MODULE_NAME}-${TF_MODULE_SYSTEM}-${TF_MODULE_VERSION}.tgz"
    - log_info "Build module package \\e[33;1m${TF_MODULE_NAME}/${TF_MODULE_SYSTEM}:${TF_MODULE_VERSION}\\e[0m..."
    # filter out glob patterns matching no file
    - |
      {
        for item in $TF_MODULE_FILES
        do
          if [[ -f "$item" ]]; then echo "$item"; fi
        done
      } | tar -cvzf "$tf_module_archive" -T -
    - log_info "Publish module \\e[33;1m${TF_MODULE_NAME}/${TF_MODULE_SYSTEM}:${TF_MODULE_VERSION}\\e[0m..."
    - |
      curl --fail --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file "$tf_module_archive" "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/terraform/modules/${TF_MODULE_NAME}/${TF_MODULE_SYSTEM}/${TF_MODULE_VERSION}/file"
  rules:
    # exclude if $TF_PUBLISH_ENABLED not set
    - if: '$TF_PUBLISH_ENABLED != "true"'
      when: never
    # on tag with release pattern: auto
    - if: '$CI_COMMIT_TAG =~ $RELEASE_REF'

# =============================================================================
# === Review env jobs
# =============================================================================