# A set of jobs/functions to be extended.
image:
  name: registry.gitlab.com/chemin/vers/notre/image_docker/terraform:${TF_IMAGE_VERSION}

variables:
  # TF_DIR defines the folder in which terraform stack is located. All terraform commands are run inside this folder.
  TF_DIR: "."
  # TF_INPUT: 0 is equivalent to have -input=false on the command line
  TF_INPUT: 0
  # TF_IN_AUTOMATION: true adjusts terraform output
  TF_IN_AUTOMATION: "true"
  # Provide a Terraform variable with the repo URL. Just declare a string variable "git_url"
  TF_VAR_git_url: ${CI_PROJECT_URL}
  # Disable tflint when set to any value other than false
  DISABLE_TFLINT: "false"


########################################################################################################################
# Terraform standard workflow
########################################################################################################################

.init-validate:
  # Init and validate terraform configuration. This will also add TF_MODULES_PRIVATE_KEY env var to ~/.ssh/id_rsa.
  # The "validate" is executed by default in dev spot runners.
  tags:
    - dev
    - check
  before_script:
    - mkdir -p ~/.ssh
    - echo "${TF_MODULES_PRIVATE_KEY}" >> ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa && ssh-keyscan -t rsa gitlab.com >> ~/.ssh/known_hosts
    - cd ${TF_DIR}
    - terraform init
  script:
    - terraform validate
    - terraform fmt -check=true -diff=true -recursive
  artifacts:
    paths:
      - ${TF_DIR}/.terraform
      - ${TF_DIR}/.terraform.lock.hcl
      - ${TF_DIR}/terraform.d

.plan:
  # Run terraform plan on the workspace defined in ${TF_WORKSPACE}
  before_script:
    - cd ${TF_DIR}
    - if [[ ${DISABLE_TFLINT} == "false" ]]; then tflint; fi # tflint needs to be run on a specific workspace. This is why we put it here.
    # An alias command to make terraform plan suitable for Gitlab report: https://docs.gitlab.com/ee/user/infrastructure/mr_integration.html
    - shopt -s expand_aliases
    - alias convert_report="jq -r '([.resource_changes[]?.change.actions?]|flatten)|{\"create\":(map(select(.==\"create\"))|length),\"update\":(map(select(.==\"update\"))|length),\"delete\":(map(select(.==\"delete\"))|length)}'"
  script:
    - echo "Planning on workspace ${TF_WORKSPACE}. Plan will be exported to ${TF_WORKSPACE}.tfplan"
    - terraform plan -out "${TF_WORKSPACE}.tfplan"
    - terraform show --json "${TF_WORKSPACE}.tfplan" | convert_report > "${TF_WORKSPACE}.json"
  artifacts:
    reports:
      terraform: ${TF_DIR}/${TF_WORKSPACE}.json
    paths:
      - ${TF_DIR}/${TF_WORKSPACE}.tfplan

.apply:
  # Run terraform apply on the exported plan and the workspace defined in ${TF_WORKSPACE}
  before_script:
    - cd ${TF_DIR}
  script:
    - echo "Applying on workspace ${TF_WORKSPACE} from ${TF_WORKSPACE}.tfplan"
    - terraform apply "${TF_WORKSPACE}.tfplan"


.destroy:
  # Run Terraform destroy on the workspace defined in ${TF_WORKSPACE}
  before_script:
    - cd ${TF_DIR}
  script:
    - echo "Destroying workspace ${TF_WORKSPACE}"
    - terraform destroy -auto-approve

########################################################################################################################
# Environment settings
########################################################################################################################
.dev:
  variables:
    TF_WORKSPACE: dev
  tags:
    - dev
    - stable
  resource_group: dev
  artifacts:
    name: dev

.stg:
  variables:
    TF_WORKSPACE: stg
  tags:
    - stg
    - stable
  resource_group: stg
  artifacts:
    name: stg

.prd:
  variables:
    TF_WORKSPACE: prd
  tags:
    - prd
    - stable
  resource_group: prd
  artifacts:
    name: prd

########################################################################################################################
# Terraform workflow with environments
########################################################################################################################
.plan-dev:
  # Run plan on dev environment
  extends:
    - .plan
    - .dev

.plan-stg:
  # Run plan on stg environment
  extends:
    - .plan
    - .stg

.plan-prd:
  # Run plan on prd environment
  extends:
    - .plan
    - .prd

.apply-dev:
  # Run terraform apply on dev
  extends:
    - .apply
    - .dev
  environment:
    name: ${TF_WORKSPACE}

.apply-stg:
  # Run terraform apply on stg
  extends:
    - .apply
    - .stg
  environment:
    name: ${TF_WORKSPACE}

.apply-prd:
  # Run terraform apply on prd
  extends:
    - .apply
    - .prd
  environment:
    name: ${TF_WORKSPACE}

.destroy-dev:
  # Destroy dev environment
  extends:
    - .destroy
    - .dev

.destroy-stg:
  # Destroy stg environment
  extends:
    - .destroy
    - .stg

.destroy-prd:
  # Destroy prd environment
  extends:
    - .destroy
    - .prd
