Skip to content
Snippets Groups Projects
Commit 8c16675c authored by Timo Furrer's avatar Timo Furrer
Browse files

Merge branch 'plan-detailed-exitcode' into 'main'

Support `warning_on_none_empty_plan` input in `plan` job.

Closes #64

See merge request components/opentofu!170
parents f438fba4 27a482a7
Branches
Tags
No related merge requests found
...@@ -237,9 +237,14 @@ if [ $sourced -eq 0 ]; then ...@@ -237,9 +237,14 @@ if [ $sourced -eq 0 ]; then
terraform_init "${@}" terraform_init "${@}"
;; ;;
"plan") "plan")
plan_args=''
if [ "${OPENTOFU_COMPONENT_USE_DETAILED_EXITCODE}" = 'true' ]; then
plan_args='-detailed-exitcode'
fi
$TF_IMPLICIT_INIT && terraform_init $TF_IMPLICIT_INIT && terraform_init
# shellcheck disable=SC2086 # shellcheck disable=SC2086
tofu "${TF_CHDIR_OPT}" "${@}" -input=false -out="${TF_PLAN_CACHE}" ${var_file_args} tofu "${TF_CHDIR_OPT}" "${@}" -input=false -out="${TF_PLAN_CACHE}" ${var_file_args} ${plan_args}
;; ;;
"plan-json") "plan-json")
tofu "${TF_CHDIR_OPT}" show -json "${TF_PLAN_CACHE}" | \ tofu "${TF_CHDIR_OPT}" show -json "${TF_PLAN_CACHE}" | \
......
...@@ -155,6 +155,10 @@ spec: ...@@ -155,6 +155,10 @@ spec:
- when: manual - when: manual
type: array type: array
description: 'Defines the `rules` of the `delete-state` job.' description: 'Defines the `rules` of the `delete-state` job.'
warning_on_none_empty_plan:
default: false
type: boolean
description: 'Whether to mark the job with a warning if the plan contains a diff.'
--- ---
...@@ -220,6 +224,7 @@ include: ...@@ -220,6 +224,7 @@ include:
artifacts_access: $[[ inputs.plan_artifacts_access ]] artifacts_access: $[[ inputs.plan_artifacts_access ]]
var_file: $[[ inputs.var_file ]] var_file: $[[ inputs.var_file ]]
rules: $[[ inputs.plan_rules ]] rules: $[[ inputs.plan_rules ]]
warning_on_none_empty_plan: $[[ inputs.warning_on_none_empty_plan ]]
- local: '/templates/apply.yml' - local: '/templates/apply.yml'
inputs: inputs:
as: '$[[ inputs.job_name_prefix ]]apply' as: '$[[ inputs.job_name_prefix ]]apply'
...@@ -262,5 +267,5 @@ include: ...@@ -262,5 +267,5 @@ include:
# job template, but the issue is that we cannot default it to something # job template, but the issue is that we cannot default it to something
# meaningful other than `null` - but `null` is also not yet supported, see # meaningful other than `null` - but `null` is also not yet supported, see
# https://gitlab.com/gitlab-org/gitlab/-/issues/440468 # https://gitlab.com/gitlab-org/gitlab/-/issues/440468
$[[ inputs.job_name_prefix ]]delete-state: '$[[ inputs.job_name_prefix ]]delete-state':
needs: ['$[[ inputs.job_name_prefix ]]destroy'] needs: ['$[[ inputs.job_name_prefix ]]destroy']
...@@ -101,6 +101,10 @@ spec: ...@@ -101,6 +101,10 @@ spec:
default: '' default: ''
type: string type: string
description: 'Path to a variables files relative to root_dir.' description: 'Path to a variables files relative to root_dir.'
warning_on_none_empty_plan:
default: false
type: boolean
description: 'Whether to mark the job with a warning if the plan contains a diff.'
--- ---
...@@ -167,6 +171,7 @@ include: ...@@ -167,6 +171,7 @@ include:
state_name: $[[ inputs.state_name ]] state_name: $[[ inputs.state_name ]]
plan_name: $[[ inputs.plan_name ]] plan_name: $[[ inputs.plan_name ]]
var_file: $[[ inputs.var_file ]] var_file: $[[ inputs.var_file ]]
warning_on_none_empty_plan: $[[ inputs.warning_on_none_empty_plan ]]
- local: '/templates/apply.yml' - local: '/templates/apply.yml'
inputs: inputs:
as: '$[[ inputs.job_name_prefix ]]apply' as: '$[[ inputs.job_name_prefix ]]apply'
......
...@@ -99,11 +99,31 @@ spec: ...@@ -99,11 +99,31 @@ spec:
default: pull-push default: pull-push
type: string type: string
description: 'Defines the cache policy of the job.' description: 'Defines the cache policy of the job.'
warning_on_none_empty_plan:
default: false
type: boolean
description: 'Whether to mark the job with a warning if the plan contains a diff.'
--- ---
# NOTE: the two following jobs are necessary to implement the abstraction logic
# required for the `warning_on_none_empty_plan` input.
# Without any kind of flow control support for the GitLab CI YAML we cannot infer
# another value from the input. However, we can clearly apply "inheritance" to
# customize behavior related to the CI keywords that have otherwise nothing
# in common with the inputs value.
'.$[[ inputs.as ]]:detailed_exitcode:warning:false':
extends: null
'.$[[ inputs.as ]]:detailed_exitcode:warning:true':
allow_failure:
exit_codes: [2]
'$[[ inputs.as ]]': '$[[ inputs.as ]]':
stage: $[[ inputs.stage ]] stage: $[[ inputs.stage ]]
extends:
# NOTE: see the comment above. This is to support the `warning_on_none_empty_plan` input.
- '.$[[ inputs.as ]]:detailed_exitcode:warning:$[[ inputs.warning_on_none_empty_plan ]]'
environment: environment:
name: $[[ inputs.state_name ]] name: $[[ inputs.state_name ]]
action: prepare action: prepare
...@@ -131,6 +151,11 @@ spec: ...@@ -131,6 +151,11 @@ spec:
TF_STATE_NAME: $[[ inputs.state_name ]] TF_STATE_NAME: $[[ inputs.state_name ]]
TF_PLAN_NAME: $[[ inputs.plan_name ]] TF_PLAN_NAME: $[[ inputs.plan_name ]]
OPENTOFU_COMPONENT_VAR_FILE: '$[[ inputs.var_file ]]' OPENTOFU_COMPONENT_VAR_FILE: '$[[ inputs.var_file ]]'
OPENTOFU_COMPONENT_USE_DETAILED_EXITCODE: '$[[ inputs.warning_on_none_empty_plan ]]'
# NOTE: we rely on correct exitcode reporting behavior for the `warning_on_none_empty_plan` input
# behavior. However, when using bash the runner does not work properly without setting
# the feature flag below to `true`.
FF_USE_NEW_BASH_EVAL_STRATEGY: 'true'
image: image:
name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]-$[[ inputs.base_os ]]$[[ inputs.image_digest ]]' name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]-$[[ inputs.base_os ]]$[[ inputs.image_digest ]]'
script: script:
......
...@@ -125,6 +125,10 @@ spec: ...@@ -125,6 +125,10 @@ spec:
when: manual when: manual
type: array type: array
description: 'Defines the `rules` of the `apply` job.' description: 'Defines the `rules` of the `apply` job.'
warning_on_none_empty_plan:
default: false
type: boolean
description: 'Whether to mark the job with a warning if the plan contains a diff.'
--- ---
...@@ -172,6 +176,7 @@ include: ...@@ -172,6 +176,7 @@ include:
artifacts_access: $[[ inputs.plan_artifacts_access ]] artifacts_access: $[[ inputs.plan_artifacts_access ]]
var_file: $[[ inputs.var_file ]] var_file: $[[ inputs.var_file ]]
rules: $[[ inputs.plan_rules ]] rules: $[[ inputs.plan_rules ]]
warning_on_none_empty_plan: $[[ inputs.warning_on_none_empty_plan ]]
- local: '/templates/apply.yml' - local: '/templates/apply.yml'
inputs: inputs:
as: '$[[ inputs.job_name_prefix ]]apply' as: '$[[ inputs.job_name_prefix ]]apply'
......
...@@ -130,6 +130,10 @@ spec: ...@@ -130,6 +130,10 @@ spec:
- when: manual - when: manual
type: array type: array
description: 'Defines the `rules` of the `delete-state` job.' description: 'Defines the `rules` of the `delete-state` job.'
warning_on_none_empty_plan:
default: false
type: boolean
description: 'Whether to mark the job with a warning if the plan contains a diff.'
--- ---
...@@ -178,6 +182,7 @@ include: ...@@ -178,6 +182,7 @@ include:
destroy: true destroy: true
var_file: $[[ inputs.var_file ]] var_file: $[[ inputs.var_file ]]
rules: $[[ inputs.plan_rules ]] rules: $[[ inputs.plan_rules ]]
warning_on_none_empty_plan: $[[ inputs.warning_on_none_empty_plan ]]
- local: '/templates/destroy.yml' - local: '/templates/destroy.yml'
inputs: inputs:
as: '$[[ inputs.job_name_prefix ]]destroy' as: '$[[ inputs.job_name_prefix ]]destroy'
...@@ -206,5 +211,5 @@ include: ...@@ -206,5 +211,5 @@ include:
# job template, but the issue is that we cannot default it to something # job template, but the issue is that we cannot default it to something
# meaningful other than `null` - but `null` is also not yet supported, see # meaningful other than `null` - but `null` is also not yet supported, see
# https://gitlab.com/gitlab-org/gitlab/-/issues/440468 # https://gitlab.com/gitlab-org/gitlab/-/issues/440468
$[[ inputs.job_name_prefix ]]delete-state: '$[[ inputs.job_name_prefix ]]delete-state':
needs: ['$[[ inputs.job_name_prefix ]]destroy'] needs: ['$[[ inputs.job_name_prefix ]]destroy']
...@@ -111,6 +111,10 @@ spec: ...@@ -111,6 +111,10 @@ spec:
- if: $CI_COMMIT_BRANCH # If there's no open merge request, add it to a *branch* pipeline instead. - if: $CI_COMMIT_BRANCH # If there's no open merge request, add it to a *branch* pipeline instead.
type: array type: array
description: 'Defines the `rules` of the `plan` job.' description: 'Defines the `rules` of the `plan` job.'
warning_on_none_empty_plan:
default: false
type: boolean
description: 'Whether to mark the job with a warning if the plan contains a diff.'
--- ---
...@@ -158,3 +162,4 @@ include: ...@@ -158,3 +162,4 @@ include:
artifacts_access: $[[ inputs.artifacts_access ]] artifacts_access: $[[ inputs.artifacts_access ]]
var_file: $[[ inputs.var_file ]] var_file: $[[ inputs.var_file ]]
rules: $[[ inputs.plan_rules ]] rules: $[[ inputs.plan_rules ]]
warning_on_none_empty_plan: $[[ inputs.warning_on_none_empty_plan ]]
include:
- component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/plan@$CI_COMMIT_SHA
inputs:
image_registry_base: $GITLAB_OPENTOFU_IMAGE_BASE
version: $CI_COMMIT_SHA
base_os: $GITLAB_OPENTOFU_BASE_IMAGE_OS
opentofu_version: $OPENTOFU_VERSION
root_dir: $TEST_TF_ROOT
state_name: $TEST_TF_STATE_NAME
warning_on_none_empty_plan: true
# For CI Terraform state cleanup
- component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/delete-state@$CI_COMMIT_SHA
inputs:
state_name: $TEST_TF_STATE_NAME
rules: [{when: always}]
stages: [build, cleanup, verify]
verify:plan-job:has-warning-state:
stage: verify
needs: ['plan']
rules: [{when: always}]
image: alpine:latest
before_script:
- apk add --update curl jq
script:
- |
endpoint="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/pipelines/${CI_PIPELINE_ID}/jobs"
is_warning_job=$(curl --silent "$endpoint" | jq -r '.[] | select(.name == "plan") | [.status == "failed", .allow_failure == true] | all')
if [ "$is_warning_job" != 'true' ]; then
echo 'Error: the plan job was not in warning state.'
exit 1
else
echo 'Success: the plan job was in warning state.'
fi
...@@ -16,6 +16,7 @@ component: ...@@ -16,6 +16,7 @@ component:
- ModuleRelease - ModuleRelease
- Destroy - Destroy
- VarFile - VarFile
- WarningOnNoneEmptyPlan
GITLAB_OPENTOFU_BASE_IMAGE_OS: GITLAB_OPENTOFU_BASE_IMAGE_OS:
- alpine - alpine
- debian - debian
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment