Terraform + Gitlab CI簡單整合方案

語言: CN / TW / HK

一 背景

利用Gitlab CI實現基礎設施編排自動化,使用者後續針對基礎設施的管理使用Gitlab完成,提交基礎設施變更後,會出發pr進行Gitlab CI流水線執行,從而實現基礎設施DevOPS流程。

二 流程架構

2.1 架構圖

2.2 流程

運維研發編寫目標雲的基於Terraform的資源清單檔案,同事專案內管理Gitlab CI流程,在K8s不同NS下注冊有對應的runner,當在不同分支下可以觸發不同ns下的CI流程。

  1. 開發或運維人員提交程式碼。
  2. 部署在對應名稱空間下的runner執行流程,建立執行單個Stage的POD來執行Terraform對應命令,例如init/fmt/play/apply等。
  3. 如果要對雲上資源進行變更,修改程式碼,再次提交pr,出發更新流水線。
  4. 如果需要銷燬,根據CI檔案配置提交BUILD為destroy,觸發雲上銷燬動作。

三 預置條件

  • Gitlab 伺服器
  • 註冊有專案的gitlab-runner
  • K8s叢集
  • 騰訊雲AK賬號

四 配置

4.1 Gitlab CI配置

4.1.1 .gitlab.yaml

```yaml variables: # PHASE: BUILD|DESTROY PHASE: DESTROY

PROXY: http://squiduser:[email protected]:3128

PROXY: http://squiduser:[email protected]:3128

REGION: "ap-guangzhou" PLAN_JSON: plan.json BACKEND_CONF: "backend_oss.conf"

before_script:

- apk add --no-cache curl git jq

  • apk add --no-cache jq
  • export http_proxy=${SQUID_PROXY}
  • export https_proxy=${SQUID_PROXY}
  • export TENCENTCLOUD_SECRET_KEY=${TENCENTCLOUD_SECRET_KEY}
  • export TENCENTCLOUD_SECRET_ID=${TENCENTCLOUD_SECRET_ID}
  • export TF_REGISTRY_CLIENT_TIMEOUT=120000
  • export CHECKPOINT_TIMEOUT=500000
  • export TF_REGISTRY_DISCOVERY_RETRY=5
  • 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)}'"

配置快取

cache: paths: - ${CI_PROJECT_DIR}/.terraform/*

stages: - init - validate - plan - deploy

Init: image: name: hashicorp/terraform:0.14.0 entrypoint: [""] stage: init retry: max: 2 when: - script_failure tags: - gitlab-runner-k8s-new script: - terraform version - terraform init -backend-config=${BACKEND_CONF} only: - dev

Validate: image: name: hashicorp/terraform:0.14.0 entrypoint: [""] stage: validate tags: - gitlab-runner-k8s-new retry: 2 script: - terraform init -backend-config=${BACKEND_CONF} - terraform validate - terraform fmt -check -recursive || echo 0 cache: paths: - ${CI_PROJECT_DIR}/.terraform/* policy: pull allow_failure: true

Plan: image: name: hashicorp/terraform:0.14.0 entrypoint: [""] stage: plan retry: 2 tags: - gitlab-runner-k8s-new artifacts: paths: - plan.bin - app_config.zip expire_in: 2 week script: - terraform init -backend-config=${BACKEND_CONF} - terraform plan -input=false -out=plan.bin -var region=${REGION} - terraform show --json "plan.bin" | convert_report > ${PLAN_JSON} - cat ${PLAN_JSON} only: variables: - $PHASE == "BUILD"

Apply: image: name: hashicorp/terraform:0.14.0 entrypoint: [""] when: manual stage: deploy retry: 2 tags: - gitlab-runner-k8s-new script: - terraform init -backend-config=${BACKEND_CONF} - terraform apply -auto-approve -input=false plan.bin only: variables: - $PHASE == "BUILD" environment: name: snunv

Destroy: image: name: hashicorp/terraform:0.14.0 entrypoint: [""] stage: deploy retry: 2 tags: - gitlab-runner-k8s-new script: - terraform init -backend-config=${BACKEND_CONF} - terraform destroy -auto-approve -var region=${REGION} only: variables: - $PHASE == "DESTROY" ```

4.1.2 環境配置

利用Gitlab CI/CD的Environment進行環境管理。

4.2 Terraform資源

```shell provider "tencentcloud" { region = var.region }

terraform { required_providers { tencentcloud = { source = "registry.terraform.io/tencentcloudstack/tencentcloud" version = ">=1.61.5" } } backend "cos" {} }

輸入變數

variable "region" { type = string }

再次僅為一個查詢示例

data "tencentcloud_instances" "cvm" { }

輸出

output "result" { value = { cvm_result = { for k, v in data.tencentcloud_instances.cvm : k => v }, count = data.tencentcloud_instances.cvm.instance_list[*] } } ```

為了terraform後端backend安全,將其儲存為單獨檔案,可不同分支或環境進行修改

shell region = "ap-beijing" bucket = "tfproject-1253329830" prefix = "samxxxxitlab/dexxxxxt"

五 測試

  • init

  • validate

  • Plan

  • 手動應用apply

檢視應用創建出的vpc

  • 製品下載

  • 銷燬

修改gitlabci檔案,銷燬

六 注意事項

  • 需要K8s叢集配置pv儲存捲來實現跨stage的任務cache。
  • 使用gitlab ci 環境管理來對執行ci/cd的人員隱藏金鑰資訊。
  • 後期可以使用gitlab 來進行變數管理。

本文僅實現簡單的Terraform + Gitlab CI 基礎設施編排整合,未將Gitlab CI的配置檔案進行抽離模版化,未與Ansible進行整合實施配置管理。

其他