diff --git a/src/gitlab-tofu.sh b/src/gitlab-tofu.sh index d168c5814b4defaa1791f53bc275c465bb29a203..9282763d5e39d4e8de75f79c4de0c5fe9af2a48b 100644 --- a/src/gitlab-tofu.sh +++ b/src/gitlab-tofu.sh @@ -62,25 +62,33 @@ if [ -n "${TF_STATE_NAME}" ] && [ -z "${TF_ADDRESS}" ]; then TF_ADDRESS="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE_NAME}" fi +if [ -z "${TF_PLAN_NAME}" ]; then + TF_PLAN_NAME=plan +fi + +if [ -z "${TF_APPLY_NO_PLAN}" ]; then + TF_APPLY_NO_PLAN=false +fi + # If TF_ROOT is set then use the -chdir option if [ -n "${TF_ROOT}" ]; then abs_tf_root=$(cd "${CI_PROJECT_DIR}"; realpath "${TF_ROOT}") TF_CHDIR_OPT="-chdir=${abs_tf_root}" - default_tf_plan_cache="${abs_tf_root}/plan.cache" - default_tf_plan_json="${abs_tf_root}/plan.json" + default_tf_plan_cache="${abs_tf_root}/${TF_PLAN_NAME}.cache" + default_tf_plan_json="${abs_tf_root}/${TF_PLAN_NAME}.json" fi # If TF_PLAN_CACHE is not set then use either the plan.cache file within TF_ROOT if set, or plan.cache in CWD if [ -z "${TF_PLAN_CACHE}" ]; then - TF_PLAN_CACHE="${default_tf_plan_cache:-plan.cache}" + TF_PLAN_CACHE="${default_tf_plan_cache:-${TF_PLAN_NAME}.cache}" fi # If TF_PLAN_JSON is not set then use either the plan.json file within TF_ROOT if set, or plan.json in CWD if [ -z "${TF_PLAN_JSON}" ]; then - TF_PLAN_JSON="${default_tf_plan_json:-plan.json}" + TF_PLAN_JSON="${default_tf_plan_json:-${TF_PLAN_NAME}.json}" fi # Set variables for the HTTP backend to default to TF_* values @@ -158,7 +166,11 @@ if [ $sourced -eq 0 ]; then case "${1}" in "apply") $TF_IMPLICIT_INIT && terraform_init - tofu "${TF_CHDIR_OPT}" "${@}" -input=false "${TF_PLAN_CACHE}" + if [ "$TF_APPLY_NO_PLAN" = false ]; then + tofu "${TF_CHDIR_OPT}" "${@}" -input=false "${TF_PLAN_CACHE}" + else + tofu "${TF_CHDIR_OPT}" "${@}" -input=false + fi ;; "destroy") $TF_IMPLICIT_INIT && terraform_init diff --git a/templates/apply.yml b/templates/apply.yml index b4c321f7bea6712d33c937e02a8771ee3456c358..235c6e70488378d9b75d8f59acc50e0f858b86a8 100644 --- a/templates/apply.yml +++ b/templates/apply.yml @@ -50,6 +50,9 @@ spec: state_name: default: default description: 'Remote OpenTofu state name.' + plan_name: + default: 'plan' + description: 'The name of the plan file to use. Will be used for TF_PLAN_CACHE and TF_PLAN_JSON.' auto_apply: default: false type: boolean @@ -76,6 +79,7 @@ spec: __CACHE_KEY_HACK: "$[[ inputs.root_dir ]]" TF_ROOT: $[[ inputs.root_dir ]] TF_STATE_NAME: $[[ inputs.state_name ]] + TF_PLAN_NAME: $[[ inputs.plan_name ]] image: name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]' script: diff --git a/templates/destroy.yml b/templates/destroy.yml index 8c2661390c8af99198afeea57df894396f06d9b7..cd9a743184f27352aac9d355f297f24645db7c47 100644 --- a/templates/destroy.yml +++ b/templates/destroy.yml @@ -50,6 +50,13 @@ spec: state_name: default: default description: 'Remote OpenTofu state name.' + no_plan: + default: true + type: boolean + description: 'Whether a plan file should be used.' + plan_name: + default: 'destroy-plan' + description: 'The name of the plan file to use. Will be used for TF_PLAN_CACHE and TF_PLAN_JSON.' auto_destroy: default: false type: boolean @@ -75,6 +82,8 @@ spec: __CACHE_KEY_HACK: "$[[ inputs.root_dir ]]" TF_ROOT: $[[ inputs.root_dir ]] TF_STATE_NAME: $[[ inputs.state_name ]] + TF_APPLY_NO_PLAN: $[[ inputs.no_plan ]] + TF_PLAN_NAME: $[[ inputs.plan_name ]] image: name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]' script: diff --git a/templates/plan.yml b/templates/plan.yml index bcaed749b3b8a097b888607fd1e7c65a0ed2a683..a28b9c614cf3439d695691141beacf8a40ddcfbf 100644 --- a/templates/plan.yml +++ b/templates/plan.yml @@ -50,10 +50,13 @@ spec: state_name: default: default description: 'Remote OpenTofu state name.' + plan_name: + default: 'plan' + description: 'The name of the plan cache and plan json file.' destroy: default: false type: boolean - description: 'Indicate if the plan should be a destroy plan' + description: 'Indicate if the plan should be a destroy plan. You may want to change the `plan_name` input to `destroy-plan` which is the default for the destroy job.' --- @@ -72,9 +75,9 @@ spec: # See: https://docs.gitlab.com/ee/ci/yaml/#artifactspublic public: false paths: - - $TF_ROOT/plan.cache + - $TF_ROOT/$[[ inputs.plan_name ]].cache reports: - terraform: $TF_ROOT/plan.json + terraform: $TF_ROOT/$[[ inputs.plan_name]].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. @@ -89,6 +92,7 @@ spec: __CACHE_KEY_HACK: "$[[ inputs.root_dir ]]" TF_ROOT: $[[ inputs.root_dir ]] TF_STATE_NAME: $[[ inputs.state_name ]] + TF_PLAN_NAME: $[[ inputs.plan_name ]] image: name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]' script: diff --git a/templates/validate-plan-destroy.yml b/templates/validate-plan-destroy.yml index 7593c8f5f085930a868eb3efd5e98d55b57c28aa..b94fc546fab0e98a9456fa4df5b7b354669a86ac 100644 --- a/templates/validate-plan-destroy.yml +++ b/templates/validate-plan-destroy.yml @@ -53,6 +53,9 @@ spec: state_name: default: default description: 'Remote OpenTofu state name.' + plan_name: + default: 'destroy-plan' + description: 'Destroy plan file name.' auto_destroy: default: false type: boolean @@ -90,6 +93,7 @@ include: image_name: $[[ inputs.image_name ]] root_dir: $[[ inputs.root_dir ]] state_name: $[[ inputs.state_name ]] + plan_name: $[[ inputs.plan_name ]] destroy: true - local: '/templates/destroy.yml' inputs: @@ -101,6 +105,8 @@ include: image_name: $[[ inputs.image_name ]] root_dir: $[[ inputs.root_dir ]] state_name: $[[ inputs.state_name ]] + no_plan: false + plan_name: $[[ inputs.plan_name ]] auto_destroy: $[[ inputs.auto_destroy ]] - local: '/templates/delete-state.yml' inputs: