- 先决条件
- 使用极狐GitLab CI/CD 将 Terraform 状态初始化为后端
- 从本地机器访问状态
- 迁移到极狐GitLab 管理的 Terraform 状态
- 使用极狐GitLab 后端作为远端数据源
- 管理 Terraform 状态文件
极狐GitLab 管理的 Terraform 状态
Terraform 使用状态文件来存储有关您的基础架构配置的详细信息。 使用 Terraform 远程后端,您可以将状态文件存储在远程和共享存储中。
极狐GitLab 提供了一个 Terraform HTTP 后端来以最少的配置安全地存储您的状态文件。
在极狐GitLab 中,您可以:
- 版本化您的 Terraform 状态文件。
- 加密传输中和静止时的状态文件。
- 锁定和解锁状态。
- 远程执行
terraform plan
和terraform apply
命令。
先决条件
对于私有部署实例,在您可以将极狐GitLab 用于 Terraform 状态文件之前:
- 管理员必须设置 Terraform 状态存储。
- 您必须为您的项目启用 基础设施 菜单。 转到 设置 > 通用,展开 可见性、项目功能、权限,然后在 运维 下,打开切换开关。
使用极狐GitLab CI/CD 将 Terraform 状态初始化为后端
执行 terraform init
命令后,您可以使用极狐GitLab CI/CD 运行 terraform
命令。
先决条件:
- 要使用
terraform apply
锁定、解锁和写入状态,您必须至少具有维护者角色。 - 要使用
terraform plan -lock=false
读取状态,您必须至少具有开发者角色。
要将极狐GitLab CI/CD 配置为后端:
-
在您的 Terraform 项目中,在像
backend.tf
这样的.tf
文件中,定义 HTTP 后端:terraform { backend "http" { } }
- 在项目仓库的根目录中,创建一个
.gitlab-ci.yml
文件。使用Terraform.gitlab-ci.yml
模板来填充它。 - 将您的项目推送到极狐GitLab。此操作触发一条流水线,该流水线运行
gitlab-terraform init
、gitlab-terraform validate
和gitlab-terraform plan
命令。 - 从运行
gitlab-terraform apply
命令的上一个流水线触发手动deploy
作业,以配置定义的基础设施。
上述 terraform
命令的输出应该可以在作业日志中查看。
gitlab-terraform
CLI 是 terraform
CLI 的包装器。
如果您更喜欢显式调用 terraform
命令,则可以覆盖模板,而是将其用作您可以实现的目标的参考。
自定义 Terraform 环境变量
使用 Terraform.gitlab-ci.yml
模板时,可以在定义您的 CI/CD 作业时,使用 Terraform HTTP 配置变量。
要自定义 terraform init
并覆盖 Terraform 配置,请使用环境变量而不是 terraform init -backend-config=...
方法。
使用 -backend-config
时,配置为:
- 缓存在
terraform plan
命令的输出中。 - 通常传递给
terraform apply
命令。
此配置可能会导致问题,例如无法在 CI 作业中锁定 Terraform 状态文件。
从本地机器访问状态
您可以从本地计算机访问极狐GitLab 管理的 Terraform 状态。
- 确保 Terraform 状态已为 CI/CD 初始化。
-
复制预先填充的 Terraform
init
命令:- 在顶部栏上,选择 主菜单 > 项目 并找到您的项目。
- 在左侧边栏上,选择 基础设施 > Terraform。
- 在您要使用的环境旁边,选择 操作 (),并选择 复制 Terraform init 命令。
- 打开终端并在本地计算机上运行此命令。
迁移到极狐GitLab 管理的 Terraform 状态
Terraform 支持在后端更改或重新配置时复制状态。使用这些操作从另一个后端迁移到极狐GitLab 管理的 Terraform 状态。
您应该使用本地终端运行迁移到极狐GitLab 管理的 Terraform 状态所需的命令。
以下示例演示如何更改状态名称。从不同的状态存储后端迁移到极狐GitLab 管理的 Terraform 状态需要相同的工作流程。
设置初始后端
PROJECT_ID="<gitlab-project-id>"
TF_USERNAME="<gitlab-username>"
TF_PASSWORD="<gitlab-personal-access-token>"
TF_ADDRESS="https://gitlab.com/api/v4/projects/${PROJECT_ID}/terraform/state/old-state-name"
terraform init \
-backend-config=address=${TF_ADDRESS} \
-backend-config=lock_address=${TF_ADDRESS}/lock \
-backend-config=unlock_address=${TF_ADDRESS}/lock \
-backend-config=username=${TF_USERNAME} \
-backend-config=password=${TF_PASSWORD} \
-backend-config=lock_method=POST \
-backend-config=unlock_method=DELETE \
-backend-config=retry_wait_min=5
Initializing the backend...
Successfully configured the backend "http"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing provider plugins...
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
re-run this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
更改后端
现在 terraform init
已经创建了一个 .terraform/
目录,它知道旧状态在哪里,您可以告诉它新位置:
TF_ADDRESS="https://gitlab.com/api/v4/projects/${PROJECT_ID}/terraform/state/new-state-name"
terraform init \
-migrate-state \
-backend-config=address=${TF_ADDRESS} \
-backend-config=lock_address=${TF_ADDRESS}/lock \
-backend-config=unlock_address=${TF_ADDRESS}/lock \
-backend-config=username=${TF_USERNAME} \
-backend-config=password=${TF_PASSWORD} \
-backend-config=lock_method=POST \
-backend-config=unlock_method=DELETE \
-backend-config=retry_wait_min=5
Initializing the backend...
Backend configuration changed!
Terraform has detected that the configuration specified for the backend
has changed. Terraform will now check for existing state in the backends.
Acquiring state lock. This may take a few moments...
Do you want to copy existing state to the new backend?
Pre-existing state was found while migrating the previous "http" backend to the
newly configured "http" backend. No existing state was found in the newly
configured "http" backend. Do you want to copy this state to the new "http"
backend? Enter "yes" to copy and "no" to start with an empty state.
Enter a value: yes
Successfully configured the backend "http"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing provider plugins...
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
如果您键入 yes
,它会将您的状态从旧位置复制到新位置。然后,您可以返回到极狐GitLab CI/CD 中运行它。
使用极狐GitLab 后端作为远端数据源
您可以使用极狐GitLab 管理的 Terraform 状态后端作为 Terraform 数据源。
-
在您的
main.tf
或其他相关文件中,声明这些变量。 将值留空。variable "example_remote_state_address" { type = string description = "Gitlab remote state file address" } variable "example_username" { type = string description = "Gitlab username to query remote state" } variable "example_access_token" { type = string description = "GitLab access token to query remote state" }
-
要覆盖上一步中的值,请创建一个名为
example.auto.tfvars
的文件。此文件应该不在您的项目仓库中进行版本控制。example_remote_state_address = "https://gitlab.com/api/v4/projects/<TARGET-PROJECT-ID>/terraform/state/<TARGET-STATE-NAME>" example_username = "<GitLab username>" example_access_token = "<GitLab Personal Access Token>"
-
在
.tf
文件中,使用 Terraform 输入变量定义数据源:data "terraform_remote_state" "example" { backend = "http" config = { address = var.example_remote_state_address username = var.example_username password = var.example_access_token } }
-
address:要用作数据源的远端状态后端的 URL。例如,
https://gitlab.com/api/v4/projects/<TARGET-PROJECT-ID>/terraform/state/<TARGET-STATE-NAME>
。 -
username:向数据源进行身份验证的用户名。如果您使用个人访问令牌进行身份验证,则此值是您的极狐GitLab 用户名。如果您使用的是极狐GitLab CI/CD,则此值为
'gitlab-ci-token'
。 -
password:用于对数据源进行身份验证的密码。如果您使用个人访问令牌进行身份验证,则此值是令牌值(令牌必须具有 API 范围)。如果您使用的是极狐GitLab CI/CD,则此值是
${CI_JOB_TOKEN}
CI/CD 变量的内容。
-
address:要用作数据源的远端状态后端的 URL。例如,
现在可以使用 data.terraform_remote_state.example.outputs.<OUTPUT-NAME>
在 Terraform 资源中引用数据源的输出。
要读取目标项目中的 Terraform 状态,您至少需要开发者角色。
管理 Terraform 状态文件
引入于 13.8 版本。
查看 Terraform 状态文件:
- 在顶部栏上,选择 菜单 > 项目 并找到您的项目。
- 在左侧边栏上,选择 基础设施 > Terraform。
管理单个 Terraform 状态版本
引入于 13.4 版本。
可以使用极狐GitLab REST API 管理各个状态版本。
如果您至少具有开发者角色,则可以使用其序列号检索状态版本:
curl --header "Private-Token: <your_access_token>" "https://gitlab.example.com/api/v4/projects/<your_project_id>/terraform/state/<your_state_name>/versions/<version-serial>"
如果您至少具有维护者角色,则可以使用其序列号删除状态版本:
curl --header "Private-Token: <your_access_token>" --request DELETE "https://gitlab.example.com/api/v4/projects/<your_project_id>/terraform/state/<your_state_name>/versions/<version-serial>"
删除状态文件
如果您至少具有维护者角色,则可以删除状态文件。
- 在左侧边栏上,选择 基础设施 > Terraform。
- 在 操作 列中,选择 操作 (),然后选择 删除状态文件和版本。
使用 API 删除状态文件
您可以通过向 REST API 发出请求来删除状态文件。例如:
curl --header "Private-Token: <your_access_token>" --request DELETE "https://gitlab.example.com/api/v4/projects/<your_project_id>/terraform/state/<your_state_name>"