Please enable Javascript to view the contents

使用 S3 存储 Terraform 的状态

 ·  ☕ 2 分钟

1. Terraform 如何管理资源状态

在执行 terraform init 之后,Terraform 会将依赖的插件下载到本地 plugins 目录。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
tree -aL 5

.
|-- myresource.tf
|-- .terraform
|   `-- plugins
|       |-- registry.terraform.io
|       |   |-- hashicorp
|       |   |   `-- null
|       |   `-- shaowenchen
|       |       `-- qingcloud
|       `-- selections.json
`-- var.tf

在执行 terraform apply 之后,Terraform 会使用 terraform.tfstate 文件存储资源的信息。新建 .terraform.tfstate.lock.info 锁定资源,避免多个 Terraform 同时使用一个状态文件。在执行完毕之后, .terraform.tfstate.lock.info 文件会被删除。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
tree -aL 5

.
|-- myresource.tf
|-- .terraform
|   `-- plugins
|       |-- registry.terraform.io
|       |   |-- hashicorp
|       |   |   `-- null
|       |   `-- shaowenchen
|       |       `-- qingcloud
|       `-- selections.json
|-- terraform.tfstate
|-- .terraform.tfstate.lock.info
`-- var.tf

terraform.tfstate 是一个 Json 文件,存储了资源的 ID 、状态等信息,格式如下:

1
2
3
4
5
6
7
8
{
  "version": 4,
  "terraform_version": "0.13.0",
  "serial": 11,
  "lineage": "9359dc1c-9a6d-b1e0-9780-d26500869e82",
  "outputs": {},
  "resources": [...]
}

在执行 terraform destroy 之后,Terraform 会新建一个 terraform.tfstate.backup 文件,备份资源状态,接着删除资源。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
tree -aL 5

.
|-- myresource.tf
|-- .terraform
|   `-- plugins
|       |-- registry.terraform.io
|       |   |-- hashicorp
|       |   |   `-- null
|       |   `-- shaowenchen
|       |       `-- qingcloud
|       `-- selections.json
|-- terraform.tfstate
|-- .terraform.tfstate.backup
`-- var.tf

具体的细节没有深究太多,简单点就是 Terraform 使用 Json 存储了资源的状态,默认存储在本地目录下。

2. 使用 S3 存储 Terraform 的状态

如果在一个团队、GitHub Actions 中,如何持久化存储 Terraform 的状态呢?持久化状态也就是需要将上面的 Json 数据存储在某一个远端持久化服务中。Terraform 支持很多种后端存储,下面是从 Terraform 官网获取的一个 Backend 列表:

  • artifactory
  • azurerm
  • consul
  • cos
  • etcd
  • etcdv3
  • gcs
  • http
  • kubernetes
  • manta
  • oss
  • pg
  • s3
  • swift

Terraform 使用 Backend 模块来处理状态的存储。在 var.tf 文件中,只需要添加一个 backend ,填上参数即可使用远端存储状态。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
terraform {
  backend "s3" {
    bucket   = "terraform-deploy"
    key      = "tf-cd"
    region     = "sh1a"
    endpoint = "s3.sh1a.qingstor.com"
    skip_region_validation      = true
    skip_metadata_api_check     = true
    skip_credentials_validation = true
    access_key = "ACCESS_KEY"
    secret_key = "SECRET_KEY"
  }
}

terraform apply 之后,在支持 S3 的对象存储上,就可以看到状态文件:

如果需要 lock 状态文件,可以使用类似 DynamoDB 的 BaaS 保证数据的一致性。

3. 参考


微信公众号
作者
微信公众号