I am trying to create a CI for Terraform code.
The first job is a linter, which should run only if Terraform files have been changed.
test_lint:
stage: lint
script:
- |
cd xxx
terraform init
terraform fmt -check -recursive -diff
terraform validate
rules:
- if: '$CI_COMMIT_BRANCH'
changes:
compare_to: 'refs/heads/main'
paths:
- 'projects/xxx/*'
- 'xxx/*'
- if: $CI_PIPELINE_SOURCE != "merge_request_event"
when: never
If the files have not been changed, I do not need to run the second job with terraform plan
and the third job with terraform apply
.
test_plan:
stage: plan
script:
- |
cd xxx
terraform init
terraform plan -out=$PLAN -parallelism=30
terraform show --json $PLAN | convert_report > $PLAN_JSON
artifacts:
paths:
- xxx/$PLAN
reports:
terraform: xxx/$PLAN_JSON
resource_group: terraform-state
test_apply:
stage: apply
script:
- |
cd xxx
terraform apply $PLAN
rules:
- if: '$CI_COMMIT_REF_NAME == "main"' ### Apply only after merging
resource_group: terraform-state
How can I skip the plan and apply jobs if the first job was not added to the pipeline? My MR settings does not allow merging if no pipelines have passed, so I need an additional dummy job that starts only when these three jobs are skipped, or not added to pipeline at all? after MR i don't need to run dummy job
I tried to use rules like in plan job for example
rules:
- if: '$CI_JOB_STATUS == "success" && $CI_JOB_STAGE == "lint"' # here i mean previous job
when: never
but it's not works
Maybe i just need to take names of previous job and add it to rule in next job with "when: never"
Like a
rules:
- if: $PREVIOUS JOB (or STAGE) = not created
when: never
Based on your comment and your request to a solution that does not duplicate code I would suggest you use a template for the needed rule:
.only_on_changes: &only_on_changes
if: '$CI_COMMIT_BRANCH'
changes:
compare_to: 'refs/heads/main'
paths:
- 'projects/xxx/*'
- 'xxx/*'
test_lint:
stage: lint
script:
- |
cd xxx
terraform init
terraform fmt -check -recursive -diff
terraform validate
rules:
- *only_on_changes
- if: $CI_PIPELINE_SOURCE != "merge_request_event"
when: never
test_plan:
stage: plan
script:
- |
cd xxx
terraform init
terraform plan -out=$PLAN -parallelism=30
terraform show --json $PLAN | convert_report > $PLAN_JSON
artifacts:
paths:
- xxx/$PLAN
reports:
terraform: xxx/$PLAN_JSON
rules:
- *only_on_changes
resource_group: terraform-state
test_apply:
stage: apply
script:
- |
cd xxx
terraform apply $PLAN
rules:
- *only_on_changes
- if: '$CI_COMMIT_REF_NAME == "main"' ### Apply only after merging
resource_group: terraform-state
If you want another job that only runs whenever the previous rule does not apply you could negate it and add it to your dummy job:
.only_on_no_changes: &only_on_no_changes
if: '$CI_COMMIT_BRANCH'
changes:
compare_to: 'refs/heads/main'
paths:
- 'projects/xxx/*'
- 'xxx/*'
when: never
dummy_job:
stage: apply
script:
- echo "Dummy Job"
rules:
- *only_on_no_changes
- when: always