spec: inputs: # Stages stage_validate: default: 'validate' description: 'Defines the validate stage. This stage includes the `fmt` and `validate` jobs.' stage_build: default: 'build' description: 'Defines the build stage. This stage includes the `plan` job.' stage_deploy: default: 'deploy' description: 'Defines the deploy stage. This stage includes the `apply` job.' stage_cleanup: default: 'cleanup' description: 'Defines the cleanup stage. This stage includes the `destroy` and `delete-state` jobs.' # Versions # This version is only required, because we cannot access the context of the component, # see https://gitlab.com/gitlab-org/gitlab/-/issues/438275 version: default: 'latest' description: 'Version of this component. Has to be the same as the one in the component include entry.' opentofu_version: default: '1.6.0' options: - '$OPENTOFU_VERSION' - '1.6.0' - '1.6.0-rc1' description: 'OpenTofu version that should be used.' # Images image_registry_base: default: '$CI_REGISTRY/components/opentofu' # FIXME: not yet possible because of https://gitlab.com/gitlab-org/gitlab/-/issues/438722 # gitlab_opentofu_image: # # FIXME: This should reference the component tag that is used. # # Currently, blocked by https://gitlab.com/gitlab-org/gitlab/-/issues/438275 # # default: '$CI_REGISTRY/components/opentofu/gitlab-opentofu:$[[ inputs.opentofu_version ]]' # default: '$CI_REGISTRY/components/opentofu/gitlab-opentofu:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]' # description: 'Tag of the gitlab-opentofu image.' # Configuration root_dir: default: ${CI_PROJECT_DIR} description: 'Root directory for the OpenTofu project.' state_name: default: default description: 'Remote OpenTofu state name.' auto_apply: default: 'false' description: 'Whether the apply job is manual or automatically run.' auto_destroy: default: 'false' description: 'Whether the destroy job is manual or automatically run.' create_destroy_job: default: 'false' description: 'Wheather the destroy job should be created or not.' create_delete_state_job: default: 'false' description: 'Wheather the delete-state job should be created or not.' --- .default: image: name: '$[[ inputs.image_registry_base ]]/gitlab-opentofu:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]' variables: TF_ROOT: $[[ inputs.root_dir ]] TF_STATE_NAME: $[[ inputs.state_name ]] cache: key: "$[[ inputs.root_dir ]]" paths: - $[[ inputs.root_dir ]]/.terraform/ fmt: extends: .default stage: $[[ inputs.stage_validate ]] needs: [] script: - gitlab-tofu fmt allow_failure: true rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_OPEN_MERGE_REQUESTS # Don't add it to a *branch* pipeline if it's already in a merge request pipeline. when: never - if: $CI_COMMIT_BRANCH # If there's no open merge request, add it to a *branch* pipeline instead. validate: extends: .default stage: $[[ inputs.stage_validate ]] script: - gitlab-tofu validate rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_OPEN_MERGE_REQUESTS # Don't add it to a *branch* pipeline if it's already in a merge request pipeline. when: never - if: $CI_COMMIT_BRANCH # If there's no open merge request, add it to a *branch* pipeline instead. plan: extends: .default stage: $[[ inputs.stage_build ]] script: - gitlab-tofu plan - gitlab-tofu plan-json environment: name: $[[ inputs.state_name ]] action: prepare resource_group: $[[ inputs.state_name ]] artifacts: # Terraform's cache files can include secrets which can be accidentally exposed. # Please exercise caution when utilizing secrets in your Terraform infrastructure and # consider limiting access to artifacts or take other security measures to protect sensitive information. # # The next line, which disables public access to pipeline artifacts, is not available on GitLab.com. # See: https://docs.gitlab.com/ee/ci/yaml/#artifactspublic public: false paths: - $[[ inputs.root_dir ]]/plan.cache reports: terraform: $[[ inputs.root_dir ]]/plan.json rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_OPEN_MERGE_REQUESTS # Don't add it to a *branch* pipeline if it's already in a merge request pipeline. when: never - if: $CI_COMMIT_BRANCH # If there's no open merge request, add it to a *branch* pipeline instead. apply: extends: .default stage: $[[ inputs.stage_deploy ]] script: - gitlab-tofu apply environment: name: $[[ inputs.state_name ]] action: start resource_group: $[[ inputs.state_name ]] rules: - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && "$[[ inputs.auto_apply ]]" == "true"' - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH when: manual destroy: extends: .default stage: $[[ inputs.stage_cleanup ]] script: - gitlab-tofu destroy environment: name: $[[ inputs.state_name ]] action: stop resource_group: $[[ inputs.state_name ]] rules: - if: '"$[[ inputs.create_destroy_job ]]" != "true"' when: never - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && "$[[ inputs.auto_destroy ]]" == "true"' - when: manual delete-state: extends: .default stage: $[[ inputs.stage_cleanup ]] needs: [destroy] resource_group: $[[ inputs.state_name ]] script: - curl --request DELETE -u "gitlab-ci-token:$CI_JOB_TOKEN" "$CI_API_V4_URL/projects/$CI_PROJECT_ID/terraform/state/$[[ inputs.state_name ]]" rules: - if: '"$[[ inputs.create_delete_state_job ]]" != "true"' when: never - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' - when: manual