Search code examples
terraformgitlab

Gitlab CI/CD pipeline not destroying created Terraform created resources


My pipeline successfully deploys stuff into my Hetzner account. But when I run destroy it says "No objects need to be destroyed."

Created resources are VMs. There is no more detail to add.

.gitlab-ci-yml:

stages:
  - validate
  - plan
  - apply
  - destroy
image:
  name: hashicorp/terraform:light
  entrypoint:
    - '/usr/bin/env'
    - 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
before_script:
  - export HCLOUD_TOKEN=${HCLOUD_TOKEN}
  - rm -rf .terraform
  - terraform --version
  - terraform init

validate:
  stage: validate
  script:
    - terraform validate

plan:
  stage: plan
  script:
    - terraform plan -out "planfile" --var-file=secret.tfvars
  dependencies:
    - validate
  artifacts:
    paths:
      - planfile

apply:
  stage: apply
  script:
    - terraform apply -input=false "planfile"
  dependencies:
    - plan
  when: manual

destroy:
  stage: destroy
  script:
    - terraform destroy --var-file=secret.tfvars
  when: manual
  dependencies: 
    - apply

Solution

  • The terraform state file is not available to your destroy job. It seems like you use a local backend, and the terraform state file is not shared between the apply and the destroy job.

    The quickest solution would be if you expose it as an artifact, as you did with the plan file between the plan and the apply job.

    apply:
      stage: apply
      script:
        - terraform apply -input=false "planfile"
      dependencies:
        - plan
      when: manual
      artifacts:
        paths:
          - terraform.tfstate
    
    destroy:
      stage: destroy
      script:
        - terraform destroy --var-file=secret.tfvars
      when: manual
      dependencies: 
        - apply    
    

    You can alternatively pass it on as part of the cache, by adding a global cache:

    cache:
      key: terraform-cache
      paths:
        - .terraform/
        - .terraform.tfstate
    

    Another alternative, would be storing your state file in Gitlab itself. Gitlab provides helpers for that Gitlab terraform state helpers including image.

    Here is what you need for a quick start, replace you code of parts of it with that and the included yml filers, do take care of everything in an advanced way, integrating terraform ideally within gitlab. To let Terraform know that it uses an http backend your backend.tf should look like below. And i'd remove your before script terraform init and other commands, as this is all managed within the helpers for you:

    terraform {
     backend "http" {}
    }