From 2fa42374a49427e28ea17b75d1bae1e3d73d5d2b Mon Sep 17 00:00:00 2001
From: Timo Furrer <tfurrer@gitlab.com>
Date: Fri, 26 Jan 2024 11:18:30 +0100
Subject: [PATCH] Add destroy pipeline

---
 templates/destroy-pipeline.yml                | 91 +++++++++++++++++++
 templates/full-pipeline.yml                   | 22 ++---
 .../integration-tests/Defaults.gitlab-ci.yml  |  4 -
 3 files changed, 100 insertions(+), 17 deletions(-)
 create mode 100644 templates/destroy-pipeline.yml

diff --git a/templates/destroy-pipeline.yml b/templates/destroy-pipeline.yml
new file mode 100644
index 0000000..1da1ab0
--- /dev/null
+++ b/templates/destroy-pipeline.yml
@@ -0,0 +1,91 @@
+spec:
+  inputs:
+    # Stages
+    stage_plan:
+      default: 'plan'
+      description: 'Defines the plan stage. This stage includes the `plan` job.'
+    stage_destroy:
+      default: 'destroy'
+      description: 'Defines the destroy stage. This stage includes the `destroy` and `delete-state` jobs.'
+
+    # Jobs
+    plan_job_name:
+      default: 'plan'
+      description: 'Name of the plan job.'
+
+    # 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.1'
+      options:
+        - '$OPENTOFU_VERSION'
+        - '1.6.1'
+        - '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_destroy:
+      default: 'false'
+      description: 'Whether the destroy job is manual or automatically run.'
+
+---
+
+include:
+  - local: '/templates/plan.yml'
+    inputs:
+      as: $[[ inputs.plan_job_name ]]
+      stage: $[[ inputs.stage_build ]]
+      version: $[[ inputs.version ]]
+      opentofu_version: $[[ inputs.opentofu_version ]]
+      image_registry_base: $[[ inputs.image_registry_base ]]
+      root_dir: $[[ inputs.root_dir ]]
+      state_name: $[[ inputs.state_name ]]
+      plan: destroy-plan.cache
+      destroy_plan: true
+  - local: '/templates/destroy.yml'
+    inputs:
+      as: 'destroy'
+      stage: $[[ inputs.stage_cleanup ]]
+      version: $[[ inputs.version ]]
+      opentofu_version: $[[ inputs.opentofu_version ]]
+      image_registry_base: $[[ inputs.image_registry_base ]]
+      root_dir: $[[ inputs.root_dir ]]
+      state_name: $[[ inputs.state_name ]]
+      auto_destroy: $[[ inputs.auto_apply ]]
+      plan: $[[ inputs.root_dir ]]/destroy-plan.cache
+  - local: '/templates/delete-state.yml'
+    inputs:
+      as: 'delete-state'
+      stage: $[[ inputs.stage_cleanup ]]
+      state_name: $[[ inputs.state_name ]]
+
+# NOTE: we have to define this `needs` here, because inputs don't support arrays, yet.
+destroy:
+  needs: 
+    - '$[[ inputs.plan_job_name ]]'
+
+delete-state:
+  needs: [destroy]
diff --git a/templates/full-pipeline.yml b/templates/full-pipeline.yml
index 86323f2..450dfb7 100644
--- a/templates/full-pipeline.yml
+++ b/templates/full-pipeline.yml
@@ -94,22 +94,18 @@ include:
       root_dir: $[[ inputs.root_dir ]]
       state_name: $[[ inputs.state_name ]]
       auto_apply: $[[ inputs.auto_apply ]]
-  - local: '/templates/destroy.yml'
+
+destroy:
+  stage: cleanup
+  trigger:
+    include: /templates/destroy-pipeline.yml
+    strategy: depend
     inputs:
-      as: 'destroy'
-      stage: $[[ inputs.stage_cleanup ]]
       version: $[[ inputs.version ]]
       opentofu_version: $[[ inputs.opentofu_version ]]
       image_registry_base: $[[ inputs.image_registry_base ]]
       root_dir: $[[ inputs.root_dir ]]
       state_name: $[[ inputs.state_name ]]
-      auto_destroy: $[[ inputs.auto_apply ]]
-  - local: '/templates/delete-state.yml'
-    inputs:
-      as: 'delete-state'
-      stage: $[[ inputs.stage_cleanup ]]
-      state_name: $[[ inputs.state_name ]]
-
-# NOTE: we have to define this `needs` here, because inputs don't support arrays, yet.
-delete-state:
-  needs: [destroy]
+      auto_destroy: $[[ inputs.auto_destroy ]]
+  rules:
+    - when: manual
diff --git a/tests/integration-tests/Defaults.gitlab-ci.yml b/tests/integration-tests/Defaults.gitlab-ci.yml
index 4e856f3..ee8772c 100644
--- a/tests/integration-tests/Defaults.gitlab-ci.yml
+++ b/tests/integration-tests/Defaults.gitlab-ci.yml
@@ -25,7 +25,3 @@ apply:
 
 destroy:
   rules: [{when: always}]
-
-delete-state:
-  rules: [{when: always}]
-
-- 
GitLab