我在GitLab CI/CD流水线中尝试使用Terraform创建Azure的ResourceGroup
总结
让我们将基础设施也转换为IaC(代码),并进行CI!因此,我使用GitLab CI/CD流水线在Azure上创建了一个ResourceGroup。
执行环境 (shí
macOS Monterey 12.3.1 -> macOS 蒙特利12.3.1
python 3.8.12 -> Python 3.8.12
Azure CLI 2.34.1 -> Azure 命令行界面 2.34.1
事前准备
この記事 にあるように Terraform用のサービスプリンシパルが準備されており、以下のシークレット情報を入手できていること
ARM_TENANT_ID
ARM_SUBSCRIPTION_ID
ARM_CLIENT_ID
ARM_CLIENT_SECRET
在Gitlab中的准备工作
创建Gitlab的个人访问令牌
-
- Gitlab CI/CD の job を実行する権限を有するアクセストークンを発行します(git clone/push時に必要)
サインインアカウントの「Edit profile」-「Access token」を選択
「Token name」に一意の名称を入力後、「Select scopes」で、「api」を選択する
「Create personal access token」ボタンを押す
画面上部に表示される「パーソナルアクセストークン」をどこかにコピーしておく
创建Gitlab仓库
- GitlabにてTerraformのコードを管理するリポジトリ(プライベートリポジトリで可)を作成し、ローカルで git clone します
将秘密信息注册到Gitlab。
需要的代码 de
Terraform代碼
这次是由以下三个代码组成的(只是创建资源组而已。。。)
# プロバイダーの定義
terraform {
required_providers {
azurerm = "~> 2.33"
}
# tfstateファイルを gitlab に保存
backend "http" {
}
}
provider "azurerm" {
features {}
tenant_id = var.ARM_TENANT_ID
subscription_id = var.ARM_SUBSCRIPTION_ID
client_id = var.ARM_CLIENT_ID
client_secret = var.ARM_CLIENT_SECRET
}
# リソースグループ
resource "azurerm_resource_group" "this" {
name = var.resource_group_name
location = var.region
tags = var.tags_def
}
# 環境変数(Azureサービスプリンシパル)
variable "ARM_TENANT_ID" {}
variable "ARM_SUBSCRIPTION_ID" {}
variable "ARM_CLIENT_ID" {}
variable "ARM_CLIENT_SECRET" {}
# タグ情報
variable "tags_def" {
default = {
owner = "ituru"
period = "2022-09-16"
CostCenter = "PSG2"
Environment = "GitLab"
}
}
# 各種パラメータ
variable "region" {} // 利用リージョン
variable "resource_group_name" {} // リソースグループ名
# パラメータ値の定義
region = "japaneast" // 利用リージョン
resource_group_name = "rg_ituru_github" // リソースグループ名
创建 Gitlab CI/CD 的 yaml 文件
在存储库的根目录下创建一个名为 .gitlab-ci.yml 的文件。在这里,我们将编写 Gitlab CI/CD 管道的代码。请参考 GitLab CI/CD 管道设置参考文档 来了解如何编写。
## https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml
include:
- template: Terraform/Base.gitlab-ci.yml
variables:
TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/tfstate_filename
cache:
key: tfstate_filename
paths:
- .terraform
before_script:
- export TF_VAR_ARM_TENANT_ID=${ARM_TENANT_ID}
- export TF_VAR_ARM_SUBSCRIPTION_ID=${ARM_SUBSCRIPTION_ID}
- export TF_VAR_ARM_CLIENT_ID=${ARM_CLIENT_ID}
- export TF_VAR_ARM_CLIENT_SECRET=${ARM_CLIENT_SECRET}
- printenv
stages:
- prepare
- validate
- build
- deploy
- cleanup
init:
stage: prepare
script:
- gitlab-terraform init
rules:
- if: '$CI_MERGE_REQUEST_IID && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH'
when: always
- if: '$CI_COMMIT_BRANCH == "main"'
validate:
stage: validate
script:
- gitlab-terraform validate
rules:
- if: '$CI_MERGE_REQUEST_IID && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH'
when: always
- if: '$CI_COMMIT_BRANCH == "main"'
plan:
stage: build
script:
- gitlab-terraform plan
- gitlab-terraform plan-json
artifacts:
name: plan
paths:
- plan.cache
reports:
terraform: plan.json
rules:
- if: '$CI_MERGE_REQUEST_IID && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH'
when: always
- if: '$CI_COMMIT_BRANCH == "main"'
apply:
stage: deploy
script:
- gitlab-terraform apply
dependencies:
- plan
rules:
- if: '$CI_MERGE_REQUEST_IID && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH'
when: never
- if: '$CI_COMMIT_BRANCH == "main"'
when: manual
destroy:
stage: cleanup
script:
- gitlab-terraform destroy
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: manual
.gitlab-ci.yml的说明
包括
使用 GitHub 上提供的模板,利用 Terraform 执行环境的容器。
变量
在执行Job时,创建了一个名为tfstate的文件夹,并将其位置作为变量嵌入到HTTP端点中。
缓存
这是为了确保可以在不同阶段之间使用terraform执行结果(tfstate文件)的配置。
预设脚本 (yù shè
读取该存储库中的设置变量,并将其定义为环境变量。
阶段
在流水线中设置每个阶段。
由于使用Terraform,所以配置为init > validate > plan > apply > destory。
开始
这是一个初始化terraform的步骤。
当主分支的合并请求被批准(主分支被更新)时,会自动执行。
验证
当主分支的合并请求被批准(主分支被更新)时,将自动执行terraform validate阶段。
计划
这是进行 terraform plan 的阶段。
当主分支的合并请求被批准(主分支被更新)时,会自动执行。
terraform plan 的执行结果将保存为 JSON 文件到 artifacts 中。
申请
这是terraform apply的阶段。
需要手动执行。
摧毁
这是一个执行terraform destroy的阶段。
需要手动执行。
尝试进行git push操作。
现在准备工作已完成。通过进行 git push,将会执行 terraform plan 并在 Azure 上创建 ResourceGroup。
推动
git add .
git commit -m "Actions commit"
git push -u origin main
行动
创建和删除 Azure 资源
手动执行创建资源(阶段:部署)和删除资源(阶段:清理)的CI/CD流水线任务。
创建资源
在CI/CD流水线的任务中,执行terraform apply(阶段:部署)会创建资源组。您可以确认资源已经成功创建。
$ az group show --name rg_ituru_gitlab
{
"id": "/subscriptions/xxxxxxxx-1717-4343-9797-zzzzzzzzzzzz/resourceGroups/rg_ituru_gitlab",
"location": "japaneast",
"managedBy": null,
"name": "rg_ituru_gitlab",
"properties": {
"provisioningState": "Succeeded"
},
"tags": {
"CostCenter": "PSG2",
"Environment": "GitLab",
"owner": "ituru",
"period": "2022-09-16"
},
"type": "Microsoft.Resources/resourceGroups"
}
删除资源
当在 CI/CD流程的作业中执行terrafrom destroy(cleanup阶段),将删除ResourceGroup。可以确认资源已成功删除。
$ az group show --name rg_ituru_gitlab
(ResourceGroupNotFound) Resource group 'rg_ituru_gitlab' could not be found.
Code: ResourceGroupNotFound
Message: Resource group 'rg_ituru_gitlab' could not be found.
总结
我已经简单理解了使用 GitLab CI/CD 管道来通过 Terraform 创建和删除 Azure 资源的实现方法。顺便提一句,我也在尝试在 GitHub Actions 上做类似的事情。
-
- GitHub Actions から Terraform で Azure の ResourceGroup を作成してみました
-
- GitHub Actions から Terraform で Azure の ResourceGroup を更新(変更)してみました
- GitHub Actions から Terraform destroy してみました
请读这篇文章。
我参考了以下文章并表示感谢:
使用 Terraform 和 GitLab CI 进行基础设施CI/CD入门
Terraform 项目的 .gitlab-ci.yml 模板
尝试使用 GitLab 管理 terraform 的 tfstate
一个关于零基础的软件工程师在 GitLab 上尝试使用 HTTPS 克隆和推送的文章
一个知识零的软件工程师在没有源代码的情况下构建 GitLab 的CI/CD流水线(DAG)的讨论
预定义变量参考资料